Guido Vranken on PSRT report:
Python-2.7.11/Modules/_io/iobase.c iobase_readline():
531 old_size = PyByteArray_GET_SIZE(buffer);
532 PyByteArray_Resize(buffer, old_size + PyBytes_GET_SIZE(b));
533 memcpy(PyByteArray_AS_STRING(buffer) + old_size,
534 PyBytes_AS_STRING(b), PyBytes_GET_SIZE(b));
PyByteArray_Resize() relies on realloc(), and thus can fail if there
is insufficient memory. However, the return value of
PyByteArray_Resize() is not checked in iobase_readline(). So if
PyByteArray_Resize() fails, the memory area is too small for the data
that memcpy will write.
Proof Of Concept
----------------
First create a file with very long lines:
with open('out.xxx', 'wb') as fp:
fp.write('x' * (1024*1024*64))
fp.write('\n')
Zip it:
$ zip out.xxx.zip out.xxx
Set a smallish memory limit
$ ulimit -Sv 70000
Then run:
import zipfile
zf = zipfile.ZipFile('out.xxx.zip', 'r')
f = zf.open('out.xxx')
r = "x" * (1024*1024*20)
f.readline()
r = ""
----------------
For me this configuration resulted in
*** Error in `./python': realloc(): invalid next size: 0x00000000024b2f20 ***
Aborted
You might need to experiment a bit with the parameters (length of
lines, size of 'r', ulimit) to get a similar result. But there is a
bug there.
Let me know if you need more information from me.
|