https://github.com/python/cpython/commit/3e19e0408d9791c235c6c85818de1b9b2eb93dfa
commit: 3e19e0408d9791c235c6c85818de1b9b2eb93dfa
branch: main
author: Jelle Zijlstra <[email protected]>
committer: JelleZijlstra <[email protected]>
date: 2026-10-22T14:16:04-07:00
summary:
gh-159739: Detect recursive untyped ctypes arguments (#160194)
_as_parameter_ chains were recursion-checked for typed arguments but not for
foreign calls without argtypes. A cyclic chain could exhaust the C stack and
crash before the function was called. Apply the same recursion guard to untyped
conversion. Backport to 3.15 and 3.14.
files:
A Misc/NEWS.d/next/Library/2026-10-21-21-26-10.gh-issue-159739.b4ueJ7.rst
M Lib/test/test_ctypes/test_as_parameter.py
M Modules/_ctypes/callproc.c
diff --git a/Lib/test/test_ctypes/test_as_parameter.py
b/Lib/test/test_ctypes/test_as_parameter.py
index 8634c3f03a02ec..dc383a12ce8bb3 100644
--- a/Lib/test/test_ctypes/test_as_parameter.py
+++ b/Lib/test/test_ctypes/test_as_parameter.py
@@ -214,6 +214,10 @@ class A:
with self.assertRaises(RecursionError):
c_type.from_param(a)
+ function = CDLL(_ctypes_test.__file__)._testfunc_p_p
+ with self.assertRaisesRegex(ArgumentError, 'RecursionError'):
+ function(a)
+
class AsParamWrapper:
def __init__(self, param):
diff --git
a/Misc/NEWS.d/next/Library/2026-10-21-21-26-10.gh-issue-159739.b4ueJ7.rst
b/Misc/NEWS.d/next/Library/2026-10-21-21-26-10.gh-issue-159739.b4ueJ7.rst
new file mode 100644
index 00000000000000..6230801bbc0927
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2026-10-21-21-26-10.gh-issue-159739.b4ueJ7.rst
@@ -0,0 +1 @@
+Detect recursive ``_as_parameter_`` chains for :mod:`ctypes` calls without
argument types.
diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c
index 84aa8c1443fdf5..c8a54b0cec83a7 100644
--- a/Modules/_ctypes/callproc.c
+++ b/Modules/_ctypes/callproc.c
@@ -91,6 +91,7 @@ module _ctypes
#define DONT_USE_SEH
#endif
+#include "pycore_ceval.h" // _Py_EnterRecursiveCall()
#include "pycore_runtime.h" // _PyRuntime
#include "pycore_global_objects.h"// _Py_ID()
#include "pycore_traceback.h" // _PyTraceback_Add()
@@ -795,8 +796,12 @@ static int ConvParam(ctypes_state *st,
attribute)
*/
if (arg) {
- int result;
- result = ConvParam(st, arg, index, pa);
+ if (_Py_EnterRecursiveCall(" while processing _as_parameter_")) {
+ Py_DECREF(arg);
+ return -1;
+ }
+ int result = ConvParam(st, arg, index, pa);
+ _Py_LeaveRecursiveCall();
Py_DECREF(arg);
return result;
}
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]