summaryrefslogtreecommitdiffstats
path: root/libelf/elf32_getshdr.c
diff options
context:
space:
mode:
Diffstat (limited to 'libelf/elf32_getshdr.c')
-rw-r--r--libelf/elf32_getshdr.c13
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