diff options
author | 2014-05-16 15:43:55 -0500 | |
---|---|---|
committer | 2014-05-16 15:43:55 -0500 | |
commit | c9890aca3a3045e53bb9b7754c80f7ded51e65f6 (patch) | |
tree | 367fd4e3e34aefb36a1b188def698244ba83b0d0 | |
parent | bec11654de69611ae6088d3aaa4a8d6f40265603 (diff) | |
download | pseudo-c9890aca3a3045e53bb9b7754c80f7ded51e65f6.tar.gz pseudo-c9890aca3a3045e53bb9b7754c80f7ded51e65f6.tar.bz2 pseudo-c9890aca3a3045e53bb9b7754c80f7ded51e65f6.zip |
pseudo_has_unload: add function
Various wrappers checked for a non-null pseudo_get_value("PSEUDO_UNLOAD") to
determine whether the environment should include the pseudo variables. None
of those checks freed the returned value when it was not null. The new
check function does.
The new check function also sees whether PSEUDO_UNLOAD was defined in the
environment that should be used in the wrapped system call. This allows
pkg_postinst scripts to strip out the LD_PRELOAD setting, for example before
invoking qemu to execute commands in an environment that does not have
libpseudo.so.
[YOCTO #4843]
Signed-off-by: Peter A. Bigot <pab@pabigot.com>
Signed-off-by: Peter Seebach <peter.seebach@windriver.com>
-rw-r--r-- | ChangeLog.txt | 3 | ||||
-rw-r--r-- | ports/common/guts/execv.c | 2 | ||||
-rw-r--r-- | ports/common/guts/execve.c | 2 | ||||
-rw-r--r-- | ports/common/guts/execvp.c | 2 | ||||
-rw-r--r-- | ports/common/guts/fork.c | 2 | ||||
-rw-r--r-- | ports/linux/newclone/pseudo_wrappers.c | 2 | ||||
-rw-r--r-- | ports/linux/oldclone/pseudo_wrappers.c | 2 | ||||
-rw-r--r-- | ports/unix/guts/popen.c | 2 | ||||
-rw-r--r-- | ports/unix/guts/system.c | 2 | ||||
-rw-r--r-- | pseudo.h | 1 | ||||
-rw-r--r-- | pseudo_util.c | 27 |
11 files changed, 39 insertions, 8 deletions
diff --git a/ChangeLog.txt b/ChangeLog.txt index 844e177..347a591 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -8,6 +8,9 @@ * (seebs) send a round-trip message to the server before exiting if any messages have been sent, so the program won't exit before the server processed those messages. + * (pabigot) Don't memory-leak on checks for PSEUDO_UNLOAD, also + check the correct environment when spawning new things. (Contributed + by Peter A. Bigot). 2014-05-15: * (seebs) drop flags when calling fchmodat() to appease GNU tar. diff --git a/ports/common/guts/execv.c b/ports/common/guts/execv.c index 763e1f9..3e1f820 100644 --- a/ports/common/guts/execv.c +++ b/ports/common/guts/execv.c @@ -19,7 +19,7 @@ } pseudo_setupenv(); - if (pseudo_get_value("PSEUDO_UNLOAD")) + if (pseudo_has_unload(NULL)) pseudo_dropenv(); /* if exec() fails, we may end up taking signals unexpectedly... diff --git a/ports/common/guts/execve.c b/ports/common/guts/execve.c index a003657..ff6a44e 100644 --- a/ports/common/guts/execve.c +++ b/ports/common/guts/execve.c @@ -20,7 +20,7 @@ } new_environ = pseudo_setupenvp(envp); - if (pseudo_get_value("PSEUDO_UNLOAD")) + if (pseudo_has_unload(new_environ)) new_environ = pseudo_dropenvp(new_environ); /* if exec() fails, we may end up taking signals unexpectedly... diff --git a/ports/common/guts/execvp.c b/ports/common/guts/execvp.c index 5e75be7..04253c3 100644 --- a/ports/common/guts/execvp.c +++ b/ports/common/guts/execvp.c @@ -20,7 +20,7 @@ } pseudo_setupenv(); - if (pseudo_get_value("PSEUDO_UNLOAD")) + if (pseudo_has_unload(NULL)) pseudo_dropenv(); /* if exec() fails, we may end up taking signals unexpectedly... diff --git a/ports/common/guts/fork.c b/ports/common/guts/fork.c index df8abd7..bebe3b0 100644 --- a/ports/common/guts/fork.c +++ b/ports/common/guts/fork.c @@ -12,7 +12,7 @@ */ if (rc == 0) { pseudo_setupenv(); - if (!pseudo_get_value("PSEUDO_UNLOAD")) { + if (!pseudo_has_unload(NULL)) { pseudo_reinit_libpseudo(); } else { pseudo_dropenv(); diff --git a/ports/linux/newclone/pseudo_wrappers.c b/ports/linux/newclone/pseudo_wrappers.c index 092e532..1fc6c59 100644 --- a/ports/linux/newclone/pseudo_wrappers.c +++ b/ports/linux/newclone/pseudo_wrappers.c @@ -28,7 +28,7 @@ int wrap_clone_child(void *args) { if (!(flags & CLONE_VM)) { pseudo_setupenv(); - if (!pseudo_get_value("PSEUDO_UNLOAD")) { + if (!pseudo_has_unload(NULL)) { pseudo_reinit_libpseudo(); } else { pseudo_dropenv(); diff --git a/ports/linux/oldclone/pseudo_wrappers.c b/ports/linux/oldclone/pseudo_wrappers.c index f0a8eec..1720dfb 100644 --- a/ports/linux/oldclone/pseudo_wrappers.c +++ b/ports/linux/oldclone/pseudo_wrappers.c @@ -22,7 +22,7 @@ int wrap_clone_child(void *args) { if (!(flags & CLONE_VM)) { pseudo_setupenv(); - if (!pseudo_get_value("PSEUDO_UNLOAD")) { + if (!pseudo_has_unload(NULL)) { pseudo_reinit_libpseudo(); } else { pseudo_dropenv(); diff --git a/ports/unix/guts/popen.c b/ports/unix/guts/popen.c index 0ca16b0..5d44c0e 100644 --- a/ports/unix/guts/popen.c +++ b/ports/unix/guts/popen.c @@ -9,7 +9,7 @@ * in ways that avoid our usual enforcement of the environment. */ pseudo_setupenv(); - if (pseudo_get_value("PSEUDO_UNLOAD")) + if (pseudo_has_unload(NULL)) pseudo_dropenv(); rc = real_popen(command, mode); diff --git a/ports/unix/guts/system.c b/ports/unix/guts/system.c index 028b372..6351592 100644 --- a/ports/unix/guts/system.c +++ b/ports/unix/guts/system.c @@ -9,7 +9,7 @@ return 1; pseudo_setupenv(); - if (pseudo_get_value("PSEUDO_UNLOAD")) + if (pseudo_has_unload(NULL)) pseudo_dropenv(); rc = real_system(command); @@ -28,6 +28,7 @@ extern void pseudo_init_client(void); void pseudo_dump_env(char **envp); int pseudo_set_value(const char *key, const char *value); char *pseudo_get_value(const char *key); +int pseudo_has_unload(char * const *envp); #include "pseudo_tables.h" diff --git a/pseudo_util.c b/pseudo_util.c index f20dbec..325cabf 100644 --- a/pseudo_util.c +++ b/pseudo_util.c @@ -95,6 +95,33 @@ dump_env(char **envp) { } #endif +int +pseudo_has_unload(char * const *envp) { + static const char unload[] = "PSEUDO_UNLOAD"; + static size_t unload_len = strlen(unload); + size_t i = 0; + + /* Is it in the caller environment? */ + if (NULL != getenv(unload)) + return 1; + + /* Is it in the environment cache? */ + if (pseudo_util_initted == -1) + pseudo_init_util(); + while (pseudo_env[i].key && strcmp(pseudo_env[i].key, unload)) + ++i; + if (pseudo_env[i].key && pseudo_env[i].value) + return 1; + + /* Is it in the operational environment? */ + while (envp && *envp) { + if ((!strncmp(*envp, unload, unload_len)) && ('=' == (*envp)[unload_len])) + return 1; + ++envp; + } + return 0; +} + /* Caller must free memory! */ char * pseudo_get_value(const char *key) { |