We need to check the cuoff points to a real Dwarf_Die before trying to
intern the cu with tsearch. Otherwise bogus keys might end up in the
search tree with NULL cus. That will cause crashes in compare_cukey
during next insertion or deletion of cus.
https://bugzilla.redhat.com/show_bug.cgi?id=1170810#c30
Signed-off-by: Mark Wielaard <mjw(a)redhat.com>
---
libdwfl/ChangeLog | 5 +++++
libdwfl/cu.c | 15 ++++++---------
2 files changed, 11 insertions(+), 9 deletions(-)
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index 6945eec..bce113e 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,5 +1,10 @@
2015-05-05 Mark Wielaard <mjw(a)redhat.com>
+ * cu.c (intern_cu): Check cuoff points to a real Dwarf_Die before
+ interning.
+
+2015-05-05 Mark Wielaard <mjw(a)redhat.com>
+
* dwfl_lineinfo.c (dwfl_lineinfo): Check info->file is valid.
2015-04-21 Mark Wielaard <mjw(a)redhat.com>
diff --git a/libdwfl/cu.c b/libdwfl/cu.c
index 3ac341e..dbbed85 100644
--- a/libdwfl/cu.c
+++ b/libdwfl/cu.c
@@ -171,6 +171,11 @@ compare_cukey (const void *a, const void *b)
static Dwfl_Error
intern_cu (Dwfl_Module *mod, Dwarf_Off cuoff, struct dwfl_cu **result)
{
+ Dwarf_Die cudie;
+ Dwarf_Die *die = INTUSE(dwarf_offdie) (mod->dw, cuoff, &cudie);
+ if (die == NULL)
+ return DWFL_E_LIBDW;
+
struct Dwarf_CU dwkey;
struct dwfl_cu key;
key.die.cu = &dwkey;
@@ -203,15 +208,7 @@ intern_cu (Dwfl_Module *mod, Dwarf_Off cuoff, struct dwfl_cu
**result)
cu->mod = mod;
cu->next = NULL;
cu->lines = NULL;
-
- /* XXX use non-searching lookup */
- Dwarf_Die *die = INTUSE(dwarf_offdie) (mod->dw, cuoff, &cu->die);
- if (die == NULL)
- {
- free (cu);
- return DWFL_E_LIBDW;
- }
- assert (die == &cu->die);
+ cu->die = cudie;
struct dwfl_cu **newvec = realloc (mod->cu, ((mod->ncu + 1)
* sizeof (mod->cu[0])));
--
2.1.0