On Thu, Aug 08, 2024 at 02:00:09PM -0400, Liam R. Howlett wrote: > Have a look at the mmapstress 3 test in ltp [1]. The tests pokes holes > and mmaps into those holes throughout the brk range. > > [1]. https://github.com/linux-test-project/ltp/blob/master/testcases/kernel/mem/mmapstress/mmapstress03.c In investigating this further, with additional reproducers, I believe that the whole bug is in vma_is_initial_heap(). Here is what I have tested so far: 1. Use only sbrk to allocate heap memory - sbrk(0) returns the start_brk before calling sbrk(increment). Afterwards, sbrk(0) returns start_brk + increment. 2. Use sbrk(0) to obtain start_brk, then request 512 MB of address space from mmap starting at start_brk. mmap allocates 512 MB of address space starting at start_brk and ending at start_brk + 0x20000000. sbrk(0) still returns start_brk. However, /proc/PID/maps flags the mmapped address space with "[heap]" 3. Use sbrk(0) to obtain start_brk, then request 512 MB of address space from mmap starting at start_brk + _SC_PAGESIZE. mmap allocates 512 MB of address space starting at start_brk + _SC_PAGESIZE and ending at start_brk + _SC_PAGESIZE + 0x20000000. sbrk(0) still returns start_brk, and /proc/PID/maps does NOT flag the mmapped address space with "[heap]". I believe that the entire bug may reside in vma_is_initial_heap because /proc/PID/maps also uses vma_is_initial_heap to flag entries with "[heap]" [1]. Also, sbrk(0) is not actually getting updated after a call to mmap, so mmap is not actually allocating heap memory. What do you all think about this patch? If it doesn't have any obvious flaws I can submit it (along with a revert for the revert). diff --git a/include/linux/mm.h b/include/linux/mm.h index c4b238a20b76..1dd588833af8 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -918,7 +918,8 @@ static inline bool vma_is_anonymous(struct vm_area_struct *vma) */ static inline bool vma_is_initial_heap(const struct vm_area_struct *vma) { - return vma->vm_start < vma->vm_mm->brk && + return vma->vm_mm->brk != vma->vm_mm->start_brk && + vma->vm_start < vma->vm_mm->brk && vma->vm_end > vma->vm_mm->start_brk; } -- [1]. https://github.com/torvalds/linux/blob/6a0e38264012809afa24113ee2162dc07f4ed22b/fs/proc/task_mmu.c#L287