mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-08-02 02:35:00 +08:00
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.
This commit is contained in:
@ -517,45 +517,26 @@ _bfd_XXi_swap_aouthdr_in (bfd * abfd,
|
||||
a->LoaderFlags = H_GET_32 (abfd, src->LoaderFlags);
|
||||
a->NumberOfRvaAndSizes = H_GET_32 (abfd, src->NumberOfRvaAndSizes);
|
||||
|
||||
{
|
||||
unsigned idx;
|
||||
/* PR 17512: Don't blindly trust NumberOfRvaAndSizes. */
|
||||
unsigned idx;
|
||||
for (idx = 0;
|
||||
idx < a->NumberOfRvaAndSizes && idx < IMAGE_NUMBEROF_DIRECTORY_ENTRIES;
|
||||
idx++)
|
||||
{
|
||||
/* If data directory is empty, rva also should be 0. */
|
||||
int size = H_GET_32 (abfd, src->DataDirectory[idx][1]);
|
||||
int vma = size ? H_GET_32 (abfd, src->DataDirectory[idx][0]) : 0;
|
||||
|
||||
/* PR 17512: Corrupt PE binaries can cause seg-faults. */
|
||||
if (a->NumberOfRvaAndSizes > IMAGE_NUMBEROF_DIRECTORY_ENTRIES)
|
||||
{
|
||||
/* xgettext:c-format */
|
||||
_bfd_error_handler
|
||||
(_("%pB: aout header specifies an invalid number of"
|
||||
" data-directory entries: %u"), abfd, a->NumberOfRvaAndSizes);
|
||||
bfd_set_error (bfd_error_bad_value);
|
||||
a->DataDirectory[idx].Size = size;
|
||||
a->DataDirectory[idx].VirtualAddress = vma;
|
||||
}
|
||||
|
||||
/* Paranoia: If the number is corrupt, then assume that the
|
||||
actual entries themselves might be corrupt as well. */
|
||||
a->NumberOfRvaAndSizes = 0;
|
||||
}
|
||||
|
||||
for (idx = 0; idx < a->NumberOfRvaAndSizes; idx++)
|
||||
{
|
||||
/* If data directory is empty, rva also should be 0. */
|
||||
int size =
|
||||
H_GET_32 (abfd, src->DataDirectory[idx][1]);
|
||||
|
||||
a->DataDirectory[idx].Size = size;
|
||||
|
||||
if (size)
|
||||
a->DataDirectory[idx].VirtualAddress =
|
||||
H_GET_32 (abfd, src->DataDirectory[idx][0]);
|
||||
else
|
||||
a->DataDirectory[idx].VirtualAddress = 0;
|
||||
}
|
||||
|
||||
while (idx < IMAGE_NUMBEROF_DIRECTORY_ENTRIES)
|
||||
{
|
||||
a->DataDirectory[idx].Size = 0;
|
||||
a->DataDirectory[idx].VirtualAddress = 0;
|
||||
idx ++;
|
||||
}
|
||||
}
|
||||
while (idx < IMAGE_NUMBEROF_DIRECTORY_ENTRIES)
|
||||
{
|
||||
a->DataDirectory[idx].Size = 0;
|
||||
a->DataDirectory[idx].VirtualAddress = 0;
|
||||
idx++;
|
||||
}
|
||||
|
||||
if (aouthdr_int->entry)
|
||||
{
|
||||
|
@ -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 */
|
||||
|
Reference in New Issue
Block a user