Three Bytes Into The Chunk

char *rec = malloc(64);
memcpy(rec, "id=", 3);
memcpy(rec + 3, payload, 61);

char *val = rec + 3;      /* points at the value, not the chunk */

/* ... hours later, in a different function ... */
free(val);

The allocator stores each chunk's size and flags in the 8 bytes immediately preceding the pointer it returned. What does free(val) actually do?

A

It faults immediately and reliably, because val is not a pointer malloc ever returned.

B

It reads the 8 bytes ending at val as a chunk header. Those bytes are the top five bytes of the real header followed by the three characters id=, so the size and flags it recovers are nonsense, and it either corrupts the heap metadata or aborts. The behavior is undefined.

C

It frees the 61 bytes from val to the end of the chunk and leaks the first 3.

D

It works. The allocator rounds the pointer down to the start of the enclosing chunk before freeing.