diff options
author | cos <cos> | 2012-12-16 11:19:04 +0100 |
---|---|---|
committer | cos <cos> | 2012-12-16 19:13:49 +0100 |
commit | 42ae327b55c8827142000952ebd2487624908989 (patch) | |
tree | 3bf5f005bb22b8fcbeb35aecb74a69089feff070 | |
parent | 9d1edbd9c618b063a4baae39a82a81da236ea72f (diff) | |
download | ratpoison-fix/unsetenv_memory_corruption.zip |
Remove memory corruption bug.fix/unsetenv_memory_corruption
Fix regression from commit a2aeb846.
Providing putenv() a variable suffixed by an equal sign with glibc, puts the
pointer of the empty string as the value of the variable. When dereferencing
the empty string, strange things happen. I doubt the OpenBSD implementation has
a severely different API, but have not verified this.
From putenv()'s manpage in Debian, it is easy to get the impression that it is
a good idea to have putenv() handling all environment variable manipulation
when using glibc. According to OpenBSD's manpage, putenv() is merely an alias
for setenv() with arguments.
The best we can do is having putenv() removing the variable on platforms where
that is possible & calling unsetenv() on OpenBSD (+ other unknown platforms).
-rw-r--r-- | src/actions.c | 17 |
1 files changed, 9 insertions, 8 deletions
diff --git a/src/actions.c b/src/actions.c index bf381c8..259ae68 100644 --- a/src/actions.c +++ b/src/actions.c @@ -4190,15 +4190,16 @@ cmd_chdir (int interactive UNUSED, struct cmdarg **args) cmdret * cmd_unsetenv (int interactive UNUSED, struct cmdarg **args) { - struct sbuf *s; + /* Remove all instances of the env. var. It is assumed a good idea to use + putenv() for all manipulation of environment variables, in order to let it + handle memory management. On OpenBSD unsetting variables using putenv() is + not possible. */ +#ifdef __OpenBSD__ + unsetenv (ARG_STRING(0)); +#else + putenv (ARG_STRING(0)); +#endif - /* Remove all instances of the env. var. We must add an '=' for it - to work on OpenBSD. */ - s = sbuf_new(0); - sbuf_copy (s, ARG_STRING(0)); - sbuf_concat (s, "="); - putenv (sbuf_get(s)); - sbuf_free (s); return cmdret_new (RET_SUCCESS, NULL); } |