xref: /xnu-10063.101.15/bsd/kern/mach_loader.c (revision 94d3b452840153a99b38a3a9659680b2a006908e)
1 /*
2  * Copyright (c) 2000-2020 Apple Inc. All rights reserved.
3  *
4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5  *
6  * This file contains Original Code and/or Modifications of Original Code
7  * as defined in and that are subject to the Apple Public Source License
8  * Version 2.0 (the 'License'). You may not use this file except in
9  * compliance with the License. The rights granted to you under the License
10  * may not be used to create, or enable the creation or redistribution of,
11  * unlawful or unlicensed copies of an Apple operating system, or to
12  * circumvent, violate, or enable the circumvention or violation of, any
13  * terms of an Apple operating system software license agreement.
14  *
15  * Please obtain a copy of the License at
16  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17  *
18  * The Original Code and all software distributed under the License are
19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23  * Please see the License for the specific language governing rights and
24  * limitations under the License.
25  *
26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27  */
28 /*
29  *	Copyright (C) 1988, 1989,  NeXT, Inc.
30  *
31  *	File:	kern/mach_loader.c
32  *	Author:	Avadis Tevanian, Jr.
33  *
34  *	Mach object file loader (kernel version, for now).
35  *
36  * 21-Jul-88  Avadis Tevanian, Jr. (avie) at NeXT
37  *	Started.
38  */
39 
40 #include <sys/param.h>
41 #include <sys/vnode_internal.h>
42 #include <sys/uio.h>
43 #include <sys/namei.h>
44 #include <sys/proc_internal.h>
45 #include <sys/kauth.h>
46 #include <sys/stat.h>
47 #include <sys/malloc.h>
48 #include <sys/mount_internal.h>
49 #include <sys/fcntl.h>
50 #include <sys/file_internal.h>
51 #include <sys/ubc_internal.h>
52 #include <sys/imgact.h>
53 #include <sys/codesign.h>
54 #include <sys/proc_uuid_policy.h>
55 #include <sys/reason.h>
56 #include <sys/kdebug.h>
57 #include <sys/spawn_internal.h>
58 
59 #include <mach/mach_types.h>
60 #include <mach/vm_map.h>        /* vm_allocate() */
61 #include <mach/mach_vm.h>       /* mach_vm_allocate() */
62 #include <mach/vm_statistics.h>
63 #include <mach/task.h>
64 #include <mach/thread_act.h>
65 
66 #include <machine/vmparam.h>
67 #include <machine/exec.h>
68 #include <machine/pal_routines.h>
69 
70 #include <kern/ast.h>
71 #include <kern/kern_types.h>
72 #include <kern/cpu_number.h>
73 #include <kern/mach_loader.h>
74 #include <kern/mach_fat.h>
75 #include <kern/kalloc.h>
76 #include <kern/task.h>
77 #include <kern/thread.h>
78 #include <kern/page_decrypt.h>
79 
80 #include <mach-o/fat.h>
81 #include <mach-o/loader.h>
82 
83 #include <vm/pmap.h>
84 #include <vm/vm_map.h>
85 #include <vm/vm_kern.h>
86 #include <vm/vm_pager.h>
87 #include <vm/vnode_pager.h>
88 #include <vm/vm_protos.h>
89 #include <vm/vm_shared_region.h>
90 #include <IOKit/IOReturn.h>     /* for kIOReturnNotPrivileged */
91 #include <IOKit/IOBSD.h>        /* for IOVnodeHasEntitlement */
92 
93 #include <os/log.h>
94 #include <os/overflow.h>
95 
96 #include "kern_exec_internal.h"
97 
98 /* XXX should have prototypes in a shared header file */
99 extern int      get_map_nentries(vm_map_t);
100 
101 extern kern_return_t    memory_object_signed(memory_object_control_t control,
102     boolean_t is_signed);
103 
104 
105 /* An empty load_result_t */
106 static const load_result_t load_result_null = {
107 	.mach_header = MACH_VM_MIN_ADDRESS,
108 	.entry_point = MACH_VM_MIN_ADDRESS,
109 	.user_stack = MACH_VM_MIN_ADDRESS,
110 	.user_stack_size = 0,
111 	.user_stack_alloc = MACH_VM_MIN_ADDRESS,
112 	.user_stack_alloc_size = 0,
113 	.all_image_info_addr = MACH_VM_MIN_ADDRESS,
114 	.all_image_info_size = 0,
115 	.thread_count = 0,
116 	.unixproc = 0,
117 	.dynlinker = 0,
118 	.needs_dynlinker = 0,
119 	.validentry = 0,
120 	.using_lcmain = 0,
121 	.is_64bit_addr = 0,
122 	.is_64bit_data = 0,
123 	.custom_stack = 0,
124 	.csflags = 0,
125 	.has_pagezero = 0,
126 	.uuid = { 0 },
127 	.min_vm_addr = MACH_VM_MAX_ADDRESS,
128 	.max_vm_addr = MACH_VM_MIN_ADDRESS,
129 	.ro_vm_start = MACH_VM_MIN_ADDRESS,
130 	.ro_vm_end = MACH_VM_MIN_ADDRESS,
131 	.cs_end_offset = 0,
132 	.threadstate = NULL,
133 	.threadstate_sz = 0,
134 	.is_rosetta = 0,
135 	.dynlinker_ro_vm_start = 0,
136 	.dynlinker_ro_vm_end = 0,
137 	.dynlinker_mach_header = MACH_VM_MIN_ADDRESS,
138 	.dynlinker_fd = -1,
139 };
140 
141 /*
142  * Prototypes of static functions.
143  */
144 static load_return_t
145 parse_machfile(
146 	struct vnode            *vp,
147 	vm_map_t                map,
148 	thread_t                thread,
149 	struct mach_header      *header,
150 	off_t                   file_offset,
151 	off_t                   macho_size,
152 	int                     depth,
153 	int64_t                 slide,
154 	int64_t                 dyld_slide,
155 	load_result_t           *result,
156 	load_result_t           *binresult,
157 	struct image_params     *imgp
158 	);
159 
160 static load_return_t
161 load_segment(
162 	struct load_command             *lcp,
163 	uint32_t                        filetype,
164 	void                            *control,
165 	off_t                           pager_offset,
166 	off_t                           macho_size,
167 	struct vnode                    *vp,
168 	vm_map_t                        map,
169 	int64_t                         slide,
170 	load_result_t                   *result,
171 	struct image_params             *imgp
172 	);
173 
174 static load_return_t
175 load_uuid(
176 	struct uuid_command             *uulp,
177 	char                            *command_end,
178 	load_result_t                   *result
179 	);
180 
181 static load_return_t
182 load_version(
183 	struct version_min_command     *vmc,
184 	boolean_t               *found_version_cmd,
185 	struct image_params             *imgp,
186 	load_result_t           *result
187 	);
188 
189 static load_return_t
190 load_code_signature(
191 	struct linkedit_data_command    *lcp,
192 	struct vnode                    *vp,
193 	off_t                           macho_offset,
194 	off_t                           macho_size,
195 	cpu_type_t                      cputype,
196 	cpu_subtype_t                   cpusubtype,
197 	load_result_t                   *result,
198 	struct image_params             *imgp);
199 
200 #if CONFIG_CODE_DECRYPTION
201 static load_return_t
202 set_code_unprotect(
203 	struct encryption_info_command  *lcp,
204 	caddr_t                         addr,
205 	vm_map_t                        map,
206 	int64_t                         slide,
207 	struct vnode                    *vp,
208 	off_t                           macho_offset,
209 	cpu_type_t                      cputype,
210 	cpu_subtype_t                   cpusubtype);
211 #endif
212 
213 static
214 load_return_t
215 load_main(
216 	struct entry_point_command      *epc,
217 	thread_t                thread,
218 	int64_t                         slide,
219 	load_result_t           *result
220 	);
221 
222 static
223 load_return_t
224 setup_driver_main(
225 	thread_t                thread,
226 	int64_t                         slide,
227 	load_result_t           *result
228 	);
229 
230 static load_return_t
231 load_unixthread(
232 	struct thread_command   *tcp,
233 	thread_t                        thread,
234 	int64_t                         slide,
235 	boolean_t                       is_x86_64_compat_binary,
236 	load_result_t                   *result
237 	);
238 
239 static load_return_t
240 load_threadstate(
241 	thread_t                thread,
242 	uint32_t        *ts,
243 	uint32_t        total_size,
244 	load_result_t *
245 	);
246 
247 static load_return_t
248 load_threadstack(
249 	thread_t                thread,
250 	uint32_t                *ts,
251 	uint32_t                total_size,
252 	mach_vm_offset_t        *user_stack,
253 	int                     *customstack,
254 	boolean_t               is_x86_64_compat_binary,
255 	load_result_t           *result
256 	);
257 
258 static load_return_t
259 load_threadentry(
260 	thread_t                thread,
261 	uint32_t        *ts,
262 	uint32_t        total_size,
263 	mach_vm_offset_t        *entry_point
264 	);
265 
266 static load_return_t
267 load_dylinker(
268 	struct dylinker_command *lcp,
269 	integer_t               archbits,
270 	vm_map_t                map,
271 	thread_t                thread,
272 	int                     depth,
273 	int64_t                 slide,
274 	load_result_t           *result,
275 	struct image_params     *imgp
276 	);
277 
278 
279 #if CONFIG_ROSETTA
280 static load_return_t
281 load_rosetta(
282 	vm_map_t                        map,
283 	thread_t                        thread,
284 	load_result_t           *result,
285 	struct image_params     *imgp
286 	);
287 #endif
288 
289 #if __x86_64__
290 extern int bootarg_no32exec;
291 static boolean_t
292 check_if_simulator_binary(
293 	struct image_params     *imgp,
294 	off_t                   file_offset,
295 	off_t                   macho_size);
296 #endif
297 
298 struct macho_data;
299 
300 static load_return_t
301 get_macho_vnode(
302 	const char                      *path,
303 	integer_t               archbits,
304 	struct mach_header      *mach_header,
305 	off_t                   *file_offset,
306 	off_t                   *macho_size,
307 	struct macho_data       *macho_data,
308 	struct vnode            **vpp,
309 	struct image_params     *imgp
310 	);
311 
312 static inline void
widen_segment_command(const struct segment_command * scp32,struct segment_command_64 * scp)313 widen_segment_command(const struct segment_command *scp32,
314     struct segment_command_64 *scp)
315 {
316 	scp->cmd = scp32->cmd;
317 	scp->cmdsize = scp32->cmdsize;
318 	bcopy(scp32->segname, scp->segname, sizeof(scp->segname));
319 	scp->vmaddr = scp32->vmaddr;
320 	scp->vmsize = scp32->vmsize;
321 	scp->fileoff = scp32->fileoff;
322 	scp->filesize = scp32->filesize;
323 	scp->maxprot = scp32->maxprot;
324 	scp->initprot = scp32->initprot;
325 	scp->nsects = scp32->nsects;
326 	scp->flags = scp32->flags;
327 }
328 
329 static void
note_all_image_info_section(const struct segment_command_64 * scp,boolean_t is64,size_t section_size,const void * sections,int64_t slide,load_result_t * result)330 note_all_image_info_section(const struct segment_command_64 *scp,
331     boolean_t is64, size_t section_size, const void *sections,
332     int64_t slide, load_result_t *result)
333 {
334 	const union {
335 		struct section s32;
336 		struct section_64 s64;
337 	} *sectionp;
338 	unsigned int i;
339 
340 
341 	if (strncmp(scp->segname, "__DATA_DIRTY", sizeof(scp->segname)) != 0 &&
342 	    strncmp(scp->segname, "__DATA", sizeof(scp->segname)) != 0) {
343 		return;
344 	}
345 	for (i = 0; i < scp->nsects; ++i) {
346 		sectionp = (const void *)
347 		    ((const char *)sections + section_size * i);
348 		if (0 == strncmp(sectionp->s64.sectname, "__all_image_info",
349 		    sizeof(sectionp->s64.sectname))) {
350 			result->all_image_info_addr =
351 			    is64 ? sectionp->s64.addr : sectionp->s32.addr;
352 			result->all_image_info_addr += slide;
353 			result->all_image_info_size =
354 			    is64 ? sectionp->s64.size : sectionp->s32.size;
355 			return;
356 		}
357 	}
358 }
359 
360 #if __arm64__
361 /*
362  * Allow bypassing some security rules (hard pagezero, no write+execute)
363  * in exchange for better binary compatibility for legacy apps built
364  * before 16KB-alignment was enforced.
365  */
366 const int fourk_binary_compatibility_unsafe = TRUE;
367 const int fourk_binary_compatibility_allow_wx = FALSE;
368 #endif /* __arm64__ */
369 
370 #if XNU_TARGET_OS_OSX
371 
372 /* Determines whether this process may host/run third party plugins. */
373 static inline bool
process_is_plugin_host(struct image_params * imgp,load_result_t * result)374 process_is_plugin_host(struct image_params *imgp, load_result_t *result)
375 {
376 	if (imgp->ip_flags & IMGPF_NOJOP) {
377 		return false;
378 	}
379 
380 	if (!result->platform_binary) {
381 		return false;
382 	}
383 
384 	struct cs_blob *csblob = csvnode_get_blob(imgp->ip_vp, imgp->ip_arch_offset);
385 	const char *identity = csblob_get_identity(csblob);
386 	if (!identity) {
387 		return false;
388 	}
389 
390 	/* Check if override host plugin entitlement is present and posix spawn attribute to disable A keys is passed */
391 	if (IOVnodeHasEntitlement(imgp->ip_vp, (int64_t)imgp->ip_arch_offset, OVERRIDE_PLUGIN_HOST_ENTITLEMENT)) {
392 		bool ret = imgp->ip_flags & IMGPF_PLUGIN_HOST_DISABLE_A_KEYS;
393 		if (ret) {
394 			proc_t p = vfs_context_proc(imgp->ip_vfs_context);
395 			set_proc_name(imgp, p);
396 			os_log(OS_LOG_DEFAULT, "%s: running binary \"%s\" in keys-off mode due to posix_spawnattr_disable_ptr_auth_a_keys_np", __func__, p->p_name);
397 		}
398 		return ret;
399 	}
400 
401 	/* Disabling library validation is a good signal that this process plans to host plugins */
402 	const char *const disable_lv_entitlements[] = {
403 		"com.apple.security.cs.disable-library-validation",
404 		"com.apple.private.cs.automator-plugins",
405 		CLEAR_LV_ENTITLEMENT,
406 	};
407 	for (size_t i = 0; i < ARRAY_COUNT(disable_lv_entitlements); i++) {
408 		const char *entitlement = disable_lv_entitlements[i];
409 		if (IOVnodeHasEntitlement(imgp->ip_vp, (int64_t)imgp->ip_arch_offset, entitlement)) {
410 			proc_t p = vfs_context_proc(imgp->ip_vfs_context);
411 			set_proc_name(imgp, p);
412 			os_log(OS_LOG_DEFAULT, "%s: running binary \"%s\" in keys-off mode due to entitlement: %s", __func__, p->p_name, entitlement);
413 			return true;
414 		}
415 	}
416 
417 	/* From /System/Library/Security/HardeningExceptions.plist */
418 	const char *const hardening_exceptions[] = {
419 		"com.apple.perl5", /* Scripting engines may load third party code and jit*/
420 		"com.apple.perl", /* Scripting engines may load third party code and jit*/
421 		"org.python.python", /* Scripting engines may load third party code and jit*/
422 		"com.apple.expect", /* Scripting engines may load third party code and jit*/
423 		"com.tcltk.wish", /* Scripting engines may load third party code and jit*/
424 		"com.tcltk.tclsh", /* Scripting engines may load third party code and jit*/
425 		"com.apple.ruby", /* Scripting engines may load third party code and jit*/
426 		"com.apple.bash", /* Required for the 'enable' command */
427 		"com.apple.zsh", /* Required for the 'zmodload' command */
428 		"com.apple.ksh", /* Required for 'builtin' command */
429 	};
430 	for (size_t i = 0; i < ARRAY_COUNT(hardening_exceptions); i++) {
431 		if (strncmp(hardening_exceptions[i], identity, strlen(hardening_exceptions[i])) == 0) {
432 			proc_t p = vfs_context_proc(imgp->ip_vfs_context);
433 			set_proc_name(imgp, p);
434 			os_log(OS_LOG_DEFAULT, "%s: running binary \"%s\" in keys-off mode due to identity: %s", __func__, p->p_name, identity);
435 			return true;
436 		}
437 	}
438 
439 	return false;
440 }
441 #endif /* XNU_TARGET_OS_OSX */
442 
443 load_return_t
load_machfile(struct image_params * imgp,struct mach_header * header,thread_t thread,vm_map_t * mapp,load_result_t * result)444 load_machfile(
445 	struct image_params     *imgp,
446 	struct mach_header      *header,
447 	thread_t                thread,
448 	vm_map_t                *mapp,
449 	load_result_t           *result
450 	)
451 {
452 	struct vnode            *vp = imgp->ip_vp;
453 	off_t                   file_offset = imgp->ip_arch_offset;
454 	off_t                   macho_size = imgp->ip_arch_size;
455 	off_t                   total_size = 0;
456 	off_t                   file_size = imgp->ip_vattr->va_data_size;
457 	pmap_t                  pmap = 0;       /* protected by create_map */
458 	vm_map_t                map;
459 	load_result_t           myresult;
460 	load_return_t           lret;
461 	boolean_t enforce_hard_pagezero = TRUE;
462 	int in_exec = (imgp->ip_flags & IMGPF_EXEC);
463 	task_t task = current_task();
464 	int64_t                 aslr_page_offset = 0;
465 	int64_t                 dyld_aslr_page_offset = 0;
466 	int64_t                 aslr_section_size = 0;
467 	int64_t                 aslr_section_offset = 0;
468 	kern_return_t           kret;
469 	unsigned int            pmap_flags = 0;
470 
471 	if (os_add_overflow(file_offset, macho_size, &total_size) ||
472 	    total_size > file_size) {
473 		return LOAD_BADMACHO;
474 	}
475 
476 	result->is_64bit_addr = ((imgp->ip_flags & IMGPF_IS_64BIT_ADDR) == IMGPF_IS_64BIT_ADDR);
477 	result->is_64bit_data = ((imgp->ip_flags & IMGPF_IS_64BIT_DATA) == IMGPF_IS_64BIT_DATA);
478 #if defined(HAS_APPLE_PAC)
479 	pmap_flags |= (imgp->ip_flags & IMGPF_NOJOP) ? PMAP_CREATE_DISABLE_JOP : 0;
480 #endif /* defined(HAS_APPLE_PAC) */
481 #if CONFIG_ROSETTA
482 	pmap_flags |= (imgp->ip_flags & IMGPF_ROSETTA) ? PMAP_CREATE_ROSETTA : 0;
483 #endif
484 	pmap_flags |= result->is_64bit_addr ? PMAP_CREATE_64BIT : 0;
485 
486 	task_t ledger_task;
487 	if (imgp->ip_new_thread) {
488 		ledger_task = get_threadtask(imgp->ip_new_thread);
489 	} else {
490 		ledger_task = task;
491 	}
492 
493 #if XNU_TARGET_OS_OSX && _POSIX_SPAWN_FORCE_4K_PAGES && PMAP_CREATE_FORCE_4K_PAGES
494 	if (imgp->ip_px_sa != NULL) {
495 		struct _posix_spawnattr* psa = (struct _posix_spawnattr *) imgp->ip_px_sa;
496 		if (psa->psa_flags & _POSIX_SPAWN_FORCE_4K_PAGES) {
497 			pmap_flags |= PMAP_CREATE_FORCE_4K_PAGES;
498 		}
499 	}
500 #endif /* XNU_TARGET_OS_OSX && _POSIX_SPAWN_FORCE_4K_PAGES && PMAP_CREATE_FORCE_4K_PAGE */
501 
502 	pmap = pmap_create_options(get_task_ledger(ledger_task),
503 	    (vm_map_size_t) 0,
504 	    pmap_flags);
505 	if (pmap == NULL) {
506 		return LOAD_RESOURCE;
507 	}
508 	map = vm_map_create_options(pmap, 0,
509 	    vm_compute_max_offset(result->is_64bit_addr),
510 	    VM_MAP_CREATE_PAGEABLE);
511 
512 #if defined(__arm64__)
513 	if (result->is_64bit_addr) {
514 		/* enforce 16KB alignment of VM map entries */
515 		vm_map_set_page_shift(map, SIXTEENK_PAGE_SHIFT);
516 	} else {
517 		vm_map_set_page_shift(map, page_shift_user32);
518 	}
519 #endif /* __arm64__ */
520 
521 #if PMAP_CREATE_FORCE_4K_PAGES
522 	if (pmap_flags & PMAP_CREATE_FORCE_4K_PAGES) {
523 		DEBUG4K_LIFE("***** launching '%s' as 4k *****\n", vp->v_name);
524 		vm_map_set_page_shift(map, FOURK_PAGE_SHIFT);
525 	}
526 #endif /* PMAP_CREATE_FORCE_4K_PAGES */
527 
528 #ifndef CONFIG_ENFORCE_SIGNED_CODE
529 	/* This turns off faulting for executable pages, which allows
530 	 * to circumvent Code Signing Enforcement. The per process
531 	 * flag (CS_ENFORCEMENT) is not set yet, but we can use the
532 	 * global flag.
533 	 */
534 	if (!cs_process_global_enforcement() && (header->flags & MH_ALLOW_STACK_EXECUTION)) {
535 		vm_map_disable_NX(map);
536 		// TODO: Message Trace or log that this is happening
537 	}
538 #endif
539 
540 	/* Forcibly disallow execution from data pages on even if the arch
541 	 * normally permits it. */
542 	if ((header->flags & MH_NO_HEAP_EXECUTION) && !(imgp->ip_flags & IMGPF_ALLOW_DATA_EXEC)) {
543 		vm_map_disallow_data_exec(map);
544 	}
545 
546 	/*
547 	 * Compute a random offset for ASLR, and an independent random offset for dyld.
548 	 */
549 	if (!(imgp->ip_flags & IMGPF_DISABLE_ASLR)) {
550 		vm_map_get_max_aslr_slide_section(map, &aslr_section_offset, &aslr_section_size);
551 		aslr_section_offset = (random() % aslr_section_offset) * aslr_section_size;
552 
553 		aslr_page_offset = random();
554 		aslr_page_offset = (aslr_page_offset % (vm_map_get_max_aslr_slide_pages(map) - 1)) + 1;
555 		aslr_page_offset <<= vm_map_page_shift(map);
556 
557 		dyld_aslr_page_offset = random();
558 		dyld_aslr_page_offset = (dyld_aslr_page_offset %
559 		    (vm_map_get_max_loader_aslr_slide_pages(map) - 1)) + 1;
560 		dyld_aslr_page_offset <<= vm_map_page_shift(map);
561 
562 		aslr_page_offset += aslr_section_offset;
563 	}
564 	if (vm_map_page_shift(map) < (int)PAGE_SHIFT) {
565 		DEBUG4K_LOAD("slide=0x%llx dyld_slide=0x%llx\n", aslr_page_offset, dyld_aslr_page_offset);
566 	}
567 
568 	if (!result) {
569 		result = &myresult;
570 	}
571 
572 	*result = load_result_null;
573 
574 	/*
575 	 * re-set the bitness on the load result since we cleared the load result above.
576 	 */
577 	result->is_64bit_addr = ((imgp->ip_flags & IMGPF_IS_64BIT_ADDR) == IMGPF_IS_64BIT_ADDR);
578 	result->is_64bit_data = ((imgp->ip_flags & IMGPF_IS_64BIT_DATA) == IMGPF_IS_64BIT_DATA);
579 
580 	lret = parse_machfile(vp, map, thread, header, file_offset, macho_size,
581 	    0, aslr_page_offset, dyld_aslr_page_offset, result,
582 	    NULL, imgp);
583 
584 	if (lret != LOAD_SUCCESS) {
585 		vm_map_deallocate(map); /* will lose pmap reference too */
586 		return lret;
587 	}
588 
589 #if __x86_64__
590 	/*
591 	 * On x86, for compatibility, don't enforce the hard page-zero restriction for 32-bit binaries.
592 	 */
593 	if (!result->is_64bit_addr) {
594 		enforce_hard_pagezero = FALSE;
595 	}
596 
597 	/*
598 	 * For processes with IMGPF_HIGH_BITS_ASLR, add a few random high bits
599 	 * to the start address for "anywhere" memory allocations.
600 	 */
601 #define VM_MAP_HIGH_START_BITS_COUNT 8
602 #define VM_MAP_HIGH_START_BITS_SHIFT 27
603 	if (result->is_64bit_addr &&
604 	    (imgp->ip_flags & IMGPF_HIGH_BITS_ASLR)) {
605 		int random_bits;
606 		vm_map_offset_t high_start;
607 
608 		random_bits = random();
609 		random_bits &= (1 << VM_MAP_HIGH_START_BITS_COUNT) - 1;
610 		high_start = (((vm_map_offset_t)random_bits)
611 		        << VM_MAP_HIGH_START_BITS_SHIFT);
612 		vm_map_set_high_start(map, high_start);
613 	}
614 #endif /* __x86_64__ */
615 
616 	/*
617 	 * Check to see if the page zero is enforced by the map->min_offset.
618 	 */
619 	if (enforce_hard_pagezero &&
620 	    (vm_map_has_hard_pagezero(map, 0x1000) == FALSE)) {
621 #if __arm64__
622 		if (
623 			!result->is_64bit_addr && /* not 64-bit address space */
624 			!(header->flags & MH_PIE) &&      /* not PIE */
625 			(vm_map_page_shift(map) != FOURK_PAGE_SHIFT ||
626 			PAGE_SHIFT != FOURK_PAGE_SHIFT) && /* page size != 4KB */
627 			result->has_pagezero && /* has a "soft" page zero */
628 			fourk_binary_compatibility_unsafe) {
629 			/*
630 			 * For backwards compatibility of "4K" apps on
631 			 * a 16K system, do not enforce a hard page zero...
632 			 */
633 		} else
634 #endif /* __arm64__ */
635 		{
636 			vm_map_deallocate(map); /* will lose pmap reference too */
637 			return LOAD_BADMACHO;
638 		}
639 	}
640 
641 #if __arm64__
642 	if (enforce_hard_pagezero && result->is_64bit_addr && (header->cputype == CPU_TYPE_ARM64)) {
643 		/* 64 bit ARM binary must have "hard page zero" of 4GB to cover the lower 32 bit address space */
644 		if (vm_map_has_hard_pagezero(map, 0x100000000) == FALSE) {
645 			vm_map_deallocate(map); /* will lose pmap reference too */
646 			return LOAD_BADMACHO;
647 		}
648 	}
649 #endif
650 
651 	vm_commit_pagezero_status(map);
652 
653 	/*
654 	 * If this is an exec, then we are going to destroy the old
655 	 * task, and it's correct to halt it; if it's spawn, the
656 	 * task is not yet running, and it makes no sense.
657 	 */
658 	if (in_exec) {
659 		proc_t p = current_proc();
660 		/*
661 		 * Mark the task as halting and start the other
662 		 * threads towards terminating themselves.  Then
663 		 * make sure any threads waiting for a process
664 		 * transition get informed that we are committed to
665 		 * this transition, and then finally complete the
666 		 * task halting (wait for threads and then cleanup
667 		 * task resources).
668 		 *
669 		 * NOTE: task_start_halt() makes sure that no new
670 		 * threads are created in the task during the transition.
671 		 * We need to mark the workqueue as exiting before we
672 		 * wait for threads to terminate (at the end of which
673 		 * we no longer have a prohibition on thread creation).
674 		 *
675 		 * Finally, clean up any lingering workqueue data structures
676 		 * that may have been left behind by the workqueue threads
677 		 * as they exited (and then clean up the work queue itself).
678 		 */
679 		kret = task_start_halt(task);
680 		if (kret != KERN_SUCCESS) {
681 			vm_map_deallocate(map); /* will lose pmap reference too */
682 			return LOAD_FAILURE;
683 		}
684 		proc_transcommit(p, 0);
685 		workq_mark_exiting(p);
686 		task_complete_halt(task);
687 		workq_exit(p);
688 
689 		/*
690 		 * Roll up accounting info to new task. The roll up is done after
691 		 * task_complete_halt to make sure the thread accounting info is
692 		 * rolled up to current_task.
693 		 */
694 		task_rollup_accounting_info(get_threadtask(thread), task);
695 	}
696 	*mapp = map;
697 
698 #if XNU_TARGET_OS_OSX
699 	if (process_is_plugin_host(imgp, result)) {
700 		/*
701 		 * We need to disable security policies for processes
702 		 * that run third party plugins.
703 		 */
704 		imgp->ip_flags |= IMGPF_3P_PLUGINS;
705 	}
706 
707 #if __has_feature(ptrauth_calls)
708 	/*
709 	 * arm64e plugin hosts currently run with JOP keys disabled, since they
710 	 * may need to run arm64 plugins.
711 	 */
712 	if (imgp->ip_flags & IMGPF_3P_PLUGINS) {
713 		imgp->ip_flags |= IMGPF_NOJOP;
714 		pmap_disable_user_jop(pmap);
715 	}
716 
717 #if CONFIG_ROSETTA
718 	/* Disable JOP keys if the Rosetta runtime being used isn't arm64e */
719 	if (result->is_rosetta && (imgp->ip_flags & IMGPF_NOJOP)) {
720 		pmap_disable_user_jop(pmap);
721 	}
722 #endif /* CONFIG_ROSETTA */
723 #endif /* __has_feature(ptrauth_calls)*/
724 #endif /* XNU_TARGET_OS_OSX */
725 
726 
727 	return LOAD_SUCCESS;
728 }
729 
730 int macho_printf = 0;
731 #define MACHO_PRINTF(args)                              \
732 	do {                                            \
733 	        if (macho_printf) {                     \
734 	                printf args;                    \
735 	        }                                       \
736 	} while (0)
737 
738 
739 static boolean_t
pie_required(cpu_type_t exectype,cpu_subtype_t execsubtype)740 pie_required(
741 	cpu_type_t exectype,
742 	cpu_subtype_t execsubtype)
743 {
744 	switch (exectype) {
745 	case CPU_TYPE_X86_64:
746 		return FALSE;
747 	case CPU_TYPE_ARM64:
748 		return TRUE;
749 	case CPU_TYPE_ARM:
750 		switch (execsubtype) {
751 		case CPU_SUBTYPE_ARM_V7K:
752 			return TRUE;
753 		}
754 		break;
755 	}
756 	return FALSE;
757 }
758 
759 /*
760  * The file size of a mach-o file is limited to 32 bits; this is because
761  * this is the limit on the kalloc() of enough bytes for a mach_header and
762  * the contents of its sizeofcmds, which is currently constrained to 32
763  * bits in the file format itself.  We read into the kernel buffer the
764  * commands section, and then parse it in order to parse the mach-o file
765  * format load_command segment(s).  We are only interested in a subset of
766  * the total set of possible commands. If "map"==VM_MAP_NULL or
767  * "thread"==THREAD_NULL, do not make permament VM modifications,
768  * just preflight the parse.
769  */
770 static
771 load_return_t
parse_machfile(struct vnode * vp,vm_map_t map,thread_t thread,struct mach_header * header,off_t file_offset,off_t macho_size,int depth,int64_t aslr_offset,int64_t dyld_aslr_offset,load_result_t * result,load_result_t * binresult,struct image_params * imgp)772 parse_machfile(
773 	struct vnode            *vp,
774 	vm_map_t                map,
775 	thread_t                thread,
776 	struct mach_header      *header,
777 	off_t                   file_offset,
778 	off_t                   macho_size,
779 	int                     depth,
780 	int64_t                 aslr_offset,
781 	int64_t                 dyld_aslr_offset,
782 	load_result_t           *result,
783 	load_result_t           *binresult,
784 	struct image_params     *imgp
785 	)
786 {
787 	uint32_t                ncmds;
788 	struct load_command     *lcp;
789 	struct dylinker_command *dlp = 0;
790 	void *                  control;
791 	load_return_t           ret = LOAD_SUCCESS;
792 	void *                  addr;
793 	vm_size_t               alloc_size, cmds_size;
794 	size_t                  offset;
795 	size_t                  oldoffset;      /* for overflow check */
796 	int                     pass;
797 	proc_t                  p = vfs_context_proc(imgp->ip_vfs_context);
798 	int                     error;
799 	int                     resid = 0;
800 	int                     spawn = (imgp->ip_flags & IMGPF_SPAWN);
801 	size_t                  mach_header_sz = sizeof(struct mach_header);
802 	boolean_t               abi64;
803 	boolean_t               got_code_signatures = FALSE;
804 	boolean_t               found_header_segment = FALSE;
805 	boolean_t               found_xhdr = FALSE;
806 	boolean_t               found_version_cmd = FALSE;
807 	int64_t                 slide = 0;
808 	boolean_t               dyld_no_load_addr = FALSE;
809 	boolean_t               is_dyld = FALSE;
810 	vm_map_offset_t         effective_page_mask = PAGE_MASK;
811 #if __arm64__
812 	uint64_t                pagezero_end = 0;
813 	uint64_t                executable_end = 0;
814 	uint64_t                writable_start = 0;
815 	vm_map_size_t           effective_page_size;
816 
817 	effective_page_mask = vm_map_page_mask(map);
818 	effective_page_size = vm_map_page_size(map);
819 #endif /* __arm64__ */
820 
821 	if (header->magic == MH_MAGIC_64 ||
822 	    header->magic == MH_CIGAM_64) {
823 		mach_header_sz = sizeof(struct mach_header_64);
824 	}
825 
826 	/*
827 	 *	Break infinite recursion
828 	 */
829 	if (depth > 2) {
830 		return LOAD_FAILURE;
831 	}
832 
833 	depth++;
834 
835 	/*
836 	 * Set CS_NO_UNTRUSTED_HELPERS by default; load_dylinker and load_rosetta
837 	 * will unset it if necessary.
838 	 */
839 	if (depth == 1) {
840 		result->csflags |= CS_NO_UNTRUSTED_HELPERS;
841 	}
842 
843 	/*
844 	 *	Check to see if right machine type.
845 	 */
846 	if (((cpu_type_t)(header->cputype & ~CPU_ARCH_MASK) != (cpu_type() & ~CPU_ARCH_MASK))
847 	    ) {
848 		return LOAD_BADARCH;
849 	}
850 
851 	if (!grade_binary(header->cputype,
852 	    header->cpusubtype & ~CPU_SUBTYPE_MASK,
853 	    header->cpusubtype & CPU_SUBTYPE_MASK, TRUE)) {
854 		return LOAD_BADARCH;
855 	}
856 
857 	abi64 = ((header->cputype & CPU_ARCH_ABI64) == CPU_ARCH_ABI64);
858 
859 	switch (header->filetype) {
860 	case MH_EXECUTE:
861 		if (depth != 1 && depth != 3) {
862 			return LOAD_FAILURE;
863 		}
864 		if (header->flags & MH_DYLDLINK) {
865 			/* Check properties of dynamic executables */
866 			if (!(header->flags & MH_PIE) && pie_required(header->cputype, header->cpusubtype & ~CPU_SUBTYPE_MASK)) {
867 				return LOAD_FAILURE;
868 			}
869 			result->needs_dynlinker = TRUE;
870 		} else if (header->cputype == CPU_TYPE_X86_64) {
871 			/* x86_64 static binaries allowed */
872 #if CONFIG_ROSETTA
873 		} else if (imgp->ip_flags & IMGPF_ROSETTA) {
874 			/* Rosetta runtime allowed */
875 #endif /* CONFIG_X86_64_COMPAT */
876 		} else {
877 			/* Check properties of static executables (disallowed except for development) */
878 #if !(DEVELOPMENT || DEBUG)
879 			return LOAD_FAILURE;
880 #endif
881 		}
882 		break;
883 	case MH_DYLINKER:
884 		if (depth != 2) {
885 			return LOAD_FAILURE;
886 		}
887 		is_dyld = TRUE;
888 		break;
889 
890 	default:
891 		return LOAD_FAILURE;
892 	}
893 
894 	/*
895 	 *	For PIE and dyld, slide everything by the ASLR offset.
896 	 */
897 	if ((header->flags & MH_PIE) || is_dyld) {
898 		slide = aslr_offset;
899 	}
900 
901 	/*
902 	 *	Get the pager for the file.
903 	 */
904 	control = ubc_getobject(vp, UBC_FLAGS_NONE);
905 
906 	/* ensure header + sizeofcmds falls within the file */
907 	if (os_add_overflow(mach_header_sz, header->sizeofcmds, &cmds_size) ||
908 	    (off_t)cmds_size > macho_size ||
909 	    round_page_overflow(cmds_size, &alloc_size) ||
910 	    alloc_size > INT_MAX) {
911 		return LOAD_BADMACHO;
912 	}
913 
914 	/*
915 	 * Map the load commands into kernel memory.
916 	 */
917 	addr = kalloc_data(alloc_size, Z_WAITOK);
918 	if (addr == NULL) {
919 		return LOAD_NOSPACE;
920 	}
921 
922 	error = vn_rdwr(UIO_READ, vp, addr, (int)alloc_size, file_offset,
923 	    UIO_SYSSPACE, 0, vfs_context_ucred(imgp->ip_vfs_context), &resid, p);
924 	if (error) {
925 		kfree_data(addr, alloc_size);
926 		return LOAD_IOERROR;
927 	}
928 
929 	if (resid) {
930 		{
931 			/* We must be able to read in as much as the mach_header indicated */
932 			kfree_data(addr, alloc_size);
933 			return LOAD_BADMACHO;
934 		}
935 	}
936 
937 	/*
938 	 *  Scan through the commands, processing each one as necessary.
939 	 *  We parse in three passes through the headers:
940 	 *  0: determine if TEXT and DATA boundary can be page-aligned, load platform version
941 	 *  1: thread state, uuid, code signature
942 	 *  2: segments
943 	 *  3: dyld, encryption, check entry point
944 	 */
945 
946 	boolean_t slide_realign = FALSE;
947 #if __arm64__
948 	if (!abi64) {
949 		slide_realign = TRUE;
950 	}
951 #endif
952 
953 	for (pass = 0; pass <= 3; pass++) {
954 		if (pass == 1) {
955 #if __arm64__
956 			boolean_t       is_pie;
957 			int64_t         adjust;
958 
959 			is_pie = ((header->flags & MH_PIE) != 0);
960 			if (pagezero_end != 0 &&
961 			    pagezero_end < effective_page_size) {
962 				/* need at least 1 page for PAGEZERO */
963 				adjust = effective_page_size;
964 				MACHO_PRINTF(("pagezero boundary at "
965 				    "0x%llx; adjust slide from "
966 				    "0x%llx to 0x%llx%s\n",
967 				    (uint64_t) pagezero_end,
968 				    slide,
969 				    slide + adjust,
970 				    (is_pie
971 				    ? ""
972 				    : " BUT NO PIE ****** :-(")));
973 				if (is_pie) {
974 					slide += adjust;
975 					pagezero_end += adjust;
976 					executable_end += adjust;
977 					writable_start += adjust;
978 				}
979 			}
980 			if (pagezero_end != 0) {
981 				result->has_pagezero = TRUE;
982 			}
983 			if (executable_end == writable_start &&
984 			    (executable_end & effective_page_mask) != 0 &&
985 			    (executable_end & FOURK_PAGE_MASK) == 0) {
986 				/*
987 				 * The TEXT/DATA boundary is 4K-aligned but
988 				 * not page-aligned.  Adjust the slide to make
989 				 * it page-aligned and avoid having a page
990 				 * with both write and execute permissions.
991 				 */
992 				adjust =
993 				    (effective_page_size -
994 				    (executable_end & effective_page_mask));
995 				MACHO_PRINTF(("page-unaligned X-W boundary at "
996 				    "0x%llx; adjust slide from "
997 				    "0x%llx to 0x%llx%s\n",
998 				    (uint64_t) executable_end,
999 				    slide,
1000 				    slide + adjust,
1001 				    (is_pie
1002 				    ? ""
1003 				    : " BUT NO PIE ****** :-(")));
1004 				if (is_pie) {
1005 					slide += adjust;
1006 				}
1007 			}
1008 #endif /* __arm64__ */
1009 
1010 			if (dyld_no_load_addr && binresult) {
1011 				/*
1012 				 * The dyld Mach-O does not specify a load address. Try to locate
1013 				 * it right after the main binary. If binresult == NULL, load
1014 				 * directly to the given slide.
1015 				 */
1016 				mach_vm_address_t max_vm_addr = binresult->max_vm_addr;
1017 				slide = vm_map_round_page(slide + max_vm_addr, effective_page_mask);
1018 			}
1019 		}
1020 
1021 		/*
1022 		 * Check that the entry point is contained in an executable segment
1023 		 */
1024 		if ((pass == 3) && (thread != THREAD_NULL)) {
1025 			if (depth == 1 && imgp && (imgp->ip_flags & IMGPF_DRIVER)) {
1026 				/* Driver binaries must have driverkit platform */
1027 				if (result->ip_platform == PLATFORM_DRIVERKIT) {
1028 					/* Driver binaries have no entry point */
1029 					ret = setup_driver_main(thread, slide, result);
1030 				} else {
1031 					ret = LOAD_FAILURE;
1032 				}
1033 			} else if (!result->using_lcmain && result->validentry == 0) {
1034 				ret = LOAD_FAILURE;
1035 			}
1036 			if (ret != KERN_SUCCESS) {
1037 				thread_state_initialize(thread);
1038 				break;
1039 			}
1040 		}
1041 
1042 		/*
1043 		 * Check that some segment maps the start of the mach-o file, which is
1044 		 * needed by the dynamic loader to read the mach headers, etc.
1045 		 */
1046 		if ((pass == 3) && (found_header_segment == FALSE)) {
1047 			ret = LOAD_BADMACHO;
1048 			break;
1049 		}
1050 
1051 		/*
1052 		 * Loop through each of the load_commands indicated by the
1053 		 * Mach-O header; if an absurd value is provided, we just
1054 		 * run off the end of the reserved section by incrementing
1055 		 * the offset too far, so we are implicitly fail-safe.
1056 		 */
1057 		offset = mach_header_sz;
1058 		ncmds = header->ncmds;
1059 
1060 		while (ncmds--) {
1061 			/* ensure enough space for a minimal load command */
1062 			if (offset + sizeof(struct load_command) > cmds_size) {
1063 				ret = LOAD_BADMACHO;
1064 				break;
1065 			}
1066 
1067 			/*
1068 			 *	Get a pointer to the command.
1069 			 */
1070 			lcp = (struct load_command *)((uintptr_t)addr + offset);
1071 			oldoffset = offset;
1072 
1073 			/*
1074 			 * Perform prevalidation of the struct load_command
1075 			 * before we attempt to use its contents.  Invalid
1076 			 * values are ones which result in an overflow, or
1077 			 * which can not possibly be valid commands, or which
1078 			 * straddle or exist past the reserved section at the
1079 			 * start of the image.
1080 			 */
1081 			if (os_add_overflow(offset, lcp->cmdsize, &offset) ||
1082 			    lcp->cmdsize < sizeof(struct load_command) ||
1083 			    offset > cmds_size) {
1084 				ret = LOAD_BADMACHO;
1085 				break;
1086 			}
1087 
1088 			/*
1089 			 * Act on struct load_command's for which kernel
1090 			 * intervention is required.
1091 			 * Note that each load command implementation is expected to validate
1092 			 * that lcp->cmdsize is large enough to fit its specific struct type
1093 			 * before dereferencing fields not covered by struct load_command.
1094 			 */
1095 			switch (lcp->cmd) {
1096 			case LC_SEGMENT: {
1097 				struct segment_command *scp = (struct segment_command *) lcp;
1098 				if (scp->cmdsize < sizeof(*scp)) {
1099 					ret = LOAD_BADMACHO;
1100 					break;
1101 				}
1102 				if (pass == 0) {
1103 					if (is_dyld && scp->vmaddr == 0 && scp->fileoff == 0) {
1104 						dyld_no_load_addr = TRUE;
1105 						if (!slide_realign) {
1106 							/* got what we need, bail early on pass 0 */
1107 							continue;
1108 						}
1109 					}
1110 
1111 #if __arm64__
1112 					assert(!abi64);
1113 
1114 					if (scp->initprot == 0 && scp->maxprot == 0 && scp->vmaddr == 0) {
1115 						/* PAGEZERO */
1116 						if (os_add3_overflow(scp->vmaddr, scp->vmsize, slide, &pagezero_end) || pagezero_end > UINT32_MAX) {
1117 							ret = LOAD_BADMACHO;
1118 							break;
1119 						}
1120 					}
1121 					if (scp->initprot & VM_PROT_EXECUTE) {
1122 						/* TEXT */
1123 						if (os_add3_overflow(scp->vmaddr, scp->vmsize, slide, &executable_end) || executable_end > UINT32_MAX) {
1124 							ret = LOAD_BADMACHO;
1125 							break;
1126 						}
1127 					}
1128 					if (scp->initprot & VM_PROT_WRITE) {
1129 						/* DATA */
1130 						if (os_add_overflow(scp->vmaddr, slide, &writable_start) || writable_start > UINT32_MAX) {
1131 							ret = LOAD_BADMACHO;
1132 							break;
1133 						}
1134 					}
1135 #endif /* __arm64__ */
1136 					break;
1137 				}
1138 
1139 				if (pass == 1 && !strncmp(scp->segname, "__XHDR", sizeof(scp->segname))) {
1140 					found_xhdr = TRUE;
1141 				}
1142 
1143 				if (pass != 2) {
1144 					break;
1145 				}
1146 
1147 				if (abi64) {
1148 					/*
1149 					 * Having an LC_SEGMENT command for the
1150 					 * wrong ABI is invalid <rdar://problem/11021230>
1151 					 */
1152 					ret = LOAD_BADMACHO;
1153 					break;
1154 				}
1155 
1156 				ret = load_segment(lcp,
1157 				    header->filetype,
1158 				    control,
1159 				    file_offset,
1160 				    macho_size,
1161 				    vp,
1162 				    map,
1163 				    slide,
1164 				    result,
1165 				    imgp);
1166 				if (ret == LOAD_SUCCESS && scp->fileoff == 0 && scp->filesize > 0) {
1167 					/* Enforce a single segment mapping offset zero, with R+X
1168 					 * protection. */
1169 					if (found_header_segment ||
1170 					    ((scp->initprot & (VM_PROT_READ | VM_PROT_EXECUTE)) != (VM_PROT_READ | VM_PROT_EXECUTE))) {
1171 						ret = LOAD_BADMACHO;
1172 						break;
1173 					}
1174 					found_header_segment = TRUE;
1175 				}
1176 
1177 				break;
1178 			}
1179 			case LC_SEGMENT_64: {
1180 				struct segment_command_64 *scp64 = (struct segment_command_64 *) lcp;
1181 				if (scp64->cmdsize < sizeof(*scp64)) {
1182 					ret = LOAD_BADMACHO;
1183 					break;
1184 				}
1185 				if (pass == 0) {
1186 					if (is_dyld && scp64->vmaddr == 0 && scp64->fileoff == 0) {
1187 						dyld_no_load_addr = TRUE;
1188 					}
1189 					/* got what we need, bail early on pass 0 */
1190 					continue;
1191 				}
1192 
1193 				if (pass == 1 && !strncmp(scp64->segname, "__XHDR", sizeof(scp64->segname))) {
1194 					found_xhdr = TRUE;
1195 				}
1196 
1197 				if (pass != 2) {
1198 					break;
1199 				}
1200 
1201 				if (!abi64) {
1202 					/*
1203 					 * Having an LC_SEGMENT_64 command for the
1204 					 * wrong ABI is invalid <rdar://problem/11021230>
1205 					 */
1206 					ret = LOAD_BADMACHO;
1207 					break;
1208 				}
1209 
1210 				ret = load_segment(lcp,
1211 				    header->filetype,
1212 				    control,
1213 				    file_offset,
1214 				    macho_size,
1215 				    vp,
1216 				    map,
1217 				    slide,
1218 				    result,
1219 				    imgp);
1220 
1221 				if (ret == LOAD_SUCCESS && scp64->fileoff == 0 && scp64->filesize > 0) {
1222 					/* Enforce a single segment mapping offset zero, with R+X
1223 					 * protection. */
1224 					if (found_header_segment ||
1225 					    ((scp64->initprot & (VM_PROT_READ | VM_PROT_EXECUTE)) != (VM_PROT_READ | VM_PROT_EXECUTE))) {
1226 						ret = LOAD_BADMACHO;
1227 						break;
1228 					}
1229 					found_header_segment = TRUE;
1230 				}
1231 
1232 				break;
1233 			}
1234 			case LC_UNIXTHREAD: {
1235 				boolean_t is_x86_64_compat_binary = FALSE;
1236 				if (pass != 1) {
1237 					break;
1238 				}
1239 #if CONFIG_ROSETTA
1240 				if (depth == 2 && (imgp->ip_flags & IMGPF_ROSETTA)) {
1241 					// Ignore dyld, Rosetta will parse it's load commands to get the
1242 					// entry point.
1243 					result->validentry = 1;
1244 					break;
1245 				}
1246 #endif
1247 				ret = load_unixthread(
1248 					(struct thread_command *) lcp,
1249 					thread,
1250 					slide,
1251 					is_x86_64_compat_binary,
1252 					result);
1253 				break;
1254 			}
1255 			case LC_MAIN:
1256 				if (pass != 1) {
1257 					break;
1258 				}
1259 				if (depth != 1) {
1260 					break;
1261 				}
1262 				ret = load_main(
1263 					(struct entry_point_command *) lcp,
1264 					thread,
1265 					slide,
1266 					result);
1267 				break;
1268 			case LC_LOAD_DYLINKER:
1269 				if (pass != 3) {
1270 					break;
1271 				}
1272 				if ((depth == 1) && (dlp == 0)) {
1273 					dlp = (struct dylinker_command *)lcp;
1274 				} else {
1275 					ret = LOAD_FAILURE;
1276 				}
1277 				break;
1278 			case LC_UUID:
1279 				if (pass == 1 && depth == 1) {
1280 					ret = load_uuid((struct uuid_command *) lcp,
1281 					    (char *)addr + cmds_size,
1282 					    result);
1283 				}
1284 				break;
1285 			case LC_CODE_SIGNATURE:
1286 				/* CODE SIGNING */
1287 				if (pass != 1) {
1288 					break;
1289 				}
1290 
1291 				/* pager -> uip ->
1292 				 *  load signatures & store in uip
1293 				 *  set VM object "signed_pages"
1294 				 */
1295 				ret = load_code_signature(
1296 					(struct linkedit_data_command *) lcp,
1297 					vp,
1298 					file_offset,
1299 					macho_size,
1300 					header->cputype,
1301 					header->cpusubtype,
1302 					result,
1303 					imgp);
1304 				if (ret != LOAD_SUCCESS) {
1305 					printf("proc %d: load code signature error %d "
1306 					    "for file \"%s\"\n",
1307 					    proc_getpid(p), ret, vp->v_name);
1308 					/*
1309 					 * Allow injections to be ignored on devices w/o enforcement enabled
1310 					 */
1311 					if (!cs_process_global_enforcement()) {
1312 						ret = LOAD_SUCCESS; /* ignore error */
1313 					}
1314 				} else {
1315 					got_code_signatures = TRUE;
1316 				}
1317 
1318 				if (got_code_signatures) {
1319 					unsigned tainted = CS_VALIDATE_TAINTED;
1320 					boolean_t valid = FALSE;
1321 					vm_size_t off = 0;
1322 
1323 
1324 					if (cs_debug > 10) {
1325 						printf("validating initial pages of %s\n", vp->v_name);
1326 					}
1327 
1328 					while (off < alloc_size && ret == LOAD_SUCCESS) {
1329 						tainted = CS_VALIDATE_TAINTED;
1330 
1331 						valid = cs_validate_range(vp,
1332 						    NULL,
1333 						    file_offset + off,
1334 						    (const void *)((uintptr_t)addr + off),
1335 						    MIN(PAGE_SIZE, cmds_size),
1336 						    &tainted);
1337 						if (!valid || (tainted & CS_VALIDATE_TAINTED)) {
1338 							if (cs_debug) {
1339 								printf("CODE SIGNING: %s[%d]: invalid initial page at offset %lld validated:%d tainted:%d csflags:0x%x\n",
1340 								    vp->v_name, proc_getpid(p), (long long)(file_offset + off), valid, tainted, result->csflags);
1341 							}
1342 							if (cs_process_global_enforcement() ||
1343 							    (result->csflags & (CS_HARD | CS_KILL | CS_ENFORCEMENT))) {
1344 								ret = LOAD_FAILURE;
1345 							}
1346 							result->csflags &= ~CS_VALID;
1347 						}
1348 						off += PAGE_SIZE;
1349 					}
1350 				}
1351 
1352 				break;
1353 #if CONFIG_CODE_DECRYPTION
1354 			case LC_ENCRYPTION_INFO:
1355 			case LC_ENCRYPTION_INFO_64:
1356 				if (pass != 3) {
1357 					break;
1358 				}
1359 				ret = set_code_unprotect(
1360 					(struct encryption_info_command *) lcp,
1361 					addr, map, slide, vp, file_offset,
1362 					header->cputype, header->cpusubtype);
1363 				if (ret != LOAD_SUCCESS) {
1364 					os_reason_t load_failure_reason = OS_REASON_NULL;
1365 					printf("proc %d: set_code_unprotect() error %d "
1366 					    "for file \"%s\"\n",
1367 					    proc_getpid(p), ret, vp->v_name);
1368 					/*
1369 					 * Don't let the app run if it's
1370 					 * encrypted but we failed to set up the
1371 					 * decrypter. If the keys are missing it will
1372 					 * return LOAD_DECRYPTFAIL.
1373 					 */
1374 					if (ret == LOAD_DECRYPTFAIL) {
1375 						/* failed to load due to missing FP keys */
1376 						proc_lock(p);
1377 						p->p_lflag |= P_LTERM_DECRYPTFAIL;
1378 						proc_unlock(p);
1379 
1380 						KERNEL_DEBUG_CONSTANT(BSDDBG_CODE(DBG_BSD_PROC, BSD_PROC_EXITREASON_CREATE) | DBG_FUNC_NONE,
1381 						    proc_getpid(p), OS_REASON_EXEC, EXEC_EXIT_REASON_FAIRPLAY_DECRYPT, 0, 0);
1382 						load_failure_reason = os_reason_create(OS_REASON_EXEC, EXEC_EXIT_REASON_FAIRPLAY_DECRYPT);
1383 					} else {
1384 						KERNEL_DEBUG_CONSTANT(BSDDBG_CODE(DBG_BSD_PROC, BSD_PROC_EXITREASON_CREATE) | DBG_FUNC_NONE,
1385 						    proc_getpid(p), OS_REASON_EXEC, EXEC_EXIT_REASON_DECRYPT, 0, 0);
1386 						load_failure_reason = os_reason_create(OS_REASON_EXEC, EXEC_EXIT_REASON_DECRYPT);
1387 					}
1388 
1389 					/*
1390 					 * Don't signal the process if it was forked and in a partially constructed
1391 					 * state as part of a spawn -- it will just be torn down when the exec fails.
1392 					 */
1393 					if (!spawn) {
1394 						assert(load_failure_reason != OS_REASON_NULL);
1395 						{
1396 							psignal_with_reason(current_proc(), SIGKILL, load_failure_reason);
1397 							load_failure_reason = OS_REASON_NULL;
1398 						}
1399 					} else {
1400 						os_reason_free(load_failure_reason);
1401 						load_failure_reason = OS_REASON_NULL;
1402 					}
1403 				}
1404 				break;
1405 #endif
1406 			case LC_VERSION_MIN_IPHONEOS:
1407 			case LC_VERSION_MIN_MACOSX:
1408 			case LC_VERSION_MIN_WATCHOS:
1409 			case LC_VERSION_MIN_TVOS: {
1410 				struct version_min_command *vmc;
1411 
1412 				if (depth != 1 || pass != 0) {
1413 					break;
1414 				}
1415 				vmc = (struct version_min_command *) lcp;
1416 				ret = load_version(vmc, &found_version_cmd, imgp, result);
1417 #if XNU_TARGET_OS_OSX
1418 				if (ret == LOAD_SUCCESS) {
1419 					if (result->ip_platform == PLATFORM_IOS) {
1420 						vm_map_mark_alien(map);
1421 					} else {
1422 						assert(!vm_map_is_alien(map));
1423 					}
1424 				}
1425 #endif /* XNU_TARGET_OS_OSX */
1426 				break;
1427 			}
1428 			case LC_BUILD_VERSION: {
1429 				if (depth != 1 || pass != 0) {
1430 					break;
1431 				}
1432 				struct build_version_command* bvc = (struct build_version_command*)lcp;
1433 				if (bvc->cmdsize < sizeof(*bvc)) {
1434 					ret = LOAD_BADMACHO;
1435 					break;
1436 				}
1437 				if (found_version_cmd == TRUE) {
1438 					ret = LOAD_BADMACHO;
1439 					break;
1440 				}
1441 				result->ip_platform = bvc->platform;
1442 				result->lr_sdk = bvc->sdk;
1443 				result->lr_min_sdk = bvc->minos;
1444 				found_version_cmd = TRUE;
1445 #if XNU_TARGET_OS_OSX
1446 				if (result->ip_platform == PLATFORM_IOS) {
1447 					vm_map_mark_alien(map);
1448 				} else {
1449 					assert(!vm_map_is_alien(map));
1450 				}
1451 #endif /* XNU_TARGET_OS_OSX */
1452 				break;
1453 			}
1454 			default:
1455 				/* Other commands are ignored by the kernel */
1456 				ret = LOAD_SUCCESS;
1457 				break;
1458 			}
1459 			if (ret != LOAD_SUCCESS) {
1460 				break;
1461 			}
1462 		}
1463 		if (ret != LOAD_SUCCESS) {
1464 			break;
1465 		}
1466 	}
1467 
1468 	if (ret == LOAD_SUCCESS) {
1469 		if (!got_code_signatures && cs_process_global_enforcement()) {
1470 			ret = LOAD_FAILURE;
1471 		}
1472 
1473 		/* Make sure if we need dyld, we got it */
1474 		if (result->needs_dynlinker && !dlp) {
1475 			ret = LOAD_FAILURE;
1476 		}
1477 
1478 		if ((ret == LOAD_SUCCESS) && (dlp != 0)) {
1479 			/*
1480 			 * load the dylinker, and slide it by the independent DYLD ASLR
1481 			 * offset regardless of the PIE-ness of the main binary.
1482 			 */
1483 			ret = load_dylinker(dlp, header->cputype, map, thread, depth,
1484 			    dyld_aslr_offset, result, imgp);
1485 		}
1486 
1487 #if CONFIG_ROSETTA
1488 		if ((ret == LOAD_SUCCESS) && (depth == 1) && (imgp->ip_flags & IMGPF_ROSETTA)) {
1489 			ret = load_rosetta(map, thread, result, imgp);
1490 			if (ret == LOAD_SUCCESS) {
1491 				if (result->user_stack_alloc_size != 0) {
1492 					// If a stack allocation is required then add a 4gb gap after the main
1493 					// binary/dyld for the worst case static translation size.
1494 					mach_vm_size_t reserved_aot_size = 0x100000000;
1495 					vm_map_offset_t mask = vm_map_page_mask(map);
1496 
1497 					mach_vm_address_t vm_end;
1498 					if (dlp != 0) {
1499 						vm_end = vm_map_round_page(result->dynlinker_max_vm_addr, mask);
1500 					} else {
1501 						vm_end = vm_map_round_page(result->max_vm_addr, mask);
1502 					}
1503 
1504 					mach_vm_size_t user_stack_size = vm_map_round_page(result->user_stack_alloc_size, mask);
1505 					result->user_stack = vm_map_round_page(vm_end + user_stack_size + reserved_aot_size + slide, mask);
1506 				}
1507 			}
1508 		}
1509 #endif
1510 
1511 		if ((ret == LOAD_SUCCESS) && (depth == 1)) {
1512 			if (result->thread_count == 0) {
1513 				ret = LOAD_FAILURE;
1514 			}
1515 #if CONFIG_ENFORCE_SIGNED_CODE
1516 			if (!(result->csflags & CS_NO_UNTRUSTED_HELPERS)) {
1517 				ret = LOAD_FAILURE;
1518 			}
1519 #endif
1520 		}
1521 	}
1522 
1523 	if (ret == LOAD_BADMACHO && found_xhdr) {
1524 		ret = LOAD_BADMACHO_UPX;
1525 	}
1526 
1527 	kfree_data(addr, alloc_size);
1528 
1529 	return ret;
1530 }
1531 
1532 load_return_t
validate_potential_simulator_binary(cpu_type_t exectype __unused,struct image_params * imgp __unused,off_t file_offset __unused,off_t macho_size __unused)1533 validate_potential_simulator_binary(
1534 	cpu_type_t               exectype __unused,
1535 	struct image_params      *imgp __unused,
1536 	off_t                    file_offset __unused,
1537 	off_t                    macho_size __unused)
1538 {
1539 #if __x86_64__
1540 	/* Allow 32 bit exec only for simulator binaries */
1541 	if (bootarg_no32exec && imgp != NULL && exectype == CPU_TYPE_X86) {
1542 		if (imgp->ip_simulator_binary == IMGPF_SB_DEFAULT) {
1543 			boolean_t simulator_binary = check_if_simulator_binary(imgp, file_offset, macho_size);
1544 			imgp->ip_simulator_binary = simulator_binary ? IMGPF_SB_TRUE : IMGPF_SB_FALSE;
1545 		}
1546 
1547 		if (imgp->ip_simulator_binary != IMGPF_SB_TRUE) {
1548 			return LOAD_BADARCH;
1549 		}
1550 	}
1551 #endif
1552 	return LOAD_SUCCESS;
1553 }
1554 
1555 #if __x86_64__
1556 static boolean_t
check_if_simulator_binary(struct image_params * imgp,off_t file_offset,off_t macho_size)1557 check_if_simulator_binary(
1558 	struct image_params     *imgp,
1559 	off_t                   file_offset,
1560 	off_t                   macho_size)
1561 {
1562 	struct mach_header      *header;
1563 	char                    *ip_vdata = NULL;
1564 	kauth_cred_t            cred = NULL;
1565 	uint32_t                ncmds;
1566 	struct load_command     *lcp;
1567 	boolean_t               simulator_binary = FALSE;
1568 	void *                  addr = NULL;
1569 	vm_size_t               alloc_size, cmds_size;
1570 	size_t                  offset;
1571 	proc_t                  p = current_proc();             /* XXXX */
1572 	int                     error;
1573 	int                     resid = 0;
1574 	size_t                  mach_header_sz = sizeof(struct mach_header);
1575 
1576 
1577 	cred =  kauth_cred_proc_ref(p);
1578 
1579 	/* Allocate page to copyin mach header */
1580 	ip_vdata = kalloc_data(PAGE_SIZE, Z_WAITOK | Z_ZERO);
1581 	if (ip_vdata == NULL) {
1582 		goto bad;
1583 	}
1584 
1585 	/* Read the Mach-O header */
1586 	error = vn_rdwr(UIO_READ, imgp->ip_vp, ip_vdata,
1587 	    PAGE_SIZE, file_offset,
1588 	    UIO_SYSSPACE, (IO_UNIT | IO_NODELOCKED),
1589 	    cred, &resid, p);
1590 	if (error) {
1591 		goto bad;
1592 	}
1593 
1594 	header = (struct mach_header *)ip_vdata;
1595 
1596 	if (header->magic == MH_MAGIC_64 ||
1597 	    header->magic == MH_CIGAM_64) {
1598 		mach_header_sz = sizeof(struct mach_header_64);
1599 	}
1600 
1601 	/* ensure header + sizeofcmds falls within the file */
1602 	if (os_add_overflow(mach_header_sz, header->sizeofcmds, &cmds_size) ||
1603 	    (off_t)cmds_size > macho_size ||
1604 	    round_page_overflow(cmds_size, &alloc_size) ||
1605 	    alloc_size > INT_MAX) {
1606 		goto bad;
1607 	}
1608 
1609 	/*
1610 	 * Map the load commands into kernel memory.
1611 	 */
1612 	addr = kalloc_data(alloc_size, Z_WAITOK);
1613 	if (addr == NULL) {
1614 		goto bad;
1615 	}
1616 
1617 	error = vn_rdwr(UIO_READ, imgp->ip_vp, addr, (int)alloc_size, file_offset,
1618 	    UIO_SYSSPACE, IO_NODELOCKED, cred, &resid, p);
1619 	if (error) {
1620 		goto bad;
1621 	}
1622 
1623 	if (resid) {
1624 		/* We must be able to read in as much as the mach_header indicated */
1625 		goto bad;
1626 	}
1627 
1628 	/*
1629 	 * Loop through each of the load_commands indicated by the
1630 	 * Mach-O header; if an absurd value is provided, we just
1631 	 * run off the end of the reserved section by incrementing
1632 	 * the offset too far, so we are implicitly fail-safe.
1633 	 */
1634 	offset = mach_header_sz;
1635 	ncmds = header->ncmds;
1636 
1637 	while (ncmds--) {
1638 		/* ensure enough space for a minimal load command */
1639 		if (offset + sizeof(struct load_command) > cmds_size) {
1640 			break;
1641 		}
1642 
1643 		/*
1644 		 *	Get a pointer to the command.
1645 		 */
1646 		lcp = (struct load_command *)((uintptr_t)addr + offset);
1647 
1648 		/*
1649 		 * Perform prevalidation of the struct load_command
1650 		 * before we attempt to use its contents.  Invalid
1651 		 * values are ones which result in an overflow, or
1652 		 * which can not possibly be valid commands, or which
1653 		 * straddle or exist past the reserved section at the
1654 		 * start of the image.
1655 		 */
1656 		if (os_add_overflow(offset, lcp->cmdsize, &offset) ||
1657 		    lcp->cmdsize < sizeof(struct load_command) ||
1658 		    offset > cmds_size) {
1659 			break;
1660 		}
1661 
1662 		/* Check if its a simulator binary. */
1663 		switch (lcp->cmd) {
1664 		case LC_VERSION_MIN_WATCHOS:
1665 			simulator_binary = TRUE;
1666 			break;
1667 
1668 		case LC_BUILD_VERSION: {
1669 			struct build_version_command *bvc;
1670 
1671 			bvc = (struct build_version_command *) lcp;
1672 			if (bvc->cmdsize < sizeof(*bvc)) {
1673 				/* unsafe to use this command struct if cmdsize
1674 				* validated above is too small for it to fit */
1675 				break;
1676 			}
1677 			if (bvc->platform == PLATFORM_IOSSIMULATOR ||
1678 			    bvc->platform == PLATFORM_WATCHOSSIMULATOR) {
1679 				simulator_binary = TRUE;
1680 			}
1681 
1682 			break;
1683 		}
1684 
1685 		case LC_VERSION_MIN_IPHONEOS: {
1686 			simulator_binary = TRUE;
1687 			break;
1688 		}
1689 
1690 		default:
1691 			/* ignore other load commands */
1692 			break;
1693 		}
1694 
1695 		if (simulator_binary == TRUE) {
1696 			break;
1697 		}
1698 	}
1699 
1700 bad:
1701 	if (ip_vdata) {
1702 		kfree_data(ip_vdata, PAGE_SIZE);
1703 	}
1704 
1705 	if (cred) {
1706 		kauth_cred_unref(&cred);
1707 	}
1708 
1709 	if (addr) {
1710 		kfree_data(addr, alloc_size);
1711 	}
1712 
1713 	return simulator_binary;
1714 }
1715 #endif /* __x86_64__ */
1716 
1717 #if CONFIG_CODE_DECRYPTION
1718 
1719 #define APPLE_UNPROTECTED_HEADER_SIZE   (3 * 4096)
1720 
1721 static load_return_t
unprotect_dsmos_segment(uint64_t file_off,uint64_t file_size,struct vnode * vp,off_t macho_offset,vm_map_t map,vm_map_offset_t map_addr,vm_map_size_t map_size)1722 unprotect_dsmos_segment(
1723 	uint64_t        file_off,
1724 	uint64_t        file_size,
1725 	struct vnode    *vp,
1726 	off_t           macho_offset,
1727 	vm_map_t        map,
1728 	vm_map_offset_t map_addr,
1729 	vm_map_size_t   map_size)
1730 {
1731 	kern_return_t   kr;
1732 	uint64_t        slice_off;
1733 
1734 	/*
1735 	 * The first APPLE_UNPROTECTED_HEADER_SIZE bytes (from offset 0 of
1736 	 * this part of a Universal binary) are not protected...
1737 	 * The rest needs to be "transformed".
1738 	 */
1739 	slice_off = file_off - macho_offset;
1740 	if (slice_off <= APPLE_UNPROTECTED_HEADER_SIZE &&
1741 	    slice_off + file_size <= APPLE_UNPROTECTED_HEADER_SIZE) {
1742 		/* it's all unprotected, nothing to do... */
1743 		kr = KERN_SUCCESS;
1744 	} else {
1745 		if (slice_off <= APPLE_UNPROTECTED_HEADER_SIZE) {
1746 			/*
1747 			 * We start mapping in the unprotected area.
1748 			 * Skip the unprotected part...
1749 			 */
1750 			uint64_t delta_file;
1751 			vm_map_offset_t delta_map;
1752 
1753 			delta_file = (uint64_t)APPLE_UNPROTECTED_HEADER_SIZE;
1754 			delta_file -= slice_off;
1755 			if (os_convert_overflow(delta_file, &delta_map)) {
1756 				return LOAD_BADMACHO;
1757 			}
1758 			if (os_add_overflow(map_addr, delta_map, &map_addr)) {
1759 				return LOAD_BADMACHO;
1760 			}
1761 			if (os_sub_overflow(map_size, delta_map, &map_size)) {
1762 				return LOAD_BADMACHO;
1763 			}
1764 		}
1765 		/* ... transform the rest of the mapping. */
1766 		struct pager_crypt_info crypt_info;
1767 		crypt_info.page_decrypt = dsmos_page_transform;
1768 		crypt_info.crypt_ops = NULL;
1769 		crypt_info.crypt_end = NULL;
1770 #pragma unused(vp, macho_offset)
1771 		crypt_info.crypt_ops = (void *)0x2e69cf40;
1772 		vm_map_offset_t crypto_backing_offset;
1773 		crypto_backing_offset = -1; /* i.e. use map entry's offset */
1774 #if VM_MAP_DEBUG_APPLE_PROTECT
1775 		if (vm_map_debug_apple_protect) {
1776 			struct proc *p;
1777 			p = current_proc();
1778 			printf("APPLE_PROTECT: %d[%s] map %p "
1779 			    "[0x%llx:0x%llx] %s(%s)\n",
1780 			    proc_getpid(p), p->p_comm, map,
1781 			    (uint64_t) map_addr,
1782 			    (uint64_t) (map_addr + map_size),
1783 			    __FUNCTION__, vp->v_name);
1784 		}
1785 #endif /* VM_MAP_DEBUG_APPLE_PROTECT */
1786 
1787 		/* The DSMOS pager can only be used by apple signed code */
1788 		struct cs_blob * blob = csvnode_get_blob(vp, file_off);
1789 		if (blob == NULL || !blob->csb_platform_binary || blob->csb_platform_path) {
1790 			return LOAD_FAILURE;
1791 		}
1792 
1793 		kr = vm_map_apple_protected(map,
1794 		    map_addr,
1795 		    map_addr + map_size,
1796 		    crypto_backing_offset,
1797 		    &crypt_info,
1798 		    CRYPTID_APP_ENCRYPTION);
1799 	}
1800 
1801 	if (kr != KERN_SUCCESS) {
1802 		return LOAD_FAILURE;
1803 	}
1804 	return LOAD_SUCCESS;
1805 }
1806 #else   /* CONFIG_CODE_DECRYPTION */
1807 static load_return_t
unprotect_dsmos_segment(__unused uint64_t file_off,__unused uint64_t file_size,__unused struct vnode * vp,__unused off_t macho_offset,__unused vm_map_t map,__unused vm_map_offset_t map_addr,__unused vm_map_size_t map_size)1808 unprotect_dsmos_segment(
1809 	__unused        uint64_t        file_off,
1810 	__unused        uint64_t        file_size,
1811 	__unused        struct vnode    *vp,
1812 	__unused        off_t           macho_offset,
1813 	__unused        vm_map_t        map,
1814 	__unused        vm_map_offset_t map_addr,
1815 	__unused        vm_map_size_t   map_size)
1816 {
1817 	return LOAD_SUCCESS;
1818 }
1819 #endif  /* CONFIG_CODE_DECRYPTION */
1820 
1821 
1822 /*
1823  * map_segment:
1824  *	Maps a Mach-O segment, taking care of mis-alignment (wrt the system
1825  *	page size) issues.
1826  *
1827  *	The mapping might result in 1, 2 or 3 map entries:
1828  *      1. for the first page, which could be overlap with the previous
1829  *         mapping,
1830  *      2. for the center (if applicable),
1831  *      3. for the last page, which could overlap with the next mapping.
1832  *
1833  *	For each of those map entries, we might have to interpose a
1834  *	"fourk_pager" to deal with mis-alignment wrt the system page size,
1835  *	either in the mapping address and/or size or the file offset and/or
1836  *	size.
1837  *	The "fourk_pager" itself would be mapped with proper alignment
1838  *	wrt the system page size and would then be populated with the
1839  *	information about the intended mapping, with a "4KB" granularity.
1840  */
1841 static kern_return_t
map_segment(vm_map_t map,vm_map_offset_t vm_start,vm_map_offset_t vm_end,memory_object_control_t control,vm_map_offset_t file_start,vm_map_offset_t file_end,vm_prot_t initprot,vm_prot_t maxprot,load_result_t * result)1842 map_segment(
1843 	vm_map_t                map,
1844 	vm_map_offset_t         vm_start,
1845 	vm_map_offset_t         vm_end,
1846 	memory_object_control_t control,
1847 	vm_map_offset_t         file_start,
1848 	vm_map_offset_t         file_end,
1849 	vm_prot_t               initprot,
1850 	vm_prot_t               maxprot,
1851 	load_result_t           *result)
1852 {
1853 	vm_map_offset_t cur_offset, cur_start, cur_end;
1854 	kern_return_t   ret;
1855 	vm_map_offset_t effective_page_mask;
1856 	vm_map_kernel_flags_t vmk_flags, cur_vmk_flags;
1857 
1858 	if (vm_end < vm_start ||
1859 	    file_end < file_start) {
1860 		return LOAD_BADMACHO;
1861 	}
1862 	if (vm_end == vm_start ||
1863 	    file_end == file_start) {
1864 		/* nothing to map... */
1865 		return LOAD_SUCCESS;
1866 	}
1867 
1868 	effective_page_mask = vm_map_page_mask(map);
1869 
1870 	vmk_flags = VM_MAP_KERNEL_FLAGS_FIXED();
1871 	if (vm_map_page_aligned(vm_start, effective_page_mask) &&
1872 	    vm_map_page_aligned(vm_end, effective_page_mask) &&
1873 	    vm_map_page_aligned(file_start, effective_page_mask) &&
1874 	    vm_map_page_aligned(file_end, effective_page_mask)) {
1875 		/* all page-aligned and map-aligned: proceed */
1876 	} else {
1877 #if __arm64__
1878 		/* use an intermediate "4K" pager */
1879 		vmk_flags.vmkf_fourk = TRUE;
1880 #else /* __arm64__ */
1881 		panic("map_segment: unexpected mis-alignment "
1882 		    "vm[0x%llx:0x%llx] file[0x%llx:0x%llx]\n",
1883 		    (uint64_t) vm_start,
1884 		    (uint64_t) vm_end,
1885 		    (uint64_t) file_start,
1886 		    (uint64_t) file_end);
1887 #endif /* __arm64__ */
1888 	}
1889 
1890 	cur_offset = 0;
1891 	cur_start = vm_start;
1892 	cur_end = vm_start;
1893 #if __arm64__
1894 	if (!vm_map_page_aligned(vm_start, effective_page_mask)) {
1895 		/* one 4K pager for the 1st page */
1896 		cur_end = vm_map_round_page(cur_start, effective_page_mask);
1897 		if (cur_end > vm_end) {
1898 			cur_end = vm_start + (file_end - file_start);
1899 		}
1900 		if (control != MEMORY_OBJECT_CONTROL_NULL) {
1901 			/* no copy-on-read for mapped binaries */
1902 			vmk_flags.vmkf_no_copy_on_read = 1;
1903 			ret = vm_map_enter_mem_object_control(
1904 				map,
1905 				&cur_start,
1906 				cur_end - cur_start,
1907 				(mach_vm_offset_t)0,
1908 				vmk_flags,
1909 				control,
1910 				file_start + cur_offset,
1911 				TRUE, /* copy */
1912 				initprot, maxprot,
1913 				VM_INHERIT_DEFAULT);
1914 		} else {
1915 			ret = vm_map_enter_mem_object(
1916 				map,
1917 				&cur_start,
1918 				cur_end - cur_start,
1919 				(mach_vm_offset_t)0,
1920 				vmk_flags,
1921 				IPC_PORT_NULL,
1922 				0, /* offset */
1923 				TRUE, /* copy */
1924 				initprot, maxprot,
1925 				VM_INHERIT_DEFAULT);
1926 		}
1927 		if (ret != KERN_SUCCESS) {
1928 			return LOAD_NOSPACE;
1929 		}
1930 		cur_offset += cur_end - cur_start;
1931 	}
1932 #endif /* __arm64__ */
1933 	if (cur_end >= vm_start + (file_end - file_start)) {
1934 		/* all mapped: done */
1935 		goto done;
1936 	}
1937 	if (vm_map_round_page(cur_end, effective_page_mask) >=
1938 	    vm_map_trunc_page(vm_start + (file_end - file_start),
1939 	    effective_page_mask)) {
1940 		/* no middle */
1941 	} else {
1942 		cur_start = cur_end;
1943 		if ((vm_start & effective_page_mask) !=
1944 		    (file_start & effective_page_mask)) {
1945 			/* one 4K pager for the middle */
1946 			cur_vmk_flags = vmk_flags;
1947 		} else {
1948 			/* regular mapping for the middle */
1949 			cur_vmk_flags = VM_MAP_KERNEL_FLAGS_FIXED();
1950 		}
1951 
1952 #if !defined(XNU_TARGET_OS_OSX)
1953 		(void) result;
1954 #else /* !defined(XNU_TARGET_OS_OSX) */
1955 		/*
1956 		 * This process doesn't have its new csflags (from
1957 		 * the image being loaded) yet, so tell VM to override the
1958 		 * current process's CS_ENFORCEMENT for this mapping.
1959 		 */
1960 		if (result->csflags & CS_ENFORCEMENT) {
1961 			cur_vmk_flags.vmkf_cs_enforcement = TRUE;
1962 		} else {
1963 			cur_vmk_flags.vmkf_cs_enforcement = FALSE;
1964 		}
1965 		cur_vmk_flags.vmkf_cs_enforcement_override = TRUE;
1966 #endif /* !defined(XNU_TARGET_OS_OSX) */
1967 
1968 		if (result->is_rosetta && (initprot & VM_PROT_EXECUTE) == VM_PROT_EXECUTE) {
1969 			cur_vmk_flags.vmkf_translated_allow_execute = TRUE;
1970 		}
1971 
1972 		cur_end = vm_map_trunc_page(vm_start + (file_end -
1973 		    file_start),
1974 		    effective_page_mask);
1975 		if (control != MEMORY_OBJECT_CONTROL_NULL) {
1976 			/* no copy-on-read for mapped binaries */
1977 			cur_vmk_flags.vmkf_no_copy_on_read = 1;
1978 			ret = vm_map_enter_mem_object_control(
1979 				map,
1980 				&cur_start,
1981 				cur_end - cur_start,
1982 				(mach_vm_offset_t)0,
1983 				cur_vmk_flags,
1984 				control,
1985 				file_start + cur_offset,
1986 				TRUE, /* copy */
1987 				initprot, maxprot,
1988 				VM_INHERIT_DEFAULT);
1989 		} else {
1990 			ret = vm_map_enter_mem_object(
1991 				map,
1992 				&cur_start,
1993 				cur_end - cur_start,
1994 				(mach_vm_offset_t)0,
1995 				cur_vmk_flags,
1996 				IPC_PORT_NULL,
1997 				0, /* offset */
1998 				TRUE, /* copy */
1999 				initprot, maxprot,
2000 				VM_INHERIT_DEFAULT);
2001 		}
2002 		if (ret != KERN_SUCCESS) {
2003 			return LOAD_NOSPACE;
2004 		}
2005 		cur_offset += cur_end - cur_start;
2006 	}
2007 	if (cur_end >= vm_start + (file_end - file_start)) {
2008 		/* all mapped: done */
2009 		goto done;
2010 	}
2011 	cur_start = cur_end;
2012 #if __arm64__
2013 	if (!vm_map_page_aligned(vm_start + (file_end - file_start),
2014 	    effective_page_mask)) {
2015 		/* one 4K pager for the last page */
2016 		cur_end = vm_start + (file_end - file_start);
2017 		if (control != MEMORY_OBJECT_CONTROL_NULL) {
2018 			/* no copy-on-read for mapped binaries */
2019 			vmk_flags.vmkf_no_copy_on_read = 1;
2020 			ret = vm_map_enter_mem_object_control(
2021 				map,
2022 				&cur_start,
2023 				cur_end - cur_start,
2024 				(mach_vm_offset_t)0,
2025 				vmk_flags,
2026 				control,
2027 				file_start + cur_offset,
2028 				TRUE, /* copy */
2029 				initprot, maxprot,
2030 				VM_INHERIT_DEFAULT);
2031 		} else {
2032 			ret = vm_map_enter_mem_object(
2033 				map,
2034 				&cur_start,
2035 				cur_end - cur_start,
2036 				(mach_vm_offset_t)0,
2037 				vmk_flags,
2038 				IPC_PORT_NULL,
2039 				0, /* offset */
2040 				TRUE, /* copy */
2041 				initprot, maxprot,
2042 				VM_INHERIT_DEFAULT);
2043 		}
2044 		if (ret != KERN_SUCCESS) {
2045 			return LOAD_NOSPACE;
2046 		}
2047 		cur_offset += cur_end - cur_start;
2048 	}
2049 #endif /* __arm64__ */
2050 done:
2051 	assert(cur_end >= vm_start + (file_end - file_start));
2052 	return LOAD_SUCCESS;
2053 }
2054 
2055 static
2056 load_return_t
load_segment(struct load_command * lcp,uint32_t filetype,void * control,off_t pager_offset,off_t macho_size,struct vnode * vp,vm_map_t map,int64_t slide,load_result_t * result,struct image_params * imgp)2057 load_segment(
2058 	struct load_command     *lcp,
2059 	uint32_t                filetype,
2060 	void *                  control,
2061 	off_t                   pager_offset,
2062 	off_t                   macho_size,
2063 	struct vnode            *vp,
2064 	vm_map_t                map,
2065 	int64_t                 slide,
2066 	load_result_t           *result,
2067 	struct image_params     *imgp)
2068 {
2069 	struct segment_command_64 segment_command, *scp;
2070 	kern_return_t           ret;
2071 	vm_map_size_t           delta_size;
2072 	vm_prot_t               initprot;
2073 	vm_prot_t               maxprot;
2074 	size_t                  segment_command_size, total_section_size,
2075 	    single_section_size;
2076 	uint64_t                file_offset, file_size;
2077 	vm_map_offset_t         vm_offset;
2078 	size_t                  vm_size;
2079 	vm_map_offset_t         vm_start, vm_end, vm_end_aligned;
2080 	vm_map_offset_t         file_start, file_end;
2081 	kern_return_t           kr;
2082 	boolean_t               verbose;
2083 	vm_map_size_t           effective_page_size;
2084 	vm_map_offset_t         effective_page_mask;
2085 #if __arm64__
2086 	boolean_t               fourk_align;
2087 #endif /* __arm64__ */
2088 
2089 	(void)imgp;
2090 
2091 	effective_page_size = vm_map_page_size(map);
2092 	effective_page_mask = vm_map_page_mask(map);
2093 
2094 	verbose = FALSE;
2095 	if (LC_SEGMENT_64 == lcp->cmd) {
2096 		segment_command_size = sizeof(struct segment_command_64);
2097 		single_section_size  = sizeof(struct section_64);
2098 #if __arm64__
2099 		/* 64-bit binary: should already be 16K-aligned */
2100 		fourk_align = FALSE;
2101 
2102 		if (vm_map_page_shift(map) == FOURK_PAGE_SHIFT &&
2103 		    PAGE_SHIFT != FOURK_PAGE_SHIFT) {
2104 			fourk_align = TRUE;
2105 			verbose = TRUE;
2106 		}
2107 #endif /* __arm64__ */
2108 	} else {
2109 		segment_command_size = sizeof(struct segment_command);
2110 		single_section_size  = sizeof(struct section);
2111 #if __arm64__
2112 		/* 32-bit binary: might need 4K-alignment */
2113 		if (effective_page_size != FOURK_PAGE_SIZE) {
2114 			/* not using 4K page size: need fourk_pager */
2115 			fourk_align = TRUE;
2116 			verbose = TRUE;
2117 		} else {
2118 			/* using 4K page size: no need for re-alignment */
2119 			fourk_align = FALSE;
2120 		}
2121 #endif /* __arm64__ */
2122 	}
2123 	if (lcp->cmdsize < segment_command_size) {
2124 		DEBUG4K_ERROR("LOAD_BADMACHO cmdsize %d < %zu\n", lcp->cmdsize, segment_command_size);
2125 		return LOAD_BADMACHO;
2126 	}
2127 	total_section_size = lcp->cmdsize - segment_command_size;
2128 
2129 	if (LC_SEGMENT_64 == lcp->cmd) {
2130 		scp = (struct segment_command_64 *)lcp;
2131 	} else {
2132 		scp = &segment_command;
2133 		widen_segment_command((struct segment_command *)lcp, scp);
2134 	}
2135 
2136 	if (verbose) {
2137 		MACHO_PRINTF(("+++ load_segment %s "
2138 		    "vm[0x%llx:0x%llx] file[0x%llx:0x%llx] "
2139 		    "prot %d/%d flags 0x%x\n",
2140 		    scp->segname,
2141 		    (uint64_t)(slide + scp->vmaddr),
2142 		    (uint64_t)(slide + scp->vmaddr + scp->vmsize),
2143 		    pager_offset + scp->fileoff,
2144 		    pager_offset + scp->fileoff + scp->filesize,
2145 		    scp->initprot,
2146 		    scp->maxprot,
2147 		    scp->flags));
2148 	}
2149 
2150 	/*
2151 	 * Make sure what we get from the file is really ours (as specified
2152 	 * by macho_size).
2153 	 */
2154 	if (scp->fileoff + scp->filesize < scp->fileoff ||
2155 	    scp->fileoff + scp->filesize > (uint64_t)macho_size) {
2156 		DEBUG4K_ERROR("LOAD_BADMACHO fileoff 0x%llx filesize 0x%llx macho_size 0x%llx\n", scp->fileoff, scp->filesize, (uint64_t)macho_size);
2157 		return LOAD_BADMACHO;
2158 	}
2159 	/*
2160 	 * Ensure that the number of sections specified would fit
2161 	 * within the load command size.
2162 	 */
2163 	if (total_section_size / single_section_size < scp->nsects) {
2164 		DEBUG4K_ERROR("LOAD_BADMACHO 0x%zx 0x%zx %d\n", total_section_size, single_section_size, scp->nsects);
2165 		return LOAD_BADMACHO;
2166 	}
2167 	/*
2168 	 * Make sure the segment is page-aligned in the file.
2169 	 */
2170 	if (os_add_overflow(pager_offset, scp->fileoff, &file_offset)) {
2171 		DEBUG4K_ERROR("LOAD_BADMACHO file_offset: 0x%llx + 0x%llx\n", pager_offset, scp->fileoff);
2172 		return LOAD_BADMACHO;
2173 	}
2174 	file_size = scp->filesize;
2175 #if __arm64__
2176 	if (fourk_align) {
2177 		if ((file_offset & FOURK_PAGE_MASK) != 0) {
2178 			/*
2179 			 * we can't mmap() it if it's not at least 4KB-aligned
2180 			 * in the file
2181 			 */
2182 			DEBUG4K_ERROR("LOAD_BADMACHO file_offset 0x%llx\n", file_offset);
2183 			return LOAD_BADMACHO;
2184 		}
2185 	} else
2186 #endif /* __arm64__ */
2187 	if ((file_offset & PAGE_MASK_64) != 0 ||
2188 	    /* we can't mmap() it if it's not page-aligned in the file */
2189 	    (file_offset & vm_map_page_mask(map)) != 0) {
2190 		/*
2191 		 * The 1st test would have failed if the system's page size
2192 		 * was what this process believe is the page size, so let's
2193 		 * fail here too for the sake of consistency.
2194 		 */
2195 		DEBUG4K_ERROR("LOAD_BADMACHO file_offset 0x%llx\n", file_offset);
2196 		return LOAD_BADMACHO;
2197 	}
2198 
2199 	/*
2200 	 * If we have a code signature attached for this slice
2201 	 * require that the segments are within the signed part
2202 	 * of the file.
2203 	 */
2204 	if (result->cs_end_offset &&
2205 	    result->cs_end_offset < (off_t)scp->fileoff &&
2206 	    result->cs_end_offset - scp->fileoff < scp->filesize) {
2207 		if (cs_debug) {
2208 			printf("section outside code signature\n");
2209 		}
2210 		DEBUG4K_ERROR("LOAD_BADMACHO end_offset 0x%llx fileoff 0x%llx filesize 0x%llx\n", result->cs_end_offset, scp->fileoff, scp->filesize);
2211 		return LOAD_BADMACHO;
2212 	}
2213 
2214 	if (os_add_overflow(scp->vmaddr, slide, &vm_offset)) {
2215 		if (cs_debug) {
2216 			printf("vmaddr too large\n");
2217 		}
2218 		DEBUG4K_ERROR("LOAD_BADMACHO vmaddr 0x%llx slide 0x%llx vm_offset 0x%llx\n", scp->vmaddr, slide, (uint64_t)vm_offset);
2219 		return LOAD_BADMACHO;
2220 	}
2221 
2222 	if (scp->vmsize > SIZE_MAX) {
2223 		DEBUG4K_ERROR("LOAD_BADMACHO vmsize 0x%llx\n", scp->vmsize);
2224 		return LOAD_BADMACHO;
2225 	}
2226 
2227 	vm_size = (size_t)scp->vmsize;
2228 
2229 	if (vm_size == 0) {
2230 		return LOAD_SUCCESS;
2231 	}
2232 	if (scp->vmaddr == 0 &&
2233 	    file_size == 0 &&
2234 	    vm_size != 0 &&
2235 	    (scp->initprot & VM_PROT_ALL) == VM_PROT_NONE &&
2236 	    (scp->maxprot & VM_PROT_ALL) == VM_PROT_NONE) {
2237 		if (map == VM_MAP_NULL) {
2238 			return LOAD_SUCCESS;
2239 		}
2240 
2241 		/*
2242 		 * For PIE, extend page zero rather than moving it.  Extending
2243 		 * page zero keeps early allocations from falling predictably
2244 		 * between the end of page zero and the beginning of the first
2245 		 * slid segment.
2246 		 */
2247 		/*
2248 		 * This is a "page zero" segment:  it starts at address 0,
2249 		 * is not mapped from the binary file and is not accessible.
2250 		 * User-space should never be able to access that memory, so
2251 		 * make it completely off limits by raising the VM map's
2252 		 * minimum offset.
2253 		 */
2254 		vm_end = (vm_map_offset_t)(vm_offset + vm_size);
2255 		if (vm_end < vm_offset) {
2256 			DEBUG4K_ERROR("LOAD_BADMACHO vm_end 0x%llx vm_offset 0x%llx vm_size 0x%llx\n", (uint64_t)vm_end, (uint64_t)vm_offset, (uint64_t)vm_size);
2257 			return LOAD_BADMACHO;
2258 		}
2259 
2260 		if (verbose) {
2261 			MACHO_PRINTF(("++++++ load_segment: "
2262 			    "page_zero up to 0x%llx\n",
2263 			    (uint64_t) vm_end));
2264 		}
2265 #if __arm64__
2266 		if (fourk_align) {
2267 			/* raise min_offset as much as page-alignment allows */
2268 			vm_end_aligned = vm_map_trunc_page(vm_end,
2269 			    effective_page_mask);
2270 		} else
2271 #endif /* __arm64__ */
2272 		{
2273 			vm_end = vm_map_round_page(vm_end,
2274 			    PAGE_MASK_64);
2275 			vm_end_aligned = vm_end;
2276 		}
2277 		ret = vm_map_raise_min_offset(map,
2278 		    vm_end_aligned);
2279 #if __arm64__
2280 		if (ret == 0 &&
2281 		    vm_end > vm_end_aligned) {
2282 			/* use fourk_pager to map the rest of pagezero */
2283 			assert(fourk_align);
2284 			ret = vm_map_enter_mem_object(
2285 				map,
2286 				&vm_end_aligned,
2287 				vm_end - vm_end_aligned,
2288 				(mach_vm_offset_t) 0,   /* mask */
2289 				VM_MAP_KERNEL_FLAGS_FIXED(.vmkf_fourk = true),
2290 				IPC_PORT_NULL,
2291 				0,
2292 				FALSE,  /* copy */
2293 				(scp->initprot & VM_PROT_ALL),
2294 				(scp->maxprot & VM_PROT_ALL),
2295 				VM_INHERIT_DEFAULT);
2296 		}
2297 #endif /* __arm64__ */
2298 
2299 		if (ret != KERN_SUCCESS) {
2300 			DEBUG4K_ERROR("LOAD_FAILURE ret 0x%x\n", ret);
2301 			return LOAD_FAILURE;
2302 		}
2303 		return LOAD_SUCCESS;
2304 	} else {
2305 #if !defined(XNU_TARGET_OS_OSX)
2306 		/* not PAGEZERO: should not be mapped at address 0 */
2307 		if (filetype != MH_DYLINKER && (imgp->ip_flags & IMGPF_ROSETTA) == 0 && scp->vmaddr == 0) {
2308 			DEBUG4K_ERROR("LOAD_BADMACHO filetype %d vmaddr 0x%llx\n", filetype, scp->vmaddr);
2309 			return LOAD_BADMACHO;
2310 		}
2311 #endif /* !defined(XNU_TARGET_OS_OSX) */
2312 	}
2313 
2314 #if __arm64__
2315 	if (fourk_align) {
2316 		/* 4K-align */
2317 		file_start = vm_map_trunc_page(file_offset,
2318 		    FOURK_PAGE_MASK);
2319 		file_end = vm_map_round_page(file_offset + file_size,
2320 		    FOURK_PAGE_MASK);
2321 		vm_start = vm_map_trunc_page(vm_offset,
2322 		    FOURK_PAGE_MASK);
2323 		vm_end = vm_map_round_page(vm_offset + vm_size,
2324 		    FOURK_PAGE_MASK);
2325 
2326 		if (file_offset - file_start > FOURK_PAGE_MASK ||
2327 		    file_end - file_offset - file_size > FOURK_PAGE_MASK) {
2328 			DEBUG4K_ERROR("LOAD_BADMACHO file_start / file_size wrap "
2329 			    "[0x%llx:0x%llx] -> [0x%llx:0x%llx]\n",
2330 			    file_offset,
2331 			    file_offset + file_size,
2332 			    (uint64_t) file_start,
2333 			    (uint64_t) file_end);
2334 			return LOAD_BADMACHO;
2335 		}
2336 
2337 		if (!strncmp(scp->segname, "__LINKEDIT", 11) &&
2338 		    page_aligned(file_start) &&
2339 		    vm_map_page_aligned(file_start, vm_map_page_mask(map)) &&
2340 		    page_aligned(vm_start) &&
2341 		    vm_map_page_aligned(vm_start, vm_map_page_mask(map))) {
2342 			/* XXX last segment: ignore mis-aligned tail */
2343 			file_end = vm_map_round_page(file_end,
2344 			    effective_page_mask);
2345 			vm_end = vm_map_round_page(vm_end,
2346 			    effective_page_mask);
2347 		}
2348 	} else
2349 #endif /* __arm64__ */
2350 	{
2351 		file_start = vm_map_trunc_page(file_offset,
2352 		    effective_page_mask);
2353 		file_end = vm_map_round_page(file_offset + file_size,
2354 		    effective_page_mask);
2355 		vm_start = vm_map_trunc_page(vm_offset,
2356 		    effective_page_mask);
2357 		vm_end = vm_map_round_page(vm_offset + vm_size,
2358 		    effective_page_mask);
2359 
2360 		if (file_offset - file_start > effective_page_mask ||
2361 		    file_end - file_offset - file_size > effective_page_mask) {
2362 			DEBUG4K_ERROR("LOAD_BADMACHO file_start / file_size wrap "
2363 			    "[0x%llx:0x%llx] -> [0x%llx:0x%llx]\n",
2364 			    file_offset,
2365 			    file_offset + file_size,
2366 			    (uint64_t) file_start,
2367 			    (uint64_t) file_end);
2368 			return LOAD_BADMACHO;
2369 		}
2370 	}
2371 
2372 	if (vm_start < result->min_vm_addr) {
2373 		result->min_vm_addr = vm_start;
2374 	}
2375 	if (vm_end > result->max_vm_addr) {
2376 		result->max_vm_addr = vm_end;
2377 	}
2378 
2379 	if (map == VM_MAP_NULL) {
2380 		return LOAD_SUCCESS;
2381 	}
2382 
2383 	if (scp->flags & SG_READ_ONLY) {
2384 		/*
2385 		 * Record the VM start/end of a segment which should
2386 		 * be RO after fixups. Only __DATA_CONST should
2387 		 * have this flag.
2388 		 */
2389 		if (result->ro_vm_start != MACH_VM_MIN_ADDRESS ||
2390 		    result->ro_vm_end != MACH_VM_MIN_ADDRESS) {
2391 			DEBUG4K_ERROR("LOAD_BADMACHO segment flags [%x] "
2392 			    "multiple segments with SG_READ_ONLY flag\n",
2393 			    scp->flags);
2394 			return LOAD_BADMACHO;
2395 		}
2396 
2397 		result->ro_vm_start = vm_start;
2398 		result->ro_vm_end = vm_end;
2399 	}
2400 
2401 	if (vm_size > 0) {
2402 		initprot = (scp->initprot) & VM_PROT_ALL;
2403 		maxprot = (scp->maxprot) & VM_PROT_ALL;
2404 		/*
2405 		 *	Map a copy of the file into the address space.
2406 		 */
2407 		if (verbose) {
2408 			MACHO_PRINTF(("++++++ load_segment: "
2409 			    "mapping at vm [0x%llx:0x%llx] of "
2410 			    "file [0x%llx:0x%llx]\n",
2411 			    (uint64_t) vm_start,
2412 			    (uint64_t) vm_end,
2413 			    (uint64_t) file_start,
2414 			    (uint64_t) file_end));
2415 		}
2416 		ret = map_segment(map,
2417 		    vm_start,
2418 		    vm_end,
2419 		    control,
2420 		    file_start,
2421 		    file_end,
2422 		    initprot,
2423 		    maxprot,
2424 		    result);
2425 		if (ret) {
2426 			DEBUG4K_ERROR("LOAD_NOSPACE start 0x%llx end 0x%llx ret 0x%x\n", (uint64_t)vm_start, (uint64_t)vm_end, ret);
2427 			return LOAD_NOSPACE;
2428 		}
2429 
2430 #if FIXME
2431 		/*
2432 		 *	If the file didn't end on a page boundary,
2433 		 *	we need to zero the leftover.
2434 		 */
2435 		delta_size = map_size - scp->filesize;
2436 		if (delta_size > 0) {
2437 			void *tmp = kalloc_data(delta_size, Z_WAITOK | Z_ZERO);
2438 			int rc;
2439 
2440 			if (tmp == NULL) {
2441 				DEBUG4K_ERROR("LOAD_RESOURCE delta_size 0x%llx ret 0x%x\n", delta_size, ret);
2442 				return LOAD_RESOURCE;
2443 			}
2444 
2445 			rc = copyout(tmp, map_addr + scp->filesize, delta_size);
2446 			kfree_data(tmp, delta_size);
2447 
2448 			if (rc) {
2449 				DEBUG4K_ERROR("LOAD_FAILURE copyout 0x%llx 0x%llx\n", map_addr + scp->filesize, delta_size);
2450 				return LOAD_FAILURE;
2451 			}
2452 		}
2453 #endif /* FIXME */
2454 	}
2455 
2456 	/*
2457 	 *	If the virtual size of the segment is greater
2458 	 *	than the size from the file, we need to allocate
2459 	 *	zero fill memory for the rest.
2460 	 */
2461 	if ((vm_end - vm_start) > (file_end - file_start)) {
2462 		delta_size = (vm_end - vm_start) - (file_end - file_start);
2463 	} else {
2464 		delta_size = 0;
2465 	}
2466 	if (delta_size > 0) {
2467 		vm_map_offset_t tmp_start;
2468 		vm_map_offset_t tmp_end;
2469 
2470 		if (os_add_overflow(vm_start, file_end - file_start, &tmp_start)) {
2471 			DEBUG4K_ERROR("LOAD_NOSPACE tmp_start: 0x%llx + 0x%llx\n", (uint64_t)vm_start, (uint64_t)(file_end - file_start));
2472 			return LOAD_NOSPACE;
2473 		}
2474 
2475 		if (os_add_overflow(tmp_start, delta_size, &tmp_end)) {
2476 			DEBUG4K_ERROR("LOAD_NOSPACE tmp_end: 0x%llx + 0x%llx\n", (uint64_t)tmp_start, (uint64_t)delta_size);
2477 			return LOAD_NOSPACE;
2478 		}
2479 
2480 		if (verbose) {
2481 			MACHO_PRINTF(("++++++ load_segment: "
2482 			    "delta mapping vm [0x%llx:0x%llx]\n",
2483 			    (uint64_t) tmp_start,
2484 			    (uint64_t) tmp_end));
2485 		}
2486 		kr = map_segment(map,
2487 		    tmp_start,
2488 		    tmp_end,
2489 		    MEMORY_OBJECT_CONTROL_NULL,
2490 		    0,
2491 		    delta_size,
2492 		    scp->initprot,
2493 		    scp->maxprot,
2494 		    result);
2495 		if (kr != KERN_SUCCESS) {
2496 			DEBUG4K_ERROR("LOAD_NOSPACE 0x%llx 0x%llx kr 0x%x\n", (unsigned long long)tmp_start, (uint64_t)delta_size, kr);
2497 			return LOAD_NOSPACE;
2498 		}
2499 	}
2500 
2501 	if ((scp->fileoff == 0) && (scp->filesize != 0)) {
2502 		result->mach_header = vm_offset;
2503 	}
2504 
2505 	if (scp->flags & SG_PROTECTED_VERSION_1) {
2506 		ret = unprotect_dsmos_segment(file_start,
2507 		    file_end - file_start,
2508 		    vp,
2509 		    pager_offset,
2510 		    map,
2511 		    vm_start,
2512 		    vm_end - vm_start);
2513 		if (ret != LOAD_SUCCESS) {
2514 			DEBUG4K_ERROR("unprotect 0x%llx 0x%llx ret %d \n", (uint64_t)vm_start, (uint64_t)vm_end, ret);
2515 			return ret;
2516 		}
2517 	} else {
2518 		ret = LOAD_SUCCESS;
2519 	}
2520 
2521 	if (LOAD_SUCCESS == ret &&
2522 	    filetype == MH_DYLINKER &&
2523 	    result->all_image_info_addr == MACH_VM_MIN_ADDRESS) {
2524 		note_all_image_info_section(scp,
2525 		    LC_SEGMENT_64 == lcp->cmd,
2526 		    single_section_size,
2527 		    ((const char *)lcp +
2528 		    segment_command_size),
2529 		    slide,
2530 		    result);
2531 	}
2532 
2533 	if (result->entry_point != MACH_VM_MIN_ADDRESS) {
2534 		if ((result->entry_point >= vm_offset) && (result->entry_point < (vm_offset + vm_size))) {
2535 			if ((scp->initprot & (VM_PROT_READ | VM_PROT_EXECUTE)) == (VM_PROT_READ | VM_PROT_EXECUTE)) {
2536 				result->validentry = 1;
2537 			} else {
2538 				/* right range but wrong protections, unset if previously validated */
2539 				result->validentry = 0;
2540 			}
2541 		}
2542 	}
2543 
2544 	if (ret != LOAD_SUCCESS && verbose) {
2545 		DEBUG4K_ERROR("ret %d\n", ret);
2546 	}
2547 	return ret;
2548 }
2549 
2550 static
2551 load_return_t
load_uuid(struct uuid_command * uulp,char * command_end,load_result_t * result)2552 load_uuid(
2553 	struct uuid_command     *uulp,
2554 	char                    *command_end,
2555 	load_result_t           *result
2556 	)
2557 {
2558 	/*
2559 	 * We need to check the following for this command:
2560 	 * - The command size should be atleast the size of struct uuid_command
2561 	 * - The UUID part of the command should be completely within the mach-o header
2562 	 */
2563 
2564 	if ((uulp->cmdsize < sizeof(struct uuid_command)) ||
2565 	    (((char *)uulp + sizeof(struct uuid_command)) > command_end)) {
2566 		return LOAD_BADMACHO;
2567 	}
2568 
2569 	memcpy(&result->uuid[0], &uulp->uuid[0], sizeof(result->uuid));
2570 	return LOAD_SUCCESS;
2571 }
2572 
2573 static
2574 load_return_t
load_version(struct version_min_command * vmc,boolean_t * found_version_cmd,struct image_params * imgp __unused,load_result_t * result)2575 load_version(
2576 	struct version_min_command     *vmc,
2577 	boolean_t               *found_version_cmd,
2578 	struct image_params             *imgp __unused,
2579 	load_result_t           *result
2580 	)
2581 {
2582 	uint32_t platform = 0;
2583 	uint32_t sdk;
2584 	uint32_t min_sdk;
2585 
2586 	if (vmc->cmdsize < sizeof(*vmc)) {
2587 		return LOAD_BADMACHO;
2588 	}
2589 	if (*found_version_cmd == TRUE) {
2590 		return LOAD_BADMACHO;
2591 	}
2592 	*found_version_cmd = TRUE;
2593 	sdk = vmc->sdk;
2594 	min_sdk = vmc->version;
2595 	switch (vmc->cmd) {
2596 	case LC_VERSION_MIN_MACOSX:
2597 		platform = PLATFORM_MACOS;
2598 		break;
2599 #if __x86_64__ /* __x86_64__ */
2600 	case LC_VERSION_MIN_IPHONEOS:
2601 		platform = PLATFORM_IOSSIMULATOR;
2602 		break;
2603 	case LC_VERSION_MIN_WATCHOS:
2604 		platform = PLATFORM_WATCHOSSIMULATOR;
2605 		break;
2606 	case LC_VERSION_MIN_TVOS:
2607 		platform = PLATFORM_TVOSSIMULATOR;
2608 		break;
2609 #else
2610 	case LC_VERSION_MIN_IPHONEOS: {
2611 #if __arm64__
2612 		if (vmc->sdk < (12 << 16)) {
2613 			/* app built with a pre-iOS12 SDK: apply legacy footprint mitigation */
2614 			result->legacy_footprint = TRUE;
2615 		}
2616 #endif /* __arm64__ */
2617 		platform = PLATFORM_IOS;
2618 		break;
2619 	}
2620 	case LC_VERSION_MIN_WATCHOS:
2621 		platform = PLATFORM_WATCHOS;
2622 		break;
2623 	case LC_VERSION_MIN_TVOS:
2624 		platform = PLATFORM_TVOS;
2625 		break;
2626 #endif /* __x86_64__ */
2627 	/* All LC_VERSION_MIN_* load commands are legacy and we will not be adding any more */
2628 	default:
2629 		sdk = (uint32_t)-1;
2630 		min_sdk = (uint32_t)-1;
2631 		__builtin_unreachable();
2632 	}
2633 	result->ip_platform = platform;
2634 	result->lr_min_sdk = min_sdk;
2635 	result->lr_sdk = sdk;
2636 	return LOAD_SUCCESS;
2637 }
2638 
2639 static
2640 load_return_t
load_main(struct entry_point_command * epc,thread_t thread,int64_t slide,load_result_t * result)2641 load_main(
2642 	struct entry_point_command      *epc,
2643 	thread_t                thread,
2644 	int64_t                         slide,
2645 	load_result_t           *result
2646 	)
2647 {
2648 	mach_vm_offset_t addr;
2649 	kern_return_t   ret;
2650 
2651 	if (epc->cmdsize < sizeof(*epc)) {
2652 		return LOAD_BADMACHO;
2653 	}
2654 	if (result->thread_count != 0) {
2655 		return LOAD_FAILURE;
2656 	}
2657 
2658 	if (thread == THREAD_NULL) {
2659 		return LOAD_SUCCESS;
2660 	}
2661 
2662 	/*
2663 	 * LC_MAIN specifies stack size but not location.
2664 	 * Add guard page to allocation size (MAXSSIZ includes guard page).
2665 	 */
2666 	if (epc->stacksize) {
2667 		if (os_add_overflow(epc->stacksize, 4 * PAGE_SIZE, &result->user_stack_size)) {
2668 			/*
2669 			 * We are going to immediately throw away this result, but we want
2670 			 * to make sure we aren't loading a dangerously close to
2671 			 * overflowing value, since this will have a guard page added to it
2672 			 * and be rounded to page boundaries
2673 			 */
2674 			return LOAD_BADMACHO;
2675 		}
2676 		result->user_stack_size = epc->stacksize;
2677 		if (os_add_overflow(epc->stacksize, PAGE_SIZE, &result->user_stack_alloc_size)) {
2678 			return LOAD_BADMACHO;
2679 		}
2680 		result->custom_stack = TRUE;
2681 	} else {
2682 		result->user_stack_alloc_size = MAXSSIZ;
2683 	}
2684 
2685 	/* use default location for stack */
2686 	ret = thread_userstackdefault(&addr, result->is_64bit_addr);
2687 	if (ret != KERN_SUCCESS) {
2688 		return LOAD_FAILURE;
2689 	}
2690 
2691 	/* The stack slides down from the default location */
2692 	result->user_stack = (user_addr_t)mach_vm_trunc_page((user_addr_t)addr - slide);
2693 
2694 	if (result->using_lcmain || result->entry_point != MACH_VM_MIN_ADDRESS) {
2695 		/* Already processed LC_MAIN or LC_UNIXTHREAD */
2696 		return LOAD_FAILURE;
2697 	}
2698 
2699 	/* kernel does *not* use entryoff from LC_MAIN.	 Dyld uses it. */
2700 	result->needs_dynlinker = TRUE;
2701 	result->using_lcmain = TRUE;
2702 
2703 	ret = thread_state_initialize( thread );
2704 	if (ret != KERN_SUCCESS) {
2705 		return LOAD_FAILURE;
2706 	}
2707 
2708 	result->unixproc = TRUE;
2709 	result->thread_count++;
2710 
2711 	return LOAD_SUCCESS;
2712 }
2713 
2714 static
2715 load_return_t
setup_driver_main(thread_t thread,int64_t slide,load_result_t * result)2716 setup_driver_main(
2717 	thread_t                thread,
2718 	int64_t                         slide,
2719 	load_result_t           *result
2720 	)
2721 {
2722 	mach_vm_offset_t addr;
2723 	kern_return_t   ret;
2724 
2725 	/* Driver binaries have no LC_MAIN, use defaults */
2726 
2727 	if (thread == THREAD_NULL) {
2728 		return LOAD_SUCCESS;
2729 	}
2730 
2731 	result->user_stack_alloc_size = MAXSSIZ;
2732 
2733 	/* use default location for stack */
2734 	ret = thread_userstackdefault(&addr, result->is_64bit_addr);
2735 	if (ret != KERN_SUCCESS) {
2736 		return LOAD_FAILURE;
2737 	}
2738 
2739 	/* The stack slides down from the default location */
2740 	result->user_stack = (user_addr_t)addr;
2741 	result->user_stack -= slide;
2742 
2743 	if (result->using_lcmain || result->entry_point != MACH_VM_MIN_ADDRESS) {
2744 		/* Already processed LC_MAIN or LC_UNIXTHREAD */
2745 		return LOAD_FAILURE;
2746 	}
2747 
2748 	result->needs_dynlinker = TRUE;
2749 
2750 	ret = thread_state_initialize( thread );
2751 	if (ret != KERN_SUCCESS) {
2752 		return LOAD_FAILURE;
2753 	}
2754 
2755 	result->unixproc = TRUE;
2756 	result->thread_count++;
2757 
2758 	return LOAD_SUCCESS;
2759 }
2760 
2761 static
2762 load_return_t
load_unixthread(struct thread_command * tcp,thread_t thread,int64_t slide,boolean_t is_x86_64_compat_binary,load_result_t * result)2763 load_unixthread(
2764 	struct thread_command   *tcp,
2765 	thread_t                thread,
2766 	int64_t                         slide,
2767 	boolean_t               is_x86_64_compat_binary,
2768 	load_result_t           *result
2769 	)
2770 {
2771 	load_return_t   ret;
2772 	int customstack = 0;
2773 	mach_vm_offset_t addr;
2774 	if (tcp->cmdsize < sizeof(*tcp)) {
2775 		return LOAD_BADMACHO;
2776 	}
2777 	if (result->thread_count != 0) {
2778 		return LOAD_FAILURE;
2779 	}
2780 
2781 	if (thread == THREAD_NULL) {
2782 		return LOAD_SUCCESS;
2783 	}
2784 
2785 	ret = load_threadstack(thread,
2786 	    (uint32_t *)(((vm_offset_t)tcp) +
2787 	    sizeof(struct thread_command)),
2788 	    tcp->cmdsize - sizeof(struct thread_command),
2789 	    &addr, &customstack, is_x86_64_compat_binary, result);
2790 	if (ret != LOAD_SUCCESS) {
2791 		return ret;
2792 	}
2793 
2794 	/* LC_UNIXTHREAD optionally specifies stack size and location */
2795 
2796 	if (customstack) {
2797 		result->custom_stack = TRUE;
2798 	} else {
2799 		result->user_stack_alloc_size = MAXSSIZ;
2800 	}
2801 
2802 	/* The stack slides down from the default location */
2803 	result->user_stack = (user_addr_t)mach_vm_trunc_page((user_addr_t)addr - slide);
2804 
2805 	{
2806 		ret = load_threadentry(thread,
2807 		    (uint32_t *)(((vm_offset_t)tcp) +
2808 		    sizeof(struct thread_command)),
2809 		    tcp->cmdsize - sizeof(struct thread_command),
2810 		    &addr);
2811 		if (ret != LOAD_SUCCESS) {
2812 			return ret;
2813 		}
2814 
2815 		if (result->using_lcmain || result->entry_point != MACH_VM_MIN_ADDRESS) {
2816 			/* Already processed LC_MAIN or LC_UNIXTHREAD */
2817 			return LOAD_FAILURE;
2818 		}
2819 
2820 		result->entry_point = (user_addr_t)addr;
2821 		result->entry_point += slide;
2822 
2823 		ret = load_threadstate(thread,
2824 		    (uint32_t *)(((vm_offset_t)tcp) + sizeof(struct thread_command)),
2825 		    tcp->cmdsize - sizeof(struct thread_command),
2826 		    result);
2827 		if (ret != LOAD_SUCCESS) {
2828 			return ret;
2829 		}
2830 	}
2831 
2832 	result->unixproc = TRUE;
2833 	result->thread_count++;
2834 
2835 	return LOAD_SUCCESS;
2836 }
2837 
2838 static
2839 load_return_t
load_threadstate(thread_t thread,uint32_t * ts,uint32_t total_size,load_result_t * result)2840 load_threadstate(
2841 	thread_t        thread,
2842 	uint32_t        *ts,
2843 	uint32_t        total_size,
2844 	load_result_t   *result
2845 	)
2846 {
2847 	uint32_t        size;
2848 	int             flavor;
2849 	uint32_t        thread_size;
2850 	uint32_t        *local_ts = NULL;
2851 	uint32_t        local_ts_size = 0;
2852 	int             ret;
2853 
2854 	(void)thread;
2855 
2856 	if (total_size > 0) {
2857 		local_ts_size = total_size;
2858 		local_ts = (uint32_t *)kalloc_data(local_ts_size, Z_WAITOK);
2859 		if (local_ts == NULL) {
2860 			return LOAD_FAILURE;
2861 		}
2862 		memcpy(local_ts, ts, local_ts_size);
2863 		ts = local_ts;
2864 	}
2865 
2866 	/*
2867 	 * Validate the new thread state; iterate through the state flavors in
2868 	 * the Mach-O file.
2869 	 * XXX: we should validate the machine state here, to avoid failing at
2870 	 * activation time where we can't bail out cleanly.
2871 	 */
2872 	while (total_size > 0) {
2873 		if (total_size < 2 * sizeof(uint32_t)) {
2874 			return LOAD_BADMACHO;
2875 		}
2876 
2877 		flavor = *ts++;
2878 		size = *ts++;
2879 
2880 		if (os_add_and_mul_overflow(size, 2, sizeof(uint32_t), &thread_size) ||
2881 		    os_sub_overflow(total_size, thread_size, &total_size)) {
2882 			ret = LOAD_BADMACHO;
2883 			goto bad;
2884 		}
2885 
2886 		ts += size;     /* ts is a (uint32_t *) */
2887 	}
2888 
2889 	result->threadstate = local_ts;
2890 	result->threadstate_sz = local_ts_size;
2891 	return LOAD_SUCCESS;
2892 
2893 bad:
2894 	if (local_ts) {
2895 		kfree_data(local_ts, local_ts_size);
2896 	}
2897 	return ret;
2898 }
2899 
2900 
2901 static
2902 load_return_t
load_threadstack(thread_t thread,uint32_t * ts,uint32_t total_size,mach_vm_offset_t * user_stack,int * customstack,__unused boolean_t is_x86_64_compat_binary,load_result_t * result)2903 load_threadstack(
2904 	thread_t                thread,
2905 	uint32_t                *ts,
2906 	uint32_t                total_size,
2907 	mach_vm_offset_t        *user_stack,
2908 	int                     *customstack,
2909 	__unused boolean_t      is_x86_64_compat_binary,
2910 	load_result_t           *result
2911 	)
2912 {
2913 	kern_return_t   ret;
2914 	uint32_t        size;
2915 	int             flavor;
2916 	uint32_t        stack_size;
2917 
2918 	if (total_size == 0) {
2919 		return LOAD_BADMACHO;
2920 	}
2921 
2922 	while (total_size > 0) {
2923 		if (total_size < 2 * sizeof(uint32_t)) {
2924 			return LOAD_BADMACHO;
2925 		}
2926 
2927 		flavor = *ts++;
2928 		size = *ts++;
2929 		if (UINT32_MAX - 2 < size ||
2930 		    UINT32_MAX / sizeof(uint32_t) < size + 2) {
2931 			return LOAD_BADMACHO;
2932 		}
2933 		stack_size = (size + 2) * sizeof(uint32_t);
2934 		if (stack_size > total_size) {
2935 			return LOAD_BADMACHO;
2936 		}
2937 		total_size -= stack_size;
2938 
2939 		/*
2940 		 * Third argument is a kernel space pointer; it gets cast
2941 		 * to the appropriate type in thread_userstack() based on
2942 		 * the value of flavor.
2943 		 */
2944 		{
2945 			ret = thread_userstack(thread, flavor, (thread_state_t)ts, size, user_stack, customstack, result->is_64bit_data);
2946 			if (ret != KERN_SUCCESS) {
2947 				return LOAD_FAILURE;
2948 			}
2949 		}
2950 
2951 		ts += size;     /* ts is a (uint32_t *) */
2952 	}
2953 	return LOAD_SUCCESS;
2954 }
2955 
2956 static
2957 load_return_t
load_threadentry(thread_t thread,uint32_t * ts,uint32_t total_size,mach_vm_offset_t * entry_point)2958 load_threadentry(
2959 	thread_t        thread,
2960 	uint32_t        *ts,
2961 	uint32_t        total_size,
2962 	mach_vm_offset_t        *entry_point
2963 	)
2964 {
2965 	kern_return_t   ret;
2966 	uint32_t        size;
2967 	int             flavor;
2968 	uint32_t        entry_size;
2969 
2970 	/*
2971 	 *	Set the thread state.
2972 	 */
2973 	*entry_point = MACH_VM_MIN_ADDRESS;
2974 	while (total_size > 0) {
2975 		if (total_size < 2 * sizeof(uint32_t)) {
2976 			return LOAD_BADMACHO;
2977 		}
2978 
2979 		flavor = *ts++;
2980 		size = *ts++;
2981 		if (UINT32_MAX - 2 < size ||
2982 		    UINT32_MAX / sizeof(uint32_t) < size + 2) {
2983 			return LOAD_BADMACHO;
2984 		}
2985 		entry_size = (size + 2) * sizeof(uint32_t);
2986 		if (entry_size > total_size) {
2987 			return LOAD_BADMACHO;
2988 		}
2989 		total_size -= entry_size;
2990 		/*
2991 		 * Third argument is a kernel space pointer; it gets cast
2992 		 * to the appropriate type in thread_entrypoint() based on
2993 		 * the value of flavor.
2994 		 */
2995 		ret = thread_entrypoint(thread, flavor, (thread_state_t)ts, size, entry_point);
2996 		if (ret != KERN_SUCCESS) {
2997 			return LOAD_FAILURE;
2998 		}
2999 		ts += size;     /* ts is a (uint32_t *) */
3000 	}
3001 	return LOAD_SUCCESS;
3002 }
3003 
3004 struct macho_data {
3005 	struct nameidata        __nid;
3006 	union macho_vnode_header {
3007 		struct mach_header      mach_header;
3008 		struct fat_header       fat_header;
3009 		char    __pad[512];
3010 	} __header;
3011 };
3012 
3013 #define DEFAULT_DYLD_PATH "/usr/lib/dyld"
3014 
3015 #if (DEVELOPMENT || DEBUG)
3016 extern char dyld_alt_path[];
3017 extern int use_alt_dyld;
3018 
3019 extern char dyld_suffix[];
3020 extern int use_dyld_suffix;
3021 
3022 typedef struct _dyld_suffix_map_entry {
3023 	const char *suffix;
3024 	const char *path;
3025 } dyld_suffix_map_entry_t;
3026 
3027 static const dyld_suffix_map_entry_t _dyld_suffix_map[] = {
3028 	[0] = {
3029 		.suffix = "",
3030 		.path = DEFAULT_DYLD_PATH,
3031 	}, {
3032 		.suffix = "release",
3033 		.path = DEFAULT_DYLD_PATH,
3034 	}, {
3035 		.suffix = "bringup",
3036 		.path = "/usr/appleinternal/lib/dyld.bringup",
3037 	},
3038 };
3039 #endif
3040 
3041 static load_return_t
load_dylinker(struct dylinker_command * lcp,cpu_type_t cputype,vm_map_t map,thread_t thread,int depth,int64_t slide,load_result_t * result,struct image_params * imgp)3042 load_dylinker(
3043 	struct dylinker_command *lcp,
3044 	cpu_type_t              cputype,
3045 	vm_map_t                map,
3046 	thread_t        thread,
3047 	int                     depth,
3048 	int64_t                 slide,
3049 	load_result_t           *result,
3050 	struct image_params     *imgp
3051 	)
3052 {
3053 	const char              *name;
3054 	struct vnode            *vp = NULLVP;   /* set by get_macho_vnode() */
3055 	struct mach_header      *header;
3056 	off_t                   file_offset = 0; /* set by get_macho_vnode() */
3057 	off_t                   macho_size = 0; /* set by get_macho_vnode() */
3058 	load_result_t           *myresult;
3059 	kern_return_t           ret;
3060 	struct macho_data       *macho_data;
3061 	struct {
3062 		struct mach_header      __header;
3063 		load_result_t           __myresult;
3064 		struct macho_data       __macho_data;
3065 	} *dyld_data;
3066 
3067 	if (lcp->cmdsize < sizeof(*lcp) || lcp->name.offset >= lcp->cmdsize) {
3068 		return LOAD_BADMACHO;
3069 	}
3070 
3071 	name = (const char *)lcp + lcp->name.offset;
3072 
3073 	/* Check for a proper null terminated string. */
3074 	size_t maxsz = lcp->cmdsize - lcp->name.offset;
3075 	size_t namelen = strnlen(name, maxsz);
3076 	if (namelen >= maxsz) {
3077 		return LOAD_BADMACHO;
3078 	}
3079 
3080 #if (DEVELOPMENT || DEBUG)
3081 
3082 	/*
3083 	 * rdar://23680808
3084 	 * If an alternate dyld has been specified via boot args, check
3085 	 * to see if PROC_UUID_ALT_DYLD_POLICY has been set on this
3086 	 * executable and redirect the kernel to load that linker.
3087 	 */
3088 
3089 	if (use_alt_dyld) {
3090 		int policy_error;
3091 		uint32_t policy_flags = 0;
3092 		int32_t policy_gencount = 0;
3093 
3094 		policy_error = proc_uuid_policy_lookup(result->uuid, &policy_flags, &policy_gencount);
3095 		if (policy_error == 0) {
3096 			if (policy_flags & PROC_UUID_ALT_DYLD_POLICY) {
3097 				name = dyld_alt_path;
3098 			}
3099 		}
3100 	} else if (use_dyld_suffix) {
3101 		size_t i = 0;
3102 
3103 #define countof(x) (sizeof(x) / sizeof(x[0]))
3104 		for (i = 0; i < countof(_dyld_suffix_map); i++) {
3105 			const dyld_suffix_map_entry_t *entry = &_dyld_suffix_map[i];
3106 
3107 			if (strcmp(entry->suffix, dyld_suffix) == 0) {
3108 				name = entry->path;
3109 				break;
3110 			}
3111 		}
3112 	}
3113 #endif
3114 
3115 #if !(DEVELOPMENT || DEBUG)
3116 	if (0 != strcmp(name, DEFAULT_DYLD_PATH)) {
3117 		return LOAD_BADMACHO;
3118 	}
3119 #endif
3120 
3121 	/* Allocate wad-of-data from heap to reduce excessively deep stacks */
3122 
3123 	dyld_data = kalloc_type(typeof(*dyld_data), Z_WAITOK);
3124 	header = &dyld_data->__header;
3125 	myresult = &dyld_data->__myresult;
3126 	macho_data = &dyld_data->__macho_data;
3127 
3128 	{
3129 		cputype = (cputype & CPU_ARCH_MASK) | (cpu_type() & ~CPU_ARCH_MASK);
3130 	}
3131 
3132 	ret = get_macho_vnode(name, cputype, header,
3133 	    &file_offset, &macho_size, macho_data, &vp, imgp);
3134 	if (ret) {
3135 		goto novp_out;
3136 	}
3137 
3138 	*myresult = load_result_null;
3139 	myresult->is_64bit_addr = result->is_64bit_addr;
3140 	myresult->is_64bit_data = result->is_64bit_data;
3141 
3142 	ret = parse_machfile(vp, map, thread, header, file_offset,
3143 	    macho_size, depth, slide, 0, myresult, result, imgp);
3144 
3145 	if (ret == LOAD_SUCCESS) {
3146 		if (result->threadstate) {
3147 			/* don't use the app's threadstate if we have a dyld */
3148 			kfree_data(result->threadstate, result->threadstate_sz);
3149 		}
3150 		result->threadstate = myresult->threadstate;
3151 		result->threadstate_sz = myresult->threadstate_sz;
3152 
3153 		result->dynlinker = TRUE;
3154 		result->entry_point = myresult->entry_point;
3155 		result->validentry = myresult->validentry;
3156 		result->all_image_info_addr = myresult->all_image_info_addr;
3157 		result->all_image_info_size = myresult->all_image_info_size;
3158 		if (!myresult->platform_binary) {
3159 			result->csflags &= ~CS_NO_UNTRUSTED_HELPERS;
3160 		}
3161 
3162 #if CONFIG_ROSETTA
3163 		if (imgp->ip_flags & IMGPF_ROSETTA) {
3164 			extern const struct fileops vnops;
3165 			// Save the file descriptor and mach header address for dyld. These will
3166 			// be passed on the stack for the Rosetta runtime's use.
3167 			struct fileproc *fp;
3168 			int dyld_fd;
3169 			proc_t p = vfs_context_proc(imgp->ip_vfs_context);
3170 			int error = falloc_exec(p, imgp->ip_vfs_context, &fp, &dyld_fd);
3171 			if (error == 0) {
3172 				error = VNOP_OPEN(vp, FREAD, imgp->ip_vfs_context);
3173 				if (error == 0) {
3174 					fp->fp_glob->fg_flag = FREAD;
3175 					fp->fp_glob->fg_ops = &vnops;
3176 					fp_set_data(fp, vp);
3177 
3178 					proc_fdlock(p);
3179 					procfdtbl_releasefd(p, dyld_fd, NULL);
3180 					fp_drop(p, dyld_fd, fp, 1);
3181 					proc_fdunlock(p);
3182 
3183 					vnode_ref(vp);
3184 
3185 					result->dynlinker_fd = dyld_fd;
3186 					result->dynlinker_fp = fp;
3187 					result->dynlinker_mach_header = myresult->mach_header;
3188 					result->dynlinker_max_vm_addr = myresult->max_vm_addr;
3189 					result->dynlinker_ro_vm_start = myresult->ro_vm_start;
3190 					result->dynlinker_ro_vm_end = myresult->ro_vm_end;
3191 				} else {
3192 					fp_free(p, dyld_fd, fp);
3193 					ret = LOAD_IOERROR;
3194 				}
3195 			} else {
3196 				ret = LOAD_IOERROR;
3197 			}
3198 		}
3199 #endif
3200 	}
3201 
3202 	struct vnode_attr *va;
3203 	va = kalloc_type(struct vnode_attr, Z_WAITOK | Z_ZERO);
3204 	VATTR_INIT(va);
3205 	VATTR_WANTED(va, va_fsid64);
3206 	VATTR_WANTED(va, va_fsid);
3207 	VATTR_WANTED(va, va_fileid);
3208 	int error = vnode_getattr(vp, va, imgp->ip_vfs_context);
3209 	if (error == 0) {
3210 		imgp->ip_dyld_fsid = vnode_get_va_fsid(va);
3211 		imgp->ip_dyld_fsobjid = va->va_fileid;
3212 	}
3213 
3214 	vnode_put(vp);
3215 	kfree_type(struct vnode_attr, va);
3216 novp_out:
3217 	kfree_type(typeof(*dyld_data), dyld_data);
3218 	return ret;
3219 }
3220 
3221 #if CONFIG_ROSETTA
3222 static const char* rosetta_runtime_path = "/usr/libexec/rosetta/runtime";
3223 
3224 #if (DEVELOPMENT || DEBUG)
3225 static const char* rosetta_runtime_path_alt_x86 = "/usr/local/libexec/rosetta/runtime_internal";
3226 static const char* rosetta_runtime_path_alt_arm = "/usr/local/libexec/rosetta/runtime_arm_internal";
3227 #endif
3228 
3229 static load_return_t
load_rosetta(vm_map_t map,thread_t thread,load_result_t * result,struct image_params * imgp)3230 load_rosetta(
3231 	vm_map_t                        map,
3232 	thread_t                        thread,
3233 	load_result_t           *result,
3234 	struct image_params     *imgp)
3235 {
3236 	struct vnode            *vp = NULLVP;   /* set by get_macho_vnode() */
3237 	struct mach_header      *header;
3238 	off_t                   file_offset = 0; /* set by get_macho_vnode() */
3239 	off_t                   macho_size = 0; /* set by get_macho_vnode() */
3240 	load_result_t           *myresult;
3241 	kern_return_t           ret;
3242 	struct macho_data       *macho_data;
3243 	const char              *rosetta_file_path;
3244 	struct {
3245 		struct mach_header      __header;
3246 		load_result_t           __myresult;
3247 		struct macho_data       __macho_data;
3248 	} *rosetta_data;
3249 	mach_vm_address_t rosetta_load_addr;
3250 	mach_vm_size_t    rosetta_size;
3251 	mach_vm_address_t shared_cache_base = SHARED_REGION_BASE_ARM64;
3252 	int64_t           slide = 0;
3253 
3254 	/* Allocate wad-of-data from heap to reduce excessively deep stacks */
3255 	rosetta_data = kalloc_type(typeof(*rosetta_data), Z_WAITOK | Z_NOFAIL);
3256 	header = &rosetta_data->__header;
3257 	myresult = &rosetta_data->__myresult;
3258 	macho_data = &rosetta_data->__macho_data;
3259 
3260 	rosetta_file_path = rosetta_runtime_path;
3261 
3262 #if (DEVELOPMENT || DEBUG)
3263 	bool use_alt_rosetta = false;
3264 	if (imgp->ip_flags & IMGPF_ALT_ROSETTA) {
3265 		use_alt_rosetta = true;
3266 	} else {
3267 		int policy_error;
3268 		uint32_t policy_flags = 0;
3269 		int32_t policy_gencount = 0;
3270 		policy_error = proc_uuid_policy_lookup(result->uuid, &policy_flags, &policy_gencount);
3271 		if (policy_error == 0 && (policy_flags & PROC_UUID_ALT_ROSETTA_POLICY) != 0) {
3272 			use_alt_rosetta = true;
3273 		}
3274 	}
3275 
3276 	if (use_alt_rosetta) {
3277 		if (imgp->ip_origcputype == CPU_TYPE_X86_64) {
3278 			rosetta_file_path = rosetta_runtime_path_alt_x86;
3279 		} else if (imgp->ip_origcputype == CPU_TYPE_ARM64) {
3280 			rosetta_file_path = rosetta_runtime_path_alt_arm;
3281 		} else {
3282 			ret = LOAD_BADARCH;
3283 			goto novp_out;
3284 		}
3285 	}
3286 #endif
3287 
3288 	ret = get_macho_vnode(rosetta_file_path, CPU_TYPE_ARM64, header,
3289 	    &file_offset, &macho_size, macho_data, &vp, imgp);
3290 	if (ret) {
3291 		goto novp_out;
3292 	}
3293 
3294 	*myresult = load_result_null;
3295 	myresult->is_64bit_addr = TRUE;
3296 	myresult->is_64bit_data = TRUE;
3297 
3298 	ret = parse_machfile(vp, NULL, NULL, header, file_offset, macho_size,
3299 	    2, 0, 0, myresult, NULL, imgp);
3300 	if (ret != LOAD_SUCCESS) {
3301 		goto out;
3302 	}
3303 
3304 	if (!(imgp->ip_flags & IMGPF_DISABLE_ASLR)) {
3305 		slide = random();
3306 		slide = (slide % (vm_map_get_max_loader_aslr_slide_pages(map) - 1)) + 1;
3307 		slide <<= vm_map_page_shift(map);
3308 	}
3309 
3310 	if (imgp->ip_origcputype == CPU_TYPE_X86_64) {
3311 		shared_cache_base = SHARED_REGION_BASE_X86_64;
3312 	}
3313 
3314 	rosetta_size = round_page(myresult->max_vm_addr - myresult->min_vm_addr);
3315 	rosetta_load_addr = shared_cache_base - rosetta_size - slide;
3316 
3317 	*myresult = load_result_null;
3318 	myresult->is_64bit_addr = TRUE;
3319 	myresult->is_64bit_data = TRUE;
3320 	myresult->is_rosetta = TRUE;
3321 
3322 	ret = parse_machfile(vp, map, thread, header, file_offset, macho_size,
3323 	    2, rosetta_load_addr, 0, myresult, result, imgp);
3324 	if (ret == LOAD_SUCCESS) {
3325 		if (result) {
3326 			if (result->threadstate) {
3327 				/* don't use the app's/dyld's threadstate */
3328 				kfree_data(result->threadstate, result->threadstate_sz);
3329 			}
3330 			assert(myresult->threadstate != NULL);
3331 
3332 			result->is_rosetta = TRUE;
3333 
3334 			result->threadstate = myresult->threadstate;
3335 			result->threadstate_sz = myresult->threadstate_sz;
3336 
3337 			result->entry_point = myresult->entry_point;
3338 			result->validentry = myresult->validentry;
3339 			if (!myresult->platform_binary) {
3340 				result->csflags &= ~CS_NO_UNTRUSTED_HELPERS;
3341 			}
3342 
3343 			if ((header->cpusubtype & ~CPU_SUBTYPE_MASK) != CPU_SUBTYPE_ARM64E) {
3344 				imgp->ip_flags |= IMGPF_NOJOP;
3345 			}
3346 		}
3347 	}
3348 
3349 out:
3350 	vnode_put(vp);
3351 novp_out:
3352 	kfree_type(typeof(*rosetta_data), rosetta_data);
3353 	return ret;
3354 }
3355 #endif
3356 
3357 static void
set_signature_error(struct vnode * vp,struct image_params * imgp,const char * fatal_failure_desc,const size_t fatal_failure_desc_len)3358 set_signature_error(
3359 	struct vnode* vp,
3360 	struct image_params * imgp,
3361 	const char* fatal_failure_desc,
3362 	const size_t fatal_failure_desc_len)
3363 {
3364 	char *vn_path = NULL;
3365 	vm_size_t vn_pathlen = MAXPATHLEN;
3366 	char const *path = NULL;
3367 
3368 	vn_path = zalloc(ZV_NAMEI);
3369 	if (vn_getpath(vp, vn_path, (int*)&vn_pathlen) == 0) {
3370 		path = vn_path;
3371 	} else {
3372 		path = "(get vnode path failed)";
3373 	}
3374 	os_reason_t reason = os_reason_create(OS_REASON_CODESIGNING,
3375 	    CODESIGNING_EXIT_REASON_TASKGATED_INVALID_SIG);
3376 
3377 	if (reason == OS_REASON_NULL) {
3378 		printf("load_code_signature: %s: failure to allocate exit reason for validation failure: %s\n",
3379 		    path, fatal_failure_desc);
3380 		goto out;
3381 	}
3382 
3383 	imgp->ip_cs_error = reason;
3384 	reason->osr_flags = (OS_REASON_FLAG_GENERATE_CRASH_REPORT |
3385 	    OS_REASON_FLAG_CONSISTENT_FAILURE);
3386 
3387 	mach_vm_address_t data_addr = 0;
3388 
3389 	int reason_error = 0;
3390 	int kcdata_error = 0;
3391 
3392 	if ((reason_error = os_reason_alloc_buffer_noblock(reason, kcdata_estimate_required_buffer_size
3393 	    (1, (uint32_t)fatal_failure_desc_len))) == 0 &&
3394 	    (kcdata_error = kcdata_get_memory_addr(&reason->osr_kcd_descriptor,
3395 	    EXIT_REASON_USER_DESC, (uint32_t)fatal_failure_desc_len,
3396 	    &data_addr)) == KERN_SUCCESS) {
3397 		kern_return_t mc_error = kcdata_memcpy(&reason->osr_kcd_descriptor, (mach_vm_address_t)data_addr,
3398 		    fatal_failure_desc, (uint32_t)fatal_failure_desc_len);
3399 
3400 		if (mc_error != KERN_SUCCESS) {
3401 			printf("load_code_signature: %s: failed to copy reason string "
3402 			    "(kcdata_memcpy error: %d, length: %ld)\n",
3403 			    path, mc_error, fatal_failure_desc_len);
3404 		}
3405 	} else {
3406 		printf("load_code_signature: %s: failed to allocate space for reason string "
3407 		    "(os_reason_alloc_buffer error: %d, kcdata error: %d, length: %ld)\n",
3408 		    path, reason_error, kcdata_error, fatal_failure_desc_len);
3409 	}
3410 out:
3411 	if (vn_path) {
3412 		zfree(ZV_NAMEI, vn_path);
3413 	}
3414 }
3415 
3416 static load_return_t
load_code_signature(struct linkedit_data_command * lcp,struct vnode * vp,off_t macho_offset,off_t macho_size,cpu_type_t cputype,cpu_subtype_t cpusubtype,load_result_t * result,struct image_params * imgp)3417 load_code_signature(
3418 	struct linkedit_data_command    *lcp,
3419 	struct vnode                    *vp,
3420 	off_t                           macho_offset,
3421 	off_t                           macho_size,
3422 	cpu_type_t                      cputype,
3423 	cpu_subtype_t                   cpusubtype,
3424 	load_result_t                   *result,
3425 	struct image_params             *imgp)
3426 {
3427 	int             ret;
3428 	kern_return_t   kr;
3429 	vm_offset_t     addr;
3430 	int             resid;
3431 	struct cs_blob  *blob;
3432 	int             error;
3433 	vm_size_t       blob_size;
3434 	uint32_t        sum;
3435 	boolean_t               anyCPU;
3436 
3437 	addr = 0;
3438 	blob = NULL;
3439 
3440 	cpusubtype &= ~CPU_SUBTYPE_MASK;
3441 
3442 	blob = ubc_cs_blob_get(vp, cputype, cpusubtype, macho_offset);
3443 
3444 	if (blob != NULL) {
3445 		/* we already have a blob for this vnode and cpu(sub)type */
3446 		anyCPU = blob->csb_cpu_type == -1;
3447 		if ((blob->csb_cpu_type != cputype &&
3448 		    blob->csb_cpu_subtype != cpusubtype && !anyCPU) ||
3449 		    (blob->csb_base_offset != macho_offset) ||
3450 		    ((blob->csb_flags & CS_VALID) == 0)) {
3451 			/* the blob has changed for this vnode: fail ! */
3452 			ret = LOAD_BADMACHO;
3453 			const char* fatal_failure_desc = "embedded signature doesn't match attached signature";
3454 			const size_t fatal_failure_desc_len = strlen(fatal_failure_desc) + 1;
3455 
3456 			printf("load_code_signature: %s\n", fatal_failure_desc);
3457 			set_signature_error(vp, imgp, fatal_failure_desc, fatal_failure_desc_len);
3458 			goto out;
3459 		}
3460 
3461 		/* It matches the blob we want here, let's verify the version */
3462 		if (!anyCPU && ubc_cs_generation_check(vp) == 0) {
3463 			/* No need to revalidate, we're good! */
3464 			ret = LOAD_SUCCESS;
3465 			goto out;
3466 		}
3467 
3468 		/* That blob may be stale, let's revalidate. */
3469 		error = ubc_cs_blob_revalidate(vp, blob, imgp, 0, result->ip_platform);
3470 		if (error == 0) {
3471 			/* Revalidation succeeded, we're good! */
3472 			/* If we were revaliding a CS blob with any CPU arch we adjust it */
3473 			if (anyCPU) {
3474 				vnode_lock_spin(vp);
3475 				struct cs_cpu_info cpu_info = {
3476 					.csb_cpu_type = cputype,
3477 					.csb_cpu_subtype = cpusubtype
3478 				};
3479 				zalloc_ro_update_field(ZONE_ID_CS_BLOB, blob, csb_cpu_info, &cpu_info);
3480 				vnode_unlock(vp);
3481 			}
3482 			ret = LOAD_SUCCESS;
3483 			goto out;
3484 		}
3485 
3486 		if (error != EAGAIN) {
3487 			printf("load_code_signature: revalidation failed: %d\n", error);
3488 			ret = LOAD_FAILURE;
3489 			goto out;
3490 		}
3491 
3492 		assert(error == EAGAIN);
3493 
3494 		/*
3495 		 * Revalidation was not possible for this blob. We just continue as if there was no blob,
3496 		 * rereading the signature, and ubc_cs_blob_add will do the right thing.
3497 		 */
3498 		blob = NULL;
3499 	}
3500 
3501 	if (lcp->cmdsize != sizeof(struct linkedit_data_command)) {
3502 		ret = LOAD_BADMACHO;
3503 		goto out;
3504 	}
3505 
3506 	sum = 0;
3507 	if (os_add_overflow(lcp->dataoff, lcp->datasize, &sum) || sum > macho_size) {
3508 		ret = LOAD_BADMACHO;
3509 		goto out;
3510 	}
3511 
3512 	blob_size = lcp->datasize;
3513 	kr = ubc_cs_blob_allocate(&addr, &blob_size);
3514 	if (kr != KERN_SUCCESS) {
3515 		ret = LOAD_NOSPACE;
3516 		goto out;
3517 	}
3518 
3519 	resid = 0;
3520 	error = vn_rdwr(UIO_READ,
3521 	    vp,
3522 	    (caddr_t) addr,
3523 	    lcp->datasize,
3524 	    macho_offset + lcp->dataoff,
3525 	    UIO_SYSSPACE,
3526 	    0,
3527 	    kauth_cred_get(),
3528 	    &resid,
3529 	    current_proc());
3530 	if (error || resid != 0) {
3531 		ret = LOAD_IOERROR;
3532 		goto out;
3533 	}
3534 
3535 	if (ubc_cs_blob_add(vp,
3536 	    result->ip_platform,
3537 	    cputype,
3538 	    cpusubtype,
3539 	    macho_offset,
3540 	    &addr,
3541 	    lcp->datasize,
3542 	    imgp,
3543 	    0,
3544 	    &blob)) {
3545 		if (addr) {
3546 			ubc_cs_blob_deallocate(addr, blob_size);
3547 			addr = 0;
3548 		}
3549 		ret = LOAD_FAILURE;
3550 		goto out;
3551 	} else {
3552 		/* ubc_cs_blob_add() has consumed "addr" */
3553 		addr = 0;
3554 	}
3555 
3556 #if CHECK_CS_VALIDATION_BITMAP
3557 	ubc_cs_validation_bitmap_allocate( vp );
3558 #endif
3559 
3560 	ret = LOAD_SUCCESS;
3561 out:
3562 	if (ret == LOAD_SUCCESS) {
3563 		if (blob == NULL) {
3564 			panic("success, but no blob!");
3565 		}
3566 
3567 		result->csflags |= blob->csb_flags;
3568 		result->platform_binary = blob->csb_platform_binary;
3569 		result->cs_end_offset = blob->csb_end_offset;
3570 	}
3571 	if (addr != 0) {
3572 		ubc_cs_blob_deallocate(addr, blob_size);
3573 		addr = 0;
3574 	}
3575 
3576 	return ret;
3577 }
3578 
3579 
3580 #if CONFIG_CODE_DECRYPTION
3581 
3582 static load_return_t
set_code_unprotect(struct encryption_info_command * eip,caddr_t addr,vm_map_t map,int64_t slide,struct vnode * vp,off_t macho_offset,cpu_type_t cputype,cpu_subtype_t cpusubtype)3583 set_code_unprotect(
3584 	struct encryption_info_command *eip,
3585 	caddr_t addr,
3586 	vm_map_t map,
3587 	int64_t slide,
3588 	struct vnode *vp,
3589 	off_t macho_offset,
3590 	cpu_type_t cputype,
3591 	cpu_subtype_t cpusubtype)
3592 {
3593 	int error, len;
3594 	pager_crypt_info_t crypt_info;
3595 	const char * cryptname = 0;
3596 	char *vpath;
3597 
3598 	size_t offset;
3599 	struct segment_command_64 *seg64;
3600 	struct segment_command *seg32;
3601 	vm_map_offset_t map_offset, map_size;
3602 	vm_object_offset_t crypto_backing_offset;
3603 	kern_return_t kr;
3604 
3605 	if (eip->cmdsize < sizeof(*eip)) {
3606 		return LOAD_BADMACHO;
3607 	}
3608 
3609 	switch (eip->cryptid) {
3610 	case 0:
3611 		/* not encrypted, just an empty load command */
3612 		return LOAD_SUCCESS;
3613 	case 1:
3614 		cryptname = "com.apple.unfree";
3615 		break;
3616 	case 0x10:
3617 		/* some random cryptid that you could manually put into
3618 		 * your binary if you want NULL */
3619 		cryptname = "com.apple.null";
3620 		break;
3621 	default:
3622 		return LOAD_BADMACHO;
3623 	}
3624 
3625 	if (map == VM_MAP_NULL) {
3626 		return LOAD_SUCCESS;
3627 	}
3628 	if (NULL == text_crypter_create) {
3629 		return LOAD_FAILURE;
3630 	}
3631 
3632 	vpath = zalloc(ZV_NAMEI);
3633 
3634 	len = MAXPATHLEN;
3635 	error = vn_getpath(vp, vpath, &len);
3636 	if (error) {
3637 		zfree(ZV_NAMEI, vpath);
3638 		return LOAD_FAILURE;
3639 	}
3640 
3641 	if (eip->cryptsize == 0) {
3642 		printf("%s:%d '%s': cryptoff 0x%llx cryptsize 0x%llx cryptid 0x%x ignored\n", __FUNCTION__, __LINE__, vpath, (uint64_t)eip->cryptoff, (uint64_t)eip->cryptsize, eip->cryptid);
3643 		zfree(ZV_NAMEI, vpath);
3644 		return LOAD_SUCCESS;
3645 	}
3646 
3647 	/* set up decrypter first */
3648 	crypt_file_data_t crypt_data = {
3649 		.filename = vpath,
3650 		.cputype = cputype,
3651 		.cpusubtype = cpusubtype,
3652 		.origin = CRYPT_ORIGIN_APP_LAUNCH,
3653 	};
3654 	kr = text_crypter_create(&crypt_info, cryptname, (void*)&crypt_data);
3655 #if VM_MAP_DEBUG_APPLE_PROTECT
3656 	if (vm_map_debug_apple_protect) {
3657 		struct proc *p;
3658 		p  = current_proc();
3659 		printf("APPLE_PROTECT: %d[%s] map %p %s(%s) -> 0x%x\n",
3660 		    proc_getpid(p), p->p_comm, map, __FUNCTION__, vpath, kr);
3661 	}
3662 #endif /* VM_MAP_DEBUG_APPLE_PROTECT */
3663 	zfree(ZV_NAMEI, vpath);
3664 
3665 	if (kr) {
3666 		printf("set_code_unprotect: unable to create decrypter %s, kr=%d\n",
3667 		    cryptname, kr);
3668 		if (kr == kIOReturnNotPrivileged) {
3669 			/* text encryption returned decryption failure */
3670 			return LOAD_DECRYPTFAIL;
3671 		} else {
3672 			return LOAD_RESOURCE;
3673 		}
3674 	}
3675 
3676 	/* this is terrible, but we have to rescan the load commands to find the
3677 	 * virtual address of this encrypted stuff. This code is gonna look like
3678 	 * the dyld source one day... */
3679 	struct mach_header *header = (struct mach_header *)addr;
3680 	size_t mach_header_sz = sizeof(struct mach_header);
3681 	if (header->magic == MH_MAGIC_64 ||
3682 	    header->magic == MH_CIGAM_64) {
3683 		mach_header_sz = sizeof(struct mach_header_64);
3684 	}
3685 	offset = mach_header_sz;
3686 	uint32_t ncmds = header->ncmds;
3687 	while (ncmds--) {
3688 		/*
3689 		 *	Get a pointer to the command.
3690 		 */
3691 		struct load_command *lcp = (struct load_command *)(addr + offset);
3692 		offset += lcp->cmdsize;
3693 
3694 		switch (lcp->cmd) {
3695 		case LC_SEGMENT_64:
3696 			seg64 = (struct segment_command_64 *)lcp;
3697 			if ((seg64->fileoff <= eip->cryptoff) &&
3698 			    (seg64->fileoff + seg64->filesize >=
3699 			    eip->cryptoff + eip->cryptsize)) {
3700 				map_offset = (vm_map_offset_t)(seg64->vmaddr + eip->cryptoff - seg64->fileoff + slide);
3701 				map_size = eip->cryptsize;
3702 				crypto_backing_offset = macho_offset + eip->cryptoff;
3703 				goto remap_now;
3704 			}
3705 			break;
3706 		case LC_SEGMENT:
3707 			seg32 = (struct segment_command *)lcp;
3708 			if ((seg32->fileoff <= eip->cryptoff) &&
3709 			    (seg32->fileoff + seg32->filesize >=
3710 			    eip->cryptoff + eip->cryptsize)) {
3711 				map_offset = (vm_map_offset_t)(seg32->vmaddr + eip->cryptoff - seg32->fileoff + slide);
3712 				map_size = eip->cryptsize;
3713 				crypto_backing_offset = macho_offset + eip->cryptoff;
3714 				goto remap_now;
3715 			}
3716 			break;
3717 		}
3718 	}
3719 
3720 	/* if we get here, did not find anything */
3721 	return LOAD_BADMACHO;
3722 
3723 remap_now:
3724 	/* now remap using the decrypter */
3725 	MACHO_PRINTF(("+++ set_code_unprotect: vm[0x%llx:0x%llx]\n",
3726 	    (uint64_t) map_offset,
3727 	    (uint64_t) (map_offset + map_size)));
3728 	kr = vm_map_apple_protected(map,
3729 	    map_offset,
3730 	    map_offset + map_size,
3731 	    crypto_backing_offset,
3732 	    &crypt_info,
3733 	    CRYPTID_APP_ENCRYPTION);
3734 	if (kr) {
3735 		printf("set_code_unprotect(): mapping failed with %x\n", kr);
3736 		return LOAD_PROTECT;
3737 	}
3738 
3739 	return LOAD_SUCCESS;
3740 }
3741 
3742 #endif
3743 
3744 /*
3745  * This routine exists to support the load_dylinker().
3746  *
3747  * This routine has its own, separate, understanding of the FAT file format,
3748  * which is terrifically unfortunate.
3749  */
3750 static
3751 load_return_t
get_macho_vnode(const char * path,cpu_type_t cputype,struct mach_header * mach_header,off_t * file_offset,off_t * macho_size,struct macho_data * data,struct vnode ** vpp,struct image_params * imgp)3752 get_macho_vnode(
3753 	const char              *path,
3754 	cpu_type_t              cputype,
3755 	struct mach_header      *mach_header,
3756 	off_t                   *file_offset,
3757 	off_t                   *macho_size,
3758 	struct macho_data       *data,
3759 	struct vnode            **vpp,
3760 	struct image_params     *imgp
3761 	)
3762 {
3763 	struct vnode            *vp;
3764 	vfs_context_t           ctx = vfs_context_current();
3765 	proc_t                  p = vfs_context_proc(ctx);
3766 	kauth_cred_t            kerncred;
3767 	struct nameidata        *ndp = &data->__nid;
3768 	boolean_t               is_fat;
3769 	struct fat_arch         fat_arch;
3770 	int                     error;
3771 	int resid;
3772 	union macho_vnode_header *header = &data->__header;
3773 	off_t fsize = (off_t)0;
3774 
3775 	/*
3776 	 * Capture the kernel credential for use in the actual read of the
3777 	 * file, since the user doing the execution may have execute rights
3778 	 * but not read rights, but to exec something, we have to either map
3779 	 * or read it into the new process address space, which requires
3780 	 * read rights.  This is to deal with lack of common credential
3781 	 * serialization code which would treat NOCRED as "serialize 'root'".
3782 	 */
3783 	kerncred = vfs_context_ucred(vfs_context_kernel());
3784 
3785 	/* init the namei data to point the file user's program name */
3786 	NDINIT(ndp, LOOKUP, OP_OPEN, FOLLOW | LOCKLEAF, UIO_SYSSPACE, CAST_USER_ADDR_T(path), ctx);
3787 
3788 	if ((error = namei(ndp)) != 0) {
3789 		if (error == ENOENT) {
3790 			error = LOAD_ENOENT;
3791 		} else {
3792 			error = LOAD_FAILURE;
3793 		}
3794 		return error;
3795 	}
3796 	nameidone(ndp);
3797 	vp = ndp->ni_vp;
3798 
3799 	/* check for regular file */
3800 	if (vp->v_type != VREG) {
3801 		error = LOAD_PROTECT;
3802 		goto bad1;
3803 	}
3804 
3805 	/* get size */
3806 	if ((error = vnode_size(vp, &fsize, ctx)) != 0) {
3807 		error = LOAD_FAILURE;
3808 		goto bad1;
3809 	}
3810 
3811 	/* Check mount point */
3812 	if (vp->v_mount->mnt_flag & MNT_NOEXEC) {
3813 		error = LOAD_PROTECT;
3814 		goto bad1;
3815 	}
3816 
3817 	/* check access */
3818 	if ((error = vnode_authorize(vp, NULL, KAUTH_VNODE_EXECUTE | KAUTH_VNODE_READ_DATA, ctx)) != 0) {
3819 		error = LOAD_PROTECT;
3820 		goto bad1;
3821 	}
3822 
3823 	/* try to open it */
3824 	if ((error = VNOP_OPEN(vp, FREAD, ctx)) != 0) {
3825 		error = LOAD_PROTECT;
3826 		goto bad1;
3827 	}
3828 
3829 	if ((error = vn_rdwr(UIO_READ, vp, (caddr_t)header, sizeof(*header), 0,
3830 	    UIO_SYSSPACE, IO_NODELOCKED, kerncred, &resid, p)) != 0) {
3831 		error = LOAD_IOERROR;
3832 		goto bad2;
3833 	}
3834 
3835 	if (resid) {
3836 		error = LOAD_BADMACHO;
3837 		goto bad2;
3838 	}
3839 
3840 	if (header->mach_header.magic == MH_MAGIC ||
3841 	    header->mach_header.magic == MH_MAGIC_64) {
3842 		is_fat = FALSE;
3843 	} else if (OSSwapBigToHostInt32(header->fat_header.magic) == FAT_MAGIC) {
3844 		is_fat = TRUE;
3845 	} else {
3846 		error = LOAD_BADMACHO;
3847 		goto bad2;
3848 	}
3849 
3850 	if (is_fat) {
3851 		error = fatfile_validate_fatarches((vm_offset_t)(&header->fat_header),
3852 		    sizeof(*header), fsize);
3853 		if (error != LOAD_SUCCESS) {
3854 			goto bad2;
3855 		}
3856 
3857 		/* Look up our architecture in the fat file. */
3858 		error = fatfile_getbestarch_for_cputype(cputype, CPU_SUBTYPE_ANY,
3859 		    (vm_offset_t)(&header->fat_header), sizeof(*header), imgp, &fat_arch);
3860 		if (error != LOAD_SUCCESS) {
3861 			goto bad2;
3862 		}
3863 
3864 		/* Read the Mach-O header out of it */
3865 		error = vn_rdwr(UIO_READ, vp, (caddr_t)&header->mach_header,
3866 		    sizeof(header->mach_header), fat_arch.offset,
3867 		    UIO_SYSSPACE, IO_NODELOCKED, kerncred, &resid, p);
3868 		if (error) {
3869 			error = LOAD_IOERROR;
3870 			goto bad2;
3871 		}
3872 
3873 		if (resid) {
3874 			error = LOAD_BADMACHO;
3875 			goto bad2;
3876 		}
3877 
3878 		/* Is this really a Mach-O? */
3879 		if (header->mach_header.magic != MH_MAGIC &&
3880 		    header->mach_header.magic != MH_MAGIC_64) {
3881 			error = LOAD_BADMACHO;
3882 			goto bad2;
3883 		}
3884 
3885 		*file_offset = fat_arch.offset;
3886 		*macho_size = fat_arch.size;
3887 	} else {
3888 		/*
3889 		 * Force get_macho_vnode() to fail if the architecture bits
3890 		 * do not match the expected architecture bits.  This in
3891 		 * turn causes load_dylinker() to fail for the same reason,
3892 		 * so it ensures the dynamic linker and the binary are in
3893 		 * lock-step.  This is potentially bad, if we ever add to
3894 		 * the CPU_ARCH_* bits any bits that are desirable but not
3895 		 * required, since the dynamic linker might work, but we will
3896 		 * refuse to load it because of this check.
3897 		 */
3898 		if ((cpu_type_t)header->mach_header.cputype != cputype) {
3899 			error = LOAD_BADARCH;
3900 			goto bad2;
3901 		}
3902 
3903 		*file_offset = 0;
3904 		*macho_size = fsize;
3905 	}
3906 
3907 	*mach_header = header->mach_header;
3908 	*vpp = vp;
3909 
3910 	ubc_setsize(vp, fsize);
3911 	return error;
3912 
3913 bad2:
3914 	(void) VNOP_CLOSE(vp, FREAD, ctx);
3915 bad1:
3916 	vnode_put(vp);
3917 	return error;
3918 }
3919