FR-AD-002 - Bind the lifetime of program name and python path to the module
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Wed, 5 Jul 2017 16:40:47 +0000 (12:40 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Mon, 17 Jul 2017 12:52:15 +0000 (08:52 -0400)
PySys_SetPath and PySys_SetName don't appear to duplicate the buffer, they just store a pointer.

src/modules/rlm_python/rlm_python.c

index c52cec5..8261cfd 100644 (file)
@@ -67,6 +67,11 @@ typedef struct rlm_python_t {
        char const      *name;                  //!< Name of the module instance
        PyThreadState   *sub_interpreter;       //!< The main interpreter/thread used for this instance.
        char const      *python_path;           //!< Path to search for python files in.
+
+#if PY_VERSION_HEX > 0x03050000
+       wchar_t         *wide_name;             //!< Special wide char encoding of radiusd name.
+       wchar_t         *wide_path;             //!< Special wide char encoding of radiusd path.
+#endif
        PyObject        *module;                //!< Local, interpreter specific module, containing
                                                //!< FreeRADIUS functions.
        bool            cext_compat;            //!< Whether or not to create sub-interpreters per module
@@ -855,19 +860,15 @@ static int python_interpreter_init(rlm_python_t *inst, CONF_SECTION *conf)
 
 #if PY_VERSION_HEX > 0x03050000
                {
-                       wchar_t *name;
-
-                       wide_name = Py_DecodeLocale(main_config.name, strlen(main_config.name));
+                       inst->wide_name = Py_DecodeLocale(main_config.name, strlen(main_config.name));
                        Py_SetProgramName(name);                /* The value of argv[0] as a wide char string */
-                       PyMem_RawFree(name);
                }
 #else
                {
                        char *name;
 
-                       name = talloc_strdup(NULL, main_config.name);
+                       memcpy(&name, &main_config.name, sizeof(name));
                        Py_SetProgramName(name);                /* The value of argv[0] as a wide char string */
-                       talloc_free(name);
                }
 #endif
 
@@ -903,23 +904,23 @@ static int python_interpreter_init(rlm_python_t *inst, CONF_SECTION *conf)
 
                /*
                 *      Set the python search path
+                *
+                *      The path buffer does not appear to be dup'd
+                *      so its lifetime should really be bound to
+                *      the lifetime of the module.
                 */
                if (inst->python_path) {
 #if PY_VERSION_HEX > 0x03050000
                        {
-                               wchar_t *name;
-
-                               path = Py_DecodeLocale(inst->python_path, strlen(inst->python_path));
+                               inst->wide_path = Py_DecodeLocale(inst->python_path, strlen(inst->python_path));
                                PySys_SetPath(path);
-                               PyMem_RawFree(path);
                        }
 #else
                        {
                                char *path;
 
-                               path = talloc_strdup(NULL, inst->python_path);
+                               memcpy(&path, inst->python_path, sizeof(path));
                                PySys_SetPath(path);
-                               talloc_free(path);
                        }
 #endif
                }
@@ -1087,8 +1088,14 @@ static int mod_detach(void *instance)
                PyThreadState_Swap(main_interpreter); /* Swap to the main thread */
                Py_Finalize();
                dlclose(python_dlhandle);
+
+#if PY_VERSION_HEX > 0x03050000
+               if (inst->wide_name) PyMem_RawFree(inst->wide_name);
+               if (inst->wide_path) PyMem_RawFree(inst->wide_path);
+#endif
        }
 
+
        return ret;
 }