diff options
Diffstat (limited to 'applets')
-rw-r--r-- | applets/applets.c | 39 |
1 files changed, 25 insertions, 14 deletions
diff --git a/applets/applets.c b/applets/applets.c index 66bcc42de..32c63d1e0 100644 --- a/applets/applets.c +++ b/applets/applets.c | |||
@@ -110,9 +110,6 @@ static char *get_trimmed_slice(char *s, char *e) | |||
110 | /* Don't depend on the tools to combine strings. */ | 110 | /* Don't depend on the tools to combine strings. */ |
111 | static const char config_file[] = "/etc/busybox.conf"; | 111 | static const char config_file[] = "/etc/busybox.conf"; |
112 | 112 | ||
113 | /* There are 4 chars + 1 nul for each of user/group/other. */ | ||
114 | static const char mode_chars[] = "Ssx-\0Ssx-\0Ttx-"; | ||
115 | |||
116 | /* We don't supply a value for the nul, so an index adjustment is | 113 | /* We don't supply a value for the nul, so an index adjustment is |
117 | * necessary below. Also, we use unsigned short here to save some | 114 | * necessary below. Also, we use unsigned short here to save some |
118 | * space even though these are really mode_t values. */ | 115 | * space even though these are really mode_t values. */ |
@@ -257,6 +254,9 @@ static void parse_config_file(void) | |||
257 | e = skip_whitespace(e+1); | 254 | e = skip_whitespace(e+1); |
258 | 255 | ||
259 | for (i = 0; i < 3; i++) { | 256 | for (i = 0; i < 3; i++) { |
257 | /* There are 4 chars + 1 nul for each of user/group/other. */ | ||
258 | static const char mode_chars[] = "Ssx-\0" "Ssx-\0" "Ttx-"; | ||
259 | |||
260 | const char *q; | 260 | const char *q; |
261 | q = strchrnul(mode_chars + 5*i, *e++); | 261 | q = strchrnul(mode_chars + 5*i, *e++); |
262 | if (!*q) { | 262 | if (!*q) { |
@@ -337,7 +337,8 @@ static inline void parse_config_file(void) | |||
337 | #if ENABLE_FEATURE_SUID | 337 | #if ENABLE_FEATURE_SUID |
338 | static void check_suid(const struct bb_applet *applet) | 338 | static void check_suid(const struct bb_applet *applet) |
339 | { | 339 | { |
340 | uid_t rgid; /* real gid */ | 340 | uid_t uid; |
341 | gid_t rgid; /* real gid */ | ||
341 | 342 | ||
342 | if (ruid == 0) /* set by parse_config_file() */ | 343 | if (ruid == 0) /* set by parse_config_file() */ |
343 | return; /* run by root - no need to check more */ | 344 | return; /* run by root - no need to check more */ |
@@ -368,16 +369,24 @@ static void check_suid(const struct bb_applet *applet) | |||
368 | if (!(m & S_IXOTH)) /* is x bit not set ? */ | 369 | if (!(m & S_IXOTH)) /* is x bit not set ? */ |
369 | bb_error_msg_and_die("you have no permission to run this applet!"); | 370 | bb_error_msg_and_die("you have no permission to run this applet!"); |
370 | 371 | ||
371 | if (sct->m_gid != 0) { | 372 | /* _both_ sgid and group_exec have to be set for setegid */ |
372 | /* _both_ have to be set for sgid */ | 373 | if ((sct->m_mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) |
373 | if ((sct->m_mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) { | 374 | rgid = sct->m_gid; |
374 | xsetgid(sct->m_gid); | 375 | /* else (no setegid) we will set egid = rgid */ |
375 | } else xsetgid(rgid); /* no sgid -> drop */ | 376 | |
376 | } | 377 | /* We set effective AND saved ids. If saved-id is not set |
377 | if (sct->m_uid != 0) { | 378 | * like we do below, seteiud(0) can still later succeed! */ |
378 | if (sct->m_mode & S_ISUID) xsetuid(sct->m_uid); | 379 | if (setresgid(-1, rgid, rgid)) |
379 | else xsetuid(ruid); /* no suid -> drop */ | 380 | bb_perror_msg_and_die("setresgid"); |
380 | } | 381 | |
382 | /* do we have to set effective uid? */ | ||
383 | uid = ruid; | ||
384 | if (sct->m_mode & S_ISUID) | ||
385 | uid = sct->m_uid; | ||
386 | /* else (no seteuid) we will set euid = ruid */ | ||
387 | |||
388 | if (setresuid(-1, uid, uid)) | ||
389 | bb_perror_msg_and_die("setresuid"); | ||
381 | return; | 390 | return; |
382 | } | 391 | } |
383 | #if !ENABLE_FEATURE_SUID_CONFIG_QUIET | 392 | #if !ENABLE_FEATURE_SUID_CONFIG_QUIET |
@@ -393,6 +402,8 @@ static void check_suid(const struct bb_applet *applet) | |||
393 | #endif | 402 | #endif |
394 | 403 | ||
395 | if (applet->need_suid == _BB_SUID_ALWAYS) { | 404 | if (applet->need_suid == _BB_SUID_ALWAYS) { |
405 | /* Real uid is not 0. If euid isn't 0 too, suid bit | ||
406 | * is most probably not set on our executable */ | ||
396 | if (geteuid()) | 407 | if (geteuid()) |
397 | bb_error_msg_and_die("applet requires root privileges!"); | 408 | bb_error_msg_and_die("applet requires root privileges!"); |
398 | } else if (applet->need_suid == _BB_SUID_NEVER) { | 409 | } else if (applet->need_suid == _BB_SUID_NEVER) { |