]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
Guard against 64bit unsigned wrap around in (int) compare functions.
authorMark Wielaard <mjw@redhat.com>
Sat, 13 Dec 2014 23:09:29 +0000 (00:09 +0100)
committerMark Wielaard <mjw@redhat.com>
Tue, 16 Dec 2014 09:55:45 +0000 (10:55 +0100)
Dwarf_Adrr and Dwarf_Off are 64-bit unsigned, and comparison functions
used in qsort or tfind return int, it is possible for the difference to
be so large that it wraps around. Make sure to just return -1, 0 or 1
in compare_aranges and compare_cukey.

Signed-off-by: Mark Wielaard <mjw@redhat.com>
libdw/ChangeLog
libdw/dwarf_getaranges.c
libdwfl/ChangeLog
libdwfl/cu.c

index 5bf1ebc03e333c80ebf7475ca66825b0d2e96883..fb7b4e9407f257774a00f8aea0f2fb76437c0410 100644 (file)
@@ -1,3 +1,8 @@
+2014-12-13  Mark Wielaard  <mjw@redhat.com>
+
+       * dwarf_getaranges.c (compare_aranges): Make sure Dwarf_Addr
+       difference doesn't wrap around before returning as int.
+
 2014-12-11  Josh Stone  <jistone@redhat.com>
 
        * dwarf_getsrclines.c (struct linelist): Add sequence.
index 20ac7ec6781cdd9e09f4481e666c5f7760383fd8..4953af53cb25767fee50324fac2c19f6d08e06de 100644 (file)
@@ -48,7 +48,9 @@ compare_aranges (const void *a, const void *b)
 {
   struct arangelist *const *p1 = a, *const *p2 = b;
   struct arangelist *l1 = *p1, *l2 = *p2;
-  return l1->arange.addr - l2->arange.addr;
+  if (l1->arange.addr != l2->arange.addr)
+    return (l1->arange.addr < l2->arange.addr) ? -1 : 1;
+  return 0;
 }
 
 int
index b83cb121ccaed4edc58ab643714a112ff5a3de93..c49558fca8c95b2236e25d607ee33fefb0e538e7 100644 (file)
@@ -1,3 +1,8 @@
+2014-12-13  Mark Wielaard  <mjw@redhat.com>
+
+       * cu.c (cudie_offset): Make sure Dwarf_Off difference doesn't
+       wrap around before returning as int.
+
 2014-12-11  Josh Stone  <jistone@redhat.com>
 
        * dwfl_module_getsrc.c (dwfl_module_getsrc): Return the *last* line
index 40b0201cd5a52ea83c0cc4890fb2bd6aaf034e4f..5ce531bd9dd30f708ebe23ee16c5333c31f52223 100644 (file)
@@ -162,7 +162,9 @@ cudie_offset (const struct dwfl_cu *cu)
 static int
 compare_cukey (const void *a, const void *b)
 {
-  return cudie_offset (a) - cudie_offset (b);
+  Dwarf_Off a_off = cudie_offset (a);
+  Dwarf_Off b_off = cudie_offset (b);
+  return (a_off < b_off) ? -1 : ((a_off > b_off) ? 1 : 0);
 }
 
 /* Intern the CU if necessary.  */