This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix PR gdb/20948: --write option to GDB causes segmentation fault


When opening a BFD for update, as gdb --write does, modifications to
anything but the contents of sections is restricted.

Do not try to write back any ELF headers in this case.

Successfully tested with no regressions on x86_64-pc-linux-gnu with
the binutils, gas, ld and gdb testsuites.

The PR is assigned to GDB, but the fix is to BFD, hence the
submission to binutils mailing list instead of GDB.

>From b61a0bf98f7effdbee30f0a2b9dfe488b69edf54 Mon Sep 17 00:00:00 2001
From: Jozef Lawrynowicz <jozef.l@mittosystems.com>
Date: Tue, 11 Sep 2018 22:56:36 +0100
Subject: [PATCH] Fix PR gdb/20948: --write option to GDB causes segmentation
 fault

When opening a BFD for update, as gdb --write does, modifications to
anything but the contents of sections is restricted.

Do not try to write back any ELF headers in this case.

	PR gdb/20948
	* bfd/elf.c (_bfd_elf_write_object_contents): Return from function
	early if abfd->direction == both_direction.
	* gdb/testsuite/gdb.base/write_mem.exp: New test.
	* gdb/testsuite/gdb.base/write_mem.c: Likewise.
---
 bfd/elf.c                            | 12 ++++++++++++
 gdb/testsuite/gdb.base/write_mem.c   |  7 +++++++
 gdb/testsuite/gdb.base/write_mem.exp | 30 ++++++++++++++++++++++++++++++
 3 files changed, 49 insertions(+)
 create mode 100644 gdb/testsuite/gdb.base/write_mem.c
 create mode 100644 gdb/testsuite/gdb.base/write_mem.exp

diff --git a/bfd/elf.c b/bfd/elf.c
index 02d605c..5320ae2 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -6391,6 +6391,18 @@ _bfd_elf_write_object_contents (bfd *abfd)
   if (! abfd->output_has_begun
       && ! _bfd_elf_compute_section_file_positions (abfd, NULL))
     return FALSE;
+  /* Do not rewrite ELF data when the BFD has been opened for update.
+     abfd->output_has_begun was set to TRUE on opening, so creation of new
+     sections, and modification of existing section sizes was restricted.
+     This means the ELF header, program headers and section headers can't have
+     changed.
+     If the contents of any sections has been modified, then those changes have
+     already been written to the BFD.  */
+  else if (abfd->direction == both_direction)
+    {
+      BFD_ASSERT (abfd->output_has_begun);
+      return TRUE;
+    }
 
   i_shdrp = elf_elfsections (abfd);
 
diff --git a/gdb/testsuite/gdb.base/write_mem.c b/gdb/testsuite/gdb.base/write_mem.c
new file mode 100644
index 0000000..941f172
--- /dev/null
+++ b/gdb/testsuite/gdb.base/write_mem.c
@@ -0,0 +1,7 @@
+/* Test for PR gdb/20948.  */
+
+int main (void)
+{
+  while (1);
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.base/write_mem.exp b/gdb/testsuite/gdb.base/write_mem.exp
new file mode 100644
index 0000000..e1f393a
--- /dev/null
+++ b/gdb/testsuite/gdb.base/write_mem.exp
@@ -0,0 +1,30 @@
+# Test for PR gdb/20948
+# Verify that invoking gdb with the --write argument works as expected
+
+global GDBFLAGS
+standard_testfile
+
+if {[build_executable $testfile.exp $testfile \
+  $srcfile [list debug nowarnings] ] == -1} {
+    untested $testfile.exp
+    return -1
+}
+
+set old_gdbflags $GDBFLAGS
+
+# Expect a failure before --write has been added to the command line
+set GDBFLAGS "$old_gdbflags $binfile"
+clean_restart
+test_print_reject "set {int}main = 0x4242" "Cannot access memory at address"
+
+# Setting memory should now work correctly after adding --write
+set GDBFLAGS "$old_gdbflags --write $binfile"
+clean_restart
+gdb_test_no_output "set {int}main = 0x4242"
+
+# Check that memory write persists after quitting GDB
+gdb_exit
+gdb_start
+gdb_test "x /xh main" "<main>:.*4242"
+
+set GDBFLAGS $old_gdbflags
-- 
2.7.4


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]