From e112450230f854094b3e1a2907e4b6d463752111 Mon Sep 17 00:00:00 2001 From: rwx403335 Date: Mon, 7 Feb 2022 17:38:42 +0800 Subject: [PATCH] fix CVE-2021-41495 --- backport-CVE-2021-41495.patch | 396 ++++++++++++++++++++++++++++++++++ numpy.spec | 6 +- 2 files changed, 401 insertions(+), 1 deletion(-) create mode 100644 backport-CVE-2021-41495.patch diff --git a/backport-CVE-2021-41495.patch b/backport-CVE-2021-41495.patch new file mode 100644 index 0000000..2293135 --- /dev/null +++ b/backport-CVE-2021-41495.patch @@ -0,0 +1,396 @@ +From ac87f071f5fcf05b6a28bcf4ba7eb965daa6959a Mon Sep 17 00:00:00 2001 +From: Matti Picus +Date: Wed, 2 Feb 2022 22:46:17 +0200 +Subject: [PATCH] ENH: review return values for PyArray_DescrNew (#20960) + +* ENH: review return value from PyArray_DescrNew* calls + +* BUG: remove unused variable + +* BUG: typo + +* Update numpy/core/src/multiarray/methods.c + +Co-authored-by: Sebastian Berg + +* Update numpy/core/src/multiarray/methods.c + +Co-authored-by: Sebastian Berg + +* Update numpy/core/src/multiarray/getset.c + +Co-authored-by: Sebastian Berg + +* Update numpy/core/src/multiarray/methods.c + +Co-authored-by: Sebastian Berg + +* fixes from review + +* Update numpy/core/src/umath/ufunc_type_resolution.c + +Co-authored-by: Sebastian Berg + +* move check to internal function + +* remove check + +* Remove unnecessary dealloc + +The dealloc is now part of the Py_DECREF(ret) and handled there. +Doing it here would decref it twice. + +* MAINT: Remove custom error message (and small cleanup) + +It is probably not good to call PyObject_GetIter() if dtype is NULL +and an error is already in progress... +(If we check for it, lets try to do it right.) + +* Fixup DescrNewFromType + +`DescrNewFromType` cannot fail in most cases, but if it does, +DescrNew does not accept NULL as input. + +Co-authored-by: Sebastian Berg +--- + +--- + numpy/core/src/multiarray/arrayobject.c | 3 +++ + numpy/core/src/multiarray/buffer.c | 6 ++++++ + numpy/core/src/multiarray/ctors.c | 24 +++++++++++++++++++++++- + numpy/core/src/multiarray/descriptor.c | 27 ++++++++++++++++++++------- + numpy/core/src/multiarray/getset.c | 13 ++++++++----- + numpy/core/src/multiarray/methods.c | 16 ++++++++++++++++ + 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, 91 insertions(+), 22 deletions(-) + +diff --git a/numpy/core/src/multiarray/arrayobject.c b/numpy/core/src/multiarray/arrayobject.c +index d20dd63..1d1d6c1 100644 +--- a/numpy/core/src/multiarray/arrayobject.c ++++ b/numpy/core/src/multiarray/arrayobject.c +@@ -1023,6 +1023,9 @@ _strings_richcompare(PyArrayObject *self, PyArrayObject *other, int cmp_op, + 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); +diff --git a/numpy/core/src/multiarray/buffer.c b/numpy/core/src/multiarray/buffer.c +index d8ad802..c633778 100644 +--- a/numpy/core/src/multiarray/buffer.c ++++ b/numpy/core/src/multiarray/buffer.c +@@ -1117,12 +1117,18 @@ _descriptor_from_pep3118_format_fast(char *s, PyObject **result) + } + + descr = PyArray_DescrFromType(type_num); ++ if (descr == NULL) { ++ return 0; ++ } + if (byte_order == '=') { + *result = (PyObject*)descr; + } + else { + *result = (PyObject*)PyArray_DescrNewByteorder(descr, byte_order); + Py_DECREF(descr); ++ if (result == NULL) { ++ return 0; ++ } + } + + return 1; +diff --git a/numpy/core/src/multiarray/ctors.c b/numpy/core/src/multiarray/ctors.c +index e72e602..d1f7b79 100644 +--- a/numpy/core/src/multiarray/ctors.c ++++ b/numpy/core/src/multiarray/ctors.c +@@ -928,6 +928,9 @@ PyArray_NewFromDescr_int(PyTypeObject *subtype, PyArray_Descr *descr, int nd, + int i; + npy_intp nbytes; + ++ if (descr == NULL) { ++ return NULL; ++ } + if (descr->subarray) { + PyObject *ret; + npy_intp newdims[2*NPY_MAXDIMS]; +@@ -1314,6 +1317,9 @@ PyArray_New(PyTypeObject *subtype, int nd, npy_intp *dims, int type_num, + return NULL; + } + PyArray_DESCR_REPLACE(descr); ++ if (descr == NULL) { ++ return NULL; ++ } + descr->elsize = itemsize; + } + new = PyArray_NewFromDescr(subtype, descr, nd, dims, strides, +@@ -1339,6 +1345,9 @@ _dtype_from_buffer_3118(PyObject *memoryview) + * terminate. + */ + descr = PyArray_DescrNewFromType(NPY_STRING); ++ if (descr == NULL) { ++ return NULL; ++ } + descr->elsize = view->itemsize; + } + return descr; +@@ -3631,6 +3640,10 @@ PyArray_FromFile(FILE *fp, PyArray_Descr *dtype, npy_intp num, char *sep) + PyArrayObject *ret; + size_t nread = 0; + ++ if (dtype == NULL) { ++ return NULL; ++ } ++ + if (PyDataType_REFCHK(dtype)) { + PyErr_SetString(PyExc_ValueError, + "Cannot read into object array"); +@@ -3693,6 +3706,9 @@ PyArray_FromBuffer(PyObject *buf, PyArray_Descr *type, + int itemsize; + int writeable = 1; + ++ if (type == NULL) { ++ return NULL; ++ } + + if (PyDataType_REFCHK(type)) { + PyErr_SetString(PyExc_ValueError, +@@ -3925,14 +3941,20 @@ 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; + } ++ + if (PyDataType_ISUNSIZED(dtype)) { + PyErr_SetString(PyExc_ValueError, + "Must specify length when using variable-size data-type."); +diff --git a/numpy/core/src/multiarray/descriptor.c b/numpy/core/src/multiarray/descriptor.c +index e7a4b6c..c46394b 100644 +--- a/numpy/core/src/multiarray/descriptor.c ++++ b/numpy/core/src/multiarray/descriptor.c +@@ -1318,6 +1318,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; +@@ -2225,7 +2228,7 @@ arraydescr_new(PyTypeObject *NPY_UNUSED(subtype), + 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; +@@ -2251,9 +2254,10 @@ arraydescr_new(PyTypeObject *NPY_UNUSED(subtype), + + /* 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; + } + +@@ -2263,10 +2267,11 @@ arraydescr_new(PyTypeObject *NPY_UNUSED(subtype), + * 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)) { + /* +@@ -3009,6 +3014,10 @@ PyArray_DescrNewByteorder(PyArray_Descr *self, char newendian) + 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) { +@@ -3045,6 +3054,10 @@ PyArray_DescrNewByteorder(PyArray_Descr *self, char newendian) + 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; + } +diff --git a/numpy/core/src/multiarray/getset.c b/numpy/core/src/multiarray/getset.c +index c5577c1..1496859 100644 +--- a/numpy/core/src/multiarray/getset.c ++++ b/numpy/core/src/multiarray/getset.c +@@ -742,15 +742,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_NewFromDescrAndBase( + Py_TYPE(self), +diff --git a/numpy/core/src/multiarray/methods.c b/numpy/core/src/multiarray/methods.c +index c3040b4..af7f92a 100644 +--- a/numpy/core/src/multiarray/methods.c ++++ b/numpy/core/src/multiarray/methods.c +@@ -1259,6 +1259,10 @@ array_sort(PyArrayObject *self, PyObject *args, PyObject *kwds) + 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; +@@ -1381,6 +1385,10 @@ array_argsort(PyArrayObject *self, PyObject *args, PyObject *kwds) + 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; +@@ -1436,6 +1444,10 @@ array_argpartition(PyArrayObject *self, PyObject *args, PyObject *kwds) + 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; +@@ -2051,6 +2063,10 @@ array_setstate(PyArrayObject *self, PyObject *args) + } + 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; + } +diff --git a/numpy/core/src/multiarray/nditer_constr.c b/numpy/core/src/multiarray/nditer_constr.c +index 18a2cc8..3462518 100644 +--- a/numpy/core/src/multiarray/nditer_constr.c ++++ b/numpy/core/src/multiarray/nditer_constr.c +@@ -1116,13 +1116,12 @@ npyiter_prepare_one_operand(PyArrayObject **op, + 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 */ +diff --git a/numpy/core/src/multiarray/scalarapi.c b/numpy/core/src/multiarray/scalarapi.c +index bc435d1..9a96184 100644 +--- a/numpy/core/src/multiarray/scalarapi.c ++++ b/numpy/core/src/multiarray/scalarapi.c +@@ -560,6 +560,9 @@ PyArray_DescrFromScalar(PyObject *sc) + descr = PyArray_DescrFromTypeObject((PyObject *)Py_TYPE(sc)); + if (PyDataType_ISUNSIZED(descr)) { + 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); +diff --git a/numpy/core/src/multiarray/scalartypes.c.src b/numpy/core/src/multiarray/scalartypes.c.src +index 52de312..2ff21c9 100644 +--- a/numpy/core/src/multiarray/scalartypes.c.src ++++ b/numpy/core/src/multiarray/scalartypes.c.src +@@ -3068,12 +3068,16 @@ void_arrtype_new(PyTypeObject *type, PyObject *args, PyObject *NPY_UNUSED(kwds)) + } + ((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; + return ret; + } + +-- +1.8.3.1 + diff --git a/numpy.spec b/numpy.spec index 67922d0..a026fba 100644 --- a/numpy.spec +++ b/numpy.spec @@ -2,7 +2,7 @@ Name: numpy Version: 1.16.5 -Release: 5 +Release: 6 Epoch: 1 Summary: A fast multidimensional array facility for Python @@ -15,6 +15,7 @@ BuildRequires: lapack-devel gcc-gfortran Cython Patch0: backport-CVE-2021-41496.patch Patch1: backport-CVE-2021-34141.patch +Patch2: backport-CVE-2021-41495.patch %description NumPy is the fundamental package for scientific computing with Python. It contains among other things: @@ -180,6 +181,9 @@ popd &> /dev/null %{python3_sitearch}/%{name}/f2py %changelog +* Mon Feb 07 2022 renhongxun - 1.16.5-6 +- fix CVE-2021-41495 + * Thu Jan 27 2022 renhongxun - 1.16.5-5 - fix CVE-2021-34141 -- Gitee