From 7dc22afb2a0296d9cf319a15ccf8c4f167602ecc Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 6 Oct 2017 22:07:49 +0200 Subject: [PATCH] bpo-31165: Detect mutated list in list_slice() Check if the list size changed before/after allocating a new list object to prevent a crash. --- .../2017-10-06-22-08-50.bpo-31165.rH1Z10.rst | 2 ++ Objects/listobject.c | 16 +++++++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2017-10-06-22-08-50.bpo-31165.rH1Z10.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2017-10-06-22-08-50.bpo-31165.rH1Z10.rst b/Misc/NEWS.d/next/Core and Builtins/2017-10-06-22-08-50.bpo-31165.rH1Z10.rst new file mode 100644 index 00000000000000..b963ee07bc3595 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2017-10-06-22-08-50.bpo-31165.rH1Z10.rst @@ -0,0 +1,2 @@ +Detect mutated list in list_slice(): check if the list size changed +before/after allocating a new list object to prevent a crash. diff --git a/Objects/listobject.c b/Objects/listobject.c index 858532252e92a7..cc3f60bd7d66aa 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -436,20 +436,26 @@ list_slice(PyListObject *a, Py_ssize_t ilow, Py_ssize_t ihigh) { PyListObject *np; PyObject **src, **dest; - Py_ssize_t i, len; + Py_ssize_t alen, i, len; + alen = Py_SIZE(a); if (ilow < 0) ilow = 0; - else if (ilow > Py_SIZE(a)) - ilow = Py_SIZE(a); + else if (ilow > alen) + ilow = alen; if (ihigh < ilow) ihigh = ilow; - else if (ihigh > Py_SIZE(a)) - ihigh = Py_SIZE(a); + else if (ihigh > alen) + ihigh = alen; len = ihigh - ilow; np = (PyListObject *) PyList_New(len); if (np == NULL) return NULL; + if (Py_SIZE(a) != alen) { + PyErr_SetString(PyExc_RuntimeError, "list mutated during slicing"); + return NULL; + } + src = a->ob_item + ilow; dest = np->ob_item; for (i = 0; i < len; i++) {