master
c 71 lines 1.78 KB
Raw
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2
3 #include "gcs.h"
4
5
6 #define GCSPUSHM "sys #3, c7, c7, #0, %[push]"
7 #define GCSPOPM "sysl %[pop], #3, c7, c7, #1"
8
9 static void test_sigsegv(int sig, siginfo_t *info, void *vuc)
10 {
11 ucontext_t *uc = vuc;
12 uint64_t inst_sigsegv;
13
14 __asm__("adr %0, inst_sigsegv" : "=r"(inst_sigsegv));
15 assert(uc->uc_mcontext.pc == inst_sigsegv);
16 assert(info->si_code == SEGV_CPERR);
17 /* TODO: Dig for ESR and verify syndrome. */
18 uc->uc_mcontext.pc += 4;
19 }
20
21 static void test_sigill(int sig, siginfo_t *info, void *vuc)
22 {
23 ucontext_t *uc = vuc;
24 uint64_t inst_sigill;
25
26 __asm__("adr %0, inst_sigill" : "=r"(inst_sigill));
27 assert(uc->uc_mcontext.pc == inst_sigill);
28 assert(info->si_code == ILL_ILLOPC);
29 uc->uc_mcontext.pc += 4;
30 }
31
32 int main()
33 {
34 struct sigaction sa = { .sa_flags = SA_SIGINFO };
35 uint64_t old, new;
36
37 sa.sa_sigaction = test_sigsegv;
38 if (sigaction(SIGSEGV, &sa, NULL) < 0) {
39 perror("sigaction");
40 exit(1);
41 }
42
43 sa.sa_sigaction = test_sigill;
44 if (sigaction(SIGILL, &sa, NULL) < 0) {
45 perror("sigaction");
46 exit(1);
47 }
48
49 /* Pushm is disabled -- SIGILL via EC_SYSTEMREGISTERTRAP */
50 asm volatile("inst_sigill:\t" GCSPUSHM
51 : : [push] "r" (1));
52
53 enable_gcs(PR_SHADOW_STACK_PUSH);
54
55 /* Valid value -- low 2 bits clear */
56 old = 0xdeadbeeffeedcaec;
57 asm volatile(GCSPUSHM "\n\t" GCSPOPM
58 : [pop] "=r" (new)
59 : [push] "r" (old)
60 : "memory");
61 assert(old == new);
62
63 /* Invalid value -- SIGSEGV via EC_GCS */
64 asm volatile(GCSPUSHM "\n"
65 "inst_sigsegv:\t" GCSPOPM
66 : [pop] "=r" (new)
67 : [push] "r" (1)
68 : "memory");
69
70 exit(0);
71 }