Do we have an example that demonstrates non-deterministic failures due to the incorrect malloc size in C?
For example, in my 'gzip' program in linux:
.
.
.
char* a = (char*)malloc(256) // correct version
is changed to
char* a = (char*)malloc(206) //faulty version
.
.
.
Because of this, a test case tc that pass on the correct version becomes fail (i.e., segmentation fault) on the faulty version. However, the failure is non-deterministic. Sometimes, the failed test case tc on the faulty version does not cause segmentation fault (i.e., pass).
This may be due to the 'undefined' behavior of malloc, but I could not know how it happens exactly.
Does anyone can give me some concrete example? Thank you in advance.
Imagine the memory as a sequence of pages. Some are available to your process, some are unavailable due to permissions and some are simply inaccessible, i.e. not mapped in. Consider this map (not to scale):
+ + +
| Page, 4096 bytes | |
+-----------------+------+ |
| | | |
| | | |
| | | |
+-----------------+------+-->v
3890B 206B X <-- Not mapped, can't touch!
If you allocate 206 bytes it all depends where in the page those 206 bytes will lie.
If they lie at the start (to the left) accessing more is OK as far as Linux is concerned (but still undefined behavior as far as C is concerned)
If however accessing more bytes spills into another page, with a different protection or into one that's not mapped in, Linux will not be amused and you'll get a segfault
So you're at the mercy of something you can't control: where malloc
will allocate your data, i.e. where the additional 50 bytes will be.