Fix an off-by-one error in the IN_RANGE macro used by readelf. Add another use of...
authorChristian Eggers <ceggers@gmx.de>
Wed, 6 Nov 2019 12:29:23 +0000 (12:29 +0000)
committerNick Clifton <nickc@redhat.com>
Wed, 6 Nov 2019 12:29:23 +0000 (12:29 +0000)
* readelf.c (IN_RANGE): Rename parameter OFF to NELEM. Add
comment.  Catch potential integer overflow and fix off by one
error whilst checking reloc location against section size.
(apply_relocations): Use IN_RANGE macro.

binutils/ChangeLog
binutils/readelf.c

index 0f5d06b5a699f4458e9f8a5351e4432fb8fc0d4e..61a2e0020ccf56e4e9b0fd32109b7e1dc32e2d2b 100644 (file)
@@ -1,3 +1,10 @@
+2019-11-06  Christian Eggers  <ceggers@gmx.de>
+
+       * readelf.c (IN_RANGE): Rename parameter OFF to NELEM. Add
+       comment.  Catch potential integer overflow and fix off by one
+       error whilst checking reloc location against section size.
+       (apply_relocations): Use IN_RANGE macro.
+
 2019-11-04  Fangrui Song  <maskray@google.com>
 
        * objcopy.c (enum option_values): Add OPTION_KEEP_SECTION.
index 370bc4c1b7d9483b6ce9335171ae19a6feb29f8e..fab8214664c60826bc39a270d35b5d46182c6c12 100644 (file)
@@ -12309,8 +12309,12 @@ process_syminfo (Filedata * filedata ATTRIBUTE_UNUSED)
   return TRUE;
 }
 
-#define IN_RANGE(START,END,ADDR,OFF)           \
-  (((ADDR) >= (START)) && ((ADDR) + (OFF) < (END)))
+/* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
+   is contained by the region START .. END.  The types of ADDR, START
+   and END should all be the same.  Note both ADDR + NELEM and END
+   point to just beyond the end of the regions that are being tested.  */
+#define IN_RANGE(START,END,ADDR,NELEM)         \
+  (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
 
 /* Check to see if the given reloc needs to be handled in a target specific
    manner.  If so then process the reloc and return TRUE otherwise return
@@ -13411,7 +13415,7 @@ apply_relocations (Filedata *                 filedata,
            }
 
          rloc = start + rp->r_offset;
-         if (rloc >= end || (rloc + reloc_size) > end || (rloc < start))
+         if (!IN_RANGE (start, end, rloc, reloc_size))
            {
              warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
                    (unsigned long) rp->r_offset,