From 1b296563c92c896f072343b5f19286e8b5942b9e Mon Sep 17 00:00:00 2001 From: hubin Date: Fri, 28 Apr 2023 11:30:47 +0800 Subject: [PATCH] elf/ld.so: Consider maybe-existing hole between PT_LOAD segments when mmap reserved area When mmap reserved area do NOT consider existing hole between PT_LOAD segments, this will cause reserved virtual address space too small to contain all the sections in the PT_LOAD segment. Since the address space mapping of subsequent segments is based on the reserved address space, each mmap has a MAP_FIXED flag, which will overwrite the reserved address space, if the reserved space is too small, these mmap with MAP_FIEXED flag will conflict with other address space. e.g. in some case, the address sapce in the .bss section(last data segment) conflicts with the address space in the heap(maybe other address space) cause the program coredump. --- elf/dl-map-segments-hugepage.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/elf/dl-map-segments-hugepage.h b/elf/dl-map-segments-hugepage.h index b99f726f..218e93a0 100644 --- a/elf/dl-map-segments-hugepage.h +++ b/elf/dl-map-segments-hugepage.h @@ -47,10 +47,18 @@ __mmap_reserved_area(const struct loadcmd loadcmds[], size_t nloadcmds, const struct loadcmd * c = loadcmds; *maparealen = 0; + /* + * Consider maybe-existing hole between PT_LOAD segments + */ while (c < &loadcmds[nloadcmds]) { - *maparealen += ALIGN_UP((c->mapend > c->allocend ? c->mapend : c->allocend), SIZE_2MB) - + // c is not the last loadcmd + if (c + 1 < &loadcmds[nloadcmds]) { + *maparealen += ALIGN_UP((c + 1)->mapstart - c->mapstart, SIZE_2MB); + } else { + *maparealen += ALIGN_UP((c->mapend > c->allocend ? c->mapend : c->allocend), SIZE_2MB) - ALIGN_DOWN(c->mapstart, SIZE_2MB); + } c++; } -- 2.38.1