Blame SOURCES/gdb-rhbz1931344-bfd_seek-elf_read_notes.patch

a8223e
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
a8223e
From: Keith Seitz <keiths@redhat.com>
a8223e
Date: Thu, 25 Mar 2021 10:31:48 -0700
a8223e
Subject: gdb-rhbz1931344-bfd_seek-elf_read_notes.patch
a8223e
a8223e
;; Backport "Save/restore file offset while reading notes in core file"
a8223e
;; (Keith Seitz, RHBZ 1931344)
a8223e
a8223e
A recent bug (RH BZ 1931344) has exposed a bug in the core file
a8223e
build-ID support that I introduced a while ago. It is pretty
a8223e
easy to demonstate the problem following a simplified procedure
a8223e
outlined in that bug:
a8223e
a8223e
[shell1]
a8223e
shell1$ /usr/libexec/qemu-kvm
a8223e
a8223e
[shell2]
a8223e
shell2$ pkill -SEGV -x qemu-kvm
a8223e
a8223e
[shell1]
a8223e
Segmentation fault (core dumped)
a8223e
a8223e
Load this core file into GDB without specifying an executable
a8223e
(an unfortunate Fedora/RHEL-ism), and GDB will inform the user
a8223e
to install debuginfo for the "missing" executable:
a8223e
a8223e
$ gdb -nx -q core.12345
a8223e
...
a8223e
Missing separate debuginfo for the main executable file
a8223e
Try: dnf --enablerepo='*debug*' install /usr/lib/debug/.build-id/e2/e9c66d3117fb2bbb5b2be122f04f2664e5df54
a8223e
Core was generated by `/usr/libexec/qemu-kvm'.
a8223e
Program terminated with signal SIGSEGV, Segmentation fault.
a8223e
...
a8223e
a8223e
The suggested build-ID is actaully for gmp not qemu-kvm. The problem
a8223e
lies in _bfd_elf_core_find_build_id, where we loop over program headers
a8223e
looking for note segments:
a8223e
a8223e
  /* Read in program headers and parse notes.  */
a8223e
  for (i = 0; i < i_ehdr.e_phnum; ++i, ++i_phdr)
a8223e
    {
a8223e
      Elf_External_Phdr x_phdr;
a8223e
a8223e
      if (bfd_bread (&x_phdr, sizeof (x_phdr), abfd) != sizeof (x_phdr))
a8223e
        goto fail;
a8223e
      elf_swap_phdr_in (abfd, &x_phdr, i_phdr);
a8223e
a8223e
      if (i_phdr->p_type == PT_NOTE && i_phdr->p_filesz > 0)
a8223e
        {
a8223e
          elf_read_notes (abfd, offset + i_phdr->p_offset,
a8223e
                          i_phdr->p_filesz, i_phdr->p_align);
a8223e
a8223e
          if (abfd->build_id != NULL)
a8223e
            return TRUE;
a8223e
        }
a8223e
a8223e
elf_read_notes uses bfd_seek to forward the stream to the location of
a8223e
the note segment. When control returns to _bfd_elf_core_fild_build_id,
a8223e
the stream is no longer in the location looking at program headers, and
a8223e
all subsequent reads will read from the wrong file offset.
a8223e
a8223e
To fix this, this patch marks the stream location and ensures
a8223e
that it is restored after elf_read_notes is called.
a8223e
a8223e
bfd/ChangeLog
a8223e
2021-03-26  Keith Seitz  <keiths@redhat.com>
a8223e
a8223e
	* elfcore.h (_bfd_elf_core_find_build_id): Seek file
a8223e
	offset of program headers after calling elf_read_notes.
a8223e
a8223e
diff --git a/bfd/elfcore.h b/bfd/elfcore.h
a8223e
--- a/bfd/elfcore.h
a8223e
+++ b/bfd/elfcore.h
a8223e
@@ -410,6 +410,13 @@ NAME(_bfd_elf, core_find_build_id)
a8223e
 	{
a8223e
 	  elf_read_notes (abfd, offset + i_phdr->p_offset,
a8223e
 			  i_phdr->p_filesz, i_phdr->p_align);
a8223e
+
a8223e
+	  /* Make sure ABFD returns to processing the program headers.  */
a8223e
+	  if (bfd_seek (abfd, (file_ptr) (offset + i_ehdr.e_phoff
a8223e
+					  + (i + 1) * sizeof (x_phdr)),
a8223e
+			SEEK_SET) != 0)
a8223e
+	    goto fail;
a8223e
+
a8223e
 	  if (abfd->build_id != NULL)
a8223e
 	    return TRUE;
a8223e
 	}