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
This commit is contained in:
Guillem Jover 2013-06-07 07:11:50 +02:00
parent e084ce3fa7
commit ad613d9d09

View File

@ -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;