diff options
author | Ron Yorston <rmy@pobox.com> | 2012-03-22 15:21:20 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2012-03-22 15:21:20 +0000 |
commit | 0d8b2c4a929ea9d3ac37499319fe0d8e7941a0c2 (patch) | |
tree | 6709ddd6071a9c238ba69233540bbcfe560c6a44 /libbb/appletlib.c | |
parent | 67758035a4fe040c6ac69b39d61bcd6bddd7b827 (diff) | |
parent | 56a3b82e9692a25ef9c9269e88feac0d579ce8e8 (diff) | |
download | busybox-w32-0d8b2c4a929ea9d3ac37499319fe0d8e7941a0c2.tar.gz busybox-w32-0d8b2c4a929ea9d3ac37499319fe0d8e7941a0c2.tar.bz2 busybox-w32-0d8b2c4a929ea9d3ac37499319fe0d8e7941a0c2.zip |
Merge commit '56a3b82e9692a25ef9c9269e88feac0d579ce8e8' into merge
Conflicts:
coreutils/ls.c
include/platform.h
libbb/bb_basename.c
Diffstat (limited to 'libbb/appletlib.c')
-rw-r--r-- | libbb/appletlib.c | 213 |
1 files changed, 97 insertions, 116 deletions
diff --git a/libbb/appletlib.c b/libbb/appletlib.c index a934f11bb..d4025b9c7 100644 --- a/libbb/appletlib.c +++ b/libbb/appletlib.c | |||
@@ -27,12 +27,13 @@ | |||
27 | * FEATURE_INSTALLER or FEATURE_SUID will still link printf routines in. :( | 27 | * FEATURE_INSTALLER or FEATURE_SUID will still link printf routines in. :( |
28 | */ | 28 | */ |
29 | #include "busybox.h" | 29 | #include "busybox.h" |
30 | #include <assert.h> | 30 | |
31 | #if !(defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) \ | 31 | #if !(defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) \ |
32 | || defined(__APPLE__) \ | 32 | || defined(__APPLE__) \ |
33 | ) | 33 | ) |
34 | # include <malloc.h> /* for mallopt */ | 34 | # include <malloc.h> /* for mallopt */ |
35 | #endif | 35 | #endif |
36 | |||
36 | /* Try to pull in PAGE_SIZE */ | 37 | /* Try to pull in PAGE_SIZE */ |
37 | #ifdef __linux__ | 38 | #ifdef __linux__ |
38 | # include <sys/user.h> | 39 | # include <sys/user.h> |
@@ -40,6 +41,9 @@ | |||
40 | #ifdef __GNU__ /* Hurd */ | 41 | #ifdef __GNU__ /* Hurd */ |
41 | # include <mach/vm_param.h> | 42 | # include <mach/vm_param.h> |
42 | #endif | 43 | #endif |
44 | #ifndef PAGE_SIZE | ||
45 | # define PAGE_SIZE (4*1024) /* guess */ | ||
46 | #endif | ||
43 | 47 | ||
44 | 48 | ||
45 | /* Declare <applet>_main() */ | 49 | /* Declare <applet>_main() */ |
@@ -47,7 +51,6 @@ | |||
47 | #include "applets.h" | 51 | #include "applets.h" |
48 | #undef PROTOTYPES | 52 | #undef PROTOTYPES |
49 | 53 | ||
50 | |||
51 | /* Include generated applet names, pointers to <applet>_main, etc */ | 54 | /* Include generated applet names, pointers to <applet>_main, etc */ |
52 | #include "applet_tables.h" | 55 | #include "applet_tables.h" |
53 | /* ...and if applet_tables generator says we have only one applet... */ | 56 | /* ...and if applet_tables generator says we have only one applet... */ |
@@ -58,9 +61,9 @@ | |||
58 | # define IF_FEATURE_INDIVIDUAL(...) __VA_ARGS__ | 61 | # define IF_FEATURE_INDIVIDUAL(...) __VA_ARGS__ |
59 | #endif | 62 | #endif |
60 | 63 | ||
61 | |||
62 | #include "usage_compressed.h" | 64 | #include "usage_compressed.h" |
63 | 65 | ||
66 | |||
64 | #if ENABLE_SHOW_USAGE && !ENABLE_FEATURE_COMPRESS_USAGE | 67 | #if ENABLE_SHOW_USAGE && !ENABLE_FEATURE_COMPRESS_USAGE |
65 | static const char usage_messages[] ALIGN1 = UNPACKED_USAGE; | 68 | static const char usage_messages[] ALIGN1 = UNPACKED_USAGE; |
66 | #else | 69 | #else |
@@ -233,13 +236,12 @@ IF_FEATURE_SUID(static uid_t ruid;) /* real uid */ | |||
233 | 236 | ||
234 | # if ENABLE_FEATURE_SUID_CONFIG | 237 | # if ENABLE_FEATURE_SUID_CONFIG |
235 | 238 | ||
236 | /* applets[] is const, so we have to define this "override" structure */ | 239 | static struct suid_config_t { |
237 | static struct BB_suid_config { | 240 | /* next ptr must be first: this struct needs to be llist-compatible */ |
241 | struct suid_config_t *m_next; | ||
242 | struct bb_uidgid_t m_ugid; | ||
238 | int m_applet; | 243 | int m_applet; |
239 | uid_t m_uid; | ||
240 | gid_t m_gid; | ||
241 | mode_t m_mode; | 244 | mode_t m_mode; |
242 | struct BB_suid_config *m_next; | ||
243 | } *suid_config; | 245 | } *suid_config; |
244 | 246 | ||
245 | static bool suid_cfg_readable; | 247 | static bool suid_cfg_readable; |
@@ -248,13 +250,10 @@ static bool suid_cfg_readable; | |||
248 | static int ingroup(uid_t u, gid_t g) | 250 | static int ingroup(uid_t u, gid_t g) |
249 | { | 251 | { |
250 | struct group *grp = getgrgid(g); | 252 | struct group *grp = getgrgid(g); |
251 | |||
252 | if (grp) { | 253 | if (grp) { |
253 | char **mem; | 254 | char **mem; |
254 | |||
255 | for (mem = grp->gr_mem; *mem; mem++) { | 255 | for (mem = grp->gr_mem; *mem; mem++) { |
256 | struct passwd *pwd = getpwnam(*mem); | 256 | struct passwd *pwd = getpwnam(*mem); |
257 | |||
258 | if (pwd && (pwd->pw_uid == u)) | 257 | if (pwd && (pwd->pw_uid == u)) |
259 | return 1; | 258 | return 1; |
260 | } | 259 | } |
@@ -262,9 +261,7 @@ static int ingroup(uid_t u, gid_t g) | |||
262 | return 0; | 261 | return 0; |
263 | } | 262 | } |
264 | 263 | ||
265 | /* This should probably be a libbb routine. In that case, | 264 | /* libbb candidate */ |
266 | * I'd probably rename it to something like bb_trimmed_slice. | ||
267 | */ | ||
268 | static char *get_trimmed_slice(char *s, char *e) | 265 | static char *get_trimmed_slice(char *s, char *e) |
269 | { | 266 | { |
270 | /* First, consider the value at e to be nul and back up until we | 267 | /* First, consider the value at e to be nul and back up until we |
@@ -282,38 +279,19 @@ static char *get_trimmed_slice(char *s, char *e) | |||
282 | return skip_whitespace(s); | 279 | return skip_whitespace(s); |
283 | } | 280 | } |
284 | 281 | ||
285 | /* Don't depend on the tools to combine strings. */ | ||
286 | static const char config_file[] ALIGN1 = "/etc/busybox.conf"; | ||
287 | |||
288 | /* We don't supply a value for the nul, so an index adjustment is | ||
289 | * necessary below. Also, we use unsigned short here to save some | ||
290 | * space even though these are really mode_t values. */ | ||
291 | static const unsigned short mode_mask[] ALIGN2 = { | ||
292 | /* SST sst xxx --- */ | ||
293 | S_ISUID, S_ISUID|S_IXUSR, S_IXUSR, 0, /* user */ | ||
294 | S_ISGID, S_ISGID|S_IXGRP, S_IXGRP, 0, /* group */ | ||
295 | 0, S_IXOTH, S_IXOTH, 0 /* other */ | ||
296 | }; | ||
297 | |||
298 | #define parse_error(x) do { errmsg = x; goto pe_label; } while (0) | ||
299 | |||
300 | static void parse_config_file(void) | 282 | static void parse_config_file(void) |
301 | { | 283 | { |
302 | struct BB_suid_config *sct_head; | 284 | /* Don't depend on the tools to combine strings. */ |
303 | struct BB_suid_config *sct; | 285 | static const char config_file[] ALIGN1 = "/etc/busybox.conf"; |
286 | |||
287 | struct suid_config_t *sct_head; | ||
304 | int applet_no; | 288 | int applet_no; |
305 | FILE *f; | 289 | FILE *f; |
306 | const char *errmsg; | 290 | const char *errmsg; |
307 | char *s; | ||
308 | char *e; | ||
309 | int i; | ||
310 | unsigned lc; | 291 | unsigned lc; |
311 | smallint section; | 292 | smallint section; |
312 | char buffer[256]; | ||
313 | struct stat st; | 293 | struct stat st; |
314 | 294 | ||
315 | assert(!suid_config); /* Should be set to NULL by bss init. */ | ||
316 | |||
317 | ruid = getuid(); | 295 | ruid = getuid(); |
318 | if (ruid == 0) /* run by root - don't need to even read config file */ | 296 | if (ruid == 0) /* run by root - don't need to even read config file */ |
319 | return; | 297 | return; |
@@ -322,7 +300,7 @@ static void parse_config_file(void) | |||
322 | || !S_ISREG(st.st_mode) /* Not a regular file? */ | 300 | || !S_ISREG(st.st_mode) /* Not a regular file? */ |
323 | || (st.st_uid != 0) /* Not owned by root? */ | 301 | || (st.st_uid != 0) /* Not owned by root? */ |
324 | || (st.st_mode & (S_IWGRP | S_IWOTH)) /* Writable by non-root? */ | 302 | || (st.st_mode & (S_IWGRP | S_IWOTH)) /* Writable by non-root? */ |
325 | || !(f = fopen_for_read(config_file)) /* Cannot open? */ | 303 | || !(f = fopen_for_read(config_file)) /* Cannot open? */ |
326 | ) { | 304 | ) { |
327 | return; | 305 | return; |
328 | } | 306 | } |
@@ -332,18 +310,21 @@ static void parse_config_file(void) | |||
332 | section = lc = 0; | 310 | section = lc = 0; |
333 | 311 | ||
334 | while (1) { | 312 | while (1) { |
335 | s = buffer; | 313 | char buffer[256]; |
336 | 314 | char *s; | |
337 | if (!fgets(s, sizeof(buffer), f)) { /* Are we done? */ | 315 | |
338 | // why? | 316 | if (!fgets(buffer, sizeof(buffer), f)) { /* Are we done? */ |
339 | if (ferror(f)) { /* Make sure it wasn't a read error. */ | 317 | // Looks like bloat |
340 | parse_error("reading"); | 318 | //if (ferror(f)) { /* Make sure it wasn't a read error. */ |
341 | } | 319 | // errmsg = "reading"; |
320 | // goto pe_label; | ||
321 | //} | ||
342 | fclose(f); | 322 | fclose(f); |
343 | suid_config = sct_head; /* Success, so set the pointer. */ | 323 | suid_config = sct_head; /* Success, so set the pointer. */ |
344 | return; | 324 | return; |
345 | } | 325 | } |
346 | 326 | ||
327 | s = buffer; | ||
347 | lc++; /* Got a (partial) line. */ | 328 | lc++; /* Got a (partial) line. */ |
348 | 329 | ||
349 | /* If a line is too long for our buffer, we consider it an error. | 330 | /* If a line is too long for our buffer, we consider it an error. |
@@ -355,7 +336,8 @@ static void parse_config_file(void) | |||
355 | * we do err on the side of caution. Besides, the line would be | 336 | * we do err on the side of caution. Besides, the line would be |
356 | * too long if it did end with a newline. */ | 337 | * too long if it did end with a newline. */ |
357 | if (!strchr(s, '\n') && !feof(f)) { | 338 | if (!strchr(s, '\n') && !feof(f)) { |
358 | parse_error("line too long"); | 339 | errmsg = "line too long"; |
340 | goto pe_label; | ||
359 | } | 341 | } |
360 | 342 | ||
361 | /* Trim leading and trailing whitespace, ignoring comments, and | 343 | /* Trim leading and trailing whitespace, ignoring comments, and |
@@ -371,12 +353,13 @@ static void parse_config_file(void) | |||
371 | /* Unlike the old code, we ignore leading and trailing | 353 | /* Unlike the old code, we ignore leading and trailing |
372 | * whitespace for the section name. We also require that | 354 | * whitespace for the section name. We also require that |
373 | * there are no stray characters after the closing bracket. */ | 355 | * there are no stray characters after the closing bracket. */ |
374 | e = strchr(s, ']'); | 356 | char *e = strchr(s, ']'); |
375 | if (!e /* Missing right bracket? */ | 357 | if (!e /* Missing right bracket? */ |
376 | || e[1] /* Trailing characters? */ | 358 | || e[1] /* Trailing characters? */ |
377 | || !*(s = get_trimmed_slice(s+1, e)) /* Missing name? */ | 359 | || !*(s = get_trimmed_slice(s+1, e)) /* Missing name? */ |
378 | ) { | 360 | ) { |
379 | parse_error("section header"); | 361 | errmsg = "section header"; |
362 | goto pe_label; | ||
380 | } | 363 | } |
381 | /* Right now we only have one section so just check it. | 364 | /* Right now we only have one section so just check it. |
382 | * If more sections are added in the future, please don't | 365 | * If more sections are added in the future, please don't |
@@ -401,12 +384,13 @@ static void parse_config_file(void) | |||
401 | * where both key and value could contain inner whitespace. */ | 384 | * where both key and value could contain inner whitespace. */ |
402 | 385 | ||
403 | /* First get the key (an applet name in our case). */ | 386 | /* First get the key (an applet name in our case). */ |
404 | e = strchr(s, '='); | 387 | char *e = strchr(s, '='); |
405 | if (e) { | 388 | if (e) { |
406 | s = get_trimmed_slice(s, e); | 389 | s = get_trimmed_slice(s, e); |
407 | } | 390 | } |
408 | if (!e || !*s) { /* Missing '=' or empty key. */ | 391 | if (!e || !*s) { /* Missing '=' or empty key. */ |
409 | parse_error("keyword"); | 392 | errmsg = "keyword"; |
393 | goto pe_label; | ||
410 | } | 394 | } |
411 | 395 | ||
412 | /* Ok, we have an applet name. Process the rhs if this | 396 | /* Ok, we have an applet name. Process the rhs if this |
@@ -415,13 +399,16 @@ static void parse_config_file(void) | |||
415 | * up when the busybox configuration is changed. */ | 399 | * up when the busybox configuration is changed. */ |
416 | applet_no = find_applet_by_name(s); | 400 | applet_no = find_applet_by_name(s); |
417 | if (applet_no >= 0) { | 401 | if (applet_no >= 0) { |
402 | unsigned i; | ||
403 | struct suid_config_t *sct; | ||
404 | |||
418 | /* Note: We currently don't check for duplicates! | 405 | /* Note: We currently don't check for duplicates! |
419 | * The last config line for each applet will be the | 406 | * The last config line for each applet will be the |
420 | * one used since we insert at the head of the list. | 407 | * one used since we insert at the head of the list. |
421 | * I suppose this could be considered a feature. */ | 408 | * I suppose this could be considered a feature. */ |
422 | sct = xmalloc(sizeof(struct BB_suid_config)); | 409 | sct = xzalloc(sizeof(*sct)); |
423 | sct->m_applet = applet_no; | 410 | sct->m_applet = applet_no; |
424 | sct->m_mode = 0; | 411 | /*sct->m_mode = 0;*/ |
425 | sct->m_next = sct_head; | 412 | sct->m_next = sct_head; |
426 | sct_head = sct; | 413 | sct_head = sct; |
427 | 414 | ||
@@ -430,48 +417,41 @@ static void parse_config_file(void) | |||
430 | e = skip_whitespace(e+1); | 417 | e = skip_whitespace(e+1); |
431 | 418 | ||
432 | for (i = 0; i < 3; i++) { | 419 | for (i = 0; i < 3; i++) { |
433 | /* There are 4 chars + 1 nul for each of user/group/other. */ | 420 | /* There are 4 chars for each of user/group/other. |
434 | static const char mode_chars[] ALIGN1 = "Ssx-\0" "Ssx-\0" "Ttx-"; | 421 | * "x-xx" instead of "x-" are to make |
435 | 422 | * "idx > 3" check catch invalid chars. | |
436 | const char *q; | 423 | */ |
437 | q = strchrnul(mode_chars + 5*i, *e++); | 424 | static const char mode_chars[] ALIGN1 = "Ssx-" "Ssx-" "x-xx"; |
438 | if (!*q) { | 425 | static const unsigned short mode_mask[] ALIGN2 = { |
439 | parse_error("mode"); | 426 | S_ISUID, S_ISUID|S_IXUSR, S_IXUSR, 0, /* Ssx- */ |
427 | S_ISGID, S_ISGID|S_IXGRP, S_IXGRP, 0, /* Ssx- */ | ||
428 | S_IXOTH, 0 /* x- */ | ||
429 | }; | ||
430 | const char *q = strchrnul(mode_chars + 4*i, *e); | ||
431 | unsigned idx = q - (mode_chars + 4*i); | ||
432 | if (idx > 3) { | ||
433 | errmsg = "mode"; | ||
434 | goto pe_label; | ||
440 | } | 435 | } |
441 | /* Adjust by -i to account for nul. */ | 436 | sct->m_mode |= mode_mask[q - mode_chars]; |
442 | sct->m_mode |= mode_mask[(q - mode_chars) - i]; | 437 | e++; |
443 | } | 438 | } |
444 | 439 | ||
445 | /* Now get the user/group info. */ | 440 | /* Now get the user/group info. */ |
446 | 441 | ||
447 | s = skip_whitespace(e); | 442 | s = skip_whitespace(e); |
448 | 443 | /* Default is 0.0, else parse USER.GROUP: */ | |
449 | /* Note: we require whitespace between the mode and the | 444 | if (*s) { |
450 | * user/group info. */ | 445 | /* We require whitespace between mode and USER.GROUP */ |
451 | if ((s == e) || !(e = strchr(s, '.'))) { | 446 | if ((s == e) || !(e = strchr(s, '.'))) { |
452 | parse_error("<uid>.<gid>"); | 447 | errmsg = "uid.gid"; |
453 | } | 448 | goto pe_label; |
454 | *e++ = '\0'; | ||
455 | |||
456 | /* We can't use get_ug_id here since it would exit() | ||
457 | * if a uid or gid was not found. Oh well... */ | ||
458 | sct->m_uid = bb_strtoul(s, NULL, 10); | ||
459 | if (errno) { | ||
460 | struct passwd *pwd = getpwnam(s); | ||
461 | if (!pwd) { | ||
462 | parse_error("user"); | ||
463 | } | 449 | } |
464 | sct->m_uid = pwd->pw_uid; | 450 | *e = ':'; /* get_uidgid needs USER:GROUP syntax */ |
465 | } | 451 | if (get_uidgid(&sct->m_ugid, s, /*allow_numeric:*/ 1) == 0) { |
466 | 452 | errmsg = "unknown user/group"; | |
467 | sct->m_gid = bb_strtoul(e, NULL, 10); | 453 | goto pe_label; |
468 | if (errno) { | ||
469 | struct group *grp; | ||
470 | grp = getgrnam(e); | ||
471 | if (!grp) { | ||
472 | parse_error("group"); | ||
473 | } | 454 | } |
474 | sct->m_gid = grp->gr_gid; | ||
475 | } | 455 | } |
476 | } | 456 | } |
477 | continue; | 457 | continue; |
@@ -485,22 +465,18 @@ static void parse_config_file(void) | |||
485 | * We may want to simply ignore such lines in case they | 465 | * We may want to simply ignore such lines in case they |
486 | * are used in some future version of busybox. */ | 466 | * are used in some future version of busybox. */ |
487 | if (!section) { | 467 | if (!section) { |
488 | parse_error("keyword outside section"); | 468 | errmsg = "keyword outside section"; |
469 | goto pe_label; | ||
489 | } | 470 | } |
490 | 471 | ||
491 | } /* while (1) */ | 472 | } /* while (1) */ |
492 | 473 | ||
493 | pe_label: | 474 | pe_label: |
494 | fprintf(stderr, "Parse error in %s, line %d: %s\n", | ||
495 | config_file, lc, errmsg); | ||
496 | |||
497 | fclose(f); | 475 | fclose(f); |
476 | bb_error_msg("parse error in %s, line %u: %s", config_file, lc, errmsg); | ||
477 | |||
498 | /* Release any allocated memory before returning. */ | 478 | /* Release any allocated memory before returning. */ |
499 | while (sct_head) { | 479 | llist_free((llist_t*)sct_head, NULL); |
500 | sct = sct_head->m_next; | ||
501 | free(sct_head); | ||
502 | sct_head = sct; | ||
503 | } | ||
504 | } | 480 | } |
505 | # else | 481 | # else |
506 | static inline void parse_config_file(void) | 482 | static inline void parse_config_file(void) |
@@ -522,7 +498,7 @@ static void check_suid(int applet_no) | |||
522 | # if ENABLE_FEATURE_SUID_CONFIG | 498 | # if ENABLE_FEATURE_SUID_CONFIG |
523 | if (suid_cfg_readable) { | 499 | if (suid_cfg_readable) { |
524 | uid_t uid; | 500 | uid_t uid; |
525 | struct BB_suid_config *sct; | 501 | struct suid_config_t *sct; |
526 | mode_t m; | 502 | mode_t m; |
527 | 503 | ||
528 | for (sct = suid_config; sct; sct = sct->m_next) { | 504 | for (sct = suid_config; sct; sct = sct->m_next) { |
@@ -531,36 +507,40 @@ static void check_suid(int applet_no) | |||
531 | } | 507 | } |
532 | goto check_need_suid; | 508 | goto check_need_suid; |
533 | found: | 509 | found: |
510 | /* Is this user allowed to run this applet? */ | ||
534 | m = sct->m_mode; | 511 | m = sct->m_mode; |
535 | if (sct->m_uid == ruid) | 512 | if (sct->m_ugid.uid == ruid) |
536 | /* same uid */ | 513 | /* same uid */ |
537 | m >>= 6; | 514 | m >>= 6; |
538 | else if ((sct->m_gid == rgid) || ingroup(ruid, sct->m_gid)) | 515 | else if ((sct->m_ugid.gid == rgid) || ingroup(ruid, sct->m_ugid.gid)) |
539 | /* same group / in group */ | 516 | /* same group / in group */ |
540 | m >>= 3; | 517 | m >>= 3; |
541 | 518 | if (!(m & S_IXOTH)) /* is x bit not set? */ | |
542 | if (!(m & S_IXOTH)) /* is x bit not set ? */ | 519 | bb_error_msg_and_die("you have no permission to run this applet"); |
543 | bb_error_msg_and_die("you have no permission to run this applet!"); | ||
544 | |||
545 | /* _both_ sgid and group_exec have to be set for setegid */ | ||
546 | if ((sct->m_mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) | ||
547 | rgid = sct->m_gid; | ||
548 | /* else (no setegid) we will set egid = rgid */ | ||
549 | 520 | ||
550 | /* We set effective AND saved ids. If saved-id is not set | 521 | /* We set effective AND saved ids. If saved-id is not set |
551 | * like we do below, seteiud(0) can still later succeed! */ | 522 | * like we do below, seteuid(0) can still later succeed! */ |
523 | |||
524 | /* Are we directed to change gid | ||
525 | * (APPLET = *s* USER.GROUP or APPLET = *S* USER.GROUP)? | ||
526 | */ | ||
527 | if (sct->m_mode & S_ISGID) | ||
528 | rgid = sct->m_ugid.gid; | ||
529 | /* else: we will set egid = rgid, thus dropping sgid effect */ | ||
552 | if (setresgid(-1, rgid, rgid)) | 530 | if (setresgid(-1, rgid, rgid)) |
553 | bb_perror_msg_and_die("setresgid"); | 531 | bb_perror_msg_and_die("setresgid"); |
554 | 532 | ||
555 | /* do we have to set effective uid? */ | 533 | /* Are we directed to change uid |
534 | * (APPLET = s** USER.GROUP or APPLET = S** USER.GROUP)? | ||
535 | */ | ||
556 | uid = ruid; | 536 | uid = ruid; |
557 | if (sct->m_mode & S_ISUID) | 537 | if (sct->m_mode & S_ISUID) |
558 | uid = sct->m_uid; | 538 | uid = sct->m_ugid.uid; |
559 | /* else (no seteuid) we will set euid = ruid */ | 539 | /* else: we will set euid = ruid, thus dropping suid effect */ |
560 | |||
561 | if (setresuid(-1, uid, uid)) | 540 | if (setresuid(-1, uid, uid)) |
562 | bb_perror_msg_and_die("setresuid"); | 541 | bb_perror_msg_and_die("setresuid"); |
563 | return; | 542 | |
543 | goto ret; | ||
564 | } | 544 | } |
565 | # if !ENABLE_FEATURE_SUID_CONFIG_QUIET | 545 | # if !ENABLE_FEATURE_SUID_CONFIG_QUIET |
566 | { | 546 | { |
@@ -568,7 +548,7 @@ static void check_suid(int applet_no) | |||
568 | 548 | ||
569 | if (!onetime) { | 549 | if (!onetime) { |
570 | onetime = 1; | 550 | onetime = 1; |
571 | fprintf(stderr, "Using fallback suid method\n"); | 551 | bb_error_msg("using fallback suid method"); |
572 | } | 552 | } |
573 | } | 553 | } |
574 | # endif | 554 | # endif |
@@ -583,6 +563,10 @@ static void check_suid(int applet_no) | |||
583 | xsetgid(rgid); /* drop all privileges */ | 563 | xsetgid(rgid); /* drop all privileges */ |
584 | xsetuid(ruid); | 564 | xsetuid(ruid); |
585 | } | 565 | } |
566 | # if ENABLE_FEATURE_SUID_CONFIG | ||
567 | ret: ; | ||
568 | llist_free((llist_t*)suid_config, NULL); | ||
569 | # endif | ||
586 | } | 570 | } |
587 | # else | 571 | # else |
588 | # define check_suid(x) ((void)0) | 572 | # define check_suid(x) ((void)0) |
@@ -799,9 +783,6 @@ int main(int argc UNUSED_PARAM, char **argv) | |||
799 | #endif | 783 | #endif |
800 | { | 784 | { |
801 | /* Tweak malloc for reduced memory consumption */ | 785 | /* Tweak malloc for reduced memory consumption */ |
802 | #ifndef PAGE_SIZE | ||
803 | # define PAGE_SIZE (4*1024) /* guess */ | ||
804 | #endif | ||
805 | #ifdef M_TRIM_THRESHOLD | 786 | #ifdef M_TRIM_THRESHOLD |
806 | /* M_TRIM_THRESHOLD is the maximum amount of freed top-most memory | 787 | /* M_TRIM_THRESHOLD is the maximum amount of freed top-most memory |
807 | * to keep before releasing to the OS | 788 | * to keep before releasing to the OS |