-
-
Notifications
You must be signed in to change notification settings - Fork 30.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
The os module should unset() environment variable at exit #83576
Comments
os.environ[key] = value has to keep internally the string "key=value\0" after putenv("key=value\0") has been called, since the glibc doesn't copy the string. Python has to manage the string memory. Internally, the posix module uses a "posix_putenv_garbage" dictionary mapping key (bytes) to value (bytes). Values are "key=value\0" strings. The bpo-35381 issue converted the os ("posix" in practice) module PEP-384: "Remove all static state from posixmodule": commit b396663. The _posix_clear() function is now called by _PyImport_Cleanup(). Problem: the glibc is not aware that Python is exiting and that the memory of the environment variable has been released. Next access to environment variables ("environ" C variable, putenv, setenv, unsetenv, ...) can crash. Sometimes, it doesn't crash even if the memory has been released, because free() does not always dig immediately holes in the heap memory (the complex problelm of memory fragmentation). The posix module should notify the glibc that the memory will be released before releasing the memory, to avoid keeping dangling pointers in the "environ" C variable. The following crash in the Elements module is an example of crash introduced by commit b396663 which introduced this issue: |
Fedora downstream issue, crash in the "elements" package: https://bugzilla.redhat.com/show_bug.cgi?id=1791761 |
I proposed bpo-39406 which avoids to have to clear environment variables set by Python at exit on platforms providing setenv(). |
bpo-39406 is a new feature. In any case we should fix potential crash in older Python versions. |
Python 3.8 and older are not affected by this issue since they never destroy the posix_putenv_garbage dictionary: memory is never released. |
I closed bpo-39406: os.putenv() is now implemented with setenv() if available. The internal putenv_dict is no longer used on Windows and if setenv() is available. Now only non-Windows platforms without setenv() are affected by this issue. |
Clearing environment variables at exit has a drawback: it changes the behavior in code executed after Python finalization (Py_FinalizeEx() call). It may cause regression. So I proposed PR 18135 to fix this issue differently: on non-Windows platforms, Python now requires setenv() to build. This PR has no backward compatibility issue: it doesn't unset environment variables at exit. |
On non-Windows platforms, Python now requires setenv() and unsetenv() setenv() and unsetenv() should be available on all platforms supported by Python. If it's not the case, someone can maintain a downstream patch which is a revert of commit b8d1262. If someone asks to support a platform which doesn't provide setenv() and unsetenv(), we can revisit the idea of unsetting variables set by Python at exit, to workaround putenv() issue: something like my (abandonned) PR 18078. |
FTR, bpo-39376 is related (avoid the process-global env vars in the first place). |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: