]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-24618: Add a check in the code constructor. (GH-8283)
authorSerhiy Storchaka <storchaka@gmail.com>
Mon, 16 Jul 2018 06:10:19 +0000 (09:10 +0300)
committerGitHub <noreply@github.com>
Mon, 16 Jul 2018 06:10:19 +0000 (09:10 +0300)
Check that the size of the varnames tuple is enough at least for all arguments.

Misc/NEWS.d/next/Core and Builtins/2018-07-14-14-01-37.bpo-24618.iTKjD_.rst [new file with mode: 0644]
Objects/codeobject.c

diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-07-14-14-01-37.bpo-24618.iTKjD_.rst b/Misc/NEWS.d/next/Core and Builtins/2018-07-14-14-01-37.bpo-24618.iTKjD_.rst
new file mode 100644 (file)
index 0000000..180b565
--- /dev/null
@@ -0,0 +1,2 @@
+Fixed reading invalid memory when create the code object with too small
+varnames tuple or too large argument counts.
index aa373a075d7dbfc3f874b9a20c496e28ad0aa16d..b07667c28df1e5600adcb3e0ffe41fea040e40ba 100644 (file)
@@ -103,7 +103,7 @@ PyCode_New(int argcount, int kwonlyargcount,
 {
     PyCodeObject *co;
     Py_ssize_t *cell2arg = NULL;
-    Py_ssize_t i, n_cellvars;
+    Py_ssize_t i, n_cellvars, n_varnames, total_args;
 
     /* Check argument types */
     if (argcount < 0 || kwonlyargcount < 0 || nlocals < 0 ||
@@ -138,10 +138,22 @@ PyCode_New(int argcount, int kwonlyargcount,
         flags &= ~CO_NOFREE;
     }
 
+    n_varnames = PyTuple_GET_SIZE(varnames);
+    if (argcount <= n_varnames && kwonlyargcount <= n_varnames) {
+        /* Never overflows. */
+        total_args = (Py_ssize_t)argcount + (Py_ssize_t)kwonlyargcount +
+                ((flags & CO_VARARGS) != 0) + ((flags & CO_VARKEYWORDS) != 0);
+    }
+    else {
+        total_args = n_varnames + 1;
+    }
+    if (total_args > n_varnames) {
+        PyErr_SetString(PyExc_ValueError, "code: varnames is too small");
+        return NULL;
+    }
+
     /* Create mapping between cells and arguments if needed. */
     if (n_cellvars) {
-        Py_ssize_t total_args = argcount + kwonlyargcount +
-            ((flags & CO_VARARGS) != 0) + ((flags & CO_VARKEYWORDS) != 0);
         bool used_cell2arg = false;
         cell2arg = PyMem_NEW(Py_ssize_t, n_cellvars);
         if (cell2arg == NULL) {