]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-127081: lock non-re-entrant `*pwent` calls in free-threading (#132748)
authorDuane Griffin <duaneg@dghda.com>
Thu, 22 May 2025 10:22:02 +0000 (22:22 +1200)
committerGitHub <noreply@github.com>
Thu, 22 May 2025 10:22:02 +0000 (15:52 +0530)
Misc/NEWS.d/next/Library/2025-04-21-00-58-04.gh-issue-127081.3DCl92.rst [new file with mode: 0644]
Modules/pwdmodule.c

diff --git a/Misc/NEWS.d/next/Library/2025-04-21-00-58-04.gh-issue-127081.3DCl92.rst b/Misc/NEWS.d/next/Library/2025-04-21-00-58-04.gh-issue-127081.3DCl92.rst
new file mode 100644 (file)
index 0000000..a99669a
--- /dev/null
@@ -0,0 +1,2 @@
+Fix libc thread safety issues with :mod:`pwd` by locking access to
+``getpwall``.
index 2240e2078b2d982719bbfaef912e53dee2691adb..c5a8cead19a773d3090c2bd2684f9d1105b9ba12 100644 (file)
@@ -301,18 +301,33 @@ pwd_getpwall_impl(PyObject *module)
     struct passwd *p;
     if ((d = PyList_New(0)) == NULL)
         return NULL;
+
+#ifdef Py_GIL_DISABLED
+    static PyMutex getpwall_mutex = {0};
+    PyMutex_Lock(&getpwall_mutex);
+#endif
+    int failure = 0;
+    PyObject *v = NULL;
     setpwent();
     while ((p = getpwent()) != NULL) {
-        PyObject *v = mkpwent(module, p);
+        v = mkpwent(module, p);
         if (v == NULL || PyList_Append(d, v) != 0) {
-            Py_XDECREF(v);
-            Py_DECREF(d);
-            endpwent();
-            return NULL;
+            /* NOTE: cannot dec-ref here, while holding the mutex. */
+            failure = 1;
+            goto done;
         }
         Py_DECREF(v);
     }
+
+done:
     endpwent();
+#ifdef Py_GIL_DISABLED
+    PyMutex_Unlock(&getpwall_mutex);
+#endif
+    if (failure) {
+        Py_XDECREF(v);
+        Py_CLEAR(d);
+    }
     return d;
 }
 #endif