|
Message-Id: <1457895230-13602-3-git-send-email-amonakov@ispras.ru> Date: Sun, 13 Mar 2016 21:53:49 +0300 From: Alexander Monakov <amonakov@...ras.ru> To: musl@...ts.openwall.com Subject: [PATCH 2/3] env: remove duplicates when adding to environment Potential presence of multiple entries for the same name in the environment can be problematic for applications that mix libc calls and direct lookups via 'environ'. Removing duplicates of the entry being set via setenv/putenv is a simple partial mitigation. --- This was raised recently on the glibc bugzilla, and Rich commented on IRC that removing all duplicates in the environment at startup is costly, but we could consider changing setenv/putenv to remove the duplicates of the entry being set. I'm afraid that wouldn't help the applications that are actually affected. However, since both setenv and putenv work via __putenv, the corresponding patch is not too big, so here's one possible approach. src/env/putenv.c | 3 ++- src/env/unsetenv.c | 21 +++++++++++++-------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/env/putenv.c b/src/env/putenv.c index 39a71be..facae1d 100644 --- a/src/env/putenv.c +++ b/src/env/putenv.c @@ -3,6 +3,7 @@ #include "libc.h" char *__strchrnul(const char *, int); +int __unsetenv(const char *, size_t, char **); static void dummy(char *p, char *r) {} weak_alias(dummy, __env_change); @@ -16,7 +17,7 @@ int __putenv(char *s, size_t l, char *r) char *tmp = __environ[i]; __environ[i] = s; __env_change(tmp, r); - return 0; + return __unsetenv(s, l, __environ+i+1); } static char **oldenv; char **newenv; diff --git a/src/env/unsetenv.c b/src/env/unsetenv.c index 86873cd..5e5727f 100644 --- a/src/env/unsetenv.c +++ b/src/env/unsetenv.c @@ -8,15 +8,9 @@ char *__strchrnul(const char *, int); static void dummy(char *p, char *r) {} weak_alias(dummy, __env_change); -int unsetenv(const char *name) +int __unsetenv(const char *name, size_t l, char **e) { - size_t l = __strchrnul(name, '=') - name; - if (!l || name[l]) { - errno = EINVAL; - return -1; - } - if (!__environ) return 0; - for (char **e = __environ; *e; e++) + for (; *e; e++) while (*e && !strncmp(name, *e, l) && l[*e] == '=') { char **ee = e, *tmp = *e; do *ee = *(ee+1); @@ -25,3 +19,14 @@ int unsetenv(const char *name) } return 0; } + +int unsetenv(const char *name) +{ + size_t l = __strchrnul(name, '=') - name; + if (!l || name[l]) { + errno = EINVAL; + return -1; + } + if (!__environ) return 0; + return __unsetenv(name, l, __environ); +} -- 2.1.3
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.