diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-05-02 23:01:32 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-05-02 23:01:32 +0000 |
commit | 3bc18253b081cc0b73f902036416fea47f2b61e5 (patch) | |
tree | c1f857892931a55c1f651b44d8f0c60121ea8e43 | |
parent | f92df58d3d97bb75d7b12437d53dd97acfd01095 (diff) | |
download | busybox-w32-3bc18253b081cc0b73f902036416fea47f2b61e5.tar.gz busybox-w32-3bc18253b081cc0b73f902036416fea47f2b61e5.tar.bz2 busybox-w32-3bc18253b081cc0b73f902036416fea47f2b61e5.zip |
fix suid config handling
-rw-r--r-- | applets/applets.c | 39 | ||||
-rw-r--r-- | libbb/xfuncs.c | 4 |
2 files changed, 27 insertions, 16 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) { |
diff --git a/libbb/xfuncs.c b/libbb/xfuncs.c index 7e1109470..a85a046cf 100644 --- a/libbb/xfuncs.c +++ b/libbb/xfuncs.c | |||
@@ -386,13 +386,13 @@ char *bin2hex(char *p, const char *cp, int count) | |||
386 | // setgid() will fail and we'll _still_be_root_, which is bad.) | 386 | // setgid() will fail and we'll _still_be_root_, which is bad.) |
387 | void xsetgid(gid_t gid) | 387 | void xsetgid(gid_t gid) |
388 | { | 388 | { |
389 | if (setgid(gid)) bb_error_msg_and_die("setgid"); | 389 | if (setgid(gid)) bb_perror_msg_and_die("setgid"); |
390 | } | 390 | } |
391 | 391 | ||
392 | // Die with an error message if we can't set uid. (See xsetgid() for why.) | 392 | // Die with an error message if we can't set uid. (See xsetgid() for why.) |
393 | void xsetuid(uid_t uid) | 393 | void xsetuid(uid_t uid) |
394 | { | 394 | { |
395 | if (setuid(uid)) bb_error_msg_and_die("setuid"); | 395 | if (setuid(uid)) bb_perror_msg_and_die("setuid"); |
396 | } | 396 | } |
397 | 397 | ||
398 | // Return how long the file at fd is, if there's any way to determine it. | 398 | // Return how long the file at fd is, if there's any way to determine it. |