]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-22689: Copy the result of getenv() in sys_breakpointhook(). (GH-8194)
authorSerhiy Storchaka <storchaka@gmail.com>
Mon, 9 Jul 2018 18:46:51 +0000 (21:46 +0300)
committerGitHub <noreply@github.com>
Mon, 9 Jul 2018 18:46:51 +0000 (21:46 +0300)
Python/sysmodule.c

index 786f2b1a0a0e2cddd9c97e5d8c63e411233b266d..b6c816e9f628cb5fe924a5403450aea79b433ccd 100644 (file)
@@ -107,7 +107,7 @@ static PyObject *
 sys_breakpointhook(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *keywords)
 {
     assert(!PyErr_Occurred());
-    const char *envar = Py_GETENV("PYTHONBREAKPOINT");
+    char *envar = Py_GETENV("PYTHONBREAKPOINT");
 
     if (envar == NULL || strlen(envar) == 0) {
         envar = "pdb.set_trace";
@@ -116,6 +116,15 @@ sys_breakpointhook(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyOb
         /* The breakpoint is explicitly no-op'd. */
         Py_RETURN_NONE;
     }
+    /* According to POSIX the string returned by getenv() might be invalidated
+     * or the string content might be overwritten by a subsequent call to
+     * getenv().  Since importing a module can performs the getenv() calls,
+     * we need to save a copy of envar. */
+    envar = _PyMem_RawStrdup(envar);
+    if (envar == NULL) {
+        PyErr_NoMemory();
+        return NULL;
+    }
     const char *last_dot = strrchr(envar, '.');
     const char *attrname = NULL;
     PyObject *modulepath = NULL;
@@ -131,12 +140,14 @@ sys_breakpointhook(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyOb
         attrname = last_dot + 1;
     }
     if (modulepath == NULL) {
+        PyMem_RawFree(envar);
         return NULL;
     }
 
     PyObject *fromlist = Py_BuildValue("(s)", attrname);
     if (fromlist == NULL) {
         Py_DECREF(modulepath);
+        PyMem_RawFree(envar);
         return NULL;
     }
     PyObject *module = PyImport_ImportModuleLevelObject(
@@ -154,6 +165,7 @@ sys_breakpointhook(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyOb
     if (hook == NULL) {
         goto error;
     }
+    PyMem_RawFree(envar);
     PyObject *retval = _PyObject_FastCallKeywords(hook, args, nargs, keywords);
     Py_DECREF(hook);
     return retval;
@@ -164,6 +176,7 @@ sys_breakpointhook(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyOb
     int status = PyErr_WarnFormat(
         PyExc_RuntimeWarning, 0,
         "Ignoring unimportable $PYTHONBREAKPOINT: \"%s\"", envar);
+    PyMem_RawFree(envar);
     if (status < 0) {
         /* Printing the warning raised an exception. */
         return NULL;