python / python/cpython

Mutable heap PyStructSequence types can segfault after modifying n_fields

Aperta
#155,322 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

interpreter-core type-crash
Lingua principale
Python
Stelle
77.2k
Fork
35.9k
Metriche di merge delle PR
Metriche PR in attesa

Descrizione

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_size
  • os.stat_result
  • time.struct_time
  • resource.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_impl
  • PyStructSequence_NewType
  • n_fields
  • Objects/structseq.c
  • PyDict_GetItemStringRef
  • tp_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

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Direzione di ricerca

Inizia da Objects/structseq.c e structseq_new_impl(), quindi esegui il riproduttore minimo di os.terminal_size descritto nell’issue. Confronta la gestione del valore scrivibile n_fields con i nomi dei membri disponibili; il lavoro è completato quando la costruzione dei tipi interessati non causa più un crash e la copertura di regressione dimostra questo comportamento.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
c, python
Ambito
backend
Tipo di issue
Bug
Difficoltà
3/5
Tempo stimato
1-2 giorni
Stato di attività
Ferma
Chiarezza
Abbastanza chiara
Idoneità per principianti
25/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.