From mboxrd@z Thu Jan 1 00:00:00 1970 X-Msuck: nntp://news.gmane.org/gmane.linux.lib.musl.general/9603 Path: news.gmane.org!not-for-mail From: Alexander Monakov Newsgroups: gmane.linux.lib.musl.general Subject: [PATCH 2/3] env: remove duplicates when adding to environment Date: Sun, 13 Mar 2016 21:53:49 +0300 Message-ID: <1457895230-13602-3-git-send-email-amonakov@ispras.ru> References: <1457895230-13602-1-git-send-email-amonakov@ispras.ru> Reply-To: musl@lists.openwall.com NNTP-Posting-Host: plane.gmane.org X-Trace: ger.gmane.org 1457895266 28207 80.91.229.3 (13 Mar 2016 18:54:26 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Sun, 13 Mar 2016 18:54:26 +0000 (UTC) To: musl@lists.openwall.com Original-X-From: musl-return-9617-gllmg-musl=m.gmane.org@lists.openwall.com Sun Mar 13 19:54:26 2016 Return-path: Envelope-to: gllmg-musl@m.gmane.org Original-Received: from mother.openwall.net ([195.42.179.200]) by plane.gmane.org with smtp (Exim 4.69) (envelope-from ) id 1afB9l-0001Vm-BV for gllmg-musl@m.gmane.org; Sun, 13 Mar 2016 19:54:25 +0100 Original-Received: (qmail 21605 invoked by uid 550); 13 Mar 2016 18:54:16 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Original-Received: (qmail 20442 invoked from network); 13 Mar 2016 18:54:01 -0000 X-Mailer: git-send-email 2.1.3 In-Reply-To: <1457895230-13602-1-git-send-email-amonakov@ispras.ru> Xref: news.gmane.org gmane.linux.lib.musl.general:9603 Archived-At: 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