diff options
-rw-r--r-- | util-linux/setpriv.c | 44 |
1 files changed, 35 insertions, 9 deletions
diff --git a/util-linux/setpriv.c b/util-linux/setpriv.c index a1fa889e7..8d9c218a3 100644 --- a/util-linux/setpriv.c +++ b/util-linux/setpriv.c | |||
@@ -57,7 +57,8 @@ | |||
57 | //usage: ) | 57 | //usage: ) |
58 | //usage: "\n--nnp,--no-new-privs Ignore setuid/setgid bits and file capabilities" | 58 | //usage: "\n--nnp,--no-new-privs Ignore setuid/setgid bits and file capabilities" |
59 | //usage: IF_FEATURE_SETPRIV_CAPABILITIES( | 59 | //usage: IF_FEATURE_SETPRIV_CAPABILITIES( |
60 | //usage: "\n--inh-caps CAP[,CAP...] Set inheritable capabilities" | 60 | //usage: "\n--inh-caps CAP,CAP Set inheritable capabilities" |
61 | //usage: "\n--ambient-caps CAP,CAP Set ambient capabilities" | ||
61 | //usage: ) | 62 | //usage: ) |
62 | 63 | ||
63 | //setpriv from util-linux 2.28: | 64 | //setpriv from util-linux 2.28: |
@@ -100,15 +101,19 @@ | |||
100 | #ifndef PR_CAP_AMBIENT | 101 | #ifndef PR_CAP_AMBIENT |
101 | #define PR_CAP_AMBIENT 47 | 102 | #define PR_CAP_AMBIENT 47 |
102 | #define PR_CAP_AMBIENT_IS_SET 1 | 103 | #define PR_CAP_AMBIENT_IS_SET 1 |
104 | #define PR_CAP_AMBIENT_RAISE 2 | ||
105 | #define PR_CAP_AMBIENT_LOWER 3 | ||
103 | #endif | 106 | #endif |
104 | 107 | ||
105 | enum { | 108 | enum { |
106 | IF_FEATURE_SETPRIV_DUMP(OPTBIT_DUMP,) | 109 | IF_FEATURE_SETPRIV_DUMP(OPTBIT_DUMP,) |
107 | IF_FEATURE_SETPRIV_CAPABILITIES(OPTBIT_INH,) | 110 | IF_FEATURE_SETPRIV_CAPABILITIES(OPTBIT_INH,) |
111 | IF_FEATURE_SETPRIV_CAPABILITIES(OPTBIT_AMB,) | ||
108 | OPTBIT_NNP, | 112 | OPTBIT_NNP, |
109 | 113 | ||
110 | IF_FEATURE_SETPRIV_DUMP(OPT_DUMP = (1 << OPTBIT_DUMP),) | 114 | IF_FEATURE_SETPRIV_DUMP(OPT_DUMP = (1 << OPTBIT_DUMP),) |
111 | IF_FEATURE_SETPRIV_CAPABILITIES(OPT_INH = (1 << OPTBIT_INH),) | 115 | IF_FEATURE_SETPRIV_CAPABILITIES(OPT_INH = (1 << OPTBIT_INH),) |
116 | IF_FEATURE_SETPRIV_CAPABILITIES(OPT_AMB = (1 << OPTBIT_AMB),) | ||
112 | OPT_NNP = (1 << OPTBIT_NNP), | 117 | OPT_NNP = (1 << OPTBIT_NNP), |
113 | }; | 118 | }; |
114 | 119 | ||
@@ -313,16 +318,14 @@ static int dump(void) | |||
313 | #endif /* FEATURE_SETPRIV_DUMP */ | 318 | #endif /* FEATURE_SETPRIV_DUMP */ |
314 | 319 | ||
315 | #if ENABLE_FEATURE_SETPRIV_CAPABILITIES | 320 | #if ENABLE_FEATURE_SETPRIV_CAPABILITIES |
316 | static void parse_cap(unsigned long *index, int *add, const char *cap) | 321 | static void parse_cap(unsigned long *index, const char *cap) |
317 | { | 322 | { |
318 | unsigned long i; | 323 | unsigned long i; |
319 | 324 | ||
320 | switch (cap[0]) { | 325 | switch (cap[0]) { |
321 | case '-': | 326 | case '-': |
322 | *add = 0; | ||
323 | break; | 327 | break; |
324 | case '+': | 328 | case '+': |
325 | *add = 1; | ||
326 | break; | 329 | break; |
327 | default: | 330 | default: |
328 | bb_error_msg_and_die("invalid capability '%s'", cap); | 331 | bb_error_msg_and_die("invalid capability '%s'", cap); |
@@ -361,12 +364,12 @@ static void set_inh_caps(char *capstring) | |||
361 | capstring = strtok(capstring, ","); | 364 | capstring = strtok(capstring, ","); |
362 | while (capstring) { | 365 | while (capstring) { |
363 | unsigned long cap; | 366 | unsigned long cap; |
364 | int add; | ||
365 | 367 | ||
366 | parse_cap(&cap, &add, capstring); | 368 | parse_cap(&cap, capstring); |
367 | if (CAP_TO_INDEX(cap) >= caps.u32s) | 369 | if (CAP_TO_INDEX(cap) >= caps.u32s) |
368 | bb_error_msg_and_die("invalid capability cap"); | 370 | bb_error_msg_and_die("invalid capability cap"); |
369 | if (add) | 371 | |
372 | if (capstring[0] == '+') | ||
370 | caps.data[CAP_TO_INDEX(cap)].inheritable |= CAP_TO_MASK(cap); | 373 | caps.data[CAP_TO_INDEX(cap)].inheritable |= CAP_TO_MASK(cap); |
371 | else | 374 | else |
372 | caps.data[CAP_TO_INDEX(cap)].inheritable &= ~CAP_TO_MASK(cap); | 375 | caps.data[CAP_TO_INDEX(cap)].inheritable &= ~CAP_TO_MASK(cap); |
@@ -379,6 +382,26 @@ static void set_inh_caps(char *capstring) | |||
379 | if (ENABLE_FEATURE_CLEAN_UP) | 382 | if (ENABLE_FEATURE_CLEAN_UP) |
380 | free(caps.data); | 383 | free(caps.data); |
381 | } | 384 | } |
385 | |||
386 | static void set_ambient_caps(char *string) | ||
387 | { | ||
388 | char *cap; | ||
389 | |||
390 | cap = strtok(string, ","); | ||
391 | while (cap) { | ||
392 | unsigned long index; | ||
393 | |||
394 | parse_cap(&index, cap); | ||
395 | if (cap[0] == '+') { | ||
396 | if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, index, 0, 0) < 0) | ||
397 | bb_perror_msg("cap_ambient_raise"); | ||
398 | } else { | ||
399 | if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_LOWER, index, 0, 0) < 0) | ||
400 | bb_perror_msg("cap_ambient_lower"); | ||
401 | } | ||
402 | cap = strtok(NULL, ","); | ||
403 | } | ||
404 | } | ||
382 | #endif /* FEATURE_SETPRIV_CAPABILITIES */ | 405 | #endif /* FEATURE_SETPRIV_CAPABILITIES */ |
383 | 406 | ||
384 | int setpriv_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 407 | int setpriv_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
@@ -392,14 +415,15 @@ int setpriv_main(int argc UNUSED_PARAM, char **argv) | |||
392 | "no-new-privs\0" No_argument "\xff" | 415 | "no-new-privs\0" No_argument "\xff" |
393 | IF_FEATURE_SETPRIV_CAPABILITIES( | 416 | IF_FEATURE_SETPRIV_CAPABILITIES( |
394 | "inh-caps\0" Required_argument "\xfe" | 417 | "inh-caps\0" Required_argument "\xfe" |
418 | "ambient-caps\0" Required_argument "\xfd" | ||
395 | ) | 419 | ) |
396 | ; | 420 | ; |
397 | int opts; | 421 | int opts; |
398 | IF_FEATURE_SETPRIV_CAPABILITIES(char *inh_caps;) | 422 | IF_FEATURE_SETPRIV_CAPABILITIES(char *inh_caps, *ambient_caps;) |
399 | 423 | ||
400 | applet_long_options = setpriv_longopts; | 424 | applet_long_options = setpriv_longopts; |
401 | opts = getopt32(argv, "+"IF_FEATURE_SETPRIV_DUMP("d") | 425 | opts = getopt32(argv, "+"IF_FEATURE_SETPRIV_DUMP("d") |
402 | IF_FEATURE_SETPRIV_CAPABILITIES("\xfe:", &inh_caps)); | 426 | IF_FEATURE_SETPRIV_CAPABILITIES("\xfe:\xfd:", &inh_caps, &ambient_caps)); |
403 | argv += optind; | 427 | argv += optind; |
404 | 428 | ||
405 | #if ENABLE_FEATURE_SETPRIV_DUMP | 429 | #if ENABLE_FEATURE_SETPRIV_DUMP |
@@ -417,6 +441,8 @@ int setpriv_main(int argc UNUSED_PARAM, char **argv) | |||
417 | #if ENABLE_FEATURE_SETPRIV_CAPABILITIES | 441 | #if ENABLE_FEATURE_SETPRIV_CAPABILITIES |
418 | if (opts & OPT_INH) | 442 | if (opts & OPT_INH) |
419 | set_inh_caps(inh_caps); | 443 | set_inh_caps(inh_caps); |
444 | if (opts & OPT_AMB) | ||
445 | set_ambient_caps(ambient_caps); | ||
420 | #endif | 446 | #endif |
421 | 447 | ||
422 | if (!argv[0]) | 448 | if (!argv[0]) |