[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.

(cherry picked from commit 05ed122de513e7cd1dd41d13453fac9b931e73ae)
This commit is contained in:
taoyuxiang 2024-07-15 10:26:06 +08:00 committed by openeuler-sync-bot
parent 03d346d3da
commit 22e8e12bc8
2 changed files with 68 additions and 1 deletions

View File

@ -0,0 +1,60 @@
From a4efa699bfb5e03e6b7142729965caad36d1996d Mon Sep 17 00:00:00 2001
From: shixuantong <shixuantong1@huawei.com>
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

View File

@ -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 <taoyuxiang2@huawei.com> - 2.34-153
- Type:bugfix
- ID:
- SUG:NA
- DESC:Check the validity of len before mmap
* Tue Jun 25 2024 chenhaixiang <chenhaixiang3@huawei.com> - 2.34-152
- Type:bugfix
- ID: