From patchwork Fri Mar 21 16:48:13 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Keith Seitz X-Patchwork-Id: 208 Return-Path: X-Original-To: siddhesh@wilcox.dreamhost.com Delivered-To: siddhesh@wilcox.dreamhost.com Received: from homiemail-mx22.g.dreamhost.com (caibbdcaabij.dreamhost.com [208.113.200.189]) by wilcox.dreamhost.com (Postfix) with ESMTP id 7F6BB3600E7 for ; Fri, 21 Mar 2014 09:48:23 -0700 (PDT) Received: by homiemail-mx22.g.dreamhost.com (Postfix, from userid 14314964) id 2DE205000240; Fri, 21 Mar 2014 09:48:23 -0700 (PDT) X-Original-To: gdb@patchwork.siddhesh.in Delivered-To: x14314964@homiemail-mx22.g.dreamhost.com Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by homiemail-mx22.g.dreamhost.com (Postfix) with ESMTPS id 0F78B5000261 for ; Fri, 21 Mar 2014 09:48:23 -0700 (PDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:message-id:date:from:mime-version:to:subject :content-type; q=dns; s=default; b=bvYaw4EofeJcmdPjC2ZDzxQOCVtf0 O4Uyb05sxTRQAvny2OWWrwzEWCdI3Vl0Oy0zgNkfz2d/wy0AspJnN2wnG18OugFD 6z8A7Paha2Su26Mm3tYp7QW8B9a8ZnGd6QMxORKD0EA4bGaKbOyA7VMBVkyabpjZ 9G59SijwGCaWvY= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:message-id:date:from:mime-version:to:subject :content-type; s=default; bh=bZYBvjeZoGk3N5R+Utg4z6U4E4k=; b=O3D 4lmN0rzveCjf9bx/nIJ70MIhIJO9mF23R4JL30qGHWhs9OKrqybdOvWnjfBo3+AY mXqM4xQn5XdW8knDxkUAbahNXQ+5kJhiRJZx9QPTJ9Q+AqRvExifKAUTGpKm1eWJ pjgXERGF/cU6KjB54pKpk9FM2d6cl/JdqvE0BVNY= Received: (qmail 19840 invoked by alias); 21 Mar 2014 16:48:18 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 19761 invoked by uid 89); 21 Mar 2014 16:48:18 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.8 required=5.0 tests=AWL, BAYES_00, SPF_HELO_PASS, SPF_PASS, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 21 Mar 2014 16:48:16 +0000 Received: from int-mx12.intmail.prod.int.phx2.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.25]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s2LGmFgg021461 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Fri, 21 Mar 2014 12:48:15 -0400 Received: from valrhona.uglyboxes.com (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx12.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s2LGmD0q030016 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO) for ; Fri, 21 Mar 2014 12:48:14 -0400 Message-ID: <532C6D4D.2050705@redhat.com> Date: Fri, 21 Mar 2014 09:48:13 -0700 From: Keith Seitz User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.3.0 MIME-Version: 1.0 To: "gdb-patches@sourceware.org ml" Subject: [RFA] Fix gdb/15827 (crash w/corrupt DWARF) X-IsSubscribed: yes X-DH-Original-To: gdb@patchwork.siddhesh.in Hi, I think most of us know that the dwarf2read.c pretty much assumes that the DWARF input is okay. The reporter of this bug used a binary fuzzer to corrupt the DWARF info: <1><569>: Abbrev Number: 16 (DW_TAG_enumeration_type) <56a> DW_AT_byte_size : 4 <56b> DW_AT_decl_file : 17 <56c> DW_AT_decl_line : 73 <56d> DW_AT_sibling : <0xb12> <2><571>: Abbrev Number: 17 (DW_TAG_enumerator) <572> DW_AT_name : (indirect string, offset: 0xf14): _SC_ARG_MAX <576> DW_AT_const_value : 0 [snip] <2>: Abbrev Number: 17 (DW_TAG_enumerator) DW_AT_name : (indirect string, offset: 0x9b7): _SC_LEVEL3_CACHE_ASSOC DW_AT_const_value : 2243 <2>: Abbrev Number: 12 (DW_TAG_array_type) DW_AT_type : <0x114> DW_AT_sibling : <0x761101c4> <3>: Abbrev Number: 10 (DW_TAG_member) DW_AT_name : (indirect string, offset: 0x1c50000): DW_AT_decl_file : 17 DW_AT_decl_line : 2539 DW_AT_type : <0x1c60000> DW_AT_data_member_location: 17 As you can see, the sibling for DIE 0xa93 points of to la-la land. This causes skip_one_die to crash, since it never validates whether the offset of the sibling is contained within the current readers's input buffer. This function does check, however, whether the offset is negative. This patch essentially adds the counterpoint check and a beginning at some tests for catch-all "corrupt" DWARF. Keith ChangeLog 2014-03-20 Keith Seitz PR gdb/15827 * dwarf2read.c (skip_one_die): Check that all relative-offset sibling DIEs fall within range of the current reader's buffer. (read_partial_die): Likewise. testsuite/ChangeLog 2014-03-20 Keith Seitz PR gdb/15827 * gdb.dwarf2/corrupt.c: New file. * gdb.dwarf2/corrupt.exp: New file. diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 705dc2d..c30b1b3 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -7103,6 +7103,8 @@ skip_one_die (const struct die_reader_specs *reader, const gdb_byte *info_ptr, if (sibling_ptr < info_ptr) complaint (&symfile_complaints, _("DW_AT_sibling points backwards")); + else if (sibling_ptr > reader->buffer_end) + dwarf2_section_buffer_overflow_complaint (reader->die_section); else return sibling_ptr; } @@ -15416,6 +15418,8 @@ read_partial_die (const struct die_reader_specs *reader, if (sibling_ptr < info_ptr) complaint (&symfile_complaints, _("DW_AT_sibling points backwards")); + else if (sibling_ptr > reader->buffer_end) + dwarf2_section_buffer_overflow_complaint (reader->die_section); else part_die->sibling = sibling_ptr; } diff --git a/gdb/testsuite/gdb.dwarf2/corrupt.c b/gdb/testsuite/gdb.dwarf2/corrupt.c new file mode 100644 index 0000000..4120f3d --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/corrupt.c @@ -0,0 +1,24 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2014 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* Dummy main function. */ + +int +main() +{ + return 0; +} diff --git a/gdb/testsuite/gdb.dwarf2/corrupt.exp b/gdb/testsuite/gdb.dwarf2/corrupt.exp new file mode 100644 index 0000000..ba5e551 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/corrupt.exp @@ -0,0 +1,78 @@ +# Copyright 2014 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Test corrupt DWARF input +# PR gdb/15827 + +load_lib dwarf.exp + +if {![dwarf2_support]} { + return 0 +} + +standard_testfile corrupt.c corrupt.S + +# Make the DWARF used for the test. +# +# Here we put DW_AT_sibling DIEs into the output which +# point off into la-la land. The whole purpose is to simulate +# corrupt DWARF information and make sure that GDB can handle it +# without crashing. + +set asm_file [standard_output_file $srcfile2] +Dwarf::assemble $asm_file { + cu {} { + compile_unit {} { + declare_labels int_label + + int_label: base_type { + {byte_size 4} + {name "int"} + } + + enumeration_type { + {name "ENUM"} + {byte_size 4} + } { + enumerator { + {name "A"} + {const_value 0} + } + enumerator { + {name "B"} + {const_value 1} + {sibling 12345678 DW_FORM_ref4} + } { + base_type { + {byte_size 1} + {name "char"} + } + } + array_type { + {type :$int_label} + {sibling 12345678 DW_FORM_ref4} + } + } + } + } +} + +if {[prepare_for_testing $testfile.exp $testfile \ + [list $srcfile $asm_file] {nodebug}]} { + return -1 +} + +# If we get here and gdb hasn't crashed, the tests pass. +pass "corrupt DWARF"