From fe1ffef2eec9c6634a1e9af951eb68f0f5614470 Mon Sep 17 00:00:00 2001
From: xujing <xujing99@huawei.com>
Date: Thu, 2 Dec 2021 11:41:46 +0800
Subject: [PATCH] glibc: fix CVE-2019-1010023
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

| PT_LOAD
|
| […] Loadable segment entries in the program header table appear in
| ascending order, sorted on the p_vaddr member.

http://www.sco.com/developers/gabi/latest/ch5.pheader.html

Some check needed to fix vulnerability in load commands mapping reported by

https://sourceware.org/bugzilla/show_bug.cgi?id=22851

Signed-off-by: lvying <lvying6@huawei.com>
Signed-off-by: xujing <xujing99@huawei.com>
---
 elf/dl-map-segments.h | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/elf/dl-map-segments.h b/elf/dl-map-segments.h
index 084076a2..a41ae73b 100644
--- a/elf/dl-map-segments.h
+++ b/elf/dl-map-segments.h
@@ -33,6 +33,7 @@ _dl_map_segments (struct link_map *l, int fd,
                   struct link_map *loader)
 {
   const struct loadcmd *c = loadcmds;
+  ElfW(Addr) l_map_end_aligned;
 
   if (__glibc_likely (type == ET_DYN))
     {
@@ -61,6 +62,8 @@ _dl_map_segments (struct link_map *l, int fd,
         return DL_MAP_SEGMENTS_ERROR_MAP_SEGMENT;
 
       l->l_map_end = l->l_map_start + maplength;
+      l_map_end_aligned = ((l->l_map_end + GLRO(dl_pagesize) - 1)
+                          & ~(GLRO(dl_pagesize) - 1));
       l->l_addr = l->l_map_start - c->mapstart;
 
       if (has_holes)
@@ -85,10 +88,16 @@ _dl_map_segments (struct link_map *l, int fd,
   /* Remember which part of the address space this object uses.  */
   l->l_map_start = c->mapstart + l->l_addr;
   l->l_map_end = l->l_map_start + maplength;
+  l_map_end_aligned = ((l->l_map_end + GLRO(dl_pagesize) - 1)
+                      & ~(GLRO(dl_pagesize) - 1));
   l->l_contiguous = !has_holes;
 
   while (c < &loadcmds[nloadcmds])
     {
+      if ((l->l_addr + c->mapend) > l_map_end_aligned ||
+          (l->l_addr + c->mapstart) < l->l_map_start)
+          return DL_MAP_SEGMENTS_ERROR_MAP_SEGMENT;
+
       if (c->mapend > c->mapstart
           /* Map the segment contents from the file.  */
           && (__mmap ((void *) (l->l_addr + c->mapstart),
-- 
2.23.0

