mirror of
https://github.com/python/cpython.git
synced 2025-08-04 08:59:19 +00:00
gh-132859: Run debugger scripts in their own namespaces (#132860)
Run debugger scripts in their own namespaces Previously scripts injected by `sys.remote_exec` were run with the globals of the `__main__` module. Instead, run each injected script with an empty set of globals. If someone really wants to use the `__main__` module's namespace, they can always `import __main__`.
This commit is contained in:
parent
402dba2928
commit
a94c7528b5
2 changed files with 38 additions and 13 deletions
|
@ -2125,6 +2125,19 @@ raise Exception("Remote script exception")
|
||||||
self.assertIn(b"Remote script exception", stderr)
|
self.assertIn(b"Remote script exception", stderr)
|
||||||
self.assertEqual(stdout.strip(), b"Target process running...")
|
self.assertEqual(stdout.strip(), b"Target process running...")
|
||||||
|
|
||||||
|
def test_new_namespace_for_each_remote_exec(self):
|
||||||
|
"""Test that each remote_exec call gets its own namespace."""
|
||||||
|
script = textwrap.dedent(
|
||||||
|
"""
|
||||||
|
assert globals() is not __import__("__main__").__dict__
|
||||||
|
print("Remote script executed successfully!")
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
returncode, stdout, stderr = self._run_remote_exec_test(script)
|
||||||
|
self.assertEqual(returncode, 0)
|
||||||
|
self.assertEqual(stderr, b"")
|
||||||
|
self.assertIn(b"Remote script executed successfully", stdout)
|
||||||
|
|
||||||
def test_remote_exec_disabled_by_env(self):
|
def test_remote_exec_disabled_by_env(self):
|
||||||
"""Test remote exec is disabled when PYTHON_DISABLE_REMOTE_DEBUG is set"""
|
"""Test remote exec is disabled when PYTHON_DISABLE_REMOTE_DEBUG is set"""
|
||||||
env = os.environ.copy()
|
env = os.environ.copy()
|
||||||
|
|
|
@ -1193,6 +1193,29 @@ _PyEval_DisableGIL(PyThreadState *tstate)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(Py_REMOTE_DEBUG) && defined(Py_SUPPORTS_REMOTE_DEBUG)
|
#if defined(Py_REMOTE_DEBUG) && defined(Py_SUPPORTS_REMOTE_DEBUG)
|
||||||
|
// Note that this function is inline to avoid creating a PLT entry
|
||||||
|
// that would be an easy target for a ROP gadget.
|
||||||
|
static inline int run_remote_debugger_source(PyObject *source)
|
||||||
|
{
|
||||||
|
const char *str = PyBytes_AsString(source);
|
||||||
|
if (!str) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject *ns = PyDict_New();
|
||||||
|
if (!ns) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject *res = PyRun_String(str, Py_file_input, ns, ns);
|
||||||
|
Py_DECREF(ns);
|
||||||
|
if (!res) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
Py_DECREF(res);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Note that this function is inline to avoid creating a PLT entry
|
// Note that this function is inline to avoid creating a PLT entry
|
||||||
// that would be an easy target for a ROP gadget.
|
// that would be an easy target for a ROP gadget.
|
||||||
static inline void run_remote_debugger_script(const char *path)
|
static inline void run_remote_debugger_script(const char *path)
|
||||||
|
@ -1225,22 +1248,11 @@ static inline void run_remote_debugger_script(const char *path)
|
||||||
Py_DECREF(fileobj);
|
Py_DECREF(fileobj);
|
||||||
|
|
||||||
if (source) {
|
if (source) {
|
||||||
const char *str = PyBytes_AsString(source);
|
if (0 != run_remote_debugger_source(source)) {
|
||||||
if (str) {
|
PyErr_FormatUnraisable("Error executing debugger script %s", path);
|
||||||
// PyRun_SimpleString() automatically raises an unraisable
|
|
||||||
// exception if it fails so we don't need to check the return value.
|
|
||||||
PyRun_SimpleString(str);
|
|
||||||
} else {
|
|
||||||
PyErr_FormatUnraisable("Error reading debugger script %s", path);
|
|
||||||
}
|
}
|
||||||
Py_DECREF(source);
|
Py_DECREF(source);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Just in case something went wrong, don't leave this function
|
|
||||||
// with an unhandled exception.
|
|
||||||
if (PyErr_Occurred()) {
|
|
||||||
PyErr_FormatUnraisable("Error executing debugger script %s", path);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int _PyRunRemoteDebugger(PyThreadState *tstate)
|
int _PyRunRemoteDebugger(PyThreadState *tstate)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue