`os.environ.clear()` now leaves the C `environ` pointer NULL, which crashes Tcl/Tk (tkinter) on the next `Tcl_CreateInterp`
Chưa có ai nhận issue này.
- Ngôn ngữ chính
- Python
- Star
- 77.2k
- Fork
- 35.9k
- Chỉ số merge pull request
- Chỉ số pull request đang chờ
Mô tả
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
Hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Hướng nghiên cứu
Bắt đầu bằng cách tái hiện lỗi crash với min.py, sau đó kiểm tra đường đi của os.environ.clear() qua posix._clearenv(). Xác minh hành vi liên quan đến con trỏ environ của C và chạy các bài kiểm tra môi trường và tkinter có liên quan; công việc được xem là hoàn tất khi việc xóa os.environ không còn khiến tkinter.Tcl() crash trên nền tảng bị ảnh hưởng.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Đánh giá
- Công nghệ
- c, python
- Lĩnh vực
- operating-systems
- Loại issue
- Lỗi
- Độ khó
- 4/5
- Thời gian dự kiến
- 3-5 ngày
- Mức độ hoạt động
- Đình trệ
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức phù hợp với người mới
- 20/100