From 427e4261f42940161824fae987a4b56924f41bd4 Mon Sep 17 00:00:00 2001 From: t30002884 Date: Mon, 15 Jul 2024 10:43:36 +0800 Subject: [PATCH] [PATCH] Check the validity of len before mmap Two cases: (1)If condition 'c->mapend + extra_len < c->mapstart + relro_len' is True, the result of "len" (size_t len = (c->mapend + extra_len) - (c->mapstart + relro_len)) will be a negative value. 'len' is of type size_t, so it overflows. later __mmap will fail, because 'len - mod' is a very large value at this point. (2)If the data segment is small, "len" may be equal to 0. In this case, __mmap also fails. In both cases, the mapping fails, the mapping is falled back, and hugepage feature of dynamic library becomes invalid. Case (1) is an exception, and the fallback is the expected. Case (2) should not be fallled back in its entirety. In this case, the code segment may continue to use huge page, and the data segment uses 4KB page. --- Check-the-validity-of-len-before-mmap.patch | 60 +++++++++++++++++++++ glibc.spec | 9 +++- 2 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 Check-the-validity-of-len-before-mmap.patch diff --git a/Check-the-validity-of-len-before-mmap.patch b/Check-the-validity-of-len-before-mmap.patch new file mode 100644 index 0000000..bf3af02 --- /dev/null +++ b/Check-the-validity-of-len-before-mmap.patch @@ -0,0 +1,60 @@ +From a4efa699bfb5e03e6b7142729965caad36d1996d Mon Sep 17 00:00:00 2001 +From: shixuantong +Date: Thu, 13 Jun 2024 16:29:38 +0800 +Subject: [PATCH] Check the validity of len before mmap + +Two cases: +(1)If condition 'c->mapend + extra_len < c->mapstart + relro_len' is True, the result of "len" (size_t len = (c->mapend + extra_len) - (c->mapstart + relro_len)) will be a negative value. 'len' is of type size_t, so it overflows. later __mmap will fail, because 'len - mod' is a very large value at this point. + +(2)If the data segment is small, "len" may be equal to 0. In this case, __mmap also fails. + +In both cases, the mapping fails, the mapping is falled back, and hugepage feature of dynamic library becomes invalid. Case (1) is an exception, and the fallback is the expected. Case (2) should not be fallled back in its entirety. In this case, the code segment may continue to use huge page, and the data segment uses 4KB page. +--- + elf/dl-load.h | 2 ++ + elf/dl-map-segments-hugepage.h | 9 +++++++++ + 2 files changed, 11 insertions(+) + +diff --git a/elf/dl-load.h b/elf/dl-load.h +index f2428165..cd0a5143 100644 +--- a/elf/dl-load.h ++++ b/elf/dl-load.h +@@ -142,6 +142,8 @@ static const char *_dl_map_segments (struct link_map *l, int fd, + N_("fail to find exec prot segment") + #define DL_MAP_SEGMENT_ERROR_EXTRA_SIZE \ + N_("wrong segment extra size") ++#define DL_MAP_SEGMENTS_GNU_RELRO \ ++ N_("relro segment size is not expected") + #endif + + #endif /* dl-load.h */ +diff --git a/elf/dl-map-segments-hugepage.h b/elf/dl-map-segments-hugepage.h +index 218e93a0..3b863288 100644 +--- a/elf/dl-map-segments-hugepage.h ++++ b/elf/dl-map-segments-hugepage.h +@@ -260,6 +260,9 @@ _mmap_segment_filesz(struct link_map *l, const struct loadcmd *c, ElfW(Addr) map + void *map_addr = 0; + + size_t relro_len = _get_relro_len(l, c); ++ if (c->mapend + extra_len < c->mapstart + relro_len) ++ return DL_MAP_SEGMENTS_GNU_RELRO; ++ + if (relro_len > 0) + { + if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES)) +@@ -279,6 +282,12 @@ _mmap_segment_filesz(struct link_map *l, const struct loadcmd *c, ElfW(Addr) map + + size_t prev_map_len = ALIGN_UP(mapstart, SIZE_2MB) - mapstart; + size_t len = (c->mapend + extra_len) - (c->mapstart + relro_len); ++ if (len == 0) ++ { ++ if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES)) ++ _dl_debug_printf("\t\tAfter mmapping relro len, remain filesz is zero\n"); ++ return NULL; ++ } + if (len <= prev_map_len || len - prev_map_len < SIZE_2MB) + { + if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES)) +-- +2.33.0 + + diff --git a/glibc.spec b/glibc.spec index be4a93d..8743d9e 100644 --- a/glibc.spec +++ b/glibc.spec @@ -71,7 +71,7 @@ ############################################################################## Name: glibc Version: 2.34 -Release: 152 +Release: 153 Summary: The GNU libc libraries License: %{all_license} URL: http://www.gnu.org/software/glibc/ @@ -354,6 +354,7 @@ Patch9045: fix-Segmentation-fault-in-nss-module.patch Patch9046: fix_nss_database_check_reload_and_get_memleak.patch Patch9047: inet-fix-warn-unused-result.patch Patch9048: LoongArch-Add-missing-relocation-type-in-elf.h.patch +Patch9049: Check-the-validity-of-len-before-mmap.patch Provides: ldconfig rtld(GNU_HASH) bundled(gnulib) @@ -1519,6 +1520,12 @@ fi %endif %changelog +* Mon Jul 15 2024 taoyuxiang - 2.34-153 +- Type:bugfix +- ID: +- SUG:NA +- DESC:Check the validity of len before mmap + * Tue Jun 25 2024 chenhaixiang - 2.34-152 - Type:bugfix - ID: -- Gitee