From: Todd C. Miller Date: Sun, 16 Sep 2012 19:18:58 +0000 (-0400) Subject: Replace the guts of sudo_setenv_nodebug() with our old setenv.c X-Git-Tag: SUDO_1_8_7~1^2~394 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=faf112c53bb305b08ed6bd0a50610eeabd0d0307;p=sudo Replace the guts of sudo_setenv_nodebug() with our old setenv.c which supports non-standard BSD and glibc semantics. sudo_setenv() now simply calls sudo_setenv2(). --- diff --git a/plugins/sudoers/env.c b/plugins/sudoers/env.c index d678fa1fb..b28f45eaf 100644 --- a/plugins/sudoers/env.c +++ b/plugins/sudoers/env.c @@ -401,6 +401,15 @@ sudo_setenv2(const char *var, const char *val, bool dupcheck, bool overwrite) debug_return_int(rval); } +/* + * Similar to setenv(3) but operates on a private copy of the environment. + */ +int +sudo_setenv(const char *var, const char *val, int overwrite) +{ + return sudo_setenv2(var, val, true, (bool)overwrite); +} + /* * Similar to setenv(3) but operates on a private copy of the environment. * Does not include warnings or debugging to avoid recursive calls. @@ -408,49 +417,48 @@ sudo_setenv2(const char *var, const char *val, bool dupcheck, bool overwrite) static int sudo_setenv_nodebug(const char *var, const char *val, int overwrite) { - char *estring; + char *ep, *estring = NULL; + const char *cp; size_t esize; int rval = -1; - esize = strlen(var) + 1 + strlen(val) + 1; - if ((estring = malloc(esize)) == NULL) { - errno = ENOMEM; + if (var == NULL || *var == '\0') { + errno = EINVAL; goto done; } - /* Build environment string and insert it. */ - if (strlcpy(estring, var, esize) >= esize || - strlcat(estring, "=", esize) >= esize || - strlcat(estring, val, esize) >= esize) { + /* + * 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 "" */ + } - errno = EINVAL; + /* Allocate and fill in estring. */ + if ((estring = ep = malloc(esize)) == NULL) { + errno = ENOMEM; goto done; } + for (cp = var; *cp && *cp != '='; cp++) + *ep++ = *cp; + *ep++ = '='; + if (val) { + for (cp = val; *cp; cp++) + *ep++ = *cp; + } + *ep = '\0'; + rval = sudo_putenv_nodebug(estring, true, overwrite); done: if (rval == -1) - efree(estring); + free(estring); return rval; } -/* - * Similar to setenv(3) but operates on a private copy of the environment. - */ -int -sudo_setenv(const char *var, const char *val, int overwrite) -{ - int rval; - debug_decl(sudo_setenv, SUDO_DEBUG_ENV) - - rval = sudo_setenv_nodebug(var, val, overwrite); - if (rval == -1) { - if (errno == EINVAL) - errorx(1, _("internal error, %s overflow"), "sudo_setenv()"); - errorx(1, _("unable to allocate memory")); - } - debug_return_int(rval); -} - /* * Similar to unsetenv(3) but operates on a private copy of the environment. * Does not include warnings or debugging to avoid recursive calls.