Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 34k
Closed
Labels
extension-modulesC modules in the Modules dirC modules in the Modules dirtype-crashA hard crash of the interpreter, possibly with a core dumpA hard crash of the interpreter, possibly with a core dump
Description
What happened?
get_weak_cache() assumes that _weak_cache is always owned by the object and safe to DECREF. When _weak_cache is a descriptor returning a new object, this assumption breaks, causing the cache object to be freed too early and leading to a use-after-free in zoneinfo_ZoneInfo_impl().
Proof of Concept:
fromzoneinfoimportZoneInfoclassCache: defget(self, *args, **kwargs): returnNonedefsetdefault(self, *args, **kwargs): returnNonedefclear(self, *args, **kwargs): passclassBombDescriptor: def__get__(self, obj, owner): returnCache() classEvilZoneInfo(ZoneInfo): passEvilZoneInfo._weak_cache=BombDescriptor() EvilZoneInfo("UTC")Related Code Snippet
static PyObject * zoneinfo_ZoneInfo_impl(PyTypeObject *type, PyObject *key) /*[clinic end generated code: output=95e61dab86bb95c3 input=ef73d7a83bf8790e]*/{zoneinfo_state *state = zoneinfo_get_state_by_self(type); PyObject *instance = zone_from_strong_cache(state, type, key); // Trigged __eq__ method if (instance != NULL || PyErr_Occurred()){return instance} PyObject *weak_cache = get_weak_cache(state, type); instance = PyObject_CallMethod(weak_cache, "get", "O", key, Py_None); if (instance == NULL){return NULL} if (instance == Py_None){Py_DECREF(instance); PyObject *tmp = zoneinfo_new_instance(state, type, key); if (tmp == NULL){return NULL} instance = PyObject_CallMethod(weak_cache, "setdefault", "OO", key, tmp); Py_DECREF(tmp); if (instance == NULL){return NULL} ((PyZoneInfo_ZoneInfo *)instance)->source = SOURCE_CACHE} update_strong_cache(state, type, key, instance); return instance} static PyObject * get_weak_cache(zoneinfo_state *state, PyTypeObject *type){if (type == state->ZoneInfoType){return state->ZONEINFO_WEAK_CACHE} else{PyObject *cache = PyObject_GetAttrString((PyObject *)type, "_weak_cache"); // BUG: The following DECREF free the newly assign cache and leads to UAF // We are assuming that the type lives at least as long as the function // that calls get_weak_cache, and that it holds a reference to the // cache, so we'll return a "borrowed reference". Py_XDECREF(cache); return cache} } Affected Versions:
| Python Version | Status | Exit Code |
|---|---|---|
Python 3.9.24+ (heads/3.9:9c4638d, Oct 17 2025, 11:19:30) | ASAN | 1 |
Python 3.10.19+ (heads/3.10:0142619, Oct 17 2025, 11:20:05) [GCC 13.3.0] | ASAN | 1 |
Python 3.11.14+ (heads/3.11:88f3f5b, Oct 17 2025, 11:20:44) [GCC 13.3.0] | ASAN | 1 |
Python 3.12.12+ (heads/3.12:8cb2092, Oct 17 2025, 11:21:35) [GCC 13.3.0] | ASAN | 1 |
Python 3.13.9+ (heads/3.13:0760a57, Oct 17 2025, 11:22:25) [GCC 13.3.0] | ASAN | 1 |
Python 3.14.0+ (heads/3.14:889e918, Oct 17 2025, 11:23:02) [GCC 13.3.0] | ASAN | 1 |
Python 3.15.0a1+ (heads/main:fbf0843, Oct 17 2025, 11:23:37) [GCC 13.3.0] | ASAN | 1 |
Sanitizer Report
===================================================================1448338==ERROR: AddressSanitizer: heap-use-after-freeonaddress0x513000037278atpc0x59e6317834efbp0x7ffc3a4859b0sp0x7ffc3a4859a0READofsize8at0x513000037278threadT0#0 0x59e6317834ee in _Py_TYPE Include/object.h:277#1 0x59e6317834ee in PyObject_GetAttrString Objects/object.c:1178#2 0x59e6316c3b2a in PyObject_CallMethod Objects/call.c:638#3 0x7674c13914f2 in zoneinfo_ZoneInfo_impl Modules/_zoneinfo.c:329#4 0x7674c1391710 in zoneinfo_ZoneInfo Modules/clinic/_zoneinfo.c.h:64#5 0x59e6317e9346 in type_call Objects/typeobject.c:2448#6 0x59e6316c2c71 in _PyObject_MakeTpCall Objects/call.c:242#7 0x59e6316c2f19 in _PyObject_VectorcallTstate Include/internal/pycore_call.h:167#8 0x59e6316c2f72 in PyObject_Vectorcall Objects/call.c:327#9 0x59e631941056 in _PyEval_EvalFrameDefault Python/generated_cases.c.h:1620#10 0x59e631984e54 in _PyEval_EvalFrame Include/internal/pycore_ceval.h:121#11 0x59e631985148 in _PyEval_Vector Python/ceval.c:2001#12 0x59e6319853f8 in PyEval_EvalCode Python/ceval.c:884#13 0x59e631a7c507 in run_eval_code_obj Python/pythonrun.c:1365#14 0x59e631a7c723 in run_mod Python/pythonrun.c:1459#15 0x59e631a7d57a in pyrun_file Python/pythonrun.c:1293#16 0x59e631a80220 in _PyRun_SimpleFileObject Python/pythonrun.c:521#17 0x59e631a804f6 in _PyRun_AnyFileObject Python/pythonrun.c:81#18 0x59e631ad174d in pymain_run_file_obj Modules/main.c:410#19 0x59e631ad19b4 in pymain_run_file Modules/main.c:429#20 0x59e631ad31b2 in pymain_run_python Modules/main.c:691#21 0x59e631ad3842 in Py_RunMain Modules/main.c:772#22 0x59e631ad3a2e in pymain_main Modules/main.c:802#23 0x59e631ad3db3 in Py_BytesMain Modules/main.c:826#24 0x59e631557645 in main Programs/python.c:15#25 0x7674c202a1c9 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58#26 0x7674c202a28a in __libc_start_main_impl ../csu/libc-start.c:360#27 0x59e631557574 in _start (/home/jackfromeast/Desktop/entropy/tasks/grammar-afl++-latest/targets/cpython/python+0x2dd574) (BuildId: ff3dc40ea460bd4beb2c3a72283cca525b319bf0)0x513000037278islocated56bytesinsideof352-byteregion [0x513000037240,0x5130000373a0) freedbythreadT0here: #0 0x7674c24fc4d8 in free ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:52#1 0x59e63178996d in _PyMem_RawFree Objects/obmalloc.c:91#2 0x59e63178bcd9 in _PyMem_DebugRawFree Objects/obmalloc.c:2955#3 0x59e63178bd1a in _PyMem_DebugFree Objects/obmalloc.c:3100#4 0x59e6317b406c in PyObject_Free Objects/obmalloc.c:1522#5 0x59e6319f2cf7 in PyObject_GC_Del Python/gc.c:2435#6 0x59e6317ce1cb in object_dealloc Objects/typeobject.c:7177#7 0x59e6317ec663 in subtype_dealloc Objects/typeobject.c:2852#8 0x59e631780481 in _Py_Dealloc Objects/object.c:3200#9 0x7674c138967b in Py_DECREF Include/refcount.h:401#10 0x7674c138969a in Py_XDECREF Include/refcount.h:511#11 0x7674c138b07b in get_weak_cache Modules/_zoneinfo.c:303#12 0x7674c13914ca in zoneinfo_ZoneInfo_impl Modules/_zoneinfo.c:328#13 0x7674c1391710 in zoneinfo_ZoneInfo Modules/clinic/_zoneinfo.c.h:64#14 0x59e6317e9346 in type_call Objects/typeobject.c:2448#15 0x59e6316c2c71 in _PyObject_MakeTpCall Objects/call.c:242#16 0x59e6316c2f19 in _PyObject_VectorcallTstate Include/internal/pycore_call.h:167#17 0x59e6316c2f72 in PyObject_Vectorcall Objects/call.c:327#18 0x59e631941056 in _PyEval_EvalFrameDefault Python/generated_cases.c.h:1620#19 0x59e631984e54 in _PyEval_EvalFrame Include/internal/pycore_ceval.h:121#20 0x59e631985148 in _PyEval_Vector Python/ceval.c:2001#21 0x59e6319853f8 in PyEval_EvalCode Python/ceval.c:884#22 0x59e631a7c507 in run_eval_code_obj Python/pythonrun.c:1365#23 0x59e631a7c723 in run_mod Python/pythonrun.c:1459#24 0x59e631a7d57a in pyrun_file Python/pythonrun.c:1293#25 0x59e631a80220 in _PyRun_SimpleFileObject Python/pythonrun.c:521#26 0x59e631a804f6 in _PyRun_AnyFileObject Python/pythonrun.c:81#27 0x59e631ad174d in pymain_run_file_obj Modules/main.c:410#28 0x59e631ad19b4 in pymain_run_file Modules/main.c:429#29 0x59e631ad31b2 in pymain_run_python Modules/main.c:691previouslyallocatedbythreadT0here: #0 0x7674c24fd9c7 in malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69#1 0x59e63178a284 in _PyMem_RawMalloc Objects/obmalloc.c:63#2 0x59e631789655 in _PyMem_DebugRawAlloc Objects/obmalloc.c:2887#3 0x59e6317896bd in _PyMem_DebugRawMalloc Objects/obmalloc.c:2920#4 0x59e63178af3b in _PyMem_DebugMalloc Objects/obmalloc.c:3085#5 0x59e6317b3f28 in PyObject_Malloc Objects/obmalloc.c:1493#6 0x59e6317e603b in _PyObject_MallocWithType Include/internal/pycore_object_alloc.h:46#7 0x59e6317e603b in _PyType_AllocNoTrack Objects/typeobject.c:2504#8 0x59e6317e61c7 in PyType_GenericAlloc Objects/typeobject.c:2535#9 0x59e6317de10e in object_new Objects/typeobject.c:7167#10 0x59e6317e9346 in type_call Objects/typeobject.c:2448#11 0x59e6316c2c71 in _PyObject_MakeTpCall Objects/call.c:242#12 0x59e6316c2f19 in _PyObject_VectorcallTstate Include/internal/pycore_call.h:167#13 0x59e6316c2f72 in PyObject_Vectorcall Objects/call.c:327#14 0x59e631941056 in _PyEval_EvalFrameDefault Python/generated_cases.c.h:1620#15 0x59e631984e54 in _PyEval_EvalFrame Include/internal/pycore_ceval.h:121#16 0x59e631985148 in _PyEval_Vector Python/ceval.c:2001#17 0x59e6316c29b8 in _PyFunction_Vectorcall Objects/call.c:413#18 0x59e6316c2e7f in _PyObject_VectorcallTstate Include/internal/pycore_call.h:169#19 0x59e6316c2f72 in PyObject_Vectorcall Objects/call.c:327#20 0x59e6317fbf01 in slot_tp_descr_get Objects/typeobject.c:10799#21 0x59e6317fdb53 in _Py_type_getattro_impl Objects/typeobject.c:6377#22 0x59e6317fdd37 in _Py_type_getattro Objects/typeobject.c:6419#23 0x59e6317831cc in PyObject_GetAttr Objects/object.c:1313#24 0x59e63178350e in PyObject_GetAttrString Objects/object.c:1183#25 0x7674c138b070 in get_weak_cache Modules/_zoneinfo.c:299#26 0x7674c13914ca in zoneinfo_ZoneInfo_impl Modules/_zoneinfo.c:328#27 0x7674c1391710 in zoneinfo_ZoneInfo Modules/clinic/_zoneinfo.c.h:64#28 0x59e6317e9346 in type_call Objects/typeobject.c:2448#29 0x59e6316c2c71 in _PyObject_MakeTpCall Objects/call.c:242#30 0x59e6316c2f19 in _PyObject_VectorcallTstate Include/internal/pycore_call.h:167SUMMARY: AddressSanitizer: heap-use-after-freeInclude/object.h:277in_Py_TYPEShadowbytesaroundthebuggyaddress: 0x513000036f80: fdfdfdfdfdfdfdfdfdfdfdfdfdfdfdfd0x513000037000: fdfdfdfafafafafafafafafafafafafa0x513000037080: 000000000000000000000000000000000x513000037100: 000000000000000000000000000000000x513000037180: 000000000000000000000000fafafafa=>0x513000037200: fafafafafafafafafdfdfdfdfdfdfd[fd] 0x513000037280: fdfdfdfdfdfdfdfdfdfdfdfdfdfdfdfd0x513000037300: fdfdfdfdfdfdfdfdfdfdfdfdfdfdfdfd0x513000037380: fdfdfdfdfafafafafafafafafafafafa0x513000037400: fafafafafafafafafafafafafafafafa0x513000037480: fafafafafafafafafafafafafafafafaShadowbytelegend (oneshadowbyterepresents8applicationbytes): Addressable: 00Partiallyaddressable: 01020304050607Heapleftredzone: faFreedheapregion: fdStackleftredzone: f1Stackmidredzone: f2Stackrightredzone: f3Stackafterreturn: f5Stackuseafterscope: f8Globalredzone: f9Globalinitorder: f6Poisonedbyuser: f7Containeroverflow: fcArraycookie: acIntraobjectredzone: bbASaninternal: feLeftallocaredzone: caRightallocaredzone: cb==1448338==ABORTINGLinked PRs
- gh-142783: Fix use-after-free vulnerability in zoneinfo module #142786
- gh-142783: Fix possible use after free in zoneinfo module #142790
- [3.13] gh-142783: Fix possible use after free in zoneinfo module (GH-142790) #142861
- [3.14] gh-142783: Fix possible use after free in zoneinfo module (GH-142790) #142862
Metadata
Metadata
Assignees
Labels
extension-modulesC modules in the Modules dirC modules in the Modules dirtype-crashA hard crash of the interpreter, possibly with a core dumpA hard crash of the interpreter, possibly with a core dump
Projects
Status
Done