[PATCH] malloc: Reject the top chunk in mem2chunk_check
Magnus Lindholm <[email protected]> Mon, 3 Aug 2026 17:54:47 +0200
| Newsgroups | gmane.comp.lib.glibc.alpha |
|---|---|
| Message-ID | <[email protected]> |
mem2chunk_check uses inuse to validate a candidate chunk. However, inuse obtains the chunk state from the header of the following chunk and therefore must not be called for the top chunk, which has no following chunk. The existing main-arena boundary check implicitly rejects the top chunk when the arena is contiguous. When the main arena is marked noncontiguous, that boundary check is skipped and mem2chunk_check can instead call inuse on the top chunk. This was exposed by the malloc-check tests on Alpha, where the main arena used the noncontiguous 1 MiB mmap fallback. An invalid pointer was interpreted as the top chunk, and inuse read beyond the end of the mapping, causing a segmentation fault instead of diagnosing the invalid pointer. Explicitly reject the top chunk before calling inuse. The top chunk is unallocated space and cannot be a valid result of mem2chunk_check. This fixes tst-tcfree1-malloc-check and tst-tcfree2-malloc-check on Alpha. Signed-off-by: Magnus Lindholm <[email protected]> --- malloc/malloc-check.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/malloc/malloc-check.c b/malloc/malloc-check.c index b1a10c74b3..109076f590 100644 --- a/malloc/malloc-check.c +++ b/malloc/malloc-check.c @@ -120,7 +120,8 @@ mem2chunk_check (void *mem, unsigned char **magic_p) if ((contig && ((char *) p < mp_.sbrk_base || ((char *) p + sz) >= (mp_.sbrk_base + main_arena.system_mem))) || - sz < MINSIZE || sz & MALLOC_ALIGN_MASK || !inuse (p) || + sz < MINSIZE || sz & MALLOC_ALIGN_MASK || + p == top (&main_arena) || !inuse (p) || (!prev_inuse (p) && ((prev_size (p) & MALLOC_ALIGN_MASK) != 0 || (contig && (char *) prev_chunk (p) < mp_.sbrk_base) || next_chunk (prev_chunk (p)) != p))) -- 2.53.0