[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH] libelf: Fix div0 issues in elf_{shdr, phdr}_count()



elf_uval() can return zero either because the field itself is zero, or because
the access is out of bounds.

c/s a01b6d4 "libelf: treat phdr and shdr similarly" introduced two div0 issues
as e_{ph,sh}entsize are not checked for sanity before being used to divide
elf->size.

Spotted by Coverity.

Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
CC: George Dunlap <George.Dunlap@xxxxxxxxxxxxx>
CC: Ian Jackson <ian.jackson@xxxxxxxxxxxxx>
CC: Jan Beulich <JBeulich@xxxxxxxx>
CC: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx>
CC: Stefano Stabellini <sstabellini@xxxxxxxxxx>
CC: Tim Deegan <tim@xxxxxxx>
CC: Wei Liu <wei.liu2@xxxxxxxxxx>

I experimented with making elf_access_unsigned() __must_check, but this didn't
cause a compiler error.  I am not quite sure why.
---
 xen/common/libelf/libelf-tools.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/xen/common/libelf/libelf-tools.c b/xen/common/libelf/libelf-tools.c
index bf661e7..f62d9c3 100644
--- a/xen/common/libelf/libelf-tools.c
+++ b/xen/common/libelf/libelf-tools.c
@@ -130,11 +130,17 @@ uint64_t elf_round_up(struct elf_binary *elf, uint64_t 
addr)
 unsigned elf_shdr_count(struct elf_binary *elf)
 {
     unsigned count = elf_uval(elf, elf->ehdr, e_shnum);
+    unsigned entsize = elf_uval(elf, elf->ehdr, e_shentsize);
     uint64_t max;
 
     if ( !count )
         return 0;
-    max = elf->size / elf_uval(elf, elf->ehdr, e_shentsize);
+    if ( !entsize )
+    {
+        elf_mark_broken(elf, "e_shentsize is zero");
+        return 0;
+    }
+    max = elf->size / entsize;
     if ( max > UINT_MAX )
         max = UINT_MAX;
     if ( count > max )
@@ -148,11 +154,17 @@ unsigned elf_shdr_count(struct elf_binary *elf)
 unsigned elf_phdr_count(struct elf_binary *elf)
 {
     unsigned count = elf_uval(elf, elf->ehdr, e_phnum);
+    unsigned entsize = elf_uval(elf, elf->ehdr, e_phentsize);
     uint64_t max;
 
     if ( !count )
         return 0;
-    max = elf->size / elf_uval(elf, elf->ehdr, e_phentsize);
+    if ( !entsize )
+    {
+        elf_mark_broken(elf, "e_phentsize is zero");
+        return 0;
+    }
+    max = elf->size / entsize;
     if ( max > UINT_MAX )
         max = UINT_MAX;
     if ( count > max )
-- 
2.1.4


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.