Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP1:GA
python-numpy
CVE-2021-41495-retval-PyArray_DescrNew.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File CVE-2021-41495-retval-PyArray_DescrNew.patch of Package python-numpy
From 039612da5dd9d39f5986bc0cdb3444a43b4b4370 Mon Sep 17 00:00:00 2001 From: mattip <matti.picus@gmail.com> Date: Tue, 1 Feb 2022 11:53:11 +0200 Subject: [PATCH 01/14] ENH: review return value from PyArray_DescrNew* calls --- numpy/core/src/multiarray/arrayobject.c | 3 ++ numpy/core/src/multiarray/arrayobject.h | 25 +++++++++++++++++++++++ numpy/core/src/multiarray/ctors.c | 25 ++++++++++++++++++++++- numpy/core/src/multiarray/descriptor.c | 30 +++++++++++++++++++++------- numpy/core/src/multiarray/getset.c | 13 +++++++----- numpy/core/src/multiarray/methods.c | 21 +++++++++++++++++++ numpy/core/src/multiarray/nditer_constr.c | 11 ++++------ numpy/core/src/multiarray/scalarapi.c | 3 ++ numpy/core/src/multiarray/scalartypes.c.src | 10 ++++++--- 9 files changed, 119 insertions(+), 22 deletions(-) --- a/numpy/core/src/multiarray/arrayobject.c +++ b/numpy/core/src/multiarray/arrayobject.c @@ -1073,6 +1073,9 @@ _strings_richcompare(PyArrayObject *self if (PyArray_TYPE(self) == NPY_STRING && PyArray_DESCR(other)->type_num == NPY_UNICODE) { PyArray_Descr* unicode = PyArray_DescrNew(PyArray_DESCR(other)); + if (unicode == NULL) { + return NULL; + } unicode->elsize = PyArray_DESCR(self)->elsize << 2; new = PyArray_FromAny((PyObject *)self, unicode, 0, 0, 0, NULL); --- a/numpy/core/src/multiarray/arrayobject.h +++ b/numpy/core/src/multiarray/arrayobject.h @@ -5,6 +5,31 @@ #error You should not include this #endif +/* For Python earlier than 2.7.12. */ +#ifndef Py_SETREF +/* Safely decref `op` and set `op` to `op2`. + * + * As in case of Py_CLEAR "the obvious" code can be deadly: + * + * Py_XDECREF(op); + * op = op2; + * + * The safe way is: + * + * Py_SETREF(op, op2); + * + * That arranges to set `op` to `op2` _before_ decref'ing, so that any code + * triggered as a side-effect of `op` getting torn down no longer believes + * `op` points to a valid object. + */ +#define Py_SETREF(op, op2) \ + do { \ + PyObject *_py_tmp = (PyObject *)(op); \ + (op) = (op2); \ + Py_XDECREF(_py_tmp); \ + } while (0) +#endif + NPY_NO_EXPORT PyObject * _strings_richcompare(PyArrayObject *self, PyArrayObject *other, int cmp_op, int rstrip); --- a/numpy/core/src/multiarray/ctors.c +++ b/numpy/core/src/multiarray/ctors.c @@ -854,6 +854,11 @@ PyArray_NewFromDescr_int(PyTypeObject *s npy_intp largest; npy_intp size; + if (descr == NULL) { + PyErr_Format(PyExc_ValueError, + "NULL descr in call to PyArray_NewFromDescr*"); + return NULL; + } if ((unsigned int)nd > (unsigned int)NPY_MAXDIMS) { PyErr_Format(PyExc_ValueError, "number of dimensions must be within [0, %d]", @@ -1208,6 +1213,9 @@ PyArray_New(PyTypeObject *subtype, int n return NULL; } PyArray_DESCR_REPLACE(descr); + if (descr == NULL) { + return NULL; + } descr->elsize = itemsize; } new = PyArray_NewFromDescr(subtype, descr, nd, dims, strides, @@ -1257,6 +1265,9 @@ _array_from_buffer_3118(PyObject *obj, P } else { descr = PyArray_DescrNewFromType(NPY_STRING); + if (descr == NULL) { + return NULL; + } descr->elsize = view->itemsize; } @@ -3234,6 +3245,10 @@ PyArray_FromFile(FILE *fp, PyArray_Descr PyArrayObject *ret; size_t nread = 0; + if (dtype == NULL) { + return NULL; + } + if (PyDataType_REFCHK(dtype)) { PyErr_SetString(PyExc_ValueError, "Cannot read into object array"); @@ -3291,6 +3306,9 @@ PyArray_FromBuffer(PyObject *buf, PyArra int itemsize; int writeable = 1; + if (type == NULL) { + return NULL; + } if (PyDataType_REFCHK(type)) { PyErr_SetString(PyExc_ValueError, @@ -3508,11 +3526,16 @@ NPY_NO_EXPORT PyObject * PyArray_FromIter(PyObject *obj, PyArray_Descr *dtype, npy_intp count) { PyObject *value; - PyObject *iter = PyObject_GetIter(obj); + PyObject *iter = NULL; PyArrayObject *ret = NULL; npy_intp i, elsize, elcount; char *item, *new_data; + if (dtype == NULL) { + return NULL; + } + + iter = PyObject_GetIter(obj); if (iter == NULL) { goto done; } --- a/numpy/core/src/multiarray/descriptor.c +++ b/numpy/core/src/multiarray/descriptor.c @@ -1144,6 +1144,9 @@ PyArray_DescrNewFromType(int type_num) PyArray_Descr *new; old = PyArray_DescrFromType(type_num); + if (old == NULL) { + return NULL; + } new = PyArray_DescrNew(old); Py_DECREF(old); return new; @@ -2004,7 +2007,7 @@ arraydescr_new(PyTypeObject *NPY_UNUSED( PyObject *args, PyObject *kwds) { PyObject *odescr, *metadata=NULL; - PyArray_Descr *descr, *conv; + PyArray_Descr *conv; npy_bool align = NPY_FALSE; npy_bool copy = NPY_FALSE; npy_bool copied = NPY_FALSE; @@ -2030,9 +2033,10 @@ arraydescr_new(PyTypeObject *NPY_UNUSED( /* Get a new copy of it unless it's already a copy */ if (copy && conv->fields == Py_None) { - descr = PyArray_DescrNew(conv); - Py_DECREF(conv); - conv = descr; + PyArray_DESCR_REPLACE(conv); + if (conv == NULL) { + return NULL; + } copied = NPY_TRUE; } @@ -2042,10 +2046,11 @@ arraydescr_new(PyTypeObject *NPY_UNUSED( * underlying dictionary */ if (!copied) { + PyArray_DESCR_REPLACE(conv); + if (conv == NULL) { + return NULL; + } copied = NPY_TRUE; - descr = PyArray_DescrNew(conv); - Py_DECREF(conv); - conv = descr; } if ((conv->metadata != NULL)) { /* @@ -2673,6 +2678,9 @@ PyArray_DescrNewByteorder(PyArray_Descr char endian; new = PyArray_DescrNew(self); + if (new == NULL) { + return NULL; + } endian = new->byteorder; if (endian != NPY_IGNORE) { if (newendian == NPY_SWAP) { @@ -2699,6 +2707,10 @@ PyArray_DescrNewByteorder(PyArray_Descr int len, i; newfields = PyDict_New(); + if (newfields == NULL) { + Py_DECREF(new); + return NULL; + } /* make new dictionary with replaced PyArray_Descr Objects */ while (PyDict_Next(self->fields, &pos, &key, &value)) { if NPY_TITLE_KEY(key, value) { @@ -2735,6 +2747,10 @@ PyArray_DescrNewByteorder(PyArray_Descr Py_DECREF(new->subarray->base); new->subarray->base = PyArray_DescrNewByteorder( self->subarray->base, newendian); + if (new->subarray->base == NULL) { + Py_DECREF(new); + return NULL; + } } return new; } --- a/numpy/core/src/multiarray/getset.c +++ b/numpy/core/src/multiarray/getset.c @@ -656,15 +656,18 @@ _get_part(PyArrayObject *self, int imag) } type = PyArray_DescrFromType(float_type_num); + if (type == NULL) { + return NULL; + } offset = (imag ? type->elsize : 0); if (!PyArray_ISNBO(PyArray_DESCR(self)->byteorder)) { - PyArray_Descr *new; - new = PyArray_DescrNew(type); - new->byteorder = PyArray_DESCR(self)->byteorder; - Py_DECREF(type); - type = new; + Py_SETREF(type, PyArray_DescrNew(type)); + if (type == NULL) { + return NULL; + } + type->byteorder = PyArray_DESCR(self)->byteorder; } ret = (PyArrayObject *) PyArray_NewFromDescr(Py_TYPE(self), --- a/numpy/core/src/multiarray/methods.c +++ b/numpy/core/src/multiarray/methods.c @@ -1162,6 +1162,10 @@ array_sort(PyArrayObject *self, PyObject return NULL; } newd = PyArray_DescrNew(saved); + if (newd == NULL) { + Py_DECREF(new_name); + return NULL; + } Py_DECREF(newd->names); newd->names = new_name; ((PyArrayObject_fields *)self)->descr = newd; @@ -1223,7 +1227,15 @@ array_partition(PyArrayObject *self, PyO if (new_name == NULL) { return NULL; } + if (newd == NULL) { + Py_DECREF(new_name); + return NULL; + } newd = PyArray_DescrNew(saved); + if (newd == NULL) { + Py_DECREF(new_name); + return NULL; + } Py_DECREF(newd->names); newd->names = new_name; ((PyArrayObject_fields *)self)->descr = newd; @@ -1337,9 +1349,14 @@ array_argpartition(PyArrayObject *self, "OO", saved, order); Py_DECREF(_numpy_internal); if (new_name == NULL) { + Py_DECREF(new_name); return NULL; } newd = PyArray_DescrNew(saved); + if (newd == NULL) { + Py_DECREF(new_name); + return NULL; + } newd->names = new_name; ((PyArrayObject_fields *)self)->descr = newd; } @@ -1754,6 +1771,10 @@ array_setstate(PyArrayObject *self, PyOb } else { fa->descr = PyArray_DescrNew(typecode); + if (fa->descr == NULL) { + Py_DECREF(rawdata); + return NULL; + } if (PyArray_DESCR(self)->byteorder == NPY_BIG) { PyArray_DESCR(self)->byteorder = NPY_LITTLE; } --- a/numpy/core/src/multiarray/nditer_constr.c +++ b/numpy/core/src/multiarray/nditer_constr.c @@ -1088,13 +1088,12 @@ npyiter_prepare_one_operand(PyArrayObjec if (op_flags & NPY_ITER_NBO) { /* Check byte order */ if (!PyArray_ISNBO((*op_dtype)->byteorder)) { - PyArray_Descr *nbo_dtype; - /* Replace with a new descr which is in native byte order */ - nbo_dtype = PyArray_DescrNewByteorder(*op_dtype, NPY_NATIVE); - Py_DECREF(*op_dtype); - *op_dtype = nbo_dtype; - + Py_SETREF(*op_dtype, + PyArray_DescrNewByteorder(*op_dtype, NPY_NATIVE)); + if (*op_dtype == NULL) { + return 0; + } NPY_IT_DBG_PRINT("Iterator: Setting NPY_OP_ITFLAG_CAST " "because of NPY_ITER_NBO\n"); /* Indicate that byte order or alignment needs fixing */ --- a/numpy/core/src/multiarray/scalarapi.c +++ b/numpy/core/src/multiarray/scalarapi.c @@ -554,6 +554,9 @@ PyArray_DescrFromScalar(PyObject *sc) descr = PyArray_DescrFromTypeObject((PyObject *)Py_TYPE(sc)); if (descr->elsize == 0) { PyArray_DESCR_REPLACE(descr); + if (descr == NULL) { + return NULL; + } type_num = descr->type_num; if (type_num == NPY_STRING) { descr->elsize = PyString_GET_SIZE(sc); --- a/numpy/core/src/multiarray/scalartypes.c.src +++ b/numpy/core/src/multiarray/scalartypes.c.src @@ -2849,12 +2849,16 @@ void_arrtype_new(PyTypeObject *type, PyO } ((PyVoidScalarObject *)ret)->obval = destptr; Py_SIZE((PyVoidScalarObject *)ret) = (int) memu; - ((PyVoidScalarObject *)ret)->descr = - PyArray_DescrNewFromType(NPY_VOID); - ((PyVoidScalarObject *)ret)->descr->elsize = (int) memu; ((PyVoidScalarObject *)ret)->flags = NPY_ARRAY_BEHAVED | NPY_ARRAY_OWNDATA; ((PyVoidScalarObject *)ret)->base = NULL; + ((PyVoidScalarObject *)ret)->descr = + PyArray_DescrNewFromType(NPY_VOID); + if (((PyVoidScalarObject *)ret)->descr == NULL) { + Py_DECREF(ret); + return NULL; + } + ((PyVoidScalarObject *)ret)->descr->elsize = (int) memu; memset(destptr, '\0', (size_t) memu); return ret; }
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor