From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id yNQqM/PPZWdlaiUAWB0awg (envelope-from ) for ; Fri, 20 Dec 2024 15:13:39 -0500 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=lC9nLkWf; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id CCE031E097; Fri, 20 Dec 2024 15:13:39 -0500 (EST) X-Spam-Checker-Version: SpamAssassin 4.0.0 (2022-12-13) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-6.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 autolearn=unavailable autolearn_force=no version=4.0.0 Received: from server2.sourceware.org (server2.sourceware.org [8.43.85.97]) (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 E6F391E091 for ; Fri, 20 Dec 2024 15:13:38 -0500 (EST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 994F53858C51 for ; Fri, 20 Dec 2024 20:13:38 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 994F53858C51 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=lC9nLkWf Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.10]) by sourceware.org (Postfix) with ESMTPS id 336723858D3C for ; Fri, 20 Dec 2024 20:06:16 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 336723858D3C 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 336723858D3C Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=198.175.65.10 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1734725176; cv=none; b=eLpkmwQ8ilW+HxdqeHrmi17TvhzTJGlKws6Ck5/2tnRJGm0WpODFpfHJqXCQiSaM6BJJ5UcC2hHAC//PCn2rMxPuXR92xxfWqPXhFR6WpRAu95qupFXXNlwpoTruZL4fg9Pxb0VvMMXA4QYQlcoEMIkz422A6lQekAXMD6uw7FA= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1734725176; c=relaxed/simple; bh=inXJeMQtdcd2Odin8V5/1LzO82wf1WYrYICvZ/70Ugo=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=eEKxrYsBAclQurKhtx8tncw2Yb7K9iCEonB3OLkzJZZrItCycgdZIczJtFKa98J6RAx/9PixNsU+6F3xlpG7Yjx8C9ktAzGK56iHx9XhyKHcbGFLYMgCvGU6dCz9fm7YUfy2VuDxowV1ekMZkWNuRctjLLZgD9L+3fh3GPnmArY= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 336723858D3C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1734725176; x=1766261176; h=from:to:subject:date:message-id:in-reply-to:references: mime-version:content-transfer-encoding; bh=inXJeMQtdcd2Odin8V5/1LzO82wf1WYrYICvZ/70Ugo=; b=lC9nLkWfgUKqZZeEMvyImvNcTwmUKQGor6zQBxr+Rz3mLq6MynBHzsl9 h7pDJvBBNm/yW/vpj8Iyy1IZfjdmohQ8jr/Cwsm24pWpnzPELuAlIgqH0 0Lx318CNrfug0+p6VN2OpMWzpi9QobhzZUeuu5f0fqzrEiwGH9eDsOzOh 8SzgTHuWx9P/UYSQ99IHFoVA11Lk2waB+g6eOHmfjBoPn3/lTsroK2u/o EkMdyO7q0eqbe5dlbkNYKqkIRPrnEqtVGhFHaDZQ1etIzgfVKvJhSD0iT ONTe+LfownKlePC0CWxOW/1TamiONeezTCZs30lyRKEzL3gZHS1ylmVik Q==; X-CSE-ConnectionGUID: y4HPHSirQkm3W0wpl9yKBA== X-CSE-MsgGUID: 4yaDCZEHRUe6YTKOgxoHnw== X-IronPort-AV: E=McAfee;i="6700,10204,11292"; a="52689144" X-IronPort-AV: E=Sophos;i="6.12,251,1728975600"; d="scan'208";a="52689144" Received: from fmviesa008.fm.intel.com ([10.60.135.148]) by orvoesa102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2024 12:06:16 -0800 X-CSE-ConnectionGUID: mu7A2fcARX2ghMjxYMbiQA== X-CSE-MsgGUID: NXpp1nvFRBCwymqPF07FZQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.12,251,1728975600"; d="scan'208";a="98809956" Received: from gkldtt-dev-004.igk.intel.com (HELO localhost) ([10.123.221.202]) by fmviesa008-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Dec 2024 12:06:14 -0800 From: "Schimpe, Christina" To: gdb-patches@sourceware.org Subject: [PATCH 07/12] gdb, bfd: amd64 linux coredump support with shadow stack. Date: Fri, 20 Dec 2024 20:04:56 +0000 Message-Id: <20241220200501.324191-8-christina.schimpe@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241220200501.324191-1-christina.schimpe@intel.com> References: <20241220200501.324191-1-christina.schimpe@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 From: Felix Willgerodt Intel's Control-Flow Enforcement Technology (CET) provides the shadow stack feature for the x86 architecture. This commit adds support to write and read the shadow-stack node in corefiles. This helps debugging return address violations post-mortem. The format is synced with the linux kernel commit "x86: Add PTRACE interface for shadow stack". As the linux kernel restricts shadow stack support to 64-bit, apply the fix for amd64 only. Co-Authored-By: Christina Schimpe --- bfd/elf.c | 24 +++++++++ gdb/amd64-linux-tdep.c | 52 +++++++++++++++++-- .../gdb.arch/amd64-shadow-stack-corefile.exp | 50 ++++++++++++++++++ 3 files changed, 122 insertions(+), 4 deletions(-) create mode 100644 gdb/testsuite/gdb.arch/amd64-shadow-stack-corefile.exp diff --git a/bfd/elf.c b/bfd/elf.c index 78394319bf0..23f1ebcd83c 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -10365,6 +10365,12 @@ elfcore_grok_xstatereg (bfd *abfd, Elf_Internal_Note *note) return elfcore_make_note_pseudosection (abfd, ".reg-xstate", note); } +static bool +elfcore_grok_sspreg (bfd *abfd, Elf_Internal_Note *note) +{ + return elfcore_make_note_pseudosection (abfd, ".reg-ssp", note); +} + static bool elfcore_grok_ppc_vmx (bfd *abfd, Elf_Internal_Note *note) { @@ -11060,6 +11066,13 @@ elfcore_grok_note (bfd *abfd, Elf_Internal_Note *note) else return true; + case NT_X86_SHSTK: /* Linux CET extension. */ + if (note->namesz == 6 + && strcmp (note->namedata, "LINUX") == 0) + return elfcore_grok_sspreg (abfd, note); + else + return true; + case NT_PPC_VMX: if (note->namesz == 6 && strcmp (note->namedata, "LINUX") == 0) @@ -12510,6 +12523,15 @@ elfcore_write_xstatereg (bfd *abfd, char *buf, int *bufsiz, note_name, NT_X86_XSTATE, xfpregs, size); } +static char * +elfcore_write_sspreg (bfd *abfd, char *buf, int *bufsiz, + const void *ssp, int size) +{ + const char *note_name = "LINUX"; + return elfcore_write_note (abfd, buf, bufsiz, + note_name, NT_X86_SHSTK, ssp, size); +} + char * elfcore_write_x86_segbases (bfd *abfd, char *buf, int *bufsiz, const void *regs, int size) @@ -13105,6 +13127,8 @@ elfcore_write_register_note (bfd *abfd, return elfcore_write_xstatereg (abfd, buf, bufsiz, data, size); if (strcmp (section, ".reg-x86-segbases") == 0) return elfcore_write_x86_segbases (abfd, buf, bufsiz, data, size); + if (strcmp (section, ".reg-ssp") == 0) + return elfcore_write_sspreg (abfd, buf, bufsiz, data, size); if (strcmp (section, ".reg-ppc-vmx") == 0) return elfcore_write_ppc_vmx (abfd, buf, bufsiz, data, size); if (strcmp (section, ".reg-ppc-vsx") == 0) diff --git a/gdb/amd64-linux-tdep.c b/gdb/amd64-linux-tdep.c index 8ed381e1a2c..95f643b1217 100644 --- a/gdb/amd64-linux-tdep.c +++ b/gdb/amd64-linux-tdep.c @@ -44,6 +44,7 @@ #include "expop.h" #include "arch/amd64-linux-tdesc.h" #include "inferior.h" +#include "x86-tdep.h" /* The syscall's XML filename for i386. */ #define XML_SYSCALL_FILENAME_AMD64 "syscalls/amd64-linux.xml" @@ -1586,6 +1587,14 @@ amd64_linux_record_signal (struct gdbarch *gdbarch, return 0; } +/* Get shadow stack pointer state from core dump. */ + +static bool +amd64_linux_core_read_ssp_state_p (bfd *abfd) +{ + return bfd_get_section_by_name (abfd, ".reg-ssp") != NULL; +} + /* Get Linux/x86 target description from core dump. */ static const struct target_desc * @@ -1595,11 +1604,14 @@ amd64_linux_core_read_description (struct gdbarch *gdbarch, { /* Linux/x86-64. */ x86_xsave_layout layout; - uint64_t xcr0 = i386_linux_core_read_xsave_info (abfd, layout); - if (xcr0 == 0) - xcr0 = X86_XSTATE_SSE_MASK; + uint64_t xstate_bv_mask = i386_linux_core_read_xsave_info (abfd, layout); + if (xstate_bv_mask == 0) + xstate_bv_mask = X86_XSTATE_SSE_MASK; + + if (amd64_linux_core_read_ssp_state_p (abfd)) + xstate_bv_mask |= X86_XSTATE_CET_U; - return amd64_linux_read_description (xcr0 & X86_XSTATE_ALL_MASK, + return amd64_linux_read_description (xstate_bv_mask & X86_XSTATE_ALL_MASK, gdbarch_ptr_bit (gdbarch) == 32); } @@ -1630,6 +1642,30 @@ static const struct regset amd64_linux_xstateregset = amd64_linux_collect_xstateregset }; +static void +amd64_linux_supply_ssp (const struct regset *regset, + struct regcache *regcache, int regnum, + const void *ssp, size_t len) +{ + x86_supply_ssp (regcache, *static_cast (ssp)); +} + +static void +amd64_linux_collect_ssp (const struct regset *regset, + const struct regcache *regcache, int regnum, + void *ssp, size_t len) +{ + x86_collect_ssp (regcache, *static_cast (ssp)); +} + +/* Shadow stack pointer register. */ + +static const struct regset amd64_linux_ssp_register + { + NULL, amd64_linux_supply_ssp, amd64_linux_collect_ssp + }; + + /* Iterate over core file register note sections. */ static void @@ -1646,6 +1682,14 @@ amd64_linux_iterate_over_regset_sections (struct gdbarch *gdbarch, cb (".reg-xstate", tdep->xsave_layout.sizeof_xsave, tdep->xsave_layout.sizeof_xsave, &amd64_linux_xstateregset, "XSAVE extended state", cb_data); + + /* SSP can be unavailable. Thus, we need to check the register status + in case we write a core file (regcache != nullptr). */ + if (tdep->ssp_regnum > 0 + && (regcache == nullptr + || REG_VALID == regcache->get_register_status (tdep->ssp_regnum))) + cb (".reg-ssp", 8, 8, &amd64_linux_ssp_register, + "shadow stack pointer", cb_data); } /* The instruction sequences used in x86_64 machines for a diff --git a/gdb/testsuite/gdb.arch/amd64-shadow-stack-corefile.exp b/gdb/testsuite/gdb.arch/amd64-shadow-stack-corefile.exp new file mode 100644 index 00000000000..25cc1529f0d --- /dev/null +++ b/gdb/testsuite/gdb.arch/amd64-shadow-stack-corefile.exp @@ -0,0 +1,50 @@ +# Copyright 2021-2024 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 the shadow stack pointer note in core dumps. + +require allow_ssp_tests + +standard_testfile amd64-shadow-stack.c +set gcorefile ${binfile}.gcore + +save_vars { ::env(GLIBC_TUNABLES) } { + + append_environment GLIBC_TUNABLES "glibc.cpu.hwcaps" "SHSTK" + + if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} \ + additional_flags="-fcf-protection=return"] } { + return -1 + } + + if { ![runto_main] } { + return -1 + } + + # Save ssp for comparison in the corefile session. + set ssp [get_hexadecimal_valueof "\$pl3_ssp" ""] + + if { ![gdb_gcore_cmd $gcorefile "save a corefile"] } { + return -1 + } + + # Now restart gdb and load the corefile. + clean_restart ${binfile} + + gdb_test "core ${gcorefile}" \ + "Core was generated by .*" "re-load generated corefile" + + gdb_test "print /x \$pl3_ssp" "= $ssp" +} -- 2.34.1 Intel Deutschland GmbH Registered Address: Am Campeon 10, 85579 Neubiberg, Germany Tel: +49 89 99 8853-0, www.intel.de Managing Directors: Sean Fennelly, Jeffrey Schneiderman, Tiffany Doon Silva Chairperson of the Supervisory Board: Nicole Lau Registered Office: Munich Commercial Register: Amtsgericht Muenchen HRB 186928