aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelix Willgerodt <felix.willgerodt@intel.com>2023-11-09 14:08:10 +0100
committerFelix Willgerodt <felix.willgerodt@intel.com>2023-11-21 08:56:25 +0100
commit4be3bbe89f67c360098373d4850565a472c36f9d (patch)
tree9c3af5df924396853a927b8d3058b10d40c270b1
parent5a6c54baa43e310447f2070e51a5ec395f188905 (diff)
downloadgdb-4be3bbe89f67c360098373d4850565a472c36f9d.zip
gdb-4be3bbe89f67c360098373d4850565a472c36f9d.tar.gz
gdb-4be3bbe89f67c360098373d4850565a472c36f9d.tar.bz2
gdb: Fix segfault with a big .dynamic section size
Consider a binary with an erroneous size of the .dynamic section: $ readelf -S a.out ... [24] .dynamic DYNAMIC 0000000000004c20 00003c20 000000fffffffa40 0000000000000010 WA 7 0 8 ... This binary causes a segfault in GDB. GDB is trying to write the .dynamic section into memory allocated on the stack with alloca(). However, the allocation silently fails and the subsequent access to the memory is causing the segfault. (On my node at least.) Stack allocation is a bad idea for something of variable size that GDB has no control over. So I changed the code to heap allocation. In addition, I changed the type of sect_size to the type that bfd actually returns. There should be no user visible change after this. Approved-By: Tom Tromey <tom@tromey.com>
-rw-r--r--gdb/solib.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/gdb/solib.c b/gdb/solib.c
index b9fb911..d055bea 100644
--- a/gdb/solib.c
+++ b/gdb/solib.c
@@ -1501,7 +1501,8 @@ int
gdb_bfd_scan_elf_dyntag (const int desired_dyntag, bfd *abfd, CORE_ADDR *ptr,
CORE_ADDR *ptr_addr)
{
- int arch_size, step, sect_size;
+ int arch_size, step;
+ bfd_size_type sect_size;
long current_dyntag;
CORE_ADDR dyn_ptr, dyn_addr;
gdb_byte *bufend, *bufstart, *buf;
@@ -1546,7 +1547,8 @@ gdb_bfd_scan_elf_dyntag (const int desired_dyntag, bfd *abfd, CORE_ADDR *ptr,
/* Read in .dynamic from the BFD. We will get the actual value
from memory later. */
sect_size = bfd_section_size (sect);
- buf = bufstart = (gdb_byte *) alloca (sect_size);
+ gdb::byte_vector buffer (sect_size);
+ buf = bufstart = buffer.data ();
if (!bfd_get_section_contents (abfd, sect,
buf, 0, sect_size))
return 0;