From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id 3616E3858D1E for ; Sat, 9 Sep 2023 02:57:17 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 3616E3858D1E Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1694228236; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=JupOA+2pyc4S17PBUIJf86y4W3YBQI5PDGQ2diPxjWM=; b=VRhaYj9vfXmFv+iwcWsN2yw6nwJnLcWHNwWauoTjYxVW2a/eDjREP1xrPOLoKmB2Rz2scz 8p3KzzoQasV5wBs7aYbF8rSZBdwzwOPKukVHxeWCXM2W15IATNifL8xKHGB/NW/JW7nc34 lWy7lzr7/ck1GTV0g3E6RoLG/l3byfo= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-628-9xd28KS3MkCO7vXP-eHLhw-1; Fri, 08 Sep 2023 22:57:15 -0400 X-MC-Unique: 9xd28KS3MkCO7vXP-eHLhw-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.rdu2.redhat.com [10.11.54.1]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 1A0FA181D381 for ; Sat, 9 Sep 2023 02:57:15 +0000 (UTC) Received: from f38-1.lan (unknown [10.22.8.74]) by smtp.corp.redhat.com (Postfix) with ESMTP id B60D140C2070; Sat, 9 Sep 2023 02:57:14 +0000 (UTC) From: Kevin Buettner To: gdb-patches@sourceware.org Cc: Kevin Buettner Subject: [PATCH] Throw error when creating an overly large gdb-index file Date: Fri, 8 Sep 2023 19:55:22 -0700 Message-ID: <20230909025521.3128935-2-kevinb@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.1 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset="US-ASCII"; x-default=true X-Spam-Status: No, score=-10.6 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,SPF_NONE,TXREP,WEIRD_PORT autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: The header in a .gdb_index section uses 32-bit unsigned offsets to refer to other areas of the section. Thus, there is a size limit of 2^32-1 which is currently unaccounted for by GDB's code for outputting these sections. At the moment, when GDB creates an overly large section, it will exit abnormally due to an internal error, which is caused by a failed assert in assert_file_size, which in turn is called from write_gdbindex_1, both of which are in gdb/dwarf2/index-write.c. This is what happens when that assert fails: $ gdb -q -nx -iex 'set auto-load no' -iex 'set debuginfod enabled off' -ex file ./libgraph_tool_inference.so -ex "save gdb-index `pwd`/" Reading symbols from ./libgraph_tool_inference.so... No executable file now. Discard symbol table from `libgraph_tool_inference.so'? (y or n) n Not confirmed. ../../gdb/dwarf2/index-write.c:1069: internal-error: assert_file_size: Assertion `file_size == expected_size' failed. A problem internal to GDB has been detected, further debugging may prove unreliable. ----- Backtrace ----- 0x55fddb4d78b0 gdb_internal_backtrace_1 ../../gdb/bt-utils.c:122 0x55fddb4d78b0 _Z22gdb_internal_backtracev ../../gdb/bt-utils.c:168 0x55fddb98b5d4 internal_vproblem ../../gdb/utils.c:396 0x55fddb98b8de _Z15internal_verrorPKciS0_P13__va_list_tag ../../gdb/utils.c:476 0x55fddbb71654 _Z18internal_error_locPKciS0_z ../../gdbsupport/errors.cc:58 0x55fddb5a0f23 assert_file_size ../../gdb/dwarf2/index-write.c:1069 0x55fddb5a1ee0 assert_file_size /usr/include/c++/13/bits/stl_iterator.h:1158 0x55fddb5a1ee0 write_gdbindex_1 ../../gdb/dwarf2/index-write.c:1119 0x55fddb5a51be write_gdbindex ../../gdb/dwarf2/index-write.c:1273 [...] --------------------- ../../gdb/dwarf2/index-write.c:1069: internal-error: assert_file_size: Assertion `file_size == expected_size' failed. This problem was encountered while building the python-graph-tool package on Fedora. The Fedora bugzilla bug can be found here: https://bugzilla.redhat.com/show_bug.cgi?id=1773651 This commit prevents the internal error from occurring by calling error() when the file size exceeds 2^32-1. Using a gdb built with this commit, I now see this behavior instead: $ gdb -q -nx -iex 'set auto-load no' -iex 'set debuginfod enabled off' -ex file ./libgraph_tool_inference.so -ex "save gdb-index `pwd`/" Reading symbols from ./libgraph_tool_inference.so... No executable file now. Discard symbol table from `/mesquite2/fedora-bugs/1773651/libgraph_tool_inference.so'? (y or n) n Not confirmed. Error while writing index for `/mesquite2/fedora-bugs/1773651/libgraph_tool_inference.so': gdb-index maximum file size of 4294967295 exceeded (gdb) I wish I could provide a test case, but due to the sizes of both the input and output files, I think that testing resources would be strained or exceeded in many environments. My testing on Fedora 38 shows no regressions. --- gdb/dwarf2/index-write.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/gdb/dwarf2/index-write.c b/gdb/dwarf2/index-write.c index 11f254e263a..6e9bf148d49 100644 --- a/gdb/dwarf2/index-write.c +++ b/gdb/dwarf2/index-write.c @@ -1083,7 +1083,7 @@ write_gdbindex_1 (FILE *out_file, { data_buf contents; const offset_type size_of_header = 6 * sizeof (offset_type); - offset_type total_len = size_of_header; + size_t total_len = size_of_header; /* The version number. */ contents.append_offset (8); @@ -1110,6 +1110,13 @@ write_gdbindex_1 (FILE *out_file, gdb_assert (contents.size () == size_of_header); + /* The maximum size of an index file is limited by the maximum value + capable of being represented by 'offset_type'. Throw an error if + that length has been exceeded. */ + size_t max_size = ~(offset_type) 0; + if (total_len > max_size) + error ("gdb-index maximum file size of %zu exceeded", max_size); + contents.file_write (out_file); cu_list.file_write (out_file); types_cu_list.file_write (out_file); -- 2.41.0