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