[New-bugs-announce] [issue4926] putenv() accepts names containing '=', return value of unsetenv() not checked

David Watson report at bugs.python.org
Tue Jan 13 00:30:37 CET 2009

New submission from David Watson <baikie at users.sourceforge.net>:

One of these problems interacts with the other, and can cause
os.unsetenv() to free memory that's still in use.  Firstly,
calling os.putenv("FOO=BAR", "value") causes putenv(3) to be
called with the string "FOO=BAR=value", which sets a variable
called FOO, not FOO=BAR; hence, os.putenv() should not accept a
name with an "=" character in it.

The way this interacts with os.unsetenv() is that the string
(FOO=BAR=value) is stored in the internal dictionary object
posix_putenv_garbage under the key "FOO=BAR".  The reference in
this dict is supposed to prevent the bytes object (str in 3.x on
Windows) that contains the string from being garbage collected
and freed until unsetenv() is called, since putenv(3) makes the
char **environ array point to the actual string, not a copy.

The problem with os.unsetenv() is that it does not check the
return value from unsetenv(3) at all and will unconditionally
remove the corresponding string from posix_putenv_garbage.
Following the example above, when os.unsetenv("FOO=BAR") is
called, unsetenv(3) will fail because the name contains an "="
character, but the object containing the string will be garbage
collected even though char **environ still has a pointer to it.

This is a bit tricky to give a visible demonstration of, but the
attached visibility.diff adds posix_putenv_garbage to the module
namespace and prints the return value from unsetenv() so you can
see what's going on.

The other two attached diffs fix the problems (for 2.x and 3.x
separately) by making os.unsetenv() raise OSError on failure in
the usual way, and os.putenv() raise ValueError when its first
argument contains "=".  They also add test cases and docs.  In
the patch for 3.x, some of the relevant code differs between Unix
and Windows; I changed both but I've only tested the Unix

components: Extension Modules
files: visibility.diff
keywords: patch
messages: 79708
nosy: baikie
severity: normal
status: open
title: putenv() accepts names containing '=', return value of unsetenv() not checked
type: behavior
Added file: http://bugs.python.org/file12708/visibility.diff

Python tracker <report at bugs.python.org>

More information about the New-bugs-announce mailing list