https://github.com/python/cpython/commit/1ddfe593200fec992d283a9b4d6ad2f1b535c018
commit: 1ddfe593200fec992d283a9b4d6ad2f1b535c018
branch: main
author: Nadeshiko Manju <[email protected]>
committer: zooba <[email protected]>
date: 2025-06-19T21:23:38+01:00
summary:
gh-135543: Emit sys.remote_exec audit event when sys.remote_exec is called
(GH-135544)
files:
A
Misc/NEWS.d/next/Core_and_Builtins/2025-06-16-02-31-42.gh-issue-135543.6b0HOF.rst
M Doc/library/sys.rst
M Lib/test/audit-tests.py
M Lib/test/support/__init__.py
M Lib/test/test_audit.py
M Lib/test/test_sys.py
M Python/ceval_gil.c
M Python/sysmodule.c
diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst
index 71f9999464ab52..f8f727f4a23410 100644
--- a/Doc/library/sys.rst
+++ b/Doc/library/sys.rst
@@ -1933,12 +1933,21 @@ always available. Unless explicitly noted otherwise,
all variables are read-only
interpreter is pre-release (alpha, beta, or release candidate) then the
local and remote interpreters must be the same exact version.
- .. audit-event:: remote_debugger_script script_path
+ .. audit-event:: sys.remote_exec pid script_path
+
+ When the code is executed in the remote process, an
+ :ref:`auditing event <auditing>` ``sys.remote_exec`` is raised with
+ the *pid* and the path to the script file.
+ This event is raised in the process that called :func:`sys.remote_exec`.
+
+ .. audit-event:: cpython.remote_debugger_script script_path
When the script is executed in the remote process, an
:ref:`auditing event <auditing>`
- ``sys.remote_debugger_script`` is raised
+ ``cpython.remote_debugger_script`` is raised
with the path in the remote process.
+ This event is raised in the remote process, not the one
+ that called :func:`sys.remote_exec`.
.. availability:: Unix, Windows.
.. versionadded:: 3.14
diff --git a/Lib/test/audit-tests.py b/Lib/test/audit-tests.py
index 08b638e4b8d524..6884ac0dbe6ff0 100644
--- a/Lib/test/audit-tests.py
+++ b/Lib/test/audit-tests.py
@@ -643,6 +643,34 @@ def test_assert_unicode():
else:
raise RuntimeError("Expected sys.audit(9) to fail.")
+def test_sys_remote_exec():
+ import tempfile
+
+ pid = os.getpid()
+ event_pid = -1
+ event_script_path = ""
+ remote_event_script_path = ""
+ def hook(event, args):
+ if event not in ["sys.remote_exec", "cpython.remote_debugger_script"]:
+ return
+ print(event, args)
+ match event:
+ case "sys.remote_exec":
+ nonlocal event_pid, event_script_path
+ event_pid = args[0]
+ event_script_path = args[1]
+ case "cpython.remote_debugger_script":
+ nonlocal remote_event_script_path
+ remote_event_script_path = args[0]
+
+ sys.addaudithook(hook)
+ with tempfile.NamedTemporaryFile(mode='w+', delete=True) as tmp_file:
+ tmp_file.write("a = 1+1\n")
+ tmp_file.flush()
+ sys.remote_exec(pid, tmp_file.name)
+ assertEqual(event_pid, pid)
+ assertEqual(event_script_path, tmp_file.name)
+ assertEqual(remote_event_script_path, tmp_file.name)
if __name__ == "__main__":
from test.support import suppress_msvcrt_asserts
diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py
index 48e74adcce3bb7..51c0ce11e8269d 100644
--- a/Lib/test/support/__init__.py
+++ b/Lib/test/support/__init__.py
@@ -46,6 +46,7 @@
# sys
"MS_WINDOWS", "is_jython", "is_android", "is_emscripten", "is_wasi",
"is_apple_mobile", "check_impl_detail", "unix_shell", "setswitchinterval",
+ "support_remote_exec_only",
# os
"get_pagesize",
# network
@@ -3069,6 +3070,27 @@ def is_libssl_fips_mode():
return False # more of a maybe, unless we add this to the _ssl module.
return get_fips_mode() != 0
+def _supports_remote_attaching():
+ PROCESS_VM_READV_SUPPORTED = False
+
+ try:
+ from _remote_debugging import PROCESS_VM_READV_SUPPORTED
+ except ImportError:
+ pass
+
+ return PROCESS_VM_READV_SUPPORTED
+
+def _support_remote_exec_only_impl():
+ if not sys.is_remote_debug_enabled():
+ return unittest.skip("Remote debugging is not enabled")
+ if sys.platform not in ("darwin", "linux", "win32"):
+ return unittest.skip("Test only runs on Linux, Windows and macOS")
+ if sys.platform == "linux" and not _supports_remote_attaching():
+ return unittest.skip("Test only runs on Linux with process_vm_readv
support")
+ return _id
+
+def support_remote_exec_only(test):
+ return _support_remote_exec_only_impl()(test)
class EqualToForwardRef:
"""Helper to ease use of annotationlib.ForwardRef in tests.
diff --git a/Lib/test/test_audit.py b/Lib/test/test_audit.py
index 5f9eb381f605d9..077765fcda210a 100644
--- a/Lib/test/test_audit.py
+++ b/Lib/test/test_audit.py
@@ -322,6 +322,14 @@ def test_assert_unicode(self):
if returncode:
self.fail(stderr)
+ @support.support_remote_exec_only
+ @support.cpython_only
+ def test_sys_remote_exec(self):
+ returncode, events, stderr = self.run_python("test_sys_remote_exec")
+ self.assertTrue(any(["sys.remote_exec" in event for event in events]))
+ self.assertTrue(any(["cpython.remote_debugger_script" in event for
event in events]))
+ if returncode:
+ self.fail(stderr)
if __name__ == "__main__":
unittest.main()
diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py
index 39e62027f03e5a..73a72024bba84d 100644
--- a/Lib/test/test_sys.py
+++ b/Lib/test/test_sys.py
@@ -1943,22 +1943,7 @@ def write(self, s):
self.assertEqual(out, b"")
self.assertEqual(err, b"")
-
-def _supports_remote_attaching():
- PROCESS_VM_READV_SUPPORTED = False
-
- try:
- from _remote_debugging import PROCESS_VM_READV_SUPPORTED
- except ImportError:
- pass
-
- return PROCESS_VM_READV_SUPPORTED
-
[email protected](not sys.is_remote_debug_enabled(), "Remote debugging is not
enabled")
[email protected](sys.platform != "darwin" and sys.platform != "linux" and
sys.platform != "win32",
- "Test only runs on Linux, Windows and MacOS")
[email protected](sys.platform == "linux" and not _supports_remote_attaching(),
- "Test only runs on Linux with process_vm_readv support")
[email protected]_remote_exec_only
@test.support.cpython_only
class TestRemoteExec(unittest.TestCase):
def tearDown(self):
@@ -2117,7 +2102,7 @@ def audit_hook(event, arg):
returncode, stdout, stderr = self._run_remote_exec_test(script,
prologue=prologue)
self.assertEqual(returncode, 0)
self.assertIn(b"Remote script executed successfully!", stdout)
- self.assertIn(b"Audit event: remote_debugger_script, arg: ", stdout)
+ self.assertIn(b"Audit event: cpython.remote_debugger_script, arg: ",
stdout)
self.assertEqual(stderr, b"")
def test_remote_exec_with_exception(self):
diff --git
a/Misc/NEWS.d/next/Core_and_Builtins/2025-06-16-02-31-42.gh-issue-135543.6b0HOF.rst
b/Misc/NEWS.d/next/Core_and_Builtins/2025-06-16-02-31-42.gh-issue-135543.6b0HOF.rst
new file mode 100644
index 00000000000000..6efe2a47bac5d4
--- /dev/null
+++
b/Misc/NEWS.d/next/Core_and_Builtins/2025-06-16-02-31-42.gh-issue-135543.6b0HOF.rst
@@ -0,0 +1,2 @@
+Emit ``sys.remote_exec`` audit event when :func:`sys.remote_exec` is called
+and migrate ``remote_debugger_script`` to ``cpython.remote_debugger_script``.
diff --git a/Python/ceval_gil.c b/Python/ceval_gil.c
index 6d2383ac7c1c65..57d8f68b000b60 100644
--- a/Python/ceval_gil.c
+++ b/Python/ceval_gil.c
@@ -1220,7 +1220,7 @@ static inline int run_remote_debugger_source(PyObject
*source)
// that would be an easy target for a ROP gadget.
static inline void run_remote_debugger_script(PyObject *path)
{
- if (0 != PySys_Audit("remote_debugger_script", "O", path)) {
+ if (0 != PySys_Audit("cpython.remote_debugger_script", "O", path)) {
PyErr_FormatUnraisable(
"Audit hook failed for remote debugger script %U", path);
return;
diff --git a/Python/sysmodule.c b/Python/sysmodule.c
index e5ae841d195d4f..b3a2512a99d2fc 100644
--- a/Python/sysmodule.c
+++ b/Python/sysmodule.c
@@ -2488,6 +2488,11 @@ sys_remote_exec_impl(PyObject *module, int pid, PyObject
*script)
if (PyUnicode_FSConverter(script, &path) == 0) {
return NULL;
}
+
+ if (PySys_Audit("sys.remote_exec", "iO", pid, script) < 0) {
+ return NULL;
+ }
+
debugger_script_path = PyBytes_AS_STRING(path);
#ifdef MS_WINDOWS
PyObject *unicode_path;
_______________________________________________
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]