]> git.saurik.com Git - apple/xnu.git/blob - tests/vm_test_code_signing_helper.c
xnu-7195.101.1.tar.gz
[apple/xnu.git] / tests / vm_test_code_signing_helper.c
1 #include <TargetConditionals.h>
2 #include <errno.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <unistd.h>
7
8 #if __has_include(<ptrauth.h>)
9 #include <ptrauth.h>
10 #endif
11
12 #include <sys/mman.h>
13 #include <sys/syslimits.h>
14
15 char *cmdname;
16
17 int
18 main(
19 int argc,
20 char *argv[])
21 {
22 uint32_t page_size;
23 void *page;
24 int ch;
25 int opt_interactive;
26
27 cmdname = argv[0];
28
29 opt_interactive = 0;
30 while ((ch = getopt(argc, argv, "i")) != -1) {
31 switch (ch) {
32 case 'i':
33 opt_interactive = 1;
34 break;
35 case '?':
36 default:
37 fprintf(stdout,
38 "Usage: %s [-i]\n"
39 "\t-i: interactive\n",
40 cmdname);
41 exit(1);
42 }
43 }
44
45 page_size = getpagesize();
46 page = mmap(NULL, page_size, PROT_READ | PROT_EXEC, MAP_ANON | MAP_SHARED, -1, 0);
47 if (!page) {
48 fprintf(stderr, "%s:%d mmap() error %d (%s)\n",
49 cmdname, __LINE__,
50 errno, strerror(errno));
51 exit(1);
52 }
53 if (opt_interactive) {
54 fprintf(stdout, "allocated page at %p\n",
55 page);
56 }
57
58 if (mprotect(page, page_size, PROT_READ | PROT_WRITE) != 0) {
59 fprintf(stderr, "%s:%d mprotect(RW) error %d (%s)\n",
60 cmdname, __LINE__,
61 errno, strerror(errno));
62 exit(1);
63 }
64
65 #if __arm64__
66 // arm64 chdir() syscall
67 char chdir_code[] = {
68 0x90, 0x01, 0x80, 0xd2, // movz x16, #0xc
69 0x01, 0x10, 0x00, 0xd4, // svc #0x80
70 0xc0, 0x03, 0x5f, 0xd6, // ret
71 };
72 #elif __arm__
73 // armv7 chdir() syscall
74 char chdir_code[] = {
75 0x0c, 0xc0, 0xa0, 0xe3, // mov r12 #0xc
76 0x80, 0x00, 0x00, 0xef, // svc #0x80
77 0x1e, 0xff, 0x2f, 0xe1, // bx lr
78 };
79 #elif __x86_64__
80 // x86_64 chdir() syscall
81 char chdir_code[] = {
82 0xb8, 0x0c, 0x00, 0x00, 0x02, // movl $0x200000c, %eax
83 0x49, 0x89, 0xca, // movq %rcx, %r10
84 0x0f, 0x05, // syscall
85 0xc3, // retq
86 };
87 #elif __i386__
88 // i386 chdir() syscall
89 char chdir_code[] = {
90 0x90, // nop
91 0xc3, // retq
92 };
93 #endif
94 memcpy(page, chdir_code, sizeof chdir_code);
95
96 if (opt_interactive) {
97 fprintf(stdout,
98 "changed page protection to r/w and copied code at %p\n",
99 page);
100 fprintf(stdout, "pausing...\n");
101 fflush(stdout);
102 getchar();
103 }
104
105 if (mprotect(page, page_size, PROT_READ | PROT_EXEC) != 0) {
106 fprintf(stderr, "%s:%d mprotect(RX) error %d (%s)\n",
107 cmdname, __LINE__,
108 errno, strerror(errno));
109 exit(1);
110 }
111
112 if (opt_interactive) {
113 fprintf(stdout,
114 "changed page protection to r/x at %p\n",
115 page);
116 fprintf(stdout, "pausing...\n");
117 fflush(stdout);
118 getchar();
119 }
120
121 char origdir[PATH_MAX];
122 getcwd(origdir, sizeof(origdir) - 1);
123
124 chdir("/");
125 if (opt_interactive) {
126 fprintf(stdout, "cwd before = %s\n", getwd(NULL));
127 }
128
129 void (*mychdir)(char *) = page;
130 #if __has_feature(ptrauth_calls)
131 mychdir = ptrauth_sign_unauthenticated(mychdir, ptrauth_key_function_pointer, 0);
132 #endif
133 mychdir(getenv("HOME"));
134 if (opt_interactive) {
135 fprintf(stdout, "cwd after = %s\n", getwd(NULL));
136 fprintf(stdout, "pausing...\n");
137 fflush(stdout);
138 getchar();
139 }
140
141 fprintf(stdout, "%s: WARNING: unsigned code was executed\n",
142 cmdname);
143
144 #if !TARGET_OS_OSX
145 /* fail: unsigned code was executed */
146 fprintf(stdout, "%s: FAIL\n", cmdname);
147 exit(1);
148 #else /* !TARGET_OS_OSX */
149 /* no fail: unsigned code is only prohibited on embedded platforms */
150 fprintf(stdout, "%s: SUCCESS\n", cmdname);
151 exit(0);
152 #endif /* !TARGET_OS_OSX */
153 }