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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>