gh-134100: Fix use-after-free in PyImport_ImportModuleLevelObject (#134117)

This commit is contained in:
Nico-Posada 2025-05-18 03:11:38 -04:00 committed by GitHub
parent fa4e088668
commit 4e9005d32f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 20 additions and 1 deletions

View file

@ -223,6 +223,21 @@ class RelativeImports:
self.__import__('sys', {'__package__': '', '__spec__': None}, self.__import__('sys', {'__package__': '', '__spec__': None},
level=1) level=1)
def test_malicious_relative_import(self):
# https://github.com/python/cpython/issues/134100
# Test to make sure UAF bug with error msg doesn't come back to life
import sys
loooong = "".ljust(0x23000, "b")
name = f"a.{loooong}.c"
with util.uncache(name):
sys.modules[name] = {}
with self.assertRaisesRegex(
KeyError,
r"'a\.b+' not in sys\.modules as expected"
):
__import__(f"{loooong}.c", {"__package__": "a"}, level=1)
(Frozen_RelativeImports, (Frozen_RelativeImports,
Source_RelativeImports Source_RelativeImports

View file

@ -0,0 +1,2 @@
Fix a use-after-free bug that occurs when an imported module isn't
in :data:`sys.modules` after its initial import. Patch by Nico-Posada.

View file

@ -3854,15 +3854,17 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals,
} }
final_mod = import_get_module(tstate, to_return); final_mod = import_get_module(tstate, to_return);
Py_DECREF(to_return);
if (final_mod == NULL) { if (final_mod == NULL) {
if (!_PyErr_Occurred(tstate)) { if (!_PyErr_Occurred(tstate)) {
_PyErr_Format(tstate, PyExc_KeyError, _PyErr_Format(tstate, PyExc_KeyError,
"%R not in sys.modules as expected", "%R not in sys.modules as expected",
to_return); to_return);
} }
Py_DECREF(to_return);
goto error; goto error;
} }
Py_DECREF(to_return);
} }
} }
else { else {