Headline
CVE-2021-41496: Potential buffer-overflow from string operations in function array_from_pyobj of fortranobject.c · Issue #19000 · numpy/numpy
Buffer overflow in the array_from_pyobj function of fortranobject.c in NumPy < 1.19, which allows attackers to conduct a Denial of Service attacks by carefully constructing an array with negative values.
Reproducing code example:
Snippet:
char mess\[200\];
if ((intent & F2PY\_INTENT\_HIDE)
|| ((intent & F2PY\_INTENT\_CACHE) && (obj==Py\_None))
|| ((intent & F2PY\_OPTIONAL) && (obj==Py\_None))
) {
/\* intent(cache), optional, intent(hide) \*/
if (count\_negative\_dimensions(rank,dims) > 0) {
int i;
strcpy(mess, "failed to create intent(cache|hide)|optional array"
"\-- must have defined dimensions but got ("); ----> 91 chars copied into mess
for(i=0;i<rank;++i)
sprintf(mess+strlen(mess),"%" NPY\_INTP\_FMT ",",dims\[i\]); ----> max of rank is F2PY\_MAX\_DIMS (40), and all values of dims could be -1. Given the format "%d," ("\-1,"), max length of this part could be 40\*3\=120 + 91 > 200
strcat(mess, ")");
PyErr\_SetString(PyExc\_ValueError,mess);
return NULL;
}
arr = (PyArrayObject \*)
PyArray\_New(&PyArray\_Type, rank, dims, type\_num,
NULL,NULL,1,
!(intent&F2PY\_INTENT\_C),
NULL);
if (arr==NULL) return NULL;
if (!(intent & F2PY\_INTENT\_CACHE))
PyArray\_FILLWBYTE(arr, 0);
return arr;
}
Error message:
File: numpy/f2py/src/fortranobject.c
Function: array_from_pyobj (line 724 : 733)
Optional call-path: External -> fortran_setattr -> array_from_pyobj
Details in description
When we run our analysis tool on NumPy, a few Inappropriate string operations are reported at call sites of function strcpy, sprintf, and strcat in array_from_pyobj. There are no boundary checks at these points despite “mess” seems large enough to ensure the operations safe except for the point shown above.
As a suggestion, it is better to replace these functions with strncpy, strncat, and snprintf.
NumPy/Python version information:
the main branch of NumPy