69 lines
2.6 KiB
Diff
69 lines
2.6 KiB
Diff
|
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
|
||
|
From: Andrew Burgess <aburgess@redhat.com>
|
||
|
Date: Thu, 14 Sep 2023 13:06:26 +0100
|
||
|
Subject: gdb-bz2237392-dwarf-obstack-allocation.patch
|
||
|
|
||
|
;; Backport upstream commit 54392c4df604f20 to fix an incorrect
|
||
|
;; obstack allocation that wold lead to memory corruption.
|
||
|
|
||
|
gdb: fix buffer overflow in DWARF reader
|
||
|
|
||
|
In this commit:
|
||
|
|
||
|
commit 48ac197b0c209ccf1f2de9704eb6cdf7c5c73a8e
|
||
|
Date: Fri Nov 19 10:12:44 2021 -0700
|
||
|
|
||
|
Handle multiple addresses in call_site_target
|
||
|
|
||
|
a buffer overflow bug was introduced when the following code was
|
||
|
added:
|
||
|
|
||
|
CORE_ADDR *saved = XOBNEWVAR (&objfile->objfile_obstack, CORE_ADDR,
|
||
|
addresses.size ());
|
||
|
std::copy (addresses.begin (), addresses.end (), saved);
|
||
|
|
||
|
The definition of XOBNEWVAR is (from libiberty.h):
|
||
|
|
||
|
#define XOBNEWVAR(O, T, S) ((T *) obstack_alloc ((O), (S)))
|
||
|
|
||
|
So 'saved' is going to point to addresses.size () bytes of memory,
|
||
|
however, the std::copy will write addresses.size () number of
|
||
|
CORE_ADDR sized entries to the address pointed to by 'saved', this is
|
||
|
going to result in memory corruption.
|
||
|
|
||
|
The mistake is that we should have used XOBNEWVEC, which allocates a
|
||
|
vector of entries, the definition of XOBNEWVEC is:
|
||
|
|
||
|
#define XOBNEWVEC(O, T, N) \
|
||
|
((T *) obstack_alloc ((O), sizeof (T) * (N)))
|
||
|
|
||
|
Which means we will have set aside enough space to create a copy of
|
||
|
the contents of the addresses vector.
|
||
|
|
||
|
I'm not sure how to create a test for this problem, this issue cropped
|
||
|
up when debugging a particular i686 built binary, which just happened
|
||
|
to trigger a glibc assertion (likely due to random memory corruption),
|
||
|
debugging the same binary built for x86-64 appeared to work just fine.
|
||
|
|
||
|
Using valgrind on the failing GDB binary pointed straight to the cause
|
||
|
of the problem, and with this patch in place there are no longer
|
||
|
valgrind errors in this area.
|
||
|
|
||
|
If anyone has ideas for a test I'm happy to work on something.
|
||
|
|
||
|
Co-Authored-By: Keith Seitz <keiths@redhat.com>
|
||
|
Approved-By: Tom Tromey <tom@tromey.com>
|
||
|
|
||
|
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
|
||
|
--- a/gdb/dwarf2/read.c
|
||
|
+++ b/gdb/dwarf2/read.c
|
||
|
@@ -12506,7 +12506,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
|
||
|
std::vector<CORE_ADDR> addresses;
|
||
|
dwarf2_ranges_read_low_addrs (ranges_offset, target_cu,
|
||
|
target_die->tag, addresses);
|
||
|
- CORE_ADDR *saved = XOBNEWVAR (&objfile->objfile_obstack, CORE_ADDR,
|
||
|
+ CORE_ADDR *saved = XOBNEWVEC (&objfile->objfile_obstack, CORE_ADDR,
|
||
|
addresses.size ());
|
||
|
std::copy (addresses.begin (), addresses.end (), saved);
|
||
|
call_site->target.set_loc_array (addresses.size (), saved);
|