From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id yftFI+zgtGrS4DsAWB0awg (envelope-from ) for ; Thu, 24 Sep 2026 04:35:56 -0400 Authentication-Results: simark.ca; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=gTWvFikv; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id 891A81E033; Thu, 24 Sep 2026 04:35:56 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-3.4 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_00, DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED,RCVD_IN_VALIDITY_CERTIFIED_BLOCKED, RCVD_IN_VALIDITY_RPBL_BLOCKED,RCVD_IN_VALIDITY_SAFE_BLOCKED autolearn=ham autolearn_force=no version=4.0.1 Received: from vm01.sourceware.org (vm01.sourceware.org [38.145.34.32]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id C8DE21E033 for ; Thu, 24 Sep 2026 04:35:55 -0400 (EDT) Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 2ED5A4BB58A3 for ; Thu, 24 Sep 2026 08:35:50 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 2ED5A4BB58A3 Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=gTWvFikv Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.14]) by sourceware.org (Postfix) with ESMTPS id 64B084BB5892 for ; Thu, 24 Sep 2026 08:34:53 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 64B084BB5892 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=intel.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 64B084BB5892 Authentication-Results: sourceware.org; arc=none smtp.remote-ip=192.198.163.14 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1790238893; cv=none; b=ueKsuXeH0EuXAuxDbB5t6/0FLitBj6I6bX2sF2A3P6raH+H88V1npXyvmxP1Xs8UAn2Mjf6ZLNI6QpxQX1UckOgVzAAO0TUJf1n5MJqZu0qwgJGYGT5700mfG7cBJtXIMPpsdBbpjzFKq0+VlhR7ewPSwiyQvjliIMto442hURc= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1790238893; c=relaxed/simple; bh=6frtbknu5ejUBNH3GPHEy2hZGYuW4CNV/alJWOLXtv0=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=bwQHHTDUQBMtZryl3XhASvTi1zLAtcG7Vuhfgsigy9RRpxLUC9fneNKo0+YP3hyvNeCL1bS7mnYPcOZ60rJWQ1mf9KeHVvT1o1Ne7wJVF2kSnTXe5QWnYA7G+J/zIEkj00pug0xxVlW3Pvz0fTeekrk5i/gab8qyJiXcB90x+PQ= ARC-Authentication-Results: i=1; sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=gTWvFikv DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 64B084BB5892 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1790238894; x=1821774894; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=6frtbknu5ejUBNH3GPHEy2hZGYuW4CNV/alJWOLXtv0=; b=gTWvFikvySq1UOlpHXn5L9VUNskumXt082kWxSn+INxH2UvYMjBtcE5x diywYitQcjjNXpsiBWtAzUM1pLi6wjnaG+uqcA8Eyi8BqUjJpZKsFnYgh X3TmgwgUFjM+3JpLvdqPs77dkJqxrfgWbvwRXj8KvyPSGhzyMvGuILEbo UFmJ8XJIRgsnfBBO5b4SQoL9PSye6U7kyyfQXOjxoKjxiId+jyiyk+ksf J5VvTqQLIxLpvR78hB8uW1gXqfibSQeEuy9YdhgON/JGrjBf7U0VRmqhr 77366ku1ljTyObA7ScANRP2w9OsF0hpQ36krN7eJm2RH6kykEEMZ/QM4l A==; X-CSE-ConnectionGUID: aMFjt7POSGWBZnHEEDX3MQ== X-CSE-MsgGUID: KU/FL/SOQlOlTJnMinyj9w== X-IronPort-AV: E=McAfee;i="6800,10657,11914"; a="91021382" X-IronPort-AV: E=Sophos;i="6.27,120,1787036400"; d="scan'208";a="91021382" Received: from fmviesa003.fm.intel.com ([10.60.135.143]) by fmvoesa108.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Sep 2026 01:34:53 -0700 X-CSE-ConnectionGUID: kE16XkBiQoeteM/pQqLQKg== X-CSE-MsgGUID: h2Ai524gQUyNG58mNl6Cqg== X-ExtLoop1: 1 Received: from gkldtt-dev-004.igk.intel.com (HELO localhost) ([10.123.221.202]) by fmviesa003-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Sep 2026 01:34:52 -0700 From: Christina Joos To: gdb-patches@sourceware.org Cc: thiago.bauermann@linaro.org, tom@tromey.com, luis.machado.foss@gmail.com Subject: [PATCH v5 10/13] gdb: Implement the hook 'is_no_return_shadow_stack_address' for amd64 linux. Date: Thu, 24 Sep 2026 10:33:07 +0200 Message-ID: <20260924083311.1961530-11-christina.joos@intel.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260924083311.1961530-1-christina.joos@intel.com> References: <20260924083311.1961530-1-christina.joos@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces~public-inbox=simark.ca@sourceware.org There can be elements on the shadow stack which are not return addresses. This can happen, for instance, in case of signals on amd64 linux. The old shadow stack pointer is pushed in a special format with bit 63 set. |1...old SSP| - Pointer to old pre-signal ssp in sigframe token format (bit 63 set to 1) Linux kernel documentation: https://docs.kernel.org/arch/x86/shstk.html Implement the gdbarch hook is_no_return_shadow_stack_address to detect this scenario to print the shadow stack backtrace correctly. --- gdb/amd64-linux-tdep.c | 61 +++++++++++++++++++ .../amd64-shadow-stack-backtrace-signal.exp | 49 +++++++++++++++ .../gdb.arch/amd64-shadow-stack-signal.c | 31 ++++++++++ 3 files changed, 141 insertions(+) create mode 100644 gdb/testsuite/gdb.arch/amd64-shadow-stack-backtrace-signal.exp create mode 100644 gdb/testsuite/gdb.arch/amd64-shadow-stack-signal.c diff --git a/gdb/amd64-linux-tdep.c b/gdb/amd64-linux-tdep.c index 42a62eaa975..49609e5ac94 100644 --- a/gdb/amd64-linux-tdep.c +++ b/gdb/amd64-linux-tdep.c @@ -1960,6 +1960,64 @@ amd64_linux_top_addr_empty_shadow_stack return addr == range.second; } +/* Return a shadow stack frame info, if the shadow stack pointer SSP + belongs to a valid shadow stack frame while the element on the shadow + stack VALUE does not refer to a return address. This can happen, for + instance, in case of signals. The old shadow stack pointer is pushed + in a special format with bit 63 set. In case this is true, a valid + shadow stack frame info is returned with its attributes frame_type and + non_return_description configured to ssp_frame_type::non_return_frame + and "", respectively. */ + +static std::optional +amd64_linux_is_no_return_shadow_stack_address + (gdbarch *gdbarch, const CORE_ADDR ssp, const CORE_ADDR value, + const unsigned long level) +{ + /* SSP must belong to the shadow stack memory range. */ + std::pair range; + if (!gdbarch_address_in_shadow_stack_memory_range (gdbarch, + ssp, + &range)) + error (_("The shadow stack pointer does not point to a shadow stack " + "memory region")); + + /* In case bit 63 is not configured, the address on the shadow stack + should be a return address. */ + constexpr CORE_ADDR mask = (CORE_ADDR) 1 << 63; + if ((value & mask) == 0) + return {}; + + /* To compare the shadow stack pointer of the previous frame with the + value of FRAME, we must clear bit 63. */ + CORE_ADDR shadow_stack_val_cleared = (value & (~mask)); + + /* Compute the previous/old SSP. The shadow stack grows downwards. To + compute the previous shadow stack pointer, we need to increment + SSP. */ + CORE_ADDR prev_ssp + = ssp + gdbarch_shadow_stack_element_size_aligned (gdbarch); + + /* We incremented SSP by one element to compute PREV_SSP before. In + case SSP points to the first element of the shadow stack, PREV_SSP + must point to the bottom of the shadow stack (RANGE.SECOND), but not + beyond that address. */ + gdb_assert (prev_ssp > range.first && prev_ssp <= range.second); + + if (shadow_stack_val_cleared == prev_ssp) + { + /* Assign the current gdbarch to the new shadow stack frame. Since + the token is no PC value, do not assign a SAL object. */ + return std::optional + ({ssp, value, level, gdbarch, {}, + ssp_frame_type::non_return_frame, + {""}, + ssp_unwind_stop_reason::no_error}); + } + + return {}; +} + static void amd64_linux_init_abi_common (struct gdbarch_info info, struct gdbarch *gdbarch, int num_disp_step_buffers) @@ -2023,6 +2081,9 @@ amd64_linux_init_abi_common (struct gdbarch_info info, struct gdbarch *gdbarch, set_gdbarch_top_addr_empty_shadow_stack (gdbarch, amd64_linux_top_addr_empty_shadow_stack); + + set_gdbarch_is_no_return_shadow_stack_address + (gdbarch, amd64_linux_is_no_return_shadow_stack_address); } static void diff --git a/gdb/testsuite/gdb.arch/amd64-shadow-stack-backtrace-signal.exp b/gdb/testsuite/gdb.arch/amd64-shadow-stack-backtrace-signal.exp new file mode 100644 index 00000000000..21373dc07f3 --- /dev/null +++ b/gdb/testsuite/gdb.arch/amd64-shadow-stack-backtrace-signal.exp @@ -0,0 +1,49 @@ +# Copyright 2024-2026 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 shadow stack backtrace for signal handling on linux. + +require allow_ssp_tests {istarget "*-*-linux*"} + +standard_testfile amd64-shadow-stack-signal.c + +save_vars { ::env(GLIBC_TUNABLES) } { + + append_environment GLIBC_TUNABLES "glibc.cpu.hwcaps" "SHSTK" + + if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} \ + {debug additional_flags="-fcf-protection=return"}] } { + return + } + + if { ![runto_main] } { + return + } + + gdb_breakpoint "handler" + gdb_test "continue" \ + ".*Program received signal SIGUSR1, User defined signal 1.*" \ + "continue until signal" + gdb_continue_to_breakpoint "continue to breakpoint in handler" + + # Test shadow stack backtrace including . + gdb_test "bt -shadow" \ + [multi_line \ + "#0\[ \t\]*$hex in \[^\r\n\]+" \ + "#1\[ \t\]*" \ + "#2\[ \t\]*$hex in \[^\r\n\]+" \ + ".*" ] \ + "test shadow stack backtrace for signal handling." +} diff --git a/gdb/testsuite/gdb.arch/amd64-shadow-stack-signal.c b/gdb/testsuite/gdb.arch/amd64-shadow-stack-signal.c new file mode 100644 index 00000000000..c726e05b224 --- /dev/null +++ b/gdb/testsuite/gdb.arch/amd64-shadow-stack-signal.c @@ -0,0 +1,31 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2024-2026 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 . */ + +#include + +void +handler (int signo) +{ +} + +int +main (void) +{ + signal (SIGUSR1, handler); + raise (SIGUSR1); + return 0; +} -- 2.53.0 ________________________________________ Intel Deutschland GmbH Registered Address: Dornacher Strasse 1, 85622 Feldkirchen, Germany Tel: +49 (89) 99143-0 www.intel.de Managing Directors: Candice Moore, Jeffrey Schneiderman, Ramachandran Sitaraman Chairperson of the Supervisory Board: Sonja Pierer Registered Seat: Munich Commercial Register B: Amtsgericht Munich HRB 186928 This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.