|
|
978e96 |
commit 0065aaaaae51cd60210ec3a7e13dddd8e01ffe2c
|
|
|
978e96 |
Author: Paul Pluzhnikov <ppluzhnikov@google.com>
|
|
|
978e96 |
Date: Sat May 5 18:08:27 2018 -0700
|
|
|
978e96 |
|
|
|
978e96 |
Fix BZ 20419. A PT_NOTE in a binary could be arbitratily large, so using
|
|
|
978e96 |
alloca for it may cause stack overflow. If the note is larger than
|
|
|
978e96 |
__MAX_ALLOCA_CUTOFF, use dynamically allocated memory to read it in.
|
|
|
978e96 |
|
|
|
978e96 |
2018-05-05 Paul Pluzhnikov <ppluzhnikov@google.com>
|
|
|
978e96 |
|
|
|
978e96 |
[BZ #20419]
|
|
|
978e96 |
* elf/dl-load.c (open_verify): Fix stack overflow.
|
|
|
978e96 |
* elf/Makefile (tst-big-note): New test.
|
|
|
978e96 |
* elf/tst-big-note-lib.S: New.
|
|
|
978e96 |
* elf/tst-big-note.c: New.
|
|
|
978e96 |
|
|
|
978e96 |
Minor textual conflicts and elf/Makefile due to continued upstream
|
|
|
978e96 |
development.
|
|
|
978e96 |
|
|
|
978e96 |
diff --git a/elf/Makefile b/elf/Makefile
|
|
|
978e96 |
index dea66ca1c12e5c29..b46b3a0e3542a06f 100644
|
|
|
978e96 |
--- a/elf/Makefile
|
|
|
978e96 |
+++ b/elf/Makefile
|
|
|
978e96 |
@@ -151,7 +151,8 @@ tests += loadtest restest1 preloadtest loadfail multiload origtest resolvfail \
|
|
|
978e96 |
tst-audit1 tst-audit2 tst-audit8 tst-audit9 \
|
|
|
978e96 |
tst-stackguard1 tst-addr1 tst-thrlock \
|
|
|
978e96 |
tst-unique1 tst-unique2 tst-unique3 tst-unique4 \
|
|
|
978e96 |
- tst-initorder tst-initorder2 tst-relsort1 tst-ptrguard1
|
|
|
978e96 |
+ tst-initorder tst-initorder2 tst-relsort1 tst-ptrguard1 \
|
|
|
978e96 |
+ tst-big-note
|
|
|
978e96 |
# reldep9
|
|
|
978e96 |
test-srcs = tst-pathopt
|
|
|
978e96 |
selinux-enabled := $(shell cat /selinux/enforce 2> /dev/null)
|
|
|
978e96 |
@@ -223,7 +224,9 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
|
|
|
978e96 |
tst-relsort1mod1 tst-relsort1mod2 tst-array2dep \
|
|
|
978e96 |
tst-array5dep \
|
|
|
978e96 |
tst-audit11mod1 tst-audit11mod2 tst-auditmod11 \
|
|
|
978e96 |
- tst-audit12mod1 tst-audit12mod2 tst-audit12mod3 tst-auditmod12
|
|
|
978e96 |
+ tst-audit12mod1 tst-audit12mod2 tst-audit12mod3 tst-auditmod12 \
|
|
|
978e96 |
+ tst-big-note-lib
|
|
|
978e96 |
+
|
|
|
978e96 |
ifeq (yesyes,$(have-fpie)$(build-shared))
|
|
|
978e96 |
modules-names += tst-piemod1
|
|
|
978e96 |
tests += tst-pie1
|
|
|
978e96 |
@@ -1234,3 +1237,5 @@ $(objpfx)tst-audit12: $(libdl)
|
|
|
978e96 |
tst-audit12-ENV = LD_AUDIT=$(objpfx)tst-auditmod12.so
|
|
|
978e96 |
$(objpfx)tst-audit12mod1.so: $(objpfx)tst-audit12mod2.so
|
|
|
978e96 |
LDFLAGS-tst-audit12mod2.so = -Wl,--version-script=tst-audit12mod2.map
|
|
|
978e96 |
+
|
|
|
978e96 |
+$(objpfx)tst-big-note: $(objpfx)tst-big-note-lib.so
|
|
|
978e96 |
diff --git a/elf/dl-load.c b/elf/dl-load.c
|
|
|
978e96 |
index 7466b686244e55b2..013efdb3814700d3 100644
|
|
|
978e96 |
--- a/elf/dl-load.c
|
|
|
978e96 |
+++ b/elf/dl-load.c
|
|
|
978e96 |
@@ -1744,6 +1744,7 @@ open_verify (const char *name, struct filebuf *fbp, struct link_map *loader,
|
|
|
978e96 |
ElfW(Ehdr) *ehdr;
|
|
|
978e96 |
ElfW(Phdr) *phdr, *ph;
|
|
|
978e96 |
ElfW(Word) *abi_note;
|
|
|
978e96 |
+ ElfW(Word) *abi_note_malloced = NULL;
|
|
|
978e96 |
unsigned int osversion;
|
|
|
978e96 |
size_t maplength;
|
|
|
978e96 |
|
|
|
978e96 |
@@ -1889,10 +1890,25 @@ open_verify (const char *name, struct filebuf *fbp, struct link_map *loader,
|
|
|
978e96 |
abi_note = (void *) (fbp->buf + ph->p_offset);
|
|
|
978e96 |
else
|
|
|
978e96 |
{
|
|
|
978e96 |
- abi_note = alloca (size);
|
|
|
978e96 |
+ /* Note: __libc_use_alloca is not usable here, because
|
|
|
978e96 |
+ thread info may not have been set up yet. */
|
|
|
978e96 |
+ if (size < __MAX_ALLOCA_CUTOFF)
|
|
|
978e96 |
+ abi_note = alloca (size);
|
|
|
978e96 |
+ else
|
|
|
978e96 |
+ {
|
|
|
978e96 |
+ /* There could be multiple PT_NOTEs. */
|
|
|
978e96 |
+ abi_note_malloced = realloc (abi_note_malloced, size);
|
|
|
978e96 |
+ if (abi_note_malloced == NULL)
|
|
|
978e96 |
+ goto read_error;
|
|
|
978e96 |
+
|
|
|
978e96 |
+ abi_note = abi_note_malloced;
|
|
|
978e96 |
+ }
|
|
|
978e96 |
__lseek (fd, ph->p_offset, SEEK_SET);
|
|
|
978e96 |
if (__libc_read (fd, (void *) abi_note, size) != size)
|
|
|
978e96 |
- goto read_error;
|
|
|
978e96 |
+ {
|
|
|
978e96 |
+ free (abi_note_malloced);
|
|
|
978e96 |
+ goto read_error;
|
|
|
978e96 |
+ }
|
|
|
978e96 |
}
|
|
|
978e96 |
|
|
|
978e96 |
while (memcmp (abi_note, &expected_note, sizeof (expected_note)))
|
|
|
978e96 |
@@ -1928,6 +1944,7 @@ open_verify (const char *name, struct filebuf *fbp, struct link_map *loader,
|
|
|
978e96 |
|
|
|
978e96 |
break;
|
|
|
978e96 |
}
|
|
|
978e96 |
+ free (abi_note_malloced);
|
|
|
978e96 |
}
|
|
|
978e96 |
|
|
|
978e96 |
return fd;
|
|
|
978e96 |
diff --git a/elf/tst-big-note-lib.S b/elf/tst-big-note-lib.S
|
|
|
978e96 |
new file mode 100644
|
|
|
978e96 |
index 0000000000000000..6b514a03cc686141
|
|
|
978e96 |
--- /dev/null
|
|
|
978e96 |
+++ b/elf/tst-big-note-lib.S
|
|
|
978e96 |
@@ -0,0 +1,26 @@
|
|
|
978e96 |
+/* Bug 20419: test for stack overflow in elf/dl-load.c open_verify()
|
|
|
978e96 |
+ Copyright (C) 2018 Free Software Foundation, Inc.
|
|
|
978e96 |
+ This file is part of the GNU C Library.
|
|
|
978e96 |
+
|
|
|
978e96 |
+ The GNU C Library is free software; you can redistribute it and/or
|
|
|
978e96 |
+ modify it under the terms of the GNU Lesser General Public
|
|
|
978e96 |
+ License as published by the Free Software Foundation; either
|
|
|
978e96 |
+ version 2.1 of the License, or (at your option) any later version.
|
|
|
978e96 |
+
|
|
|
978e96 |
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
|
978e96 |
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
978e96 |
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
978e96 |
+ Lesser General Public License for more details.
|
|
|
978e96 |
+
|
|
|
978e96 |
+ You should have received a copy of the GNU Lesser General Public
|
|
|
978e96 |
+ License along with the GNU C Library; if not, see
|
|
|
978e96 |
+ <http://www.gnu.org/licenses/>. */
|
|
|
978e96 |
+
|
|
|
978e96 |
+/* This creates a .so with 8MiB PT_NOTE segment.
|
|
|
978e96 |
+ On a typical Linux system with 8MiB "ulimit -s", that was enough
|
|
|
978e96 |
+ to trigger stack overflow in open_verify. */
|
|
|
978e96 |
+
|
|
|
978e96 |
+.pushsection .note.big,"a"
|
|
|
978e96 |
+.balign 4
|
|
|
978e96 |
+.fill 8*1024*1024, 1, 0
|
|
|
978e96 |
+.popsection
|
|
|
978e96 |
diff --git a/elf/tst-big-note.c b/elf/tst-big-note.c
|
|
|
978e96 |
new file mode 100644
|
|
|
978e96 |
index 0000000000000000..fcd2b0ed82cc1667
|
|
|
978e96 |
--- /dev/null
|
|
|
978e96 |
+++ b/elf/tst-big-note.c
|
|
|
978e96 |
@@ -0,0 +1,26 @@
|
|
|
978e96 |
+/* Bug 20419: test for stack overflow in elf/dl-load.c open_verify()
|
|
|
978e96 |
+ Copyright (C) 2018 Free Software Foundation, Inc.
|
|
|
978e96 |
+ This file is part of the GNU C Library.
|
|
|
978e96 |
+
|
|
|
978e96 |
+ The GNU C Library is free software; you can redistribute it and/or
|
|
|
978e96 |
+ modify it under the terms of the GNU Lesser General Public
|
|
|
978e96 |
+ License as published by the Free Software Foundation; either
|
|
|
978e96 |
+ version 2.1 of the License, or (at your option) any later version.
|
|
|
978e96 |
+
|
|
|
978e96 |
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
|
978e96 |
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
978e96 |
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
978e96 |
+ Lesser General Public License for more details.
|
|
|
978e96 |
+
|
|
|
978e96 |
+ You should have received a copy of the GNU Lesser General Public
|
|
|
978e96 |
+ License along with the GNU C Library; if not, see
|
|
|
978e96 |
+ <http://www.gnu.org/licenses/>. */
|
|
|
978e96 |
+
|
|
|
978e96 |
+/* This file must be run from within a directory called "elf". */
|
|
|
978e96 |
+
|
|
|
978e96 |
+int main (int argc, char *argv[])
|
|
|
978e96 |
+{
|
|
|
978e96 |
+ /* Nothing to do here: merely linking against tst-big-note-lib.so triggers
|
|
|
978e96 |
+ the bug. */
|
|
|
978e96 |
+ return 0;
|
|
|
978e96 |
+}
|