mirror of
https://github.com/sudo-project/sudo.git
synced 2025-08-31 14:25:15 +00:00
Now that sudoers is a dynamically loaded module we cannot override
the libc environment functions because the symbols may already have been resolved via libc. Remove getenv/putenv/setenv/unsetenv replacements from sudoers and add replacements for setenv/unsetenv for systems that lack them.
This commit is contained in:
@@ -255,134 +255,6 @@ sudo_setenv(const char *var, const char *val, int dupcheck)
|
||||
sudo_putenv(estring, dupcheck, TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Version of getenv(3) that uses our own environ pointer.
|
||||
*/
|
||||
char *
|
||||
getenv(const char *var)
|
||||
{
|
||||
char *cp, **ev;
|
||||
size_t vlen = strlen(var);
|
||||
|
||||
for (ev = env.envp; (cp = *ev) != NULL; ev++) {
|
||||
if (strncmp(var, cp, vlen) == 0 && cp[vlen] == '=')
|
||||
return cp + vlen + 1;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Version of setenv(3) that uses our own environ pointer.
|
||||
*/
|
||||
int
|
||||
setenv(const char *var, const char *val, int overwrite)
|
||||
{
|
||||
char *estring, *ep;
|
||||
const char *cp;
|
||||
size_t esize;
|
||||
|
||||
if (!var || *var == '\0') {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* POSIX says a var name with '=' is an error but BSD
|
||||
* just ignores the '=' and anything after it.
|
||||
*/
|
||||
for (cp = var; *cp && *cp != '='; cp++)
|
||||
;
|
||||
esize = (size_t)(cp - var) + 2;
|
||||
if (val) {
|
||||
esize += strlen(val); /* glibc treats a NULL val as "" */
|
||||
}
|
||||
|
||||
/* Allocate and fill in estring. */
|
||||
estring = ep = emalloc(esize);
|
||||
for (cp = var; *cp && *cp != '='; cp++)
|
||||
*ep++ = *cp;
|
||||
*ep++ = '=';
|
||||
if (val) {
|
||||
for (cp = val; *cp; cp++)
|
||||
*ep++ = *cp;
|
||||
}
|
||||
*ep = '\0';
|
||||
|
||||
#ifdef ENV_DEBUG
|
||||
if (env.envp[env.env_len] != NULL)
|
||||
errorx(1, "setenv: corrupted envp, len mismatch");
|
||||
#endif
|
||||
sudo_putenv(estring, TRUE, overwrite);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Version of unsetenv(3) that uses our own environ pointer.
|
||||
*/
|
||||
#ifdef UNSETENV_VOID
|
||||
void
|
||||
#else
|
||||
int
|
||||
#endif
|
||||
unsetenv(const char *var)
|
||||
{
|
||||
char **ep = env.envp;
|
||||
size_t len;
|
||||
|
||||
if (var == NULL || *var == '\0' || strchr(var, '=') != NULL) {
|
||||
errno = EINVAL;
|
||||
#ifdef UNSETENV_VOID
|
||||
return;
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef ENV_DEBUG
|
||||
if (env.envp[env.env_len] != NULL)
|
||||
errorx(1, "unsetenv: corrupted envp, len mismatch");
|
||||
#endif
|
||||
|
||||
len = strlen(var);
|
||||
while (*ep != NULL) {
|
||||
if (strncmp(var, *ep, len) == 0 && (*ep)[len] == '=') {
|
||||
/* Found it; shift remainder + NULL over by one. */
|
||||
char **cur = ep;
|
||||
while ((*cur = *(cur + 1)) != NULL)
|
||||
cur++;
|
||||
/* Keep going, could be multiple instances of the var. */
|
||||
} else {
|
||||
ep++;
|
||||
}
|
||||
}
|
||||
env.env_len = ep - env.envp;
|
||||
#ifndef UNSETENV_VOID
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Version of putenv(3) that uses our own environ pointer.
|
||||
*/
|
||||
int
|
||||
#ifdef PUTENV_CONST
|
||||
putenv(const char *string)
|
||||
#else
|
||||
putenv(char *string)
|
||||
#endif
|
||||
{
|
||||
if (strchr(string, '=') == NULL) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
#ifdef ENV_DEBUG
|
||||
if (env.envp[env.env_len] != NULL)
|
||||
errorx(1, "putenv: corrupted envp, len mismatch");
|
||||
#endif
|
||||
sudo_putenv((char *)string, TRUE, TRUE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Similar to putenv(3) but operates on sudo's private copy of the
|
||||
* environment (not environ) and it always overwrites. The dupcheck param
|
||||
|
Reference in New Issue
Block a user