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

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