From 295bba52f4e712396f367a22bd3f0ab6f8cfee0a Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith" Date: Sun, 13 Apr 2025 22:16:12 -0700 Subject: [PATCH 1/3] GH-115322: fix ctypes call_function audit hook on 32-bit platforms. It was using a signed conversion to communicate the function id (pointer) value. --- Modules/_ctypes/callproc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c index f5db49ff4bc61c..848f06e138b87a 100644 --- a/Modules/_ctypes/callproc.c +++ b/Modules/_ctypes/callproc.c @@ -1199,8 +1199,8 @@ PyObject *_ctypes_callproc(ctypes_state *st, PyObject *retval = NULL; // Both call_function and call_cdeclfunction call us: - if (PySys_Audit("ctypes.call_function", "nO", - (Py_ssize_t)pProc, argtuple) < 0) { + if (PySys_Audit("ctypes.call_function", "KO", + (unsigned long long)pProc, argtuple) < 0) { return NULL; } From 07ea52ad1914c79aa324f6a7df9f3f6f95ff587a Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith" Date: Sun, 13 Apr 2025 22:21:34 -0700 Subject: [PATCH 2/3] update-news --- .../Security/2024-02-18-02-53-25.gh-issue-115322.Um2Sjx.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Security/2024-02-18-02-53-25.gh-issue-115322.Um2Sjx.rst b/Misc/NEWS.d/next/Security/2024-02-18-02-53-25.gh-issue-115322.Um2Sjx.rst index a09e1f1fcdcab7..8eb5c3ed04ee2c 100644 --- a/Misc/NEWS.d/next/Security/2024-02-18-02-53-25.gh-issue-115322.Um2Sjx.rst +++ b/Misc/NEWS.d/next/Security/2024-02-18-02-53-25.gh-issue-115322.Um2Sjx.rst @@ -1,4 +1,5 @@ The underlying extension modules behind :mod:`readline`:, :mod:`subprocess`, and :mod:`ctypes` now raise audit events on previously uncovered code paths that could lead to file system access related to C function calling and -external binary execution. +external binary execution. The ``ctypes.call_function`` audit hook has also +been fixed to use an unsigned value for its ``function pointer``. From 100c52f8eaa0314d00cb71faa544293682a36af6 Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith" Date: Sun, 13 Apr 2025 22:58:32 -0700 Subject: [PATCH 3/3] Fix the pointer size determination. --- Lib/test/audit-tests.py | 4 ++-- Modules/_ctypes/callproc.c | 9 +++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/Lib/test/audit-tests.py b/Lib/test/audit-tests.py index 3d81f27e5cb46d..08b638e4b8d524 100644 --- a/Lib/test/audit-tests.py +++ b/Lib/test/audit-tests.py @@ -311,10 +311,10 @@ def test_ctypes_call_function(): with TestHook() as hook: _ctypes.call_function(ctypes._memmove_addr, (0, 0, 0)) - assert ("ctypes.call_function", (ctypes._memmove_addr, (0, 0, 0))) in hook.seen + assert ("ctypes.call_function", (ctypes._memmove_addr, (0, 0, 0))) in hook.seen, f"{ctypes._memmove_addr=} {hook.seen=}" ctypes.CFUNCTYPE(ctypes.c_voidp)(ctypes._memset_addr)(1, 0, 0) - assert ("ctypes.call_function", (ctypes._memset_addr, (1, 0, 0))) in hook.seen + assert ("ctypes.call_function", (ctypes._memset_addr, (1, 0, 0))) in hook.seen, f"{ctypes._memset_addr=} {hook.seen=}" with TestHook() as hook: ctypes.cast(ctypes.c_voidp(0), ctypes.POINTER(ctypes.c_char)) diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c index 848f06e138b87a..cb8ab7b33a2953 100644 --- a/Modules/_ctypes/callproc.c +++ b/Modules/_ctypes/callproc.c @@ -1199,8 +1199,17 @@ PyObject *_ctypes_callproc(ctypes_state *st, PyObject *retval = NULL; // Both call_function and call_cdeclfunction call us: +#if SIZEOF_VOID_P == SIZEOF_LONG + if (PySys_Audit("ctypes.call_function", "kO", + (unsigned long)pProc, argtuple) < 0) { +#elif SIZEOF_VOID_P == SIZEOF_LONG_LONG if (PySys_Audit("ctypes.call_function", "KO", (unsigned long long)pProc, argtuple) < 0) { +#else +# warning "unexpected pointer size, you may see odd values in audit hooks" + if (PySys_Audit("ctypes.call_function", "nO", + (Py_ssize_t)pProc, argtuple) < 0) { +#endif return NULL; }