Skip to content

Commit c426636

Browse files
committed
Issue #18408: Fix _PyMem_DebugRealloc()
Don't mark old extra memory dead before calling realloc(). realloc() can fail and realloc() must not touch the original buffer on failure. So mark old extra memory dead only on success if the new buffer did not move (has the same address).
1 parent 9e6b4d7 commit c426636

1 file changed

Lines changed: 8 additions & 6 deletions

File tree

Objects/obmalloc.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1780,7 +1780,7 @@ static void *
17801780
_PyMem_DebugRealloc(void *ctx, void *p, size_t nbytes)
17811781
{
17821782
debug_alloc_api_t *api = (debug_alloc_api_t *)ctx;
1783-
uchar *q = (uchar *)p;
1783+
uchar *q = (uchar *)p, *oldq;
17841784
uchar *tail;
17851785
size_t total; /* nbytes + 4*SST */
17861786
size_t original_nbytes;
@@ -1797,24 +1797,26 @@ _PyMem_DebugRealloc(void *ctx, void *p, size_t nbytes)
17971797
/* overflow: can't represent total as a size_t */
17981798
return NULL;
17991799

1800-
if (nbytes < original_nbytes) {
1801-
/* shrinking: mark old extra memory dead */
1802-
memset(q + nbytes, DEADBYTE, original_nbytes - nbytes + 2*SST);
1803-
}
1804-
18051800
/* Resize and add decorations. We may get a new pointer here, in which
18061801
* case we didn't get the chance to mark the old memory with DEADBYTE,
18071802
* but we live with that.
18081803
*/
1804+
oldq = q;
18091805
q = (uchar *)api->alloc.realloc(api->alloc.ctx, q - 2*SST, total);
18101806
if (q == NULL)
18111807
return NULL;
18121808

1809+
if (q == oldq && nbytes < original_nbytes) {
1810+
/* shrinking: mark old extra memory dead */
1811+
memset(q + nbytes, DEADBYTE, original_nbytes - nbytes);
1812+
}
1813+
18131814
write_size_t(q, nbytes);
18141815
assert(q[SST] == (uchar)api->api_id);
18151816
for (i = 1; i < SST; ++i)
18161817
assert(q[SST + i] == FORBIDDENBYTE);
18171818
q += 2*SST;
1819+
18181820
tail = q + nbytes;
18191821
memset(tail, FORBIDDENBYTE, SST);
18201822
write_size_t(tail + SST, serialno);

0 commit comments

Comments
 (0)