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

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