This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH] CVE-2019-1010023: add check for load commands mapping [#22851]
- From: Zhipeng Xie <xiezhipeng1 at huawei dot com>
- To: <fweimer at redhat dot com>, <rschiron at redhat dot com>
- Cc: <libc-alpha at sourceware dot org>, <lvying6 at huawei dot com>, <joseph at codesourcery dot com>, <roland at hack dot frob dot com>, <xiezhipeng1 at huawei dot com>
- Date: Thu, 6 Feb 2020 09:40:55 -0500
- Subject: [PATCH] CVE-2019-1010023: add check for load commands mapping [#22851]
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 <xiezhipeng1@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 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),
--
2.18.1