Fix access violation when parsing a corrupt IEEE binary.
PR binutils/21612 * libieee.h (struct common_header_type): Add end_p field. * ieee.c (this_byte_and_next): Do not advance input_p beyond end_p. (read_id): Check for a length that exceeds the remaining bytes in the input buffer. (ieee_seek): Initialise end_p. (ieee_archive_p): Likewise. (ieee_object_p): Likewise.
This commit is contained in:
parent
80053e466b
commit
acb56a8301
@ -1,3 +1,15 @@
|
||||
2017-06-19 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
PR binutils/21612
|
||||
* libieee.h (struct common_header_type): Add end_p field.
|
||||
* ieee.c (this_byte_and_next): Do not advance input_p beyond
|
||||
end_p.
|
||||
(read_id): Check for a length that exceeds the remaining bytes in
|
||||
the input buffer.
|
||||
(ieee_seek): Initialise end_p.
|
||||
(ieee_archive_p): Likewise.
|
||||
(ieee_object_p): Likewise.
|
||||
|
||||
2017-06-19 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
PR binutils/21611
|
||||
|
23
bfd/ieee.c
23
bfd/ieee.c
@ -170,7 +170,7 @@ ieee_write_id (bfd *abfd, const char *id)
|
||||
standard requires. */
|
||||
|
||||
#define this_byte(ieee) *((ieee)->input_p)
|
||||
#define this_byte_and_next(ieee) (*((ieee)->input_p++))
|
||||
#define this_byte_and_next(ieee) ((ieee)->input_p < (ieee)->end_p ? *((ieee)->input_p++) : 0)
|
||||
|
||||
static bfd_boolean
|
||||
next_byte (common_header_type * ieee)
|
||||
@ -220,6 +220,15 @@ read_id (common_header_type *ieee)
|
||||
length = (length * 256) + this_byte_and_next (ieee);
|
||||
}
|
||||
|
||||
/* PR 21612: Check for an invalid length. */
|
||||
if (ieee->input_p + length >= ieee->end_p)
|
||||
{
|
||||
_bfd_error_handler (_("IEEE parser: string length: %#lx longer than buffer: %#lx"),
|
||||
length, (long) (ieee->end_p - ieee->input_p));
|
||||
bfd_set_error (bfd_error_invalid_operation);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Buy memory and read string. */
|
||||
string = bfd_alloc (ieee->abfd, (bfd_size_type) length + 1);
|
||||
if (!string)
|
||||
@ -699,12 +708,12 @@ ieee_seek (ieee_data_type * ieee, file_ptr offset)
|
||||
if (offset < 0 || (bfd_size_type) offset >= ieee->h.total_amt)
|
||||
{
|
||||
ieee->h.input_p = ieee->h.first_byte + ieee->h.total_amt;
|
||||
ieee->h.last_byte = ieee->h.input_p;
|
||||
ieee->h.end_p = ieee->h.last_byte = ieee->h.input_p;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ieee->h.input_p = ieee->h.first_byte + offset;
|
||||
ieee->h.last_byte = (ieee->h.first_byte + ieee_part_after (ieee, offset));
|
||||
ieee->h.end_p = ieee->h.last_byte = (ieee->h.first_byte + ieee_part_after (ieee, offset));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -1375,6 +1384,8 @@ ieee_archive_p (bfd *abfd)
|
||||
|
||||
ieee->h.first_byte = buffer;
|
||||
ieee->h.input_p = buffer;
|
||||
ieee->h.total_amt = sizeof (buffer);
|
||||
ieee->h.end_p = buffer + sizeof (buffer);
|
||||
|
||||
ieee->h.abfd = abfd;
|
||||
|
||||
@ -1442,6 +1453,8 @@ ieee_archive_p (bfd *abfd)
|
||||
bfd_bread ((void *) buffer, (bfd_size_type) sizeof (buffer), abfd);
|
||||
ieee->h.first_byte = buffer;
|
||||
ieee->h.input_p = buffer;
|
||||
ieee->h.total_amt = sizeof (buffer);
|
||||
ieee->h.end_p = buffer + sizeof (buffer);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1465,6 +1478,8 @@ ieee_archive_p (bfd *abfd)
|
||||
bfd_bread ((void *) buffer, (bfd_size_type) sizeof (buffer), abfd);
|
||||
ieee->h.first_byte = buffer;
|
||||
ieee->h.input_p = buffer;
|
||||
ieee->h.total_amt = sizeof (buffer);
|
||||
ieee->h.end_p = buffer + sizeof (buffer);
|
||||
|
||||
(void) next_byte (&(ieee->h)); /* Drop F8. */
|
||||
if (! next_byte (&(ieee->h))) /* Drop 14. */
|
||||
@ -1890,6 +1905,8 @@ ieee_object_p (bfd *abfd)
|
||||
|
||||
ieee->h.input_p = buffer;
|
||||
ieee->h.total_amt = sizeof (buffer);
|
||||
ieee->h.end_p = buffer + sizeof (buffer);
|
||||
|
||||
if (this_byte_and_next (&(ieee->h)) != Module_Beginning)
|
||||
goto got_wrong_format;
|
||||
|
||||
|
@ -64,6 +64,7 @@ typedef struct ieee_per_section
|
||||
|
||||
typedef struct {
|
||||
unsigned char *input_p;
|
||||
unsigned char *end_p;
|
||||
unsigned char *first_byte;
|
||||
unsigned char *last_byte;
|
||||
bfd_size_type total_amt;
|
||||
|
Loading…
Reference in New Issue
Block a user