Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Segfault from NULL dereference in _zoneinfo.get_weak_cache #146076

@devdanzin

Description

@devdanzin

Crash report

What happened?

It's possible to cause a segfault by deleting the _weak_cache of a ZoneInfo subclass, then trying to access the removed cache.

Automated diagnosis:

Bug: NULL dereference via unchecked get_weak_cache return. get_weak_cache() can return NULL for ZoneInfo subclasses that lack a _weak_cache attribute. The return value is used at lines 323 and 498 without NULL checks, passing NULL to PyObject_CallMethod -> segfault.

File: Modules/_zoneinfo.c, lines 323 and 498

MRE:

from zoneinfo import ZoneInfo

class BadZoneInfo(ZoneInfo):
    pass

delattr(BadZoneInfo, '_weak_cache')
BadZoneInfo("UTC")
BadZoneInfo.clear_cache()

Backtrace:

Program received signal SIGSEGV, Segmentation fault.
0x00007bfff598d1ec in Py_DECREF (lineno=326, op=0x0, filename=<optimized out>) at ./Include/refcount.h:390
390         if (op->ob_refcnt_full <= 0 || op->ob_refcnt > (((PY_UINT32_T)-1) - (1<<20))) {

#0  0x00007bfff598d1ec in Py_DECREF (lineno=326, op=0x0, filename=<optimized out>) at ./Include/refcount.h:390
#1  zoneinfo_ZoneInfo_impl (type=type@entry=0x7d8ff702dda0, key=key@entry=0x7c6ff70e7a20) at ./Modules/_zoneinfo.c:326
#2  0x00007bfff5982b63 in zoneinfo_ZoneInfo (type=<optimized out>, args=0x7c6ff70409f0, kwargs=<optimized out>) at ./Modules/clinic/_zoneinfo.c.h:64
#3  0x0000555555c7beb3 in type_call (self=<optimized out>, args=<optimized out>, kwds=<optimized out>) at Objects/typeobject.c:2441
#4  0x0000555555aba90b in _PyObject_MakeTpCall (tstate=0x5555568f7b18 <_PyRuntime+360664>, callable=0x7d8ff702dda0, args=0x7bfff5d1af28, nargs=1, keywords=0x0) at Objects/call.c:242
#5  0x0000555555e588dd in _Py_VectorCallInstrumentation_StackRefSteal (callable=..., arguments=<optimized out>, total_args=1, kwnames=..., call_instrumentation=<optimized out>,
    frame=<optimized out>, this_instr=<optimized out>, tstate=<optimized out>) at Python/ceval.c:770
#6  0x0000555555e94263 in _PyEval_EvalFrameDefault (tstate=<optimized out>, frame=<optimized out>, throwflag=<optimized out>) at Python/generated_cases.c.h:1838
#7  0x0000555555e57778 in _PyEval_EvalFrame (tstate=0x5555568f7b18 <_PyRuntime+360664>, frame=0x7e8ff6fe5220, throwflag=0) at ./Include/internal/pycore_ceval.h:118
#8  _PyEval_Vector (tstate=<optimized out>, func=<optimized out>, locals=<optimized out>, args=<optimized out>, argcount=<optimized out>, kwnames=0x0) at Python/ceval.c:2134
#9  0x0000555555e57195 in PyEval_EvalCode (co=<optimized out>, globals=<optimized out>, locals=0x7c7ff70884c0) at Python/ceval.c:681
#10 0x0000555556061fb0 in run_eval_code_obj (tstate=tstate@entry=0x5555568f7b18 <_PyRuntime+360664>, co=co@entry=0x7d2ff6ffde10, globals=globals@entry=0x7c7ff70884c0,
    locals=locals@entry=0x7c7ff70884c0) at Python/pythonrun.c:1368
#11 0x000055555606117c in run_mod (mod=<optimized out>, filename=<optimized out>, globals=<optimized out>, locals=<optimized out>, flags=<optimized out>, arena=<optimized out>,
    interactive_src=<optimized out>, generate_new_source=<optimized out>) at Python/pythonrun.c:1471
#12 0x000055555605b69d in pyrun_file (fp=fp@entry=0x7d4ff6fefd00, filename=filename@entry=0x7cbff6ffc490, start=start@entry=257, globals=globals@entry=0x7c7ff70884c0,
    locals=locals@entry=0x7c7ff70884c0, closeit=closeit@entry=1, flags=0x7bfff5e1ef10) at Python/pythonrun.c:1295
#13 0x00005555560591fd in _PyRun_SimpleFileObject (fp=<optimized out>, filename=<optimized out>, closeit=<optimized out>, flags=<optimized out>) at Python/pythonrun.c:518
#14 0x000055555605856e in _PyRun_AnyFileObject (fp=fp@entry=0x7d4ff6fefd00, filename=filename@entry=0x7cbff6ffc490, closeit=closeit@entry=1, flags=flags@entry=0x7bfff5e1ef10)
    at Python/pythonrun.c:81
#15 0x00005555560d721b in pymain_run_file_obj (program_name=0x7caff7024fc0, filename=0x7cbff6ffc490, skip_source_first_line=0) at Modules/main.c:410
#16 pymain_run_file (config=0x5555568c2b50 <_PyRuntime+143632>) at Modules/main.c:429
#17 0x00005555560d54b2 in pymain_run_python (exitcode=0x7bfff5e1eb00) at Modules/main.c:714
#18 Py_RunMain () at Modules/main.c:795

Found using cpython-review-toolkit with Claude Opus 4.6, using the /cpython-review-toolkit:explore Modules/_zoneinfo.c all deep command.

CPython versions tested on:

CPython main branch

Operating systems tested on:

Linux

Output from running 'python -VV' on the command line:

Python 3.15.0a7+ (heads/main:99e2c5eccd2, Mar 17 2026, 08:26:50) [Clang 21.1.2 (2ubuntu6)]

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    extension-modulesC modules in the Modules dirtype-crashA hard crash of the interpreter, possibly with a core dump

    Projects

    Status

    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions