[PATCH v3 6/6] setpriv: allow modifying ambient capabilities
Denys Vlasenko
vda.linux at googlemail.com
Fri Jul 7 00:15:14 UTC 2017
Applied all patches, thanks.
On Thu, Jul 6, 2017 at 3:21 PM, Patrick Steinhardt <ps at pks.im> wrote:
> 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 at pks.im>
> ---
> util-linux/setpriv.c | 49 +++++++++++++++++++++++++++++++++++++++++++------
> 1 file changed, 43 insertions(+), 6 deletions(-)
>
> diff --git a/util-linux/setpriv.c b/util-linux/setpriv.c
> index b9e481a6f..9ada33df4 100644
> --- a/util-linux/setpriv.c
> +++ b/util-linux/setpriv.c
> @@ -53,16 +53,20 @@
> //usage:#define setpriv_full_usage "\n\n"
> //usage: "Run PROG with different privilege settings\n"
> //usage: IF_FEATURE_SETPRIV_DUMP(
> -//usage: "\n-d,--dump Show current capabilities"
> +//usage: "\n-d,--dump Show current capabilities"
> //usage: )
> -//usage: "\n--nnp,--no-new-privs Ignore setuid/setgid bits and file capabilities"
> +//usage: "\n--nnp,--no-new-privs Ignore setuid/setgid bits and file capabilities"
> //usage: IF_FEATURE_SETPRIV_CAPABILITIES(
> -//usage: "\n--inh-caps <caps,...> Set inheritable capabilities"
> +//usage: "\n--inh-caps <caps,...> Set inheritable capabilities"
> +//usage: )
> +//usage: IF_FEATURE_SETPRIV_CAPABILITIES(
> +//usage: "\n--ambient-caps <caps,...> Set ambient capabilities"
> //usage: )
>
> -//setpriv from util-linux 2.28:
> +//setpriv from util-linux 4fb515f90079739771b64dcb6beeb384e3be7cf5
> // -d, --dump show current state (and do not exec anything)
> // --nnp, --no-new-privs disallow granting new privileges
> +// --ambient-caps <caps,...> set ambient capabilities
> // --inh-caps <caps,...> set inheritable capabilities
> // --bounding-set <caps> set capability bounding set
> // --ruid <uid> set real uid
> @@ -100,15 +104,19 @@
> #ifndef PR_CAP_AMBIENT
> #define PR_CAP_AMBIENT 47
> #define PR_CAP_AMBIENT_IS_SET 1
> +#define PR_CAP_AMBIENT_RAISE 2
> +#define PR_CAP_AMBIENT_LOWER 3
> #endif
>
> enum {
> IF_FEATURE_SETPRIV_DUMP(OPTBIT_DUMP,)
> IF_FEATURE_SETPRIV_CAPABILITIES(OPTBIT_INH,)
> + IF_FEATURE_SETPRIV_CAPABILITIES(OPTBIT_AMB,)
> OPTBIT_NNP,
>
> IF_FEATURE_SETPRIV_DUMP(OPT_DUMP = (1 << OPTBIT_DUMP),)
> IF_FEATURE_SETPRIV_CAPABILITIES(OPT_INH = (1 << OPTBIT_INH),)
> + IF_FEATURE_SETPRIV_CAPABILITIES(OPT_AMB = (1 << OPTBIT_AMB),)
> OPT_NNP = (1 << OPTBIT_NNP),
> };
>
> @@ -396,6 +404,29 @@ static void set_inh_caps(char *capstring)
> if (ENABLE_FEATURE_CLEAN_UP)
> free(caps.data);
> }
> +
> +static void set_ambient_caps(char *string)
> +{
> + char *cap;
> +
> + cap = strtok(string, ",");
> + while (cap) {
> + unsigned long index;
> + int add;
> +
> + parse_cap(&index, &add, cap);
> +
> + if (add) {
> + if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, index, 0, 0) < 0)
> + bb_perror_msg("cap_ambient_raise");
> + } else {
> + if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_LOWER, index, 0, 0) < 0)
> + bb_perror_msg("cap_ambient_lower");
> + }
> +
> + cap = strtok(NULL, ",");
> + }
> +}
> #endif /* FEATURE_SETPRIV_CAPABILITIES */
>
> int setpriv_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
> @@ -410,15 +441,18 @@ int setpriv_main(int argc UNUSED_PARAM, char **argv)
> IF_FEATURE_SETPRIV_CAPABILITIES(
> "inh-caps\0" Required_argument "\xfe"
> )
> + IF_FEATURE_SETPRIV_CAPABILITIES(
> + "ambient-caps\0" Required_argument "\xfd"
> + )
> ;
> #if ENABLE_FEATURE_SETPRIV_CAPABILITIES
> - char *inh_caps;
> + char *inh_caps, *ambient_caps;
> #endif
> int opts;
>
> applet_long_options = setpriv_longopts;
> opts = getopt32(argv, "+"IF_FEATURE_SETPRIV_DUMP("d")
> - IF_FEATURE_SETPRIV_CAPABILITIES("\xfe:" , &inh_caps));
> + IF_FEATURE_SETPRIV_CAPABILITIES("\xfe:\xfd:" , &inh_caps, &ambient_caps));
>
> argv += optind;
>
> @@ -437,6 +471,9 @@ int setpriv_main(int argc UNUSED_PARAM, char **argv)
> #if ENABLE_FEATURE_SETPRIV_CAPABILITIES
> if (opts & OPT_INH)
> set_inh_caps(inh_caps);
> +
> + if (opts & OPT_AMB)
> + set_ambient_caps(ambient_caps);
> #endif
>
> if (!argv[0])
> --
> 2.13.2
>
More information about the busybox
mailing list