Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: "Schimpe, Christina" <christina.schimpe@intel.com>
To: Thiago Jung Bauermann <thiago.bauermann@linaro.org>,
	Luis Machado <luis.machado@arm.com>
Cc: "gdb-patches@sourceware.org" <gdb-patches@sourceware.org>,
	"eliz@gnu.org" <eliz@gnu.org>
Subject: RE: [PATCH v4 07/11] gdb: Handle shadow stack pointer register unwinding for amd64 linux.
Date: Mon, 23 Jun 2025 14:55:13 +0000	[thread overview]
Message-ID: <SN7PR11MB76388605C7D433A4ED16C741F979A@SN7PR11MB7638.namprd11.prod.outlook.com> (raw)
In-Reply-To: <871prfp4rk.fsf@linaro.org>

> -----Original Message-----
> From: Thiago Jung Bauermann <thiago.bauermann@linaro.org>
> Sent: Friday, June 20, 2025 3:43 AM
> To: Luis Machado <luis.machado@arm.com>
> Cc: Schimpe, Christina <christina.schimpe@intel.com>; gdb-
> patches@sourceware.org; eliz@gnu.org
> Subject: Re: [PATCH v4 07/11] gdb: Handle shadow stack pointer register
> unwinding for amd64 linux.
> 
> Luis Machado <luis.machado@arm.com> writes:
> 
> > On 6/17/25 13:11, Christina Schimpe wrote:
> >> +	 Using /proc/PID/smaps we can only check if the current shadow
> >> +	 stack pointer SSP points to shadow stack memory.  Only if this is
> >> +	 the case a valid previous shadow stack pointer can be
> >> +	 calculated.  */
> >> +      std::pair<CORE_ADDR, CORE_ADDR> range;
> >> +      if (linux_address_in_shadow_stack_mem_range (ssp, &range))
> >> +	{
> >> +	  /* The shadow stack grows downwards.  To compute the previous
> >> +	     shadow stack pointer, we need to increment SSP.  */
> >> +	  CORE_ADDR new_ssp
> >> +	    = ssp + amd64_linux_shadow_stack_element_size_aligned
> >> +(gdbarch);
> >> +
> >> +	  /* If NEW_SSP points to the end of or before (<=) the current
> >> +	     shadow stack memory range we consider NEW_SSP as valid (but
> >> +	     empty).  */
> >
> > I couldn't quite understand the difference between the empty case and
> > the unavailable case. But maybe I just don't fully understand the feature.
> >
> > Would it be possible to make the comment a bit more clear?
> 
> I understood it to mean that if new_ssp == range.second, then it points to
> the top of the stack and there aren't any elements.
> 
> Whereas if new_ssp points outside of the shadow stack area, then it's
> garbage and we failed to unwind it, hence the unavailable value.
> 
> Christina, please correct me if I'm wrong.
> 
> But now looking at this again, I think there's an off-by-one error:
> range.second is the first address outside of the memory range, so the
> comparison needs to be strictly less than. And the shadow stack will be
> empty if new_ssp == range.second - 1 (there's no need to check for that,
> though).
> 
> >> +	  if (new_ssp <= range.second)
> >> +	    return frame_unwind_got_address (this_frame, regnum, new_ssp);
> >> +	}
> >> +    }
> >> +
> >> +  /* Return a value which is marked as unavailable in case we could not
> >> +     calculate a valid previous shadow stack pointer.  */
> >> +  value *retval
> >> +    = value::allocate_register (get_next_frame_sentinel_okay (this_frame),
> >> +				regnum, register_type (gdbarch, regnum));
> >> +  retval->mark_bytes_unavailable (0, retval->type ()->length ());
> >> +  return retval;
> >> +}

Hi Thiago, 

> Whereas if new_ssp points outside of the shadow stack area, then it's
> garbage and we failed to unwind it, hence the unavailable value.

Yes, this is how it should be. 😊

But I think the current implementation should be correct.
I wrote a small testprogram, which enables shadow stack manually using ARCH_PRCTL in enable_ssp:

~~~

int call ()
{
  return 0;
}

int enable_ssp ()
{
   int ret;
   if (ARCH_PRCTL(ARCH_SHSTK_ENABLE, ARCH_SHSTK_SHSTK)) {
     printf("[FAIL]\tEnabling shadow stack failed\n");
     return 1;
   }

   ret = call (); // stop in enable_ssp

   if (ARCH_PRCTL(ARCH_SHSTK_DISABLE, ARCH_SHSTK_SHSTK)) {
     ret = 1;
     printf("[FAIL]\tDisabling shadow stack failed\n");
   }
   return ret;
}

int main ()
{
  return enable_ssp ();
}

~~~

If we stop in enable_ssp, ("ret = call ()"), we have the scenario that shadow stack is enabled,
but no call instruction has been executed yet.
So we'll have an empty shadow stack, but SSP is valid and pointing to the end address
(==range.second) of the shadow stack address space:

~~~
(gdb) r
Starting program: /tmp/main 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Breakpoint 1, enable_ssp () at main.c:52
52	   ret = call (); // stop in enable_ssp
(gdb) p $pl3_ssp
$1 = (void *) 0x7ffff7c00000
(gdb) info proc mappings
process 94192
Mapped address spaces:

Start Addr         End Addr           Size               Offset             Perms File 
[...]
0x0000555555558000 0x0000555555559000 0x1000             0x3000             rw-p  /tmp/main 
0x00007ffff7400000 0x00007ffff7c00000 0x800000           0x0                rw-p   
[...]

~~~

Checking the unwinding we see that one frame above SSP becomes unavailable:
~~~
(gdb) up
#1  0x00005555555551d4 in main () at main.c:63
63	  return enable_ssp ();
(gdb) p $pl3_ssp
$3 = <unavailable>
(gdb) down
#0  enable_ssp () at main.c:52
52	   ret = call (); // stop in enable_ssp
(gdb) p $pl3_ssp
$4 = (void *) 0x7ffff7c00000
~~~

Or unwinding from call:
~~~
Breakpoint 1, call () at main.c:41
41	  return 0;
(gdb) p $pl3_ssp
$1 = (void *) 0x7ffff7bffff8
(gdb) up
#1  0x000055555555518a in enable_ssp () at main.c:52
52	   ret = call (); // stop in enable_ssp
(gdb) p $pl3_ssp
$2 = (void *) 0x7ffff7c00000
(gdb) up
#2  0x00005555555551d4 in main () at main.c:63
63	  return enable_ssp ();
(gdb) p $pl3_ssp
$3 = <unavailable>
(gdb) down
#1  0x000055555555518a in enable_ssp () at main.c:52
52	   ret = call (); // stop in enable_ssp
(gdb) p $pl3_ssp
$4 = (void *) 0x7ffff7c00000
(gdb) down 
#0  call () at main.c:41
41	  return 0;
(gdb) p $pl3_ssp
$5 = (void *) 0x7ffff7bffff8
~~~

So the check

"if (new_ssp <= range.second)"

seems correct to me.

Christina



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

  reply	other threads:[~2025-06-23 14:55 UTC|newest]

Thread overview: 53+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-06-17 12:11 [PATCH v4 00/11] Add CET shadow stack support Christina Schimpe
2025-06-17 12:11 ` [PATCH v4 01/11] gdbserver: Add optional runtime register set type Christina Schimpe
2025-06-19  9:27   ` Luis Machado
2025-06-17 12:11 ` [PATCH v4 02/11] gdbserver: Add assert in x86_linux_read_description Christina Schimpe
2025-06-19  9:27   ` Luis Machado
2025-06-17 12:11 ` [PATCH v4 03/11] gdb: Sync up x86-gcc-cpuid.h with cpuid.h from gcc 14 branch Christina Schimpe
2025-06-17 18:12   ` Tom Tromey
2025-06-20 12:39     ` Schimpe, Christina
2025-06-17 12:11 ` [PATCH v4 04/11] gdb, gdbserver: Use xstate_bv for target description creation on x86 Christina Schimpe
2025-06-19  9:23   ` Luis Machado
2025-06-23 12:46     ` Schimpe, Christina
2025-06-23 12:56       ` Luis Machado
2025-06-24 13:46         ` Schimpe, Christina
2025-06-26 16:03           ` Luis Machado
2025-06-17 12:11 ` [PATCH v4 05/11] gdb, gdbserver: Add support of Intel shadow stack pointer register Christina Schimpe
2025-06-17 12:20   ` Eli Zaretskii
2025-06-19  9:24   ` Luis Machado
2025-06-23 13:05     ` Schimpe, Christina
2025-06-17 12:11 ` [PATCH v4 06/11] gdb: amd64 linux coredump support with shadow stack Christina Schimpe
2025-06-19  9:24   ` Luis Machado
2025-06-23 13:16     ` Schimpe, Christina
2025-06-17 12:11 ` [PATCH v4 07/11] gdb: Handle shadow stack pointer register unwinding for amd64 linux Christina Schimpe
2025-06-19  9:25   ` Luis Machado
2025-06-20  1:42     ` Thiago Jung Bauermann
2025-06-23 14:55       ` Schimpe, Christina [this message]
2025-06-23 23:26         ` Thiago Jung Bauermann
2025-06-23 15:00     ` Schimpe, Christina
2025-06-23 15:06       ` Luis Machado
2025-06-23 23:36         ` Thiago Jung Bauermann
2025-06-20  1:52   ` Thiago Jung Bauermann
2025-06-17 12:11 ` [PATCH v4 08/11] gdb, gdbarch: Enable inferior calls for shadow stack support Christina Schimpe
2025-06-19  9:25   ` Luis Machado
2025-06-23 17:49     ` Schimpe, Christina
2025-06-17 12:11 ` [PATCH v4 09/11] gdb: Implement amd64 linux shadow stack support for inferior calls Christina Schimpe
2025-06-17 12:21   ` Eli Zaretskii
2025-06-19  9:25   ` Luis Machado
2025-06-27 19:52     ` Schimpe, Christina
2025-06-28 10:38       ` Luis Machado
2025-06-28 20:03         ` Thiago Jung Bauermann
2025-06-28 21:05           ` Thiago Jung Bauermann
2025-06-17 12:11 ` [PATCH v4 10/11] gdb, gdbarch: Introduce gdbarch method to get the shadow stack pointer Christina Schimpe
2025-06-17 18:16   ` Tom Tromey
2025-06-20 12:59     ` Schimpe, Christina
2025-06-19  9:26   ` Luis Machado
2025-06-23 18:00     ` Schimpe, Christina
2025-06-17 12:11 ` [PATCH v4 11/11] gdb: Enable displaced stepping with shadow stack on amd64 linux Christina Schimpe
2025-06-17 12:22   ` Eli Zaretskii
2025-06-17 15:16     ` Schimpe, Christina
2025-06-19  9:26   ` Luis Machado
2025-06-23 18:24     ` Schimpe, Christina
2025-06-24  8:05       ` Luis Machado
2025-06-27 19:26         ` Schimpe, Christina
2025-06-28 10:35           ` Luis Machado

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=SN7PR11MB76388605C7D433A4ED16C741F979A@SN7PR11MB7638.namprd11.prod.outlook.com \
    --to=christina.schimpe@intel.com \
    --cc=eliz@gnu.org \
    --cc=gdb-patches@sourceware.org \
    --cc=luis.machado@arm.com \
    --cc=thiago.bauermann@linaro.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