sys_heap: perform cheap overflow detection on freed memory
Make the LEFT_SIZE field first and SIZE_AND_USED field last (for an allocated chunk) so they sit right next to the allocated memory. The current chunk's SIZE_AND_USED field points to the next (right) chunk, and from there the LEFT_SIZE field should point back to the current chunk. Many trivial memory overflows should trip that test. One way to make this test more robust could involve xor'ing the values within respective accessor pairs. But at least the fact that the size value is shifted by one bit already prevent fooling the test with a same-byte corruption. Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
This commit is contained in:
parent
cb3d460a2c
commit
74fbca412a
|
@ -112,6 +112,20 @@ void sys_heap_free(struct sys_heap *heap, void *mem)
|
|||
chunkid_t c = ((uint8_t *)mem - chunk_header_bytes(h)
|
||||
- (uint8_t *)chunk_buf(h)) / CHUNK_UNIT;
|
||||
|
||||
/*
|
||||
* This should catch many double-free cases.
|
||||
* This is cheap enough so let's do it all the time.
|
||||
*/
|
||||
__ASSERT(chunk_used(h, c),
|
||||
"unexpected heap state (double-free?) for memory at %p", mem);
|
||||
/*
|
||||
* It is easy to catch many common memory overflow cases with
|
||||
* a quick check on this and next chunk header fields that are
|
||||
* immediately before and after the freed memory.
|
||||
*/
|
||||
__ASSERT(left_chunk(h, right_chunk(h, c)) == c,
|
||||
"corrupted heap bounds (buffer overflow?) for memory at %p", mem);
|
||||
|
||||
/* Merge with right chunk? We can just absorb it. */
|
||||
if (!chunk_used(h, right_chunk(h, c))) {
|
||||
chunkid_t rc = right_chunk(h, c);
|
||||
|
|
|
@ -51,7 +51,7 @@ typedef size_t chunkid_t;
|
|||
|
||||
typedef struct { char bytes[CHUNK_UNIT]; } chunk_unit_t;
|
||||
|
||||
enum chunk_fields { SIZE_AND_USED, LEFT_SIZE, FREE_PREV, FREE_NEXT };
|
||||
enum chunk_fields { LEFT_SIZE, SIZE_AND_USED, FREE_PREV, FREE_NEXT };
|
||||
|
||||
struct z_heap_bucket {
|
||||
chunkid_t next;
|
||||
|
|
Loading…
Reference in a new issue