x32/cet: Enable shadow stack during startup for Linux 6.10-rc4

Message ID 20240619210032.2141424-1-hjl.tools@gmail.com
State Under Review
Delegated to: Maxim Kuvyrkov
Headers
Series x32/cet: Enable shadow stack during startup for Linux 6.10-rc4 |

Checks

Context Check Description
redhat-pt-bot/TryBot-apply_patch success Patch applied to master at the time it was sent
redhat-pt-bot/TryBot-32bit success Build for i686
linaro-tcwg-bot/tcwg_glibc_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_glibc_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_glibc_check--master-aarch64 success Test passed
linaro-tcwg-bot/tcwg_glibc_check--master-arm success Test passed

Commit Message

H.J. Lu June 19, 2024, 9 p.m. UTC
  Enable shadow stack during startup for Linux 6.10-rc4:

commit 2883f01ec37dd8668e7222dfdb5980c86fdfe277
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Fri Mar 15 07:04:33 2024 -0700

    x86/shstk: Enable shadow stacks for x32

    1. Add shadow stack support to x32 signal.
    2. Use the 64-bit map_shadow_stack syscall for x32.
    3. Set up shadow stack for x32.

Add the map_shadow_stack system call to <fixup-asm-unistd.h> and regenerate
arch-syscall.h.  Tested on Intel Tiger Lake.
---
 sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h     | 1 +
 sysdeps/unix/sysv/linux/x86_64/x32/fixup-asm-unistd.h | 4 ++++
 sysdeps/x86_64/x32/dl-machine.h                       | 7 +++++--
 3 files changed, 10 insertions(+), 2 deletions(-)
  

Comments

H.J. Lu July 15, 2024, 1:18 p.m. UTC | #1
On Thu, Jun 20, 2024, 5:00 AM H.J. Lu <hjl.tools@gmail.com> wrote:

> Enable shadow stack during startup for Linux 6.10-rc4:
>
> commit 2883f01ec37dd8668e7222dfdb5980c86fdfe277
> Author: H.J. Lu <hjl.tools@gmail.com>
> Date:   Fri Mar 15 07:04:33 2024 -0700
>
>     x86/shstk: Enable shadow stacks for x32
>
>     1. Add shadow stack support to x32 signal.
>     2. Use the 64-bit map_shadow_stack syscall for x32.
>     3. Set up shadow stack for x32.
>
> Add the map_shadow_stack system call to <fixup-asm-unistd.h> and regenerate
> arch-syscall.h.  Tested on Intel Tiger Lake.
> ---
>  sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h     | 1 +
>  sysdeps/unix/sysv/linux/x86_64/x32/fixup-asm-unistd.h | 4 ++++
>  sysdeps/x86_64/x32/dl-machine.h                       | 7 +++++--
>  3 files changed, 10 insertions(+), 2 deletions(-)
>
> diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h
> b/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h
> index 3040a47d72..df3e22236d 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h
> +++ b/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h
> @@ -155,6 +155,7 @@
>  #define __NR_lsm_set_self_attr 1073742284
>  #define __NR_lstat 1073741830
>  #define __NR_madvise 1073741852
> +#define __NR_map_shadow_stack 1073742277
>  #define __NR_mbind 1073742061
>  #define __NR_membarrier 1073742148
>  #define __NR_memfd_create 1073742143
> diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/fixup-asm-unistd.h
> b/sysdeps/unix/sysv/linux/x86_64/x32/fixup-asm-unistd.h
> index 98124169e6..47fa8af4ce 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/x32/fixup-asm-unistd.h
> +++ b/sysdeps/unix/sysv/linux/x86_64/x32/fixup-asm-unistd.h
> @@ -15,6 +15,10 @@
>     License along with the GNU C Library; if not, see
>     <http://www.gnu.org/licenses/>.  */
>
> +#ifndef __NR_map_shadow_stack
> +# define __NR_map_shadow_stack 1073742277
> +#endif
> +
>  /* X32 uses the same 64-bit syscall interface for set_thread_area.   */
>  #ifndef __NR_set_thread_area
>  # define __NR_set_thread_area 1073742029
> diff --git a/sysdeps/x86_64/x32/dl-machine.h
> b/sysdeps/x86_64/x32/dl-machine.h
> index c35cee9261..3eb59bde7c 100644
> --- a/sysdeps/x86_64/x32/dl-machine.h
> +++ b/sysdeps/x86_64/x32/dl-machine.h
> @@ -45,13 +45,16 @@ _start:\n\
>  _dl_start_user:\n\
>         # Save the user entry point address in %r12.\n\
>         movl %eax, %r12d\n\
> +       # Save %rsp value in %r13.\n\
> +       movl %esp, %r13d\n\
> +"\
> +       RTLD_START_ENABLE_X86_FEATURES \
> +"\
>         # Read the original argument count.\n\
>         movl (%rsp), %edx\n\
>         # Call _dl_init (struct link_map *main_map, int argc, char **argv,
> char **env)\n\
>         # argc -> rsi\n\
>         movl %edx, %esi\n\
> -       # Save %rsp value in %r13.\n\
> -       movl %esp, %r13d\n\
>         # And align stack for the _dl_init call.\n\
>         and $-16, %esp\n\
>         # _dl_loaded -> rdi\n\
> --
> 2.45.2
>

Linux kernel 6.10 supports x32 shadow stack.  OK for 2.40?


>
>
  
Carlos O'Donell July 15, 2024, 1:49 p.m. UTC | #2
On 6/19/24 5:00 PM, H.J. Lu wrote:
> Enable shadow stack during startup for Linux 6.10-rc4:
> 
> commit 2883f01ec37dd8668e7222dfdb5980c86fdfe277
> Author: H.J. Lu <hjl.tools@gmail.com>
> Date:   Fri Mar 15 07:04:33 2024 -0700
> 
>     x86/shstk: Enable shadow stacks for x32
> 
>     1. Add shadow stack support to x32 signal.
>     2. Use the 64-bit map_shadow_stack syscall for x32.
>     3. Set up shadow stack for x32.
> 
> Add the map_shadow_stack system call to <fixup-asm-unistd.h> and regenerate
> arch-syscall.h.  Tested on Intel Tiger Lake.

This needs to wait for glibc 2.41.

We are touching target startup code here.

We can review this shortly at the start of August when the dev branch reopens.

> ---
>  sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h     | 1 +
>  sysdeps/unix/sysv/linux/x86_64/x32/fixup-asm-unistd.h | 4 ++++
>  sysdeps/x86_64/x32/dl-machine.h                       | 7 +++++--
>  3 files changed, 10 insertions(+), 2 deletions(-)
> 
> diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h b/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h
> index 3040a47d72..df3e22236d 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h
> +++ b/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h
> @@ -155,6 +155,7 @@
>  #define __NR_lsm_set_self_attr 1073742284
>  #define __NR_lstat 1073741830
>  #define __NR_madvise 1073741852
> +#define __NR_map_shadow_stack 1073742277
>  #define __NR_mbind 1073742061
>  #define __NR_membarrier 1073742148
>  #define __NR_memfd_create 1073742143
> diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/fixup-asm-unistd.h b/sysdeps/unix/sysv/linux/x86_64/x32/fixup-asm-unistd.h
> index 98124169e6..47fa8af4ce 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/x32/fixup-asm-unistd.h
> +++ b/sysdeps/unix/sysv/linux/x86_64/x32/fixup-asm-unistd.h
> @@ -15,6 +15,10 @@
>     License along with the GNU C Library; if not, see
>     <http://www.gnu.org/licenses/>.  */
>  
> +#ifndef __NR_map_shadow_stack
> +# define __NR_map_shadow_stack 1073742277
> +#endif
> +
>  /* X32 uses the same 64-bit syscall interface for set_thread_area.   */
>  #ifndef __NR_set_thread_area
>  # define __NR_set_thread_area 1073742029
> diff --git a/sysdeps/x86_64/x32/dl-machine.h b/sysdeps/x86_64/x32/dl-machine.h
> index c35cee9261..3eb59bde7c 100644
> --- a/sysdeps/x86_64/x32/dl-machine.h
> +++ b/sysdeps/x86_64/x32/dl-machine.h
> @@ -45,13 +45,16 @@ _start:\n\
>  _dl_start_user:\n\
>  	# Save the user entry point address in %r12.\n\
>  	movl %eax, %r12d\n\
> +	# Save %rsp value in %r13.\n\
> +	movl %esp, %r13d\n\
> +"\
> +	RTLD_START_ENABLE_X86_FEATURES \
> +"\
>  	# Read the original argument count.\n\
>  	movl (%rsp), %edx\n\
>  	# Call _dl_init (struct link_map *main_map, int argc, char **argv, char **env)\n\
>  	# argc -> rsi\n\
>  	movl %edx, %esi\n\
> -	# Save %rsp value in %r13.\n\
> -	movl %esp, %r13d\n\
>  	# And align stack for the _dl_init call.\n\
>  	and $-16, %esp\n\
>  	# _dl_loaded -> rdi\n\
  

Patch

diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h b/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h
index 3040a47d72..df3e22236d 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h
@@ -155,6 +155,7 @@ 
 #define __NR_lsm_set_self_attr 1073742284
 #define __NR_lstat 1073741830
 #define __NR_madvise 1073741852
+#define __NR_map_shadow_stack 1073742277
 #define __NR_mbind 1073742061
 #define __NR_membarrier 1073742148
 #define __NR_memfd_create 1073742143
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/fixup-asm-unistd.h b/sysdeps/unix/sysv/linux/x86_64/x32/fixup-asm-unistd.h
index 98124169e6..47fa8af4ce 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/fixup-asm-unistd.h
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/fixup-asm-unistd.h
@@ -15,6 +15,10 @@ 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#ifndef __NR_map_shadow_stack
+# define __NR_map_shadow_stack 1073742277
+#endif
+
 /* X32 uses the same 64-bit syscall interface for set_thread_area.   */
 #ifndef __NR_set_thread_area
 # define __NR_set_thread_area 1073742029
diff --git a/sysdeps/x86_64/x32/dl-machine.h b/sysdeps/x86_64/x32/dl-machine.h
index c35cee9261..3eb59bde7c 100644
--- a/sysdeps/x86_64/x32/dl-machine.h
+++ b/sysdeps/x86_64/x32/dl-machine.h
@@ -45,13 +45,16 @@  _start:\n\
 _dl_start_user:\n\
 	# Save the user entry point address in %r12.\n\
 	movl %eax, %r12d\n\
+	# Save %rsp value in %r13.\n\
+	movl %esp, %r13d\n\
+"\
+	RTLD_START_ENABLE_X86_FEATURES \
+"\
 	# Read the original argument count.\n\
 	movl (%rsp), %edx\n\
 	# Call _dl_init (struct link_map *main_map, int argc, char **argv, char **env)\n\
 	# argc -> rsi\n\
 	movl %edx, %esi\n\
-	# Save %rsp value in %r13.\n\
-	movl %esp, %r13d\n\
 	# And align stack for the _dl_init call.\n\
 	and $-16, %esp\n\
 	# _dl_loaded -> rdi\n\