This is the mail archive of the
elfutils-devel@sourceware.org
mailing list for the elfutils project.
[PATCH] libdw: Add missing size check to parse_eh_frame_hdr.
- From: Mark Wielaard <mjw at redhat dot com>
- To: elfutils-devel at lists dot fedorahosted dot org
- Date: Sat, 03 Jan 2015 00:31:09 +0100
- Subject: [PATCH] libdw: Add missing size check to parse_eh_frame_hdr.
afl-fuzz showed that when parse_eh_frame_hdr was called from
getcfi_scn_eh_frame invalid data could be read because of a missing size
check. That check was there when parse_eh_frame_hdr was called from
getcfi_gnu_eh_frame. Move the size check into parse_eh_frame. And add
an extra check to make sure d_buf is not NULL.
Signed-off-by: Mark Wielaard <mjw@redhat.com>
---
libdw/ChangeLog | 6 ++++++
libdw/dwarf_getcfi_elf.c | 12 ++++--------
2 files changed, 10 insertions(+), 8 deletions(-)
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index dd11755..ad5d891 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,5 +1,11 @@
2015-01-02 Mark Wielaard <mjw@redhat.com>
+ * dwarf_getcfi_elf.c (parse_eh_frame_hdr): Add size check.
+ (getcfi_gnu_eh_frame): Remove size check. Check d_buf is not NULL.
+ (getcfi_scn_eh_frame): Check d_buf is not NULL.
+
+2015-01-02 Mark Wielaard <mjw@redhat.com>
+
* dwarf_getlocation.c (__libdw_intern_expression): Check dbg is not
NULL for DW_OP_call_ref and DW_OP_GNU_implicit_pointer. For
DW_OP_addr if dbg is NULL then read argument directly.
diff --git a/libdw/dwarf_getcfi_elf.c b/libdw/dwarf_getcfi_elf.c
index 61ca60d..e58eae6 100644
--- a/libdw/dwarf_getcfi_elf.c
+++ b/libdw/dwarf_getcfi_elf.c
@@ -76,7 +76,7 @@ parse_eh_frame_hdr (const uint8_t *hdr, size_t hdr_size, GElf_Addr hdr_vaddr,
{
const uint8_t *h = hdr;
- if (*h++ != 1) /* version */
+ if (hdr_size < 4 || *h++ != 1) /* version */
return (void *) -1l;
uint8_t eh_frame_ptr_encoding = *h++;
@@ -125,15 +125,11 @@ parse_eh_frame_hdr (const uint8_t *hdr, size_t hdr_size, GElf_Addr hdr_vaddr,
static Dwarf_CFI *
getcfi_gnu_eh_frame (Elf *elf, const GElf_Ehdr *ehdr, const GElf_Phdr *phdr)
{
- if (unlikely (phdr->p_filesz < 4))
- goto invalid;
-
Elf_Data *data = elf_getdata_rawchunk (elf, phdr->p_offset, phdr->p_filesz,
ELF_T_BYTE);
- if (data == NULL)
+ if (data == NULL || data->d_buf == NULL)
{
invalid_hdr:
- invalid:
/* XXX might be read error or corrupt phdr */
__libdw_seterrno (DWARF_E_INVALID_CFI);
return NULL;
@@ -211,7 +207,7 @@ getcfi_scn_eh_frame (Elf *elf, const GElf_Ehdr *ehdr,
Elf_Scn *hdr_scn, GElf_Addr hdr_vaddr)
{
Elf_Data *data = elf_rawdata (scn, NULL);
- if (data == NULL)
+ if (data == NULL || data->d_buf == NULL)
{
__libdw_seterrno (DWARF_E_INVALID_ELF);
return NULL;
@@ -223,7 +219,7 @@ getcfi_scn_eh_frame (Elf *elf, const GElf_Ehdr *ehdr,
if (hdr_scn != NULL)
{
Elf_Data *hdr_data = elf_rawdata (hdr_scn, NULL);
- if (hdr_data != NULL)
+ if (hdr_data != NULL && hdr_data->d_buf != NULL)
{
GElf_Addr eh_frame_vaddr;
cfi->search_table_vaddr = hdr_vaddr;
--
2.1.0