Use non-exiting allocatings in the sudoers plugin.
This commit is contained in:
@@ -211,7 +211,7 @@ static const char *initial_keepenv_table[] = {
|
||||
/*
|
||||
* Initialize env based on envp.
|
||||
*/
|
||||
void
|
||||
bool
|
||||
env_init(char * const envp[])
|
||||
{
|
||||
char * const *ep;
|
||||
@@ -220,7 +220,7 @@ env_init(char * const envp[])
|
||||
|
||||
if (envp == NULL) {
|
||||
/* Free the old envp we allocated, if any. */
|
||||
sudo_efree(env.old_envp);
|
||||
free(env.old_envp);
|
||||
|
||||
/* Reset to initial state but keep a pointer to what we allocated. */
|
||||
env.old_envp = env.envp;
|
||||
@@ -235,7 +235,13 @@ env_init(char * const envp[])
|
||||
|
||||
env.env_len = len;
|
||||
env.env_size = len + 1 + 128;
|
||||
env.envp = sudo_emallocarray(env.env_size, sizeof(char *));
|
||||
env.envp = reallocarray(NULL, env.env_size, sizeof(char *));
|
||||
if (env.envp == NULL) {
|
||||
env.env_size = 0;
|
||||
env.env_len = 0;
|
||||
sudo_warnx(U_("unable to allocate memory"));
|
||||
debug_return_bool(false);
|
||||
}
|
||||
#ifdef ENV_DEBUG
|
||||
memset(env.envp, 0, env.env_size * sizeof(char *));
|
||||
#endif
|
||||
@@ -243,11 +249,11 @@ env_init(char * const envp[])
|
||||
env.envp[len] = NULL;
|
||||
|
||||
/* Free the old envp we allocated, if any. */
|
||||
sudo_efree(env.old_envp);
|
||||
free(env.old_envp);
|
||||
env.old_envp = NULL;
|
||||
}
|
||||
|
||||
debug_return;
|
||||
debug_return_bool(true);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -398,7 +404,8 @@ sudo_setenv2(const char *var, const char *val, bool dupcheck, bool overwrite)
|
||||
debug_decl(sudo_setenv2, SUDOERS_DEBUG_ENV)
|
||||
|
||||
esize = strlen(var) + 1 + strlen(val) + 1;
|
||||
estring = sudo_emalloc(esize);
|
||||
if ((estring = malloc(esize)) == NULL)
|
||||
debug_return_int(-1);
|
||||
|
||||
/* Build environment string and insert it. */
|
||||
if (strlcpy(estring, var, esize) >= esize ||
|
||||
@@ -411,7 +418,7 @@ sudo_setenv2(const char *var, const char *val, bool dupcheck, bool overwrite)
|
||||
rval = sudo_putenv(estring, dupcheck, overwrite);
|
||||
}
|
||||
if (rval == -1)
|
||||
sudo_efree(estring);
|
||||
free(estring);
|
||||
debug_return_int(rval);
|
||||
}
|
||||
|
||||
@@ -821,6 +828,16 @@ env_update_didvar(const char *ep, unsigned int *didvar)
|
||||
}
|
||||
}
|
||||
|
||||
#define CHECK_PUTENV(a, b, c) do { \
|
||||
if (sudo_putenv((a), (b), (c)) == -1) \
|
||||
goto bad; \
|
||||
} while (0)
|
||||
|
||||
#define CHECK_SETENV2(a, b, c, d) do { \
|
||||
if (sudo_setenv2((a), (b), (c), (d)) == -1) \
|
||||
goto bad; \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Build a new environment and ether clear potentially dangerous
|
||||
* variables from the old one or start with a clean slate.
|
||||
@@ -843,9 +860,13 @@ rebuild_env(void)
|
||||
didvar = 0;
|
||||
env.env_len = 0;
|
||||
env.env_size = 128;
|
||||
sudo_efree(env.old_envp);
|
||||
free(env.old_envp);
|
||||
env.old_envp = env.envp;
|
||||
env.envp = sudo_emallocarray(env.env_size, sizeof(char *));
|
||||
env.envp = reallocarray(NULL, env.env_size, sizeof(char *));
|
||||
if (env.envp == NULL) {
|
||||
env.env_size = 0;
|
||||
goto bad;
|
||||
}
|
||||
#ifdef ENV_DEBUG
|
||||
memset(env.envp, 0, env.env_size * sizeof(char *));
|
||||
#else
|
||||
@@ -905,8 +926,7 @@ rebuild_env(void)
|
||||
|
||||
if (keepit) {
|
||||
/* Preserve variable. */
|
||||
if (sudo_putenv(*ep, false, false) == -1)
|
||||
goto bad;
|
||||
CHECK_PUTENV(*ep, false, false);
|
||||
env_update_didvar(*ep, &didvar);
|
||||
}
|
||||
}
|
||||
@@ -918,25 +938,25 @@ rebuild_env(void)
|
||||
* on sudoers options).
|
||||
*/
|
||||
if (ISSET(sudo_mode, MODE_LOGIN_SHELL)) {
|
||||
sudo_setenv2("SHELL", runas_pw->pw_shell,
|
||||
CHECK_SETENV2("SHELL", runas_pw->pw_shell,
|
||||
ISSET(didvar, DID_SHELL), true);
|
||||
sudo_setenv2("LOGNAME", runas_pw->pw_name,
|
||||
CHECK_SETENV2("LOGNAME", runas_pw->pw_name,
|
||||
ISSET(didvar, DID_LOGNAME), true);
|
||||
sudo_setenv2("USER", runas_pw->pw_name,
|
||||
CHECK_SETENV2("USER", runas_pw->pw_name,
|
||||
ISSET(didvar, DID_USER), true);
|
||||
sudo_setenv2("USERNAME", runas_pw->pw_name,
|
||||
CHECK_SETENV2("USERNAME", runas_pw->pw_name,
|
||||
ISSET(didvar, DID_USERNAME), true);
|
||||
} else {
|
||||
if (!ISSET(didvar, DID_SHELL))
|
||||
sudo_setenv2("SHELL", sudo_user.pw->pw_shell, false, true);
|
||||
CHECK_SETENV2("SHELL", sudo_user.pw->pw_shell, false, true);
|
||||
/* We will set LOGNAME later in the !def_set_logname case. */
|
||||
if (!def_set_logname) {
|
||||
if (!ISSET(didvar, DID_LOGNAME))
|
||||
sudo_setenv2("LOGNAME", user_name, false, true);
|
||||
CHECK_SETENV2("LOGNAME", user_name, false, true);
|
||||
if (!ISSET(didvar, DID_USER))
|
||||
sudo_setenv2("USER", user_name, false, true);
|
||||
CHECK_SETENV2("USER", user_name, false, true);
|
||||
if (!ISSET(didvar, DID_USERNAME))
|
||||
sudo_setenv2("USERNAME", user_name, false, true);
|
||||
CHECK_SETENV2("USERNAME", user_name, false, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -950,10 +970,13 @@ rebuild_env(void)
|
||||
*/
|
||||
if (ISSET(sudo_mode, MODE_LOGIN_SHELL) || !ISSET(didvar, KEPT_MAIL)) {
|
||||
cp = _PATH_MAILDIR;
|
||||
if (cp[sizeof(_PATH_MAILDIR) - 2] == '/')
|
||||
sudo_easprintf(&cp, "MAIL=%s%s", _PATH_MAILDIR, runas_pw->pw_name);
|
||||
else
|
||||
sudo_easprintf(&cp, "MAIL=%s/%s", _PATH_MAILDIR, runas_pw->pw_name);
|
||||
if (cp[sizeof(_PATH_MAILDIR) - 2] == '/') {
|
||||
if (asprintf(&cp, "MAIL=%s%s", _PATH_MAILDIR, runas_pw->pw_name) == -1)
|
||||
goto bad;
|
||||
} else {
|
||||
if (asprintf(&cp, "MAIL=%s/%s", _PATH_MAILDIR, runas_pw->pw_name) == -1)
|
||||
goto bad;
|
||||
}
|
||||
if (sudo_putenv(cp, ISSET(didvar, DID_MAIL), true) == -1) {
|
||||
free(cp);
|
||||
goto bad;
|
||||
@@ -973,15 +996,13 @@ rebuild_env(void)
|
||||
SET(didvar, DID_PATH);
|
||||
else if (strncmp(*ep, "TERM=", 5) == 0)
|
||||
SET(didvar, DID_TERM);
|
||||
if (sudo_putenv(*ep, false, false) == -1)
|
||||
goto bad;
|
||||
CHECK_PUTENV(*ep, false, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Replace the PATH envariable with a secure one? */
|
||||
if (def_secure_path && !user_is_exempt()) {
|
||||
if (sudo_setenv2("PATH", def_secure_path, true, true) == -1)
|
||||
goto bad;
|
||||
CHECK_SETENV2("PATH", def_secure_path, true, true);
|
||||
SET(didvar, DID_PATH);
|
||||
}
|
||||
|
||||
@@ -993,58 +1014,50 @@ rebuild_env(void)
|
||||
*/
|
||||
if (def_set_logname && !ISSET(sudo_mode, MODE_LOGIN_SHELL)) {
|
||||
if (!ISSET(didvar, KEPT_LOGNAME))
|
||||
sudo_setenv2("LOGNAME", runas_pw->pw_name, true, true);
|
||||
CHECK_SETENV2("LOGNAME", runas_pw->pw_name, true, true);
|
||||
if (!ISSET(didvar, KEPT_USER))
|
||||
sudo_setenv2("USER", runas_pw->pw_name, true, true);
|
||||
CHECK_SETENV2("USER", runas_pw->pw_name, true, true);
|
||||
if (!ISSET(didvar, KEPT_USERNAME))
|
||||
sudo_setenv2("USERNAME", runas_pw->pw_name, true, true);
|
||||
CHECK_SETENV2("USERNAME", runas_pw->pw_name, true, true);
|
||||
}
|
||||
|
||||
/* Set $HOME to target user if not preserving user's value. */
|
||||
if (reset_home)
|
||||
sudo_setenv2("HOME", runas_pw->pw_dir, true, true);
|
||||
CHECK_SETENV2("HOME", runas_pw->pw_dir, true, true);
|
||||
|
||||
/* Provide default values for $TERM and $PATH if they are not set. */
|
||||
if (!ISSET(didvar, DID_TERM)) {
|
||||
if (sudo_putenv("TERM=unknown", false, false) == -1)
|
||||
goto bad;
|
||||
}
|
||||
if (!ISSET(didvar, DID_PATH)) {
|
||||
if (sudo_setenv2("PATH", _PATH_STDPATH, false, true) == -1)
|
||||
goto bad;
|
||||
}
|
||||
if (!ISSET(didvar, DID_TERM))
|
||||
CHECK_PUTENV("TERM=unknown", false, false);
|
||||
if (!ISSET(didvar, DID_PATH))
|
||||
CHECK_SETENV2("PATH", _PATH_STDPATH, false, true);
|
||||
|
||||
/* Set PS1 if SUDO_PS1 is set. */
|
||||
if (ps1 != NULL) {
|
||||
if (sudo_putenv(ps1, true, true) == -1)
|
||||
goto bad;
|
||||
}
|
||||
if (ps1 != NULL)
|
||||
CHECK_PUTENV(ps1, true, true);
|
||||
|
||||
/* Add the SUDO_COMMAND envariable (cmnd + args). */
|
||||
if (user_args) {
|
||||
sudo_easprintf(&cp, "SUDO_COMMAND=%s %s", user_cmnd, user_args);
|
||||
if (asprintf(&cp, "SUDO_COMMAND=%s %s", user_cmnd, user_args) == -1)
|
||||
goto bad;
|
||||
if (sudo_putenv(cp, true, true) == -1) {
|
||||
sudo_efree(cp);
|
||||
free(cp);
|
||||
goto bad;
|
||||
}
|
||||
} else {
|
||||
if (sudo_setenv2("SUDO_COMMAND", user_cmnd, true, true) == -1)
|
||||
goto bad;
|
||||
CHECK_SETENV2("SUDO_COMMAND", user_cmnd, true, true);
|
||||
}
|
||||
|
||||
/* Add the SUDO_USER, SUDO_UID, SUDO_GID environment variables. */
|
||||
if (sudo_setenv2("SUDO_USER", user_name, true, true) == -1)
|
||||
goto bad;
|
||||
CHECK_SETENV2("SUDO_USER", user_name, true, true);
|
||||
snprintf(idbuf, sizeof(idbuf), "%u", (unsigned int) user_uid);
|
||||
if (sudo_setenv2("SUDO_UID", idbuf, true, true) == -1)
|
||||
goto bad;
|
||||
CHECK_SETENV2("SUDO_UID", idbuf, true, true);
|
||||
snprintf(idbuf, sizeof(idbuf), "%u", (unsigned int) user_gid);
|
||||
if (sudo_setenv2("SUDO_GID", idbuf, true, true) == -1)
|
||||
goto bad;
|
||||
CHECK_SETENV2("SUDO_GID", idbuf, true, true);
|
||||
|
||||
debug_return_bool(true);
|
||||
|
||||
bad:
|
||||
sudo_warn(U_("unable to rebuild the environment"));
|
||||
debug_return_bool(false);
|
||||
}
|
||||
|
||||
@@ -1177,7 +1190,11 @@ read_env_file(const char *path, int overwrite)
|
||||
val_len -= 2;
|
||||
}
|
||||
|
||||
cp = sudo_emalloc(var_len + 1 + val_len + 1);
|
||||
if ((cp = malloc(var_len + 1 + val_len + 1)) == NULL) {
|
||||
/* XXX - no undo on failure */
|
||||
rval = false;
|
||||
break;
|
||||
}
|
||||
memcpy(cp, var, var_len + 1); /* includes '=' */
|
||||
memcpy(cp + var_len + 1, val, val_len + 1); /* includes NUL */
|
||||
|
||||
@@ -1193,32 +1210,43 @@ read_env_file(const char *path, int overwrite)
|
||||
debug_return_bool(rval);
|
||||
}
|
||||
|
||||
void
|
||||
bool
|
||||
init_envtables(void)
|
||||
{
|
||||
struct list_member *cur;
|
||||
const char **p;
|
||||
debug_decl(init_envtables, SUDOERS_DEBUG_ENV)
|
||||
|
||||
/* Fill in the "env_delete" list. */
|
||||
for (p = initial_badenv_table; *p; p++) {
|
||||
cur = sudo_ecalloc(1, sizeof(struct list_member));
|
||||
cur->value = sudo_estrdup(*p);
|
||||
cur = calloc(1, sizeof(struct list_member));
|
||||
if (cur == NULL || (cur->value = strdup(*p)) == NULL) {
|
||||
free(cur);
|
||||
debug_return_bool(false);
|
||||
}
|
||||
SLIST_INSERT_HEAD(&def_env_delete, cur, entries);
|
||||
}
|
||||
|
||||
/* Fill in the "env_check" list. */
|
||||
for (p = initial_checkenv_table; *p; p++) {
|
||||
cur = sudo_ecalloc(1, sizeof(struct list_member));
|
||||
cur->value = sudo_estrdup(*p);
|
||||
cur = calloc(1, sizeof(struct list_member));
|
||||
if (cur == NULL || (cur->value = strdup(*p)) == NULL) {
|
||||
free(cur);
|
||||
debug_return_bool(false);
|
||||
}
|
||||
SLIST_INSERT_HEAD(&def_env_check, cur, entries);
|
||||
}
|
||||
|
||||
/* Fill in the "env_keep" list. */
|
||||
for (p = initial_keepenv_table; *p; p++) {
|
||||
cur = sudo_ecalloc(1, sizeof(struct list_member));
|
||||
cur->value = sudo_estrdup(*p);
|
||||
cur = calloc(1, sizeof(struct list_member));
|
||||
if (cur == NULL || (cur->value = strdup(*p)) == NULL) {
|
||||
free(cur);
|
||||
debug_return_bool(false);
|
||||
}
|
||||
SLIST_INSERT_HEAD(&def_env_keep, cur, entries);
|
||||
}
|
||||
debug_return_bool(true);
|
||||
}
|
||||
|
||||
int
|
||||
|
Reference in New Issue
Block a user