fix suid config handling
This commit is contained in:
parent
f92df58d3d
commit
3bc18253b0
@ -110,9 +110,6 @@ static char *get_trimmed_slice(char *s, char *e)
|
|||||||
/* Don't depend on the tools to combine strings. */
|
/* Don't depend on the tools to combine strings. */
|
||||||
static const char config_file[] = "/etc/busybox.conf";
|
static const char config_file[] = "/etc/busybox.conf";
|
||||||
|
|
||||||
/* There are 4 chars + 1 nul for each of user/group/other. */
|
|
||||||
static const char mode_chars[] = "Ssx-\0Ssx-\0Ttx-";
|
|
||||||
|
|
||||||
/* We don't supply a value for the nul, so an index adjustment is
|
/* We don't supply a value for the nul, so an index adjustment is
|
||||||
* necessary below. Also, we use unsigned short here to save some
|
* necessary below. Also, we use unsigned short here to save some
|
||||||
* space even though these are really mode_t values. */
|
* space even though these are really mode_t values. */
|
||||||
@ -257,6 +254,9 @@ static void parse_config_file(void)
|
|||||||
e = skip_whitespace(e+1);
|
e = skip_whitespace(e+1);
|
||||||
|
|
||||||
for (i = 0; i < 3; i++) {
|
for (i = 0; i < 3; i++) {
|
||||||
|
/* There are 4 chars + 1 nul for each of user/group/other. */
|
||||||
|
static const char mode_chars[] = "Ssx-\0" "Ssx-\0" "Ttx-";
|
||||||
|
|
||||||
const char *q;
|
const char *q;
|
||||||
q = strchrnul(mode_chars + 5*i, *e++);
|
q = strchrnul(mode_chars + 5*i, *e++);
|
||||||
if (!*q) {
|
if (!*q) {
|
||||||
@ -337,7 +337,8 @@ static inline void parse_config_file(void)
|
|||||||
#if ENABLE_FEATURE_SUID
|
#if ENABLE_FEATURE_SUID
|
||||||
static void check_suid(const struct bb_applet *applet)
|
static void check_suid(const struct bb_applet *applet)
|
||||||
{
|
{
|
||||||
uid_t rgid; /* real gid */
|
uid_t uid;
|
||||||
|
gid_t rgid; /* real gid */
|
||||||
|
|
||||||
if (ruid == 0) /* set by parse_config_file() */
|
if (ruid == 0) /* set by parse_config_file() */
|
||||||
return; /* run by root - no need to check more */
|
return; /* run by root - no need to check more */
|
||||||
@ -368,16 +369,24 @@ static void check_suid(const struct bb_applet *applet)
|
|||||||
if (!(m & S_IXOTH)) /* is x bit not set ? */
|
if (!(m & S_IXOTH)) /* is x bit not set ? */
|
||||||
bb_error_msg_and_die("you have no permission to run this applet!");
|
bb_error_msg_and_die("you have no permission to run this applet!");
|
||||||
|
|
||||||
if (sct->m_gid != 0) {
|
/* _both_ sgid and group_exec have to be set for setegid */
|
||||||
/* _both_ have to be set for sgid */
|
if ((sct->m_mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))
|
||||||
if ((sct->m_mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
|
rgid = sct->m_gid;
|
||||||
xsetgid(sct->m_gid);
|
/* else (no setegid) we will set egid = rgid */
|
||||||
} else xsetgid(rgid); /* no sgid -> drop */
|
|
||||||
}
|
/* We set effective AND saved ids. If saved-id is not set
|
||||||
if (sct->m_uid != 0) {
|
* like we do below, seteiud(0) can still later succeed! */
|
||||||
if (sct->m_mode & S_ISUID) xsetuid(sct->m_uid);
|
if (setresgid(-1, rgid, rgid))
|
||||||
else xsetuid(ruid); /* no suid -> drop */
|
bb_perror_msg_and_die("setresgid");
|
||||||
}
|
|
||||||
|
/* do we have to set effective uid? */
|
||||||
|
uid = ruid;
|
||||||
|
if (sct->m_mode & S_ISUID)
|
||||||
|
uid = sct->m_uid;
|
||||||
|
/* else (no seteuid) we will set euid = ruid */
|
||||||
|
|
||||||
|
if (setresuid(-1, uid, uid))
|
||||||
|
bb_perror_msg_and_die("setresuid");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#if !ENABLE_FEATURE_SUID_CONFIG_QUIET
|
#if !ENABLE_FEATURE_SUID_CONFIG_QUIET
|
||||||
@ -393,6 +402,8 @@ static void check_suid(const struct bb_applet *applet)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (applet->need_suid == _BB_SUID_ALWAYS) {
|
if (applet->need_suid == _BB_SUID_ALWAYS) {
|
||||||
|
/* Real uid is not 0. If euid isn't 0 too, suid bit
|
||||||
|
* is most probably not set on our executable */
|
||||||
if (geteuid())
|
if (geteuid())
|
||||||
bb_error_msg_and_die("applet requires root privileges!");
|
bb_error_msg_and_die("applet requires root privileges!");
|
||||||
} else if (applet->need_suid == _BB_SUID_NEVER) {
|
} else if (applet->need_suid == _BB_SUID_NEVER) {
|
||||||
|
@ -386,13 +386,13 @@ char *bin2hex(char *p, const char *cp, int count)
|
|||||||
// setgid() will fail and we'll _still_be_root_, which is bad.)
|
// setgid() will fail and we'll _still_be_root_, which is bad.)
|
||||||
void xsetgid(gid_t gid)
|
void xsetgid(gid_t gid)
|
||||||
{
|
{
|
||||||
if (setgid(gid)) bb_error_msg_and_die("setgid");
|
if (setgid(gid)) bb_perror_msg_and_die("setgid");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Die with an error message if we can't set uid. (See xsetgid() for why.)
|
// Die with an error message if we can't set uid. (See xsetgid() for why.)
|
||||||
void xsetuid(uid_t uid)
|
void xsetuid(uid_t uid)
|
||||||
{
|
{
|
||||||
if (setuid(uid)) bb_error_msg_and_die("setuid");
|
if (setuid(uid)) bb_perror_msg_and_die("setuid");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return how long the file at fd is, if there's any way to determine it.
|
// Return how long the file at fd is, if there's any way to determine it.
|
||||||
|
Loading…
Reference in New Issue
Block a user