From: Denys Vlasenko Date: Sat, 22 Jul 2017 00:15:17 +0000 (+0200) Subject: libbb: avoid malloc/free in bb_unsetenv() X-Git-Tag: 1_28_0~335 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=ef0366eb4f02bb0cda359b977fdbdfa7c145f76f;p=oweals%2Fbusybox.git libbb: avoid malloc/free in bb_unsetenv() function old new delta bb_unsetenv 55 83 +28 Signed-off-by: Denys Vlasenko --- diff --git a/libbb/xfuncs_printf.c b/libbb/xfuncs_printf.c index 1b11caf6b..f569b0263 100644 --- a/libbb/xfuncs_printf.c +++ b/libbb/xfuncs_printf.c @@ -344,20 +344,28 @@ void FAST_FUNC xsetenv(const char *key, const char *value) */ void FAST_FUNC bb_unsetenv(const char *var) { - char *tp = strchr(var, '='); - - if (!tp) { - unsetenv(var); - return; + char onstack[128 - 16]; /* smaller stack setup code on x86 */ + char *tp; + + tp = strchr(var, '='); + if (tp) { + /* In case var was putenv'ed, we can't replace '=' + * with NUL and unsetenv(var) - it won't work, + * env is modified by the replacement, unsetenv + * sees "VAR" instead of "VAR=VAL" and does not remove it! + * Horror :( + */ + unsigned sz = tp - var; + if (sz < sizeof(onstack)) { + ((char*)mempcpy(onstack, var, sz))[0] = '\0'; + tp = NULL; + var = onstack; + } else { + /* unlikely: very long var name */ + var = tp = xstrndup(var, sz); + } } - - /* In case var was putenv'ed, we can't replace '=' - * with NUL and unsetenv(var) - it won't work, - * env is modified by the replacement, unsetenv - * sees "VAR" instead of "VAR=VAL" and does not remove it! - * horror :( */ - tp = xstrndup(var, tp - var); - unsetenv(tp); + unsetenv(var); free(tp); }