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 push 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 KSFT_SKIP 4
19
20.macro function name
21 .macro endfunction
22 .type \name, @function
23 .purgem endfunction
24 .endm
25\name:
26.endm
27
28// Print a single character x0 to stdout
29// Clobbers x0-x2,x8
30function putc
31 str x0, [sp, #-16]!
32
33 mov x0, #1 // STDOUT_FILENO
34 mov x1, sp
35 mov x2, #1
36 mov x8, #__NR_write
37 svc #0
38
39 add sp, sp, #16
40 ret
41endfunction
42.globl putc
43
44// Print a NUL-terminated string starting at address x0 to stdout
45// Clobbers x0-x3,x8
46function puts
47 mov x1, x0
48
49 mov x2, #0
500: ldrb w3, [x0], #1
51 cbz w3, 1f
52 add x2, x2, #1
53 b 0b
54
551: mov w0, #1 // STDOUT_FILENO
56 mov x8, #__NR_write
57 svc #0
58
59 ret
60endfunction
61.globl puts
62
63// Utility macro to print a literal string
64// Clobbers x0-x4,x8
65.macro puts string
66 .pushsection .rodata.str1.1, "aMS", @progbits, 1
67.L__puts_literal\@: .string "\string"
68 .popsection
69
70 ldr x0, =.L__puts_literal\@
71 bl puts
72.endm
73
74.globl _start
75function _start
76 // Run with GCS
77 mov x0, PR_SET_SHADOW_STACK_STATUS
78 mov x1, PR_SHADOW_STACK_ENABLE | PR_SHADOW_STACK_PUSH
79 mov x2, xzr
80 mov x3, xzr
81 mov x4, xzr
82 mov x5, xzr
83 mov x8, #__NR_prctl
84 svc #0
85 cbz x0, 1f
86 puts "Failed to enable GCS with push permission\n"
87 mov x0, #KSFT_SKIP
88 b 2f
891:
90 sys #3, c7, c7, #0, x0 // GCSPUSHM
91 sysl x0, #3, c7, c7, #1 // GCSPOPM
92
93 mov x0, #0
942:
95 mov x8, #__NR_exit
96 svc #0