The sanity check in get_shnum multiplies the size of the Shdr with the
number of sections to check if they all fit into maxsize (minux
e_shoff). But that multiplication can overflow (on 32 bit). Rewrite to
use division of maxsize - e_shoff by Shdr size to check against the
result.

        * libelf/elf_begin.c (get_shnum): Check truncation with
        division instead of multiplication.

Signed-off-by: Mark Wielaard <[email protected]>
---
 libelf/elf_begin.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libelf/elf_begin.c b/libelf/elf_begin.c
index 4fddd1ca1383..5a79dd8d275b 100644
--- a/libelf/elf_begin.c
+++ b/libelf/elf_begin.c
@@ -199,7 +199,7 @@ get_shnum (void *map_address, unsigned char *e_ident, int 
fildes,
 
       /* If the section headers were truncated, pretend none were there.  */
       if (ehdr.e32->e_shoff > maxsize
-         || maxsize - ehdr.e32->e_shoff < sizeof (Elf32_Shdr) * result)
+         || result > (maxsize - ehdr.e32->e_shoff) / sizeof (Elf32_Shdr))
        result = 0;
     }
   else
@@ -268,7 +268,7 @@ get_shnum (void *map_address, unsigned char *e_ident, int 
fildes,
 
       /* If the section headers were truncated, pretend none were there.  */
       if (ehdr.e64->e_shoff > maxsize
-         || maxsize - ehdr.e64->e_shoff < sizeof (Elf64_Shdr) * result)
+         || result > (maxsize - ehdr.e64->e_shoff) / sizeof (Elf64_Shdr))
        result = 0;
     }
 
-- 
2.56.0

Reply via email to