From: Guillem Jover Date: Fri, 7 Jun 2013 05:11:50 +0000 (+0200) Subject: Create a shallow copy of environ before replacing it in setproctitle() X-Git-Tag: 0.5.2~1 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ad613d9d09e12c2397d8804c66f65ff1f89eed64;p=thirdparty%2Flibbsd.git Create a shallow copy of environ before replacing it in setproctitle() Because clearenv() or setenv() might free the environ array of pointers, we should make sure to copy it so that we can access it later on when doing the deep copy via setenv(). Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=65470 --- diff --git a/src/setproctitle.c b/src/setproctitle.c index 0d97954..7e4b165 100644 --- a/src/setproctitle.c +++ b/src/setproctitle.c @@ -76,36 +76,60 @@ spt_clearenv(void) } static int -spt_copyenv(char *oldenv[]) +spt_copyenv(int envc, char *envp[]) { + char **envcopy; char *eq; + int envsize; int i, error; - if (environ != oldenv) + if (environ != envp) return 0; + /* Make a copy of the old environ array of pointers, in case + * clearenv() or setenv() is implemented to free the internal + * environ array, because we will need to access the old environ + * contents to make the new copy. */ + envsize = (envc + 1) * sizeof(char *); + envcopy = malloc(envsize); + if (envcopy == NULL) + return errno; + memcpy(envcopy, envp, envsize); + error = spt_clearenv(); if (error) { - environ = oldenv; + environ = envp; + free(envcopy); return error; } - for (i = 0; oldenv[i]; i++) { - eq = strchr(oldenv[i], '='); + for (i = 0; envcopy[i]; i++) { + eq = strchr(envcopy[i], '='); if (eq == NULL) continue; *eq = '\0'; - if (setenv(oldenv[i], eq + 1, 1) < 0) + if (setenv(envcopy[i], eq + 1, 1) < 0) error = errno; *eq = '='; if (error) { - environ = oldenv; +#ifdef HAVE_CLEARENV + /* Because the old environ might not be available + * anymore we will make do with the shallow copy. */ + environ = envcopy; +#else + environ = envp; + free(envcopy); +#endif return error; } } + /* Dispose of the shallow copy, now that we've finished transfering + * the old environment. */ + free(envcopy); + return 0; } @@ -133,7 +157,7 @@ static void spt_init(int argc, char *argv[], char *envp[]) { char *base, *end, *nul, *tmp; - int i, error; + int i, envc, error; /* Try to make sure we got called with main() arguments. */ if (argc < 0) @@ -159,6 +183,7 @@ spt_init(int argc, char *argv[], char *envp[]) end = envp[i] + strlen(envp[i]) + 1; } + envc = i; SPT.arg0 = strdup(argv[0]); if (SPT.arg0 == NULL) { @@ -173,7 +198,7 @@ spt_init(int argc, char *argv[], char *envp[]) } setprogname(tmp); - error = spt_copyenv(envp); + error = spt_copyenv(envc, envp); if (error) { SPT.error = error; return;