From patchwork Thu Feb 6 14:40:55 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Zhipeng Xie X-Patchwork-Id: 37703 Received: (qmail 66427 invoked by alias); 6 Feb 2020 06:36:53 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 66418 invoked by uid 89); 6 Feb 2020 06:36:53 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-25.0 required=5.0 tests=BAYES_00, DATE_IN_FUTURE_06_12, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, SPF_HELO_PASS, SPF_PASS autolearn=ham version=3.3.1 spammy=vulnerability, H*r:0800, HContent-Transfer-Encoding:8bit X-HELO: huawei.com From: Zhipeng Xie To: , CC: , , , , Subject: [PATCH] CVE-2019-1010023: add check for load commands mapping [#22851] Date: Thu, 6 Feb 2020 09:40:55 -0500 Message-ID: <20200206144055.16981-1-xiezhipeng1@huawei.com> MIME-Version: 1.0 Glibc assume the following constraint in ELF specification. | 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: Zhipeng Xie --- 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 ac9f09ab4c..8353fcd730 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),