This is the mail archive of the elfutils-devel@sourceware.org mailing list for the elfutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]