Commit Graph

23 Commits

Author SHA1 Message Date
James Byrne
6937487be7 libbb: reduce the overhead of single parameter bb_error_msg() calls
Back in 2007, commit 0c97c9d437 ("'simple' error message functions by
Loic Grenie") introduced bb_simple_perror_msg() to allow for a lower
overhead call to bb_perror_msg() when only a string was being printed
with no parameters. This saves space for some CPU architectures because
it avoids the overhead of a call to a variadic function. However there
has never been a simple version of bb_error_msg(), and since 2007 many
new calls to bb_perror_msg() have been added that only take a single
parameter and so could have been using bb_simple_perror_message().

This changeset introduces 'simple' versions of bb_info_msg(),
bb_error_msg(), bb_error_msg_and_die(), bb_herror_msg() and
bb_herror_msg_and_die(), and replaces all calls that only take a
single parameter, or use something like ("%s", arg), with calls to the
corresponding 'simple' version.

Since it is likely that single parameter calls to the variadic functions
may be accidentally reintroduced in the future a new debugging config
option WARN_SIMPLE_MSG has been introduced. This uses some macro magic
which will cause any such calls to generate a warning, but this is
turned off by default to avoid use of the unpleasant macros in normal
circumstances.

This is a large changeset due to the number of calls that have been
replaced. The only files that contain changes other than simple
substitution of function calls are libbb.h, libbb/herror_msg.c,
libbb/verror_msg.c and libbb/xfuncs_printf.c. In miscutils/devfsd.c,
networking/udhcp/common.h and util-linux/mdev.c additonal macros have
been added for logging so that single parameter and multiple parameter
logging variants exist.

The amount of space saved varies considerably by architecture, and was
found to be as follows (for 'defconfig' using GCC 7.4):

Arm:     -92 bytes
MIPS:    -52 bytes
PPC:   -1836 bytes
x86_64: -938 bytes

Note that for the MIPS architecture only an exception had to be made
disabling the 'simple' calls for 'udhcp' (in networking/udhcp/common.h)
because it made these files larger on MIPS.

Signed-off-by: James Byrne <james.byrne@origamienergy.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2019-07-02 11:35:03 +02:00
Denys Vlasenko
b097a84d62 config: update size information
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2018-12-28 03:20:17 +01:00
Denys Vlasenko
0180b57aaf setpriv: placete "declaration of 'index' shadows a global declaration" warning
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2017-08-29 15:34:38 +02:00
Denys Vlasenko
200bcc851a run-init: new applet
function                                             old     new   delta
switch_root_main                                     354     637    +283
drop_usermodehelper                                    -     157    +157
cap_name_to_number                                     -      77     +77
packed_usage                                       31707   31743     +36
applet_names                                        2665    2674      +9
applet_main                                         1544    1548      +4
applet_install_loc                                   193     194      +1
setpriv_main                                         933     928      -5
getcaps                                              131     122      -9
parse_cap                                            117      29     -88
------------------------------------------------------------------------------
(add/remove: 3/0 grow/shrink: 5/3 up/down: 567/-102)          Total: 465 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2017-08-21 19:30:01 +02:00
Denys Vlasenko
44b3f2ffbc libbb: move capability names code to libbb
function                                             old     new   delta
cap_name_to_number                                     -      77     +77
parse_cap                                            117      29     -88
------------------------------------------------------------------------------
(add/remove: 2/0 grow/shrink: 0/1 up/down: 77/-88)            Total: -11 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2017-08-21 02:14:19 +02:00
Denys Vlasenko
ec2482e966 setpriv: code shrink
function                                             old     new   delta
parse_cap                                            125     117      -8
setpriv_main                                         949     933     -16
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/2 up/down: 0/-24)             Total: -24 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2017-08-20 20:21:31 +02:00
Denys Vlasenko
79747415d6 setpriv: accept any case in capability names
This should work: setpriv --inh-caps -SyS_ReSOuRCE sh

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2017-08-18 19:11:57 +02:00
Denys Vlasenko
036585a911 getopt32: remove applet_long_options
FEATURE_GETOPT_LONG made dependent on LONG_OPTS.

The folloving options are removed, now LONG_OPTS enables long options
for affected applets:
FEATURE_ENV_LONG_OPTIONS	FEATURE_EXPAND_LONG_OPTIONS
FEATURE_UNEXPAND_LONG_OPTIONS	FEATURE_MKDIR_LONG_OPTIONS
FEATURE_MV_LONG_OPTIONS		FEATURE_RMDIR_LONG_OPTIONS
FEATURE_ADDGROUP_LONG_OPTIONS	FEATURE_ADDUSER_LONG_OPTIONS
FEATURE_HWCLOCK_LONG_OPTIONS	FEATURE_NSENTER_LONG_OPTS
FEATURE_CHCON_LONG_OPTIONS	FEATURE_RUNCON_LONG_OPTIONS

They either had a small number of long options, or their long options are
essential.

Example: upstream addgroup and adduser have ONLY longopts,
we should probably go further and get rid
of non-standard short options.

To this end, make addgroup and adduser "select LONG_OPTS".
We had this breakage caused by us even in our own package!
	#if ENABLE_LONG_OPTS || !ENABLE_ADDGROUP
                /* We try to use --gid, not -g, because "standard" addgroup
                 * has no short option -g, it has only long --gid.
                 */
                argv[1] = (char*)"--gid";
	#else
                /* Breaks if system in fact does NOT use busybox addgroup */
                argv[1] = (char*)"-g";
	#endif

xargs: its lone longopt no longer depends on DESKTOP, only on LONG_OPTS.

hwclock TODO: get rid of incompatible -t, -l aliases to --systz, --localtime

Shorten help texts by omitting long option when short opt alternative exists.

Reduction of size comes from the fact that store of an immediate
(an address of longopts) to a fixed address (global variable)
is a longer insn than pushing that immediate or passing it in a register.
This effect is CPU-agnostic.

function                                             old     new   delta
getopt32                                            1350      22   -1328
vgetopt32                                              -    1318   +1318
getopt32long                                           -      24     +24
tftpd_main                                           562     567      +5
scan_recursive                                       376     380      +4
collect_cpu                                          545     546      +1
date_main                                           1096    1095      -1
hostname_main                                        262     259      -3
uname_main                                           259     255      -4
setpriv_main                                         362     358      -4
rmdir_main                                           191     187      -4
mv_main                                              562     558      -4
ipcalc_main                                          548     544      -4
ifenslave_main                                       641     637      -4
gzip_main                                            192     188      -4
gunzip_main                                           77      73      -4
fsfreeze_main                                         81      77      -4
flock_main                                           318     314      -4
deluser_main                                         337     333      -4
cp_main                                              374     370      -4
chown_main                                           175     171      -4
applet_long_options                                    4       -      -4
xargs_main                                           894     889      -5
wget_main                                           2540    2535      -5
udhcpc_main                                         2767    2762      -5
touch_main                                           436     431      -5
tar_main                                            1014    1009      -5
start_stop_daemon_main                              1033    1028      -5
sed_main                                             682     677      -5
script_main                                         1082    1077      -5
run_parts_main                                       330     325      -5
rtcwake_main                                         459     454      -5
od_main                                             2169    2164      -5
nl_main                                              201     196      -5
modprobe_main                                        773     768      -5
mkdir_main                                           160     155      -5
ls_main                                              568     563      -5
install_main                                         773     768      -5
hwclock_main                                         411     406      -5
getopt_main                                          622     617      -5
fstrim_main                                          256     251      -5
env_main                                             198     193      -5
dumpleases_main                                      635     630      -5
dpkg_main                                           3991    3986      -5
diff_main                                           1355    1350      -5
cryptpw_main                                         233     228      -5
cpio_main                                            593     588      -5
conspy_main                                         1135    1130      -5
chpasswd_main                                        313     308      -5
adduser_main                                         887     882      -5
addgroup_main                                        416     411      -5
ftpgetput_main                                       351     345      -6
get_terminal_width_height                            242     234      -8
expand_main                                          690     680     -10
static.expand_longopts                                18       -     -18
static.unexpand_longopts                              27       -     -27
mkdir_longopts                                        28       -     -28
env_longopts                                          30       -     -30
static.ifenslave_longopts                             34       -     -34
mv_longopts                                           46       -     -46
static.rmdir_longopts                                 48       -     -48
packed_usage                                       31739   31687     -52
------------------------------------------------------------------------------
(add/remove: 2/8 grow/shrink: 3/49 up/down: 1352/-1840)      Total: -488 bytes
   text	   data	    bss	    dec	    hex	filename
 915681	    485	   6880	 923046	  e15a6	busybox_old
 915428	    485	   6876	 922789	  e14a5	busybox_unstripped

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2017-08-08 17:09:40 +02:00
Denys Vlasenko
72089cf6b4 config: deindent all help texts
Those two spaces after tab have no effect, and always a nuisance when editing.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2017-07-21 09:50:55 +02:00
Denys Vlasenko
4eed2c6c50 Update menuconfig items with approximate applet sizes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2017-07-18 22:01:24 +02:00
Denys Vlasenko
b0c0b6d5ba setpriv: remove dependency on libcap headers
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2017-07-07 17:59:40 +02:00
Denys Vlasenko
2bfe7838ab setpriv: factor out capability name printing
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2017-07-07 16:09:45 +02:00
Denys Vlasenko
cf5748cc89 setpriv: code shrink, and grouping capability code together
function                                             old     new   delta
static.versions                                        -       3      +3
getcaps                                              174     149     -25

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2017-07-07 16:00:07 +02:00
Patrick Steinhardt
6842d00ceb setpriv: allow modifying ambient capabilities
With Linux 4.3, a new set of capabilities has been introduced with the
ambient capabilities. These aim to solve the problem that it was
impossible to grant run programs with elevated privileges across
non-root users. Quoting from capabilities(7):

    This is a set of capabilities that are preserved across an execve(2)
    of a program that is not privileged.  The ambient capability set
    obeys the invariant that no capability can ever be ambient if it is
    not both permitted and inheritable.

With this new set of capabilities it is now possible to run an
executable with elevated privileges as a different user, making it much
easier to do proper privilege separation.

Note though that the `--ambient-caps` switch is not part of any released
version of util-linux, yet. It has been applied in 0c92194ee (setpriv:
support modifying the set of ambient capabilities, 2017-06-24) and will
probably be part of v2.31.

function                                             old     new   delta
parse_cap                                              -     174    +174
setpriv_main                                        1246    1301     +55
.rodata                                           146307  146347     +40
static.setpriv_longopts                               40      55     +15
packed_usage                                       32092   32079     -13

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2017-07-07 02:14:23 +02:00
Patrick Steinhardt
0f49f6f926 setpriv: allow modifying inheritable caps
The main use case of setpriv is to modify the current state of
privileges available to the calling process and spawn a new executable
with the modified, new state. Next to the already supported case of
modifying the no-new-privs flag, util-linux also supports to modify
capability sets.

This commit introduces to add or drop capabilities from the set of
inheritable capabilities. Quoting from capabilities(7):

    This is a set of capabilities preserved across an execve(2).
    Inheritable capabilities remain inheritable when executing any
    program, and inheritable capabilities are added to the permitted set
    when executing a program that has the corresponding bits set in the
    file inheritable set.

As such, inheritable capabilities enable executing files with certain
privileges if the file itself has these privileges set. Note though that
inheritable capabilities are dropped across execve when running as a
non-root user.

function                                             old     new   delta
getcaps                                                -     237    +237
setpriv_main                                        1129    1246    +117
.rodata                                           146198  146307    +109
static.setpriv_longopts                               29      40     +11
packed_usage                                       32107   32092     -15

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2017-07-07 01:59:45 +02:00
Patrick Steinhardt
5e0987405c setpriv: dump ambient capabilities
As with the previous commit, this commit introduces the ability to dump
the set of ambient capabilities.

function                                             old     new   delta
setpriv_main                                         982    1129    +147
.rodata                                           146148  146198     +50

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2017-07-06 23:02:33 +02:00
Patrick Steinhardt
f34c701fa8 setpriv: dump capability bounding set
As with the previous commit, this one implements the ability to dump the
capability bounding set.

function                                             old     new   delta
setpriv_main                                         838     982    +144
.rodata                                           146101  146148     +47

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2017-07-06 22:59:23 +02:00
Patrick Steinhardt
ad63102943 setpriv: dump inheritable capability set
The setpriv executable from util-linux also dumps out information on the
different capability sets known by the kernel. By default, these are the
inheritable capabilities, bounding capabilities and (not yet released)
the ambient capabilities, which have been introduced with Linux 4.3.
This patch introduces the ability to dump the set of inheritable
capabilities.

By default, setpriv(1) identifies capabilities by their human-readable
name, for example 'net_admin'. For unknown capabilities, though, it does
instead use the capability's value, for example 'cap_12', which is
equivalent to 'net_admin'. As there is no kernel interface to retrieve
capability names by their index, we have to declare these ourselves,
which adds to setpriv's size.

To counteract, using the human-readble name has been made configurable.
The following sizes are with the 'FEATURE_SETPRIV_CAPABILITY_NAMES'
enabled:

function                                             old     new   delta
.rodata                                           145969  146405    +436
setpriv_main                                         467     842    +375
capabilities                                           -     304    +304

And with 'FEATURE_SETPRIV_CAPABILITY_NAMES' disabled:

function                                             old     new   delta
setpriv_main                                         467     838    +371
.rodata                                           145969  146101    +132

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2017-07-06 22:47:16 +02:00
Patrick Steinhardt
10c53b85c9 setpriv: dump no-new-privs info
Introduce the ability to dump the state of the no-new-privs flag, which
states whethere it is allowed to grant new privileges.

function                                             old     new   delta
setpriv_main                                         419     467     +48
.rodata                                           145926  145969     +43

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2017-07-06 22:27:22 +02:00
Denys Vlasenko
6798486141 setpriv: dump user and group info
setpriv from util-linux has an option to dump the current state
regarding privilege settings via '--dump'. It prints out information on
the real and effective user and group IDs, supplementary groups, the
no-new-privs flag, the capability sets as well as secure bits.

This patch is the start of supporting this mode. To make introduction of
the '--dump' easier to reason about, its introduction has been split
into multiple patches. This particular one introduces the ability to
print out user and group information of the current process.

function                                             old     new   delta
setpriv_main                                          89     322    +233
getresuid                                              -      41     +41
getresgid                                              -      41     +41
static.setpriv_longopts                               22      29      +7
packed_usage                                       31675   31669      -6
------------------------------------------------------------------------------
(add/remove: 4/0 grow/shrink: 2/1 up/down: 322/-6)            Total: 316 bytes

Patch by Patrick Steinhardt <ps@pks.im>

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2017-07-04 18:59:11 +02:00
Patrick Steinhardt
6a3bcf340a setpriv: prepare option parsing logic for additional opts
The current option parsing logic of setpriv only supports the case where
we want to execute a sub-program and have at most one argument. Refactor
handling of options to solve these shortcomings to make it easy to
support 'setpriv --dump', which does not accept any additional
arguments, as well as the case where additional options are passed to
setpriv. This is done by handling 'argc' ourselves, throwing an error
when no program is specified, as well as introducing an enum for the
different option bitmasks.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2017-07-04 17:15:32 +02:00
Patrick Steinhardt
d253b557a3 setpriv: do not process remaining args
By default, the 'getopt32' call will continue parsing the command line
even after hitting a non-option string. But in setpriv, this should be
avoided, as all parameters following the initial non-option argument are
in fact arguments to the binary that is to be executed by setpriv.
Otherwise, calling e.g. 'busybox setpriv ls -l' would result in an error
due to the unknown parameter "-l".

Fix the issue by passing "+" as the first character in the options
string. This will cause 'getopt32' to stop processing after hitting the
first non-option.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2017-07-04 17:10:31 +02:00
Assaf Gordon
62d1e98fbd setpriv: new applet
Add a minimal 'setpriv' implementation supporting the NO_NEW_PRIVS bit.
Typical usage:

    $ busybox setpriv sudo uname
    Linux
    $ busybox setpriv --nnp sudo uname
    sudo: effective uid is not 0, is /usr/bin/sudo on a file system with
    the 'nosuid' option set or an NFS file system without root privileges?

function                                             old     new   delta
packed_usage                                       31580   31685    +105
setpriv_main                                           -      87     +87
prctl                                                  -      53     +53
static.setpriv_longopts                                -      22     +22
applet_names                                        2620    2628      +8
applet_main                                         1516    1520      +4
------------------------------------------------------------------------------
(add/remove: 5/0 grow/shrink: 3/0 up/down: 279/0)             Total: 279 bytes

Signed-off-by: Assaf Gordon <assafgordon@gmail.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2017-06-14 11:46:52 +02:00