Move noexec handling to sudo front-end where it is documented as being.
This commit is contained in:
@@ -413,7 +413,7 @@ matches_env_keep(const char *var)
|
||||
* Also adds sudo-specific variables (SUDO_*).
|
||||
*/
|
||||
void
|
||||
rebuild_env(int noexec)
|
||||
rebuild_env(void)
|
||||
{
|
||||
char **old_envp, **ep, *cp, *ps1;
|
||||
char idbuf[MAX_UID_T_LEN];
|
||||
@@ -602,30 +602,6 @@ rebuild_env(int noexec)
|
||||
if (!ISSET(didvar, DID_PATH))
|
||||
sudo_setenv("PATH", _PATH_STDPATH, FALSE);
|
||||
|
||||
/*
|
||||
* Preload a noexec file? For a list of LD_PRELOAD-alikes, see
|
||||
* http://www.fortran-2000.com/ArnaudRecipes/sharedlib.html
|
||||
* XXX - should prepend to original value, if any
|
||||
*/
|
||||
if (noexec && def_noexec_file != NULL) {
|
||||
#if defined(__darwin__) || defined(__APPLE__)
|
||||
sudo_setenv("DYLD_INSERT_LIBRARIES", def_noexec_file, TRUE);
|
||||
sudo_setenv("DYLD_FORCE_FLAT_NAMESPACE", "", TRUE);
|
||||
#else
|
||||
# if defined(__osf__) || defined(__sgi)
|
||||
easprintf(&cp, "%s:DEFAULT", def_noexec_file);
|
||||
sudo_setenv("_RLD_LIST", cp, TRUE);
|
||||
efree(cp);
|
||||
# else
|
||||
# ifdef _AIX
|
||||
sudo_setenv("LDR_PRELOAD", def_noexec_file, TRUE);
|
||||
# else
|
||||
sudo_setenv("LD_PRELOAD", def_noexec_file, TRUE);
|
||||
# endif /* _AIX */
|
||||
# endif /* __osf__ || __sgi */
|
||||
#endif /* __darwin__ || __APPLE__ */
|
||||
}
|
||||
|
||||
/* Set PS1 if SUDO_PS1 is set. */
|
||||
if (ps1 != NULL)
|
||||
sudo_putenv(ps1, TRUE, TRUE);
|
||||
|
@@ -433,7 +433,7 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[],
|
||||
def_env_reset = FALSE;
|
||||
|
||||
/* Build a new environment that avoids any nasty bits. */
|
||||
rebuild_env(def_noexec); /* XXX - move noexec bits */
|
||||
rebuild_env();
|
||||
|
||||
/* Require a password if sudoers says so. */
|
||||
if (def_authenticate) {
|
||||
@@ -533,9 +533,6 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[],
|
||||
command_info[info_len++] = estrdup("iolog_compress=true");
|
||||
}
|
||||
|
||||
if (def_noexec)
|
||||
command_info[info_len++] = estrdup("noexec=true");
|
||||
|
||||
log_allowed(validated);
|
||||
if (ISSET(sudo_mode, MODE_CHECK))
|
||||
rval = display_cmnd(snl, list_pw ? list_pw : sudo_user.pw);
|
||||
@@ -646,6 +643,10 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[],
|
||||
}
|
||||
if (def_closefrom >= 0)
|
||||
easprintf(&command_info[info_len++], "closefrom=%d", def_closefrom);
|
||||
if (def_noexec)
|
||||
command_info[info_len++] = estrdup("noexec=true");
|
||||
if (def_noexec_file)
|
||||
command_info[info_len++] = fmt_string("noexec_file", def_noexec_file);
|
||||
#ifdef HAVE_LOGIN_CAP_H
|
||||
if (lc != NULL)
|
||||
command_info[info_len++] = fmt_string("login_class", lc->lc_class);
|
||||
|
@@ -123,8 +123,8 @@ struct sudo_user {
|
||||
#define MODE_MASK 0x0000ffff
|
||||
|
||||
/* Mode flags */
|
||||
#define MODE_BACKGROUND 0x00010000
|
||||
#define MODE_SHELL 0x00020000
|
||||
#define MODE_BACKGROUND 0x00010000 /* XXX - unused */
|
||||
#define MODE_SHELL 0x00020000 /* XXX - not set but is used */
|
||||
#define MODE_LOGIN_SHELL 0x00040000
|
||||
#define MODE_IMPLIED_SHELL 0x00080000
|
||||
#define MODE_RESET_HOME 0x00100000
|
||||
@@ -295,7 +295,7 @@ void env_init(char * const envp[]);
|
||||
void init_envtables(void);
|
||||
void insert_env_vars(char * const envp[]);
|
||||
void read_env_file(const char *, int);
|
||||
void rebuild_env(int);
|
||||
void rebuild_env(void);
|
||||
void validate_env_vars(char * const envp[]);
|
||||
|
||||
/* fmt_string.c */
|
||||
|
80
src/sudo.c
80
src/sudo.c
@@ -450,6 +450,7 @@ command_info_to_details(char * const info[], struct command_details *details)
|
||||
|
||||
memset(details, 0, sizeof(*details));
|
||||
details->closefrom = -1;
|
||||
details->noexec_file = _PATH_SUDO_NOEXEC;
|
||||
|
||||
#define SET_STRING(s, n) \
|
||||
if (strncmp(s, info[i], sizeof(s) - 1) == 0 && info[i][sizeof(s) - 1]) { \
|
||||
@@ -504,6 +505,7 @@ command_info_to_details(char * const info[], struct command_details *details)
|
||||
SET(details->flags, CD_NOEXEC);
|
||||
break;
|
||||
}
|
||||
SET_STRING("noexec_file=", noexec_file)
|
||||
break;
|
||||
case 'p':
|
||||
if (strncmp("preserve_groups=", info[i], sizeof("preserve_groups=") - 1) == 0) {
|
||||
@@ -754,6 +756,75 @@ set_project(struct passwd *pw)
|
||||
}
|
||||
#endif /* HAVE_PROJECT_H */
|
||||
|
||||
/*
|
||||
* Disable execution of child processes in the command we are about
|
||||
* to run. On systems with privilege sets, we can remove the exec
|
||||
* privilege. On other systems we use LD_PRELOAD and the like.
|
||||
*/
|
||||
static void
|
||||
disable_execute(struct command_details *details)
|
||||
{
|
||||
char *cp, **ev, **nenvp;
|
||||
int env_len = 0, env_size = 128;
|
||||
|
||||
#ifdef HAVE_PRIV_SET
|
||||
/* Solaris privileges, remove PRIV_PROC_EXEC post-execve. */
|
||||
if (priv_set(PRIV_OFF, PRIV_LIMIT, "PRIV_PROC_EXEC", NULL) == 0)
|
||||
return;
|
||||
warning("unable to remove PRIV_PROC_EXEC from PRIV_LIMIT");
|
||||
#endif /* HAVE_PRIV_SET */
|
||||
|
||||
nenvp = emalloc2(env_size, sizeof(char *));
|
||||
for (ev = details->envp; *ev != NULL; ev++) {
|
||||
if (env_len + 2 > env_size) {
|
||||
env_size += 128;
|
||||
nenvp = erealloc3(nenvp, env_size, sizeof(char *));
|
||||
}
|
||||
/*
|
||||
* Prune out existing preloaded libraries.
|
||||
* XXX - should save and append instead of replacing.
|
||||
*/
|
||||
#if defined(__darwin__) || defined(__APPLE__)
|
||||
if (strncmp(*ev, "DYLD_INSERT_LIBRARIES=", sizeof("DYLD_INSERT_LIBRARIES=") - 1) == 0)
|
||||
continue;
|
||||
if (strncmp(*ev, "DYLD_FORCE_FLAT_NAMESPACE=", sizeof("DYLD_INSERT_LIBRARIES=") - 1) == 0)
|
||||
continue;
|
||||
#elif defined(__osf__) || defined(__sgi)
|
||||
if (strncmp(*ev, "_RLD_LIST=", sizeof("_RLD_LIST=") - 1) == 0)
|
||||
continue;
|
||||
#elif defined(_AIX)
|
||||
if (strncmp(*ev, "LDR_PRELOAD=", sizeof("LDR_PRELOAD=") - 1) == 0)
|
||||
continue;
|
||||
#else
|
||||
if (strncmp(*ev, "LD_PRELOAD=", sizeof("LD_PRELOAD=") - 1) == 0)
|
||||
continue;
|
||||
#endif
|
||||
nenvp[env_len++] = *ev;
|
||||
}
|
||||
|
||||
/*
|
||||
* Preload a noexec file? For a list of LD_PRELOAD-alikes, see
|
||||
* http://www.fortran-2000.com/ArnaudRecipes/sharedlib.html
|
||||
* XXX - need to support 32-bit and 64-bit variants
|
||||
*/
|
||||
#if defined(__darwin__) || defined(__APPLE__)
|
||||
nenvp[env_len++] = "DYLD_FORCE_FLAT_NAMESPACE=";
|
||||
cp = fmt_string("DYLD_INSERT_LIBRARIES", details->noexec_file);
|
||||
#elif defined(__osf__) || defined(__sgi)
|
||||
easprintf(&cp, "_RLD_LIST=%s:DEFAULT", details->noexec_file);
|
||||
#elif defined(_AIX)
|
||||
cp = fmt_string("LDR_PRELOAD", details->noexec_file);
|
||||
#else
|
||||
cp = fmt_string("LD_PRELOAD", details->noexec_file);
|
||||
#endif
|
||||
if (cp == NULL)
|
||||
error(1, NULL);
|
||||
nenvp[env_len++] = cp;
|
||||
nenvp[env_len] = NULL;
|
||||
|
||||
details->envp = nenvp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup the execution environment immediately prior to the call to execve()
|
||||
* Returns TRUE on success and FALSE on failure.
|
||||
@@ -865,13 +936,8 @@ exec_setup(struct command_details *details, const char *ptyname, int ptyfd)
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX - should do env-based noexec here too */
|
||||
#ifdef HAVE_PRIV_SET
|
||||
if (ISSET(details->flags, CD_NOEXEC)) {
|
||||
if (priv_set(PRIV_OFF, PRIV_LIMIT, "PRIV_PROC_EXEC", NULL) == -1)
|
||||
warning("unable to remove PRIV_PROC_EXEC from PRIV_LIMIT");
|
||||
}
|
||||
#endif /* HAVE_PRIV_SET */
|
||||
if (ISSET(details->flags, CD_NOEXEC))
|
||||
disable_execute(details);
|
||||
|
||||
#ifdef HAVE_SETRESUID
|
||||
if (setresuid(details->uid, details->euid, details->euid) != 0) {
|
||||
|
@@ -139,6 +139,7 @@ struct command_details {
|
||||
const char *chroot;
|
||||
const char *selinux_role;
|
||||
const char *selinux_type;
|
||||
const char *noexec_file;
|
||||
char **argv;
|
||||
char **envp;
|
||||
};
|
||||
|
Reference in New Issue
Block a user