diff options
Diffstat (limited to 'libelf/elf32_getshdr.c')
| -rw-r--r-- | libelf/elf32_getshdr.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/libelf/elf32_getshdr.c b/libelf/elf32_getshdr.c index bd9340dd..97fb28d2 100644 --- a/libelf/elf32_getshdr.c +++ b/libelf/elf32_getshdr.c @@ -60,7 +60,8 @@ load_shdr_wrlock (Elf_Scn *scn) goto out; size_t shnum; - if (__elf_getshdrnum_rdlock (elf, &shnum) != 0) + if (__elf_getshdrnum_rdlock (elf, &shnum) != 0 + || shnum > SIZE_MAX / sizeof (ElfW2(LIBELFBITS,Shdr))) goto out; size_t size = shnum * sizeof (ElfW2(LIBELFBITS,Shdr)); @@ -77,6 +78,16 @@ load_shdr_wrlock (Elf_Scn *scn) if (elf->map_address != NULL) { + /* First see whether the information in the ELF header is + valid and it does not ask for too much. */ + if (unlikely (ehdr->e_shoff >= elf->maximum_size) + || unlikely (elf->maximum_size - ehdr->e_shoff < size)) + { + /* Something is wrong. */ + __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER); + goto free_and_out; + } + ElfW2(LIBELFBITS,Shdr) *notcvt; /* All the data is already mapped. If we could use it |
