xref: /xnu-8792.81.2/tests/codesigntests.c (revision 19c3b8c28c31cb8130e034cfb5df6bf9ba342d90)
1*19c3b8c2SApple OSS Distributions #include <darwintest.h>
2*19c3b8c2SApple OSS Distributions #include <stdint.h>
3*19c3b8c2SApple OSS Distributions #include <bsm/libbsm.h>
4*19c3b8c2SApple OSS Distributions #include <System/sys/codesign.h>
5*19c3b8c2SApple OSS Distributions #include <sys/errno.h>
6*19c3b8c2SApple OSS Distributions #include <stdio.h>
7*19c3b8c2SApple OSS Distributions #include <unistd.h>
8*19c3b8c2SApple OSS Distributions 
9*19c3b8c2SApple OSS Distributions #define MAXBUFLEN 1024 * 1024
10*19c3b8c2SApple OSS Distributions 
11*19c3b8c2SApple OSS Distributions T_GLOBAL_META(
12*19c3b8c2SApple OSS Distributions 	T_META_NAMESPACE("xnu.codesigning"),
13*19c3b8c2SApple OSS Distributions 	T_META_RADAR_COMPONENT_NAME("xnu"),
14*19c3b8c2SApple OSS Distributions 	T_META_RADAR_COMPONENT_VERSION("codesigning"),
15*19c3b8c2SApple OSS Distributions 	T_META_OWNER("rkendallkuppe"));
16*19c3b8c2SApple OSS Distributions 
17*19c3b8c2SApple OSS Distributions int
get_blob(pid_t pid,int op)18*19c3b8c2SApple OSS Distributions get_blob(pid_t pid, int op)
19*19c3b8c2SApple OSS Distributions {
20*19c3b8c2SApple OSS Distributions 	uint8_t header[8];
21*19c3b8c2SApple OSS Distributions 	unsigned int cnt;
22*19c3b8c2SApple OSS Distributions 	int rcent;
23*19c3b8c2SApple OSS Distributions 
24*19c3b8c2SApple OSS Distributions 	for (cnt = 0; cnt < sizeof(header); cnt++) {
25*19c3b8c2SApple OSS Distributions 		rcent = csops(pid, op, header, cnt);
26*19c3b8c2SApple OSS Distributions 		if (rcent != -1 && errno != ERANGE) {
27*19c3b8c2SApple OSS Distributions 			T_ASSERT_FAIL("errno != ERANGE for short header");
28*19c3b8c2SApple OSS Distributions 		}
29*19c3b8c2SApple OSS Distributions 	}
30*19c3b8c2SApple OSS Distributions 
31*19c3b8c2SApple OSS Distributions 	rcent = csops(pid, op, header, sizeof(header));
32*19c3b8c2SApple OSS Distributions 	if (rcent == -1 && errno == ERANGE) {
33*19c3b8c2SApple OSS Distributions 		uint32_t len, bufferlen, bufferlen2;
34*19c3b8c2SApple OSS Distributions 
35*19c3b8c2SApple OSS Distributions 		memcpy(&len, &header[4], 4);
36*19c3b8c2SApple OSS Distributions 		bufferlen = ntohl(len);
37*19c3b8c2SApple OSS Distributions 
38*19c3b8c2SApple OSS Distributions 		T_LOG("Checking bufferlen on blob from kernel for csop %d", op);
39*19c3b8c2SApple OSS Distributions 		T_ASSERT_LE_INT(bufferlen, MAXBUFLEN, "Buffer length %zu on blob from kernel can't exceed %zu",
40*19c3b8c2SApple OSS Distributions 		    (size_t)bufferlen, MAXBUFLEN);
41*19c3b8c2SApple OSS Distributions 		T_ASSERT_NE_INT(bufferlen, 0, "Buffer length %zu on blob from kernel can't be zero",
42*19c3b8c2SApple OSS Distributions 		    (size_t)bufferlen);
43*19c3b8c2SApple OSS Distributions 		T_ASSERT_GE_INT(bufferlen, 8, "Buffer length %zu on blob from kernel can't be less than a byte",
44*19c3b8c2SApple OSS Distributions 		    (size_t)bufferlen);
45*19c3b8c2SApple OSS Distributions 
46*19c3b8c2SApple OSS Distributions 		uint8_t buffer[bufferlen + 1];
47*19c3b8c2SApple OSS Distributions 
48*19c3b8c2SApple OSS Distributions 		rcent = csops(pid, op, buffer, bufferlen - 1);
49*19c3b8c2SApple OSS Distributions 		T_ASSERT_POSIX_ERROR(errno, ERANGE, "Performing CS OPS csops with a full buffer - 1");
50*19c3b8c2SApple OSS Distributions 
51*19c3b8c2SApple OSS Distributions 		rcent = csops(pid, op, buffer, bufferlen);
52*19c3b8c2SApple OSS Distributions 		T_ASSERT_EQ_INT(rcent, 0, "Performing CS OPS with full buffer.");
53*19c3b8c2SApple OSS Distributions 
54*19c3b8c2SApple OSS Distributions 		memcpy(&len, &buffer[4], 4);
55*19c3b8c2SApple OSS Distributions 		bufferlen2 = ntohl(len);
56*19c3b8c2SApple OSS Distributions 
57*19c3b8c2SApple OSS Distributions 		if (op == CS_OPS_BLOB) {
58*19c3b8c2SApple OSS Distributions 			T_ASSERT_LE_INT(bufferlen2, bufferlen, "Checking %zu is %zu larger on second try",
59*19c3b8c2SApple OSS Distributions 			    (size_t)bufferlen2, (size_t)bufferlen);
60*19c3b8c2SApple OSS Distributions 
61*19c3b8c2SApple OSS Distributions 			/*
62*19c3b8c2SApple OSS Distributions 			 * CS_OPS_BLOB may want a bigger buffer than the size
63*19c3b8c2SApple OSS Distributions 			 * of the actual blob. If the blob came in through a
64*19c3b8c2SApple OSS Distributions 			 * load command for example, then CS_OPS_BLOB will
65*19c3b8c2SApple OSS Distributions 			 * want to copy out the whole buffer that the load
66*19c3b8c2SApple OSS Distributions 			 * command points to, which is usually an estimated
67*19c3b8c2SApple OSS Distributions 			 * size. The actual blob, and therefore the size in
68*19c3b8c2SApple OSS Distributions 			 * the blob's header, may be smaller.
69*19c3b8c2SApple OSS Distributions 			 */
70*19c3b8c2SApple OSS Distributions 			T_LOG("Blob is smaller (%zu) than expected (%zu). This is fine.",
71*19c3b8c2SApple OSS Distributions 			    (size_t)bufferlen2, (size_t)bufferlen);
72*19c3b8c2SApple OSS Distributions 		} else {
73*19c3b8c2SApple OSS Distributions 			T_ASSERT_EQ_INT(bufferlen2, bufferlen, "Checking bufferlen sizes are different");
74*19c3b8c2SApple OSS Distributions 		}
75*19c3b8c2SApple OSS Distributions 
76*19c3b8c2SApple OSS Distributions 		rcent = csops(pid, op, buffer, bufferlen + 1);
77*19c3b8c2SApple OSS Distributions 		T_ASSERT_EQ_INT(rcent, 0, "Performing CS OPS with a full buffer + 1");
78*19c3b8c2SApple OSS Distributions 
79*19c3b8c2SApple OSS Distributions 		return 0;
80*19c3b8c2SApple OSS Distributions 	} else if (rcent == 0) {
81*19c3b8c2SApple OSS Distributions 		return 0;
82*19c3b8c2SApple OSS Distributions 	} else {
83*19c3b8c2SApple OSS Distributions 		return 1;
84*19c3b8c2SApple OSS Distributions 	}
85*19c3b8c2SApple OSS Distributions }
86*19c3b8c2SApple OSS Distributions 
87*19c3b8c2SApple OSS Distributions /*
88*19c3b8c2SApple OSS Distributions  *  This source is compiled with different names and build flags.
89*19c3b8c2SApple OSS Distributions  *  Makefile has the detail of the TESTNAME.
90*19c3b8c2SApple OSS Distributions  */
91*19c3b8c2SApple OSS Distributions 
92*19c3b8c2SApple OSS Distributions T_DECL(TESTNAME, "CS OP, code sign operations test")
93*19c3b8c2SApple OSS Distributions {
94*19c3b8c2SApple OSS Distributions 	uint32_t status;
95*19c3b8c2SApple OSS Distributions 	int rcent;
96*19c3b8c2SApple OSS Distributions 	pid_t pid;
97*19c3b8c2SApple OSS Distributions 
98*19c3b8c2SApple OSS Distributions 	pid = getpid();
99*19c3b8c2SApple OSS Distributions 
100*19c3b8c2SApple OSS Distributions 
101*19c3b8c2SApple OSS Distributions 	rcent = get_blob(pid, CS_OPS_ENTITLEMENTS_BLOB);
102*19c3b8c2SApple OSS Distributions 	T_ASSERT_EQ_INT(rcent, 0, "Getting CS OPS entitlements blob");
103*19c3b8c2SApple OSS Distributions 
104*19c3b8c2SApple OSS Distributions 	rcent = get_blob(0, CS_OPS_ENTITLEMENTS_BLOB);
105*19c3b8c2SApple OSS Distributions 	T_ASSERT_EQ_INT(rcent, 0, "Getting CS OPS entitlements blob");
106*19c3b8c2SApple OSS Distributions 
107*19c3b8c2SApple OSS Distributions 	rcent = get_blob(pid, CS_OPS_BLOB);
108*19c3b8c2SApple OSS Distributions 
109*19c3b8c2SApple OSS Distributions 	T_ASSERT_EQ_INT(rcent, 0, "Getting CS OPS blob");
110*19c3b8c2SApple OSS Distributions 
111*19c3b8c2SApple OSS Distributions 	rcent = get_blob(0, CS_OPS_BLOB);
112*19c3b8c2SApple OSS Distributions 	T_ASSERT_EQ_INT(rcent, 0, "Getting CS OPS blob");
113*19c3b8c2SApple OSS Distributions 
114*19c3b8c2SApple OSS Distributions 	rcent = get_blob(pid, CS_OPS_IDENTITY);
115*19c3b8c2SApple OSS Distributions 	T_ASSERT_EQ_INT(rcent, 0, "Getting CS OPs identity");
116*19c3b8c2SApple OSS Distributions 
117*19c3b8c2SApple OSS Distributions 	rcent = get_blob(0, CS_OPS_IDENTITY);
118*19c3b8c2SApple OSS Distributions 	T_ASSERT_EQ_INT(rcent, 0, "Getting CS OPs identity");
119*19c3b8c2SApple OSS Distributions 
120*19c3b8c2SApple OSS Distributions 	rcent = csops(pid, CS_OPS_SET_STATUS, &status, sizeof(status) - 1);
121*19c3b8c2SApple OSS Distributions 	T_ASSERT_NE_INT(rcent, 0, "Checking CS OPs set status by setting buffer to (status - 1)");
122*19c3b8c2SApple OSS Distributions 
123*19c3b8c2SApple OSS Distributions 	status = CS_RESTRICT;
124*19c3b8c2SApple OSS Distributions 	rcent = csops(pid, CS_OPS_SET_STATUS, &status, sizeof(status));
125*19c3b8c2SApple OSS Distributions 	T_ASSERT_EQ_INT(rcent, 0, "Checking CS OPs set status by setting proc RESTRICTED");
126*19c3b8c2SApple OSS Distributions 
127*19c3b8c2SApple OSS Distributions 	rcent = csops(pid, CS_OPS_STATUS, &status, sizeof(status));
128*19c3b8c2SApple OSS Distributions 	T_ASSERT_EQ_INT(rcent, 0, "Getting CS OPs status of process");
129*19c3b8c2SApple OSS Distributions 
130*19c3b8c2SApple OSS Distributions 	/*
131*19c3b8c2SApple OSS Distributions 	 * Only run the folling tests if not HARD since otherwise
132*19c3b8c2SApple OSS Distributions 	 * we'll just die when marking ourself invalid.
133*19c3b8c2SApple OSS Distributions 	 */
134*19c3b8c2SApple OSS Distributions 
135*19c3b8c2SApple OSS Distributions 	if ((status & CS_KILL) == 0) {
136*19c3b8c2SApple OSS Distributions 		rcent = csops(pid, CS_OPS_MARKINVALID, NULL, 0);
137*19c3b8c2SApple OSS Distributions 		T_ASSERT_POSIX_ZERO(rcent, 0, "Setting CS OPs mark proc invalid");
138*19c3b8c2SApple OSS Distributions 
139*19c3b8c2SApple OSS Distributions 		status = CS_ENFORCEMENT;
140*19c3b8c2SApple OSS Distributions 		rcent = csops(pid, CS_OPS_SET_STATUS, &status, sizeof(status));
141*19c3b8c2SApple OSS Distributions 		T_ASSERT_POSIX_ERROR(rcent, -1, "Managed to set flags on an INVALID proc");
142*19c3b8c2SApple OSS Distributions 
143*19c3b8c2SApple OSS Distributions 		rcent = get_blob(pid, CS_OPS_ENTITLEMENTS_BLOB);
144*19c3b8c2SApple OSS Distributions 		T_ASSERT_POSIX_ERROR(rcent, 1, "Got entitlements while invalid");
145*19c3b8c2SApple OSS Distributions 
146*19c3b8c2SApple OSS Distributions 		rcent = get_blob(pid, CS_OPS_IDENTITY);
147*19c3b8c2SApple OSS Distributions 		T_ASSERT_POSIX_ERROR(rcent, 1, "Getting CS OPS identity");
148*19c3b8c2SApple OSS Distributions 
149*19c3b8c2SApple OSS Distributions 		rcent = get_blob(0, CS_OPS_IDENTITY);
150*19c3b8c2SApple OSS Distributions 		T_ASSERT_POSIX_ERROR(rcent, 1, "Getting CS OPS identity");
151*19c3b8c2SApple OSS Distributions 
152*19c3b8c2SApple OSS Distributions 		rcent = get_blob(0, CS_OPS_BLOB);
153*19c3b8c2SApple OSS Distributions 		T_ASSERT_POSIX_ERROR(rcent, 1, "Geting CS OPS blob");
154*19c3b8c2SApple OSS Distributions 	}
155*19c3b8c2SApple OSS Distributions }
156