From: Alan Modra Date: Wed, 7 Aug 2019 14:07:49 +0000 (+0930) Subject: Integer overflows in readelf get_data X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=7c1c1904bedb8f873731651b420a23f573785728;p=binutils-gdb.git Integer overflows in readelf get_data I noticed the test for overflow of amt = size * nmemb in get_data wasn't effective. An obvious example of nmemb = 3 and size = half max value overflows but doesn't result in amt < nmemb. This patch fixes this problem and reports a size truncation or overflow rather than out of memory in more cases. * readelf.c (get_data): Improve overflow checks. --- diff --git a/binutils/ChangeLog b/binutils/ChangeLog index c5d2d8fb835..b60ae64b272 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,7 @@ +2019-08-08 Alan Modra + + * readelf.c (get_data): Improve overflow checks. + 2019-08-07 Nick Clifton PR 24777 diff --git a/binutils/readelf.c b/binutils/readelf.c index 5e18734f10b..3e3e27d19c5 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -385,9 +385,9 @@ get_data (void * var, /* If the size_t type is smaller than the bfd_size_type, eg because you are building a 32-bit tool on a 64-bit host, then make sure that when the sizes are cast to (size_t) no information is lost. */ - if (sizeof (size_t) < sizeof (bfd_size_type) - && ( (bfd_size_type) ((size_t) size) != size - || (bfd_size_type) ((size_t) nmemb) != nmemb)) + if ((size_t) size != size + || (size_t) nmemb != nmemb + || (size_t) amt != amt) { if (reason) error (_("Size truncation prevents reading %s" @@ -397,7 +397,7 @@ get_data (void * var, } /* Check for size overflow. */ - if (amt < nmemb) + if (amt / size != nmemb || (size_t) amt + 1 == 0) { if (reason) error (_("Size overflow prevents reading %s" @@ -429,10 +429,8 @@ get_data (void * var, mvar = var; if (mvar == NULL) { - /* Check for overflow. */ - if (nmemb < (~(bfd_size_type) 0 - 1) / size) - /* + 1 so that we can '\0' terminate invalid string table sections. */ - mvar = malloc ((size_t) amt + 1); + /* + 1 so that we can '\0' terminate invalid string table sections. */ + mvar = malloc ((size_t) amt + 1); if (mvar == NULL) {