From: Alan Modra Date: Wed, 20 Feb 2019 07:52:50 +0000 (+1030) Subject: Unsigned integer overflows in readelf checks X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c22b42ce308eb538050b4b5789e406b63102b35a;p=binutils-gdb.git Unsigned integer overflows in readelf checks PR 24132 PR 24138 * readelf.c (get_data): Avoid possibility of overflow when checking for a read that may extend past end of file. (process_program_headers): Likewise. --- diff --git a/binutils/ChangeLog b/binutils/ChangeLog index ce933babfe1..ff67363169f 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,11 @@ +2019-02-20 Alan Modra + + PR 24132 + PR 24138 + * readelf.c (get_data): Avoid possibility of overflow when + checking for a read that may extend past end of file. + (process_program_headers): Likewise. + 2019-02-20 Alan Modra PR 24233 diff --git a/binutils/readelf.c b/binutils/readelf.c index 77acc6a7b42..3f424c4e63d 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -398,10 +398,11 @@ get_data (void * var, return NULL; } - /* Be kind to memory chekers (eg valgrind, address sanitizer) by not + /* Be kind to memory checkers (eg valgrind, address sanitizer) by not attempting to allocate memory when the read is bound to fail. */ - if (amt > filedata->file_size - || offset + archive_file_offset + amt > filedata->file_size) + if (archive_file_offset > filedata->file_size + || offset > filedata->file_size - archive_file_offset + || amt > filedata->file_size - archive_file_offset - offset) { if (reason) error (_("Reading %s bytes extends past end of file for %s\n"), @@ -5235,7 +5236,8 @@ process_program_headers (Filedata * filedata) segment. Check this after matching against the section headers so we don't warn on debuginfo file (which have NOBITS .dynamic sections). */ - if (dynamic_addr + dynamic_size >= filedata->file_size) + if (dynamic_addr > filedata->file_size + || dynamic_size > filedata->file_size - dynamic_addr) { error (_("the dynamic segment offset + size exceeds the size of the file\n")); dynamic_addr = dynamic_size = 0;