`os.environ.clear()` now leaves the C `environ` pointer NULL, which crashes Tcl/Tk (tkinter) on the next `Tcl_CreateInterp`
Nadie ha tomado este issue todavía.
- Lenguaje dominante
- Python
- Estrellas
- 77.2k
- Forks
- 35.9k
- Métricas de merge de PR
- Métricas de PR pendientes
Descripción
Crash report
What happened?
Since gh-139482 (PR gh-139965, October 2025) os.environ.clear() calls posix._clearenv() →
clearenv(3). On glibc clearenv() sets the global environ to NULL rather than to an
empty array. Any C library that walks environ without a NULL check then segfaults; Tcl is one
of them (TclSetupEnv in generic/tclEnv.c reads environ[0], in 8.6 and on Tcl main).
Before this change clear() removed keys one at a time with unsetenv(), which leaves
environ a valid empty array, and the program below worked.
The following code:
import os
os.environ.clear()
import tkinter
tkinter.Tcl()
Resulted in this output:
AddressSanitizer:DEADLYSIGNAL
==1527921==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x75e7d758a13f bp 0x78b7d9e5f060 sp 0x7ffdab0f82c0 T0)
==1527921==The signal is caused by a READ memory access.
==1527921==Hint: address points to the zero page.
#0 0x75e7d758a13f in TclSetupEnv (/lib/x86_64-linux-gnu/libtcl8.6.so+0xb213f)
#1 0x75e7d75114d8 in Tcl_CreateInterp (/lib/x86_64-linux-gnu/libtcl8.6.so+0x394d8)
#2 0x75e7d88c1607 in Tkapp_New Modules/_tkinter.c:643:17
#3 0x75e7d88c1607 in _tkinter_create_impl Modules/_tkinter.c:3483:25
#4 0x75e7d88c1607 in _tkinter_create Modules/clinic/_tkinter.c.h:898:20
#5 0x6375e0068750 in cfunction_vectorcall_FASTCALL Objects/methodobject.c:449:24
#6 0x6375dfeb5205 in _PyObject_VectorcallTstate Include/internal/pycore_call.h:144:11
#7 0x6375e04005ac in _Py_VectorCallInstrumentation_StackRefSteal Python/ceval.c:770:11
#8 0x6375e0449521 in _PyEval_EvalFrameDefault Python/generated_cases.c.h:1906:35
#9 0x6375e03ff857 in _PyEval_Vector Python/ceval.c:2176:12
#10 0x6375dfeb55b4 in _PyObject_VectorcallDictTstate Objects/call.c:135:15
#11 0x6375dfeb97e6 in _PyObject_Call_Prepend Objects/call.c:504:24
#12 0x6375e017d7b0 in call_method Objects/typeobject.c:3070:19
#13 0x6375e01c9165 in slot_tp_init Objects/typeobject.c:11115:21
#14 0x6375e0159c7a in type_call Objects/typeobject.c:2454:19
Without a sanitizer it is a plain Segmentation fault. It is deterministic.
Evidence that the NULL pointer is the cause:
import os, ctypes
environ = ctypes.c_void_p.in_dll(ctypes.CDLL(None), "environ")
os.environ.clear()
print(environ.value) # None -> environ == NULL
Deleting the keys individually instead keeps environ non-NULL and tkinter.Tcl() succeeds:
import os
for k in list(os.environ):
del os.environ[k]
import tkinter
tkinter.Tcl() # OK
Calling libc.clearenv() directly from ctypes reproduces the crash too, so the library
behaviour is glibc's; the regression is that os.environ.clear() now exposes it to every
tkinter (and any other environ-walking extension) user. Possible fixes on the CPython side:
after clearenv(), point environ at a static {NULL} array (glibc's setenv/putenv copy
rather than realloc an environ they did not allocate, so this is safe), or fall back to the
per-key unsetenv() loop.
To reproduce:
./python min.py
Commit:
e682b4478c2ad09de0bbe821127f451f02f6e5ca (main, 2026-09-16)
Build configuration:
../configure --with-pydebug --enable-experimental-jit=yes --with-address-sanitizer --with-undefined-behavior-sanitizer
Operating System:
Ubuntu 22.04.5 LTS, x86_64, glibc 2.35, Tcl/Tk 8.6.12 (libtcl8.6 8.6.12+dfsg-1build1), in Docker (image fusion-fuzz-cpython:latest)
This bug was found by fusion-fuzz
CPython versions tested on:
CPython main branch
Operating systems tested on:
No response
Output from running 'python -VV' on the command line:
No response
Linked PRs
- gh-157745
Guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Línea de trabajo
Comienza reproduciendo el fallo con min.py y, después, inspecciona la ruta de os.environ.clear() a través de posix._clearenv(). Verifica el comportamiento en torno al puntero environ de C y ejecuta las pruebas relevantes de entorno y tkinter; el trabajo estará terminado cuando vaciar os.environ ya no provoque que tkinter.Tcl() falle en la plataforma afectada.
Escrito por el modelo de indexación a partir del texto del issue.
Evaluación
- Stack tecnológico
- c, python
- Área
- operating-systems
- Tipo de issue
- Error
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Estado de actividad
- Estancado
- Claridad
- Bien especificado
- Aptitud para principiantes
- 20/100