diff options
author | Wilco Dijkstra <wilco.dijkstra@arm.com> | 2025-03-31 11:44:02 +0000 |
---|---|---|
committer | Wilco Dijkstra <wilco.dijkstra@arm.com> | 2025-04-15 11:14:57 +0000 |
commit | 9b0c8ced9c71a86f68d3e29693979dad6da3b79d (patch) | |
tree | 3a6a89e4af60a4792e61ee2161bcc1df9b319eb1 | |
parent | 0296654d61ffa095fc7729f1efafa7d0e4fa4f7a (diff) | |
download | glibc-9b0c8ced9c71a86f68d3e29693979dad6da3b79d.zip glibc-9b0c8ced9c71a86f68d3e29693979dad6da3b79d.tar.gz glibc-9b0c8ced9c71a86f68d3e29693979dad6da3b79d.tar.bz2 |
malloc: Improve free checks
The checks on size can be merged and use __builtin_add_overflow. Since
tcache only handles small sizes (and rejects sizes < MINSIZE), delay this
check until after tcache.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
-rw-r--r-- | malloc/malloc.c | 15 |
1 files changed, 6 insertions, 9 deletions
diff --git a/malloc/malloc.c b/malloc/malloc.c index e827875..19b6cfa 100644 --- a/malloc/malloc.c +++ b/malloc/malloc.c @@ -3468,16 +3468,8 @@ __libc_free (void *mem) INTERNAL_SIZE_T size = chunksize (p); - /* Little security check which won't hurt performance: the - allocator never wraps around at the end of the address space. - Therefore we can exclude some size values which might appear - here by accident or by "design" from some intruder. */ - if (__glibc_unlikely ((uintptr_t) p > (uintptr_t) -size - || misaligned_chunk (p))) + if (__glibc_unlikely (misaligned_chunk (p))) malloc_printerr ("free(): invalid pointer"); - /* We know that each chunk is at least MINSIZE bytes. */ - if (__glibc_unlikely (size < MINSIZE)) - malloc_printerr ("free(): invalid size"); check_inuse_chunk (arena_for_chunk (p), p); @@ -3486,6 +3478,11 @@ __libc_free (void *mem) return; #endif + /* Check size >= MINSIZE and p + size does not overflow. */ + if (__glibc_unlikely (__builtin_add_overflow_p ((uintptr_t) p, size - MINSIZE, + (uintptr_t) 0))) + malloc_printerr ("free(): invalid size"); + _int_free_chunk (arena_for_chunk (p), p, size, 0); } libc_hidden_def (__libc_free) |