aboutsummaryrefslogtreecommitdiff
path: root/bfd/peicode.h
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2022-10-07 10:23:05 +1030
committerAlan Modra <amodra@gmail.com>2022-10-07 12:30:28 +1030
commitea4e4a19b7f6c192c307b5a37c67d141f3aea074 (patch)
tree7428330c72d7adb92a9e32032ba7041c3c42d8b3 /bfd/peicode.h
parentfea044ba7b5ed9be93ce49b36188edbba7fcebb3 (diff)
downloadgdb-ea4e4a19b7f6c192c307b5a37c67d141f3aea074.zip
gdb-ea4e4a19b7f6c192c307b5a37c67d141f3aea074.tar.gz
gdb-ea4e4a19b7f6c192c307b5a37c67d141f3aea074.tar.bz2
PR29653, objcopy/strip: fuzzed small input file induces large output file
_bfd_check_format functions should not print errors or warnings if they return NULL. A NULL return means the particular target under test does not match, so there isn't any reason to make a complaint about the target. In fact there isn't a good reason to warn even if the target matches, except via the _bfd_per_xvec_warn mechanism; Some other target might be a better match. This patch tidies pe_bfd_object_p with the above in mind, and restricts the PE optional header SectionAlignment and FileAlignment fields somewhat. I chose to warn on nonsense values rather than refusing to match. Refusing to match would be OK too. PR 29653 * peXXigen.c (_bfd_XXi_swap_aouthdr_in): Don't emit error about invalid NumberOfRvaAndSizes here. Limit loop copying data directory to IMAGE_NUMBEROF_DIRECTORY_ENTRIES. * peicode.h (pe_bfd_object_p): Don't clear and test bfd_error around bfd_coff_swap_aouthdr_in. Warn on invalid SectionAlignment, FileAlignment and NumberOfRvaAndSizes. Don't return NULL on invalid NumberOfRvaAndSizes.
Diffstat (limited to 'bfd/peicode.h')
-rw-r--r--bfd/peicode.h34
1 files changed, 28 insertions, 6 deletions
diff --git a/bfd/peicode.h b/bfd/peicode.h
index 54a159f..3888dd4 100644
--- a/bfd/peicode.h
+++ b/bfd/peicode.h
@@ -1519,19 +1519,41 @@ pe_bfd_object_p (bfd * abfd)
if (amt > opt_hdr_size)
memset (opthdr + opt_hdr_size, 0, amt - opt_hdr_size);
- bfd_set_error (bfd_error_no_error);
- bfd_coff_swap_aouthdr_in (abfd, opthdr, & internal_a);
- if (bfd_get_error () != bfd_error_no_error)
- return NULL;
- }
+ bfd_coff_swap_aouthdr_in (abfd, opthdr, &internal_a);
+
+ struct internal_extra_pe_aouthdr *a = &internal_a.pe;
+ if ((a->SectionAlignment & -a->SectionAlignment) != a->SectionAlignment
+ || a->SectionAlignment >= 0x80000000)
+ {
+ const char **warn = _bfd_per_xvec_warn (abfd->xvec);
+ *warn = _("%pB: adjusting invalid SectionAlignment");
+ a->SectionAlignment &= -a->SectionAlignment;
+ if (a->SectionAlignment >= 0x80000000)
+ a->SectionAlignment = 0x40000000;
+ }
+
+ if ((a->FileAlignment & -a->FileAlignment) != a->FileAlignment
+ || a->FileAlignment > a->SectionAlignment)
+ {
+ const char **warn = _bfd_per_xvec_warn (abfd->xvec);
+ *warn = _("%pB: adjusting invalid FileAlignment");
+ a->FileAlignment &= -a->FileAlignment;
+ if (a->FileAlignment > a->SectionAlignment)
+ a->FileAlignment = a->SectionAlignment;
+ }
+ if (a->NumberOfRvaAndSizes > IMAGE_NUMBEROF_DIRECTORY_ENTRIES)
+ {
+ const char **warn = _bfd_per_xvec_warn (abfd->xvec);
+ *warn = _("%pB: invalid NumberOfRvaAndSizes");
+ }
+ }
result = coff_real_object_p (abfd, internal_f.f_nscns, &internal_f,
(opt_hdr_size != 0
? &internal_a
: (struct internal_aouthdr *) NULL));
-
if (result)
{
/* Now the whole header has been processed, see if there is a build-id */