]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-102660: Fix is_core_module() (gh-103257)
authorEric Snow <ericsnowcurrently@gmail.com>
Tue, 4 Apr 2023 23:03:40 +0000 (17:03 -0600)
committerGitHub <noreply@github.com>
Tue, 4 Apr 2023 23:03:40 +0000 (17:03 -0600)
In gh-102744 we added is_core_module() (in Python/import.c), which relies on get_core_module_dict() (also added in that PR).  The problem is that_PyImport_FixupBuiltin(), which ultimately calls is_core_module(), is called on the builtins module before interp->builtins_copyis set.  Consequently, the builtins module isn't considered a "core" module while it is getting "fixed up" and its module def m_copy erroneously gets set.  Under isolated interpreters this causes problems since sys and builtins are allowed even though they are still single-phase init modules.  (This was discovered while working on gh-101660.)

The solution is to stop relying on get_core_module_dict() in is_core_module().

Python/import.c

index 24249ae4a6ade192cb420889728f32a78be0a0af..1db5b9333bbba1311640efc995aef8f9d2bc4f3c 100644 (file)
@@ -1110,7 +1110,17 @@ get_core_module_dict(PyInterpreterState *interp,
 static inline int
 is_core_module(PyInterpreterState *interp, PyObject *name, PyObject *filename)
 {
-    return get_core_module_dict(interp, name, filename) != NULL;
+    /* This might be called before the core dict copies are in place,
+       so we can't rely on get_core_module_dict() here. */
+    if (filename == name) {
+        if (PyUnicode_CompareWithASCIIString(name, "sys") == 0) {
+            return 1;
+        }
+        if (PyUnicode_CompareWithASCIIString(name, "builtins") == 0) {
+            return 1;
+        }
+    }
+    return 0;
 }
 
 static int
@@ -1136,6 +1146,8 @@ fix_up_extension(PyObject *mod, PyObject *name, PyObject *filename)
     // when the extension module doesn't support sub-interpreters.
     if (def->m_size == -1) {
         if (!is_core_module(tstate->interp, name, filename)) {
+            assert(PyUnicode_CompareWithASCIIString(name, "sys") != 0);
+            assert(PyUnicode_CompareWithASCIIString(name, "builtins") != 0);
             if (def->m_base.m_copy) {
                 /* Somebody already imported the module,
                    likely under a different name.