|
| 1 | +From b3847cb425387f93f099513980721e3d87c236de Mon Sep 17 00:00:00 2001 |
| 2 | +From: AllSpark < [email protected]> |
| 3 | +Date: Wed, 1 Oct 2025 19:12:40 +0000 |
| 4 | +Subject: [PATCH] bfd/elf: Avoid matching corrupt section header in linker |
| 5 | + input (PR ld/33457) |
| 6 | + |
| 7 | +- Change elf_swap_shdr_in to return bool; return false for corrupt section header when abfd->is_linker_input. |
| 8 | +- In elf_object_p, check return value of elf_swap_shdr_in and reject on failure. |
| 9 | +- Preserve warning message and set abfd->read_only after rejection logic. |
| 10 | + |
| 11 | +Backport of upstream patch 9ca499644a21ceb3f946d1c179c38a83be084490. |
| 12 | + |
| 13 | +Signed-off-by: Azure Linux Security Servicing Account < [email protected]> |
| 14 | +Upstream-reference: AI Backport of https://github.com/bminor/binutils-gdb/commit/9ca499644a21ceb3f946d1c179c38a83be084490.patch |
| 15 | +--- |
| 16 | + bfd/elfcode.h | 16 ++++++++++------ |
| 17 | + 1 file changed, 10 insertions(+), 6 deletions(-) |
| 18 | + |
| 19 | +diff --git a/bfd/elfcode.h b/bfd/elfcode.h |
| 20 | +index 7eb27c2e..8195b92e 100644 |
| 21 | +--- a/bfd/elfcode.h |
| 22 | ++++ b/bfd/elfcode.h |
| 23 | +@@ -298,7 +298,7 @@ elf_swap_ehdr_out (bfd *abfd, |
| 24 | + /* Translate an ELF section header table entry in external format into an |
| 25 | + ELF section header table entry in internal format. */ |
| 26 | + |
| 27 | +-static void |
| 28 | ++static bool |
| 29 | + elf_swap_shdr_in (bfd *abfd, |
| 30 | + const Elf_External_Shdr *src, |
| 31 | + Elf_Internal_Shdr *dst) |
| 32 | +@@ -325,9 +325,12 @@ elf_swap_shdr_in (bfd *abfd, |
| 33 | + && ((ufile_ptr) dst->sh_offset > filesize |
| 34 | + || dst->sh_size > filesize - dst->sh_offset)) |
| 35 | + { |
| 36 | +- abfd->read_only = 1; |
| 37 | + _bfd_error_handler (_("warning: %pB has a section " |
| 38 | + "extending past end of file"), abfd); |
| 39 | ++ /* PR ld/33457: Don't match corrupt section header. */ |
| 40 | ++ if (abfd->is_linker_input) |
| 41 | ++ return false; |
| 42 | ++ abfd->read_only = 1; |
| 43 | + } |
| 44 | + } |
| 45 | + dst->sh_link = H_GET_32 (abfd, src->sh_link); |
| 46 | +@@ -336,6 +339,7 @@ elf_swap_shdr_in (bfd *abfd, |
| 47 | + dst->sh_entsize = H_GET_WORD (abfd, src->sh_entsize); |
| 48 | + dst->bfd_section = NULL; |
| 49 | + dst->contents = NULL; |
| 50 | ++ return true; |
| 51 | + } |
| 52 | + |
| 53 | + /* Translate an ELF section header table entry in internal format into an |
| 54 | +@@ -628,9 +632,9 @@ elf_object_p (bfd *abfd) |
| 55 | + |
| 56 | + /* Read the first section header at index 0, and convert to internal |
| 57 | + form. */ |
| 58 | +- if (bfd_bread (&x_shdr, sizeof x_shdr, abfd) != sizeof (x_shdr)) |
| 59 | ++ if (bfd_bread (&x_shdr, sizeof x_shdr, abfd) != sizeof (x_shdr) |
| 60 | ++ || !elf_swap_shdr_in (abfd, &x_shdr, &i_shdr)) |
| 61 | + goto got_no_match; |
| 62 | +- elf_swap_shdr_in (abfd, &x_shdr, &i_shdr); |
| 63 | + |
| 64 | + /* If the section count is zero, the actual count is in the first |
| 65 | + section header. */ |
| 66 | +@@ -716,9 +720,9 @@ elf_object_p (bfd *abfd) |
| 67 | + to internal form. */ |
| 68 | + for (shindex = 1; shindex < i_ehdrp->e_shnum; shindex++) |
| 69 | + { |
| 70 | +- if (bfd_bread (&x_shdr, sizeof x_shdr, abfd) != sizeof (x_shdr)) |
| 71 | ++ if (bfd_bread (&x_shdr, sizeof x_shdr, abfd) != sizeof (x_shdr) |
| 72 | ++ || !elf_swap_shdr_in (abfd, &x_shdr, i_shdrp + shindex)) |
| 73 | + goto got_no_match; |
| 74 | +- elf_swap_shdr_in (abfd, &x_shdr, i_shdrp + shindex); |
| 75 | + |
| 76 | + /* Sanity check sh_link and sh_info. */ |
| 77 | + if (i_shdrp[shindex].sh_link >= num_sec) |
| 78 | +-- |
| 79 | +2.45.4 |
| 80 | + |
0 commit comments