[issue35842] A potential bug about use of uninitialised variable
New submission from rongxin : In the source file mmapmodule.c, the function mmap_subscript contains a potential bug about the use of uninitialised variable. mmapmodule.c: 764 static PyObject * 765 mmap_subscript(mmap_object *self, PyObject *item) 766 { ... else if (PySlice_Check(item)) { 782Py_ssize_t start, stop, step, slicelen; 783 784if (PySlice_Unpack(item, &start, &stop, &step) < 0) { 785return NULL; 786} 787slicelen = PySlice_AdjustIndices(self->size, &start, &stop, step); ... In Line 782 of the file mmapmodule.c, the variable stop is not initialised and will be passed to the function PySlice_Unpack as the third parameter. Inside the function, it is likely that stop is not initialised. Please see the following code. sliceobject.c: 196 int 197 PySlice_Unpack(PyObject *_r, 198 Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step) 199 { ... 231if (r->stop == Py_None) { 232*stop = *step < 0 ? PY_SSIZE_T_MIN : PY_SSIZE_T_MAX; 233} 234else { 235if (!_PyEval_SliceIndex(r->stop, stop)) return -1; 236} The third parameter **stop** may be changed at line 232 or 235. However, at Line 235, it is still likely that **stop** is not initialised at Line 235 where **stop** is passed as the second parameter. Note that, at Line 235, we only know r->stop!=Py_None. The following is the code snippet of the function _PyEval_SliceIndex. ceval.c: 4718 int 4719 _PyEval_SliceIndex(PyObject *v, Py_ssize_t *pi) 4720 { 4721 if (v != Py_None) { 4722 Py_ssize_t x; 4723 if (PyIndex_Check(v)) { 4724 x = PyNumber_AsSsize_t(v, NULL); 4725 if (x == -1 && PyErr_Occurred()) 4726 return 0; 4727 } 4728 else { 4729 PyErr_SetString(PyExc_TypeError, 4730 "slice indices must be integers or " 4731 "None or have an __index__ method"); 4732 return 0; 4733 } 4734 *pi = x; 4735 } 4736return 1; 4737 } As we can see, it is likely that when the third parameter v can be NULL, then the function _PyEval_SliceIndex will return 1. In the caller function PySlice_Unpack, at Line 235, the condition **if (!_PyEval_SliceIndex(r->stop, stop))** is not satisfied, and thus it will go to Line 238 which returns 0. In the caller function mmap_subscript in the file mmapmodule.c, at Line 784, since the return value is 0, and thus the path condition **PySlice_Unpack(item, &start, &stop, &step) < 0** is not satisfied. It will continue to execute the Line 787. The uninitialised variable **stop** again will be passed to the function PySlice_AdjustIndices as the third parameter. **stop** then will be dereferenced without initialisation. Please see the following. sliceobject.c: 241 Py_ssize_t 242 PySlice_AdjustIndices(Py_ssize_t length, 243 Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t step) ... 260 if (*stop < 0) { 261*stop += length; ... -- messages: 334466 nosy: wurongxin1987 priority: normal severity: normal status: open title: A potential bug about use of uninitialised variable type: security versions: Python 3.8 ___ Python tracker <https://bugs.python.org/issue35842> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue35842] A potential bug about use of uninitialised variable
rongxin added the comment: BTW, if this bug is true, there is a similar code snippet in the same file. mmapmodule.c: 845 static int 846 mmap_ass_subscript(mmap_object *self, PyObject *item, PyObject *value) 847 { ... 888else if (PySlice_Check(item)) { 889Py_ssize_t start, stop, step, slicelen; 890Py_buffer vbuf; 891 892if (PySlice_Unpack(item, &start, &stop, &step) < 0) { 893return -1; 894} 895slicelen = PySlice_AdjustIndices(self->size, &start, &stop, step); -- ___ Python tracker <https://bugs.python.org/issue35842> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue35842] A potential bug about use of uninitialised variable
rongxin added the comment: Hi, Josh Rosenberg. As you mentioned PySlice_New (which is ultimately responsible for all slice construction) explicitly replaces any argument of NULL with Py_None, I am not sure whether this is always true r->stop cannot be NULL. I detected this bug using the code of Python 2.7.15. The implementation of _PyEval_SliceIndex is shown as followings. Please read the comments of this functions, and it is possible that v would be NULL. I wonder whether your assumption r->stop cannot be NULL will be broken in Python 2.7.15 /* Extract a slice index from a PyInt or PyLong or an object with the nb_index slot defined, and store in *pi. Silently reduce values larger than PY_SSIZE_T_MAX to PY_SSIZE_T_MAX, and silently boost values less than PY_SSIZE_T_MIN to PY_SSIZE_T_MIN. Return 0 on error, 1 on success. */ /* Note: If v is NULL, return success without storing into *pi. This is because_PyEval_SliceIndex() is called by apply_slice(), which can be called by the SLICE opcode with v and/or w equal to NULL. */ int _PyEval_SliceIndex(PyObject *v, Py_ssize_t *pi) { if (v != NULL && v != Py_None) { Py_ssize_t x; if (PyInt_Check(v)) { /* XXX(nnorwitz): I think PyInt_AS_LONG is correct, however, it looks like it should be AsSsize_t. There should be a comment here explaining why. */ x = PyInt_AS_LONG(v); } else if (PyIndex_Check(v)) { x = PyNumber_AsSsize_t(v, NULL); if (x == -1 && PyErr_Occurred()) return 0; } else { PyErr_SetString(PyExc_TypeError, "slice indices must be integers or " "None or have an __index__ method"); return 0; } *pi = x; } return 1; } -- ___ Python tracker <https://bugs.python.org/issue35842> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue35842] A potential bug about use of uninitialised variable
rongxin added the comment: I think this bug is valid at least in Python 2.7, as I mentioned the implementation of _PyEval_SliceIndex is different from the one in Python 3.8. The condition " if (v != NULL && v != Py_None) " will bypass the NULL pointer dereference. Would you please check this again? Thanks. -- status: closed -> open versions: +Python 2.7 -Python 3.8 ___ Python tracker <https://bugs.python.org/issue35842> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue35842] A potential bug about use of uninitialised variable
Change by rongxin : -- resolution: not a bug -> ___ Python tracker <https://bugs.python.org/issue35842> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue35842] A potential bug about use of uninitialised variable
rongxin added the comment: Josh Rosenberg, thanks for your useful comments. -- ___ Python tracker <https://bugs.python.org/issue35842> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com