Accepting request 647251 from devel:gcc
- Fix crash when reading core [bsc #1109013] * Add gdb-fix-crash-when-reading-core.patch https://sourceware.org/ml/gdb-cvs/2018-11/msg00022.html (forwarded request 647075 from tomdevries) OBS-URL: https://build.opensuse.org/request/show/647251 OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/gdb?expand=0&rev=123
This commit is contained in:
commit
2e7557aa27
220
gdb-fix-crash-when-reading-core.patch
Normal file
220
gdb-fix-crash-when-reading-core.patch
Normal file
@ -0,0 +1,220 @@
|
||||
From 31aceee86308321c2ef299e50773d0043e458e7f Mon Sep 17 00:00:00 2001
|
||||
From: Tom de Vries <tdevries@suse.de>
|
||||
Date: Thu, 1 Nov 2018 09:21:18 +0100
|
||||
Subject: [PATCH] [gdb] Fix gdb crash when reading core file
|
||||
|
||||
Consider the test-case from this patch, compiled with O0.
|
||||
|
||||
The executable segfaults, and generates a core dump:
|
||||
...
|
||||
$ ./a.out
|
||||
Segmentation fault (core dumped)
|
||||
...
|
||||
|
||||
When loading the core file, limiting stack size to 4MB, gdb crashes:
|
||||
...
|
||||
$ ulimit -s 4096
|
||||
$ gdb -batch ./a.out core.saved
|
||||
[New LWP 19379]
|
||||
Segmentation fault (core dumped)
|
||||
...
|
||||
|
||||
The crash originates here in linux_vsyscall_range_raw, where we call alloca
|
||||
with phdrs_size == 4194112 (roughly 4MB):
|
||||
...
|
||||
phdrs = (Elf_Internal_Phdr *) alloca (phdrs_size);
|
||||
...
|
||||
|
||||
While for this test-case gdb runs fine with the system default stack limit of
|
||||
8MB, there are cases reported of 12MB phdrs_size where gdb also crashes with
|
||||
the system default stack limit.
|
||||
|
||||
Fix this by using xmalloc instead of alloca, which prevents the crash provided
|
||||
the stack limit is at least 112kb.
|
||||
|
||||
Build and reg-tested on x86_64-linux.
|
||||
|
||||
2018-11-06 Tom de Vries <tdevries@suse.de>
|
||||
|
||||
* linux-tdep.c (linux_vsyscall_range_raw): Use xmalloc to allocate
|
||||
program headers.
|
||||
|
||||
* gdb.base/many-headers.c: New test.
|
||||
* gdb.base/many-headers.exp: New file.
|
||||
---
|
||||
gdb/ChangeLog | 5 +++
|
||||
gdb/linux-tdep.c | 12 +++---
|
||||
gdb/testsuite/ChangeLog | 5 +++
|
||||
gdb/testsuite/gdb.base/many-headers.c | 50 ++++++++++++++++++++++++
|
||||
gdb/testsuite/gdb.base/many-headers.exp | 67 +++++++++++++++++++++++++++++++++
|
||||
5 files changed, 133 insertions(+), 6 deletions(-)
|
||||
create mode 100644 gdb/testsuite/gdb.base/many-headers.c
|
||||
create mode 100644 gdb/testsuite/gdb.base/many-headers.exp
|
||||
|
||||
diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c
|
||||
index c958c0dfe9..2c766808f0 100644
|
||||
--- a/gdb/linux-tdep.c
|
||||
+++ b/gdb/linux-tdep.c
|
||||
@@ -2269,7 +2269,6 @@ linux_vsyscall_range_raw (struct gdbarch *gdbarch, struct mem_range *range)
|
||||
the vDSO. */
|
||||
if (!target_has_execution)
|
||||
{
|
||||
- Elf_Internal_Phdr *phdrs;
|
||||
long phdrs_size;
|
||||
int num_phdrs, i;
|
||||
|
||||
@@ -2277,16 +2276,17 @@ linux_vsyscall_range_raw (struct gdbarch *gdbarch, struct mem_range *range)
|
||||
if (phdrs_size == -1)
|
||||
return 0;
|
||||
|
||||
- phdrs = (Elf_Internal_Phdr *) alloca (phdrs_size);
|
||||
- num_phdrs = bfd_get_elf_phdrs (core_bfd, phdrs);
|
||||
+ gdb::unique_xmalloc_ptr<Elf_Internal_Phdr>
|
||||
+ phdrs ((Elf_Internal_Phdr *) xmalloc (phdrs_size));
|
||||
+ num_phdrs = bfd_get_elf_phdrs (core_bfd, phdrs.get ());
|
||||
if (num_phdrs == -1)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < num_phdrs; i++)
|
||||
- if (phdrs[i].p_type == PT_LOAD
|
||||
- && phdrs[i].p_vaddr == range->start)
|
||||
+ if (phdrs.get ()[i].p_type == PT_LOAD
|
||||
+ && phdrs.get ()[i].p_vaddr == range->start)
|
||||
{
|
||||
- range->length = phdrs[i].p_memsz;
|
||||
+ range->length = phdrs.get ()[i].p_memsz;
|
||||
return 1;
|
||||
}
|
||||
|
||||
diff --git a/gdb/testsuite/gdb.base/many-headers.c b/gdb/testsuite/gdb.base/many-headers.c
|
||||
new file mode 100644
|
||||
index 0000000000..49675b4e40
|
||||
--- /dev/null
|
||||
+++ b/gdb/testsuite/gdb.base/many-headers.c
|
||||
@@ -0,0 +1,50 @@
|
||||
+/* This testcase is part of GDB, the GNU debugger.
|
||||
+
|
||||
+ Copyright 2018 Free Software Foundation, Inc.
|
||||
+
|
||||
+ This program is free software; you can redistribute it and/or modify
|
||||
+ it under the terms of the GNU General Public License as published by
|
||||
+ the Free Software Foundation; either version 3 of the License, or
|
||||
+ (at your option) any later version.
|
||||
+
|
||||
+ This program is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ GNU General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU General Public License
|
||||
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+#include <malloc.h>
|
||||
+#include <sys/mman.h>
|
||||
+
|
||||
+int
|
||||
+main (void)
|
||||
+{
|
||||
+ char *ptr;
|
||||
+ int ind, cnt;
|
||||
+
|
||||
+ cnt = 100000;
|
||||
+ for (ind = 0; ind < cnt; ind++)
|
||||
+ {
|
||||
+ ptr = mmap (NULL, 100, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
|
||||
+ if (ptr == NULL)
|
||||
+ {
|
||||
+ fprintf (stderr, "Error allocating memory using mmap\n");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ ptr = mmap (NULL, 100, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
|
||||
+ if (ptr == NULL)
|
||||
+ {
|
||||
+ fprintf (stderr, "Error allocating memory using mmap\n");
|
||||
+ return -1;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ ptr = NULL;
|
||||
+ *ptr = '\0';
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
diff --git a/gdb/testsuite/gdb.base/many-headers.exp b/gdb/testsuite/gdb.base/many-headers.exp
|
||||
new file mode 100644
|
||||
index 0000000000..f02b291e36
|
||||
--- /dev/null
|
||||
+++ b/gdb/testsuite/gdb.base/many-headers.exp
|
||||
@@ -0,0 +1,67 @@
|
||||
+# Copyright 2018 Free Software Foundation, Inc.
|
||||
+
|
||||
+# This program is free software; you can redistribute it and/or modify
|
||||
+# it under the terms of the GNU General Public License as published by
|
||||
+# the Free Software Foundation; either version 3 of the License, or
|
||||
+# (at your option) any later version.
|
||||
+#
|
||||
+# This program is distributed in the hope that it will be useful,
|
||||
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+# GNU General Public License for more details.
|
||||
+#
|
||||
+# You should have received a copy of the GNU General Public License
|
||||
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
+
|
||||
+# Test if gdb can read a core file with a program header size of 4MB, if the
|
||||
+# stack size is limited to 4MB.
|
||||
+
|
||||
+if { [target_info gdb_protocol] != "" } {
|
||||
+ # Even though the feature under features being tested are supported by
|
||||
+ # gdbserver, the way this test is written doesn't make it easy with a
|
||||
+ # remote target.
|
||||
+ unsupported "not native"
|
||||
+ return
|
||||
+}
|
||||
+
|
||||
+standard_testfile
|
||||
+
|
||||
+if {[prepare_for_testing "failed to prepare" $testfile $srcfile debug]} {
|
||||
+ return -1
|
||||
+}
|
||||
+
|
||||
+# Generate core file.
|
||||
+set corefile [core_find $binfile]
|
||||
+if {$corefile == ""} {
|
||||
+ return 0
|
||||
+}
|
||||
+
|
||||
+# Limit is in kb, so this is 4MB.
|
||||
+set stack_limit 4096
|
||||
+
|
||||
+# Verify if we can set the stack limit.
|
||||
+catch {
|
||||
+ system [concat \
|
||||
+ "(" \
|
||||
+ "ulimit -s $stack_limit;" \
|
||||
+ ")"]
|
||||
+} msg
|
||||
+if { "$msg" != "" } {
|
||||
+ untested "Can't set stack limit"
|
||||
+ return -1
|
||||
+}
|
||||
+
|
||||
+# Run gdb with stack limit
|
||||
+catch {
|
||||
+ system [concat \
|
||||
+ "(" \
|
||||
+ "ulimit -s $stack_limit;" \
|
||||
+ "$GDB $INTERNAL_GDBFLAGS $GDBFLAGS -batch -core=$corefile" \
|
||||
+ ")"]
|
||||
+} msg
|
||||
+set test "read core file"
|
||||
+if { "$msg" == "" } {
|
||||
+ pass "$test"
|
||||
+} else {
|
||||
+ fail "$test"
|
||||
+}
|
||||
--
|
||||
2.16.4
|
||||
|
@ -1,3 +1,10 @@
|
||||
-------------------------------------------------------------------
|
||||
Wed Nov 7 15:04:28 UTC 2018 - tdevries@suse.com
|
||||
|
||||
- Fix crash when reading core [bsc #1109013]
|
||||
* Add gdb-fix-crash-when-reading-core.patch
|
||||
https://sourceware.org/ml/gdb-cvs/2018-11/msg00022.html
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Tue Sep 11 15:01:59 UTC 2018 - matz@suse.com
|
||||
|
||||
|
5
gdb.spec
5
gdb.spec
@ -240,6 +240,9 @@ Patch1004: gdb-fix-buf-overflow.diff
|
||||
Patch1005: gdb-7.10-swo18929.patch
|
||||
Patch1007: gdb-fix-s390-build.diff
|
||||
|
||||
# Backports from master
|
||||
Patch2000: gdb-fix-crash-when-reading-core.patch
|
||||
|
||||
# libipt support
|
||||
Patch3000: v1.5-libipt-static.patch
|
||||
|
||||
@ -554,6 +557,8 @@ find -name "*.info*"|xargs rm -f
|
||||
%patch1005 -p1
|
||||
%patch1007 -p1
|
||||
|
||||
%patch2000 -p1
|
||||
|
||||
#unpack libipt
|
||||
%if 0%{have_libipt}
|
||||
tar xzf %{SOURCE7}
|
||||
|
Loading…
x
Reference in New Issue
Block a user