[New-bugs-announce] [issue31637] integer overflow in the size of a ctypes.Array
Oren Milman
report at bugs.python.org
Fri Sep 29 06:39:58 EDT 2017
New submission from Oren Milman <orenmn at gmail.com>:
The following code:
from ctypes import *
from _testcapi import PY_SSIZE_T_MAX, LONG_MAX
if LONG_MAX == PY_SSIZE_T_MAX == (1 << 31) - 1:
class MyArray(Array):
_type_ = c_longlong
_length_ = 1 << 29
arr = MyArray()
for i in range(3):
arr[i] = i
for i in range(3):
print(arr[i])
Produces this output (on a 32bit Python on my Windows 10):
2
2
2
This is because PyCArrayType_new() (in Modules/_ctypes/_ctypes.c) raises a
"array too large" error in case (length * itemsize < 0). However, this
multiplication might also overflow to a non-negative number, e.g. to zero in
the code above.
PyCArrayType_new() then does:
stgdict->size = itemsize * length;
Array_ass_item() and Array_item() both do:
size = stgdict->size / stgdict->length;
offset = index * size;
So in the above code, the integer overflow caused the array to collapse to a
single element (the first element).
ISTM that we can fix this by changing the overflow detection logic to this:
assert(itemsize >= 0 && length >= 0);
array_size = itemsize * length;
if (itemsize && array_size / itemsize != length) {
PyErr_SetString(PyExc_OverflowError,
"array too large");
goto error;
}
The assertion is guaranteed to be true after #29843 is resolved. (I would open
a PR for #29843 soon.)
----------
components: ctypes
messages: 303322
nosy: Oren Milman
priority: normal
severity: normal
status: open
title: integer overflow in the size of a ctypes.Array
type: behavior
versions: Python 3.7
_______________________________________
Python tracker <report at bugs.python.org>
<https://bugs.python.org/issue31637>
_______________________________________
More information about the New-bugs-announce
mailing list