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
2/*
3 * This program test's basic kernel shadow stack support. It enables shadow
4 * stack manual via the arch_prctl(), instead of relying on glibc. It's
5 * Makefile doesn't compile with shadow stack support, so it doesn't rely on
6 * any particular glibc. As a result it can't do any operations that require
7 * special glibc shadow stack support (longjmp(), swapcontext(), etc). Just
8 * stick to the basics and hope the compiler doesn't do anything strange.
9 */
10
11#define _GNU_SOURCE
12
13#include <sys/syscall.h>
14#include <asm/mman.h>
15#include <sys/mman.h>
16#include <sys/stat.h>
17#include <sys/wait.h>
18#include <stdio.h>
19#include <stdlib.h>
20#include <fcntl.h>
21#include <unistd.h>
22#include <string.h>
23#include <errno.h>
24#include <stdbool.h>
25#include <x86intrin.h>
26#include <asm/prctl.h>
27#include <sys/prctl.h>
28#include <stdint.h>
29#include <signal.h>
30#include <pthread.h>
31#include <sys/ioctl.h>
32#include <linux/userfaultfd.h>
33#include <setjmp.h>
34#include <sys/ptrace.h>
35#include <sys/signal.h>
36#include <linux/elf.h>
37
38/*
39 * Define the ABI defines if needed, so people can run the tests
40 * without building the headers.
41 */
42#ifndef __NR_map_shadow_stack
43#define __NR_map_shadow_stack 453
44
45#define SHADOW_STACK_SET_TOKEN (1ULL << 0)
46
47#define ARCH_SHSTK_ENABLE 0x5001
48#define ARCH_SHSTK_DISABLE 0x5002
49#define ARCH_SHSTK_LOCK 0x5003
50#define ARCH_SHSTK_UNLOCK 0x5004
51#define ARCH_SHSTK_STATUS 0x5005
52
53#define ARCH_SHSTK_SHSTK (1ULL << 0)
54#define ARCH_SHSTK_WRSS (1ULL << 1)
55
56#define NT_X86_SHSTK 0x204
57#endif
58
59#define SS_SIZE 0x200000
60#define PAGE_SIZE 0x1000
61
62#if (__GNUC__ < 8) || (__GNUC__ == 8 && __GNUC_MINOR__ < 5)
63int main(int argc, char *argv[])
64{
65 printf("[SKIP]\tCompiler does not support CET.\n");
66 return 0;
67}
68#else
69void write_shstk(unsigned long *addr, unsigned long val)
70{
71 asm volatile("wrssq %[val], (%[addr])\n"
72 : "=m" (addr)
73 : [addr] "r" (addr), [val] "r" (val));
74}
75
76static inline unsigned long __attribute__((always_inline)) get_ssp(void)
77{
78 unsigned long ret = 0;
79
80 asm volatile("xor %0, %0; rdsspq %0" : "=r" (ret));
81 return ret;
82}
83
84/*
85 * For use in inline enablement of shadow stack.
86 *
87 * The program can't return from the point where shadow stack gets enabled
88 * because there will be no address on the shadow stack. So it can't use
89 * syscall() for enablement, since it is a function.
90 *
91 * Based on code from nolibc.h. Keep a copy here because this can't pull in all
92 * of nolibc.h.
93 */
94#define ARCH_PRCTL(arg1, arg2) \
95({ \
96 long _ret; \
97 register long _num asm("eax") = __NR_arch_prctl; \
98 register long _arg1 asm("rdi") = (long)(arg1); \
99 register long _arg2 asm("rsi") = (long)(arg2); \
100 \
101 asm volatile ( \
102 "syscall\n" \
103 : "=a"(_ret) \
104 : "r"(_arg1), "r"(_arg2), \
105 "0"(_num) \
106 : "rcx", "r11", "memory", "cc" \
107 ); \
108 _ret; \
109})
110
111void *create_shstk(void *addr)
112{
113 return (void *)syscall(__NR_map_shadow_stack, addr, SS_SIZE, SHADOW_STACK_SET_TOKEN);
114}
115
116void *create_normal_mem(void *addr)
117{
118 return mmap(addr, SS_SIZE, PROT_READ | PROT_WRITE,
119 MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
120}
121
122void free_shstk(void *shstk)
123{
124 munmap(shstk, SS_SIZE);
125}
126
127int reset_shstk(void *shstk)
128{
129 return madvise(shstk, SS_SIZE, MADV_DONTNEED);
130}
131
132void try_shstk(unsigned long new_ssp)
133{
134 unsigned long ssp;
135
136 printf("[INFO]\tnew_ssp = %lx, *new_ssp = %lx\n",
137 new_ssp, *((unsigned long *)new_ssp));
138
139 ssp = get_ssp();
140 printf("[INFO]\tchanging ssp from %lx to %lx\n", ssp, new_ssp);
141
142 asm volatile("rstorssp (%0)\n":: "r" (new_ssp));
143 asm volatile("saveprevssp");
144 printf("[INFO]\tssp is now %lx\n", get_ssp());
145
146 /* Switch back to original shadow stack */
147 ssp -= 8;
148 asm volatile("rstorssp (%0)\n":: "r" (ssp));
149 asm volatile("saveprevssp");
150}
151
152int test_shstk_pivot(void)
153{
154 void *shstk = create_shstk(0);
155
156 if (shstk == MAP_FAILED) {
157 printf("[FAIL]\tError creating shadow stack: %d\n", errno);
158 return 1;
159 }
160 try_shstk((unsigned long)shstk + SS_SIZE - 8);
161 free_shstk(shstk);
162
163 printf("[OK]\tShadow stack pivot\n");
164 return 0;
165}
166
167int test_shstk_faults(void)
168{
169 unsigned long *shstk = create_shstk(0);
170
171 /* Read shadow stack, test if it's zero to not get read optimized out */
172 if (*shstk != 0)
173 goto err;
174
175 /* Wrss memory that was already read. */
176 write_shstk(shstk, 1);
177 if (*shstk != 1)
178 goto err;
179
180 /* Page out memory, so we can wrss it again. */
181 if (reset_shstk((void *)shstk))
182 goto err;
183
184 write_shstk(shstk, 1);
185 if (*shstk != 1)
186 goto err;
187
188 printf("[OK]\tShadow stack faults\n");
189 return 0;
190
191err:
192 return 1;
193}
194
195unsigned long saved_ssp;
196unsigned long saved_ssp_val;
197volatile bool segv_triggered;
198
199void __attribute__((noinline)) violate_ss(void)
200{
201 saved_ssp = get_ssp();
202 saved_ssp_val = *(unsigned long *)saved_ssp;
203
204 /* Corrupt shadow stack */
205 printf("[INFO]\tCorrupting shadow stack\n");
206 write_shstk((void *)saved_ssp, 0);
207}
208
209void segv_handler(int signum, siginfo_t *si, void *uc)
210{
211 printf("[INFO]\tGenerated shadow stack violation successfully\n");
212
213 segv_triggered = true;
214
215 /* Fix shadow stack */
216 write_shstk((void *)saved_ssp, saved_ssp_val);
217}
218
219int test_shstk_violation(void)
220{
221 struct sigaction sa = {};
222
223 sa.sa_sigaction = segv_handler;
224 sa.sa_flags = SA_SIGINFO;
225 if (sigaction(SIGSEGV, &sa, NULL))
226 return 1;
227
228 segv_triggered = false;
229
230 /* Make sure segv_triggered is set before violate_ss() */
231 asm volatile("" : : : "memory");
232
233 violate_ss();
234
235 signal(SIGSEGV, SIG_DFL);
236
237 printf("[OK]\tShadow stack violation test\n");
238
239 return !segv_triggered;
240}
241
242/* Gup test state */
243#define MAGIC_VAL 0x12345678
244bool is_shstk_access;
245void *shstk_ptr;
246int fd;
247
248void reset_test_shstk(void *addr)
249{
250 if (shstk_ptr)
251 free_shstk(shstk_ptr);
252 shstk_ptr = create_shstk(addr);
253}
254
255void test_access_fix_handler(int signum, siginfo_t *si, void *uc)
256{
257 printf("[INFO]\tViolation from %s\n", is_shstk_access ? "shstk access" : "normal write");
258
259 segv_triggered = true;
260
261 /* Fix shadow stack */
262 if (is_shstk_access) {
263 reset_test_shstk(shstk_ptr);
264 return;
265 }
266
267 free_shstk(shstk_ptr);
268 create_normal_mem(shstk_ptr);
269}
270
271bool test_shstk_access(void *ptr)
272{
273 is_shstk_access = true;
274 segv_triggered = false;
275 write_shstk(ptr, MAGIC_VAL);
276
277 asm volatile("" : : : "memory");
278
279 return segv_triggered;
280}
281
282bool test_write_access(void *ptr)
283{
284 is_shstk_access = false;
285 segv_triggered = false;
286 *(unsigned long *)ptr = MAGIC_VAL;
287
288 asm volatile("" : : : "memory");
289
290 return segv_triggered;
291}
292
293bool gup_write(void *ptr)
294{
295 unsigned long val;
296
297 lseek(fd, (unsigned long)ptr, SEEK_SET);
298 if (write(fd, &val, sizeof(val)) < 0)
299 return 1;
300
301 return 0;
302}
303
304bool gup_read(void *ptr)
305{
306 unsigned long val;
307
308 lseek(fd, (unsigned long)ptr, SEEK_SET);
309 if (read(fd, &val, sizeof(val)) < 0)
310 return 1;
311
312 return 0;
313}
314
315int test_gup(void)
316{
317 struct sigaction sa = {};
318 int status;
319 pid_t pid;
320
321 sa.sa_sigaction = test_access_fix_handler;
322 sa.sa_flags = SA_SIGINFO;
323 if (sigaction(SIGSEGV, &sa, NULL))
324 return 1;
325
326 segv_triggered = false;
327
328 fd = open("/proc/self/mem", O_RDWR);
329 if (fd == -1)
330 return 1;
331
332 reset_test_shstk(0);
333 if (gup_read(shstk_ptr))
334 return 1;
335 if (test_shstk_access(shstk_ptr))
336 return 1;
337 printf("[INFO]\tGup read -> shstk access success\n");
338
339 reset_test_shstk(0);
340 if (gup_write(shstk_ptr))
341 return 1;
342 if (test_shstk_access(shstk_ptr))
343 return 1;
344 printf("[INFO]\tGup write -> shstk access success\n");
345
346 reset_test_shstk(0);
347 if (gup_read(shstk_ptr))
348 return 1;
349 if (!test_write_access(shstk_ptr))
350 return 1;
351 printf("[INFO]\tGup read -> write access success\n");
352
353 reset_test_shstk(0);
354 if (gup_write(shstk_ptr))
355 return 1;
356 if (!test_write_access(shstk_ptr))
357 return 1;
358 printf("[INFO]\tGup write -> write access success\n");
359
360 close(fd);
361
362 /* COW/gup test */
363 reset_test_shstk(0);
364 pid = fork();
365 if (!pid) {
366 fd = open("/proc/self/mem", O_RDWR);
367 if (fd == -1)
368 exit(1);
369
370 if (gup_write(shstk_ptr)) {
371 close(fd);
372 exit(1);
373 }
374 close(fd);
375 exit(0);
376 }
377 waitpid(pid, &status, 0);
378 if (WEXITSTATUS(status)) {
379 printf("[FAIL]\tWrite in child failed\n");
380 return 1;
381 }
382 if (*(unsigned long *)shstk_ptr == MAGIC_VAL) {
383 printf("[FAIL]\tWrite in child wrote through to shared memory\n");
384 return 1;
385 }
386
387 printf("[INFO]\tCow gup write -> write access success\n");
388
389 free_shstk(shstk_ptr);
390
391 signal(SIGSEGV, SIG_DFL);
392
393 printf("[OK]\tShadow gup test\n");
394
395 return 0;
396}
397
398int test_mprotect(void)
399{
400 struct sigaction sa = {};
401
402 sa.sa_sigaction = test_access_fix_handler;
403 sa.sa_flags = SA_SIGINFO;
404 if (sigaction(SIGSEGV, &sa, NULL))
405 return 1;
406
407 segv_triggered = false;
408
409 /* mprotect a shadow stack as read only */
410 reset_test_shstk(0);
411 if (mprotect(shstk_ptr, SS_SIZE, PROT_READ) < 0) {
412 printf("[FAIL]\tmprotect(PROT_READ) failed\n");
413 return 1;
414 }
415
416 /* try to wrss it and fail */
417 if (!test_shstk_access(shstk_ptr)) {
418 printf("[FAIL]\tShadow stack access to read-only memory succeeded\n");
419 return 1;
420 }
421
422 /*
423 * The shadow stack was reset above to resolve the fault, make the new one
424 * read-only.
425 */
426 if (mprotect(shstk_ptr, SS_SIZE, PROT_READ) < 0) {
427 printf("[FAIL]\tmprotect(PROT_READ) failed\n");
428 return 1;
429 }
430
431 /* then back to writable */
432 if (mprotect(shstk_ptr, SS_SIZE, PROT_WRITE | PROT_READ) < 0) {
433 printf("[FAIL]\tmprotect(PROT_WRITE) failed\n");
434 return 1;
435 }
436
437 /* then wrss to it and succeed */
438 if (test_shstk_access(shstk_ptr)) {
439 printf("[FAIL]\tShadow stack access to mprotect() writable memory failed\n");
440 return 1;
441 }
442
443 free_shstk(shstk_ptr);
444
445 signal(SIGSEGV, SIG_DFL);
446
447 printf("[OK]\tmprotect() test\n");
448
449 return 0;
450}
451
452char zero[4096];
453
454static void *uffd_thread(void *arg)
455{
456 struct uffdio_copy req;
457 int uffd = *(int *)arg;
458 struct uffd_msg msg;
459 int ret;
460
461 while (1) {
462 ret = read(uffd, &msg, sizeof(msg));
463 if (ret > 0)
464 break;
465 else if (errno == EAGAIN)
466 continue;
467 return (void *)1;
468 }
469
470 req.dst = msg.arg.pagefault.address;
471 req.src = (__u64)zero;
472 req.len = 4096;
473 req.mode = 0;
474
475 if (ioctl(uffd, UFFDIO_COPY, &req))
476 return (void *)1;
477
478 return (void *)0;
479}
480
481int test_userfaultfd(void)
482{
483 struct uffdio_register uffdio_register;
484 struct uffdio_api uffdio_api;
485 struct sigaction sa = {};
486 pthread_t thread;
487 void *res;
488 int uffd;
489
490 sa.sa_sigaction = test_access_fix_handler;
491 sa.sa_flags = SA_SIGINFO;
492 if (sigaction(SIGSEGV, &sa, NULL))
493 return 1;
494
495 uffd = syscall(__NR_userfaultfd, O_CLOEXEC | O_NONBLOCK);
496 if (uffd < 0) {
497 printf("[SKIP]\tUserfaultfd unavailable.\n");
498 return 0;
499 }
500
501 reset_test_shstk(0);
502
503 uffdio_api.api = UFFD_API;
504 uffdio_api.features = 0;
505 if (ioctl(uffd, UFFDIO_API, &uffdio_api))
506 goto err;
507
508 uffdio_register.range.start = (__u64)shstk_ptr;
509 uffdio_register.range.len = 4096;
510 uffdio_register.mode = UFFDIO_REGISTER_MODE_MISSING;
511 if (ioctl(uffd, UFFDIO_REGISTER, &uffdio_register))
512 goto err;
513
514 if (pthread_create(&thread, NULL, &uffd_thread, &uffd))
515 goto err;
516
517 reset_shstk(shstk_ptr);
518 test_shstk_access(shstk_ptr);
519
520 if (pthread_join(thread, &res))
521 goto err;
522
523 if (test_shstk_access(shstk_ptr))
524 goto err;
525
526 free_shstk(shstk_ptr);
527
528 signal(SIGSEGV, SIG_DFL);
529
530 if (!res)
531 printf("[OK]\tUserfaultfd test\n");
532 return !!res;
533err:
534 free_shstk(shstk_ptr);
535 close(uffd);
536 signal(SIGSEGV, SIG_DFL);
537 return 1;
538}
539
540/* Simple linked list for keeping track of mappings in test_guard_gap() */
541struct node {
542 struct node *next;
543 void *mapping;
544};
545
546/*
547 * This tests whether mmap will place other mappings in a shadow stack's guard
548 * gap. The steps are:
549 * 1. Finds an empty place by mapping and unmapping something.
550 * 2. Map a shadow stack in the middle of the known empty area.
551 * 3. Map a bunch of PAGE_SIZE mappings. These will use the search down
552 * direction, filling any gaps until it encounters the shadow stack's
553 * guard gap.
554 * 4. When a mapping lands below the shadow stack from step 2, then all
555 * of the above gaps are filled. The search down algorithm will have
556 * looked at the shadow stack gaps.
557 * 5. See if it landed in the gap.
558 */
559int test_guard_gap_other_gaps(void)
560{
561 void *free_area, *shstk, *test_map = (void *)0xFFFFFFFFFFFFFFFF;
562 struct node *head = NULL, *cur;
563
564 free_area = mmap(0, SS_SIZE * 3, PROT_READ | PROT_WRITE,
565 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
566 munmap(free_area, SS_SIZE * 3);
567
568 shstk = create_shstk(free_area + SS_SIZE);
569 if (shstk == MAP_FAILED)
570 return 1;
571
572 while (test_map > shstk) {
573 test_map = mmap(0, PAGE_SIZE, PROT_READ | PROT_WRITE,
574 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
575 if (test_map == MAP_FAILED)
576 return 1;
577 cur = malloc(sizeof(*cur));
578 cur->mapping = test_map;
579
580 cur->next = head;
581 head = cur;
582 }
583
584 while (head) {
585 cur = head;
586 head = cur->next;
587 munmap(cur->mapping, PAGE_SIZE);
588 free(cur);
589 }
590
591 free_shstk(shstk);
592
593 if (shstk - test_map - PAGE_SIZE != PAGE_SIZE)
594 return 1;
595
596 printf("[OK]\tGuard gap test, other mapping's gaps\n");
597
598 return 0;
599}
600
601/* Tests respecting the guard gap of the mapping getting placed */
602int test_guard_gap_new_mappings_gaps(void)
603{
604 void *free_area, *shstk_start, *test_map = (void *)0xFFFFFFFFFFFFFFFF;
605 struct node *head = NULL, *cur;
606 int ret = 0;
607
608 free_area = mmap(0, PAGE_SIZE * 4, PROT_READ | PROT_WRITE,
609 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
610 munmap(free_area, PAGE_SIZE * 4);
611
612 /* Test letting map_shadow_stack find a free space */
613 shstk_start = mmap(free_area, PAGE_SIZE, PROT_READ | PROT_WRITE,
614 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
615 if (shstk_start == MAP_FAILED || shstk_start != free_area)
616 return 1;
617
618 while (test_map > shstk_start) {
619 test_map = (void *)syscall(__NR_map_shadow_stack, 0, PAGE_SIZE, 0);
620 if (test_map == MAP_FAILED) {
621 printf("[INFO]\tmap_shadow_stack MAP_FAILED\n");
622 ret = 1;
623 break;
624 }
625
626 cur = malloc(sizeof(*cur));
627 cur->mapping = test_map;
628
629 cur->next = head;
630 head = cur;
631
632 if (test_map == free_area + PAGE_SIZE) {
633 printf("[INFO]\tNew mapping has other mapping in guard gap!\n");
634 ret = 1;
635 break;
636 }
637 }
638
639 while (head) {
640 cur = head;
641 head = cur->next;
642 munmap(cur->mapping, PAGE_SIZE);
643 free(cur);
644 }
645
646 munmap(shstk_start, PAGE_SIZE);
647
648 if (!ret)
649 printf("[OK]\tGuard gap test, placement mapping's gaps\n");
650
651 return ret;
652}
653
654/*
655 * Too complicated to pull it out of the 32 bit header, but also get the
656 * 64 bit one needed above. Just define a copy here.
657 */
658#define __NR_compat_sigaction 67
659
660/*
661 * Call 32 bit signal handler to get 32 bit signals ABI. Make sure
662 * to push the registers that will get clobbered.
663 */
664int sigaction32(int signum, const struct sigaction *restrict act,
665 struct sigaction *restrict oldact)
666{
667 register long syscall_reg asm("eax") = __NR_compat_sigaction;
668 register long signum_reg asm("ebx") = signum;
669 register long act_reg asm("ecx") = (long)act;
670 register long oldact_reg asm("edx") = (long)oldact;
671 int ret = 0;
672
673 asm volatile ("int $0x80;"
674 : "=a"(ret), "=m"(oldact)
675 : "r"(syscall_reg), "r"(signum_reg), "r"(act_reg),
676 "r"(oldact_reg)
677 : "r8", "r9", "r10", "r11"
678 );
679
680 return ret;
681}
682
683sigjmp_buf jmp_buffer;
684
685void segv_gp_handler(int signum, siginfo_t *si, void *uc)
686{
687 segv_triggered = true;
688
689 /*
690 * To work with old glibc, this can't rely on siglongjmp working with
691 * shadow stack enabled, so disable shadow stack before siglongjmp().
692 */
693 ARCH_PRCTL(ARCH_SHSTK_DISABLE, ARCH_SHSTK_SHSTK);
694 siglongjmp(jmp_buffer, -1);
695}
696
697/*
698 * Transition to 32 bit mode and check that a #GP triggers a segfault.
699 */
700int test_32bit(void)
701{
702 struct sigaction sa = {};
703 struct sigaction *sa32;
704
705 /* Create sigaction in 32 bit address range */
706 sa32 = mmap(0, 4096, PROT_READ | PROT_WRITE,
707 MAP_32BIT | MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
708 sa32->sa_flags = SA_SIGINFO;
709
710 sa.sa_sigaction = segv_gp_handler;
711 sa.sa_flags = SA_SIGINFO;
712 if (sigaction(SIGSEGV, &sa, NULL))
713 return 1;
714
715
716 segv_triggered = false;
717
718 /* Make sure segv_triggered is set before triggering the #GP */
719 asm volatile("" : : : "memory");
720
721 /*
722 * Set handler to somewhere in 32 bit address space
723 */
724 sa32->sa_handler = (void *)sa32;
725 if (sigaction32(SIGUSR1, sa32, NULL))
726 return 1;
727
728 if (!sigsetjmp(jmp_buffer, 1))
729 raise(SIGUSR1);
730
731 if (segv_triggered)
732 printf("[OK]\t32 bit test\n");
733
734 return !segv_triggered;
735}
736
737void segv_handler_ptrace(int signum, siginfo_t *si, void *uc)
738{
739 /* The SSP adjustment caused a segfault. */
740 exit(0);
741}
742
743int test_ptrace(void)
744{
745 unsigned long saved_ssp, ssp = 0;
746 struct sigaction sa= {};
747 struct iovec iov;
748 int status;
749 int pid;
750
751 iov.iov_base = &ssp;
752 iov.iov_len = sizeof(ssp);
753
754 pid = fork();
755 if (!pid) {
756 ssp = get_ssp();
757
758 sa.sa_sigaction = segv_handler_ptrace;
759 sa.sa_flags = SA_SIGINFO;
760 if (sigaction(SIGSEGV, &sa, NULL))
761 return 1;
762
763 ptrace(PTRACE_TRACEME, NULL, NULL, NULL);
764 /*
765 * The parent will tweak the SSP and return from this function
766 * will #CP.
767 */
768 raise(SIGTRAP);
769
770 exit(1);
771 }
772
773 while (waitpid(pid, &status, 0) != -1 && WSTOPSIG(status) != SIGTRAP);
774
775 if (ptrace(PTRACE_GETREGSET, pid, NT_X86_SHSTK, &iov)) {
776 printf("[INFO]\tFailed to PTRACE_GETREGS\n");
777 goto out_kill;
778 }
779
780 if (!ssp) {
781 printf("[INFO]\tPtrace child SSP was 0\n");
782 goto out_kill;
783 }
784
785 saved_ssp = ssp;
786
787 iov.iov_len = 0;
788 if (!ptrace(PTRACE_SETREGSET, pid, NT_X86_SHSTK, &iov)) {
789 printf("[INFO]\tToo small size accepted via PTRACE_SETREGS\n");
790 goto out_kill;
791 }
792
793 iov.iov_len = sizeof(ssp) + 1;
794 if (!ptrace(PTRACE_SETREGSET, pid, NT_X86_SHSTK, &iov)) {
795 printf("[INFO]\tToo large size accepted via PTRACE_SETREGS\n");
796 goto out_kill;
797 }
798
799 ssp += 1;
800 if (!ptrace(PTRACE_SETREGSET, pid, NT_X86_SHSTK, &iov)) {
801 printf("[INFO]\tUnaligned SSP written via PTRACE_SETREGS\n");
802 goto out_kill;
803 }
804
805 ssp = 0xFFFFFFFFFFFF0000;
806 if (!ptrace(PTRACE_SETREGSET, pid, NT_X86_SHSTK, &iov)) {
807 printf("[INFO]\tKernel range SSP written via PTRACE_SETREGS\n");
808 goto out_kill;
809 }
810
811 /*
812 * Tweak the SSP so the child with #CP when it resumes and returns
813 * from raise()
814 */
815 ssp = saved_ssp + 8;
816 iov.iov_len = sizeof(ssp);
817 if (ptrace(PTRACE_SETREGSET, pid, NT_X86_SHSTK, &iov)) {
818 printf("[INFO]\tFailed to PTRACE_SETREGS\n");
819 goto out_kill;
820 }
821
822 if (ptrace(PTRACE_DETACH, pid, NULL, NULL)) {
823 printf("[INFO]\tFailed to PTRACE_DETACH\n");
824 goto out_kill;
825 }
826
827 waitpid(pid, &status, 0);
828 if (WEXITSTATUS(status))
829 return 1;
830
831 printf("[OK]\tPtrace test\n");
832 return 0;
833
834out_kill:
835 kill(pid, SIGKILL);
836 return 1;
837}
838
839int main(int argc, char *argv[])
840{
841 int ret = 0;
842
843 if (ARCH_PRCTL(ARCH_SHSTK_ENABLE, ARCH_SHSTK_SHSTK)) {
844 printf("[SKIP]\tCould not enable Shadow stack\n");
845 return 1;
846 }
847
848 if (ARCH_PRCTL(ARCH_SHSTK_DISABLE, ARCH_SHSTK_SHSTK)) {
849 ret = 1;
850 printf("[FAIL]\tDisabling shadow stack failed\n");
851 }
852
853 if (ARCH_PRCTL(ARCH_SHSTK_ENABLE, ARCH_SHSTK_SHSTK)) {
854 printf("[SKIP]\tCould not re-enable Shadow stack\n");
855 return 1;
856 }
857
858 if (ARCH_PRCTL(ARCH_SHSTK_ENABLE, ARCH_SHSTK_WRSS)) {
859 printf("[SKIP]\tCould not enable WRSS\n");
860 ret = 1;
861 goto out;
862 }
863
864 /* Should have succeeded if here, but this is a test, so double check. */
865 if (!get_ssp()) {
866 printf("[FAIL]\tShadow stack disabled\n");
867 return 1;
868 }
869
870 if (test_shstk_pivot()) {
871 ret = 1;
872 printf("[FAIL]\tShadow stack pivot\n");
873 goto out;
874 }
875
876 if (test_shstk_faults()) {
877 ret = 1;
878 printf("[FAIL]\tShadow stack fault test\n");
879 goto out;
880 }
881
882 if (test_shstk_violation()) {
883 ret = 1;
884 printf("[FAIL]\tShadow stack violation test\n");
885 goto out;
886 }
887
888 if (test_gup()) {
889 ret = 1;
890 printf("[FAIL]\tShadow shadow stack gup\n");
891 goto out;
892 }
893
894 if (test_mprotect()) {
895 ret = 1;
896 printf("[FAIL]\tShadow shadow mprotect test\n");
897 goto out;
898 }
899
900 if (test_userfaultfd()) {
901 ret = 1;
902 printf("[FAIL]\tUserfaultfd test\n");
903 goto out;
904 }
905
906 if (test_guard_gap_other_gaps()) {
907 ret = 1;
908 printf("[FAIL]\tGuard gap test, other mappings' gaps\n");
909 goto out;
910 }
911
912 if (test_guard_gap_new_mappings_gaps()) {
913 ret = 1;
914 printf("[FAIL]\tGuard gap test, placement mapping's gaps\n");
915 goto out;
916 }
917
918 if (test_ptrace()) {
919 ret = 1;
920 printf("[FAIL]\tptrace test\n");
921 }
922
923 if (test_32bit()) {
924 ret = 1;
925 printf("[FAIL]\t32 bit test\n");
926 goto out;
927 }
928
929 return ret;
930
931out:
932 /*
933 * Disable shadow stack before the function returns, or there will be a
934 * shadow stack violation.
935 */
936 if (ARCH_PRCTL(ARCH_SHSTK_DISABLE, ARCH_SHSTK_SHSTK)) {
937 ret = 1;
938 printf("[FAIL]\tDisabling shadow stack failed\n");
939 }
940
941 return ret;
942}
943#endif