1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2023 ARM Limited.
9 #include <linux/prctl.h>
13 #include <linux/sched.h>
15 #include "kselftest.h"
18 /* nolibc doesn't have sysconf(), just hard code the maximum */
19 static size_t page_size
= 65536;
21 static __attribute__((noinline
)) void valid_gcs_function(void)
23 /* Do something the compiler can't optimise out */
24 my_syscall1(__NR_prctl
, PR_SVE_GET_VL
);
27 static inline int gcs_set_status(unsigned long mode
)
29 bool enabling
= mode
& PR_SHADOW_STACK_ENABLE
;
31 unsigned long new_mode
;
34 * The prctl takes 1 argument but we need to ensure that the
35 * other 3 values passed in registers to the syscall are zero
36 * since the kernel validates them.
38 ret
= my_syscall5(__NR_prctl
, PR_SET_SHADOW_STACK_STATUS
, mode
,
42 ret
= my_syscall5(__NR_prctl
, PR_GET_SHADOW_STACK_STATUS
,
45 if (new_mode
!= mode
) {
46 ksft_print_msg("Mode set to %lx not %lx\n",
51 ksft_print_msg("Failed to validate mode: %d\n", ret
);
54 if (enabling
!= chkfeat_gcs()) {
55 ksft_print_msg("%senabled by prctl but %senabled in CHKFEAT\n",
56 enabling
? "" : "not ",
57 chkfeat_gcs() ? "" : "not ");
65 /* Try to read the status */
66 static bool read_status(void)
71 ret
= my_syscall5(__NR_prctl
, PR_GET_SHADOW_STACK_STATUS
,
74 ksft_print_msg("Failed to read state: %d\n", ret
);
78 return state
& PR_SHADOW_STACK_ENABLE
;
81 /* Just a straight enable */
82 static bool base_enable(void)
86 ret
= gcs_set_status(PR_SHADOW_STACK_ENABLE
);
88 ksft_print_msg("PR_SHADOW_STACK_ENABLE failed %d\n", ret
);
95 /* Check we can read GCSPR_EL0 when GCS is enabled */
96 static bool read_gcspr_el0(void)
98 unsigned long *gcspr_el0
;
100 ksft_print_msg("GET GCSPR\n");
101 gcspr_el0
= get_gcspr();
102 ksft_print_msg("GCSPR_EL0 is %p\n", gcspr_el0
);
107 /* Also allow writes to stack */
108 static bool enable_writeable(void)
112 ret
= gcs_set_status(PR_SHADOW_STACK_ENABLE
| PR_SHADOW_STACK_WRITE
);
114 ksft_print_msg("PR_SHADOW_STACK_ENABLE writeable failed: %d\n", ret
);
118 ret
= gcs_set_status(PR_SHADOW_STACK_ENABLE
);
120 ksft_print_msg("failed to restore plain enable %d\n", ret
);
127 /* Also allow writes to stack */
128 static bool enable_push_pop(void)
132 ret
= gcs_set_status(PR_SHADOW_STACK_ENABLE
| PR_SHADOW_STACK_PUSH
);
134 ksft_print_msg("PR_SHADOW_STACK_ENABLE with push failed: %d\n",
139 ret
= gcs_set_status(PR_SHADOW_STACK_ENABLE
);
141 ksft_print_msg("failed to restore plain enable %d\n", ret
);
148 /* Enable GCS and allow everything */
149 static bool enable_all(void)
153 ret
= gcs_set_status(PR_SHADOW_STACK_ENABLE
| PR_SHADOW_STACK_PUSH
|
154 PR_SHADOW_STACK_WRITE
);
156 ksft_print_msg("PR_SHADOW_STACK_ENABLE with everything failed: %d\n",
161 ret
= gcs_set_status(PR_SHADOW_STACK_ENABLE
);
163 ksft_print_msg("failed to restore plain enable %d\n", ret
);
170 static bool enable_invalid(void)
172 int ret
= gcs_set_status(ULONG_MAX
);
174 ksft_print_msg("GCS_SET_STATUS %lx succeeded\n", ULONG_MAX
);
182 static bool map_guarded_stack(void)
186 uint64_t expected_cap
;
190 buf
= (void *)my_syscall3(__NR_map_shadow_stack
, 0, page_size
,
191 SHADOW_STACK_SET_MARKER
|
192 SHADOW_STACK_SET_TOKEN
);
193 if (buf
== MAP_FAILED
) {
194 ksft_print_msg("Failed to map %lu byte GCS: %d\n",
198 ksft_print_msg("Mapped GCS at %p-%p\n", buf
,
199 (void *)((uint64_t)buf
+ page_size
));
201 /* The top of the newly allocated region should be 0 */
202 elem
= (page_size
/ sizeof(uint64_t)) - 1;
204 ksft_print_msg("Last entry is 0x%llx not 0x0\n", buf
[elem
]);
208 /* Then a valid cap token */
210 expected_cap
= ((uint64_t)buf
+ page_size
- 16);
211 expected_cap
&= GCS_CAP_ADDR_MASK
;
212 expected_cap
|= GCS_CAP_VALID_TOKEN
;
213 if (buf
[elem
] != expected_cap
) {
214 ksft_print_msg("Cap entry is 0x%llx not 0x%llx\n",
215 buf
[elem
], expected_cap
);
218 ksft_print_msg("cap token is 0x%llx\n", buf
[elem
]);
220 /* The rest should be zeros */
221 for (elem
= 0; elem
< page_size
/ sizeof(uint64_t) - 2; elem
++) {
224 ksft_print_msg("GCS slot %d is 0x%llx not 0x0\n",
229 ret
= munmap(buf
, page_size
);
231 ksft_print_msg("Failed to unmap %ld byte GCS: %d\n",
239 /* A fork()ed process can run */
240 static bool test_fork(void)
242 unsigned long child_mode
;
249 ksft_print_msg("fork() failed: %d\n", errno
);
254 /* In child, make sure we can call a function, read
255 * the GCS pointer and status and then exit */
256 valid_gcs_function();
259 ret
= my_syscall5(__NR_prctl
, PR_GET_SHADOW_STACK_STATUS
,
260 &child_mode
, 0, 0, 0);
261 if (ret
== 0 && !(child_mode
& PR_SHADOW_STACK_ENABLE
)) {
262 ksft_print_msg("GCS not enabled in child\n");
270 * In parent, check we can still do function calls then block
273 valid_gcs_function();
275 ksft_print_msg("Waiting for child %d\n", pid
);
277 ret
= waitpid(pid
, &status
, 0);
279 ksft_print_msg("Failed to wait for child: %d\n",
284 if (!WIFEXITED(status
)) {
285 ksft_print_msg("Child exited due to signal %d\n",
289 if (WEXITSTATUS(status
)) {
290 ksft_print_msg("Child exited with status %d\n",
291 WEXITSTATUS(status
));
301 typedef bool (*gcs_test
)(void);
308 { "read_status", read_status
},
309 { "base_enable", base_enable
, true },
310 { "read_gcspr_el0", read_gcspr_el0
},
311 { "enable_writeable", enable_writeable
, true },
312 { "enable_push_pop", enable_push_pop
, true },
313 { "enable_all", enable_all
, true },
314 { "enable_invalid", enable_invalid
, true },
315 { "map_guarded_stack", map_guarded_stack
},
316 { "fork", test_fork
},
322 unsigned long gcs_mode
;
327 * We don't have getauxval() with nolibc so treat a failure to
328 * read GCS state as a lack of support and skip.
330 ret
= my_syscall5(__NR_prctl
, PR_GET_SHADOW_STACK_STATUS
,
333 ksft_exit_skip("Failed to read GCS state: %d\n", ret
);
335 if (!(gcs_mode
& PR_SHADOW_STACK_ENABLE
)) {
336 gcs_mode
= PR_SHADOW_STACK_ENABLE
;
337 ret
= my_syscall5(__NR_prctl
, PR_SET_SHADOW_STACK_STATUS
,
340 ksft_exit_fail_msg("Failed to enable GCS: %d\n", ret
);
343 ksft_set_plan(ARRAY_SIZE(tests
));
345 for (i
= 0; i
< ARRAY_SIZE(tests
); i
++) {
346 ksft_test_result((*tests
[i
].test
)(), "%s\n", tests
[i
].name
);
349 /* One last test: disable GCS, we can do this one time */
350 my_syscall5(__NR_prctl
, PR_SET_SHADOW_STACK_STATUS
, 0, 0, 0, 0);
352 ksft_print_msg("Failed to disable GCS: %d\n", ret
);