From: Todd C. Miller Date: Tue, 17 Mar 2015 02:19:24 +0000 (-0600) Subject: For sudoedit, run the editor with the user's original environment X-Git-Tag: SUDO_1_8_13^2~1 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=be4872f691fe6b0970bcbe680aa62a09281dda87;p=sudo For sudoedit, run the editor with the user's original environment as per the documentation (and as in sudo 1.7.x). Bug #688 --- diff --git a/plugins/sudoers/env.c b/plugins/sudoers/env.c index d2f844f3e..3b3664240 100644 --- a/plugins/sudoers/env.c +++ b/plugins/sudoers/env.c @@ -101,8 +101,8 @@ #define KEPT_MAX 0xff00 struct environment { - char * const *old_envp; /* pointer the environment we passed back */ char **envp; /* pointer to the new environment */ + char **old_envp; /* pointer the old environment we allocated */ size_t env_size; /* size of new_environ in char **'s */ size_t env_len; /* number of slots used, not counting NULL */ }; @@ -219,10 +219,14 @@ env_init(char * const envp[]) debug_decl(env_init, SUDOERS_DEBUG_ENV) if (envp == NULL) { + /* Free the old envp we allocated, if any. */ + sudo_efree(env.old_envp); + /* Reset to initial state but keep a pointer to what we allocated. */ - envp = env.envp; - memset(&env, 0, sizeof(env)); - env.old_envp = envp; + env.old_envp = env.envp; + env.envp = NULL; + env.env_size = 0; + env.env_len = 0; } else { /* Make private copy of envp. */ for (ep = envp; *ep != NULL; ep++) @@ -239,8 +243,8 @@ env_init(char * const envp[]) env.envp[len] = NULL; /* Free the old envp we allocated, if any. */ - if (env.old_envp != NULL) - sudo_efree((void *)env.old_envp); + sudo_efree(env.old_envp); + env.old_envp = NULL; } debug_return; @@ -255,6 +259,22 @@ env_get(void) return env.envp; } +/* + * Swap the old and new copies of the environment. + */ +bool +env_swap_old(void) +{ + char **old_envp; + + if (env.old_envp == NULL) + return false; + old_envp = env.old_envp; + env.old_envp = env.envp; + env.envp = old_envp; + return true; +} + /* * Similar to putenv(3) but operates on sudo's private copy of the * environment (not environ) and it always overwrites. The dupcheck param @@ -810,7 +830,7 @@ env_update_didvar(const char *ep, unsigned int *didvar) bool rebuild_env(void) { - char **old_envp, **ep, *cp, *ps1; + char **ep, *cp, *ps1; char idbuf[MAX_UID_T_LEN + 1]; unsigned int didvar; bool reset_home = false; @@ -823,7 +843,8 @@ rebuild_env(void) didvar = 0; env.env_len = 0; env.env_size = 128; - old_envp = env.envp; + sudo_efree(env.old_envp); + env.old_envp = env.envp; env.envp = sudo_emallocarray(env.env_size, sizeof(char *)); #ifdef ENV_DEBUG memset(env.envp, 0, env.env_size * sizeof(char *)); @@ -867,7 +888,7 @@ rebuild_env(void) } /* Pull in vars we want to keep from the old environment. */ - for (ep = old_envp; *ep; ep++) { + for (ep = env.old_envp; *ep; ep++) { bool keepit; /* @@ -943,7 +964,7 @@ rebuild_env(void) * Copy environ entries as long as they don't match env_delete or * env_check. */ - for (ep = old_envp; *ep; ep++) { + for (ep = env.old_envp; *ep; ep++) { /* Add variable unless it matches a black list. */ if (!env_should_delete(*ep)) { if (strncmp(*ep, "SUDO_PS1=", 9) == 0) @@ -970,7 +991,7 @@ rebuild_env(void) * they have already been set) or sudoedit (because we want the editor * to find the invoking user's startup files). */ - if (def_set_logname && !ISSET(sudo_mode, MODE_LOGIN_SHELL|MODE_EDIT)) { + if (def_set_logname && !ISSET(sudo_mode, MODE_LOGIN_SHELL)) { if (!ISSET(didvar, KEPT_LOGNAME)) sudo_setenv2("LOGNAME", runas_pw->pw_name, true, true); if (!ISSET(didvar, KEPT_USER)) @@ -1021,9 +1042,6 @@ rebuild_env(void) if (sudo_setenv2("SUDO_GID", idbuf, true, true) == -1) goto bad; - /* Free old environment. */ - sudo_efree(old_envp); - debug_return_bool(true); bad: diff --git a/plugins/sudoers/sudoers.c b/plugins/sudoers/sudoers.c index 8359bea82..b165cd02d 100644 --- a/plugins/sudoers/sudoers.c +++ b/plugins/sudoers/sudoers.c @@ -525,6 +525,9 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[], safe_cmnd = find_editor(NewArgc - 1, NewArgv + 1, &edit_argc, &edit_argv); if (safe_cmnd == NULL || audit_success(edit_argc, edit_argv) != 0) goto bad; + + /* We want to run the editor with the unmodified environment. */ + env_swap_old(); } else { if (audit_success(NewArgc, NewArgv) != 0) goto bad; diff --git a/plugins/sudoers/sudoers.h b/plugins/sudoers/sudoers.h index 1d659b5d5..a8d22a0a7 100644 --- a/plugins/sudoers/sudoers.h +++ b/plugins/sudoers/sudoers.h @@ -324,6 +324,7 @@ char *expand_iolog_path(const char *prefix, const char *dir, const char *file, /* env.c */ char **env_get(void); bool env_merge(char * const envp[]); +bool env_swap_old(void); void env_init(char * const envp[]); void init_envtables(void); bool insert_env_vars(char * const envp[]);