aboutsummaryrefslogtreecommitdiff
path: root/binutils/readelf.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2019-08-07 23:37:49 +0930
committerAlan Modra <amodra@gmail.com>2019-08-08 00:16:05 +0930
commit7c1c1904bedb8f873731651b420a23f573785728 (patch)
treedfd8977ec0d6f14abbc5986fde3bc90ba105a26a /binutils/readelf.c
parentf927cc8faff0d2e39561c90f5182ebe99b2f77f6 (diff)
downloadgdb-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.c14
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)
{