diff options
Diffstat (limited to 'libelf/libelf_ehdr.c')
-rw-r--r-- | libelf/libelf_ehdr.c | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/libelf/libelf_ehdr.c b/libelf/libelf_ehdr.c index 38e4e74e14d2..e06c03355038 100644 --- a/libelf/libelf_ehdr.c +++ b/libelf/libelf_ehdr.c @@ -31,7 +31,7 @@ #include "_libelf.h" -ELFTC_VCSID("$Id: libelf_ehdr.c 3632 2018-10-10 21:12:43Z jkoshy $"); +ELFTC_VCSID("$Id: libelf_ehdr.c 3732 2019-04-22 11:08:38Z jkoshy $"); /* * Retrieve counts for sections, phdrs and the section string table index @@ -51,7 +51,12 @@ _libelf_load_extended(Elf *e, int ec, uint64_t shoff, uint16_t phnum, fsz = _libelf_fsize(ELF_T_SHDR, ec, e->e_version, 1); assert(fsz > 0); - if (e->e_rawsize < shoff + fsz) { /* raw file too small */ + if (shoff + fsz < shoff) { /* Numeric overflow. */ + LIBELF_SET_ERROR(HEADER, 0); + return (0); + } + + if ((uint64_t) e->e_rawsize < shoff + fsz) { LIBELF_SET_ERROR(HEADER, 0); return (0); } @@ -138,14 +143,13 @@ _libelf_ehdr(Elf *e, int ec, int allocate) fsz = _libelf_fsize(ELF_T_EHDR, ec, e->e_version, (size_t) 1); assert(fsz > 0); - if (e->e_cmd != ELF_C_WRITE && e->e_rawsize < fsz) { + if (e->e_cmd != ELF_C_WRITE && e->e_rawsize < (off_t) fsz) { LIBELF_SET_ERROR(HEADER, 0); return (NULL); } - msz = _libelf_msize(ELF_T_EHDR, ec, EV_CURRENT); - - assert(msz > 0); + if ((msz = _libelf_msize(ELF_T_EHDR, ec, EV_CURRENT)) == 0) + return (NULL); if ((ehdr = calloc((size_t) 1, msz)) == NULL) { LIBELF_SET_ERROR(RESOURCE, 0); |