xref: /xnu-10002.81.5/bsd/kern/code_signing/ppl.c (revision 5e3eaea39dcf651e66cb99ba7d70e32cc4a99587)
1*5e3eaea3SApple OSS Distributions /*
2*5e3eaea3SApple OSS Distributions  * Copyright (c) 2022 Apple Computer, Inc. All rights reserved.
3*5e3eaea3SApple OSS Distributions  *
4*5e3eaea3SApple OSS Distributions  * @APPLE_LICENSE_HEADER_START@
5*5e3eaea3SApple OSS Distributions  *
6*5e3eaea3SApple OSS Distributions  * The contents of this file constitute Original Code as defined in and
7*5e3eaea3SApple OSS Distributions  * are subject to the Apple Public Source License Version 1.1 (the
8*5e3eaea3SApple OSS Distributions  * "License").  You may not use this file except in compliance with the
9*5e3eaea3SApple OSS Distributions  * License.  Please obtain a copy of the License at
10*5e3eaea3SApple OSS Distributions  * http://www.apple.com/publicsource and read it before using this file.
11*5e3eaea3SApple OSS Distributions  *
12*5e3eaea3SApple OSS Distributions  * This Original Code and all software distributed under the License are
13*5e3eaea3SApple OSS Distributions  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14*5e3eaea3SApple OSS Distributions  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15*5e3eaea3SApple OSS Distributions  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16*5e3eaea3SApple OSS Distributions  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
17*5e3eaea3SApple OSS Distributions  * License for the specific language governing rights and limitations
18*5e3eaea3SApple OSS Distributions  * under the License.
19*5e3eaea3SApple OSS Distributions  *
20*5e3eaea3SApple OSS Distributions  * @APPLE_LICENSE_HEADER_END@
21*5e3eaea3SApple OSS Distributions  */
22*5e3eaea3SApple OSS Distributions 
23*5e3eaea3SApple OSS Distributions #include <os/overflow.h>
24*5e3eaea3SApple OSS Distributions #include <machine/atomic.h>
25*5e3eaea3SApple OSS Distributions #include <mach/vm_param.h>
26*5e3eaea3SApple OSS Distributions #include <vm/vm_kern.h>
27*5e3eaea3SApple OSS Distributions #include <kern/zalloc.h>
28*5e3eaea3SApple OSS Distributions #include <kern/kalloc.h>
29*5e3eaea3SApple OSS Distributions #include <kern/assert.h>
30*5e3eaea3SApple OSS Distributions #include <kern/locks.h>
31*5e3eaea3SApple OSS Distributions #include <kern/lock_rw.h>
32*5e3eaea3SApple OSS Distributions #include <libkern/libkern.h>
33*5e3eaea3SApple OSS Distributions #include <libkern/section_keywords.h>
34*5e3eaea3SApple OSS Distributions #include <libkern/coretrust/coretrust.h>
35*5e3eaea3SApple OSS Distributions #include <pexpert/pexpert.h>
36*5e3eaea3SApple OSS Distributions #include <sys/vm.h>
37*5e3eaea3SApple OSS Distributions #include <sys/proc.h>
38*5e3eaea3SApple OSS Distributions #include <sys/codesign.h>
39*5e3eaea3SApple OSS Distributions #include <sys/code_signing.h>
40*5e3eaea3SApple OSS Distributions #include <uuid/uuid.h>
41*5e3eaea3SApple OSS Distributions #include <IOKit/IOBSD.h>
42*5e3eaea3SApple OSS Distributions 
43*5e3eaea3SApple OSS Distributions #if PMAP_CS_PPL_MONITOR
44*5e3eaea3SApple OSS Distributions /*
45*5e3eaea3SApple OSS Distributions  * The Page Protection Layer layer implements the PMAP_CS monitor environment which
46*5e3eaea3SApple OSS Distributions  * provides code signing and memory isolation enforcements for data structures which
47*5e3eaea3SApple OSS Distributions  * are critical to ensuring that all code executed on the system is authorized to do
48*5e3eaea3SApple OSS Distributions  * so.
49*5e3eaea3SApple OSS Distributions  *
50*5e3eaea3SApple OSS Distributions  * Unless the data is managed by the PPL itself, XNU needs to page-align everything,
51*5e3eaea3SApple OSS Distributions  * and then reference the memory as read-only.
52*5e3eaea3SApple OSS Distributions  */
53*5e3eaea3SApple OSS Distributions 
54*5e3eaea3SApple OSS Distributions typedef uint64_t pmap_paddr_t __kernel_ptr_semantics;
55*5e3eaea3SApple OSS Distributions extern vm_map_address_t phystokv(pmap_paddr_t pa);
56*5e3eaea3SApple OSS Distributions extern pmap_paddr_t kvtophys_nofail(vm_offset_t va);
57*5e3eaea3SApple OSS Distributions 
58*5e3eaea3SApple OSS Distributions #pragma mark Initialization
59*5e3eaea3SApple OSS Distributions 
60*5e3eaea3SApple OSS Distributions void
code_signing_init()61*5e3eaea3SApple OSS Distributions code_signing_init()
62*5e3eaea3SApple OSS Distributions {
63*5e3eaea3SApple OSS Distributions 	/* Does nothing */
64*5e3eaea3SApple OSS Distributions }
65*5e3eaea3SApple OSS Distributions 
66*5e3eaea3SApple OSS Distributions #pragma mark Developer Mode
67*5e3eaea3SApple OSS Distributions 
68*5e3eaea3SApple OSS Distributions SECURITY_READ_ONLY_LATE(bool*) developer_mode_enabled = &ppl_developer_mode_storage;
69*5e3eaea3SApple OSS Distributions 
70*5e3eaea3SApple OSS Distributions void
ppl_toggle_developer_mode(bool state)71*5e3eaea3SApple OSS Distributions ppl_toggle_developer_mode(
72*5e3eaea3SApple OSS Distributions 	bool state)
73*5e3eaea3SApple OSS Distributions {
74*5e3eaea3SApple OSS Distributions 	pmap_toggle_developer_mode(state);
75*5e3eaea3SApple OSS Distributions }
76*5e3eaea3SApple OSS Distributions 
77*5e3eaea3SApple OSS Distributions #pragma mark Code Signing and Provisioning Profiles
78*5e3eaea3SApple OSS Distributions 
79*5e3eaea3SApple OSS Distributions bool
ppl_code_signing_enabled(void)80*5e3eaea3SApple OSS Distributions ppl_code_signing_enabled(void)
81*5e3eaea3SApple OSS Distributions {
82*5e3eaea3SApple OSS Distributions 	return pmap_cs_enabled();
83*5e3eaea3SApple OSS Distributions }
84*5e3eaea3SApple OSS Distributions 
85*5e3eaea3SApple OSS Distributions kern_return_t
ppl_register_provisioning_profile(const void * profile_blob,const size_t profile_blob_size,void ** profile_obj)86*5e3eaea3SApple OSS Distributions ppl_register_provisioning_profile(
87*5e3eaea3SApple OSS Distributions 	const void *profile_blob,
88*5e3eaea3SApple OSS Distributions 	const size_t profile_blob_size,
89*5e3eaea3SApple OSS Distributions 	void **profile_obj)
90*5e3eaea3SApple OSS Distributions {
91*5e3eaea3SApple OSS Distributions 	pmap_profile_payload_t *pmap_payload = NULL;
92*5e3eaea3SApple OSS Distributions 	vm_address_t payload_addr = 0;
93*5e3eaea3SApple OSS Distributions 	vm_size_t payload_size = 0;
94*5e3eaea3SApple OSS Distributions 	vm_size_t payload_size_aligned = 0;
95*5e3eaea3SApple OSS Distributions 	kern_return_t ret = KERN_DENIED;
96*5e3eaea3SApple OSS Distributions 
97*5e3eaea3SApple OSS Distributions 	if (os_add_overflow(sizeof(*pmap_payload), profile_blob_size, &payload_size)) {
98*5e3eaea3SApple OSS Distributions 		panic("attempted to load a too-large profile: %lu bytes", profile_blob_size);
99*5e3eaea3SApple OSS Distributions 	}
100*5e3eaea3SApple OSS Distributions 	payload_size_aligned = round_page(payload_size);
101*5e3eaea3SApple OSS Distributions 
102*5e3eaea3SApple OSS Distributions 	ret = kmem_alloc(kernel_map, &payload_addr, payload_size_aligned,
103*5e3eaea3SApple OSS Distributions 	    KMA_KOBJECT | KMA_DATA | KMA_ZERO, VM_KERN_MEMORY_SECURITY);
104*5e3eaea3SApple OSS Distributions 	if (ret != KERN_SUCCESS) {
105*5e3eaea3SApple OSS Distributions 		printf("unable to allocate memory for pmap profile payload: %d\n", ret);
106*5e3eaea3SApple OSS Distributions 		goto exit;
107*5e3eaea3SApple OSS Distributions 	}
108*5e3eaea3SApple OSS Distributions 
109*5e3eaea3SApple OSS Distributions 	/* We need to setup the payload before we send it to the PPL */
110*5e3eaea3SApple OSS Distributions 	pmap_payload = (pmap_profile_payload_t*)payload_addr;
111*5e3eaea3SApple OSS Distributions 
112*5e3eaea3SApple OSS Distributions 	pmap_payload->profile_blob_size = profile_blob_size;
113*5e3eaea3SApple OSS Distributions 	memcpy(pmap_payload->profile_blob, profile_blob, profile_blob_size);
114*5e3eaea3SApple OSS Distributions 
115*5e3eaea3SApple OSS Distributions 	ret = pmap_register_provisioning_profile(payload_addr, payload_size_aligned);
116*5e3eaea3SApple OSS Distributions 	if (ret == KERN_SUCCESS) {
117*5e3eaea3SApple OSS Distributions 		*profile_obj = &pmap_payload->profile_obj_storage;
118*5e3eaea3SApple OSS Distributions 		*profile_obj = (pmap_cs_profile_t*)phystokv(kvtophys_nofail((vm_offset_t)*profile_obj));
119*5e3eaea3SApple OSS Distributions 	}
120*5e3eaea3SApple OSS Distributions 
121*5e3eaea3SApple OSS Distributions exit:
122*5e3eaea3SApple OSS Distributions 	if ((ret != KERN_SUCCESS) && (payload_addr != 0)) {
123*5e3eaea3SApple OSS Distributions 		kmem_free(kernel_map, payload_addr, payload_size_aligned);
124*5e3eaea3SApple OSS Distributions 		payload_addr = 0;
125*5e3eaea3SApple OSS Distributions 		payload_size_aligned = 0;
126*5e3eaea3SApple OSS Distributions 	}
127*5e3eaea3SApple OSS Distributions 
128*5e3eaea3SApple OSS Distributions 	return ret;
129*5e3eaea3SApple OSS Distributions }
130*5e3eaea3SApple OSS Distributions 
131*5e3eaea3SApple OSS Distributions kern_return_t
ppl_unregister_provisioning_profile(void * profile_obj)132*5e3eaea3SApple OSS Distributions ppl_unregister_provisioning_profile(
133*5e3eaea3SApple OSS Distributions 	void *profile_obj)
134*5e3eaea3SApple OSS Distributions {
135*5e3eaea3SApple OSS Distributions 	pmap_cs_profile_t *ppl_profile_obj = profile_obj;
136*5e3eaea3SApple OSS Distributions 	kern_return_t ret = KERN_DENIED;
137*5e3eaea3SApple OSS Distributions 
138*5e3eaea3SApple OSS Distributions 	ret = pmap_unregister_provisioning_profile(ppl_profile_obj);
139*5e3eaea3SApple OSS Distributions 	if (ret != KERN_SUCCESS) {
140*5e3eaea3SApple OSS Distributions 		return ret;
141*5e3eaea3SApple OSS Distributions 	}
142*5e3eaea3SApple OSS Distributions 
143*5e3eaea3SApple OSS Distributions 	/* Get the original payload address */
144*5e3eaea3SApple OSS Distributions 	const pmap_profile_payload_t *pmap_payload = ppl_profile_obj->original_payload;
145*5e3eaea3SApple OSS Distributions 	const vm_address_t payload_addr = (const vm_address_t)pmap_payload;
146*5e3eaea3SApple OSS Distributions 
147*5e3eaea3SApple OSS Distributions 	/* Get the original payload size */
148*5e3eaea3SApple OSS Distributions 	vm_size_t payload_size = pmap_payload->profile_blob_size + sizeof(*pmap_payload);
149*5e3eaea3SApple OSS Distributions 	payload_size = round_page(payload_size);
150*5e3eaea3SApple OSS Distributions 
151*5e3eaea3SApple OSS Distributions 	/* Free the payload */
152*5e3eaea3SApple OSS Distributions 	kmem_free(kernel_map, payload_addr, payload_size);
153*5e3eaea3SApple OSS Distributions 	pmap_payload = NULL;
154*5e3eaea3SApple OSS Distributions 
155*5e3eaea3SApple OSS Distributions 	return KERN_SUCCESS;
156*5e3eaea3SApple OSS Distributions }
157*5e3eaea3SApple OSS Distributions 
158*5e3eaea3SApple OSS Distributions kern_return_t
ppl_associate_provisioning_profile(void * sig_obj,void * profile_obj)159*5e3eaea3SApple OSS Distributions ppl_associate_provisioning_profile(
160*5e3eaea3SApple OSS Distributions 	void *sig_obj,
161*5e3eaea3SApple OSS Distributions 	void *profile_obj)
162*5e3eaea3SApple OSS Distributions {
163*5e3eaea3SApple OSS Distributions 	return pmap_associate_provisioning_profile(sig_obj, profile_obj);
164*5e3eaea3SApple OSS Distributions }
165*5e3eaea3SApple OSS Distributions 
166*5e3eaea3SApple OSS Distributions kern_return_t
ppl_disassociate_provisioning_profile(void * sig_obj)167*5e3eaea3SApple OSS Distributions ppl_disassociate_provisioning_profile(
168*5e3eaea3SApple OSS Distributions 	void *sig_obj)
169*5e3eaea3SApple OSS Distributions {
170*5e3eaea3SApple OSS Distributions 	return pmap_disassociate_provisioning_profile(sig_obj);
171*5e3eaea3SApple OSS Distributions }
172*5e3eaea3SApple OSS Distributions 
173*5e3eaea3SApple OSS Distributions void
ppl_set_compilation_service_cdhash(const uint8_t cdhash[CS_CDHASH_LEN])174*5e3eaea3SApple OSS Distributions ppl_set_compilation_service_cdhash(
175*5e3eaea3SApple OSS Distributions 	const uint8_t cdhash[CS_CDHASH_LEN])
176*5e3eaea3SApple OSS Distributions {
177*5e3eaea3SApple OSS Distributions 	pmap_set_compilation_service_cdhash(cdhash);
178*5e3eaea3SApple OSS Distributions }
179*5e3eaea3SApple OSS Distributions 
180*5e3eaea3SApple OSS Distributions bool
ppl_match_compilation_service_cdhash(const uint8_t cdhash[CS_CDHASH_LEN])181*5e3eaea3SApple OSS Distributions ppl_match_compilation_service_cdhash(
182*5e3eaea3SApple OSS Distributions 	const uint8_t cdhash[CS_CDHASH_LEN])
183*5e3eaea3SApple OSS Distributions {
184*5e3eaea3SApple OSS Distributions 	return pmap_match_compilation_service_cdhash(cdhash);
185*5e3eaea3SApple OSS Distributions }
186*5e3eaea3SApple OSS Distributions 
187*5e3eaea3SApple OSS Distributions void
ppl_set_local_signing_public_key(const uint8_t public_key[XNU_LOCAL_SIGNING_KEY_SIZE])188*5e3eaea3SApple OSS Distributions ppl_set_local_signing_public_key(
189*5e3eaea3SApple OSS Distributions 	const uint8_t public_key[XNU_LOCAL_SIGNING_KEY_SIZE])
190*5e3eaea3SApple OSS Distributions {
191*5e3eaea3SApple OSS Distributions 	return pmap_set_local_signing_public_key(public_key);
192*5e3eaea3SApple OSS Distributions }
193*5e3eaea3SApple OSS Distributions 
194*5e3eaea3SApple OSS Distributions uint8_t*
ppl_get_local_signing_public_key(void)195*5e3eaea3SApple OSS Distributions ppl_get_local_signing_public_key(void)
196*5e3eaea3SApple OSS Distributions {
197*5e3eaea3SApple OSS Distributions 	return pmap_get_local_signing_public_key();
198*5e3eaea3SApple OSS Distributions }
199*5e3eaea3SApple OSS Distributions 
200*5e3eaea3SApple OSS Distributions void
ppl_unrestrict_local_signing_cdhash(const uint8_t cdhash[CS_CDHASH_LEN])201*5e3eaea3SApple OSS Distributions ppl_unrestrict_local_signing_cdhash(
202*5e3eaea3SApple OSS Distributions 	const uint8_t cdhash[CS_CDHASH_LEN])
203*5e3eaea3SApple OSS Distributions {
204*5e3eaea3SApple OSS Distributions 	pmap_unrestrict_local_signing(cdhash);
205*5e3eaea3SApple OSS Distributions }
206*5e3eaea3SApple OSS Distributions 
207*5e3eaea3SApple OSS Distributions vm_size_t
ppl_managed_code_signature_size(void)208*5e3eaea3SApple OSS Distributions ppl_managed_code_signature_size(void)
209*5e3eaea3SApple OSS Distributions {
210*5e3eaea3SApple OSS Distributions 	return pmap_cs_blob_limit;
211*5e3eaea3SApple OSS Distributions }
212*5e3eaea3SApple OSS Distributions 
213*5e3eaea3SApple OSS Distributions kern_return_t
ppl_register_code_signature(const vm_address_t signature_addr,const vm_size_t signature_size,const vm_offset_t code_directory_offset,const char * signature_path,void ** sig_obj,vm_address_t * ppl_signature_addr)214*5e3eaea3SApple OSS Distributions ppl_register_code_signature(
215*5e3eaea3SApple OSS Distributions 	const vm_address_t signature_addr,
216*5e3eaea3SApple OSS Distributions 	const vm_size_t signature_size,
217*5e3eaea3SApple OSS Distributions 	const vm_offset_t code_directory_offset,
218*5e3eaea3SApple OSS Distributions 	const char *signature_path,
219*5e3eaea3SApple OSS Distributions 	void **sig_obj,
220*5e3eaea3SApple OSS Distributions 	vm_address_t *ppl_signature_addr)
221*5e3eaea3SApple OSS Distributions {
222*5e3eaea3SApple OSS Distributions 	pmap_cs_code_directory_t *cd_entry = NULL;
223*5e3eaea3SApple OSS Distributions 
224*5e3eaea3SApple OSS Distributions 	/* PPL doesn't care about the signature path */
225*5e3eaea3SApple OSS Distributions 	(void)signature_path;
226*5e3eaea3SApple OSS Distributions 
227*5e3eaea3SApple OSS Distributions 	kern_return_t ret = pmap_cs_register_code_signature_blob(
228*5e3eaea3SApple OSS Distributions 		signature_addr,
229*5e3eaea3SApple OSS Distributions 		signature_size,
230*5e3eaea3SApple OSS Distributions 		code_directory_offset,
231*5e3eaea3SApple OSS Distributions 		(pmap_cs_code_directory_t**)sig_obj);
232*5e3eaea3SApple OSS Distributions 
233*5e3eaea3SApple OSS Distributions 	if (ret != KERN_SUCCESS) {
234*5e3eaea3SApple OSS Distributions 		return ret;
235*5e3eaea3SApple OSS Distributions 	}
236*5e3eaea3SApple OSS Distributions 	cd_entry = *((pmap_cs_code_directory_t**)sig_obj);
237*5e3eaea3SApple OSS Distributions 
238*5e3eaea3SApple OSS Distributions 	if (ppl_signature_addr) {
239*5e3eaea3SApple OSS Distributions 		*ppl_signature_addr = (vm_address_t)cd_entry->superblob;
240*5e3eaea3SApple OSS Distributions 	}
241*5e3eaea3SApple OSS Distributions 
242*5e3eaea3SApple OSS Distributions 	return KERN_SUCCESS;
243*5e3eaea3SApple OSS Distributions }
244*5e3eaea3SApple OSS Distributions 
245*5e3eaea3SApple OSS Distributions kern_return_t
ppl_unregister_code_signature(void * sig_obj)246*5e3eaea3SApple OSS Distributions ppl_unregister_code_signature(
247*5e3eaea3SApple OSS Distributions 	void *sig_obj)
248*5e3eaea3SApple OSS Distributions {
249*5e3eaea3SApple OSS Distributions 	return pmap_cs_unregister_code_signature_blob(sig_obj);
250*5e3eaea3SApple OSS Distributions }
251*5e3eaea3SApple OSS Distributions 
252*5e3eaea3SApple OSS Distributions kern_return_t
ppl_verify_code_signature(void * sig_obj)253*5e3eaea3SApple OSS Distributions ppl_verify_code_signature(
254*5e3eaea3SApple OSS Distributions 	void *sig_obj)
255*5e3eaea3SApple OSS Distributions {
256*5e3eaea3SApple OSS Distributions 	return pmap_cs_verify_code_signature_blob(sig_obj);
257*5e3eaea3SApple OSS Distributions }
258*5e3eaea3SApple OSS Distributions 
259*5e3eaea3SApple OSS Distributions kern_return_t
ppl_reconstitute_code_signature(void * sig_obj,vm_address_t * unneeded_addr,vm_size_t * unneeded_size)260*5e3eaea3SApple OSS Distributions ppl_reconstitute_code_signature(
261*5e3eaea3SApple OSS Distributions 	void *sig_obj,
262*5e3eaea3SApple OSS Distributions 	vm_address_t *unneeded_addr,
263*5e3eaea3SApple OSS Distributions 	vm_size_t *unneeded_size)
264*5e3eaea3SApple OSS Distributions {
265*5e3eaea3SApple OSS Distributions 	return pmap_cs_unlock_unneeded_code_signature(
266*5e3eaea3SApple OSS Distributions 		sig_obj,
267*5e3eaea3SApple OSS Distributions 		unneeded_addr,
268*5e3eaea3SApple OSS Distributions 		unneeded_size);
269*5e3eaea3SApple OSS Distributions }
270*5e3eaea3SApple OSS Distributions 
271*5e3eaea3SApple OSS Distributions #pragma mark Address Spaces
272*5e3eaea3SApple OSS Distributions 
273*5e3eaea3SApple OSS Distributions kern_return_t
ppl_associate_code_signature(pmap_t pmap,void * sig_obj,const vm_address_t region_addr,const vm_size_t region_size,const vm_offset_t region_offset)274*5e3eaea3SApple OSS Distributions ppl_associate_code_signature(
275*5e3eaea3SApple OSS Distributions 	pmap_t pmap,
276*5e3eaea3SApple OSS Distributions 	void *sig_obj,
277*5e3eaea3SApple OSS Distributions 	const vm_address_t region_addr,
278*5e3eaea3SApple OSS Distributions 	const vm_size_t region_size,
279*5e3eaea3SApple OSS Distributions 	const vm_offset_t region_offset)
280*5e3eaea3SApple OSS Distributions {
281*5e3eaea3SApple OSS Distributions 	return pmap_cs_associate(
282*5e3eaea3SApple OSS Distributions 		pmap,
283*5e3eaea3SApple OSS Distributions 		sig_obj,
284*5e3eaea3SApple OSS Distributions 		region_addr,
285*5e3eaea3SApple OSS Distributions 		region_size,
286*5e3eaea3SApple OSS Distributions 		region_offset);
287*5e3eaea3SApple OSS Distributions }
288*5e3eaea3SApple OSS Distributions 
289*5e3eaea3SApple OSS Distributions kern_return_t
ppl_allow_jit_region(__unused pmap_t pmap)290*5e3eaea3SApple OSS Distributions ppl_allow_jit_region(
291*5e3eaea3SApple OSS Distributions 	__unused pmap_t pmap)
292*5e3eaea3SApple OSS Distributions {
293*5e3eaea3SApple OSS Distributions 	/* PPL does not support this API */
294*5e3eaea3SApple OSS Distributions 	return KERN_NOT_SUPPORTED;
295*5e3eaea3SApple OSS Distributions }
296*5e3eaea3SApple OSS Distributions 
297*5e3eaea3SApple OSS Distributions kern_return_t
ppl_associate_jit_region(pmap_t pmap,const vm_address_t region_addr,const vm_size_t region_size)298*5e3eaea3SApple OSS Distributions ppl_associate_jit_region(
299*5e3eaea3SApple OSS Distributions 	pmap_t pmap,
300*5e3eaea3SApple OSS Distributions 	const vm_address_t region_addr,
301*5e3eaea3SApple OSS Distributions 	const vm_size_t region_size)
302*5e3eaea3SApple OSS Distributions {
303*5e3eaea3SApple OSS Distributions 	return pmap_cs_associate(
304*5e3eaea3SApple OSS Distributions 		pmap,
305*5e3eaea3SApple OSS Distributions 		PMAP_CS_ASSOCIATE_JIT,
306*5e3eaea3SApple OSS Distributions 		region_addr,
307*5e3eaea3SApple OSS Distributions 		region_size,
308*5e3eaea3SApple OSS Distributions 		0);
309*5e3eaea3SApple OSS Distributions }
310*5e3eaea3SApple OSS Distributions 
311*5e3eaea3SApple OSS Distributions kern_return_t
ppl_associate_debug_region(pmap_t pmap,const vm_address_t region_addr,const vm_size_t region_size)312*5e3eaea3SApple OSS Distributions ppl_associate_debug_region(
313*5e3eaea3SApple OSS Distributions 	pmap_t pmap,
314*5e3eaea3SApple OSS Distributions 	const vm_address_t region_addr,
315*5e3eaea3SApple OSS Distributions 	const vm_size_t region_size)
316*5e3eaea3SApple OSS Distributions {
317*5e3eaea3SApple OSS Distributions 	return pmap_cs_associate(
318*5e3eaea3SApple OSS Distributions 		pmap,
319*5e3eaea3SApple OSS Distributions 		PMAP_CS_ASSOCIATE_COW,
320*5e3eaea3SApple OSS Distributions 		region_addr,
321*5e3eaea3SApple OSS Distributions 		region_size,
322*5e3eaea3SApple OSS Distributions 		0);
323*5e3eaea3SApple OSS Distributions }
324*5e3eaea3SApple OSS Distributions 
325*5e3eaea3SApple OSS Distributions kern_return_t
ppl_address_space_debugged(pmap_t pmap)326*5e3eaea3SApple OSS Distributions ppl_address_space_debugged(
327*5e3eaea3SApple OSS Distributions 	pmap_t pmap)
328*5e3eaea3SApple OSS Distributions {
329*5e3eaea3SApple OSS Distributions 	/*
330*5e3eaea3SApple OSS Distributions 	 * ppl_associate_debug_region is a fairly idempotent function which simply
331*5e3eaea3SApple OSS Distributions 	 * checks if an address space is already debugged or not and returns a value
332*5e3eaea3SApple OSS Distributions 	 * based on that. The actual memory region is not inserted into the address
333*5e3eaea3SApple OSS Distributions 	 * space, so we can pass whatever in this case. The only caveat here though
334*5e3eaea3SApple OSS Distributions 	 * is that the memory region needs to be page-aligned and cannot be NULL.
335*5e3eaea3SApple OSS Distributions 	 */
336*5e3eaea3SApple OSS Distributions 	return ppl_associate_debug_region(pmap, PAGE_SIZE, PAGE_SIZE);
337*5e3eaea3SApple OSS Distributions }
338*5e3eaea3SApple OSS Distributions 
339*5e3eaea3SApple OSS Distributions kern_return_t
ppl_allow_invalid_code(pmap_t pmap)340*5e3eaea3SApple OSS Distributions ppl_allow_invalid_code(
341*5e3eaea3SApple OSS Distributions 	pmap_t pmap)
342*5e3eaea3SApple OSS Distributions {
343*5e3eaea3SApple OSS Distributions 	return pmap_cs_allow_invalid(pmap);
344*5e3eaea3SApple OSS Distributions }
345*5e3eaea3SApple OSS Distributions 
346*5e3eaea3SApple OSS Distributions kern_return_t
ppl_get_trust_level_kdp(pmap_t pmap,uint32_t * trust_level)347*5e3eaea3SApple OSS Distributions ppl_get_trust_level_kdp(
348*5e3eaea3SApple OSS Distributions 	pmap_t pmap,
349*5e3eaea3SApple OSS Distributions 	uint32_t *trust_level)
350*5e3eaea3SApple OSS Distributions {
351*5e3eaea3SApple OSS Distributions 	return pmap_get_trust_level_kdp(pmap, trust_level);
352*5e3eaea3SApple OSS Distributions }
353*5e3eaea3SApple OSS Distributions 
354*5e3eaea3SApple OSS Distributions kern_return_t
ppl_address_space_exempt(const pmap_t pmap)355*5e3eaea3SApple OSS Distributions ppl_address_space_exempt(
356*5e3eaea3SApple OSS Distributions 	const pmap_t pmap)
357*5e3eaea3SApple OSS Distributions {
358*5e3eaea3SApple OSS Distributions 	if (pmap_performs_stage2_translations(pmap) == true) {
359*5e3eaea3SApple OSS Distributions 		return KERN_SUCCESS;
360*5e3eaea3SApple OSS Distributions 	}
361*5e3eaea3SApple OSS Distributions 
362*5e3eaea3SApple OSS Distributions 	return KERN_DENIED;
363*5e3eaea3SApple OSS Distributions }
364*5e3eaea3SApple OSS Distributions 
365*5e3eaea3SApple OSS Distributions kern_return_t
ppl_fork_prepare(pmap_t old_pmap,pmap_t new_pmap)366*5e3eaea3SApple OSS Distributions ppl_fork_prepare(
367*5e3eaea3SApple OSS Distributions 	pmap_t old_pmap,
368*5e3eaea3SApple OSS Distributions 	pmap_t new_pmap)
369*5e3eaea3SApple OSS Distributions {
370*5e3eaea3SApple OSS Distributions 	return pmap_cs_fork_prepare(old_pmap, new_pmap);
371*5e3eaea3SApple OSS Distributions }
372*5e3eaea3SApple OSS Distributions 
373*5e3eaea3SApple OSS Distributions kern_return_t
ppl_acquire_signing_identifier(const void * sig_obj,const char ** signing_id)374*5e3eaea3SApple OSS Distributions ppl_acquire_signing_identifier(
375*5e3eaea3SApple OSS Distributions 	const void *sig_obj,
376*5e3eaea3SApple OSS Distributions 	const char **signing_id)
377*5e3eaea3SApple OSS Distributions {
378*5e3eaea3SApple OSS Distributions 	const pmap_cs_code_directory_t *cd_entry = sig_obj;
379*5e3eaea3SApple OSS Distributions 
380*5e3eaea3SApple OSS Distributions 	/* If we reach here, the identifier must have been setup */
381*5e3eaea3SApple OSS Distributions 	assert(cd_entry->identifier != NULL);
382*5e3eaea3SApple OSS Distributions 
383*5e3eaea3SApple OSS Distributions 	if (signing_id) {
384*5e3eaea3SApple OSS Distributions 		*signing_id = cd_entry->identifier;
385*5e3eaea3SApple OSS Distributions 	}
386*5e3eaea3SApple OSS Distributions 
387*5e3eaea3SApple OSS Distributions 	return KERN_SUCCESS;
388*5e3eaea3SApple OSS Distributions }
389*5e3eaea3SApple OSS Distributions 
390*5e3eaea3SApple OSS Distributions #pragma mark Entitlements
391*5e3eaea3SApple OSS Distributions 
392*5e3eaea3SApple OSS Distributions kern_return_t
ppl_associate_kernel_entitlements(void * sig_obj,const void * kernel_entitlements)393*5e3eaea3SApple OSS Distributions ppl_associate_kernel_entitlements(
394*5e3eaea3SApple OSS Distributions 	void *sig_obj,
395*5e3eaea3SApple OSS Distributions 	const void *kernel_entitlements)
396*5e3eaea3SApple OSS Distributions {
397*5e3eaea3SApple OSS Distributions 	pmap_cs_code_directory_t *cd_entry = sig_obj;
398*5e3eaea3SApple OSS Distributions 	return pmap_associate_kernel_entitlements(cd_entry, kernel_entitlements);
399*5e3eaea3SApple OSS Distributions }
400*5e3eaea3SApple OSS Distributions 
401*5e3eaea3SApple OSS Distributions kern_return_t
ppl_resolve_kernel_entitlements(pmap_t pmap,const void ** kernel_entitlements)402*5e3eaea3SApple OSS Distributions ppl_resolve_kernel_entitlements(
403*5e3eaea3SApple OSS Distributions 	pmap_t pmap,
404*5e3eaea3SApple OSS Distributions 	const void **kernel_entitlements)
405*5e3eaea3SApple OSS Distributions {
406*5e3eaea3SApple OSS Distributions 	kern_return_t ret = KERN_DENIED;
407*5e3eaea3SApple OSS Distributions 	const void *entitlements = NULL;
408*5e3eaea3SApple OSS Distributions 
409*5e3eaea3SApple OSS Distributions 	ret = pmap_resolve_kernel_entitlements(pmap, &entitlements);
410*5e3eaea3SApple OSS Distributions 	if ((ret == KERN_SUCCESS) && (kernel_entitlements != NULL)) {
411*5e3eaea3SApple OSS Distributions 		*kernel_entitlements = entitlements;
412*5e3eaea3SApple OSS Distributions 	}
413*5e3eaea3SApple OSS Distributions 
414*5e3eaea3SApple OSS Distributions 	return ret;
415*5e3eaea3SApple OSS Distributions }
416*5e3eaea3SApple OSS Distributions 
417*5e3eaea3SApple OSS Distributions kern_return_t
ppl_accelerate_entitlements(void * sig_obj,CEQueryContext_t * ce_ctx)418*5e3eaea3SApple OSS Distributions ppl_accelerate_entitlements(
419*5e3eaea3SApple OSS Distributions 	void *sig_obj,
420*5e3eaea3SApple OSS Distributions 	CEQueryContext_t *ce_ctx)
421*5e3eaea3SApple OSS Distributions {
422*5e3eaea3SApple OSS Distributions 	pmap_cs_code_directory_t *cd_entry = sig_obj;
423*5e3eaea3SApple OSS Distributions 	kern_return_t ret = KERN_DENIED;
424*5e3eaea3SApple OSS Distributions 
425*5e3eaea3SApple OSS Distributions 	ret = pmap_accelerate_entitlements(cd_entry);
426*5e3eaea3SApple OSS Distributions 
427*5e3eaea3SApple OSS Distributions 	/*
428*5e3eaea3SApple OSS Distributions 	 * We only ever get KERN_ABORTED when we cannot accelerate the entitlements
429*5e3eaea3SApple OSS Distributions 	 * because it would consume too much memory. In this case, we still want to
430*5e3eaea3SApple OSS Distributions 	 * return the ce_ctx since we don't want the system to fall-back to non-PPL
431*5e3eaea3SApple OSS Distributions 	 * locked down memory, so we switch this to a success case.
432*5e3eaea3SApple OSS Distributions 	 */
433*5e3eaea3SApple OSS Distributions 	if (ret == KERN_ABORTED) {
434*5e3eaea3SApple OSS Distributions 		ret = KERN_SUCCESS;
435*5e3eaea3SApple OSS Distributions 	}
436*5e3eaea3SApple OSS Distributions 
437*5e3eaea3SApple OSS Distributions 	/* Return the accelerated context to the caller */
438*5e3eaea3SApple OSS Distributions 	if ((ret == KERN_SUCCESS) && (ce_ctx != NULL)) {
439*5e3eaea3SApple OSS Distributions 		*ce_ctx = cd_entry->ce_ctx;
440*5e3eaea3SApple OSS Distributions 	}
441*5e3eaea3SApple OSS Distributions 
442*5e3eaea3SApple OSS Distributions 	return ret;
443*5e3eaea3SApple OSS Distributions }
444*5e3eaea3SApple OSS Distributions 
445*5e3eaea3SApple OSS Distributions #pragma mark Image4
446*5e3eaea3SApple OSS Distributions 
447*5e3eaea3SApple OSS Distributions void*
ppl_image4_storage_data(size_t * allocated_size)448*5e3eaea3SApple OSS Distributions ppl_image4_storage_data(
449*5e3eaea3SApple OSS Distributions 	size_t *allocated_size)
450*5e3eaea3SApple OSS Distributions {
451*5e3eaea3SApple OSS Distributions 	return pmap_image4_pmap_data(allocated_size);
452*5e3eaea3SApple OSS Distributions }
453*5e3eaea3SApple OSS Distributions 
454*5e3eaea3SApple OSS Distributions void
ppl_image4_set_nonce(const img4_nonce_domain_index_t ndi,const img4_nonce_t * nonce)455*5e3eaea3SApple OSS Distributions ppl_image4_set_nonce(
456*5e3eaea3SApple OSS Distributions 	const img4_nonce_domain_index_t ndi,
457*5e3eaea3SApple OSS Distributions 	const img4_nonce_t *nonce)
458*5e3eaea3SApple OSS Distributions {
459*5e3eaea3SApple OSS Distributions 	return pmap_image4_set_nonce(ndi, nonce);
460*5e3eaea3SApple OSS Distributions }
461*5e3eaea3SApple OSS Distributions 
462*5e3eaea3SApple OSS Distributions void
ppl_image4_roll_nonce(const img4_nonce_domain_index_t ndi)463*5e3eaea3SApple OSS Distributions ppl_image4_roll_nonce(
464*5e3eaea3SApple OSS Distributions 	const img4_nonce_domain_index_t ndi)
465*5e3eaea3SApple OSS Distributions {
466*5e3eaea3SApple OSS Distributions 	return pmap_image4_roll_nonce(ndi);
467*5e3eaea3SApple OSS Distributions }
468*5e3eaea3SApple OSS Distributions 
469*5e3eaea3SApple OSS Distributions errno_t
ppl_image4_copy_nonce(const img4_nonce_domain_index_t ndi,img4_nonce_t * nonce_out)470*5e3eaea3SApple OSS Distributions ppl_image4_copy_nonce(
471*5e3eaea3SApple OSS Distributions 	const img4_nonce_domain_index_t ndi,
472*5e3eaea3SApple OSS Distributions 	img4_nonce_t *nonce_out)
473*5e3eaea3SApple OSS Distributions {
474*5e3eaea3SApple OSS Distributions 	return pmap_image4_copy_nonce(ndi, nonce_out);
475*5e3eaea3SApple OSS Distributions }
476*5e3eaea3SApple OSS Distributions 
477*5e3eaea3SApple OSS Distributions errno_t
ppl_image4_execute_object(img4_runtime_object_spec_index_t obj_spec_index,const img4_buff_t * payload,const img4_buff_t * manifest)478*5e3eaea3SApple OSS Distributions ppl_image4_execute_object(
479*5e3eaea3SApple OSS Distributions 	img4_runtime_object_spec_index_t obj_spec_index,
480*5e3eaea3SApple OSS Distributions 	const img4_buff_t *payload,
481*5e3eaea3SApple OSS Distributions 	const img4_buff_t *manifest)
482*5e3eaea3SApple OSS Distributions {
483*5e3eaea3SApple OSS Distributions 	errno_t err = EINVAL;
484*5e3eaea3SApple OSS Distributions 	kern_return_t kr = KERN_DENIED;
485*5e3eaea3SApple OSS Distributions 	img4_buff_t payload_aligned = IMG4_BUFF_INIT;
486*5e3eaea3SApple OSS Distributions 	img4_buff_t manifest_aligned = IMG4_BUFF_INIT;
487*5e3eaea3SApple OSS Distributions 	vm_address_t payload_addr = 0;
488*5e3eaea3SApple OSS Distributions 	vm_size_t payload_len_aligned = 0;
489*5e3eaea3SApple OSS Distributions 	vm_address_t manifest_addr = 0;
490*5e3eaea3SApple OSS Distributions 	vm_size_t manifest_len_aligned = 0;
491*5e3eaea3SApple OSS Distributions 
492*5e3eaea3SApple OSS Distributions 	if (payload == NULL) {
493*5e3eaea3SApple OSS Distributions 		printf("invalid object execution request: no payload\n");
494*5e3eaea3SApple OSS Distributions 		goto out;
495*5e3eaea3SApple OSS Distributions 	}
496*5e3eaea3SApple OSS Distributions 
497*5e3eaea3SApple OSS Distributions 	/*
498*5e3eaea3SApple OSS Distributions 	 * The PPL will attempt to lockdown both the payload and the manifest before executing
499*5e3eaea3SApple OSS Distributions 	 * the object. In order for that to happen, both the artifacts need to be page-aligned.
500*5e3eaea3SApple OSS Distributions 	 */
501*5e3eaea3SApple OSS Distributions 	payload_len_aligned = round_page(payload->i4b_len);
502*5e3eaea3SApple OSS Distributions 	if (manifest != NULL) {
503*5e3eaea3SApple OSS Distributions 		manifest_len_aligned = round_page(manifest->i4b_len);
504*5e3eaea3SApple OSS Distributions 	}
505*5e3eaea3SApple OSS Distributions 
506*5e3eaea3SApple OSS Distributions 	kr = kmem_alloc(
507*5e3eaea3SApple OSS Distributions 		kernel_map,
508*5e3eaea3SApple OSS Distributions 		&payload_addr,
509*5e3eaea3SApple OSS Distributions 		payload_len_aligned,
510*5e3eaea3SApple OSS Distributions 		KMA_KOBJECT,
511*5e3eaea3SApple OSS Distributions 		VM_KERN_MEMORY_SECURITY);
512*5e3eaea3SApple OSS Distributions 
513*5e3eaea3SApple OSS Distributions 	if (kr != KERN_SUCCESS) {
514*5e3eaea3SApple OSS Distributions 		printf("unable to allocate memory for image4 payload: %d\n", kr);
515*5e3eaea3SApple OSS Distributions 		err = ENOMEM;
516*5e3eaea3SApple OSS Distributions 		goto out;
517*5e3eaea3SApple OSS Distributions 	}
518*5e3eaea3SApple OSS Distributions 
519*5e3eaea3SApple OSS Distributions 	/* Copy in the payload */
520*5e3eaea3SApple OSS Distributions 	memcpy((uint8_t*)payload_addr, payload->i4b_bytes, payload->i4b_len);
521*5e3eaea3SApple OSS Distributions 
522*5e3eaea3SApple OSS Distributions 	/* Construct the aligned payload buffer */
523*5e3eaea3SApple OSS Distributions 	payload_aligned.i4b_bytes = (uint8_t*)payload_addr;
524*5e3eaea3SApple OSS Distributions 	payload_aligned.i4b_len = payload->i4b_len;
525*5e3eaea3SApple OSS Distributions 
526*5e3eaea3SApple OSS Distributions 	if (manifest != NULL) {
527*5e3eaea3SApple OSS Distributions 		kr = kmem_alloc(
528*5e3eaea3SApple OSS Distributions 			kernel_map,
529*5e3eaea3SApple OSS Distributions 			&manifest_addr,
530*5e3eaea3SApple OSS Distributions 			manifest_len_aligned,
531*5e3eaea3SApple OSS Distributions 			KMA_KOBJECT,
532*5e3eaea3SApple OSS Distributions 			VM_KERN_MEMORY_SECURITY);
533*5e3eaea3SApple OSS Distributions 
534*5e3eaea3SApple OSS Distributions 		if (kr != KERN_SUCCESS) {
535*5e3eaea3SApple OSS Distributions 			printf("unable to allocate memory for image4 manifest: %d\n", kr);
536*5e3eaea3SApple OSS Distributions 			err = ENOMEM;
537*5e3eaea3SApple OSS Distributions 			goto out;
538*5e3eaea3SApple OSS Distributions 		}
539*5e3eaea3SApple OSS Distributions 
540*5e3eaea3SApple OSS Distributions 		/* Construct the aligned manifest buffer */
541*5e3eaea3SApple OSS Distributions 		manifest_aligned.i4b_bytes = (uint8_t*)manifest_addr;
542*5e3eaea3SApple OSS Distributions 		manifest_aligned.i4b_len = manifest->i4b_len;
543*5e3eaea3SApple OSS Distributions 
544*5e3eaea3SApple OSS Distributions 		/* Copy in the manifest */
545*5e3eaea3SApple OSS Distributions 		memcpy((uint8_t*)manifest_addr, manifest->i4b_bytes, manifest->i4b_len);
546*5e3eaea3SApple OSS Distributions 	}
547*5e3eaea3SApple OSS Distributions 
548*5e3eaea3SApple OSS Distributions 	err = pmap_image4_execute_object(obj_spec_index, &payload_aligned, &manifest_aligned);
549*5e3eaea3SApple OSS Distributions 	if (err != 0) {
550*5e3eaea3SApple OSS Distributions 		printf("unable to execute image4 object: %d\n", err);
551*5e3eaea3SApple OSS Distributions 		goto out;
552*5e3eaea3SApple OSS Distributions 	}
553*5e3eaea3SApple OSS Distributions 
554*5e3eaea3SApple OSS Distributions out:
555*5e3eaea3SApple OSS Distributions 	/* We always free the manifest as it isn't required anymore */
556*5e3eaea3SApple OSS Distributions 	if (manifest_addr != 0) {
557*5e3eaea3SApple OSS Distributions 		kmem_free(kernel_map, manifest_addr, manifest_len_aligned);
558*5e3eaea3SApple OSS Distributions 		manifest_addr = 0;
559*5e3eaea3SApple OSS Distributions 		manifest_len_aligned = 0;
560*5e3eaea3SApple OSS Distributions 	}
561*5e3eaea3SApple OSS Distributions 
562*5e3eaea3SApple OSS Distributions 	/* If we encountered an error -- free the allocated payload */
563*5e3eaea3SApple OSS Distributions 	if ((err != 0) && (payload_addr != 0)) {
564*5e3eaea3SApple OSS Distributions 		kmem_free(kernel_map, payload_addr, payload_len_aligned);
565*5e3eaea3SApple OSS Distributions 		payload_addr = 0;
566*5e3eaea3SApple OSS Distributions 		payload_len_aligned = 0;
567*5e3eaea3SApple OSS Distributions 	}
568*5e3eaea3SApple OSS Distributions 
569*5e3eaea3SApple OSS Distributions 	return err;
570*5e3eaea3SApple OSS Distributions }
571*5e3eaea3SApple OSS Distributions 
572*5e3eaea3SApple OSS Distributions errno_t
ppl_image4_copy_object(img4_runtime_object_spec_index_t obj_spec_index,vm_address_t object_out,size_t * object_length)573*5e3eaea3SApple OSS Distributions ppl_image4_copy_object(
574*5e3eaea3SApple OSS Distributions 	img4_runtime_object_spec_index_t obj_spec_index,
575*5e3eaea3SApple OSS Distributions 	vm_address_t object_out,
576*5e3eaea3SApple OSS Distributions 	size_t *object_length)
577*5e3eaea3SApple OSS Distributions {
578*5e3eaea3SApple OSS Distributions 	errno_t err = EINVAL;
579*5e3eaea3SApple OSS Distributions 	kern_return_t kr = KERN_DENIED;
580*5e3eaea3SApple OSS Distributions 	vm_address_t object_addr = 0;
581*5e3eaea3SApple OSS Distributions 	vm_size_t object_len_aligned = 0;
582*5e3eaea3SApple OSS Distributions 
583*5e3eaea3SApple OSS Distributions 	if (object_out == 0) {
584*5e3eaea3SApple OSS Distributions 		printf("invalid object copy request: no object input buffer\n");
585*5e3eaea3SApple OSS Distributions 		goto out;
586*5e3eaea3SApple OSS Distributions 	} else if (object_length == NULL) {
587*5e3eaea3SApple OSS Distributions 		printf("invalid object copy request: no object input length\n");
588*5e3eaea3SApple OSS Distributions 		goto out;
589*5e3eaea3SApple OSS Distributions 	}
590*5e3eaea3SApple OSS Distributions 
591*5e3eaea3SApple OSS Distributions 	/*
592*5e3eaea3SApple OSS Distributions 	 * The PPL will attempt to pin the input buffer in order to ensure that the kernel
593*5e3eaea3SApple OSS Distributions 	 * didn't pass in PPL-owned buffers. The PPL cannot pin the same page more than once,
594*5e3eaea3SApple OSS Distributions 	 * and attempting to do so will panic the system. Hence, we allocate fresh pages for
595*5e3eaea3SApple OSS Distributions 	 * for the PPL to pin.
596*5e3eaea3SApple OSS Distributions 	 *
597*5e3eaea3SApple OSS Distributions 	 * We can send in the address for the length pointer since that is allocated on the
598*5e3eaea3SApple OSS Distributions 	 * stack, so the PPL can pin our stack for the duration of the call as no other
599*5e3eaea3SApple OSS Distributions 	 * thread can be using our stack, meaning the PPL will never attempt to double-pin
600*5e3eaea3SApple OSS Distributions 	 * the page.
601*5e3eaea3SApple OSS Distributions 	 */
602*5e3eaea3SApple OSS Distributions 	object_len_aligned = round_page(*object_length);
603*5e3eaea3SApple OSS Distributions 
604*5e3eaea3SApple OSS Distributions 	kr = kmem_alloc(
605*5e3eaea3SApple OSS Distributions 		kernel_map,
606*5e3eaea3SApple OSS Distributions 		&object_addr,
607*5e3eaea3SApple OSS Distributions 		object_len_aligned,
608*5e3eaea3SApple OSS Distributions 		KMA_KOBJECT,
609*5e3eaea3SApple OSS Distributions 		VM_KERN_MEMORY_SECURITY);
610*5e3eaea3SApple OSS Distributions 
611*5e3eaea3SApple OSS Distributions 	if (kr != KERN_SUCCESS) {
612*5e3eaea3SApple OSS Distributions 		printf("unable to allocate memory for image4 object: %d\n", kr);
613*5e3eaea3SApple OSS Distributions 		err = ENOMEM;
614*5e3eaea3SApple OSS Distributions 		goto out;
615*5e3eaea3SApple OSS Distributions 	}
616*5e3eaea3SApple OSS Distributions 
617*5e3eaea3SApple OSS Distributions 	err = pmap_image4_copy_object(obj_spec_index, object_addr, object_length);
618*5e3eaea3SApple OSS Distributions 	if (err != 0) {
619*5e3eaea3SApple OSS Distributions 		printf("unable to copy image4 object: %d\n", err);
620*5e3eaea3SApple OSS Distributions 		goto out;
621*5e3eaea3SApple OSS Distributions 	}
622*5e3eaea3SApple OSS Distributions 
623*5e3eaea3SApple OSS Distributions 	/* Copy the data back into the caller passed buffer */
624*5e3eaea3SApple OSS Distributions 	memcpy((void*)object_out, (void*)object_addr, *object_length);
625*5e3eaea3SApple OSS Distributions 
626*5e3eaea3SApple OSS Distributions out:
627*5e3eaea3SApple OSS Distributions 	/* We don't ever need to keep around our page-aligned buffer */
628*5e3eaea3SApple OSS Distributions 	if (object_addr != 0) {
629*5e3eaea3SApple OSS Distributions 		kmem_free(kernel_map, object_addr, object_len_aligned);
630*5e3eaea3SApple OSS Distributions 		object_addr = 0;
631*5e3eaea3SApple OSS Distributions 		object_len_aligned = 0;
632*5e3eaea3SApple OSS Distributions 	}
633*5e3eaea3SApple OSS Distributions 
634*5e3eaea3SApple OSS Distributions 	return err;
635*5e3eaea3SApple OSS Distributions }
636*5e3eaea3SApple OSS Distributions 
637*5e3eaea3SApple OSS Distributions const void*
ppl_image4_get_monitor_exports(void)638*5e3eaea3SApple OSS Distributions ppl_image4_get_monitor_exports(void)
639*5e3eaea3SApple OSS Distributions {
640*5e3eaea3SApple OSS Distributions 	/*
641*5e3eaea3SApple OSS Distributions 	 * AppleImage4 can query the PMAP_CS runtime on its own since the PMAP_CS
642*5e3eaea3SApple OSS Distributions 	 * runtime is compiled within the kernel extension itself. As a result, we
643*5e3eaea3SApple OSS Distributions 	 * never expect this KPI to be called when the system uses the PPL monitor.
644*5e3eaea3SApple OSS Distributions 	 */
645*5e3eaea3SApple OSS Distributions 
646*5e3eaea3SApple OSS Distributions 	printf("explicit monitor-exports-get not required for the PPL\n");
647*5e3eaea3SApple OSS Distributions 	return NULL;
648*5e3eaea3SApple OSS Distributions }
649*5e3eaea3SApple OSS Distributions 
650*5e3eaea3SApple OSS Distributions errno_t
ppl_image4_set_release_type(__unused const char * release_type)651*5e3eaea3SApple OSS Distributions ppl_image4_set_release_type(
652*5e3eaea3SApple OSS Distributions 	__unused const char *release_type)
653*5e3eaea3SApple OSS Distributions {
654*5e3eaea3SApple OSS Distributions 	/*
655*5e3eaea3SApple OSS Distributions 	 * AppleImage4 stores the release type in the CTRR protected memory region
656*5e3eaea3SApple OSS Distributions 	 * of its kernel extension. This is accessible by the PMAP_CS runtime as the
657*5e3eaea3SApple OSS Distributions 	 * runtime is compiled alongside the kernel extension. As a result, we never
658*5e3eaea3SApple OSS Distributions 	 * expect this KPI to be called when the system uses the PPL monitor.
659*5e3eaea3SApple OSS Distributions 	 */
660*5e3eaea3SApple OSS Distributions 
661*5e3eaea3SApple OSS Distributions 	printf("explicit release-type-set set not required for the PPL\n");
662*5e3eaea3SApple OSS Distributions 	return ENOTSUP;
663*5e3eaea3SApple OSS Distributions }
664*5e3eaea3SApple OSS Distributions 
665*5e3eaea3SApple OSS Distributions errno_t
ppl_image4_set_bnch_shadow(__unused const img4_nonce_domain_index_t ndi)666*5e3eaea3SApple OSS Distributions ppl_image4_set_bnch_shadow(
667*5e3eaea3SApple OSS Distributions 	__unused const img4_nonce_domain_index_t ndi)
668*5e3eaea3SApple OSS Distributions {
669*5e3eaea3SApple OSS Distributions 	/*
670*5e3eaea3SApple OSS Distributions 	 * AppleImage4 stores the BNCH shadow in the CTRR protected memory region
671*5e3eaea3SApple OSS Distributions 	 * of its kernel extension. This is accessible by the PMAP_CS runtime as the
672*5e3eaea3SApple OSS Distributions 	 * runtime is compiled alongside the kernel extension. As a result, we never
673*5e3eaea3SApple OSS Distributions 	 * expect this KPI to be called when the system uses the PPL monitor.
674*5e3eaea3SApple OSS Distributions 	 */
675*5e3eaea3SApple OSS Distributions 
676*5e3eaea3SApple OSS Distributions 	printf("explicit BNCH-shadow-set not required for the PPL\n");
677*5e3eaea3SApple OSS Distributions 	return ENOTSUP;
678*5e3eaea3SApple OSS Distributions }
679*5e3eaea3SApple OSS Distributions 
680*5e3eaea3SApple OSS Distributions #endif /* PMAP_CS_PPL_MONITOR */
681