diff options
author | Alan Modra <amodra@gmail.com> | 2019-08-07 23:37:49 +0930 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2019-08-08 00:16:05 +0930 |
commit | 7c1c1904bedb8f873731651b420a23f573785728 (patch) | |
tree | dfd8977ec0d6f14abbc5986fde3bc90ba105a26a /binutils/readelf.c | |
parent | f927cc8faff0d2e39561c90f5182ebe99b2f77f6 (diff) | |
download | gdb-7c1c1904bedb8f873731651b420a23f573785728.zip gdb-7c1c1904bedb8f873731651b420a23f573785728.tar.gz gdb-7c1c1904bedb8f873731651b420a23f573785728.tar.bz2 |
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.
Diffstat (limited to 'binutils/readelf.c')
-rw-r--r-- | binutils/readelf.c | 14 |
1 files changed, 6 insertions, 8 deletions
diff --git a/binutils/readelf.c b/binutils/readelf.c index 5e18734..3e3e27d 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) { |