static PyObject *
zoneinfo_ZoneInfo_impl(PyTypeObject *type, PyObject *key)
/*[clinic end generated code: output=95e61dab86bb95c3 input=ef73d7a83bf8790e]*/
{
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;
}
// Bug: Type Confusion
((PyZoneInfo_ZoneInfo *)instance)->source = SOURCE_CACHE;
}
update_strong_cache(state, type, key, instance);
return instance;
}
What happened?
Handler
zoneinfo_ZoneInfo_impl()callsweak_cache.setdefault(key, tmp)and blindly treats the returned object as aZoneInfo, immediately casting toPyZoneInfo_ZoneInfoand writing to its fields. A subclass can swap_weak_cachewith a dict-like object whosesetdefault()returns a non-ZoneInfo(e.g., anint), causing type confusion and subsequent memory corruption/crash under ASan. A minimal PoC overridessetdefault()to return the wrong type and triggers a buffer overflow during teardown.Proof of Concept:
Affected Versions:
Details
Python 3.9.24+ (heads/3.9:9c4638d, Oct 17 2025, 11:19:30)Python 3.10.19+ (heads/3.10:0142619, Oct 17 2025, 11:20:05) [GCC 13.3.0]Python 3.11.14+ (heads/3.11:88f3f5b, Oct 17 2025, 11:20:44) [GCC 13.3.0]Python 3.12.12+ (heads/3.12:8cb2092, Oct 17 2025, 11:21:35) [GCC 13.3.0]Python 3.13.9+ (heads/3.13:0760a57, Oct 17 2025, 11:22:25) [GCC 13.3.0]Python 3.14.0+ (heads/3.14:889e918, Oct 17 2025, 11:23:02) [GCC 13.3.0]Python 3.15.0a1+ (heads/main:fbf0843, Oct 17 2025, 11:23:37) [GCC 13.3.0]Related Code Snippet
Details
Sanitizer Report
Details
Linked PRs