From: Petr Machata Date: Wed, 9 Mar 2011 00:10:26 +0000 (+0100) Subject: dwarflint: Check that there's enough data for .debug_line opcode X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c2366ba2f3e0e9b09e5fa3555d81317782597eca;p=thirdparty%2Felfutils.git dwarflint: Check that there's enough data for .debug_line opcode - fixes a SEGV on invalid data. Test case provided --- diff --git a/dwarflint/check_debug_info.cc b/dwarflint/check_debug_info.cc index 31d65ac47..984d60876 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::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 14f91080d..2f32e47ed 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 a38f7ef70..644cff16e 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 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 000000000..9b0401eb1 Binary files /dev/null and b/dwarflint/tests/garbage-5.bz2 differ diff --git a/dwarflint/tests/run-bad.sh b/dwarflint/tests/run-bad.sh index 779ec27d7..2da33b651 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 <