]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
dwarflint: Check that there's enough data for .debug_line opcode
authorPetr Machata <pmachata@redhat.com>
Wed, 9 Mar 2011 00:10:26 +0000 (01:10 +0100)
committerPetr Machata <pmachata@redhat.com>
Wed, 9 Mar 2011 00:10:26 +0000 (01:10 +0100)
- fixes a SEGV on invalid data.  Test case provided

dwarflint/check_debug_info.cc
dwarflint/check_debug_line.cc
dwarflint/check_debug_line.hh
dwarflint/tests/garbage-5.bz2 [new file with mode: 0644]
dwarflint/tests/run-bad.sh

index 31d65ac470a76aaa588411d8b7acef1dbc42111a..984d608767fbca5d57c0508b0c99bd3f59ddf99b 100644 (file)
@@ -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)
     {
index 14f91080d67a4d50e01449bd4dda13f54905757d..2f32e47ed0dfa3422b60f8cf17eaa15711d28542 100644 (file)
@@ -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 ();
+}
index a38f7ef70f49bdc4da7c8e26c4883681ea983965..644cff16e0b1d1cbb96b24c03b246b366631d89e 100644 (file)
@@ -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 (file)
index 0000000..9b0401e
Binary files /dev/null and b/dwarflint/tests/garbage-5.bz2 differ
index 779ec27d7a9b0349a433d8a0b6215b5f4951c53c..2da33b651181d00d2e75f1f4e469a9c34d52b649 100755 (executable)
@@ -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