Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1// SPDX-License-Identifier: GPL-2.0-only
2//
3// Copyright 2024 Arm Limited
4//
5// Give ourselves GCS write permissions then use them
6
7#include <asm/unistd.h>
8
9/* Shadow Stack/Guarded Control Stack interface */
10#define PR_GET_SHADOW_STACK_STATUS 74
11#define PR_SET_SHADOW_STACK_STATUS 75
12#define PR_LOCK_SHADOW_STACK_STATUS 76
13
14# define PR_SHADOW_STACK_ENABLE (1UL << 0)
15# define PR_SHADOW_STACK_WRITE (1UL << 1)
16# define PR_SHADOW_STACK_PUSH (1UL << 2)
17
18#define GCSPR_EL0 S3_3_C2_C5_1
19
20#define KSFT_SKIP 4
21
22.macro function name
23 .macro endfunction
24 .type \name, @function
25 .purgem endfunction
26 .endm
27\name:
28.endm
29
30// Print a single character x0 to stdout
31// Clobbers x0-x2,x8
32function putc
33 str x0, [sp, #-16]!
34
35 mov x0, #1 // STDOUT_FILENO
36 mov x1, sp
37 mov x2, #1
38 mov x8, #__NR_write
39 svc #0
40
41 add sp, sp, #16
42 ret
43endfunction
44.globl putc
45
46// Print a NUL-terminated string starting at address x0 to stdout
47// Clobbers x0-x3,x8
48function puts
49 mov x1, x0
50
51 mov x2, #0
520: ldrb w3, [x0], #1
53 cbz w3, 1f
54 add x2, x2, #1
55 b 0b
56
571: mov w0, #1 // STDOUT_FILENO
58 mov x8, #__NR_write
59 svc #0
60
61 ret
62endfunction
63.globl puts
64
65// Utility macro to print a literal string
66// Clobbers x0-x4,x8
67.macro puts string
68 .pushsection .rodata.str1.1, "aMS", @progbits, 1
69.L__puts_literal\@: .string "\string"
70 .popsection
71
72 ldr x0, =.L__puts_literal\@
73 bl puts
74.endm
75
76.globl _start
77function _start
78 // Run with GCS
79 mov x0, PR_SET_SHADOW_STACK_STATUS
80 mov x1, PR_SHADOW_STACK_ENABLE | PR_SHADOW_STACK_WRITE
81 mov x2, xzr
82 mov x3, xzr
83 mov x4, xzr
84 mov x5, xzr
85 mov x8, #__NR_prctl
86 svc #0
87 cbz x0, 1f
88 puts "Failed to enable GCS with write permission\n"
89 mov x0, #KSFT_SKIP
90 b 2f
911:
92 mrs x0, GCSPR_EL0
93 sub x0, x0, #8
94 .inst 0xd91f1c01 // GCSSTR x1, x0
95
96 mov x0, #0
972:
98 mov x8, #__NR_exit
99 svc #0