Bug 6512 - Data corruption caused by realloc()
Summary: Data corruption caused by realloc()
Status: RESOLVED INVALID
Alias: None
Product: uClibc
Classification: Unclassified
Component: Other (show other bugs)
Version: unspecified
Hardware: All All
: P5 critical
Target Milestone: ---
Assignee: unassigned
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-09-25 09:01 UTC by Svenning Sørensen
Modified: 2013-09-25 20:29 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:


Attachments
Patch for realloc() data corruption (754 bytes, application/octet-stream)
2013-09-25 09:01 UTC, Svenning Sørensen
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Svenning Sørensen 2013-09-25 09:01:56 UTC
Created attachment 5060 [details]
Patch for realloc() data corruption

In some cases data gets corrupted by calling realloc().
This happens when the size of the original memory blob is small (*) and the new blob is allocated at a different location.
In this case, parts of the original memory doesn't get copied but will contain random data.

(*) Specifically, if the original size is exactly 16, 24, or 32 bytes (on 32-bit architectures).

Needless to say, memory corruption can be very hard to track down and cause all kinds of unpredictable behavior and unreproducable errors (speaking by experience here), so this is a critical bug.

The attached patch fixes the issue.
Note that while the patch is based on uClibc-0.9.31, the bug is still present in current (0.9.33.2) uClibc.
Comment 1 Svenning Sørensen 2013-09-25 12:11:39 UTC
Hmm.. just realized I might have been a bit to hasty.
That patch may not fix the real issue, which may instead be due to incorrect overhead calculation in the memcpy above - ie for sizes > 36 bytes.
Guess I need to debug a little further..
Comment 2 Svenning Sørensen 2013-09-25 20:29:15 UTC
OK, red herring.

I guess I was confused by the fact that the chunk pointer doesn't actually point to the chunk, but is offset to point 4 bytes below, making the overhead only 4 bytes instead of 8, as the struct layout made me think.

So, as the comment correctly states, the amount of user data in a chunk is always an odd number of 'size_t's; testing for > 3 or > 4 (for example) is equally correct, even though (to my own defense) it didn't seem so at first glance.
At least the patch doesn't break anything :)

Dang, guess I'll have to look elsewhere for the cause of my weird memory corruption..