Message303457
There several bugs in the memory allocator.
Incorrectly detected the case when realloc() resizes a memory block in-place. Wrong address is used for filling the extra memory with DEADBYTE.
- if (q == oldq && nbytes < original_nbytes) {
+ if (q == oldq - 2*SST && nbytes < original_nbytes) {
/* shrinking: mark old extra memory dead */
- memset(q + nbytes, DEADBYTE, original_nbytes - nbytes);
+ memset(q + 2*SST + nbytes, DEADBYTE, original_nbytes - nbytes);
}
But fixing this exposes other problem. _PyMem_DebugRawRealloc() is called recursively. _PyMem_DebugRawRealloc calls api->alloc.realloc which is _PyMem_DebugRawRealloc. There are two nested debug allocators. The block is nested in other block, both have their own header and footer.
|header1|header2|------------------------------|footer2|footer1|
_PyMem_DebugRawRealloc fills the extra memory with DEADBYTE.
|header|---------------------------..unused..|footer|
|header|---------------------------|footer|XXXXXXXXX|
But in case of nested _PyMem_DebugRawRealloc's, the outer one (which reallocates the inner block), overwrites the footer of the outer block.
|header1|header2|--------------------..unused..|footer2|footer1|
|header1|header2|--------------------..unused|footer1|XXXXXXXXX| after inner realloc
|header1|header2|--------------------|footer2|YYYYYYYYY|XXXXXXX| after outher realloc
XXX are DEADBYTEs written by the inner allocator, YYY are DEADBYTEs written by the outer allocator. |
|
Date |
User |
Action |
Args |
2017-10-01 12:02:14 | serhiy.storchaka | set | recipients:
+ serhiy.storchaka, vstinner, davin |
2017-10-01 12:02:14 | serhiy.storchaka | set | messageid: <1506859334.23.0.213398074469.issue31626@psf.upfronthosting.co.za> |
2017-10-01 12:02:14 | serhiy.storchaka | link | issue31626 messages |
2017-10-01 12:02:13 | serhiy.storchaka | create | |
|