aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-05-02 23:01:32 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-05-02 23:01:32 +0000
commit3bc18253b081cc0b73f902036416fea47f2b61e5 (patch)
treec1f857892931a55c1f651b44d8f0c60121ea8e43
parentf92df58d3d97bb75d7b12437d53dd97acfd01095 (diff)
downloadbusybox-w32-3bc18253b081cc0b73f902036416fea47f2b61e5.tar.gz
busybox-w32-3bc18253b081cc0b73f902036416fea47f2b61e5.tar.bz2
busybox-w32-3bc18253b081cc0b73f902036416fea47f2b61e5.zip
fix suid config handling
-rw-r--r--applets/applets.c39
-rw-r--r--libbb/xfuncs.c4
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. */
111static const char config_file[] = "/etc/busybox.conf"; 111static const char config_file[] = "/etc/busybox.conf";
112 112
113/* There are 4 chars + 1 nul for each of user/group/other. */
114static 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
338static void check_suid(const struct bb_applet *applet) 338static 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.)
387void xsetgid(gid_t gid) 387void 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.)
393void xsetuid(uid_t uid) 393void 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.