gelf_fsize, elf32_fsize and elf64_fsize return count * sizeof type as
size_t, or zero to indicate an error. Check count is zero or count
times size would overflow and fail with libelf errno set to
ELF_E_INVALID_OPERAND in that case.
* libelf/elf32_fsize.c (elf32_fsize): Check whether count is
zero or count times size would overflow.
* libelf/gelf_fsize.c (gelf_fsize): Likewise.
Signed-off-by: Mark Wielaard <[email protected]>
---
libelf/elf32_fsize.c | 10 +++++++++-
libelf/gelf_fsize.c | 10 +++++++++-
2 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/libelf/elf32_fsize.c b/libelf/elf32_fsize.c
index 139f4a91ce78..d48fde3df320 100644
--- a/libelf/elf32_fsize.c
+++ b/libelf/elf32_fsize.c
@@ -56,5 +56,13 @@ elfw2(LIBELFBITS, fsize) (Elf_Type type, size_t count,
unsigned int version)
return 0;
}
- return (count * __libelf_type_sizes[ELFW(ELFCLASS,LIBELFBITS) - 1][type]);
+ size_t size = __libelf_type_sizes[ELFW(ELFCLASS,LIBELFBITS) - 1][type];
+
+ if (unlikely (count == 0 || count > SIZE_MAX / size))
+ {
+ __libelf_seterrno (ELF_E_INVALID_OPERAND);
+ return 0;
+ }
+
+ return count * size;
}
diff --git a/libelf/gelf_fsize.c b/libelf/gelf_fsize.c
index 371f08f2cc2c..ba4a8e880f74 100644
--- a/libelf/gelf_fsize.c
+++ b/libelf/gelf_fsize.c
@@ -107,7 +107,15 @@ gelf_fsize (Elf *elf, Elf_Type type, size_t count,
unsigned int version)
return 0;
}
- return count * __libelf_type_sizes[elf->class - 1][type];
+ size_t size = __libelf_type_sizes[elf->class - 1][type];
+
+ if (count == 0 || count > SIZE_MAX / size)
+ {
+ __libelf_seterrno (ELF_E_INVALID_OPERAND);
+ return 0;
+ }
+
+ return count * size;
}
INTDEF(gelf_fsize)
--
2.56.0