1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) 2023 ARM Limited. 4 */ 5 6 #include <limits.h> 7 #include <stdbool.h> 8 9 #include <linux/prctl.h> 10 11 #include <sys/mman.h> 12 #include <asm/mman.h> 13 #include <asm/hwcap.h> 14 #include <linux/sched.h> 15 16 #include "kselftest.h" 17 #include "gcs-util.h" 18 19 /* nolibc doesn't have sysconf(), just hard code the maximum */ 20 static size_t page_size = 65536; 21 22 static __attribute__((noinline)) void valid_gcs_function(void) 23 { 24 /* Do something the compiler can't optimise out */ 25 my_syscall1(__NR_prctl, PR_SVE_GET_VL); 26 } 27 28 static inline int gcs_set_status(unsigned long mode) 29 { 30 bool enabling = mode & PR_SHADOW_STACK_ENABLE; 31 int ret; 32 unsigned long new_mode; 33 34 /* 35 * The prctl takes 1 argument but we need to ensure that the 36 * other 3 values passed in registers to the syscall are zero 37 * since the kernel validates them. 38 */ 39 ret = my_syscall5(__NR_prctl, PR_SET_SHADOW_STACK_STATUS, mode, 40 0, 0, 0); 41 42 if (ret == 0) { 43 ret = my_syscall5(__NR_prctl, PR_GET_SHADOW_STACK_STATUS, 44 &new_mode, 0, 0, 0); 45 if (ret == 0) { 46 if (new_mode != mode) { 47 ksft_print_msg("Mode set to %lx not %lx\n", 48 new_mode, mode); 49 ret = -EINVAL; 50 } 51 } else { 52 ksft_print_msg("Failed to validate mode: %d\n", ret); 53 } 54 55 if (enabling != chkfeat_gcs()) { 56 ksft_print_msg("%senabled by prctl but %senabled in CHKFEAT\n", 57 enabling ? "" : "not ", 58 chkfeat_gcs() ? "" : "not "); 59 ret = -EINVAL; 60 } 61 } 62 63 return ret; 64 } 65 66 /* Try to read the status */ 67 static bool read_status(void) 68 { 69 unsigned long state; 70 int ret; 71 72 ret = my_syscall5(__NR_prctl, PR_GET_SHADOW_STACK_STATUS, 73 &state, 0, 0, 0); 74 if (ret != 0) { 75 ksft_print_msg("Failed to read state: %d\n", ret); 76 return false; 77 } 78 79 return state & PR_SHADOW_STACK_ENABLE; 80 } 81 82 /* Just a straight enable */ 83 static bool base_enable(void) 84 { 85 int ret; 86 87 ret = gcs_set_status(PR_SHADOW_STACK_ENABLE); 88 if (ret) { 89 ksft_print_msg("PR_SHADOW_STACK_ENABLE failed %d\n", ret); 90 return false; 91 } 92 93 return true; 94 } 95 96 /* Check we can read GCSPR_EL0 when GCS is enabled */ 97 static bool read_gcspr_el0(void) 98 { 99 unsigned long *gcspr_el0; 100 101 ksft_print_msg("GET GCSPR\n"); 102 gcspr_el0 = get_gcspr(); 103 ksft_print_msg("GCSPR_EL0 is %p\n", gcspr_el0); 104 105 return true; 106 } 107 108 /* Also allow writes to stack */ 109 static bool enable_writeable(void) 110 { 111 int ret; 112 113 ret = gcs_set_status(PR_SHADOW_STACK_ENABLE | PR_SHADOW_STACK_WRITE); 114 if (ret) { 115 ksft_print_msg("PR_SHADOW_STACK_ENABLE writeable failed: %d\n", ret); 116 return false; 117 } 118 119 ret = gcs_set_status(PR_SHADOW_STACK_ENABLE); 120 if (ret) { 121 ksft_print_msg("failed to restore plain enable %d\n", ret); 122 return false; 123 } 124 125 return true; 126 } 127 128 /* Also allow writes to stack */ 129 static bool enable_push_pop(void) 130 { 131 int ret; 132 133 ret = gcs_set_status(PR_SHADOW_STACK_ENABLE | PR_SHADOW_STACK_PUSH); 134 if (ret) { 135 ksft_print_msg("PR_SHADOW_STACK_ENABLE with push failed: %d\n", 136 ret); 137 return false; 138 } 139 140 ret = gcs_set_status(PR_SHADOW_STACK_ENABLE); 141 if (ret) { 142 ksft_print_msg("failed to restore plain enable %d\n", ret); 143 return false; 144 } 145 146 return true; 147 } 148 149 /* Enable GCS and allow everything */ 150 static bool enable_all(void) 151 { 152 int ret; 153 154 ret = gcs_set_status(PR_SHADOW_STACK_ENABLE | PR_SHADOW_STACK_PUSH | 155 PR_SHADOW_STACK_WRITE); 156 if (ret) { 157 ksft_print_msg("PR_SHADOW_STACK_ENABLE with everything failed: %d\n", 158 ret); 159 return false; 160 } 161 162 ret = gcs_set_status(PR_SHADOW_STACK_ENABLE); 163 if (ret) { 164 ksft_print_msg("failed to restore plain enable %d\n", ret); 165 return false; 166 } 167 168 return true; 169 } 170 171 static bool enable_invalid(void) 172 { 173 int ret = gcs_set_status(ULONG_MAX); 174 if (ret == 0) { 175 ksft_print_msg("GCS_SET_STATUS %lx succeeded\n", ULONG_MAX); 176 return false; 177 } 178 179 return true; 180 } 181 182 /* Map a GCS */ 183 static bool map_guarded_stack(void) 184 { 185 int ret; 186 uint64_t *buf; 187 uint64_t expected_cap; 188 int elem; 189 bool pass = true; 190 191 buf = (void *)my_syscall3(__NR_map_shadow_stack, 0, page_size, 192 SHADOW_STACK_SET_MARKER | 193 SHADOW_STACK_SET_TOKEN); 194 if (buf == MAP_FAILED) { 195 ksft_print_msg("Failed to map %lu byte GCS: %d\n", 196 page_size, errno); 197 return false; 198 } 199 ksft_print_msg("Mapped GCS at %p-%p\n", buf, 200 (void *)((uint64_t)buf + page_size)); 201 202 /* The top of the newly allocated region should be 0 */ 203 elem = (page_size / sizeof(uint64_t)) - 1; 204 if (buf[elem]) { 205 ksft_print_msg("Last entry is 0x%llx not 0x0\n", buf[elem]); 206 pass = false; 207 } 208 209 /* Then a valid cap token */ 210 elem--; 211 expected_cap = ((uint64_t)buf + page_size - 16); 212 expected_cap &= GCS_CAP_ADDR_MASK; 213 expected_cap |= GCS_CAP_VALID_TOKEN; 214 if (buf[elem] != expected_cap) { 215 ksft_print_msg("Cap entry is 0x%llx not 0x%llx\n", 216 buf[elem], expected_cap); 217 pass = false; 218 } 219 ksft_print_msg("cap token is 0x%llx\n", buf[elem]); 220 221 /* The rest should be zeros */ 222 for (elem = 0; elem < page_size / sizeof(uint64_t) - 2; elem++) { 223 if (!buf[elem]) 224 continue; 225 ksft_print_msg("GCS slot %d is 0x%llx not 0x0\n", 226 elem, buf[elem]); 227 pass = false; 228 } 229 230 ret = munmap(buf, page_size); 231 if (ret != 0) { 232 ksft_print_msg("Failed to unmap %ld byte GCS: %d\n", 233 page_size, errno); 234 pass = false; 235 } 236 237 return pass; 238 } 239 240 /* A fork()ed process can run */ 241 static bool test_fork(void) 242 { 243 unsigned long child_mode; 244 int ret, status; 245 pid_t pid; 246 bool pass = true; 247 248 pid = fork(); 249 if (pid == -1) { 250 ksft_print_msg("fork() failed: %d\n", errno); 251 pass = false; 252 goto out; 253 } 254 if (pid == 0) { 255 /* In child, make sure we can call a function, read 256 * the GCS pointer and status and then exit */ 257 valid_gcs_function(); 258 get_gcspr(); 259 260 ret = my_syscall5(__NR_prctl, PR_GET_SHADOW_STACK_STATUS, 261 &child_mode, 0, 0, 0); 262 if (ret == 0 && !(child_mode & PR_SHADOW_STACK_ENABLE)) { 263 ksft_print_msg("GCS not enabled in child\n"); 264 ret = -EINVAL; 265 } 266 267 exit(ret); 268 } 269 270 /* 271 * In parent, check we can still do function calls then block 272 * for the child. 273 */ 274 valid_gcs_function(); 275 276 ksft_print_msg("Waiting for child %d\n", pid); 277 278 ret = waitpid(pid, &status, 0); 279 if (ret == -1) { 280 ksft_print_msg("Failed to wait for child: %d\n", 281 errno); 282 return false; 283 } 284 285 if (!WIFEXITED(status)) { 286 ksft_print_msg("Child exited due to signal %d\n", 287 WTERMSIG(status)); 288 pass = false; 289 } else { 290 if (WEXITSTATUS(status)) { 291 ksft_print_msg("Child exited with status %d\n", 292 WEXITSTATUS(status)); 293 pass = false; 294 } 295 } 296 297 out: 298 299 return pass; 300 } 301 302 /* A vfork()ed process can run and exit */ 303 static bool test_vfork(void) 304 { 305 unsigned long child_mode; 306 int ret, status; 307 pid_t pid; 308 bool pass = true; 309 310 pid = vfork(); 311 if (pid == -1) { 312 ksft_print_msg("vfork() failed: %d\n", errno); 313 pass = false; 314 goto out; 315 } 316 if (pid == 0) { 317 /* 318 * In child, make sure we can call a function, read 319 * the GCS pointer and status and then exit. 320 */ 321 valid_gcs_function(); 322 get_gcspr(); 323 324 ret = my_syscall5(__NR_prctl, PR_GET_SHADOW_STACK_STATUS, 325 &child_mode, 0, 0, 0); 326 if (ret == 0 && !(child_mode & PR_SHADOW_STACK_ENABLE)) { 327 ksft_print_msg("GCS not enabled in child\n"); 328 ret = EXIT_FAILURE; 329 } 330 331 _exit(ret); 332 } 333 334 /* 335 * In parent, check we can still do function calls then check 336 * on the child. 337 */ 338 valid_gcs_function(); 339 340 ksft_print_msg("Waiting for child %d\n", pid); 341 342 ret = waitpid(pid, &status, 0); 343 if (ret == -1) { 344 ksft_print_msg("Failed to wait for child: %d\n", 345 errno); 346 return false; 347 } 348 349 if (!WIFEXITED(status)) { 350 ksft_print_msg("Child exited due to signal %d\n", 351 WTERMSIG(status)); 352 pass = false; 353 } else if (WEXITSTATUS(status)) { 354 ksft_print_msg("Child exited with status %d\n", 355 WEXITSTATUS(status)); 356 pass = false; 357 } 358 359 out: 360 361 return pass; 362 } 363 364 typedef bool (*gcs_test)(void); 365 366 static struct { 367 char *name; 368 gcs_test test; 369 bool needs_enable; 370 } tests[] = { 371 { "read_status", read_status }, 372 { "base_enable", base_enable, true }, 373 { "read_gcspr_el0", read_gcspr_el0 }, 374 { "enable_writeable", enable_writeable, true }, 375 { "enable_push_pop", enable_push_pop, true }, 376 { "enable_all", enable_all, true }, 377 { "enable_invalid", enable_invalid, true }, 378 { "map_guarded_stack", map_guarded_stack }, 379 { "fork", test_fork }, 380 { "vfork", test_vfork }, 381 }; 382 383 int main(void) 384 { 385 int i, ret; 386 unsigned long gcs_mode; 387 388 ksft_print_header(); 389 390 if (!(getauxval(AT_HWCAP) & HWCAP_GCS)) 391 ksft_exit_skip("SKIP GCS not supported\n"); 392 393 ret = my_syscall5(__NR_prctl, PR_GET_SHADOW_STACK_STATUS, 394 &gcs_mode, 0, 0, 0); 395 if (ret != 0) 396 ksft_exit_fail_msg("Failed to read GCS state: %d\n", ret); 397 398 if (!(gcs_mode & PR_SHADOW_STACK_ENABLE)) { 399 gcs_mode = PR_SHADOW_STACK_ENABLE; 400 ret = my_syscall5(__NR_prctl, PR_SET_SHADOW_STACK_STATUS, 401 gcs_mode, 0, 0, 0); 402 if (ret != 0) 403 ksft_exit_fail_msg("Failed to enable GCS: %d\n", ret); 404 } 405 406 ksft_set_plan(ARRAY_SIZE(tests)); 407 408 for (i = 0; i < ARRAY_SIZE(tests); i++) { 409 ksft_test_result((*tests[i].test)(), "%s\n", tests[i].name); 410 } 411 412 /* One last test: disable GCS, we can do this one time */ 413 ret = my_syscall5(__NR_prctl, PR_SET_SHADOW_STACK_STATUS, 0, 0, 0, 0); 414 if (ret != 0) 415 ksft_print_msg("Failed to disable GCS: %d\n", ret); 416 417 ksft_finished(); 418 419 return 0; 420 } 421