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

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