aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--util-linux/setpriv.c44
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
105enum { 108enum {
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
316static void parse_cap(unsigned long *index, int *add, const char *cap) 321static 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
386static 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
384int setpriv_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 407int 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])