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:
Matt Wozniski 2025-04-23 19:40:24 -04:00 committed by GitHub
parent 402dba2928
commit a94c7528b5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 38 additions and 13 deletions

View file

@ -1193,6 +1193,29 @@ _PyEval_DisableGIL(PyThreadState *tstate)
#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)
@ -1225,22 +1248,11 @@ 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)