gh-142349: Fix refcount corruption in lazy import specialization (#144733)

Remove spurious Py_DECREF on borrowed ref in LOAD_GLOBAL specialization

_PyDict_LookupIndexAndValue() returns a borrowed reference via
_Py_dict_lookup(), but specialize_load_global_lock_held() called
Py_DECREF(value) on it when bailing out for lazy imports. Each time
the adaptive counter fired while a lazy import was still in globals,
this stole one reference from the dict's object. With 8+ threads
racing through LOAD_GLOBAL during concurrent lazy import resolution,
enough triggers accumulated to drive the refcount to zero while the
dict and other threads still referenced the object, causing
use-after-free.
This commit is contained in:
Pablo Galindo Salgado 2026-02-12 11:45:28 +00:00 committed by GitHub
parent 2e3e76e5cd
commit 072cd7c336
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -1321,7 +1321,6 @@ specialize_load_global_lock_held(
}
if (value != NULL && PyLazyImport_CheckExact(value)) {
SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_ATTR_MODULE_LAZY_VALUE);
Py_DECREF(value);
goto fail;
}
PyInterpreterState *interp = _PyInterpreterState_GET();