[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