self.assertIn(b"Remote script exception", stderr)
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):
"""Test remote exec is disabled when PYTHON_DISABLE_REMOTE_DEBUG is set"""
env = os.environ.copy()
#endif
#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
// that would be an easy target for a ROP gadget.
static inline void run_remote_debugger_script(const char *path)
Py_DECREF(fileobj);
if (source) {
- const char *str = PyBytes_AsString(source);
- if (str) {
- // 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);
+ if (0 != run_remote_debugger_source(source)) {
+ PyErr_FormatUnraisable("Error executing debugger script %s", path);
}
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)