From 3be61db35cff9baee6e997f993acdf4aa3e11e4f Mon Sep 17 00:00:00 2001 From: Robert Manner Date: Tue, 18 Feb 2020 14:33:34 +0100 Subject: [PATCH] plugins/python: restore the original python inittab after interpreter deinit --- plugins/python/python_plugin_common.c | 43 +++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/plugins/python/python_plugin_common.c b/plugins/python/python_plugin_common.c index 37494cebc..1225d5fb9 100644 --- a/plugins/python/python_plugin_common.c +++ b/plugins/python/python_plugin_common.c @@ -30,6 +30,8 @@ #include #include +static struct _inittab * python_inittab_copy = NULL; +static size_t python_inittab_copy_len = 0; const char * _lookup_value(char * const keyvalues[], const char *key) @@ -128,6 +130,41 @@ _python_plugin_new_interpreter(void) debug_return_ptr(py_interpreter); } +static int +_save_inittab(void) +{ + debug_decl(_save_inittab, PYTHON_DEBUG_INTERNAL); + free(python_inittab_copy); // just to be sure (it is always NULL) + + for (python_inittab_copy_len = 0; + PyImport_Inittab[python_inittab_copy_len].name != NULL; + ++python_inittab_copy_len) { + } + ++python_inittab_copy_len; // for the null mark + + python_inittab_copy = malloc(sizeof(struct _inittab) * python_inittab_copy_len); + if (python_inittab_copy == NULL) { + debug_return_int(SUDO_RC_ERROR); + } + + memcpy(python_inittab_copy, PyImport_Inittab, python_inittab_copy_len * sizeof(struct _inittab)); + debug_return_int(SUDO_RC_OK); +} + +static void +_restore_inittab(void) +{ + debug_decl(_restore_inittab, PYTHON_DEBUG_INTERNAL); + + if (python_inittab_copy != NULL) + memcpy(PyImport_Inittab, python_inittab_copy, python_inittab_copy_len * sizeof(struct _inittab)); + + free(python_inittab_copy); + python_inittab_copy = NULL; + python_inittab_copy_len = 0; + debug_return; +} + void python_plugin_handle_plugin_error_exception(PyObject **py_result, struct PluginContext *plugin_ctx) { @@ -312,6 +349,9 @@ _python_plugin_register_plugin_in_py_ctx(void) Py_IsolatedFlag = 1; Py_NoUserSiteDirectory = 1; + if (_save_inittab() != SUDO_RC_OK) + debug_return_int(SUDO_RC_ERROR); + PyImport_AppendInittab("sudo", sudo_module_init); Py_InitializeEx(0); py_ctx.py_main_interpreter = PyThreadState_Get(); @@ -580,6 +620,9 @@ python_plugin_unlink(void) if (Py_FinalizeEx() != 0) { sudo_debug_printf(SUDO_DEBUG_WARN, "Closing: failed to deinit python interpreter\n"); } + + // Restore inittab so "sudo" module does not remain there (as garbage) + _restore_inittab(); } py_ctx_reset(); debug_return;