Mutable heap PyStructSequence types can segfault after modifying n_fields
Dieses Issue hat noch niemand übernommen.
- Vorherrschende Sprache
- Python
- Sterne
- 77.2k
- Forks
- 35.9k
- PR-Merge-Kennzahlen
- PR-Kennzahlen ausstehend
Beschreibung
Crash report
What happened?
Several heap PyStructSequence types can be crashed from pure Python by modifying the writable n_fields attribute on the type and then constructing a new instance.
The issue reproduces with at least:
os.terminal_sizeos.stat_resulttime.struct_timeresource.struct_rusage
Minimal reproducer:
import os
os.terminal_size.n_fields = 100000
os.terminal_size((1, 2))
This consistently terminates the interpreter with:
Segmentation fault (core dumped)
The crash also reproduces for other mutable heap PyStructSequence types by assigning a large value to n_fields before construction.
The backtrace shows the crash occurring in structseq_new_impl():
#0 __strlen_avx2()
#1 PyUnicode_FromString()
#2 PyDict_GetItemStringRef()
#3 structseq_new_impl() at Objects/structseq.c:243
At the point of failure:
max_len = 100000
i = 2
n_unnamed_fields = 0
From inspecting Objects/structseq.c, structseq_new_impl() uses the type's n_fields value to determine how many member names to process. After modifying n_fields from Python, the constructor eventually reaches a NULL member name, leading to a crash through PyDict_GetItemStringRef() and PyUnicode_FromString().
During investigation I also verified that immutable builtin structseq types such as sys.version_info are not affected because their type attributes cannot be modified and new instances cannot be created.
I searched the existing issue tracker using keywords including:
structseq_new_implPyStructSequence_NewTypen_fieldsObjects/structseq.cPyDict_GetItemStringReftp_members
but could not find an existing report describing this behavior.
CPython versions tested on:
CPython main branch
Operating systems tested on:
Linux
Output from running 'python -VV' on the command line:
Python 3.16.0a0 (heads/main:e469fa9c807, Aug 7 2026, 09:37:12) [GCC 13.3.0]
Linked PRs
- gh-155361
Beitragsleitfaden
Erste Schritte
- Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
- Forke das Repository und arbeite in einem Branch.
- Öffne einen Pull Request, der die Issue-Nummer nennt.
Rechercherichtung
Beginne mit Objects/structseq.c und structseq_new_impl() und führe anschließend den im Issue beschriebenen minimalen Reproducer für os.terminal_size aus. Vergleiche die Behandlung des beschreibbaren n_fields-Werts mit den verfügbaren Membernamen; abgeschlossen ist die Arbeit, wenn das Konstruieren der betroffenen Typen nicht mehr abstürzt und die Regressionstests dieses Verhalten belegen.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Bewertung
- Tech-Stack
- c, python
- Bereich
- backend
- Issue-Typ
- Bug
- Schwierigkeit
- 3/5
- Geschätzter Aufwand
- 1-2 Tage
- Aktivitätsstatus
- Veraltet
- Klarheit
- Größtenteils klar
- Anfängerfreundlichkeit
- 25/100