diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2011-05-16 13:19:25 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2011-05-16 13:19:25 +0200 |
commit | 3770b6b06168d9971b3583924a6ddf01b28c8745 (patch) | |
tree | b765350a7f3c39476e08a63f73455a8e38b0a7ca /libbb/appletlib.c | |
parent | 9be4702a304863095d20181b5632ee7e0a4acdc4 (diff) | |
download | busybox-w32-3770b6b06168d9971b3583924a6ddf01b28c8745.tar.gz busybox-w32-3770b6b06168d9971b3583924a6ddf01b28c8745.tar.bz2 busybox-w32-3770b6b06168d9971b3583924a6ddf01b28c8745.zip |
main: make busybox.conf mode handling less obscure
function old new delta
static.mode_mask - 20 +20
main 782 785 +3
static.mode_chars 15 13 -2
run_applet_no_and_exit 450 441 -9
mode_mask 24 - -24
------------------------------------------------------------------------------
(add/remove: 2/2 grow/shrink: 1/2 up/down: 41/-53) Total: -12 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'libbb/appletlib.c')
-rw-r--r-- | libbb/appletlib.c | 67 |
1 files changed, 34 insertions, 33 deletions
diff --git a/libbb/appletlib.c b/libbb/appletlib.c index 269cc5bbf..ed60a1a0a 100644 --- a/libbb/appletlib.c +++ b/libbb/appletlib.c | |||
@@ -281,21 +281,11 @@ static char *get_trimmed_slice(char *s, char *e) | |||
281 | return skip_whitespace(s); | 281 | return skip_whitespace(s); |
282 | } | 282 | } |
283 | 283 | ||
284 | /* Don't depend on the tools to combine strings. */ | ||
285 | static const char config_file[] ALIGN1 = "/etc/busybox.conf"; | ||
286 | |||
287 | /* We don't supply a value for the nul, so an index adjustment is | ||
288 | * necessary below. Also, we use unsigned short here to save some | ||
289 | * space even though these are really mode_t values. */ | ||
290 | static const unsigned short mode_mask[] ALIGN2 = { | ||
291 | /* SST sst xxx --- */ | ||
292 | S_ISUID, S_ISUID|S_IXUSR, S_IXUSR, 0, /* user */ | ||
293 | S_ISGID, S_ISGID|S_IXGRP, S_IXGRP, 0, /* group */ | ||
294 | 0, S_IXOTH, S_IXOTH, 0 /* other */ | ||
295 | }; | ||
296 | |||
297 | static void parse_config_file(void) | 284 | static void parse_config_file(void) |
298 | { | 285 | { |
286 | /* Don't depend on the tools to combine strings. */ | ||
287 | static const char config_file[] ALIGN1 = "/etc/busybox.conf"; | ||
288 | |||
299 | struct suid_config_t *sct_head; | 289 | struct suid_config_t *sct_head; |
300 | int applet_no; | 290 | int applet_no; |
301 | FILE *f; | 291 | FILE *f; |
@@ -411,7 +401,7 @@ static void parse_config_file(void) | |||
411 | * up when the busybox configuration is changed. */ | 401 | * up when the busybox configuration is changed. */ |
412 | applet_no = find_applet_by_name(s); | 402 | applet_no = find_applet_by_name(s); |
413 | if (applet_no >= 0) { | 403 | if (applet_no >= 0) { |
414 | int i; | 404 | unsigned i; |
415 | struct suid_config_t *sct; | 405 | struct suid_config_t *sct; |
416 | 406 | ||
417 | /* Note: We currently don't check for duplicates! | 407 | /* Note: We currently don't check for duplicates! |
@@ -429,17 +419,24 @@ static void parse_config_file(void) | |||
429 | e = skip_whitespace(e+1); | 419 | e = skip_whitespace(e+1); |
430 | 420 | ||
431 | for (i = 0; i < 3; i++) { | 421 | for (i = 0; i < 3; i++) { |
432 | /* There are 4 chars + 1 nul for each of user/group/other. */ | 422 | /* There are 4 chars for each of user/group/other. |
433 | static const char mode_chars[] ALIGN1 = "Ssx-\0" "Ssx-\0" "Ttx-"; | 423 | * "x-xx" instead of "x-" are to make |
434 | 424 | * "idx > 3" check catch invalid chars. | |
435 | const char *q; | 425 | */ |
436 | q = strchrnul(mode_chars + 5*i, *e++); | 426 | static const char mode_chars[] ALIGN1 = "Ssx-" "Ssx-" "x-xx"; |
437 | if (!*q) { | 427 | static const unsigned short mode_mask[] ALIGN2 = { |
428 | S_ISUID, S_ISUID|S_IXUSR, S_IXUSR, 0, /* Ssx- */ | ||
429 | S_ISGID, S_ISGID|S_IXGRP, S_IXGRP, 0, /* Ssx- */ | ||
430 | S_IXOTH, 0 /* x- */ | ||
431 | }; | ||
432 | const char *q = strchrnul(mode_chars + 4*i, *e); | ||
433 | unsigned idx = q - (mode_chars + 4*i); | ||
434 | if (idx > 3) { | ||
438 | errmsg = "mode"; | 435 | errmsg = "mode"; |
439 | goto pe_label; | 436 | goto pe_label; |
440 | } | 437 | } |
441 | /* Adjust by -i to account for nul. */ | 438 | sct->m_mode |= mode_mask[q - mode_chars]; |
442 | sct->m_mode |= mode_mask[(q - mode_chars) - i]; | 439 | e++; |
443 | } | 440 | } |
444 | 441 | ||
445 | /* Now get the user/group info. */ | 442 | /* Now get the user/group info. */ |
@@ -512,6 +509,7 @@ static void check_suid(int applet_no) | |||
512 | } | 509 | } |
513 | goto check_need_suid; | 510 | goto check_need_suid; |
514 | found: | 511 | found: |
512 | /* Is this user allowed to run this applet? */ | ||
515 | m = sct->m_mode; | 513 | m = sct->m_mode; |
516 | if (sct->m_ugid.uid == ruid) | 514 | if (sct->m_ugid.uid == ruid) |
517 | /* same uid */ | 515 | /* same uid */ |
@@ -519,28 +517,31 @@ static void check_suid(int applet_no) | |||
519 | else if ((sct->m_ugid.gid == rgid) || ingroup(ruid, sct->m_ugid.gid)) | 517 | else if ((sct->m_ugid.gid == rgid) || ingroup(ruid, sct->m_ugid.gid)) |
520 | /* same group / in group */ | 518 | /* same group / in group */ |
521 | m >>= 3; | 519 | m >>= 3; |
522 | 520 | if (!(m & S_IXOTH)) /* is x bit not set? */ | |
523 | if (!(m & S_IXOTH)) /* is x bit not set ? */ | ||
524 | bb_error_msg_and_die("you have no permission to run this applet!"); | 521 | bb_error_msg_and_die("you have no permission to run this applet!"); |
525 | 522 | ||
526 | /* _both_ sgid and group_exec have to be set for setegid */ | ||
527 | if ((sct->m_mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) | ||
528 | rgid = sct->m_ugid.gid; | ||
529 | /* else (no setegid) we will set egid = rgid */ | ||
530 | |||
531 | /* We set effective AND saved ids. If saved-id is not set | 523 | /* We set effective AND saved ids. If saved-id is not set |
532 | * like we do below, seteiud(0) can still later succeed! */ | 524 | * like we do below, seteuid(0) can still later succeed! */ |
525 | |||
526 | /* Are we directed to change gid | ||
527 | * (APPLET = *s* USER.GROUP or APPLET = *S* USER.GROUP)? | ||
528 | */ | ||
529 | if (sct->m_mode & S_ISGID) | ||
530 | rgid = sct->m_ugid.gid; | ||
531 | /* else: we will set egid = rgid, thus dropping sgid effect */ | ||
533 | if (setresgid(-1, rgid, rgid)) | 532 | if (setresgid(-1, rgid, rgid)) |
534 | bb_perror_msg_and_die("setresgid"); | 533 | bb_perror_msg_and_die("setresgid"); |
535 | 534 | ||
536 | /* do we have to set effective uid? */ | 535 | /* Are we directed to change uid |
536 | * (APPLET = s** USER.GROUP or APPLET = S** USER.GROUP)? | ||
537 | */ | ||
537 | uid = ruid; | 538 | uid = ruid; |
538 | if (sct->m_mode & S_ISUID) | 539 | if (sct->m_mode & S_ISUID) |
539 | uid = sct->m_ugid.uid; | 540 | uid = sct->m_ugid.uid; |
540 | /* else (no seteuid) we will set euid = ruid */ | 541 | /* else: we will set euid = ruid, thus dropping suid effect */ |
541 | |||
542 | if (setresuid(-1, uid, uid)) | 542 | if (setresuid(-1, uid, uid)) |
543 | bb_perror_msg_and_die("setresuid"); | 543 | bb_perror_msg_and_die("setresuid"); |
544 | |||
544 | goto ret; | 545 | goto ret; |
545 | } | 546 | } |
546 | # if !ENABLE_FEATURE_SUID_CONFIG_QUIET | 547 | # if !ENABLE_FEATURE_SUID_CONFIG_QUIET |