1 | #include <asm/hwcap.h> |
2 | #include <stdbool.h> |
3 | #include <sys/auxv.h> |
4 | #include <sys/prctl.h> |
5 | |
6 | #ifndef HWCAP_GCS |
7 | #define HWCAP_GCS (1UL << 32) |
8 | #endif |
9 | |
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 PRCTL_SYSCALL_NO 167 |
19 | |
20 | // Once we enable GCS, we cannot return from the function that made the syscall |
21 | // to enable it. This is because the control stack is empty, there is no valid |
22 | // address for us to return to. So for the initial enable we must use inline asm |
23 | // instead of the libc's prctl wrapper function. |
24 | #define my_prctl(option, arg2, arg3, arg4, arg5) \ |
25 | ({ \ |
26 | register unsigned long x0 __asm__("x0") = option; \ |
27 | register unsigned long x1 __asm__("x1") = arg2; \ |
28 | register unsigned long x2 __asm__("x2") = arg3; \ |
29 | register unsigned long x3 __asm__("x3") = arg4; \ |
30 | register unsigned long x4 __asm__("x4") = arg5; \ |
31 | register unsigned long x8 __asm__("x8") = PRCTL_SYSCALL_NO; \ |
32 | __asm__ __volatile__("svc #0\n" \ |
33 | : "=r"(x0) \ |
34 | : "r"(x0), "r"(x1), "r"(x2), "r"(x3), "r"(x4), \ |
35 | "r"(x8) \ |
36 | : "cc", "memory"); \ |
37 | }) |
38 | |
39 | unsigned long get_gcs_status() { |
40 | unsigned long mode = 0; |
41 | prctl(PR_GET_SHADOW_STACK_STATUS, &mode, 0, 0, 0); |
42 | return mode; |
43 | } |
44 | |
45 | extern void _start(); |
46 | bool change_gcs_config(bool enable) { |
47 | // The test unlocks and disables all features (excluding the main enable bit) |
48 | // before calling this expression. Enable them again. |
49 | unsigned long new_status = |
50 | enable | PR_SHADOW_STACK_PUSH | PR_SHADOW_STACK_WRITE; |
51 | |
52 | if (enable) { |
53 | // We would not be able to return from prctl(). |
54 | my_prctl(PR_SET_SHADOW_STACK_STATUS, new_status, 0, 0, 0); |
55 | |
56 | // This is a stack, so we must push in reverse order to the pops we want to |
57 | // have later. So push the return of __lldb_expr (_start), then the return |
58 | // address of this function (__lldb_expr). |
59 | __asm__ __volatile__("sys #3, C7, C7, #0, %0\n" // gcspushm _start |
60 | "sys #3, C7, C7, #0, x30\n" // gcspushm x30 |
61 | : |
62 | : "r" (_start)); |
63 | } else { |
64 | if (prctl(PR_SET_SHADOW_STACK_STATUS, new_status, 0, 0, 0) != 0) |
65 | return false; |
66 | } |
67 | |
68 | // Turn back on all locks. |
69 | if (prctl(PR_LOCK_SHADOW_STACK_STATUS, ~(0UL), 0, 0, 0) != 0) |
70 | return false; |
71 | |
72 | return true; |
73 | } |
74 | |
75 | void gcs_signal() { |
76 | // If we enabled GCS manually, then we could just return from main to generate |
77 | // a signal. However, if the C library enabled it, then we'd just exit |
78 | // normally. Assume the latter, and try to return to some bogus address to |
79 | // generate the signal. |
80 | __asm__ __volatile__( |
81 | // Corrupt the link register. This could be many numbers but 16 is a |
82 | // nicely aligned value that is unlikely to result in a fault because the |
83 | // PC is misaligned, which would hide the GCS fault. |
84 | "add x30, x30, #10\n" |
85 | "ret\n" ); |
86 | } |
87 | |
88 | // These functions are used to observe gcspr_el0 changing as we enter them, and |
89 | // the fault we cause by changing its value. Also used to check expression |
90 | // eval can handle function calls. |
91 | int test_func2() { return 99; } |
92 | |
93 | int test_func() { return test_func2(); } |
94 | |
95 | int main() { |
96 | if (!(getauxval(AT_HWCAP) & HWCAP_GCS)) |
97 | return 1; |
98 | |
99 | unsigned long mode = get_gcs_status(); |
100 | if ((mode & 1) == 0) { |
101 | // If GCS wasn't already enabled by the C library, enable it. |
102 | my_prctl(PR_SET_SHADOW_STACK_STATUS, PR_SHADOW_STACK_ENABLE, 0, 0, 0); |
103 | // From this point on, we cannot return from main without faulting because |
104 | // the return address from main, and every function before that, is not on |
105 | // the guarded control stack. |
106 | } |
107 | |
108 | // By now we should have one memory region where the GCS is stored. |
109 | |
110 | // For register read/write tests. |
111 | volatile int i = test_func(); |
112 | |
113 | // If this was a register test, we would have disabled GCS during the |
114 | // test_func call. We cannot re-enable it from ptrace so skip this part in |
115 | // this case. |
116 | mode = get_gcs_status(); |
117 | if ((mode & 1) == 1) |
118 | gcs_signal(); // Set break point at this line. |
119 | |
120 | return 0; |
121 | } |
122 | |