summaryrefslogtreecommitdiff
path: root/Check-the-validity-of-len-before-mmap.patch
diff options
context:
space:
mode:
authorCoprDistGit <infra@openeuler.org>2024-08-03 06:28:41 +0000
committerCoprDistGit <infra@openeuler.org>2024-08-03 06:28:41 +0000
commitd20db0561a6a36f914fde030512503b114ef9a0c (patch)
treed4e5e3494d95c269a1cee6195f11bf3201bcadbf /Check-the-validity-of-len-before-mmap.patch
parent016343d99b1b269d7246ef1e143d4b54914433d4 (diff)
Diffstat (limited to 'Check-the-validity-of-len-before-mmap.patch')
-rw-r--r--Check-the-validity-of-len-before-mmap.patch60
1 files changed, 60 insertions, 0 deletions
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 <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
+
+