From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.223.130]) by sourceware.org (Postfix) with ESMTPS id 229F03858D1E for ; Sat, 6 Apr 2024 08:29:35 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 229F03858D1E Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=suse.de Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=suse.de ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 229F03858D1E Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=195.135.223.130 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1712392190; cv=none; b=ArnyRpz/Y9z01yhoe+FLMrA1gFRWUYnnaKJ63edAKDxxL75D82uQObPhpRqHKip/nJzGu5yr8OSosXG2FATt4YSdXrvxpJ8y8uRuj5+XlE+DJ2ufQloHjCIHCneCM9f68qweZyDdYBlnhI5nuSH+YS7fFpELbADYJSJq3wqF390= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1712392190; c=relaxed/simple; bh=sIWpkLRPGhXVFBhhu+NxqyV6Vz1lZH7b63cfDlWNioQ=; h=DKIM-Signature:DKIM-Signature:DKIM-Signature:DKIM-Signature: Message-ID:Date:MIME-Version:Subject:To:From; b=evq+AqP5XgO7efk5Uaeg9vBjSmnjBqiVXRl9k1iqLG3s1AkqA9qcMBlR0UjOt0HRVGffPPeZEyIQDw8Lwhf88Y+QEwcMnHphD+IIYtEqYFBhV0QJ1/Arx9NEMrB3TQL5FfL/Q4HiOPiiAFtfstab0UDjn29zW7hl6NKMXqyDe8Y= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from imap2.dmz-prg2.suse.org (imap2.dmz-prg2.suse.org [10.150.64.98]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id C546021AFE; Sat, 6 Apr 2024 08:29:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1712392173; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc: mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=em1+XnHHHBP3pAJdGLPtQMBUhfQIGFUDDWHFDqCBL9o=; b=pDPEaarcSgq3xrq0KlmTiNJFoa7om1ci9irNhxAaKzsBtxA3FIGptnXybQFBrD7FiFiied k8x8/zQYjxbSq+ft1yv6EMs7Psrr9O+9CdX9BHc7f883qRNPyyjDbUTPe484vsqL9koc69 8NRexzIWCL80yE78w2uKJkqw7UFI42o= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1712392173; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc: mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=em1+XnHHHBP3pAJdGLPtQMBUhfQIGFUDDWHFDqCBL9o=; b=k/BI3HmVsm6DD+fjXiUI2nEM+dvQOusCsUxEgrxQTBx38FKBY6xN9ZSIqnzsyPtryZoi7B I9s5DyMeQwr7zpAw== Authentication-Results: smtp-out1.suse.de; none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1712392173; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc: mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=em1+XnHHHBP3pAJdGLPtQMBUhfQIGFUDDWHFDqCBL9o=; b=pDPEaarcSgq3xrq0KlmTiNJFoa7om1ci9irNhxAaKzsBtxA3FIGptnXybQFBrD7FiFiied k8x8/zQYjxbSq+ft1yv6EMs7Psrr9O+9CdX9BHc7f883qRNPyyjDbUTPe484vsqL9koc69 8NRexzIWCL80yE78w2uKJkqw7UFI42o= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1712392173; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc: mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=em1+XnHHHBP3pAJdGLPtQMBUhfQIGFUDDWHFDqCBL9o=; b=k/BI3HmVsm6DD+fjXiUI2nEM+dvQOusCsUxEgrxQTBx38FKBY6xN9ZSIqnzsyPtryZoi7B I9s5DyMeQwr7zpAw== Received: from imap2.dmz-prg2.suse.org (localhost [127.0.0.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by imap2.dmz-prg2.suse.org (Postfix) with ESMTPS id A2652139E8; Sat, 6 Apr 2024 08:29:33 +0000 (UTC) Received: from dovecot-director2.suse.de ([2a07:de40:b281:106:10:150:64:167]) by imap2.dmz-prg2.suse.org with ESMTPSA id hRJDJu0HEWbVZgAAn2gu4w (envelope-from ); Sat, 06 Apr 2024 08:29:33 +0000 Message-ID: <544ecc72-916f-436e-b4f2-093bea6882a9@suse.de> Date: Sat, 6 Apr 2024 10:29:41 +0200 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH v3 1/2] [gdb/symtab] Fix an out of bounds array access in find_epilogue_using_linetable Content-Language: en-US To: Bernd Edlinger , "gdb-patches@sourceware.org" References: <20240405151012.14763-1-tdevries@suse.de> From: Tom de Vries In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Spam-Score: -4.29 X-Spam-Level: X-Spamd-Result: default: False [-4.29 / 50.00]; BAYES_HAM(-3.00)[100.00%]; NEURAL_HAM_LONG(-1.00)[-1.000]; NEURAL_HAM_SHORT(-0.20)[-0.999]; MIME_GOOD(-0.10)[text/plain]; XM_UA_NO_VERSION(0.01)[]; MIME_TRACE(0.00)[0:+]; FREEMAIL_TO(0.00)[hotmail.de,sourceware.org]; TO_DN_EQ_ADDR_SOME(0.00)[]; ARC_NA(0.00)[]; MID_RHS_MATCH_FROM(0.00)[]; RCVD_VIA_SMTP_AUTH(0.00)[]; RCPT_COUNT_TWO(0.00)[2]; FREEMAIL_ENVRCPT(0.00)[hotmail.de]; DKIM_SIGNED(0.00)[suse.de:s=susede2_rsa,suse.de:s=susede2_ed25519]; FROM_EQ_ENVFROM(0.00)[]; FROM_HAS_DN(0.00)[]; TO_DN_SOME(0.00)[]; RCVD_TLS_ALL(0.00)[]; TO_MATCH_ENVRCPT_ALL(0.00)[]; RCVD_COUNT_TWO(0.00)[2]; FUZZY_BLOCKED(0.00)[rspamd.com]; DBL_BLOCKED_OPENRESOLVER(0.00)[suse.de:email,imap2.dmz-prg2.suse.org:helo,imap2.dmz-prg2.suse.org:rdns] X-Spam-Status: No, score=-12.2 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,SPF_HELO_NONE,SPF_PASS,TXREP 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: On 4/6/24 07:03, Bernd Edlinger wrote: > On 4/5/24 17:10, Tom de Vries wrote: >> From: Bernd Edlinger >> >> An out of bounds array access in find_epilogue_using_linetable causes random >> test failures like these: >> >> FAIL: gdb.base/unwind-on-each-insn-amd64.exp: foo: instruction 6: $fba_value == $fn_fba >> FAIL: gdb.base/unwind-on-each-insn-amd64.exp: foo: instruction 6: check frame-id matches >> FAIL: gdb.base/unwind-on-each-insn-amd64.exp: foo: instruction 6: bt 2 >> FAIL: gdb.base/unwind-on-each-insn-amd64.exp: foo: instruction 6: up >> FAIL: gdb.base/unwind-on-each-insn-amd64.exp: foo: instruction 6: $sp_value == $::main_sp >> FAIL: gdb.base/unwind-on-each-insn-amd64.exp: foo: instruction 6: $fba_value == $::main_fba >> FAIL: gdb.base/unwind-on-each-insn-amd64.exp: foo: instruction 6: [string equal $fid $::main_fid] >> >> Here the read happens below the first element of the line >> table, and the test failure depends on the value that is >> read from there. >> >> It also happens that std::lower_bound returns a pointer exactly at the upper >> bound of the line table, also here the read value is undefined, that happens >> in this test: >> >> FAIL: gdb.dwarf2/dw2-epilogue-begin.exp: confirm watchpoint doesn't trigger >> >> Fixes: 528b729be1a2 ("gdb/dwarf2: Add support for DW_LNS_set_epilogue_begin in line-table") >> >> Co-Authored-By: Tom de Vries >> >> PR symtab/31268 >> Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31268 >> --- >> gdb/symtab.c | 85 +++++++++++++++++++++++++++++++++++++++++++++------- >> 1 file changed, 75 insertions(+), 10 deletions(-) >> >> diff --git a/gdb/symtab.c b/gdb/symtab.c >> index 86603dfebc3..0c126d99cd4 100644 >> --- a/gdb/symtab.c >> +++ b/gdb/symtab.c >> @@ -4166,10 +4166,14 @@ find_epilogue_using_linetable (CORE_ADDR func_addr) >> = unrelocated_addr (end_pc - objfile->text_section_offset ()); >> >> const linetable *linetable = sal.symtab->linetable (); >> - /* This should find the last linetable entry of the current function. >> - It is probably where the epilogue begins, but since the DWARF 5 >> - spec doesn't guarantee it, we iterate backwards through the function >> - until we either find it or are sure that it doesn't exist. */ >> + if (linetable->nitems == 0) >> + { >> + /* Empty line table. */ >> + return {}; >> + } >> + >> + /* Find the first linetable entry after the current function. Note that >> + this also may be an end_sequence entry. */ >> auto it = std::lower_bound >> (linetable->item, linetable->item + linetable->nitems, unrel_end, >> [] (const linetable_entry <e, unrelocated_addr pc) >> @@ -4177,13 +4181,74 @@ find_epilogue_using_linetable (CORE_ADDR func_addr) >> return lte.unrelocated_pc () < pc; >> }); >> >> - while (it->unrelocated_pc () >= unrel_start) >> - { >> - if (it->epilogue_begin) >> - return {it->pc (objfile)}; >> - it --; >> - } >> + if (it == linetable->item + linetable->nitems) >> + { >> + /* We couldn't find either: >> + - a linetable entry starting the function after the current >> + function, or >> + - an end_sequence entry that terminates the current function >> + at unrel_end. >> + This can happen when the linetable doesn't describe the full >> + extent of the function. Even though this is a corner case, which >> + may not happen other than in dwarf assembly test-cases, let's >> + handle this. >> + >> + Move to the last entry in the linetable, and check that it's an >> + end_sequence terminating the current function. */ >> + gdb_assert (it != &linetable->item[0]); >> + it--; >> + if (!(it->line == 0 >> + && unrel_start <= it->unrelocated_pc () >> + && it->unrelocated_pc () < unrel_end)) >> + return {}; > > Why is this check necessary here, and not also when > this is not the last function in the line-table? > > And why is this check necessary at all? > It spells out as much as possible the specific conditions of the corner-case we're handling. We could also just simply handle the cornercase by returning {}, I went forth and back a bit on that, and decided to support it on the basis that at least currently we have dwarf assembly test-cases in the testsuite that trigger this path, though I've submitted a series to clean that up. But I'm still on the fence about this, if you prefer a "return {}" I'm fine with that. >> + } >> + else >> + gdb_assert (unrel_end <= it->unrelocated_pc ()); > > Why do you not check that 'it' points to an end_sequence > at exactly unrel_end? > It could be anything at an address much higher PC than unrel_end. This assert spells out the post-condition of the call to std::lower_bound, in case it found an entry. If there's debug info where one line entry straddles two functions, the call returns the entry after it, which doesn't have address unrel_end. Having said that, we can unsupport such a scenario by doing: ... else { if (unrel_end < it->unrelocated_pc ()) return {}; gdb_assert (unrel_end == it->unrelocated_pc ()); ... Thanks, - Tom