Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: "Schimpe, Christina" <christina.schimpe@intel.com>
To: gdb-patches@sourceware.org
Subject: [PATCH 12/12] gdb: Enable displaced stepping with shadow stack on amd64 linux.
Date: Fri, 20 Dec 2024 20:05:01 +0000	[thread overview]
Message-ID: <20241220200501.324191-13-christina.schimpe@intel.com> (raw)
In-Reply-To: <20241220200501.324191-1-christina.schimpe@intel.com>

This patch enables displaced stepping to support Intel's Control-Flow
Enforcement Technology (CET), which provides the shadow stack feature
for the x86 architecture.
Following the restriction of the linux kernel, enable displaced stepping
for amd64 only.

If displaced stepping is active and the single stepped instruction is a
call instruction, the return address atop the stack is the address following
the copied instruction.  However, to allow normal program execution it has
to be the address following the original instruction.  Due to that reason,
the return address is corrected in amd64_displaced_step_fixup and
i386_displaced_step_fixup.

To avoid a control-protection exception if shadow stack is active,
the shadow stack top address must be corrected as well.
---
 gdb/amd64-linux-tdep.c                        |  2 +
 gdb/amd64-tdep.c                              | 12 +++
 gdb/doc/gdb.texinfo                           | 11 ++-
 gdb/i386-tdep.c                               | 12 +++
 .../gdb.arch/amd64-shadow-stack-disp-step.exp | 84 +++++++++++++++++++
 5 files changed, 120 insertions(+), 1 deletion(-)
 create mode 100644 gdb/testsuite/gdb.arch/amd64-shadow-stack-disp-step.exp

diff --git a/gdb/amd64-linux-tdep.c b/gdb/amd64-linux-tdep.c
index ef59cfcb7e4..a034d75dd52 100644
--- a/gdb/amd64-linux-tdep.c
+++ b/gdb/amd64-linux-tdep.c
@@ -2068,6 +2068,8 @@ amd64_linux_init_abi_common(struct gdbarch_info info, struct gdbarch *gdbarch,
     (gdbarch, amd64_linux_remove_non_address_bits_watchpoint);
 
   set_gdbarch_shadow_stack_push (gdbarch, amd64_linux_shadow_stack_push);
+  set_gdbarch_get_shadow_stack_pointer (gdbarch,
+					amd64_linux_get_shadow_stack_pointer);
   dwarf2_frame_set_init_reg (gdbarch, amd64_init_reg);
 }
 
diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c
index a298333e70a..988a4cb285b 100644
--- a/gdb/amd64-tdep.c
+++ b/gdb/amd64-tdep.c
@@ -1747,6 +1747,18 @@ amd64_displaced_step_fixup (struct gdbarch *gdbarch,
       displaced_debug_printf ("relocated return addr at %s to %s",
 			      paddress (gdbarch, rsp),
 			      paddress (gdbarch, retaddr));
+
+      /* If shadow stack is enabled, we need to correct the return address
+	 on the shadow stack too.  */
+      std::optional<CORE_ADDR> ssp = gdbarch_get_shadow_stack_pointer (gdbarch);
+      if (ssp.has_value ())
+	{
+	  write_memory_unsigned_integer (*ssp, retaddr_len, byte_order,
+					 retaddr);
+	  displaced_debug_printf ("relocated shadow stack return addr at %s "
+				  "to %s", paddress (gdbarch, *ssp),
+				  paddress (gdbarch, retaddr));
+	}
     }
 }
 
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 4bed63cb0a1..022c944ea5c 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -26858,12 +26858,20 @@ the program stream must be an @code{ENDBR} instruction, otherwise the
 processor signals a control protection exception.
 @end itemize
 
-Impact on Call/Print:
+Impact on GDB commands:
+@itemize @bullet
+@item Call/Print:
 Inferior calls in @value{GDBN} reset the current PC to the beginning of the
 function that is called.  No call instruction is executed, but the @code{RET}
 instruction actually is.  To avoid a control protection exception due to the
 missing return address on the shadow stack, @value{GDBN} pushes the new return
 address to the shadow stack and updates the shadow stack pointer.
+@item Step:
+With displaced stepping, @value{GDBN} may run an out of line copy of a call
+instruction.  In this case, the wrong return address is pushed on the shadow
+stack.  @value{GDBN} corrects this value to avoid a control protection
+exception.  For more details on displaced stepping, see @ref{displaced-stepping}.
+@end itemize
 
 @node Alpha
 @subsection Alpha
@@ -41579,6 +41587,7 @@ GLOBAL              Disassembler_2	(Matches current architecture)
 @cindex out-of-line single-stepping
 @item set displaced-stepping
 @itemx show displaced-stepping
+@anchor{displaced-stepping}
 Control whether or not @value{GDBN} will do @dfn{displaced stepping}
 if the target supports it.  Displaced stepping is a way to single-step
 over breakpoints without removing them from the inferior, by executing
diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
index b338029d990..ec98b52c649 100644
--- a/gdb/i386-tdep.c
+++ b/gdb/i386-tdep.c
@@ -899,6 +899,18 @@ i386_displaced_step_fixup (struct gdbarch *gdbarch,
       displaced_debug_printf ("relocated return addr at %s to %s",
 			      paddress (gdbarch, esp),
 			      paddress (gdbarch, retaddr));
+
+      /* If shadow stack is enabled, we need to correct the return address
+	 on the shadow stack too.  */
+      std::optional<CORE_ADDR> ssp = gdbarch_get_shadow_stack_pointer (gdbarch);
+      if (ssp.has_value ())
+	{
+	  write_memory_unsigned_integer (*ssp, retaddr_len, byte_order,
+					 retaddr);
+	  displaced_debug_printf ("relocated shadow stack return addr at %s "
+				  "to %s", paddress (gdbarch, *ssp),
+				  paddress (gdbarch, retaddr));
+	}
     }
 }
 
diff --git a/gdb/testsuite/gdb.arch/amd64-shadow-stack-disp-step.exp b/gdb/testsuite/gdb.arch/amd64-shadow-stack-disp-step.exp
new file mode 100644
index 00000000000..493ca0100cb
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/amd64-shadow-stack-disp-step.exp
@@ -0,0 +1,84 @@
+# Copyright 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 <http://www.gnu.org/licenses/>.
+
+# Test continue from call instructions with shadow stack and displaced
+# stepping being enabled.
+
+require allow_ssp_tests support_displaced_stepping
+
+standard_testfile amd64-shadow-stack.c
+
+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
+    }
+
+    # Enable displaced stepping.
+    gdb_test_no_output "set displaced-stepping on"
+    gdb_test "show displaced-stepping" ".* displaced stepping .* is on.*"
+
+    if { ![runto_main] } {
+	return -1
+    }
+
+    # Get the address of the call1 instruction.
+    set call1_addr -1
+    gdb_test_multiple "disassemble main" "" {
+	-re -wrap "($hex) <\\+($decimal)>:\\s*call\\s*0x.*<call1>.*" {
+	    set call1_addr $expect_out(1,string)
+	    pass $gdb_test_name
+	}
+    }
+
+    if { $call1_addr == -1 } {
+	return -1
+    }
+
+    # Get the address of the call2 instruction.
+    set call2_addr -1
+    gdb_test_multiple "disassemble call1" "" {
+	-re -wrap "($hex) <\\+($decimal)>:\\s*call\\s*0x.*<call2>.*" {
+	    set call2_addr $expect_out(1,string)
+	    pass $gdb_test_name
+	}
+    }
+
+    if { $call2_addr == -1 } {
+	return -1
+    }
+
+    gdb_test "break *$call1_addr" \
+	"Breakpoint $decimal at $hex.*" \
+	"break at the address of the call1 instruction"
+
+    gdb_test "break *$call2_addr" \
+	"Breakpoint $decimal at $hex.*" \
+	"break at the address of the call2 instruction"
+
+    gdb_test "continue" \
+	"Breakpoint $decimal, $call1_addr in main ().*" \
+	"continue until call1 instruction"
+
+    # Test continue from breakpoint at call1 and call2 instructions.
+    gdb_test "continue" \
+	"Breakpoint $decimal, $call2_addr in call1 ().*" \
+	"continue from call1 instruction"
+
+    gdb_continue_to_end "continue from call2 instruction"
+}
-- 
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


  parent reply	other threads:[~2024-12-20 20:10 UTC|newest]

Thread overview: 72+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-12-20 20:04 [PATCH 00/12] Add CET shadow stack support Schimpe, Christina
2024-12-20 20:04 ` [PATCH 01/12] gdb, testsuite: Rename set_sanitizer_default to append_environment Schimpe, Christina
2025-01-28 13:45   ` Guinevere Larsen
2025-01-30 13:07     ` Schimpe, Christina
2025-01-30 14:27       ` Tom de Vries
2025-01-30 16:39         ` Schimpe, Christina
2024-12-20 20:04 ` [PATCH 02/12] gdbserver: Add optional runtime register set type Schimpe, Christina
2025-01-28 13:35   ` Guinevere Larsen
2025-01-30 10:28     ` Schimpe, Christina
2025-01-30 13:53       ` Guinevere Larsen
2025-01-30 17:43         ` Schimpe, Christina
2025-02-06  2:59       ` Thiago Jung Bauermann
2025-02-06 12:15         ` Schimpe, Christina
2024-12-20 20:04 ` [PATCH 03/12] gdbserver: Add assert in x86_linux_read_description Schimpe, Christina
2025-02-06  3:00   ` Thiago Jung Bauermann
2024-12-20 20:04 ` [PATCH 04/12] gdb: Sync up x86-gcc-cpuid.h with cpuid.h from gcc 14 branch Schimpe, Christina
2025-02-06  3:03   ` Thiago Jung Bauermann
2025-02-06 12:23     ` Schimpe, Christina
2024-12-20 20:04 ` [PATCH 05/12] gdb, gdbserver: Use xstate_bv for target description creation on x86 Schimpe, Christina
2025-01-30 14:51   ` Guinevere Larsen
2025-01-30 16:45     ` Schimpe, Christina
2025-02-06  3:09   ` Thiago Jung Bauermann
2025-02-06 12:33     ` Schimpe, Christina
2024-12-20 20:04 ` [PATCH 06/12] gdb, gdbserver: Add support of Intel shadow stack pointer register Schimpe, Christina
2025-02-06  3:13   ` Thiago Jung Bauermann
2025-02-06 14:33     ` Schimpe, Christina
2025-02-08  3:44       ` Thiago Jung Bauermann
2024-12-20 20:04 ` [PATCH 07/12] gdb, bfd: amd64 linux coredump support with shadow stack Schimpe, Christina
2025-02-06  3:15   ` Thiago Jung Bauermann
2025-02-07 11:54     ` Schimpe, Christina
2024-12-20 20:04 ` [PATCH 08/12] gdb: Handle shadow stack pointer register unwinding for amd64 linux Schimpe, Christina
2025-01-30 14:29   ` Guinevere Larsen
2025-01-30 16:11     ` Schimpe, Christina
2025-01-30 16:13       ` Guinevere Larsen
2025-01-30 16:40         ` Schimpe, Christina
2025-02-06  3:30   ` Thiago Jung Bauermann
2025-02-06 14:40     ` Schimpe, Christina
2024-12-20 20:04 ` [PATCH 09/12] gdb, gdbarch: Enable inferior calls for shadow stack support Schimpe, Christina
2025-02-06  3:31   ` Thiago Jung Bauermann
2025-02-06 15:07     ` Schimpe, Christina
2025-02-08  3:57       ` Thiago Jung Bauermann
2025-02-10  8:37         ` Schimpe, Christina
2024-12-20 20:04 ` [PATCH 10/12] gdb: Implement amd64 linux shadow stack support for inferior calls Schimpe, Christina
2025-02-06  3:34   ` Thiago Jung Bauermann
2025-02-07 11:55     ` Schimpe, Christina
2024-12-20 20:05 ` [PATCH 11/12] gdb, gdbarch: Introduce gdbarch method to get the shadow stack pointer Schimpe, Christina
2025-01-28 20:27   ` Guinevere Larsen
2025-01-30 10:33     ` Luis Machado
2025-01-30 12:34       ` Schimpe, Christina
2025-01-30 13:42         ` Guinevere Larsen
2025-02-06  3:35   ` Thiago Jung Bauermann
2025-02-07 12:01     ` Schimpe, Christina
2025-02-08  4:03       ` Thiago Jung Bauermann
2025-02-10  8:58         ` Schimpe, Christina
2025-02-11  1:53           ` Thiago Jung Bauermann
2025-02-15  3:45             ` Thiago Jung Bauermann
2025-02-16 10:45               ` Schimpe, Christina
2025-02-20  8:48                 ` Schimpe, Christina
2025-02-21  5:10                   ` Thiago Jung Bauermann
2025-02-21  9:41                     ` Schimpe, Christina
2024-12-20 20:05 ` Schimpe, Christina [this message]
2024-12-20 20:14   ` [PATCH 12/12] gdb: Enable displaced stepping with shadow stack on amd64 linux Eli Zaretskii
2025-01-02  9:04     ` Schimpe, Christina
2025-01-02  9:15       ` Eli Zaretskii
2025-02-06  3:37   ` Thiago Jung Bauermann
2025-01-16 14:01 ` [PING][PATCH 00/12] Add CET shadow stack support Schimpe, Christina
2025-01-27  9:44   ` [PING*2][PATCH " Schimpe, Christina
2025-01-30 15:01 ` [PATCH " Guinevere Larsen
2025-01-30 17:46   ` Schimpe, Christina
2025-02-04  3:57     ` Thiago Jung Bauermann
2025-02-04  9:40       ` Schimpe, Christina
2025-02-06  3:44         ` Thiago Jung Bauermann

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20241220200501.324191-13-christina.schimpe@intel.com \
    --to=christina.schimpe@intel.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox