summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPetr Machata <pmachata@redhat.com>2011-03-09 01:10:26 +0100
committerPetr Machata <pmachata@redhat.com>2011-03-09 01:10:26 +0100
commitc2366ba2f3e0e9b09e5fa3555d81317782597eca (patch)
treeb2d1b81b205f39390237670bee57a70e49859837
parentf338f9ba56ce3f53138e1ab477c2ede44810d3fa (diff)
downloadelfutils-c2366ba2f3e0e9b09e5fa3555d81317782597eca.tar.gz
dwarflint: Check that there's enough data for .debug_line opcode
- fixes a SEGV on invalid data. Test case provided
-rw-r--r--dwarflint/check_debug_info.cc5
-rw-r--r--dwarflint/check_debug_line.cc16
-rw-r--r--dwarflint/check_debug_line.hh8
-rw-r--r--dwarflint/tests/garbage-5.bz2bin0 -> 2780 bytes
-rwxr-xr-xdwarflint/tests/run-bad.sh8
5 files changed, 29 insertions, 8 deletions
diff --git a/dwarflint/check_debug_info.cc b/dwarflint/check_debug_info.cc
index 31d65ac4..984d6087 100644
--- a/dwarflint/check_debug_info.cc
+++ b/dwarflint/check_debug_info.cc
@@ -1196,6 +1196,11 @@ check_debug_info_refs::check_debug_info_refs (checkstack &stack,
, _m_line (lint.toplev_check (stack, _m_line))
, _m_aranges (lint.toplev_check (stack, _m_aranges))
{
+ // XXX if .debug_line is present and broken, we don't want to report
+ // every unsatisfied reference. If .debug_line is absent and
+ // references are present, we want to diagnose that in one line. If
+ // .debug_line is present and valid, then we want to check each
+ // reference separately.
for (std::vector<cu>::iterator it = _m_info->cus.begin ();
it != _m_info->cus.end (); ++it)
{
diff --git a/dwarflint/check_debug_line.cc b/dwarflint/check_debug_line.cc
index 14f91080..2f32e47e 100644
--- a/dwarflint/check_debug_line.cc
+++ b/dwarflint/check_debug_line.cc
@@ -1,5 +1,5 @@
/* Low-level checking of .debug_line.
- Copyright (C) 2009, 2010 Red Hat, Inc.
+ Copyright (C) 2009, 2010, 2011 Red Hat, Inc.
This file is part of Red Hat elfutils.
Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -399,6 +399,14 @@ check_debug_line::check_debug_line (checkstack &stack, dwarflint &lint)
if (!checked_read_uleb128 (&sub_ctx, &skip_len, &where,
"length of extended opcode"))
goto skip;
+ if (!read_ctx_need_data (&sub_ctx, skip_len))
+ {
+ wr_error (where)
+ << "not enough data to read an opcode of length "
+ << skip_len << '.' << std::endl;
+ goto skip;
+ }
+
const unsigned char *next = sub_ctx.ptr + skip_len;
if (!read_ctx_read_ubyte (&sub_ctx, &extended))
{
@@ -628,3 +636,9 @@ check_debug_line::check_debug_line (checkstack &stack, dwarflint &lint)
else
throw check_base::failed ();
}
+
+bool
+check_debug_line::has_line_table (Dwarf_Off off) const
+{
+ return _m_line_tables.find (off) != _m_line_tables.end ();
+}
diff --git a/dwarflint/check_debug_line.hh b/dwarflint/check_debug_line.hh
index a38f7ef7..644cff16 100644
--- a/dwarflint/check_debug_line.hh
+++ b/dwarflint/check_debug_line.hh
@@ -1,5 +1,5 @@
/* Low-level checking of .debug_line
- Copyright (C) 2010 Red Hat, Inc.
+ Copyright (C) 2010, 2011 Red Hat, Inc.
This file is part of Red Hat elfutils.
Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -46,11 +46,7 @@ public:
std::set<Dwarf_Off> const &line_tables () const { return _m_line_tables; }
- bool
- has_line_table (Dwarf_Off off) const
- {
- return _m_line_tables.find (off) != _m_line_tables.end ();
- }
+ bool has_line_table (Dwarf_Off off) const;
};
#endif//DWARFLINT_CHECK_DEBUG_LINE_HH
diff --git a/dwarflint/tests/garbage-5.bz2 b/dwarflint/tests/garbage-5.bz2
new file mode 100644
index 00000000..9b0401eb
--- /dev/null
+++ b/dwarflint/tests/garbage-5.bz2
Binary files differ
diff --git a/dwarflint/tests/run-bad.sh b/dwarflint/tests/run-bad.sh
index 779ec27d..2da33b65 100755
--- a/dwarflint/tests/run-bad.sh
+++ b/dwarflint/tests/run-bad.sh
@@ -27,7 +27,8 @@
srcdir=$srcdir/tests
-testfiles hello.bad-1 hello.bad-3 garbage-1 garbage-2 garbage-3 garbage-4
+testfiles hello.bad-1 hello.bad-3 garbage-1 garbage-2 garbage-3 garbage-4 \
+ garbage-5
testrun_compare ./dwarflint hello.bad-1 <<EOF
error: .debug_info: DIE 0x83: abbrev section at 0x0 doesn't contain code 83.
@@ -58,3 +59,8 @@ EOF
testrun_compare ./dwarflint garbage-4 <<EOF
error: .debug_info: DIE 0x6c: this DIE claims that its sibling is 0x80000085 but it's actually 0x85.
EOF
+
+testrun_compare ./dwarflint garbage-5 <<EOF
+error: .debug_line: offset 0x3e: not enough data to read an opcode of length 5.
+error: .debug_info: DIE 0xb (abbr. attribute 0xc): unresolved reference to .debug_line table 0x0.
+EOF