1 /*
2  * Copyright (c) 1999-2014 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  *	File:	ubc_subr.c
30  *	Author:	Umesh Vaishampayan [umeshv@apple.com]
31  *		05-Aug-1999	umeshv	Created.
32  *
33  *	Functions related to Unified Buffer cache.
34  *
35  * Caller of UBC functions MUST have a valid reference on the vnode.
36  *
37  */
38 
39 #include <sys/types.h>
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/lock.h>
43 #include <sys/mman.h>
44 #include <sys/mount_internal.h>
45 #include <sys/vnode_internal.h>
46 #include <sys/ubc_internal.h>
47 #include <sys/ucred.h>
48 #include <sys/proc_internal.h>
49 #include <sys/kauth.h>
50 #include <sys/buf.h>
51 #include <sys/user.h>
52 #include <sys/codesign.h>
53 #include <sys/codedir_internal.h>
54 #include <sys/fsevents.h>
55 #include <sys/fcntl.h>
56 
57 #include <mach/mach_types.h>
58 #include <mach/memory_object_types.h>
59 #include <mach/memory_object_control.h>
60 #include <mach/vm_map.h>
61 #include <mach/mach_vm.h>
62 #include <mach/upl.h>
63 
64 #include <kern/kern_types.h>
65 #include <kern/kalloc.h>
66 #include <kern/zalloc.h>
67 #include <kern/thread.h>
68 #include <vm/vm_kern.h>
69 #include <vm/vm_protos.h> /* last */
70 
71 #include <libkern/crypto/sha1.h>
72 #include <libkern/crypto/sha2.h>
73 #include <libkern/libkern.h>
74 
75 #include <security/mac_framework.h>
76 #include <stdbool.h>
77 
78 /* XXX These should be in a BSD accessible Mach header, but aren't. */
79 extern kern_return_t memory_object_pages_resident(memory_object_control_t,
80 							boolean_t *);
81 extern kern_return_t	memory_object_signed(memory_object_control_t control,
82 					     boolean_t is_signed);
83 extern boolean_t	memory_object_is_slid(memory_object_control_t	control);
84 extern boolean_t	memory_object_is_signed(memory_object_control_t);
85 
86 extern void Debugger(const char *message);
87 
88 
89 /* XXX no one uses this interface! */
90 kern_return_t ubc_page_op_with_control(
91 	memory_object_control_t	 control,
92 	off_t		         f_offset,
93 	int		         ops,
94 	ppnum_t	                 *phys_entryp,
95 	int		         *flagsp);
96 
97 
98 #if DIAGNOSTIC
99 #if defined(assert)
100 #undef assert
101 #endif
102 #define assert(cond)    \
103     ((void) ((cond) ? 0 : panic("Assert failed: %s", # cond)))
104 #else
105 #include <kern/assert.h>
106 #endif /* DIAGNOSTIC */
107 
108 static int ubc_info_init_internal(struct vnode *vp, int withfsize, off_t filesize);
109 static int ubc_umcallback(vnode_t, void *);
110 static int ubc_msync_internal(vnode_t, off_t, off_t, off_t *, int, int *);
111 static void ubc_cs_free(struct ubc_info *uip);
112 
113 static boolean_t ubc_cs_supports_multilevel_hash(struct cs_blob *blob);
114 static void ubc_cs_convert_to_multilevel_hash(struct cs_blob *blob);
115 
116 struct zone	*ubc_info_zone;
117 static uint32_t	cs_blob_generation_count = 1;
118 
119 /*
120  * CODESIGNING
121  * Routines to navigate code signing data structures in the kernel...
122  */
123 
124 extern int cs_debug;
125 
126 #define	PAGE_SHIFT_4K		(12)
127 
128 static boolean_t
cs_valid_range( const void *start, const void *end, const void *lower_bound, const void *upper_bound)129 cs_valid_range(
130 	const void *start,
131 	const void *end,
132 	const void *lower_bound,
133 	const void *upper_bound)
134 {
135 	if (upper_bound < lower_bound ||
136 	    end < start) {
137 		return FALSE;
138 	}
139 
140 	if (start < lower_bound ||
141 	    end > upper_bound) {
142 		return FALSE;
143 	}
144 
145 	return TRUE;
146 }
147 
148 typedef void (*cs_md_init)(void *ctx);
149 typedef void (*cs_md_update)(void *ctx, const void *data, size_t size);
150 typedef void (*cs_md_final)(void *hash, void *ctx);
151 
152 struct cs_hash {
153     uint8_t		cs_type;	/* type code as per code signing */
154     size_t		cs_size;	/* size of effective hash (may be truncated) */
155     size_t		cs_digest_size;	/* size of native hash */
156     cs_md_init		cs_init;
157     cs_md_update 	cs_update;
158     cs_md_final		cs_final;
159 };
160 
161 static const struct cs_hash cs_hash_sha1 = {
162     .cs_type = CS_HASHTYPE_SHA1,
163     .cs_size = CS_SHA1_LEN,
164     .cs_digest_size = SHA_DIGEST_LENGTH,
165     .cs_init = (cs_md_init)SHA1Init,
166     .cs_update = (cs_md_update)SHA1Update,
167     .cs_final = (cs_md_final)SHA1Final,
168 };
169 #if CRYPTO_SHA2
170 static const struct cs_hash cs_hash_sha256 = {
171     .cs_type = CS_HASHTYPE_SHA256,
172     .cs_size = SHA256_DIGEST_LENGTH,
173     .cs_digest_size = SHA256_DIGEST_LENGTH,
174     .cs_init = (cs_md_init)SHA256_Init,
175     .cs_update = (cs_md_update)SHA256_Update,
176     .cs_final = (cs_md_final)SHA256_Final,
177 };
178 static const struct cs_hash cs_hash_sha256_truncate = {
179     .cs_type = CS_HASHTYPE_SHA256_TRUNCATED,
180     .cs_size = CS_SHA256_TRUNCATED_LEN,
181     .cs_digest_size = SHA256_DIGEST_LENGTH,
182     .cs_init = (cs_md_init)SHA256_Init,
183     .cs_update = (cs_md_update)SHA256_Update,
184     .cs_final = (cs_md_final)SHA256_Final,
185 };
186 static const struct cs_hash cs_hash_sha384 = {
187     .cs_type = CS_HASHTYPE_SHA384,
188     .cs_size = SHA384_DIGEST_LENGTH,
189     .cs_digest_size = SHA384_DIGEST_LENGTH,
190     .cs_init = (cs_md_init)SHA384_Init,
191     .cs_update = (cs_md_update)SHA384_Update,
192     .cs_final = (cs_md_final)SHA384_Final,
193 };
194 #endif
195 
196 static struct cs_hash const *
cs_find_md(uint8_t type)197 cs_find_md(uint8_t type)
198 {
199 	if (type == CS_HASHTYPE_SHA1) {
200 		return &cs_hash_sha1;
201 #if CRYPTO_SHA2
202 	} else if (type == CS_HASHTYPE_SHA256) {
203 		return &cs_hash_sha256;
204 	} else if (type == CS_HASHTYPE_SHA256_TRUNCATED) {
205 		return &cs_hash_sha256_truncate;
206 	} else if (type == CS_HASHTYPE_SHA384) {
207 		return &cs_hash_sha384;
208 #endif
209 	}
210 	return NULL;
211 }
212 
213 union cs_hash_union {
214 	SHA1_CTX		sha1ctxt;
215 	SHA256_CTX		sha256ctx;
216 	SHA384_CTX		sha384ctx;
217 };
218 
219 
220 /*
221  * Choose among different hash algorithms.
222  * Higher is better, 0 => don't use at all.
223  */
224 static const uint32_t hashPriorities[] = {
225 	CS_HASHTYPE_SHA1,
226 	CS_HASHTYPE_SHA256_TRUNCATED,
227 	CS_HASHTYPE_SHA256,
228 	CS_HASHTYPE_SHA384,
229 };
230 
231 static unsigned int
hash_rank(const CS_CodeDirectory *cd)232 hash_rank(const CS_CodeDirectory *cd)
233 {
234 	uint32_t type = cd->hashType;
235 	unsigned int n;
236 
237 	for (n = 0; n < sizeof(hashPriorities) / sizeof(hashPriorities[0]); ++n)
238 		if (hashPriorities[n] == type)
239 			return n + 1;
240 	return 0;	/* not supported */
241 }
242 
243 
244 /*
245  * Locating a page hash
246  */
247 static const unsigned char *
hashes( const CS_CodeDirectory *cd, uint32_t page, size_t hash_len, const char *lower_bound, const char *upper_bound)248 hashes(
249 	const CS_CodeDirectory *cd,
250 	uint32_t page,
251 	size_t hash_len,
252 	const char *lower_bound,
253 	const char *upper_bound)
254 {
255 	const unsigned char *base, *top, *hash;
256 	uint32_t nCodeSlots = ntohl(cd->nCodeSlots);
257 
258 	assert(cs_valid_range(cd, cd + 1, lower_bound, upper_bound));
259 
260 	if((ntohl(cd->version) >= CS_SUPPORTSSCATTER) && (ntohl(cd->scatterOffset))) {
261 		/* Get first scatter struct */
262 		const SC_Scatter *scatter = (const SC_Scatter*)
263 			((const char*)cd + ntohl(cd->scatterOffset));
264 		uint32_t hashindex=0, scount, sbase=0;
265 		/* iterate all scatter structs */
266 		do {
267 			if((const char*)scatter > (const char*)cd + ntohl(cd->length)) {
268 				if(cs_debug) {
269 					printf("CODE SIGNING: Scatter extends past Code Directory\n");
270 				}
271 				return NULL;
272 			}
273 
274 			scount = ntohl(scatter->count);
275 			uint32_t new_base = ntohl(scatter->base);
276 
277 			/* last scatter? */
278 			if (scount == 0) {
279 				return NULL;
280 			}
281 
282 			if((hashindex > 0) && (new_base <= sbase)) {
283 				if(cs_debug) {
284 					printf("CODE SIGNING: unordered Scatter, prev base %d, cur base %d\n",
285 					sbase, new_base);
286 				}
287 				return NULL;	/* unordered scatter array */
288 			}
289 			sbase = new_base;
290 
291 			/* this scatter beyond page we're looking for? */
292 			if (sbase > page) {
293 				return NULL;
294 			}
295 
296 			if (sbase+scount >= page) {
297 				/* Found the scatter struct that is
298 				 * referencing our page */
299 
300 				/* base = address of first hash covered by scatter */
301 				base = (const unsigned char *)cd + ntohl(cd->hashOffset) +
302 					hashindex * hash_len;
303 				/* top = address of first hash after this scatter */
304 				top = base + scount * hash_len;
305 				if (!cs_valid_range(base, top, lower_bound,
306 						    upper_bound) ||
307 				    hashindex > nCodeSlots) {
308 					return NULL;
309 				}
310 
311 				break;
312 			}
313 
314 			/* this scatter struct is before the page we're looking
315 			 * for. Iterate. */
316 			hashindex+=scount;
317 			scatter++;
318 		} while(1);
319 
320 		hash = base + (page - sbase) * hash_len;
321 	} else {
322 		base = (const unsigned char *)cd + ntohl(cd->hashOffset);
323 		top = base + nCodeSlots * hash_len;
324 		if (!cs_valid_range(base, top, lower_bound, upper_bound) ||
325 		    page > nCodeSlots) {
326 			return NULL;
327 		}
328 		assert(page < nCodeSlots);
329 
330 		hash = base + page * hash_len;
331 	}
332 
333 	if (!cs_valid_range(hash, hash + hash_len,
334 			    lower_bound, upper_bound)) {
335 		hash = NULL;
336 	}
337 
338 	return hash;
339 }
340 
341 /*
342  * cs_validate_codedirectory
343  *
344  * Validate that pointers inside the code directory to make sure that
345  * all offsets and lengths are constrained within the buffer.
346  *
347  * Parameters:	cd			Pointer to code directory buffer
348  *		length			Length of buffer
349  *
350  * Returns:	0			Success
351  *		EBADEXEC		Invalid code signature
352  */
353 
354 static int
cs_validate_codedirectory(const CS_CodeDirectory *cd, size_t length)355 cs_validate_codedirectory(const CS_CodeDirectory *cd, size_t length)
356 {
357 	struct cs_hash const *hashtype;
358 
359 	if (length < sizeof(*cd))
360 		return EBADEXEC;
361 	if (ntohl(cd->magic) != CSMAGIC_CODEDIRECTORY)
362 		return EBADEXEC;
363 	if (cd->pageSize < PAGE_SHIFT_4K || cd->pageSize > PAGE_SHIFT)
364 		return EBADEXEC;
365 	hashtype = cs_find_md(cd->hashType);
366 	if (hashtype == NULL)
367 		return EBADEXEC;
368 
369 	if (cd->hashSize != hashtype->cs_size)
370 		return EBADEXEC;
371 
372 	if (length < ntohl(cd->hashOffset))
373 		return EBADEXEC;
374 
375 	/* check that nSpecialSlots fits in the buffer in front of hashOffset */
376 	if (ntohl(cd->hashOffset) / hashtype->cs_size < ntohl(cd->nSpecialSlots))
377 		return EBADEXEC;
378 
379 	/* check that codeslots fits in the buffer */
380 	if ((length - ntohl(cd->hashOffset)) / hashtype->cs_size <  ntohl(cd->nCodeSlots))
381 		return EBADEXEC;
382 
383 	if (ntohl(cd->version) >= CS_SUPPORTSSCATTER && cd->scatterOffset) {
384 
385 		if (length < ntohl(cd->scatterOffset))
386 			return EBADEXEC;
387 
388 		const SC_Scatter *scatter = (const SC_Scatter *)
389 			(((const uint8_t *)cd) + ntohl(cd->scatterOffset));
390 		uint32_t nPages = 0;
391 
392 		/*
393 		 * Check each scatter buffer, since we don't know the
394 		 * length of the scatter buffer array, we have to
395 		 * check each entry.
396 		 */
397 		while(1) {
398 			/* check that the end of each scatter buffer in within the length */
399 			if (((const uint8_t *)scatter) + sizeof(scatter[0]) > (const uint8_t *)cd + length)
400 				return EBADEXEC;
401 			uint32_t scount = ntohl(scatter->count);
402 			if (scount == 0)
403 				break;
404 			if (nPages + scount < nPages)
405 				return EBADEXEC;
406 			nPages += scount;
407 			scatter++;
408 
409 			/* XXX check that basees doesn't overlap */
410 			/* XXX check that targetOffset doesn't overlap */
411 		}
412 #if 0 /* rdar://12579439 */
413 		if (nPages != ntohl(cd->nCodeSlots))
414 			return EBADEXEC;
415 #endif
416 	}
417 
418 	if (length < ntohl(cd->identOffset))
419 		return EBADEXEC;
420 
421 	/* identifier is NUL terminated string */
422 	if (cd->identOffset) {
423 		const uint8_t *ptr = (const uint8_t *)cd + ntohl(cd->identOffset);
424 		if (memchr(ptr, 0, length - ntohl(cd->identOffset)) == NULL)
425 			return EBADEXEC;
426 	}
427 
428 	/* team identifier is NULL terminated string */
429 	if (ntohl(cd->version) >= CS_SUPPORTSTEAMID && ntohl(cd->teamOffset)) {
430 		if (length < ntohl(cd->teamOffset))
431 			return EBADEXEC;
432 
433 		const uint8_t *ptr = (const uint8_t *)cd + ntohl(cd->teamOffset);
434 		if (memchr(ptr, 0, length - ntohl(cd->teamOffset)) == NULL)
435 			return EBADEXEC;
436 	}
437 
438 	return 0;
439 }
440 
441 /*
442  *
443  */
444 
445 static int
cs_validate_blob(const CS_GenericBlob *blob, size_t length)446 cs_validate_blob(const CS_GenericBlob *blob, size_t length)
447 {
448 	if (length < sizeof(CS_GenericBlob) || length < ntohl(blob->length))
449 		return EBADEXEC;
450 	return 0;
451 }
452 
453 /*
454  * cs_validate_csblob
455  *
456  * Validate that superblob/embedded code directory to make sure that
457  * all internal pointers are valid.
458  *
459  * Will validate both a superblob csblob and a "raw" code directory.
460  *
461  *
462  * Parameters:	buffer			Pointer to code signature
463  *		length			Length of buffer
464  *		rcd			returns pointer to code directory
465  *
466  * Returns:	0			Success
467  *		EBADEXEC		Invalid code signature
468  */
469 
470 static int
cs_validate_csblob( const uint8_t *addr, size_t *blob_size_p, const CS_CodeDirectory **rcd, const CS_GenericBlob **rentitlements)471 cs_validate_csblob(
472 	const uint8_t *addr,
473 	size_t *blob_size_p,
474 	const CS_CodeDirectory **rcd,
475 	const CS_GenericBlob **rentitlements)
476 {
477 	const CS_GenericBlob *blob;
478 	int error;
479 	size_t length, blob_size;
480 
481 	*rcd = NULL;
482 	*rentitlements = NULL;
483 
484 	blob = (const CS_GenericBlob *)(const void *)addr;
485 	blob_size = *blob_size_p;
486 
487 	length = blob_size;
488 	error = cs_validate_blob(blob, length);
489 	if (error)
490 		return error;
491 	length = ntohl(blob->length);
492 
493 	if (ntohl(blob->magic) == CSMAGIC_EMBEDDED_SIGNATURE) {
494 		const CS_SuperBlob *sb;
495 		uint32_t n, count;
496 		const CS_CodeDirectory *best_cd = NULL;
497 		unsigned int best_rank = 0;
498 
499 		if (length < sizeof(CS_SuperBlob))
500 			return EBADEXEC;
501 
502 		sb = (const CS_SuperBlob *)blob;
503 		count = ntohl(sb->count);
504 
505 		/* check that the array of BlobIndex fits in the rest of the data */
506 		if ((length - sizeof(CS_SuperBlob)) / sizeof(CS_BlobIndex) < count)
507 			return EBADEXEC;
508 
509 		/* now check each BlobIndex */
510 		for (n = 0; n < count; n++) {
511 			const CS_BlobIndex *blobIndex = &sb->index[n];
512 			uint32_t type = ntohl(blobIndex->type);
513 			uint32_t offset = ntohl(blobIndex->offset);
514 			if (length < offset)
515 				return EBADEXEC;
516 
517 			const CS_GenericBlob *subBlob =
518 				(const CS_GenericBlob *)(const void *)(addr + offset);
519 
520 			size_t subLength = length - offset;
521 
522 			if ((error = cs_validate_blob(subBlob, subLength)) != 0)
523 				return error;
524 			subLength = ntohl(subBlob->length);
525 
526 			/* extra validation for CDs, that is also returned */
527 			if (type == CSSLOT_CODEDIRECTORY || (type >= CSSLOT_ALTERNATE_CODEDIRECTORIES && type < CSSLOT_ALTERNATE_CODEDIRECTORY_LIMIT)) {
528 				const CS_CodeDirectory *candidate = (const CS_CodeDirectory *)subBlob;
529 				if ((error = cs_validate_codedirectory(candidate, subLength)) != 0)
530 					return error;
531 				unsigned int rank = hash_rank(candidate);
532 				if (cs_debug > 3)
533 					printf("CodeDirectory type %d rank %d at slot 0x%x index %d\n", candidate->hashType, (int)rank, (int)type, (int)n);
534 				if (best_cd == NULL || rank > best_rank) {
535 					best_cd = candidate;
536 					best_rank = rank;
537 
538 					if (cs_debug > 2)
539 						printf("using CodeDirectory type %d (rank %d)\n", (int)best_cd->hashType, best_rank);
540 					*rcd = best_cd;
541 				} else if (best_cd != NULL && rank == best_rank) {
542 					/* repeat of a hash type (1:1 mapped to ranks), illegal and suspicious */
543 					printf("multiple hash=%d CodeDirectories in signature; rejecting\n", best_cd->hashType);
544 					return EBADEXEC;
545 				}
546 			} else if (type == CSSLOT_ENTITLEMENTS) {
547 				if (ntohl(subBlob->magic) != CSMAGIC_EMBEDDED_ENTITLEMENTS) {
548 					return EBADEXEC;
549 				}
550 				if (*rentitlements != NULL) {
551 					printf("multiple entitlements blobs\n");
552 					return EBADEXEC;
553 				}
554 				*rentitlements = subBlob;
555 			}
556 		}
557 
558 	} else if (ntohl(blob->magic) == CSMAGIC_CODEDIRECTORY) {
559 
560 		if ((error = cs_validate_codedirectory((const CS_CodeDirectory *)(const void *)addr, length)) != 0)
561 			return error;
562 		*rcd = (const CS_CodeDirectory *)blob;
563 	} else {
564 		return EBADEXEC;
565 	}
566 
567 	if (*rcd == NULL)
568 		return EBADEXEC;
569 
570 	*blob_size_p = blob_size;
571 
572 	return 0;
573 }
574 
575 /*
576  * cs_find_blob_bytes
577  *
578  * Find an blob from the superblob/code directory. The blob must have
579  * been been validated by cs_validate_csblob() before calling
580  * this. Use csblob_find_blob() instead.
581  *
582  * Will also find a "raw" code directory if its stored as well as
583  * searching the superblob.
584  *
585  * Parameters:	buffer			Pointer to code signature
586  *		length			Length of buffer
587  *		type			type of blob to find
588  *		magic			the magic number for that blob
589  *
590  * Returns:	pointer			Success
591  *		NULL			Buffer not found
592  */
593 
594 const CS_GenericBlob *
csblob_find_blob_bytes(const uint8_t *addr, size_t length, uint32_t type, uint32_t magic)595 csblob_find_blob_bytes(const uint8_t *addr, size_t length, uint32_t type, uint32_t magic)
596 {
597 	const CS_GenericBlob *blob = (const CS_GenericBlob *)(const void *)addr;
598 
599 	if (ntohl(blob->magic) == CSMAGIC_EMBEDDED_SIGNATURE) {
600 		const CS_SuperBlob *sb = (const CS_SuperBlob *)blob;
601 		size_t n, count = ntohl(sb->count);
602 
603 		for (n = 0; n < count; n++) {
604 			if (ntohl(sb->index[n].type) != type)
605 				continue;
606 			uint32_t offset = ntohl(sb->index[n].offset);
607 			if (length - sizeof(const CS_GenericBlob) < offset)
608 				return NULL;
609 			blob = (const CS_GenericBlob *)(const void *)(addr + offset);
610 			if (ntohl(blob->magic) != magic)
611 				continue;
612 			return blob;
613 		}
614 	} else if (type == CSSLOT_CODEDIRECTORY
615 		   && ntohl(blob->magic) == CSMAGIC_CODEDIRECTORY
616 		   && magic == CSMAGIC_CODEDIRECTORY)
617 		return blob;
618 	return NULL;
619 }
620 
621 
622 const CS_GenericBlob *
csblob_find_blob(struct cs_blob *csblob, uint32_t type, uint32_t magic)623 csblob_find_blob(struct cs_blob *csblob, uint32_t type, uint32_t magic)
624 {
625 	if ((csblob->csb_flags & CS_VALID) == 0)
626 		return NULL;
627 	return csblob_find_blob_bytes((const uint8_t *)csblob->csb_mem_kaddr, csblob->csb_mem_size, type, magic);
628 }
629 
630 static const uint8_t *
find_special_slot(const CS_CodeDirectory *cd, size_t slotsize, uint32_t slot)631 find_special_slot(const CS_CodeDirectory *cd, size_t slotsize, uint32_t slot)
632 {
633 	/* there is no zero special slot since that is the first code slot */
634 	if (ntohl(cd->nSpecialSlots) < slot || slot == 0)
635 		return NULL;
636 
637 	return ((const uint8_t *)cd + ntohl(cd->hashOffset) - (slotsize * slot));
638 }
639 
640 static uint8_t cshash_zero[CS_HASH_MAX_SIZE] = { 0 };
641 
642 int
csblob_get_entitlements(struct cs_blob *csblob, void **out_start, size_t *out_length)643 csblob_get_entitlements(struct cs_blob *csblob, void **out_start, size_t *out_length)
644 {
645 	uint8_t computed_hash[CS_HASH_MAX_SIZE];
646 	const CS_GenericBlob *entitlements;
647 	const CS_CodeDirectory *code_dir;
648 	const uint8_t *embedded_hash;
649 	union cs_hash_union context;
650 
651 	*out_start = NULL;
652 	*out_length = 0;
653 
654 	if (csblob->csb_hashtype == NULL || csblob->csb_hashtype->cs_digest_size > sizeof(computed_hash))
655 	    return EBADEXEC;
656 
657 	code_dir = csblob->csb_cd;
658 
659 	if ((csblob->csb_flags & CS_VALID) == 0) {
660 		entitlements = NULL;
661 	} else {
662 		entitlements = csblob->csb_entitlements_blob;
663 	}
664 	embedded_hash = find_special_slot(code_dir, csblob->csb_hashtype->cs_size, CSSLOT_ENTITLEMENTS);
665 
666 	if (embedded_hash == NULL) {
667 		if (entitlements)
668 			return EBADEXEC;
669 		return 0;
670 	} else if (entitlements == NULL) {
671 		if (memcmp(embedded_hash, cshash_zero, csblob->csb_hashtype->cs_size) != 0) {
672 			return EBADEXEC;
673 		} else {
674 			return 0;
675 		}
676 	}
677 
678 	csblob->csb_hashtype->cs_init(&context);
679 	csblob->csb_hashtype->cs_update(&context, entitlements, ntohl(entitlements->length));
680 	csblob->csb_hashtype->cs_final(computed_hash, &context);
681 
682 	if (memcmp(computed_hash, embedded_hash, csblob->csb_hashtype->cs_size) != 0)
683 		return EBADEXEC;
684 
685 	*out_start = __DECONST(void *, entitlements);
686 	*out_length = ntohl(entitlements->length);
687 
688 	return 0;
689 }
690 
691 /*
692  * CODESIGNING
693  * End of routines to navigate code signing data structures in the kernel.
694  */
695 
696 
697 
698 /*
699  * ubc_init
700  *
701  * Initialization of the zone for Unified Buffer Cache.
702  *
703  * Parameters:	(void)
704  *
705  * Returns:	(void)
706  *
707  * Implicit returns:
708  *		ubc_info_zone(global)	initialized for subsequent allocations
709  */
710 __private_extern__ void
ubc_init(void)711 ubc_init(void)
712 {
713 	int	i;
714 
715 	i = (vm_size_t) sizeof (struct ubc_info);
716 
717 	ubc_info_zone = zinit (i, 10000*i, 8192, "ubc_info zone");
718 
719 	zone_change(ubc_info_zone, Z_NOENCRYPT, TRUE);
720 }
721 
722 
723 /*
724  * ubc_info_init
725  *
726  * Allocate and attach an empty ubc_info structure to a vnode
727  *
728  * Parameters:	vp			Pointer to the vnode
729  *
730  * Returns:	0			Success
731  *	vnode_size:ENOMEM		Not enough space
732  *	vnode_size:???			Other error from vnode_getattr
733  *
734  */
735 int
ubc_info_init(struct vnode *vp)736 ubc_info_init(struct vnode *vp)
737 {
738 	return(ubc_info_init_internal(vp, 0, 0));
739 }
740 
741 
742 /*
743  * ubc_info_init_withsize
744  *
745  * Allocate and attach a sized ubc_info structure to a vnode
746  *
747  * Parameters:	vp			Pointer to the vnode
748  *		filesize		The size of the file
749  *
750  * Returns:	0			Success
751  *	vnode_size:ENOMEM		Not enough space
752  *	vnode_size:???			Other error from vnode_getattr
753  */
754 int
ubc_info_init_withsize(struct vnode *vp, off_t filesize)755 ubc_info_init_withsize(struct vnode *vp, off_t filesize)
756 {
757 	return(ubc_info_init_internal(vp, 1, filesize));
758 }
759 
760 
761 /*
762  * ubc_info_init_internal
763  *
764  * Allocate and attach a ubc_info structure to a vnode
765  *
766  * Parameters:	vp			Pointer to the vnode
767  *		withfsize{0,1}		Zero if the size should be obtained
768  *					from the vnode; otherwise, use filesize
769  *		filesize		The size of the file, if withfsize == 1
770  *
771  * Returns:	0			Success
772  *	vnode_size:ENOMEM		Not enough space
773  *	vnode_size:???			Other error from vnode_getattr
774  *
775  * Notes:	We call a blocking zalloc(), and the zone was created as an
776  *		expandable and collectable zone, so if no memory is available,
777  *		it is possible for zalloc() to block indefinitely.  zalloc()
778  *		may also panic if the zone of zones is exhausted, since it's
779  *		NOT expandable.
780  *
781  *		We unconditionally call vnode_pager_setup(), even if this is
782  *		a reuse of a ubc_info; in that case, we should probably assert
783  *		that it does not already have a pager association, but do not.
784  *
785  *		Since memory_object_create_named() can only fail from receiving
786  *		an invalid pager argument, the explicit check and panic is
787  *		merely precautionary.
788  */
789 static int
ubc_info_init_internal(vnode_t vp, int withfsize, off_t filesize)790 ubc_info_init_internal(vnode_t vp, int withfsize, off_t filesize)
791 {
792 	struct ubc_info	*uip;
793 	void *  pager;
794 	int error = 0;
795 	kern_return_t kret;
796 	memory_object_control_t control;
797 
798 	uip = vp->v_ubcinfo;
799 
800 	/*
801 	 * If there is not already a ubc_info attached to the vnode, we
802 	 * attach one; otherwise, we will reuse the one that's there.
803 	 */
804 	if (uip == UBC_INFO_NULL) {
805 
806 		uip = (struct ubc_info *) zalloc(ubc_info_zone);
807 		bzero((char *)uip, sizeof(struct ubc_info));
808 
809 		uip->ui_vnode = vp;
810 		uip->ui_flags = UI_INITED;
811 		uip->ui_ucred = NOCRED;
812 	}
813 	assert(uip->ui_flags != UI_NONE);
814 	assert(uip->ui_vnode == vp);
815 
816 	/* now set this ubc_info in the vnode */
817 	vp->v_ubcinfo = uip;
818 
819 	/*
820 	 * Allocate a pager object for this vnode
821 	 *
822 	 * XXX The value of the pager parameter is currently ignored.
823 	 * XXX Presumably, this API changed to avoid the race between
824 	 * XXX setting the pager and the UI_HASPAGER flag.
825 	 */
826 	pager = (void *)vnode_pager_setup(vp, uip->ui_pager);
827 	assert(pager);
828 
829 	/*
830 	 * Explicitly set the pager into the ubc_info, after setting the
831 	 * UI_HASPAGER flag.
832 	 */
833 	SET(uip->ui_flags, UI_HASPAGER);
834 	uip->ui_pager = pager;
835 
836 	/*
837 	 * Note: We can not use VNOP_GETATTR() to get accurate
838 	 * value of ui_size because this may be an NFS vnode, and
839 	 * nfs_getattr() can call vinvalbuf(); if this happens,
840 	 * ubc_info is not set up to deal with that event.
841 	 * So use bogus size.
842 	 */
843 
844 	/*
845 	 * create a vnode - vm_object association
846 	 * memory_object_create_named() creates a "named" reference on the
847 	 * memory object we hold this reference as long as the vnode is
848 	 * "alive."  Since memory_object_create_named() took its own reference
849 	 * on the vnode pager we passed it, we can drop the reference
850 	 * vnode_pager_setup() returned here.
851 	 */
852 	kret = memory_object_create_named(pager,
853 		(memory_object_size_t)uip->ui_size, &control);
854 	vnode_pager_deallocate(pager);
855 	if (kret != KERN_SUCCESS)
856 		panic("ubc_info_init: memory_object_create_named returned %d", kret);
857 
858 	assert(control);
859 	uip->ui_control = control;	/* cache the value of the mo control */
860 	SET(uip->ui_flags, UI_HASOBJREF);	/* with a named reference */
861 
862 	if (withfsize == 0) {
863 		/* initialize the size */
864 		error = vnode_size(vp, &uip->ui_size, vfs_context_current());
865 		if (error)
866 			uip->ui_size = 0;
867 	} else {
868 		uip->ui_size = filesize;
869 	}
870 	vp->v_lflag |= VNAMED_UBC;	/* vnode has a named ubc reference */
871 
872 	return (error);
873 }
874 
875 
876 /*
877  * ubc_info_free
878  *
879  * Free a ubc_info structure
880  *
881  * Parameters:	uip			A pointer to the ubc_info to free
882  *
883  * Returns:	(void)
884  *
885  * Notes:	If there is a credential that has subsequently been associated
886  *		with the ubc_info via a call to ubc_setcred(), the reference
887  *		to the credential is dropped.
888  *
889  *		It's actually impossible for a ubc_info.ui_control to take the
890  *		value MEMORY_OBJECT_CONTROL_NULL.
891  */
892 static void
ubc_info_free(struct ubc_info *uip)893 ubc_info_free(struct ubc_info *uip)
894 {
895 	if (IS_VALID_CRED(uip->ui_ucred)) {
896 		kauth_cred_unref(&uip->ui_ucred);
897 	}
898 
899 	if (uip->ui_control != MEMORY_OBJECT_CONTROL_NULL)
900 		memory_object_control_deallocate(uip->ui_control);
901 
902 	cluster_release(uip);
903 	ubc_cs_free(uip);
904 
905 	zfree(ubc_info_zone, uip);
906 	return;
907 }
908 
909 
910 void
ubc_info_deallocate(struct ubc_info *uip)911 ubc_info_deallocate(struct ubc_info *uip)
912 {
913         ubc_info_free(uip);
914 }
915 
mach_to_bsd_errno(kern_return_t mach_err)916 errno_t mach_to_bsd_errno(kern_return_t mach_err)
917 {
918 	switch (mach_err) {
919 	case KERN_SUCCESS:
920 		return 0;
921 
922 	case KERN_INVALID_ADDRESS:
923 	case KERN_INVALID_ARGUMENT:
924 	case KERN_NOT_IN_SET:
925 	case KERN_INVALID_NAME:
926 	case KERN_INVALID_TASK:
927 	case KERN_INVALID_RIGHT:
928 	case KERN_INVALID_VALUE:
929 	case KERN_INVALID_CAPABILITY:
930 	case KERN_INVALID_HOST:
931 	case KERN_MEMORY_PRESENT:
932 	case KERN_INVALID_PROCESSOR_SET:
933 	case KERN_INVALID_POLICY:
934 	case KERN_ALREADY_WAITING:
935 	case KERN_DEFAULT_SET:
936 	case KERN_EXCEPTION_PROTECTED:
937 	case KERN_INVALID_LEDGER:
938 	case KERN_INVALID_MEMORY_CONTROL:
939 	case KERN_INVALID_SECURITY:
940 	case KERN_NOT_DEPRESSED:
941 	case KERN_LOCK_OWNED:
942 	case KERN_LOCK_OWNED_SELF:
943 		return EINVAL;
944 
945 	case KERN_PROTECTION_FAILURE:
946 	case KERN_NOT_RECEIVER:
947 	case KERN_NO_ACCESS:
948 	case KERN_POLICY_STATIC:
949 		return EACCES;
950 
951 	case KERN_NO_SPACE:
952 	case KERN_RESOURCE_SHORTAGE:
953 	case KERN_UREFS_OVERFLOW:
954 	case KERN_INVALID_OBJECT:
955 		return ENOMEM;
956 
957 	case KERN_FAILURE:
958 		return EIO;
959 
960 	case KERN_MEMORY_FAILURE:
961 	case KERN_POLICY_LIMIT:
962 	case KERN_CODESIGN_ERROR:
963 		return EPERM;
964 
965 	case KERN_MEMORY_ERROR:
966 		return EBUSY;
967 
968 	case KERN_ALREADY_IN_SET:
969 	case KERN_NAME_EXISTS:
970 	case KERN_RIGHT_EXISTS:
971 		return EEXIST;
972 
973 	case KERN_ABORTED:
974 		return EINTR;
975 
976 	case KERN_TERMINATED:
977 	case KERN_LOCK_SET_DESTROYED:
978 	case KERN_LOCK_UNSTABLE:
979 	case KERN_SEMAPHORE_DESTROYED:
980 		return ENOENT;
981 
982 	case KERN_RPC_SERVER_TERMINATED:
983 		return ECONNRESET;
984 
985 	case KERN_NOT_SUPPORTED:
986 		return ENOTSUP;
987 
988 	case KERN_NODE_DOWN:
989 		return ENETDOWN;
990 
991 	case KERN_NOT_WAITING:
992 		return ENOENT;
993 
994 	case KERN_OPERATION_TIMED_OUT:
995 		return ETIMEDOUT;
996 
997 	default:
998 		return EIO;
999 	}
1000 }
1001 
1002 /*
1003  * ubc_setsize_ex
1004  *
1005  * Tell the VM that the the size of the file represented by the vnode has
1006  * changed
1007  *
1008  * Parameters:	vp	   The vp whose backing file size is
1009  *					   being changed
1010  *				nsize  The new size of the backing file
1011  *				opts   Options
1012  *
1013  * Returns:	EINVAL for new size < 0
1014  *			ENOENT if no UBC info exists
1015  *          EAGAIN if UBC_SETSIZE_NO_FS_REENTRY option is set and new_size < old size
1016  *          Other errors (mapped to errno_t) returned by VM functions
1017  *
1018  * Notes:   This function will indicate success if the new size is the
1019  *		    same or larger than the old size (in this case, the
1020  *		    remainder of the file will require modification or use of
1021  *		    an existing upl to access successfully).
1022  *
1023  *		    This function will fail if the new file size is smaller,
1024  *		    and the memory region being invalidated was unable to
1025  *		    actually be invalidated and/or the last page could not be
1026  *		    flushed, if the new size is not aligned to a page
1027  *		    boundary.  This is usually indicative of an I/O error.
1028  */
ubc_setsize_ex(struct vnode *vp, off_t nsize, ubc_setsize_opts_t opts)1029 errno_t ubc_setsize_ex(struct vnode *vp, off_t nsize, ubc_setsize_opts_t opts)
1030 {
1031 	off_t osize;	/* ui_size before change */
1032 	off_t lastpg, olastpgend, lastoff;
1033 	struct ubc_info *uip;
1034 	memory_object_control_t control;
1035 	kern_return_t kret = KERN_SUCCESS;
1036 
1037 	if (nsize < (off_t)0)
1038 		return EINVAL;
1039 
1040 	if (!UBCINFOEXISTS(vp))
1041 		return ENOENT;
1042 
1043 	uip = vp->v_ubcinfo;
1044 	osize = uip->ui_size;
1045 
1046 	if (ISSET(opts, UBC_SETSIZE_NO_FS_REENTRY) && nsize < osize)
1047 		return EAGAIN;
1048 
1049 	/*
1050 	 * Update the size before flushing the VM
1051 	 */
1052 	uip->ui_size = nsize;
1053 
1054 	if (nsize >= osize) {	/* Nothing more to do */
1055 		if (nsize > osize) {
1056 			lock_vnode_and_post(vp, NOTE_EXTEND);
1057 		}
1058 
1059 		return 0;
1060 	}
1061 
1062 	/*
1063 	 * When the file shrinks, invalidate the pages beyond the
1064 	 * new size. Also get rid of garbage beyond nsize on the
1065 	 * last page. The ui_size already has the nsize, so any
1066 	 * subsequent page-in will zero-fill the tail properly
1067 	 */
1068 	lastpg = trunc_page_64(nsize);
1069 	olastpgend = round_page_64(osize);
1070 	control = uip->ui_control;
1071 	assert(control);
1072 	lastoff = (nsize & PAGE_MASK_64);
1073 
1074 	if (lastoff) {
1075 		upl_t		upl;
1076 		upl_page_info_t	*pl;
1077 
1078 		/*
1079 		 * new EOF ends up in the middle of a page
1080 		 * zero the tail of this page if it's currently
1081 		 * present in the cache
1082 		 */
1083 		kret = ubc_create_upl(vp, lastpg, PAGE_SIZE, &upl, &pl, UPL_SET_LITE);
1084 
1085 		if (kret != KERN_SUCCESS)
1086 		        panic("ubc_setsize: ubc_create_upl (error = %d)\n", kret);
1087 
1088 		if (upl_valid_page(pl, 0))
1089 		        cluster_zero(upl, (uint32_t)lastoff, PAGE_SIZE - (uint32_t)lastoff, NULL);
1090 
1091 		ubc_upl_abort_range(upl, 0, PAGE_SIZE, UPL_ABORT_FREE_ON_EMPTY);
1092 
1093 		lastpg += PAGE_SIZE_64;
1094 	}
1095 	if (olastpgend > lastpg) {
1096 		int	flags;
1097 
1098 		if (lastpg == 0)
1099 			flags = MEMORY_OBJECT_DATA_FLUSH_ALL;
1100 		else
1101 			flags = MEMORY_OBJECT_DATA_FLUSH;
1102 		/*
1103 		 * invalidate the pages beyond the new EOF page
1104 		 *
1105 		 */
1106 		kret = memory_object_lock_request(control,
1107 										  (memory_object_offset_t)lastpg,
1108 										  (memory_object_size_t)(olastpgend - lastpg), NULL, NULL,
1109 										  MEMORY_OBJECT_RETURN_NONE, flags, VM_PROT_NO_CHANGE);
1110 		if (kret != KERN_SUCCESS)
1111 		        printf("ubc_setsize: invalidate failed (error = %d)\n", kret);
1112 	}
1113 	return mach_to_bsd_errno(kret);
1114 }
1115 
1116 // Returns true for success
ubc_setsize(vnode_t vp, off_t nsize)1117 int ubc_setsize(vnode_t vp, off_t nsize)
1118 {
1119 	return ubc_setsize_ex(vp, nsize, 0) == 0;
1120 }
1121 
1122 /*
1123  * ubc_getsize
1124  *
1125  * Get the size of the file assocated with the specified vnode
1126  *
1127  * Parameters:	vp			The vnode whose size is of interest
1128  *
1129  * Returns:	0			There is no ubc_info associated with
1130  *					this vnode, or the size is zero
1131  *		!0			The size of the file
1132  *
1133  * Notes:	Using this routine, it is not possible for a caller to
1134  *		successfully distinguish between a vnode associate with a zero
1135  *		length file, and a vnode with no associated ubc_info.  The
1136  *		caller therefore needs to not care, or needs to ensure that
1137  *		they have previously successfully called ubc_info_init() or
1138  *		ubc_info_init_withsize().
1139  */
1140 off_t
ubc_getsize(struct vnode *vp)1141 ubc_getsize(struct vnode *vp)
1142 {
1143 	/* people depend on the side effect of this working this way
1144 	 * as they call this for directory
1145 	 */
1146 	if (!UBCINFOEXISTS(vp))
1147 		return ((off_t)0);
1148 	return (vp->v_ubcinfo->ui_size);
1149 }
1150 
1151 
1152 /*
1153  * ubc_umount
1154  *
1155  * Call ubc_msync(vp, 0, EOF, NULL, UBC_PUSHALL) on all the vnodes for this
1156  * mount point
1157  *
1158  * Parameters:	mp			The mount point
1159  *
1160  * Returns:	0			Success
1161  *
1162  * Notes:	There is no failure indication for this function.
1163  *
1164  *		This function is used in the unmount path; since it may block
1165  *		I/O indefinitely, it should not be used in the forced unmount
1166  *		path, since a device unavailability could also block that
1167  *		indefinitely.
1168  *
1169  *		Because there is no device ejection interlock on USB, FireWire,
1170  *		or similar devices, it's possible that an ejection that begins
1171  *		subsequent to the vnode_iterate() completing, either on one of
1172  *		those devices, or a network mount for which the server quits
1173  *		responding, etc., may cause the caller to block indefinitely.
1174  */
1175 __private_extern__ int
ubc_umount(struct mount *mp)1176 ubc_umount(struct mount *mp)
1177 {
1178 	vnode_iterate(mp, 0, ubc_umcallback, 0);
1179 	return(0);
1180 }
1181 
1182 
1183 /*
1184  * ubc_umcallback
1185  *
1186  * Used by ubc_umount() as an internal implementation detail; see ubc_umount()
1187  * and vnode_iterate() for details of implementation.
1188  */
1189 static int
ubc_umcallback(vnode_t vp, __unused void * args)1190 ubc_umcallback(vnode_t vp, __unused void * args)
1191 {
1192 
1193 	if (UBCINFOEXISTS(vp)) {
1194 
1195 		(void) ubc_msync(vp, (off_t)0, ubc_getsize(vp), NULL, UBC_PUSHALL);
1196 	}
1197 	return (VNODE_RETURNED);
1198 }
1199 
1200 
1201 /*
1202  * ubc_getcred
1203  *
1204  * Get the credentials currently active for the ubc_info associated with the
1205  * vnode.
1206  *
1207  * Parameters:	vp			The vnode whose ubc_info credentials
1208  *					are to be retrieved
1209  *
1210  * Returns:	!NOCRED			The credentials
1211  *		NOCRED			If there is no ubc_info for the vnode,
1212  *					or if there is one, but it has not had
1213  *					any credentials associated with it via
1214  *					a call to ubc_setcred()
1215  */
1216 kauth_cred_t
ubc_getcred(struct vnode *vp)1217 ubc_getcred(struct vnode *vp)
1218 {
1219         if (UBCINFOEXISTS(vp))
1220 	        return (vp->v_ubcinfo->ui_ucred);
1221 
1222 	return (NOCRED);
1223 }
1224 
1225 
1226 /*
1227  * ubc_setthreadcred
1228  *
1229  * If they are not already set, set the credentials of the ubc_info structure
1230  * associated with the vnode to those of the supplied thread; otherwise leave
1231  * them alone.
1232  *
1233  * Parameters:	vp			The vnode whose ubc_info creds are to
1234  *					be set
1235  *		p			The process whose credentials are to
1236  *					be used, if not running on an assumed
1237  *					credential
1238  *		thread			The thread whose credentials are to
1239  *					be used
1240  *
1241  * Returns:	1			This vnode has no associated ubc_info
1242  *		0			Success
1243  *
1244  * Notes:	This function takes a proc parameter to account for bootstrap
1245  *		issues where a task or thread may call this routine, either
1246  *		before credentials have been initialized by bsd_init(), or if
1247  *		there is no BSD info asscoiate with a mach thread yet.  This
1248  *		is known to happen in both the initial swap and memory mapping
1249  *		calls.
1250  *
1251  *		This function is generally used only in the following cases:
1252  *
1253  *		o	a memory mapped file via the mmap() system call
1254  *		o	a swap store backing file
1255  *		o	subsequent to a successful write via vn_write()
1256  *
1257  *		The information is then used by the NFS client in order to
1258  *		cons up a wire message in either the page-in or page-out path.
1259  *
1260  *		There are two potential problems with the use of this API:
1261  *
1262  *		o	Because the write path only set it on a successful
1263  *			write, there is a race window between setting the
1264  *			credential and its use to evict the pages to the
1265  *			remote file server
1266  *
1267  *		o	Because a page-in may occur prior to a write, the
1268  *			credential may not be set at this time, if the page-in
1269  *			is not the result of a mapping established via mmap().
1270  *
1271  *		In both these cases, this will be triggered from the paging
1272  *		path, which will instead use the credential of the current
1273  *		process, which in this case is either the dynamic_pager or
1274  *		the kernel task, both of which utilize "root" credentials.
1275  *
1276  *		This may potentially permit operations to occur which should
1277  *		be denied, or it may cause to be denied operations which
1278  *		should be permitted, depending on the configuration of the NFS
1279  *		server.
1280  */
1281 int
ubc_setthreadcred(struct vnode *vp, proc_t p, thread_t thread)1282 ubc_setthreadcred(struct vnode *vp, proc_t p, thread_t thread)
1283 {
1284 	struct ubc_info *uip;
1285 	kauth_cred_t credp;
1286 	struct uthread  *uthread = get_bsdthread_info(thread);
1287 
1288 	if (!UBCINFOEXISTS(vp))
1289 		return (1);
1290 
1291 	vnode_lock(vp);
1292 
1293 	uip = vp->v_ubcinfo;
1294 	credp = uip->ui_ucred;
1295 
1296 	if (!IS_VALID_CRED(credp)) {
1297 		/* use per-thread cred, if assumed identity, else proc cred */
1298 		if (uthread == NULL || (uthread->uu_flag & UT_SETUID) == 0) {
1299 			uip->ui_ucred = kauth_cred_proc_ref(p);
1300 		} else {
1301 			uip->ui_ucred = uthread->uu_ucred;
1302 			kauth_cred_ref(uip->ui_ucred);
1303 		}
1304 	}
1305 	vnode_unlock(vp);
1306 
1307 	return (0);
1308 }
1309 
1310 
1311 /*
1312  * ubc_setcred
1313  *
1314  * If they are not already set, set the credentials of the ubc_info structure
1315  * associated with the vnode to those of the process; otherwise leave them
1316  * alone.
1317  *
1318  * Parameters:	vp			The vnode whose ubc_info creds are to
1319  *					be set
1320  *		p			The process whose credentials are to
1321  *					be used
1322  *
1323  * Returns:	0			This vnode has no associated ubc_info
1324  *		1			Success
1325  *
1326  * Notes:	The return values for this function are inverted from nearly
1327  *		all other uses in the kernel.
1328  *
1329  *		See also ubc_setthreadcred(), above.
1330  *
1331  *		This function is considered deprecated, and generally should
1332  *		not be used, as it is incompatible with per-thread credentials;
1333  *		it exists for legacy KPI reasons.
1334  *
1335  * DEPRECATION:	ubc_setcred() is being deprecated. Please use
1336  *		ubc_setthreadcred() instead.
1337  */
1338 int
ubc_setcred(struct vnode *vp, proc_t p)1339 ubc_setcred(struct vnode *vp, proc_t p)
1340 {
1341 	struct ubc_info *uip;
1342 	kauth_cred_t credp;
1343 
1344 	/* If there is no ubc_info, deny the operation */
1345 	if ( !UBCINFOEXISTS(vp))
1346 		return (0);
1347 
1348 	/*
1349 	 * Check to see if there is already a credential reference in the
1350 	 * ubc_info; if there is not, take one on the supplied credential.
1351 	 */
1352 	vnode_lock(vp);
1353 	uip = vp->v_ubcinfo;
1354 	credp = uip->ui_ucred;
1355 	if (!IS_VALID_CRED(credp)) {
1356 		uip->ui_ucred = kauth_cred_proc_ref(p);
1357 	}
1358 	vnode_unlock(vp);
1359 
1360 	return (1);
1361 }
1362 
1363 /*
1364  * ubc_getpager
1365  *
1366  * Get the pager associated with the ubc_info associated with the vnode.
1367  *
1368  * Parameters:	vp			The vnode to obtain the pager from
1369  *
1370  * Returns:	!VNODE_PAGER_NULL	The memory_object_t for the pager
1371  *		VNODE_PAGER_NULL	There is no ubc_info for this vnode
1372  *
1373  * Notes:	For each vnode that has a ubc_info associated with it, that
1374  *		ubc_info SHALL have a pager associated with it, so in the
1375  *		normal case, it's impossible to return VNODE_PAGER_NULL for
1376  *		a vnode with an associated ubc_info.
1377  */
1378 __private_extern__ memory_object_t
ubc_getpager(struct vnode *vp)1379 ubc_getpager(struct vnode *vp)
1380 {
1381         if (UBCINFOEXISTS(vp))
1382 	        return (vp->v_ubcinfo->ui_pager);
1383 
1384 	return (0);
1385 }
1386 
1387 
1388 /*
1389  * ubc_getobject
1390  *
1391  * Get the memory object control associated with the ubc_info associated with
1392  * the vnode
1393  *
1394  * Parameters:	vp			The vnode to obtain the memory object
1395  *					from
1396  *		flags			DEPRECATED
1397  *
1398  * Returns:	!MEMORY_OBJECT_CONTROL_NULL
1399  *		MEMORY_OBJECT_CONTROL_NULL
1400  *
1401  * Notes:	Historically, if the flags were not "do not reactivate", this
1402  *		function would look up the memory object using the pager if
1403  *		it did not exist (this could be the case if the vnode had
1404  *		been previously reactivated).  The flags would also permit a
1405  *		hold to be requested, which would have created an object
1406  *		reference, if one had not already existed.  This usage is
1407  *		deprecated, as it would permit a race between finding and
1408  *		taking the reference vs. a single reference being dropped in
1409  *		another thread.
1410  */
1411 memory_object_control_t
ubc_getobject(struct vnode *vp, __unused int flags)1412 ubc_getobject(struct vnode *vp, __unused int flags)
1413 {
1414         if (UBCINFOEXISTS(vp))
1415 	        return((vp->v_ubcinfo->ui_control));
1416 
1417 	return (MEMORY_OBJECT_CONTROL_NULL);
1418 }
1419 
1420 boolean_t
ubc_strict_uncached_IO(struct vnode *vp)1421 ubc_strict_uncached_IO(struct vnode *vp)
1422 {
1423         boolean_t result = FALSE;
1424 
1425 	if (UBCINFOEXISTS(vp)) {
1426 	        result = memory_object_is_slid(vp->v_ubcinfo->ui_control);
1427 	}
1428 	return result;
1429 }
1430 
1431 /*
1432  * ubc_blktooff
1433  *
1434  * Convert a given block number to a memory backing object (file) offset for a
1435  * given vnode
1436  *
1437  * Parameters:	vp			The vnode in which the block is located
1438  *		blkno			The block number to convert
1439  *
1440  * Returns:	!-1			The offset into the backing object
1441  *		-1			There is no ubc_info associated with
1442  *					the vnode
1443  *		-1			An error occurred in the underlying VFS
1444  *					while translating the block to an
1445  *					offset; the most likely cause is that
1446  *					the caller specified a block past the
1447  *					end of the file, but this could also be
1448  *					any other error from VNOP_BLKTOOFF().
1449  *
1450  * Note:	Representing the error in band loses some information, but does
1451  *		not occlude a valid offset, since an off_t of -1 is normally
1452  *		used to represent EOF.  If we had a more reliable constant in
1453  *		our header files for it (i.e. explicitly cast to an off_t), we
1454  *		would use it here instead.
1455  */
1456 off_t
ubc_blktooff(vnode_t vp, daddr64_t blkno)1457 ubc_blktooff(vnode_t vp, daddr64_t blkno)
1458 {
1459 	off_t file_offset = -1;
1460 	int error;
1461 
1462 	if (UBCINFOEXISTS(vp)) {
1463 		error = VNOP_BLKTOOFF(vp, blkno, &file_offset);
1464 		if (error)
1465 			file_offset = -1;
1466 	}
1467 
1468 	return (file_offset);
1469 }
1470 
1471 
1472 /*
1473  * ubc_offtoblk
1474  *
1475  * Convert a given offset in a memory backing object into a block number for a
1476  * given vnode
1477  *
1478  * Parameters:	vp			The vnode in which the offset is
1479  *					located
1480  *		offset			The offset into the backing object
1481  *
1482  * Returns:	!-1			The returned block number
1483  *		-1			There is no ubc_info associated with
1484  *					the vnode
1485  *		-1			An error occurred in the underlying VFS
1486  *					while translating the block to an
1487  *					offset; the most likely cause is that
1488  *					the caller specified a block past the
1489  *					end of the file, but this could also be
1490  *					any other error from VNOP_OFFTOBLK().
1491  *
1492  * Note:	Representing the error in band loses some information, but does
1493  *		not occlude a valid block number, since block numbers exceed
1494  *		the valid range for offsets, due to their relative sizes.  If
1495  *		we had a more reliable constant than -1 in our header files
1496  *		for it (i.e. explicitly cast to an daddr64_t), we would use it
1497  *		here instead.
1498  */
1499 daddr64_t
ubc_offtoblk(vnode_t vp, off_t offset)1500 ubc_offtoblk(vnode_t vp, off_t offset)
1501 {
1502 	daddr64_t blkno = -1;
1503 	int error = 0;
1504 
1505 	if (UBCINFOEXISTS(vp)) {
1506 		error = VNOP_OFFTOBLK(vp, offset, &blkno);
1507 		if (error)
1508 			blkno = -1;
1509 	}
1510 
1511 	return (blkno);
1512 }
1513 
1514 
1515 /*
1516  * ubc_pages_resident
1517  *
1518  * Determine whether or not a given vnode has pages resident via the memory
1519  * object control associated with the ubc_info associated with the vnode
1520  *
1521  * Parameters:	vp			The vnode we want to know about
1522  *
1523  * Returns:	1			Yes
1524  *		0			No
1525  */
1526 int
ubc_pages_resident(vnode_t vp)1527 ubc_pages_resident(vnode_t vp)
1528 {
1529 	kern_return_t		kret;
1530 	boolean_t			has_pages_resident;
1531 
1532 	if (!UBCINFOEXISTS(vp))
1533 		return (0);
1534 
1535 	/*
1536 	 * The following call may fail if an invalid ui_control is specified,
1537 	 * or if there is no VM object associated with the control object.  In
1538 	 * either case, reacting to it as if there were no pages resident will
1539 	 * result in correct behavior.
1540 	 */
1541 	kret = memory_object_pages_resident(vp->v_ubcinfo->ui_control, &has_pages_resident);
1542 
1543 	if (kret != KERN_SUCCESS)
1544 		return (0);
1545 
1546 	if (has_pages_resident == TRUE)
1547 		return (1);
1548 
1549 	return (0);
1550 }
1551 
1552 /*
1553  * ubc_msync
1554  *
1555  * Clean and/or invalidate a range in the memory object that backs this vnode
1556  *
1557  * Parameters:	vp			The vnode whose associated ubc_info's
1558  *					associated memory object is to have a
1559  *					range invalidated within it
1560  *		beg_off			The start of the range, as an offset
1561  *		end_off			The end of the range, as an offset
1562  *		resid_off		The address of an off_t supplied by the
1563  *					caller; may be set to NULL to ignore
1564  *		flags			See ubc_msync_internal()
1565  *
1566  * Returns:	0			Success
1567  *		!0			Failure; an errno is returned
1568  *
1569  * Implicit Returns:
1570  *		*resid_off, modified	If non-NULL, the  contents are ALWAYS
1571  *					modified; they are initialized to the
1572  *					beg_off, and in case of an I/O error,
1573  *					the difference between beg_off and the
1574  *					current value will reflect what was
1575  *					able to be written before the error
1576  *					occurred.  If no error is returned, the
1577  *					value of the resid_off is undefined; do
1578  *					NOT use it in place of end_off if you
1579  *					intend to increment from the end of the
1580  *					last call and call iteratively.
1581  *
1582  * Notes:	see ubc_msync_internal() for more detailed information.
1583  *
1584  */
1585 errno_t
ubc_msync(vnode_t vp, off_t beg_off, off_t end_off, off_t *resid_off, int flags)1586 ubc_msync(vnode_t vp, off_t beg_off, off_t end_off, off_t *resid_off, int flags)
1587 {
1588         int retval;
1589 	int io_errno = 0;
1590 
1591 	if (resid_off)
1592 	        *resid_off = beg_off;
1593 
1594         retval = ubc_msync_internal(vp, beg_off, end_off, resid_off, flags, &io_errno);
1595 
1596 	if (retval == 0 && io_errno == 0)
1597 	        return (EINVAL);
1598 	return (io_errno);
1599 }
1600 
1601 
1602 /*
1603  * ubc_msync_internal
1604  *
1605  * Clean and/or invalidate a range in the memory object that backs this vnode
1606  *
1607  * Parameters:	vp			The vnode whose associated ubc_info's
1608  *					associated memory object is to have a
1609  *					range invalidated within it
1610  *		beg_off			The start of the range, as an offset
1611  *		end_off			The end of the range, as an offset
1612  *		resid_off		The address of an off_t supplied by the
1613  *					caller; may be set to NULL to ignore
1614  *		flags			MUST contain at least one of the flags
1615  *					UBC_INVALIDATE, UBC_PUSHDIRTY, or
1616  *					UBC_PUSHALL; if UBC_PUSHDIRTY is used,
1617  *					UBC_SYNC may also be specified to cause
1618  *					this function to block until the
1619  *					operation is complete.  The behavior
1620  *					of UBC_SYNC is otherwise undefined.
1621  *		io_errno		The address of an int to contain the
1622  *					errno from a failed I/O operation, if
1623  *					one occurs; may be set to NULL to
1624  *					ignore
1625  *
1626  * Returns:	1			Success
1627  *		0			Failure
1628  *
1629  * Implicit Returns:
1630  *		*resid_off, modified	The contents of this offset MAY be
1631  *					modified; in case of an I/O error, the
1632  *					difference between beg_off and the
1633  *					current value will reflect what was
1634  *					able to be written before the error
1635  *					occurred.
1636  *		*io_errno, modified	The contents of this offset are set to
1637  *					an errno, if an error occurs; if the
1638  *					caller supplies an io_errno parameter,
1639  *					they should be careful to initialize it
1640  *					to 0 before calling this function to
1641  *					enable them to distinguish an error
1642  *					with a valid *resid_off from an invalid
1643  *					one, and to avoid potentially falsely
1644  *					reporting an error, depending on use.
1645  *
1646  * Notes:	If there is no ubc_info associated with the vnode supplied,
1647  *		this function immediately returns success.
1648  *
1649  *		If the value of end_off is less than or equal to beg_off, this
1650  *		function immediately returns success; that is, end_off is NOT
1651  *		inclusive.
1652  *
1653  *		IMPORTANT: one of the flags UBC_INVALIDATE, UBC_PUSHDIRTY, or
1654  *		UBC_PUSHALL MUST be specified; that is, it is NOT possible to
1655  *		attempt to block on in-progress I/O by calling this function
1656  *		with UBC_PUSHDIRTY, and then later call it with just UBC_SYNC
1657  *		in order to block pending on the I/O already in progress.
1658  *
1659  *		The start offset is truncated to the page boundary and the
1660  *		size is adjusted to include the last page in the range; that
1661  *		is, end_off on exactly a page boundary will not change if it
1662  *		is rounded, and the range of bytes written will be from the
1663  *		truncate beg_off to the rounded (end_off - 1).
1664  */
1665 static int
ubc_msync_internal(vnode_t vp, off_t beg_off, off_t end_off, off_t *resid_off, int flags, int *io_errno)1666 ubc_msync_internal(vnode_t vp, off_t beg_off, off_t end_off, off_t *resid_off, int flags, int *io_errno)
1667 {
1668 	memory_object_size_t	tsize;
1669 	kern_return_t		kret;
1670 	int request_flags = 0;
1671 	int flush_flags   = MEMORY_OBJECT_RETURN_NONE;
1672 
1673 	if ( !UBCINFOEXISTS(vp))
1674 	        return (0);
1675 	if ((flags & (UBC_INVALIDATE | UBC_PUSHDIRTY | UBC_PUSHALL)) == 0)
1676 	        return (0);
1677 	if (end_off <= beg_off)
1678 	        return (1);
1679 
1680 	if (flags & UBC_INVALIDATE)
1681 	        /*
1682 		 * discard the resident pages
1683 		 */
1684 		request_flags = (MEMORY_OBJECT_DATA_FLUSH | MEMORY_OBJECT_DATA_NO_CHANGE);
1685 
1686 	if (flags & UBC_SYNC)
1687 	        /*
1688 		 * wait for all the I/O to complete before returning
1689 		 */
1690 	        request_flags |= MEMORY_OBJECT_IO_SYNC;
1691 
1692 	if (flags & UBC_PUSHDIRTY)
1693 	        /*
1694 		 * we only return the dirty pages in the range
1695 		 */
1696 	        flush_flags = MEMORY_OBJECT_RETURN_DIRTY;
1697 
1698 	if (flags & UBC_PUSHALL)
1699 	        /*
1700 		 * then return all the interesting pages in the range (both
1701 		 * dirty and precious) to the pager
1702 		 */
1703 	        flush_flags = MEMORY_OBJECT_RETURN_ALL;
1704 
1705 	beg_off = trunc_page_64(beg_off);
1706 	end_off = round_page_64(end_off);
1707 	tsize   = (memory_object_size_t)end_off - beg_off;
1708 
1709 	/* flush and/or invalidate pages in the range requested */
1710 	kret = memory_object_lock_request(vp->v_ubcinfo->ui_control,
1711 					  beg_off, tsize,
1712 					  (memory_object_offset_t *)resid_off,
1713 					  io_errno, flush_flags, request_flags,
1714 					  VM_PROT_NO_CHANGE);
1715 
1716 	return ((kret == KERN_SUCCESS) ? 1 : 0);
1717 }
1718 
1719 
1720 /*
1721  * ubc_map
1722  *
1723  * Explicitly map a vnode that has an associate ubc_info, and add a reference
1724  * to it for the ubc system, if there isn't one already, so it will not be
1725  * recycled while it's in use, and set flags on the ubc_info to indicate that
1726  * we have done this
1727  *
1728  * Parameters:	vp			The vnode to map
1729  *		flags			The mapping flags for the vnode; this
1730  *					will be a combination of one or more of
1731  *					PROT_READ, PROT_WRITE, and PROT_EXEC
1732  *
1733  * Returns:	0			Success
1734  *		EPERM			Permission was denied
1735  *
1736  * Notes:	An I/O reference on the vnode must already be held on entry
1737  *
1738  *		If there is no ubc_info associated with the vnode, this function
1739  *		will return success.
1740  *
1741  *		If a permission error occurs, this function will return
1742  *		failure; all other failures will cause this function to return
1743  *		success.
1744  *
1745  *		IMPORTANT: This is an internal use function, and its symbols
1746  *		are not exported, hence its error checking is not very robust.
1747  *		It is primarily used by:
1748  *
1749  *		o	mmap(), when mapping a file
1750  *		o	When mapping a shared file (a shared library in the
1751  *			shared segment region)
1752  *		o	When loading a program image during the exec process
1753  *
1754  *		...all of these uses ignore the return code, and any fault that
1755  *		results later because of a failure is handled in the fix-up path
1756  *		of the fault handler.  The interface exists primarily as a
1757  *		performance hint.
1758  *
1759  *		Given that third party implementation of the type of interfaces
1760  *		that would use this function, such as alternative executable
1761  *		formats, etc., are unsupported, this function is not exported
1762  *		for general use.
1763  *
1764  *		The extra reference is held until the VM system unmaps the
1765  *		vnode from its own context to maintain a vnode reference in
1766  *		cases like open()/mmap()/close(), which leave the backing
1767  *		object referenced by a mapped memory region in a process
1768  *		address space.
1769  */
1770 __private_extern__ int
ubc_map(vnode_t vp, int flags)1771 ubc_map(vnode_t vp, int flags)
1772 {
1773 	struct ubc_info *uip;
1774 	int error = 0;
1775 	int need_ref = 0;
1776 	int need_wakeup = 0;
1777 
1778 	if (UBCINFOEXISTS(vp)) {
1779 
1780 		vnode_lock(vp);
1781 		uip = vp->v_ubcinfo;
1782 
1783 		while (ISSET(uip->ui_flags, UI_MAPBUSY)) {
1784 			SET(uip->ui_flags, UI_MAPWAITING);
1785 			(void) msleep(&uip->ui_flags, &vp->v_lock,
1786 				      PRIBIO, "ubc_map", NULL);
1787 		}
1788 		SET(uip->ui_flags, UI_MAPBUSY);
1789 		vnode_unlock(vp);
1790 
1791 		error = VNOP_MMAP(vp, flags, vfs_context_current());
1792 
1793 		/*
1794 		 * rdar://problem/22587101 required that we stop propagating
1795 		 * EPERM up the stack. Otherwise, we would have to funnel up
1796 		 * the error at all the call sites for memory_object_map().
1797 		 * The risk is in having to undo the map/object/entry state at
1798 		 * all these call sites. It would also affect more than just mmap()
1799 		 * e.g. vm_remap().
1800 		 *
1801 		 *	if (error != EPERM)
1802 		 *       	error = 0;
1803 		 */
1804 
1805 		error = 0;
1806 
1807 		vnode_lock_spin(vp);
1808 
1809 		if (error == 0) {
1810 			if ( !ISSET(uip->ui_flags, UI_ISMAPPED))
1811 			        need_ref = 1;
1812 			SET(uip->ui_flags, (UI_WASMAPPED | UI_ISMAPPED));
1813 			if (flags & PROT_WRITE) {
1814 				SET(uip->ui_flags, UI_MAPPEDWRITE);
1815 			}
1816 		}
1817 		CLR(uip->ui_flags, UI_MAPBUSY);
1818 
1819 		if (ISSET(uip->ui_flags, UI_MAPWAITING)) {
1820 			CLR(uip->ui_flags, UI_MAPWAITING);
1821 			need_wakeup = 1;
1822 		}
1823 		vnode_unlock(vp);
1824 
1825 		if (need_wakeup)
1826 			wakeup(&uip->ui_flags);
1827 
1828 		if (need_ref) {
1829 			/*
1830 			 * Make sure we get a ref as we can't unwind from here
1831 			 */
1832 			if (vnode_ref_ext(vp, 0, VNODE_REF_FORCE))
1833 				panic("%s : VNODE_REF_FORCE failed\n", __FUNCTION__);
1834 		}
1835 	}
1836 	return (error);
1837 }
1838 
1839 
1840 /*
1841  * ubc_destroy_named
1842  *
1843  * Destroy the named memory object associated with the ubc_info control object
1844  * associated with the designated vnode, if there is a ubc_info associated
1845  * with the vnode, and a control object is associated with it
1846  *
1847  * Parameters:	vp			The designated vnode
1848  *
1849  * Returns:	(void)
1850  *
1851  * Notes:	This function is called on vnode termination for all vnodes,
1852  *		and must therefore not assume that there is a ubc_info that is
1853  *		associated with the vnode, nor that there is a control object
1854  *		associated with the ubc_info.
1855  *
1856  *		If all the conditions necessary are present, this function
1857  *		calls memory_object_destory(), which will in turn end up
1858  *		calling ubc_unmap() to release any vnode references that were
1859  *		established via ubc_map().
1860  *
1861  *		IMPORTANT: This is an internal use function that is used
1862  *		exclusively by the internal use function vclean().
1863  */
1864 __private_extern__ void
ubc_destroy_named(vnode_t vp)1865 ubc_destroy_named(vnode_t vp)
1866 {
1867 	memory_object_control_t control;
1868 	struct ubc_info *uip;
1869 	kern_return_t kret;
1870 
1871 	if (UBCINFOEXISTS(vp)) {
1872 	        uip = vp->v_ubcinfo;
1873 
1874 		/* Terminate the memory object  */
1875 		control = ubc_getobject(vp, UBC_HOLDOBJECT);
1876 		if (control != MEMORY_OBJECT_CONTROL_NULL) {
1877 		        kret = memory_object_destroy(control, 0);
1878 			if (kret != KERN_SUCCESS)
1879 			        panic("ubc_destroy_named: memory_object_destroy failed");
1880 		}
1881 	}
1882 }
1883 
1884 
1885 /*
1886  * ubc_isinuse
1887  *
1888  * Determine whether or not a vnode is currently in use by ubc at a level in
1889  * excess of the requested busycount
1890  *
1891  * Parameters:	vp			The vnode to check
1892  *		busycount		The threshold busy count, used to bias
1893  *					the count usually already held by the
1894  *					caller to avoid races
1895  *
1896  * Returns:	1			The vnode is in use over the threshold
1897  *		0			The vnode is not in use over the
1898  *					threshold
1899  *
1900  * Notes:	Because the vnode is only held locked while actually asking
1901  *		the use count, this function only represents a snapshot of the
1902  *		current state of the vnode.  If more accurate information is
1903  *		required, an additional busycount should be held by the caller
1904  *		and a non-zero busycount used.
1905  *
1906  *		If there is no ubc_info associated with the vnode, this
1907  *		function will report that the vnode is not in use by ubc.
1908  */
1909 int
ubc_isinuse(struct vnode *vp, int busycount)1910 ubc_isinuse(struct vnode *vp, int busycount)
1911 {
1912 	if ( !UBCINFOEXISTS(vp))
1913 		return (0);
1914 	return(ubc_isinuse_locked(vp, busycount, 0));
1915 }
1916 
1917 
1918 /*
1919  * ubc_isinuse_locked
1920  *
1921  * Determine whether or not a vnode is currently in use by ubc at a level in
1922  * excess of the requested busycount
1923  *
1924  * Parameters:	vp			The vnode to check
1925  *		busycount		The threshold busy count, used to bias
1926  *					the count usually already held by the
1927  *					caller to avoid races
1928  *		locked			True if the vnode is already locked by
1929  *					the caller
1930  *
1931  * Returns:	1			The vnode is in use over the threshold
1932  *		0			The vnode is not in use over the
1933  *					threshold
1934  *
1935  * Notes:	If the vnode is not locked on entry, it is locked while
1936  *		actually asking the use count.  If this is the case, this
1937  *		function only represents a snapshot of the current state of
1938  *		the vnode.  If more accurate information is required, the
1939  *		vnode lock should be held by the caller, otherwise an
1940  *		additional busycount should be held by the caller and a
1941  *		non-zero busycount used.
1942  *
1943  *		If there is no ubc_info associated with the vnode, this
1944  *		function will report that the vnode is not in use by ubc.
1945  */
1946 int
ubc_isinuse_locked(struct vnode *vp, int busycount, int locked)1947 ubc_isinuse_locked(struct vnode *vp, int busycount, int locked)
1948 {
1949 	int retval = 0;
1950 
1951 
1952 	if (!locked)
1953 		vnode_lock_spin(vp);
1954 
1955 	if ((vp->v_usecount - vp->v_kusecount) > busycount)
1956 		retval = 1;
1957 
1958 	if (!locked)
1959 		vnode_unlock(vp);
1960 	return (retval);
1961 }
1962 
1963 
1964 /*
1965  * ubc_unmap
1966  *
1967  * Reverse the effects of a ubc_map() call for a given vnode
1968  *
1969  * Parameters:	vp			vnode to unmap from ubc
1970  *
1971  * Returns:	(void)
1972  *
1973  * Notes:	This is an internal use function used by vnode_pager_unmap().
1974  *		It will attempt to obtain a reference on the supplied vnode,
1975  *		and if it can do so, and there is an associated ubc_info, and
1976  *		the flags indicate that it was mapped via ubc_map(), then the
1977  *		flag is cleared, the mapping removed, and the reference taken
1978  *		by ubc_map() is released.
1979  *
1980  *		IMPORTANT: This MUST only be called by the VM
1981  *		to prevent race conditions.
1982  */
1983 __private_extern__ void
ubc_unmap(struct vnode *vp)1984 ubc_unmap(struct vnode *vp)
1985 {
1986 	struct ubc_info *uip;
1987 	int	need_rele = 0;
1988 	int	need_wakeup = 0;
1989 
1990 	if (vnode_getwithref(vp))
1991 	        return;
1992 
1993 	if (UBCINFOEXISTS(vp)) {
1994 		bool want_fsevent = false;
1995 
1996 		vnode_lock(vp);
1997 		uip = vp->v_ubcinfo;
1998 
1999 		while (ISSET(uip->ui_flags, UI_MAPBUSY)) {
2000 			SET(uip->ui_flags, UI_MAPWAITING);
2001 			(void) msleep(&uip->ui_flags, &vp->v_lock,
2002 				      PRIBIO, "ubc_unmap", NULL);
2003 		}
2004 		SET(uip->ui_flags, UI_MAPBUSY);
2005 
2006 		if (ISSET(uip->ui_flags, UI_ISMAPPED)) {
2007 			if (ISSET(uip->ui_flags, UI_MAPPEDWRITE))
2008 				want_fsevent = true;
2009 
2010 			need_rele = 1;
2011 
2012 			/*
2013 			 * We want to clear the mapped flags after we've called
2014 			 * VNOP_MNOMAP to avoid certain races and allow
2015 			 * VNOP_MNOMAP to call ubc_is_mapped_writable.
2016 			 */
2017 		}
2018 		vnode_unlock(vp);
2019 
2020 		if (need_rele) {
2021 				vfs_context_t ctx = vfs_context_current();
2022 
2023 		        (void)VNOP_MNOMAP(vp, ctx);
2024 
2025 #if CONFIG_FSE
2026 				/*
2027 				 * Why do we want an fsevent here?  Normally the
2028 				 * content modified fsevent is posted when a file is
2029 				 * closed and only if it's written to via conventional
2030 				 * means.  It's perfectly legal to close a file and
2031 				 * keep your mappings and we don't currently track
2032 				 * whether it was written to via a mapping.
2033 				 * Therefore, we need to post an fsevent here if the
2034 				 * file was mapped writable.  This may result in false
2035 				 * events, i.e. we post a notification when nothing
2036 				 * has really changed.
2037 				 */
2038 				if (want_fsevent && need_fsevent(FSE_CONTENT_MODIFIED, vp)) {
2039 					add_fsevent(FSE_CONTENT_MODIFIED, ctx,
2040 								FSE_ARG_VNODE, vp,
2041 								FSE_ARG_DONE);
2042 				}
2043 #endif
2044 
2045 		        vnode_rele(vp);
2046 		}
2047 
2048 		vnode_lock_spin(vp);
2049 
2050 		if (need_rele)
2051 			CLR(uip->ui_flags, UI_ISMAPPED | UI_MAPPEDWRITE);
2052 
2053 		CLR(uip->ui_flags, UI_MAPBUSY);
2054 
2055 		if (ISSET(uip->ui_flags, UI_MAPWAITING)) {
2056 			CLR(uip->ui_flags, UI_MAPWAITING);
2057 			need_wakeup = 1;
2058 		}
2059 		vnode_unlock(vp);
2060 
2061 		if (need_wakeup)
2062 		        wakeup(&uip->ui_flags);
2063 
2064 	}
2065 	/*
2066 	 * the drop of the vnode ref will cleanup
2067 	 */
2068 	vnode_put(vp);
2069 }
2070 
2071 
2072 /*
2073  * ubc_page_op
2074  *
2075  * Manipulate individual page state for a vnode with an associated ubc_info
2076  * with an associated memory object control.
2077  *
2078  * Parameters:	vp			The vnode backing the page
2079  *		f_offset		A file offset interior to the page
2080  *		ops			The operations to perform, as a bitmap
2081  *					(see below for more information)
2082  *		phys_entryp		The address of a ppnum_t; may be NULL
2083  *					to ignore
2084  *		flagsp			A pointer to an int to contain flags;
2085  *					may be NULL to ignore
2086  *
2087  * Returns:	KERN_SUCCESS		Success
2088  *		KERN_INVALID_ARGUMENT	If the memory object control has no VM
2089  *					object associated
2090  *		KERN_INVALID_OBJECT	If UPL_POP_PHYSICAL and the object is
2091  *					not physically contiguous
2092  *		KERN_INVALID_OBJECT	If !UPL_POP_PHYSICAL and the object is
2093  *					physically contiguous
2094  *		KERN_FAILURE		If the page cannot be looked up
2095  *
2096  * Implicit Returns:
2097  *		*phys_entryp (modified)	If phys_entryp is non-NULL and
2098  *					UPL_POP_PHYSICAL
2099  *		*flagsp (modified)	If flagsp is non-NULL and there was
2100  *					!UPL_POP_PHYSICAL and a KERN_SUCCESS
2101  *
2102  * Notes:	For object boundaries, it is considerably more efficient to
2103  *		ensure that f_offset is in fact on a page boundary, as this
2104  *		will avoid internal use of the hash table to identify the
2105  *		page, and would therefore skip a number of early optimizations.
2106  *		Since this is a page operation anyway, the caller should try
2107  *		to pass only a page aligned offset because of this.
2108  *
2109  *		*flagsp may be modified even if this function fails.  If it is
2110  *		modified, it will contain the condition of the page before the
2111  *		requested operation was attempted; these will only include the
2112  *		bitmap flags, and not the PL_POP_PHYSICAL, UPL_POP_DUMP,
2113  *		UPL_POP_SET, or UPL_POP_CLR bits.
2114  *
2115  *		The flags field may contain a specific operation, such as
2116  *		UPL_POP_PHYSICAL or UPL_POP_DUMP:
2117  *
2118  *		o	UPL_POP_PHYSICAL	Fail if not contiguous; if
2119  *						*phys_entryp and successful, set
2120  *						*phys_entryp
2121  *		o	UPL_POP_DUMP		Dump the specified page
2122  *
2123  *		Otherwise, it is treated as a bitmap of one or more page
2124  *		operations to perform on the final memory object; allowable
2125  *		bit values are:
2126  *
2127  *		o	UPL_POP_DIRTY		The page is dirty
2128  *		o	UPL_POP_PAGEOUT		The page is paged out
2129  *		o	UPL_POP_PRECIOUS	The page is precious
2130  *		o	UPL_POP_ABSENT		The page is absent
2131  *		o	UPL_POP_BUSY		The page is busy
2132  *
2133  *		If the page status is only being queried and not modified, then
2134  *		not other bits should be specified.  However, if it is being
2135  *		modified, exactly ONE of the following bits should be set:
2136  *
2137  *		o	UPL_POP_SET		Set the current bitmap bits
2138  *		o	UPL_POP_CLR		Clear the current bitmap bits
2139  *
2140  *		Thus to effect a combination of setting an clearing, it may be
2141  *		necessary to call this function twice.  If this is done, the
2142  *		set should be used before the clear, since clearing may trigger
2143  *		a wakeup on the destination page, and if the page is backed by
2144  *		an encrypted swap file, setting will trigger the decryption
2145  *		needed before the wakeup occurs.
2146  */
2147 kern_return_t
ubc_page_op( struct vnode *vp, off_t f_offset, int ops, ppnum_t *phys_entryp, int *flagsp)2148 ubc_page_op(
2149 	struct vnode 	*vp,
2150 	off_t		f_offset,
2151 	int		ops,
2152 	ppnum_t	*phys_entryp,
2153 	int		*flagsp)
2154 {
2155 	memory_object_control_t		control;
2156 
2157 	control = ubc_getobject(vp, UBC_FLAGS_NONE);
2158 	if (control == MEMORY_OBJECT_CONTROL_NULL)
2159 		return KERN_INVALID_ARGUMENT;
2160 
2161 	return (memory_object_page_op(control,
2162 				      (memory_object_offset_t)f_offset,
2163 				      ops,
2164 				      phys_entryp,
2165 				      flagsp));
2166 }
2167 
2168 
2169 /*
2170  * ubc_range_op
2171  *
2172  * Manipulate page state for a range of memory for a vnode with an associated
2173  * ubc_info with an associated memory object control, when page level state is
2174  * not required to be returned from the call (i.e. there are no phys_entryp or
2175  * flagsp parameters to this call, and it takes a range which may contain
2176  * multiple pages, rather than an offset interior to a single page).
2177  *
2178  * Parameters:	vp			The vnode backing the page
2179  *		f_offset_beg		A file offset interior to the start page
2180  *		f_offset_end		A file offset interior to the end page
2181  *		ops			The operations to perform, as a bitmap
2182  *					(see below for more information)
2183  *		range			The address of an int; may be NULL to
2184  *					ignore
2185  *
2186  * Returns:	KERN_SUCCESS		Success
2187  *		KERN_INVALID_ARGUMENT	If the memory object control has no VM
2188  *					object associated
2189  *		KERN_INVALID_OBJECT	If the object is physically contiguous
2190  *
2191  * Implicit Returns:
2192  *		*range (modified)	If range is non-NULL, its contents will
2193  *					be modified to contain the number of
2194  *					bytes successfully operated upon.
2195  *
2196  * Notes:	IMPORTANT: This function cannot be used on a range that
2197  *		consists of physically contiguous pages.
2198  *
2199  *		For object boundaries, it is considerably more efficient to
2200  *		ensure that f_offset_beg and f_offset_end are in fact on page
2201  *		boundaries, as this will avoid internal use of the hash table
2202  *		to identify the page, and would therefore skip a number of
2203  *		early optimizations.  Since this is an operation on a set of
2204  *		pages anyway, the caller should try to pass only a page aligned
2205  *		offsets because of this.
2206  *
2207  *		*range will be modified only if this function succeeds.
2208  *
2209  *		The flags field MUST contain a specific operation; allowable
2210  *		values are:
2211  *
2212  *		o	UPL_ROP_ABSENT	Returns the extent of the range
2213  *					presented which is absent, starting
2214  *					with the start address presented
2215  *
2216  *		o	UPL_ROP_PRESENT	Returns the extent of the range
2217  *					presented which is present (resident),
2218  *					starting with the start address
2219  *					presented
2220  *		o	UPL_ROP_DUMP	Dump the pages which are found in the
2221  *					target object for the target range.
2222  *
2223  *		IMPORTANT: For UPL_ROP_ABSENT and UPL_ROP_PRESENT; if there are
2224  *		multiple regions in the range, only the first matching region
2225  *		is returned.
2226  */
2227 kern_return_t
ubc_range_op( struct vnode *vp, off_t f_offset_beg, off_t f_offset_end, int ops, int *range)2228 ubc_range_op(
2229 	struct vnode 	*vp,
2230 	off_t		f_offset_beg,
2231 	off_t		f_offset_end,
2232 	int             ops,
2233 	int             *range)
2234 {
2235 	memory_object_control_t		control;
2236 
2237 	control = ubc_getobject(vp, UBC_FLAGS_NONE);
2238 	if (control == MEMORY_OBJECT_CONTROL_NULL)
2239 		return KERN_INVALID_ARGUMENT;
2240 
2241 	return (memory_object_range_op(control,
2242 				      (memory_object_offset_t)f_offset_beg,
2243 				      (memory_object_offset_t)f_offset_end,
2244 				      ops,
2245 				      range));
2246 }
2247 
2248 
2249 /*
2250  * ubc_create_upl
2251  *
2252  * Given a vnode, cause the population of a portion of the vm_object; based on
2253  * the nature of the request, the pages returned may contain valid data, or
2254  * they may be uninitialized.
2255  *
2256  * Parameters:	vp			The vnode from which to create the upl
2257  *		f_offset		The start offset into the backing store
2258  *					represented by the vnode
2259  *		bufsize			The size of the upl to create
2260  *		uplp			Pointer to the upl_t to receive the
2261  *					created upl; MUST NOT be NULL
2262  *		plp			Pointer to receive the internal page
2263  *					list for the created upl; MAY be NULL
2264  *					to ignore
2265  *
2266  * Returns:	KERN_SUCCESS		The requested upl has been created
2267  *		KERN_INVALID_ARGUMENT	The bufsize argument is not an even
2268  *					multiple of the page size
2269  *		KERN_INVALID_ARGUMENT	There is no ubc_info associated with
2270  *					the vnode, or there is no memory object
2271  *					control associated with the ubc_info
2272  *	memory_object_upl_request:KERN_INVALID_VALUE
2273  *					The supplied upl_flags argument is
2274  *					invalid
2275  * Implicit Returns:
2276  *		*uplp (modified)
2277  *		*plp (modified)		If non-NULL, the value of *plp will be
2278  *					modified to point to the internal page
2279  *					list; this modification may occur even
2280  *					if this function is unsuccessful, in
2281  *					which case the contents may be invalid
2282  *
2283  * Note:	If successful, the returned *uplp MUST subsequently be freed
2284  *		via a call to ubc_upl_commit(), ubc_upl_commit_range(),
2285  *		ubc_upl_abort(), or ubc_upl_abort_range().
2286  */
2287 kern_return_t
ubc_create_upl( struct vnode *vp, off_t f_offset, int bufsize, upl_t *uplp, upl_page_info_t **plp, int uplflags)2288 ubc_create_upl(
2289 	struct vnode	*vp,
2290 	off_t 		f_offset,
2291 	int		bufsize,
2292 	upl_t		*uplp,
2293 	upl_page_info_t	**plp,
2294 	int		uplflags)
2295 {
2296 	memory_object_control_t		control;
2297 	kern_return_t			kr;
2298 
2299 	if (plp != NULL)
2300 		*plp = NULL;
2301 	*uplp = NULL;
2302 
2303 	if (bufsize & 0xfff)
2304 		return KERN_INVALID_ARGUMENT;
2305 
2306 	if (bufsize > MAX_UPL_SIZE_BYTES)
2307 		return KERN_INVALID_ARGUMENT;
2308 
2309 	if (uplflags & (UPL_UBC_MSYNC | UPL_UBC_PAGEOUT | UPL_UBC_PAGEIN)) {
2310 
2311 		if (uplflags & UPL_UBC_MSYNC) {
2312 			uplflags &= UPL_RET_ONLY_DIRTY;
2313 
2314 			uplflags |= UPL_COPYOUT_FROM | UPL_CLEAN_IN_PLACE |
2315 				    UPL_SET_INTERNAL | UPL_SET_LITE;
2316 
2317 		} else if (uplflags & UPL_UBC_PAGEOUT) {
2318 			uplflags &= UPL_RET_ONLY_DIRTY;
2319 
2320 			if (uplflags & UPL_RET_ONLY_DIRTY)
2321 				uplflags |= UPL_NOBLOCK;
2322 
2323 			uplflags |= UPL_FOR_PAGEOUT | UPL_CLEAN_IN_PLACE |
2324                                     UPL_COPYOUT_FROM | UPL_SET_INTERNAL | UPL_SET_LITE;
2325 		} else {
2326 			uplflags |= UPL_RET_ONLY_ABSENT |
2327 				    UPL_NO_SYNC | UPL_CLEAN_IN_PLACE |
2328 				    UPL_SET_INTERNAL | UPL_SET_LITE;
2329 
2330 			/*
2331 			 * if the requested size == PAGE_SIZE, we don't want to set
2332 			 * the UPL_NOBLOCK since we may be trying to recover from a
2333 			 * previous partial pagein I/O that occurred because we were low
2334 			 * on memory and bailed early in order to honor the UPL_NOBLOCK...
2335 			 * since we're only asking for a single page, we can block w/o fear
2336 			 * of tying up pages while waiting for more to become available
2337 			 */
2338 			if (bufsize > PAGE_SIZE)
2339 				uplflags |= UPL_NOBLOCK;
2340 		}
2341 	} else {
2342 		uplflags &= ~UPL_FOR_PAGEOUT;
2343 
2344 		if (uplflags & UPL_WILL_BE_DUMPED) {
2345 			uplflags &= ~UPL_WILL_BE_DUMPED;
2346 			uplflags |= (UPL_NO_SYNC|UPL_SET_INTERNAL);
2347 		} else
2348 			uplflags |= (UPL_NO_SYNC|UPL_CLEAN_IN_PLACE|UPL_SET_INTERNAL);
2349 	}
2350 	control = ubc_getobject(vp, UBC_FLAGS_NONE);
2351 	if (control == MEMORY_OBJECT_CONTROL_NULL)
2352 		return KERN_INVALID_ARGUMENT;
2353 
2354 	kr = memory_object_upl_request(control, f_offset, bufsize, uplp, NULL, NULL, uplflags);
2355 	if (kr == KERN_SUCCESS && plp != NULL)
2356 		*plp = UPL_GET_INTERNAL_PAGE_LIST(*uplp);
2357 	return kr;
2358 }
2359 
2360 
2361 /*
2362  * ubc_upl_maxbufsize
2363  *
2364  * Return the maximum bufsize ubc_create_upl( ) will take.
2365  *
2366  * Parameters:	none
2367  *
2368  * Returns:	maximum size buffer (in bytes) ubc_create_upl( ) will take.
2369  */
2370 upl_size_t
ubc_upl_maxbufsize( void)2371 ubc_upl_maxbufsize(
2372 	void)
2373 {
2374 	return(MAX_UPL_SIZE_BYTES);
2375 }
2376 
2377 /*
2378  * ubc_upl_map
2379  *
2380  * Map the page list assocated with the supplied upl into the kernel virtual
2381  * address space at the virtual address indicated by the dst_addr argument;
2382  * the entire upl is mapped
2383  *
2384  * Parameters:	upl			The upl to map
2385  *		dst_addr		The address at which to map the upl
2386  *
2387  * Returns:	KERN_SUCCESS		The upl has been mapped
2388  *		KERN_INVALID_ARGUMENT	The upl is UPL_NULL
2389  *		KERN_FAILURE		The upl is already mapped
2390  *	vm_map_enter:KERN_INVALID_ARGUMENT
2391  *					A failure code from vm_map_enter() due
2392  *					to an invalid argument
2393  */
2394 kern_return_t
ubc_upl_map( upl_t upl, vm_offset_t *dst_addr)2395 ubc_upl_map(
2396 	upl_t		upl,
2397 	vm_offset_t	*dst_addr)
2398 {
2399 	return (vm_upl_map(kernel_map, upl, dst_addr));
2400 }
2401 
2402 
2403 /*
2404  * ubc_upl_unmap
2405  *
2406  * Unmap the page list assocated with the supplied upl from the kernel virtual
2407  * address space; the entire upl is unmapped.
2408  *
2409  * Parameters:	upl			The upl to unmap
2410  *
2411  * Returns:	KERN_SUCCESS		The upl has been unmapped
2412  *		KERN_FAILURE		The upl is not currently mapped
2413  *		KERN_INVALID_ARGUMENT	If the upl is UPL_NULL
2414  */
2415 kern_return_t
ubc_upl_unmap( upl_t upl)2416 ubc_upl_unmap(
2417 	upl_t	upl)
2418 {
2419 	return(vm_upl_unmap(kernel_map, upl));
2420 }
2421 
2422 
2423 /*
2424  * ubc_upl_commit
2425  *
2426  * Commit the contents of the upl to the backing store
2427  *
2428  * Parameters:	upl			The upl to commit
2429  *
2430  * Returns:	KERN_SUCCESS		The upl has been committed
2431  *		KERN_INVALID_ARGUMENT	The supplied upl was UPL_NULL
2432  *		KERN_FAILURE		The supplied upl does not represent
2433  *					device memory, and the offset plus the
2434  *					size would exceed the actual size of
2435  *					the upl
2436  *
2437  * Notes:	In practice, the only return value for this function should be
2438  *		KERN_SUCCESS, unless there has been data structure corruption;
2439  *		since the upl is deallocated regardless of success or failure,
2440  *		there's really nothing to do about this other than panic.
2441  *
2442  *		IMPORTANT: Use of this function should not be mixed with use of
2443  *		ubc_upl_commit_range(), due to the unconditional deallocation
2444  *		by this function.
2445  */
2446 kern_return_t
ubc_upl_commit( upl_t upl)2447 ubc_upl_commit(
2448 	upl_t 			upl)
2449 {
2450 	upl_page_info_t	*pl;
2451 	kern_return_t 	kr;
2452 
2453 	pl = UPL_GET_INTERNAL_PAGE_LIST(upl);
2454 	kr = upl_commit(upl, pl, MAX_UPL_SIZE_BYTES >> PAGE_SHIFT);
2455 	upl_deallocate(upl);
2456 	return kr;
2457 }
2458 
2459 
2460 /*
2461  * ubc_upl_commit
2462  *
2463  * Commit the contents of the specified range of the upl to the backing store
2464  *
2465  * Parameters:	upl			The upl to commit
2466  *		offset			The offset into the upl
2467  *		size			The size of the region to be committed,
2468  *					starting at the specified offset
2469  *		flags			commit type (see below)
2470  *
2471  * Returns:	KERN_SUCCESS		The range has been committed
2472  *		KERN_INVALID_ARGUMENT	The supplied upl was UPL_NULL
2473  *		KERN_FAILURE		The supplied upl does not represent
2474  *					device memory, and the offset plus the
2475  *					size would exceed the actual size of
2476  *					the upl
2477  *
2478  * Notes:	IMPORTANT: If the commit is successful, and the object is now
2479  *		empty, the upl will be deallocated.  Since the caller cannot
2480  *		check that this is the case, the UPL_COMMIT_FREE_ON_EMPTY flag
2481  *		should generally only be used when the offset is 0 and the size
2482  *		is equal to the upl size.
2483  *
2484  *		The flags argument is a bitmap of flags on the rage of pages in
2485  *		the upl to be committed; allowable flags are:
2486  *
2487  *		o	UPL_COMMIT_FREE_ON_EMPTY	Free the upl when it is
2488  *							both empty and has been
2489  *							successfully committed
2490  *		o	UPL_COMMIT_CLEAR_DIRTY		Clear each pages dirty
2491  *							bit; will prevent a
2492  *							later pageout
2493  *		o	UPL_COMMIT_SET_DIRTY		Set each pages dirty
2494  *							bit; will cause a later
2495  *							pageout
2496  *		o	UPL_COMMIT_INACTIVATE		Clear each pages
2497  *							reference bit; the page
2498  *							will not be accessed
2499  *		o	UPL_COMMIT_ALLOW_ACCESS		Unbusy each page; pages
2500  *							become busy when an
2501  *							IOMemoryDescriptor is
2502  *							mapped or redirected,
2503  *							and we have to wait for
2504  *							an IOKit driver
2505  *
2506  *		The flag UPL_COMMIT_NOTIFY_EMPTY is used internally, and should
2507  *		not be specified by the caller.
2508  *
2509  *		The UPL_COMMIT_CLEAR_DIRTY and UPL_COMMIT_SET_DIRTY flags are
2510  *		mutually exclusive, and should not be combined.
2511  */
2512 kern_return_t
ubc_upl_commit_range( upl_t upl, upl_offset_t offset, upl_size_t size, int flags)2513 ubc_upl_commit_range(
2514 	upl_t 			upl,
2515 	upl_offset_t		offset,
2516 	upl_size_t		size,
2517 	int				flags)
2518 {
2519 	upl_page_info_t	*pl;
2520 	boolean_t		empty;
2521 	kern_return_t 	kr;
2522 
2523 	if (flags & UPL_COMMIT_FREE_ON_EMPTY)
2524 		flags |= UPL_COMMIT_NOTIFY_EMPTY;
2525 
2526 	if (flags & UPL_COMMIT_KERNEL_ONLY_FLAGS) {
2527 		return KERN_INVALID_ARGUMENT;
2528 	}
2529 
2530 	pl = UPL_GET_INTERNAL_PAGE_LIST(upl);
2531 
2532 	kr = upl_commit_range(upl, offset, size, flags,
2533 			      pl, MAX_UPL_SIZE_BYTES >> PAGE_SHIFT, &empty);
2534 
2535 	if((flags & UPL_COMMIT_FREE_ON_EMPTY) && empty)
2536 		upl_deallocate(upl);
2537 
2538 	return kr;
2539 }
2540 
2541 
2542 /*
2543  * ubc_upl_abort_range
2544  *
2545  * Abort the contents of the specified range of the specified upl
2546  *
2547  * Parameters:	upl			The upl to abort
2548  *		offset			The offset into the upl
2549  *		size			The size of the region to be aborted,
2550  *					starting at the specified offset
2551  *		abort_flags		abort type (see below)
2552  *
2553  * Returns:	KERN_SUCCESS		The range has been aborted
2554  *		KERN_INVALID_ARGUMENT	The supplied upl was UPL_NULL
2555  *		KERN_FAILURE		The supplied upl does not represent
2556  *					device memory, and the offset plus the
2557  *					size would exceed the actual size of
2558  *					the upl
2559  *
2560  * Notes:	IMPORTANT: If the abort is successful, and the object is now
2561  *		empty, the upl will be deallocated.  Since the caller cannot
2562  *		check that this is the case, the UPL_ABORT_FREE_ON_EMPTY flag
2563  *		should generally only be used when the offset is 0 and the size
2564  *		is equal to the upl size.
2565  *
2566  *		The abort_flags argument is a bitmap of flags on the range of
2567  *		pages in the upl to be aborted; allowable flags are:
2568  *
2569  *		o	UPL_ABORT_FREE_ON_EMPTY	Free the upl when it is both
2570  *						empty and has been successfully
2571  *						aborted
2572  *		o	UPL_ABORT_RESTART	The operation must be restarted
2573  *		o	UPL_ABORT_UNAVAILABLE	The pages are unavailable
2574  *		o	UPL_ABORT_ERROR		An I/O error occurred
2575  *		o	UPL_ABORT_DUMP_PAGES	Just free the pages
2576  *		o	UPL_ABORT_NOTIFY_EMPTY	RESERVED
2577  *		o	UPL_ABORT_ALLOW_ACCESS	RESERVED
2578  *
2579  *		The UPL_ABORT_NOTIFY_EMPTY is an internal use flag and should
2580  *		not be specified by the caller.  It is intended to fulfill the
2581  *		same role as UPL_COMMIT_NOTIFY_EMPTY does in the function
2582  *		ubc_upl_commit_range(), but is never referenced internally.
2583  *
2584  *		The UPL_ABORT_ALLOW_ACCESS is defined, but neither set nor
2585  *		referenced; do not use it.
2586  */
2587 kern_return_t
ubc_upl_abort_range( upl_t upl, upl_offset_t offset, upl_size_t size, int abort_flags)2588 ubc_upl_abort_range(
2589 	upl_t			upl,
2590 	upl_offset_t		offset,
2591 	upl_size_t		size,
2592 	int				abort_flags)
2593 {
2594 	kern_return_t 	kr;
2595 	boolean_t		empty = FALSE;
2596 
2597 	if (abort_flags & UPL_ABORT_FREE_ON_EMPTY)
2598 		abort_flags |= UPL_ABORT_NOTIFY_EMPTY;
2599 
2600 	kr = upl_abort_range(upl, offset, size, abort_flags, &empty);
2601 
2602 	if((abort_flags & UPL_ABORT_FREE_ON_EMPTY) && empty)
2603 		upl_deallocate(upl);
2604 
2605 	return kr;
2606 }
2607 
2608 
2609 /*
2610  * ubc_upl_abort
2611  *
2612  * Abort the contents of the specified upl
2613  *
2614  * Parameters:	upl			The upl to abort
2615  *		abort_type		abort type (see below)
2616  *
2617  * Returns:	KERN_SUCCESS		The range has been aborted
2618  *		KERN_INVALID_ARGUMENT	The supplied upl was UPL_NULL
2619  *		KERN_FAILURE		The supplied upl does not represent
2620  *					device memory, and the offset plus the
2621  *					size would exceed the actual size of
2622  *					the upl
2623  *
2624  * Notes:	IMPORTANT: If the abort is successful, and the object is now
2625  *		empty, the upl will be deallocated.  Since the caller cannot
2626  *		check that this is the case, the UPL_ABORT_FREE_ON_EMPTY flag
2627  *		should generally only be used when the offset is 0 and the size
2628  *		is equal to the upl size.
2629  *
2630  *		The abort_type is a bitmap of flags on the range of
2631  *		pages in the upl to be aborted; allowable flags are:
2632  *
2633  *		o	UPL_ABORT_FREE_ON_EMPTY	Free the upl when it is both
2634  *						empty and has been successfully
2635  *						aborted
2636  *		o	UPL_ABORT_RESTART	The operation must be restarted
2637  *		o	UPL_ABORT_UNAVAILABLE	The pages are unavailable
2638  *		o	UPL_ABORT_ERROR		An I/O error occurred
2639  *		o	UPL_ABORT_DUMP_PAGES	Just free the pages
2640  *		o	UPL_ABORT_NOTIFY_EMPTY	RESERVED
2641  *		o	UPL_ABORT_ALLOW_ACCESS	RESERVED
2642  *
2643  *		The UPL_ABORT_NOTIFY_EMPTY is an internal use flag and should
2644  *		not be specified by the caller.  It is intended to fulfill the
2645  *		same role as UPL_COMMIT_NOTIFY_EMPTY does in the function
2646  *		ubc_upl_commit_range(), but is never referenced internally.
2647  *
2648  *		The UPL_ABORT_ALLOW_ACCESS is defined, but neither set nor
2649  *		referenced; do not use it.
2650  */
2651 kern_return_t
ubc_upl_abort( upl_t upl, int abort_type)2652 ubc_upl_abort(
2653 	upl_t			upl,
2654 	int				abort_type)
2655 {
2656 	kern_return_t	kr;
2657 
2658 	kr = upl_abort(upl, abort_type);
2659 	upl_deallocate(upl);
2660 	return kr;
2661 }
2662 
2663 
2664 /*
2665  * ubc_upl_pageinfo
2666  *
2667  *  Retrieve the internal page list for the specified upl
2668  *
2669  * Parameters:	upl			The upl to obtain the page list from
2670  *
2671  * Returns:	!NULL			The (upl_page_info_t *) for the page
2672  *					list internal to the upl
2673  *		NULL			Error/no page list associated
2674  *
2675  * Notes:	IMPORTANT: The function is only valid on internal objects
2676  *		where the list request was made with the UPL_INTERNAL flag.
2677  *
2678  *		This function is a utility helper function, since some callers
2679  *		may not have direct access to the header defining the macro,
2680  *		due to abstraction layering constraints.
2681  */
2682 upl_page_info_t *
ubc_upl_pageinfo( upl_t upl)2683 ubc_upl_pageinfo(
2684 	upl_t			upl)
2685 {
2686 	return (UPL_GET_INTERNAL_PAGE_LIST(upl));
2687 }
2688 
2689 
2690 int
UBCINFOEXISTS(const struct vnode * vp)2691 UBCINFOEXISTS(const struct vnode * vp)
2692 {
2693         return((vp) && ((vp)->v_type == VREG) && ((vp)->v_ubcinfo != UBC_INFO_NULL));
2694 }
2695 
2696 
2697 void
ubc_upl_range_needed( upl_t upl, int index, int count)2698 ubc_upl_range_needed(
2699 	upl_t		upl,
2700 	int		index,
2701 	int		count)
2702 {
2703 	upl_range_needed(upl, index, count);
2704 }
2705 
ubc_is_mapped(const struct vnode *vp, boolean_t *writable)2706 boolean_t ubc_is_mapped(const struct vnode *vp, boolean_t *writable)
2707 {
2708 	if (!UBCINFOEXISTS(vp) || !ISSET(vp->v_ubcinfo->ui_flags, UI_ISMAPPED))
2709 		return FALSE;
2710 	if (writable)
2711 		*writable = ISSET(vp->v_ubcinfo->ui_flags, UI_MAPPEDWRITE);
2712 	return TRUE;
2713 }
2714 
ubc_is_mapped_writable(const struct vnode *vp)2715 boolean_t ubc_is_mapped_writable(const struct vnode *vp)
2716 {
2717 	boolean_t writable;
2718 	return ubc_is_mapped(vp, &writable) && writable;
2719 }
2720 
2721 
2722 /*
2723  * CODE SIGNING
2724  */
2725 static volatile SInt32 cs_blob_size = 0;
2726 static volatile SInt32 cs_blob_count = 0;
2727 static SInt32 cs_blob_size_peak = 0;
2728 static UInt32 cs_blob_size_max = 0;
2729 static SInt32 cs_blob_count_peak = 0;
2730 
2731 SYSCTL_INT(_vm, OID_AUTO, cs_blob_count, CTLFLAG_RD | CTLFLAG_LOCKED, (int *)(uintptr_t)&cs_blob_count, 0, "Current number of code signature blobs");
2732 SYSCTL_INT(_vm, OID_AUTO, cs_blob_size, CTLFLAG_RD | CTLFLAG_LOCKED, (int *)(uintptr_t)&cs_blob_size, 0, "Current size of all code signature blobs");
2733 SYSCTL_INT(_vm, OID_AUTO, cs_blob_count_peak, CTLFLAG_RD | CTLFLAG_LOCKED, &cs_blob_count_peak, 0, "Peak number of code signature blobs");
2734 SYSCTL_INT(_vm, OID_AUTO, cs_blob_size_peak, CTLFLAG_RD | CTLFLAG_LOCKED, &cs_blob_size_peak, 0, "Peak size of code signature blobs");
2735 SYSCTL_INT(_vm, OID_AUTO, cs_blob_size_max, CTLFLAG_RD | CTLFLAG_LOCKED, &cs_blob_size_max, 0, "Size of biggest code signature blob");
2736 
2737 /*
2738  * Function: csblob_parse_teamid
2739  *
2740  * Description: This function returns a pointer to the team id
2741  		stored within the codedirectory of the csblob.
2742 		If the codedirectory predates team-ids, it returns
2743 		NULL.
2744 		This does not copy the name but returns a pointer to
2745 		it within the CD. Subsequently, the CD must be
2746 		available when this is used.
2747 */
2748 
2749 static const char *
csblob_parse_teamid(struct cs_blob *csblob)2750 csblob_parse_teamid(struct cs_blob *csblob)
2751 {
2752 	const CS_CodeDirectory *cd;
2753 
2754 	cd = csblob->csb_cd;
2755 
2756 	if (ntohl(cd->version) < CS_SUPPORTSTEAMID)
2757 		return NULL;
2758 
2759 	if (cd->teamOffset == 0)
2760 		return NULL;
2761 
2762 	const char *name = ((const char *)cd) + ntohl(cd->teamOffset);
2763 	if (cs_debug > 1)
2764 		printf("found team-id %s in cdblob\n", name);
2765 
2766 	return name;
2767 }
2768 
2769 
2770 kern_return_t
ubc_cs_blob_allocate( vm_offset_t *blob_addr_p, vm_size_t *blob_size_p)2771 ubc_cs_blob_allocate(
2772 	vm_offset_t	*blob_addr_p,
2773 	vm_size_t	*blob_size_p)
2774 {
2775 	kern_return_t	kr;
2776 
2777 	*blob_addr_p = (vm_offset_t) kalloc_tag(*blob_size_p, VM_KERN_MEMORY_SECURITY);
2778 	if (*blob_addr_p == 0) {
2779 		kr = KERN_NO_SPACE;
2780 	} else {
2781 		kr = KERN_SUCCESS;
2782 	}
2783 	return kr;
2784 }
2785 
2786 void
ubc_cs_blob_deallocate( vm_offset_t blob_addr, vm_size_t blob_size)2787 ubc_cs_blob_deallocate(
2788 	vm_offset_t	blob_addr,
2789 	vm_size_t	blob_size)
2790 {
2791 	kfree((void *) blob_addr, blob_size);
2792 }
2793 
2794 /*
2795  * Some codesigned files use a lowest common denominator page size of
2796  * 4KiB, but can be used on systems that have a runtime page size of
2797  * 16KiB. Since faults will only occur on 16KiB ranges in
2798  * cs_validate_range(), we can convert the original Code Directory to
2799  * a multi-level scheme where groups of 4 hashes are combined to form
2800  * a new hash, which represents 16KiB in the on-disk file.  This can
2801  * reduce the wired memory requirement for the Code Directory by
2802  * 75%. Care must be taken for binaries that use the "fourk" VM pager
2803  * for unaligned access, which may still attempt to validate on
2804  * non-16KiB multiples for compatibility with 3rd party binaries.
2805  */
2806 static boolean_t
ubc_cs_supports_multilevel_hash(struct cs_blob *blob)2807 ubc_cs_supports_multilevel_hash(struct cs_blob *blob)
2808 {
2809 	const CS_CodeDirectory *cd;
2810 
2811 	/*
2812 	 * Only applies to binaries that ship as part of the OS,
2813 	 * primarily the shared cache.
2814 	 */
2815 	if (!blob->csb_platform_binary || blob->csb_teamid != NULL) {
2816 		return FALSE;
2817 	}
2818 
2819 	/*
2820 	 * If the runtime page size matches the code signing page
2821 	 * size, there is no work to do.
2822 	 */
2823 	if (PAGE_SHIFT <= blob->csb_hash_pageshift) {
2824 		return FALSE;
2825 	}
2826 
2827 	cd = blob->csb_cd;
2828 
2829 	/*
2830 	 * There must be a valid integral multiple of hashes
2831 	 */
2832 	if (ntohl(cd->nCodeSlots) & (PAGE_MASK >> blob->csb_hash_pageshift)) {
2833 		return FALSE;
2834 	}
2835 
2836 	/*
2837 	 * Scatter lists must also have ranges that have an integral number of hashes
2838 	 */
2839 	if ((ntohl(cd->version) >= CS_SUPPORTSSCATTER) && (ntohl(cd->scatterOffset))) {
2840 
2841 		const SC_Scatter *scatter = (const SC_Scatter*)
2842 			((const char*)cd + ntohl(cd->scatterOffset));
2843 		/* iterate all scatter structs to make sure they are all aligned */
2844 		do {
2845 			uint32_t sbase = ntohl(scatter->base);
2846 			uint32_t scount = ntohl(scatter->count);
2847 
2848 			/* last scatter? */
2849 			if (scount == 0) {
2850 				break;
2851 			}
2852 
2853 			if (sbase & (PAGE_MASK >> blob->csb_hash_pageshift)) {
2854 				return FALSE;
2855 			}
2856 
2857 			if (scount & (PAGE_MASK >> blob->csb_hash_pageshift)) {
2858 				return FALSE;
2859 			}
2860 
2861 			scatter++;
2862 		} while(1);
2863 	}
2864 
2865 	/* Covered range must be a multiple of the new page size */
2866 	if (ntohl(cd->codeLimit) & PAGE_MASK) {
2867 		return FALSE;
2868 	}
2869 
2870 	/* All checks pass */
2871 	return TRUE;
2872 }
2873 
2874 /*
2875  * All state and preconditions were checked before, so this
2876  * function cannot fail.
2877  */
2878 static void
ubc_cs_convert_to_multilevel_hash(struct cs_blob *blob)2879 ubc_cs_convert_to_multilevel_hash(struct cs_blob *blob)
2880 {
2881 	const CS_CodeDirectory	*old_cd, *cd;
2882 	CS_CodeDirectory	*new_cd;
2883 	const CS_GenericBlob *entitlements;
2884 	vm_offset_t     new_blob_addr;
2885 	vm_size_t       new_blob_size;
2886 	vm_size_t       new_cdsize;
2887 	kern_return_t	kr;
2888 	int				error;
2889 	size_t		length;
2890 
2891 	uint32_t		hashes_per_new_hash_shift = (uint32_t)(PAGE_SHIFT - blob->csb_hash_pageshift);
2892 
2893 	if (cs_debug > 1) {
2894 		printf("CODE SIGNING: Attempting to convert Code Directory for %lu -> %lu page shift\n",
2895 			   (unsigned long)blob->csb_hash_pageshift, (unsigned long)PAGE_SHIFT);
2896 	}
2897 
2898 	old_cd = blob->csb_cd;
2899 
2900 	/* Up to the hashes, we can copy all data */
2901 	new_cdsize  = ntohl(old_cd->hashOffset);
2902 	new_cdsize += (ntohl(old_cd->nCodeSlots) >> hashes_per_new_hash_shift) * old_cd->hashSize;
2903 
2904 	new_blob_size  = sizeof(CS_SuperBlob);
2905 	new_blob_size += sizeof(CS_BlobIndex);
2906 	new_blob_size += new_cdsize;
2907 
2908 	if (blob->csb_entitlements_blob) {
2909 		/* We need to add a slot for the entitlements */
2910 		new_blob_size += sizeof(CS_BlobIndex);
2911 		new_blob_size += ntohl(blob->csb_entitlements_blob->length);
2912 	}
2913 
2914 	kr = ubc_cs_blob_allocate(&new_blob_addr, &new_blob_size);
2915 	if (kr != KERN_SUCCESS) {
2916 		if (cs_debug > 1) {
2917 			printf("CODE SIGNING: Failed to allocate memory for new Code Signing Blob: %d\n",
2918 				   kr);
2919 		}
2920 		return;
2921 	}
2922 
2923 	CS_SuperBlob		*new_superblob;
2924 
2925 	new_superblob = (CS_SuperBlob *)new_blob_addr;
2926 	new_superblob->magic = htonl(CSMAGIC_EMBEDDED_SIGNATURE);
2927 	new_superblob->length = htonl((uint32_t)new_blob_size);
2928 	if (blob->csb_entitlements_blob) {
2929 		vm_size_t			ent_offset, cd_offset;
2930 
2931 		cd_offset  = sizeof(CS_SuperBlob) + 2 * sizeof(CS_BlobIndex);
2932 		ent_offset = cd_offset +  new_cdsize;
2933 
2934 		new_superblob->count = htonl(2);
2935 		new_superblob->index[0].type = htonl(CSSLOT_CODEDIRECTORY);
2936 		new_superblob->index[0].offset = htonl((uint32_t)cd_offset);
2937 		new_superblob->index[1].type = htonl(CSSLOT_ENTITLEMENTS);
2938 		new_superblob->index[1].offset = htonl((uint32_t)ent_offset);
2939 
2940 		memcpy((void *)(new_blob_addr + ent_offset), blob->csb_entitlements_blob, ntohl(blob->csb_entitlements_blob->length));
2941 
2942 		new_cd = (CS_CodeDirectory *)(new_blob_addr + cd_offset);
2943 	} else {
2944 		vm_size_t			cd_offset;
2945 
2946 		cd_offset  = sizeof(CS_SuperBlob) + 1 * sizeof(CS_BlobIndex);
2947 
2948 		new_superblob->count = htonl(1);
2949 		new_superblob->index[0].type = htonl(CSSLOT_CODEDIRECTORY);
2950 		new_superblob->index[0].offset = htonl((uint32_t)cd_offset);
2951 
2952 		new_cd = (CS_CodeDirectory *)new_blob_addr;
2953 	}
2954 
2955 	memcpy(new_cd, old_cd, ntohl(old_cd->hashOffset));
2956 
2957 	/* Update fields in the Code Directory structure */
2958 	new_cd->length = htonl((uint32_t)new_cdsize);
2959 
2960 	uint32_t nCodeSlots = ntohl(new_cd->nCodeSlots);
2961 	nCodeSlots >>= hashes_per_new_hash_shift;
2962 	new_cd->nCodeSlots = htonl(nCodeSlots);
2963 
2964 	new_cd->pageSize = PAGE_SHIFT; /* Not byte-swapped */
2965 
2966 	if ((ntohl(new_cd->version) >= CS_SUPPORTSSCATTER) && (ntohl(new_cd->scatterOffset))) {
2967 		SC_Scatter *scatter = (SC_Scatter*)
2968 			((char *)new_cd + ntohl(new_cd->scatterOffset));
2969 		/* iterate all scatter structs to scale their counts */
2970 		do {
2971 			uint32_t scount = ntohl(scatter->count);
2972 			uint32_t sbase  = ntohl(scatter->base);
2973 
2974 			/* last scatter? */
2975 			if (scount == 0) {
2976 				break;
2977 			}
2978 
2979 			scount >>= hashes_per_new_hash_shift;
2980 			scatter->count = htonl(scount);
2981 
2982 			sbase >>= hashes_per_new_hash_shift;
2983 			scatter->base = htonl(sbase);
2984 
2985 			scatter++;
2986 		} while(1);
2987 	}
2988 
2989 	/* For each group of hashes, hash them together */
2990 	const unsigned char *src_base = (const unsigned char *)old_cd + ntohl(old_cd->hashOffset);
2991 	unsigned char *dst_base = (unsigned char *)new_cd + ntohl(new_cd->hashOffset);
2992 
2993 	uint32_t hash_index;
2994 	for (hash_index = 0; hash_index < nCodeSlots; hash_index++) {
2995 		union cs_hash_union	mdctx;
2996 
2997 		uint32_t source_hash_len = old_cd->hashSize << hashes_per_new_hash_shift;
2998 		const unsigned char *src = src_base + hash_index * source_hash_len;
2999 		unsigned char *dst = dst_base + hash_index * new_cd->hashSize;
3000 
3001 		blob->csb_hashtype->cs_init(&mdctx);
3002 		blob->csb_hashtype->cs_update(&mdctx, src, source_hash_len);
3003 		blob->csb_hashtype->cs_final(dst, &mdctx);
3004 	}
3005 
3006 	length = new_blob_size;
3007 	error = cs_validate_csblob((const uint8_t *)new_blob_addr, &length, &cd, &entitlements);
3008 	assert(length == new_blob_size);
3009 	if (error) {
3010 
3011 		if (cs_debug > 1) {
3012 			printf("CODE SIGNING: Failed to validate new Code Signing Blob: %d\n",
3013 				   error);
3014 		}
3015 
3016 		ubc_cs_blob_deallocate(new_blob_addr, new_blob_size);
3017 		return;
3018 	}
3019 
3020 	/* New Code Directory is ready for use, swap it out in the blob structure */
3021 	ubc_cs_blob_deallocate(blob->csb_mem_kaddr, blob->csb_mem_size);
3022 
3023 	blob->csb_mem_size = new_blob_size;
3024 	blob->csb_mem_kaddr = new_blob_addr;
3025 	blob->csb_cd = cd;
3026 	blob->csb_entitlements_blob = entitlements;
3027 
3028 	/* The blob has some cached attributes of the Code Directory, so update those */
3029 
3030 	blob->csb_hash_firstlevel_pagesize = blob->csb_hash_pagesize; /* Save the original page size */
3031 
3032 	blob->csb_hash_pagesize = PAGE_SIZE;
3033 	blob->csb_hash_pagemask = PAGE_MASK;
3034 	blob->csb_hash_pageshift = PAGE_SHIFT;
3035 	blob->csb_end_offset = ntohl(cd->codeLimit);
3036 	if((ntohl(cd->version) >= CS_SUPPORTSSCATTER) && (ntohl(cd->scatterOffset))) {
3037 		const SC_Scatter *scatter = (const SC_Scatter*)
3038 			((const char*)cd + ntohl(cd->scatterOffset));
3039 		blob->csb_start_offset = ((off_t)ntohl(scatter->base)) * PAGE_SIZE;
3040 	} else {
3041 		blob->csb_start_offset = 0;
3042 	}
3043 }
3044 
3045 int
ubc_cs_blob_add( struct vnode *vp, cpu_type_t cputype, off_t base_offset, vm_address_t *addr, vm_size_t size, struct image_params *imgp, __unused int flags, struct cs_blob **ret_blob)3046 ubc_cs_blob_add(
3047 	struct vnode	*vp,
3048 	cpu_type_t	cputype,
3049 	off_t		base_offset,
3050 	vm_address_t	*addr,
3051 	vm_size_t	size,
3052 	struct image_params *imgp,
3053 	__unused int	flags,
3054 	struct cs_blob	**ret_blob)
3055 {
3056 	kern_return_t		kr;
3057 	struct ubc_info		*uip;
3058 	struct cs_blob		*blob, *oblob;
3059 	int			error;
3060 	const CS_CodeDirectory *cd;
3061 	const CS_GenericBlob *entitlements;
3062 	off_t			blob_start_offset, blob_end_offset;
3063 	union cs_hash_union	mdctx;
3064 	boolean_t		record_mtime;
3065 	size_t			length;
3066 
3067 	record_mtime = FALSE;
3068 	if (ret_blob)
3069 	    *ret_blob = NULL;
3070 
3071 	blob = (struct cs_blob *) kalloc(sizeof (struct cs_blob));
3072 	if (blob == NULL) {
3073 		return ENOMEM;
3074 	}
3075 
3076 	/* fill in the new blob */
3077 	blob->csb_cpu_type = cputype;
3078 	blob->csb_base_offset = base_offset;
3079 	blob->csb_mem_size = size;
3080 	blob->csb_mem_offset = 0;
3081 	blob->csb_mem_kaddr = *addr;
3082 	blob->csb_flags = 0;
3083 	blob->csb_platform_binary = 0;
3084 	blob->csb_platform_path = 0;
3085 	blob->csb_teamid = NULL;
3086 	blob->csb_entitlements_blob = NULL;
3087 	blob->csb_entitlements = NULL;
3088 
3089 	/* Transfer ownership. Even on error, this function will deallocate */
3090 	*addr = 0;
3091 
3092 	/*
3093 	 * Validate the blob's contents
3094 	 */
3095 	length = (size_t) size;
3096 	error = cs_validate_csblob((const uint8_t *)blob->csb_mem_kaddr,
3097 				   &length, &cd, &entitlements);
3098 	if (error) {
3099 
3100 		if (cs_debug)
3101 			printf("CODESIGNING: csblob invalid: %d\n", error);
3102 		/*
3103 		 * The vnode checker can't make the rest of this function
3104 		 * succeed if csblob validation failed, so bail */
3105 		goto out;
3106 
3107 	} else {
3108 		const unsigned char *md_base;
3109 		uint8_t hash[CS_HASH_MAX_SIZE];
3110 		int md_size;
3111 
3112 		size = (vm_size_t) length;
3113 		assert(size <= blob->csb_mem_size);
3114 		if (size < blob->csb_mem_size) {
3115 			vm_address_t new_blob_addr;
3116 			const CS_CodeDirectory *new_cd;
3117 			const CS_GenericBlob *new_entitlements;
3118 
3119 			kr = ubc_cs_blob_allocate(&new_blob_addr, &size);
3120 			if (kr != KERN_SUCCESS) {
3121 				if (cs_debug > 1) {
3122 					printf("CODE SIGNING: failed to "
3123 					       "re-allocate blob (size "
3124 					       "0x%llx->0x%llx) error 0x%x\n",
3125 					       (uint64_t)blob->csb_mem_size,
3126 					       (uint64_t)size,
3127 					       kr);
3128 				}
3129 			} else {
3130 				memcpy(new_blob_addr, blob->csb_mem_kaddr, size);
3131 				if (cd == NULL) {
3132 					new_cd = NULL;
3133 				} else {
3134 					new_cd = ((uintptr_t)cd
3135 						  - (uintptr_t)blob->csb_mem_kaddr
3136 						  + (uintptr_t)new_blob_addr);
3137 				}
3138 				if (entitlements == NULL) {
3139 					new_entitlements = NULL;
3140 				} else {
3141 					new_entitlements = ((uintptr_t)entitlements
3142 							    - (uintptr_t)blob->csb_mem_kaddr
3143 							    + (uintptr_t)new_blob_addr);
3144 				}
3145 //				printf("CODE SIGNING: %s:%d kaddr 0x%llx cd %p ents %p -> blob 0x%llx cd %p ents %p\n", __FUNCTION__, __LINE__, (uint64_t)blob->csb_mem_kaddr, cd, entitlements, (uint64_t)new_blob_addr, new_cd, new_entitlements);
3146 				ubc_cs_blob_deallocate(blob->csb_mem_kaddr,
3147 						       blob->csb_mem_size);
3148 				blob->csb_mem_kaddr = new_blob_addr;
3149 				blob->csb_mem_size = size;
3150 				cd = new_cd;
3151 				entitlements = new_entitlements;
3152 			}
3153 		}
3154 
3155 		blob->csb_cd = cd;
3156 		blob->csb_entitlements_blob = entitlements; /* may be NULL, not yet validated */
3157 		blob->csb_hashtype = cs_find_md(cd->hashType);
3158 		if (blob->csb_hashtype == NULL || blob->csb_hashtype->cs_digest_size > sizeof(hash))
3159 			panic("validated CodeDirectory but unsupported type");
3160 
3161 		blob->csb_hash_pageshift = cd->pageSize;
3162 		blob->csb_hash_pagesize = (1U << cd->pageSize);
3163 		blob->csb_hash_pagemask = blob->csb_hash_pagesize - 1;
3164 		blob->csb_hash_firstlevel_pagesize = 0;
3165 		blob->csb_flags = (ntohl(cd->flags) & CS_ALLOWED_MACHO) | CS_VALID;
3166 		blob->csb_end_offset = (((vm_offset_t)ntohl(cd->codeLimit) + blob->csb_hash_pagemask) & ~((vm_offset_t)blob->csb_hash_pagemask));
3167 		if((ntohl(cd->version) >= CS_SUPPORTSSCATTER) && (ntohl(cd->scatterOffset))) {
3168 			const SC_Scatter *scatter = (const SC_Scatter*)
3169 				((const char*)cd + ntohl(cd->scatterOffset));
3170 			blob->csb_start_offset = ((off_t)ntohl(scatter->base)) * blob->csb_hash_pagesize;
3171 		} else {
3172 			blob->csb_start_offset = 0;
3173 		}
3174 		/* compute the blob's cdhash */
3175 		md_base = (const unsigned char *) cd;
3176 		md_size = ntohl(cd->length);
3177 
3178 		blob->csb_hashtype->cs_init(&mdctx);
3179 		blob->csb_hashtype->cs_update(&mdctx, md_base, md_size);
3180 		blob->csb_hashtype->cs_final(hash, &mdctx);
3181 
3182 		memcpy(blob->csb_cdhash, hash, CS_CDHASH_LEN);
3183 	}
3184 
3185 	/*
3186 	 * Let policy module check whether the blob's signature is accepted.
3187 	 */
3188 #if CONFIG_MACF
3189     unsigned int cs_flags = blob->csb_flags;
3190 	error = mac_vnode_check_signature(vp, blob, imgp, &cs_flags, flags);
3191     blob->csb_flags = cs_flags;
3192 
3193 	if (error) {
3194 		if (cs_debug)
3195 			printf("check_signature[pid: %d], error = %d\n", current_proc()->p_pid, error);
3196 		goto out;
3197 	}
3198 	if ((flags & MAC_VNODE_CHECK_DYLD_SIM) && !(blob->csb_flags & CS_PLATFORM_BINARY)) {
3199 		if (cs_debug)
3200 			printf("check_signature[pid: %d], is not apple signed\n", current_proc()->p_pid);
3201 		error = EPERM;
3202 		goto out;
3203 	}
3204 #endif
3205 
3206 	if (blob->csb_flags & CS_PLATFORM_BINARY) {
3207 		if (cs_debug > 1)
3208 			printf("check_signature[pid: %d]: platform binary\n", current_proc()->p_pid);
3209 		blob->csb_platform_binary = 1;
3210 		blob->csb_platform_path = !!(blob->csb_flags & CS_PLATFORM_PATH);
3211 	} else {
3212 		blob->csb_platform_binary = 0;
3213 		blob->csb_platform_path = 0;
3214 		blob->csb_teamid = csblob_parse_teamid(blob);
3215 		if (cs_debug > 1) {
3216 			if (blob->csb_teamid)
3217 				printf("check_signature[pid: %d]: team-id is %s\n", current_proc()->p_pid, blob->csb_teamid);
3218 			else
3219 				printf("check_signature[pid: %d]: no team-id\n", current_proc()->p_pid);
3220 		}
3221 	}
3222 
3223 	/*
3224 	 * Validate the blob's coverage
3225 	 */
3226 	blob_start_offset = blob->csb_base_offset + blob->csb_start_offset;
3227 	blob_end_offset = blob->csb_base_offset + blob->csb_end_offset;
3228 
3229 	if (blob_start_offset >= blob_end_offset ||
3230 	    blob_start_offset < 0 ||
3231 	    blob_end_offset <= 0) {
3232 		/* reject empty or backwards blob */
3233 		error = EINVAL;
3234 		goto out;
3235 	}
3236 
3237 	if (ubc_cs_supports_multilevel_hash(blob)) {
3238 		ubc_cs_convert_to_multilevel_hash(blob);
3239 	}
3240 
3241 	vnode_lock(vp);
3242 	if (! UBCINFOEXISTS(vp)) {
3243 		vnode_unlock(vp);
3244 		error = ENOENT;
3245 		goto out;
3246 	}
3247 	uip = vp->v_ubcinfo;
3248 
3249 	/* check if this new blob overlaps with an existing blob */
3250 	for (oblob = uip->cs_blobs;
3251 	     oblob != NULL;
3252 	     oblob = oblob->csb_next) {
3253 		 off_t oblob_start_offset, oblob_end_offset;
3254 
3255 		 /* check for conflicting teamid */
3256 		 if (blob->csb_platform_binary) { //platform binary needs to be the same for app slices
3257 			 if (!oblob->csb_platform_binary) {
3258 				 vnode_unlock(vp);
3259 				 error = EALREADY;
3260 				 goto out;
3261 			 }
3262 		 } else if (blob->csb_teamid) { //teamid binary needs to be the same for app slices
3263 		 	if (oblob->csb_platform_binary ||
3264 			    oblob->csb_teamid == NULL ||
3265 			    strcmp(oblob->csb_teamid, blob->csb_teamid) != 0) {
3266 				vnode_unlock(vp);
3267 				error = EALREADY;
3268 				goto out;
3269 			}
3270 		 } else { // non teamid binary needs to be the same for app slices
3271 		 	if (oblob->csb_platform_binary ||
3272 				oblob->csb_teamid != NULL) {
3273 				vnode_unlock(vp);
3274 				error = EALREADY;
3275 				goto out;
3276 			}
3277 		 }
3278 
3279 		 oblob_start_offset = (oblob->csb_base_offset +
3280 				       oblob->csb_start_offset);
3281 		 oblob_end_offset = (oblob->csb_base_offset +
3282 				     oblob->csb_end_offset);
3283 		 if (blob_start_offset >= oblob_end_offset ||
3284 		     blob_end_offset <= oblob_start_offset) {
3285 			 /* no conflict with this existing blob */
3286 		 } else {
3287 			 /* conflict ! */
3288 			 if (blob_start_offset == oblob_start_offset &&
3289 			     blob_end_offset == oblob_end_offset &&
3290 			     blob->csb_mem_size == oblob->csb_mem_size &&
3291 			     blob->csb_flags == oblob->csb_flags &&
3292 			     (blob->csb_cpu_type == CPU_TYPE_ANY ||
3293 			      oblob->csb_cpu_type == CPU_TYPE_ANY ||
3294 			      blob->csb_cpu_type == oblob->csb_cpu_type) &&
3295 			     !bcmp(blob->csb_cdhash,
3296 				   oblob->csb_cdhash,
3297 				   CS_CDHASH_LEN)) {
3298 				 /*
3299 				  * We already have this blob:
3300 				  * we'll return success but
3301 				  * throw away the new blob.
3302 				  */
3303 				 if (oblob->csb_cpu_type == CPU_TYPE_ANY) {
3304 					 /*
3305 					  * The old blob matches this one
3306 					  * but doesn't have any CPU type.
3307 					  * Update it with whatever the caller
3308 					  * provided this time.
3309 					  */
3310 					 oblob->csb_cpu_type = cputype;
3311 				 }
3312 				 vnode_unlock(vp);
3313 				 if (ret_blob)
3314 					 *ret_blob = oblob;
3315 				 error = EAGAIN;
3316 				 goto out;
3317 			 } else {
3318 				 /* different blob: reject the new one */
3319 				 vnode_unlock(vp);
3320 				 error = EALREADY;
3321 				 goto out;
3322 			 }
3323 		 }
3324 
3325 	}
3326 
3327 
3328 	/* mark this vnode's VM object as having "signed pages" */
3329 	kr = memory_object_signed(uip->ui_control, TRUE);
3330 	if (kr != KERN_SUCCESS) {
3331 		vnode_unlock(vp);
3332 		error = ENOENT;
3333 		goto out;
3334 	}
3335 
3336 	if (uip->cs_blobs == NULL) {
3337 		/* loading 1st blob: record the file's current "modify time" */
3338 		record_mtime = TRUE;
3339 	}
3340 
3341 	/* set the generation count for cs_blobs */
3342 	uip->cs_add_gen = cs_blob_generation_count;
3343 
3344 	/*
3345 	 * Add this blob to the list of blobs for this vnode.
3346 	 * We always add at the front of the list and we never remove a
3347 	 * blob from the list, so ubc_cs_get_blobs() can return whatever
3348 	 * the top of the list was and that list will remain valid
3349 	 * while we validate a page, even after we release the vnode's lock.
3350 	 */
3351 	blob->csb_next = uip->cs_blobs;
3352 	uip->cs_blobs = blob;
3353 
3354 	OSAddAtomic(+1, &cs_blob_count);
3355 	if (cs_blob_count > cs_blob_count_peak) {
3356 		cs_blob_count_peak = cs_blob_count; /* XXX atomic ? */
3357 	}
3358 	OSAddAtomic((SInt32) +blob->csb_mem_size, &cs_blob_size);
3359 	if ((SInt32) cs_blob_size > cs_blob_size_peak) {
3360 		cs_blob_size_peak = (SInt32) cs_blob_size; /* XXX atomic ? */
3361 	}
3362 	if ((UInt32) blob->csb_mem_size > cs_blob_size_max) {
3363 		cs_blob_size_max = (UInt32) blob->csb_mem_size;
3364 	}
3365 
3366 	if (cs_debug > 1) {
3367 		proc_t p;
3368 		const char *name = vnode_getname_printable(vp);
3369 		p = current_proc();
3370 		printf("CODE SIGNING: proc %d(%s) "
3371 		       "loaded %s signatures for file (%s) "
3372 		       "range 0x%llx:0x%llx flags 0x%x\n",
3373 		       p->p_pid, p->p_comm,
3374 		       blob->csb_cpu_type == -1 ? "detached" : "embedded",
3375 		       name,
3376 		       blob->csb_base_offset + blob->csb_start_offset,
3377 		       blob->csb_base_offset + blob->csb_end_offset,
3378 		       blob->csb_flags);
3379 		vnode_putname_printable(name);
3380 	}
3381 
3382 	vnode_unlock(vp);
3383 
3384 	if (record_mtime) {
3385 		vnode_mtime(vp, &uip->cs_mtime, vfs_context_current());
3386 	}
3387 
3388 	if (ret_blob)
3389 		*ret_blob = blob;
3390 
3391 	error = 0;	/* success ! */
3392 
3393 out:
3394 	if (error) {
3395 		if (cs_debug)
3396 			printf("check_signature[pid: %d]: error = %d\n", current_proc()->p_pid, error);
3397 
3398 		/* we failed; release what we allocated */
3399 		if (blob) {
3400 			if (blob->csb_mem_kaddr) {
3401 				ubc_cs_blob_deallocate(blob->csb_mem_kaddr, blob->csb_mem_size);
3402 				blob->csb_mem_kaddr = 0;
3403 			}
3404 			if (blob->csb_entitlements != NULL) {
3405 				osobject_release(blob->csb_entitlements);
3406 				blob->csb_entitlements = NULL;
3407 			}
3408 			kfree(blob, sizeof (*blob));
3409 			blob = NULL;
3410 		}
3411 	}
3412 
3413 	if (error == EAGAIN) {
3414 		/*
3415 		 * See above:  error is EAGAIN if we were asked
3416 		 * to add an existing blob again.  We cleaned the new
3417 		 * blob and we want to return success.
3418 		 */
3419 		error = 0;
3420 	}
3421 
3422 	return error;
3423 }
3424 
3425 void
csvnode_print_debug(struct vnode *vp)3426 csvnode_print_debug(struct vnode *vp)
3427 {
3428 	const char	*name = NULL;
3429 	struct ubc_info	*uip;
3430 	struct cs_blob *blob;
3431 
3432 	name = vnode_getname_printable(vp);
3433 	if (name) {
3434 		printf("csvnode: name: %s\n", name);
3435 		vnode_putname_printable(name);
3436 	}
3437 
3438 	vnode_lock_spin(vp);
3439 
3440 	if (! UBCINFOEXISTS(vp)) {
3441 		blob = NULL;
3442 		goto out;
3443 	}
3444 
3445 	uip = vp->v_ubcinfo;
3446 	for (blob = uip->cs_blobs; blob != NULL; blob = blob->csb_next) {
3447 		printf("csvnode: range: %lu -> %lu flags: 0x%08x platform: %s path: %s team: %s\n",
3448 		       (unsigned long)blob->csb_start_offset,
3449 		       (unsigned long)blob->csb_end_offset,
3450 		       blob->csb_flags,
3451 		       blob->csb_platform_binary ? "yes" : "no",
3452 		       blob->csb_platform_path ? "yes" : "no",
3453 		       blob->csb_teamid ? blob->csb_teamid : "<NO-TEAM>");
3454 	}
3455 
3456 out:
3457 	vnode_unlock(vp);
3458 
3459 }
3460 
3461 struct cs_blob *
ubc_cs_blob_get( struct vnode *vp, cpu_type_t cputype, off_t offset)3462 ubc_cs_blob_get(
3463 	struct vnode	*vp,
3464 	cpu_type_t	cputype,
3465 	off_t		offset)
3466 {
3467 	struct ubc_info	*uip;
3468 	struct cs_blob	*blob;
3469 	off_t offset_in_blob;
3470 
3471 	vnode_lock_spin(vp);
3472 
3473 	if (! UBCINFOEXISTS(vp)) {
3474 		blob = NULL;
3475 		goto out;
3476 	}
3477 
3478 	uip = vp->v_ubcinfo;
3479 	for (blob = uip->cs_blobs;
3480 	     blob != NULL;
3481 	     blob = blob->csb_next) {
3482 		if (cputype != -1 && blob->csb_cpu_type == cputype) {
3483 			break;
3484 		}
3485 		if (offset != -1) {
3486 			offset_in_blob = offset - blob->csb_base_offset;
3487 			if (offset_in_blob >= blob->csb_start_offset &&
3488 			    offset_in_blob < blob->csb_end_offset) {
3489 				/* our offset is covered by this blob */
3490 				break;
3491 			}
3492 		}
3493 	}
3494 
3495 out:
3496 	vnode_unlock(vp);
3497 
3498 	return blob;
3499 }
3500 
3501 static void
ubc_cs_free( struct ubc_info *uip)3502 ubc_cs_free(
3503 	struct ubc_info	*uip)
3504 {
3505 	struct cs_blob	*blob, *next_blob;
3506 
3507 	for (blob = uip->cs_blobs;
3508 	     blob != NULL;
3509 	     blob = next_blob) {
3510 		next_blob = blob->csb_next;
3511 		if (blob->csb_mem_kaddr != 0) {
3512 			ubc_cs_blob_deallocate(blob->csb_mem_kaddr,
3513 					       blob->csb_mem_size);
3514 			blob->csb_mem_kaddr = 0;
3515 		}
3516 		if (blob->csb_entitlements != NULL) {
3517 			osobject_release(blob->csb_entitlements);
3518 			blob->csb_entitlements = NULL;
3519 		}
3520 		OSAddAtomic(-1, &cs_blob_count);
3521 		OSAddAtomic((SInt32) -blob->csb_mem_size, &cs_blob_size);
3522 		kfree(blob, sizeof (*blob));
3523 	}
3524 #if CHECK_CS_VALIDATION_BITMAP
3525 	ubc_cs_validation_bitmap_deallocate( uip->ui_vnode );
3526 #endif
3527 	uip->cs_blobs = NULL;
3528 }
3529 
3530 /* check cs blob generation on vnode
3531  * returns:
3532  *    0         : Success, the cs_blob attached is current
3533  *    ENEEDAUTH : Generation count mismatch. Needs authentication again.
3534  */
3535 int
ubc_cs_generation_check( struct vnode *vp)3536 ubc_cs_generation_check(
3537 	struct vnode	*vp)
3538 {
3539 	int retval = ENEEDAUTH;
3540 
3541 	vnode_lock_spin(vp);
3542 
3543 	if (UBCINFOEXISTS(vp) && vp->v_ubcinfo->cs_add_gen == cs_blob_generation_count) {
3544 		retval = 0;
3545 	}
3546 
3547 	vnode_unlock(vp);
3548 	return retval;
3549 }
3550 
3551 int
ubc_cs_blob_revalidate( struct vnode *vp, struct cs_blob *blob, struct image_params *imgp, int flags )3552 ubc_cs_blob_revalidate(
3553 	struct vnode	*vp,
3554 	struct cs_blob *blob,
3555 	struct image_params *imgp,
3556 	int flags
3557 	)
3558 {
3559 	int error = 0;
3560 	const CS_CodeDirectory *cd = NULL;
3561 	const CS_GenericBlob *entitlements = NULL;
3562 	size_t size;
3563 	assert(vp != NULL);
3564 	assert(blob != NULL);
3565 
3566 	size = blob->csb_mem_size;
3567 	error = cs_validate_csblob((const uint8_t *)blob->csb_mem_kaddr,
3568 				   &size, &cd, &entitlements);
3569 	if (error) {
3570 		if (cs_debug) {
3571 			printf("CODESIGNING: csblob invalid: %d\n", error);
3572 		}
3573 		goto out;
3574 	}
3575 	assert(size == blob->csb_mem_size);
3576 
3577     unsigned int cs_flags = (ntohl(cd->flags) & CS_ALLOWED_MACHO) | CS_VALID;
3578 
3579 	/* callout to mac_vnode_check_signature */
3580 #if CONFIG_MACF
3581 	error = mac_vnode_check_signature(vp, blob, imgp, &cs_flags, flags);
3582 	if (cs_debug && error) {
3583 			printf("revalidate: check_signature[pid: %d], error = %d\n", current_proc()->p_pid, error);
3584 	}
3585 #else
3586 	(void)flags;
3587 #endif
3588 
3589 	/* update generation number if success */
3590 	vnode_lock_spin(vp);
3591     blob->csb_flags = cs_flags;
3592 	if (UBCINFOEXISTS(vp)) {
3593 		if (error == 0)
3594 			vp->v_ubcinfo->cs_add_gen = cs_blob_generation_count;
3595 		else
3596 			vp->v_ubcinfo->cs_add_gen = 0;
3597 	}
3598 
3599 	vnode_unlock(vp);
3600 
3601 out:
3602 	return error;
3603 }
3604 
3605 void
cs_blob_reset_cachenull3606 cs_blob_reset_cache()
3607 {
3608 	/* incrementing odd no by 2 makes sure '0' is never reached. */
3609 	OSAddAtomic(+2, &cs_blob_generation_count);
3610 	printf("Reseting cs_blob cache from all vnodes. \n");
3611 }
3612 
3613 struct cs_blob *
ubc_get_cs_blobs( struct vnode *vp)3614 ubc_get_cs_blobs(
3615 	struct vnode	*vp)
3616 {
3617 	struct ubc_info	*uip;
3618 	struct cs_blob	*blobs;
3619 
3620 	/*
3621 	 * No need to take the vnode lock here.  The caller must be holding
3622 	 * a reference on the vnode (via a VM mapping or open file descriptor),
3623 	 * so the vnode will not go away.  The ubc_info stays until the vnode
3624 	 * goes away.  And we only modify "blobs" by adding to the head of the
3625 	 * list.
3626 	 * The ubc_info could go away entirely if the vnode gets reclaimed as
3627 	 * part of a forced unmount.  In the case of a code-signature validation
3628 	 * during a page fault, the "paging_in_progress" reference on the VM
3629 	 * object guarantess that the vnode pager (and the ubc_info) won't go
3630 	 * away during the fault.
3631 	 * Other callers need to protect against vnode reclaim by holding the
3632 	 * vnode lock, for example.
3633 	 */
3634 
3635 	if (! UBCINFOEXISTS(vp)) {
3636 		blobs = NULL;
3637 		goto out;
3638 	}
3639 
3640 	uip = vp->v_ubcinfo;
3641 	blobs = uip->cs_blobs;
3642 
3643 out:
3644 	return blobs;
3645 }
3646 
3647 void
ubc_get_cs_mtime( struct vnode *vp, struct timespec *cs_mtime)3648 ubc_get_cs_mtime(
3649 	struct vnode	*vp,
3650 	struct timespec	*cs_mtime)
3651 {
3652 	struct ubc_info	*uip;
3653 
3654 	if (! UBCINFOEXISTS(vp)) {
3655 		cs_mtime->tv_sec = 0;
3656 		cs_mtime->tv_nsec = 0;
3657 		return;
3658 	}
3659 
3660 	uip = vp->v_ubcinfo;
3661 	cs_mtime->tv_sec = uip->cs_mtime.tv_sec;
3662 	cs_mtime->tv_nsec = uip->cs_mtime.tv_nsec;
3663 }
3664 
3665 unsigned long cs_validate_page_no_hash = 0;
3666 unsigned long cs_validate_page_bad_hash = 0;
3667 static boolean_t
cs_validate_hash( struct cs_blob *blobs, memory_object_t pager, memory_object_offset_t page_offset, const void *data, vm_size_t *bytes_processed, unsigned *tainted)3668 cs_validate_hash(
3669 	struct cs_blob		*blobs,
3670 	memory_object_t		pager,
3671 	memory_object_offset_t	page_offset,
3672 	const void		*data,
3673 	vm_size_t		*bytes_processed,
3674 	unsigned		*tainted)
3675 {
3676 	union cs_hash_union	mdctx;
3677 	struct cs_hash const	*hashtype = NULL;
3678 	unsigned char		actual_hash[CS_HASH_MAX_SIZE];
3679 	unsigned char		expected_hash[CS_HASH_MAX_SIZE];
3680 	boolean_t		found_hash;
3681 	struct cs_blob		*blob;
3682 	const CS_CodeDirectory	*cd;
3683 	const unsigned char	*hash;
3684 	boolean_t		validated;
3685 	off_t			offset;	/* page offset in the file */
3686 	size_t			size;
3687 	off_t			codeLimit = 0;
3688 	const char		*lower_bound, *upper_bound;
3689 	vm_offset_t		kaddr, blob_addr;
3690 
3691 	/* retrieve the expected hash */
3692 	found_hash = FALSE;
3693 
3694 	for (blob = blobs;
3695 	     blob != NULL;
3696 	     blob = blob->csb_next) {
3697 		offset = page_offset - blob->csb_base_offset;
3698 		if (offset < blob->csb_start_offset ||
3699 		    offset >= blob->csb_end_offset) {
3700 			/* our page is not covered by this blob */
3701 			continue;
3702 		}
3703 
3704 		/* blob data has been released */
3705 		kaddr = blob->csb_mem_kaddr;
3706 		if (kaddr == 0) {
3707 			continue;
3708 		}
3709 
3710 		blob_addr = kaddr + blob->csb_mem_offset;
3711 		lower_bound = CAST_DOWN(char *, blob_addr);
3712 		upper_bound = lower_bound + blob->csb_mem_size;
3713 
3714 		cd = blob->csb_cd;
3715 		if (cd != NULL) {
3716 			/* all CD's that have been injected is already validated */
3717 
3718 			hashtype = blob->csb_hashtype;
3719 			if (hashtype == NULL)
3720 				panic("unknown hash type ?");
3721 			if (hashtype->cs_digest_size > sizeof(actual_hash))
3722 				panic("hash size too large");
3723 			if (offset & blob->csb_hash_pagemask)
3724 				panic("offset not aligned to cshash boundary");
3725 
3726 			codeLimit = ntohl(cd->codeLimit);
3727 
3728 			hash = hashes(cd, (uint32_t)(offset>>blob->csb_hash_pageshift),
3729 				      hashtype->cs_size,
3730 				      lower_bound, upper_bound);
3731 			if (hash != NULL) {
3732 				bcopy(hash, expected_hash, hashtype->cs_size);
3733 				found_hash = TRUE;
3734 			}
3735 
3736 			break;
3737 		}
3738 	}
3739 
3740 	if (found_hash == FALSE) {
3741 		/*
3742 		 * We can't verify this page because there is no signature
3743 		 * for it (yet).  It's possible that this part of the object
3744 		 * is not signed, or that signatures for that part have not
3745 		 * been loaded yet.
3746 		 * Report that the page has not been validated and let the
3747 		 * caller decide if it wants to accept it or not.
3748 		 */
3749 		cs_validate_page_no_hash++;
3750 		if (cs_debug > 1) {
3751 			printf("CODE SIGNING: cs_validate_page: "
3752 			       "mobj %p off 0x%llx: no hash to validate !?\n",
3753 			       pager, page_offset);
3754 		}
3755 		validated = FALSE;
3756 		*tainted = 0;
3757 	} else {
3758 
3759 		*tainted = 0;
3760 
3761 		size = blob->csb_hash_pagesize;
3762 		*bytes_processed = size;
3763 
3764 		const uint32_t *asha1, *esha1;
3765 		if ((off_t)(offset + size) > codeLimit) {
3766 			/* partial page at end of segment */
3767 			assert(offset < codeLimit);
3768 			size = (size_t) (codeLimit & blob->csb_hash_pagemask);
3769 			*tainted |= CS_VALIDATE_NX;
3770 		}
3771 
3772 		hashtype->cs_init(&mdctx);
3773 
3774 		if (blob->csb_hash_firstlevel_pagesize) {
3775 			const unsigned char *partial_data = (const unsigned char *)data;
3776 			size_t i;
3777 			for (i=0; i < size;) {
3778 				union cs_hash_union	partialctx;
3779 				unsigned char partial_digest[CS_HASH_MAX_SIZE];
3780 				size_t partial_size = MIN(size-i, blob->csb_hash_firstlevel_pagesize);
3781 
3782 				hashtype->cs_init(&partialctx);
3783 				hashtype->cs_update(&partialctx, partial_data, partial_size);
3784 				hashtype->cs_final(partial_digest, &partialctx);
3785 
3786 				/* Update cumulative multi-level hash */
3787 				hashtype->cs_update(&mdctx, partial_digest, hashtype->cs_size);
3788 				partial_data = partial_data + partial_size;
3789 				i += partial_size;
3790 			}
3791 		} else {
3792 			hashtype->cs_update(&mdctx, data, size);
3793 		}
3794 		hashtype->cs_final(actual_hash, &mdctx);
3795 
3796 		asha1 = (const uint32_t *) actual_hash;
3797 		esha1 = (const uint32_t *) expected_hash;
3798 
3799 		if (bcmp(expected_hash, actual_hash, hashtype->cs_size) != 0) {
3800 			if (cs_debug) {
3801 				printf("CODE SIGNING: cs_validate_page: "
3802 				       "mobj %p off 0x%llx size 0x%lx: "
3803 				       "actual [0x%x 0x%x 0x%x 0x%x 0x%x] != "
3804 				       "expected [0x%x 0x%x 0x%x 0x%x 0x%x]\n",
3805 				       pager, page_offset, size,
3806 				       asha1[0], asha1[1], asha1[2],
3807 				       asha1[3], asha1[4],
3808 				       esha1[0], esha1[1], esha1[2],
3809 				       esha1[3], esha1[4]);
3810 			}
3811 			cs_validate_page_bad_hash++;
3812 			*tainted |= CS_VALIDATE_TAINTED;
3813 		} else {
3814 			if (cs_debug > 10) {
3815 				printf("CODE SIGNING: cs_validate_page: "
3816 				       "mobj %p off 0x%llx size 0x%lx: "
3817 				       "SHA1 OK\n",
3818 				       pager, page_offset, size);
3819 			}
3820 		}
3821 		validated = TRUE;
3822 	}
3823 
3824 	return validated;
3825 }
3826 
3827 boolean_t
cs_validate_range( struct vnode *vp, memory_object_t pager, memory_object_offset_t page_offset, const void *data, vm_size_t dsize, unsigned *tainted)3828 cs_validate_range(
3829 	struct vnode	*vp,
3830 	memory_object_t		pager,
3831 	memory_object_offset_t	page_offset,
3832 	const void		*data,
3833 	vm_size_t		dsize,
3834 	unsigned		*tainted)
3835 {
3836 	vm_size_t offset_in_range;
3837 	boolean_t all_subranges_validated = TRUE; /* turn false if any subrange fails */
3838 
3839 	struct cs_blob *blobs = ubc_get_cs_blobs(vp);
3840 
3841 	*tainted = 0;
3842 
3843 	for (offset_in_range = 0;
3844 		 offset_in_range < dsize;
3845 		 /* offset_in_range updated based on bytes processed */) {
3846 		unsigned subrange_tainted = 0;
3847 		boolean_t subrange_validated;
3848 		vm_size_t bytes_processed = 0;
3849 
3850 		subrange_validated = cs_validate_hash(blobs,
3851 											  pager,
3852 											  page_offset + offset_in_range,
3853 											  (const void *)((const char *)data + offset_in_range),
3854 											  &bytes_processed,
3855 											  &subrange_tainted);
3856 
3857 		*tainted |= subrange_tainted;
3858 
3859 		if (bytes_processed == 0) {
3860 			/* Cannote make forward progress, so return an error */
3861 			all_subranges_validated = FALSE;
3862 			break;
3863 		} else if (subrange_validated == FALSE) {
3864 			all_subranges_validated = FALSE;
3865 			/* Keep going to detect other types of failures in subranges */
3866 		}
3867 
3868 		offset_in_range += bytes_processed;
3869 	}
3870 
3871 	return all_subranges_validated;
3872 }
3873 
3874 int
ubc_cs_getcdhash( vnode_t vp, off_t offset, unsigned char *cdhash)3875 ubc_cs_getcdhash(
3876 	vnode_t		vp,
3877 	off_t		offset,
3878 	unsigned char	*cdhash)
3879 {
3880 	struct cs_blob	*blobs, *blob;
3881 	off_t		rel_offset;
3882 	int		ret;
3883 
3884 	vnode_lock(vp);
3885 
3886 	blobs = ubc_get_cs_blobs(vp);
3887 	for (blob = blobs;
3888 	     blob != NULL;
3889 	     blob = blob->csb_next) {
3890 		/* compute offset relative to this blob */
3891 		rel_offset = offset - blob->csb_base_offset;
3892 		if (rel_offset >= blob->csb_start_offset &&
3893 		    rel_offset < blob->csb_end_offset) {
3894 			/* this blob does cover our "offset" ! */
3895 			break;
3896 		}
3897 	}
3898 
3899 	if (blob == NULL) {
3900 		/* we didn't find a blob covering "offset" */
3901 		ret = EBADEXEC; /* XXX any better error ? */
3902 	} else {
3903 		/* get the SHA1 hash of that blob */
3904 		bcopy(blob->csb_cdhash, cdhash, sizeof (blob->csb_cdhash));
3905 		ret = 0;
3906 	}
3907 
3908 	vnode_unlock(vp);
3909 
3910 	return ret;
3911 }
3912 
3913 boolean_t
ubc_cs_is_range_codesigned( vnode_t vp, mach_vm_offset_t start, mach_vm_size_t size)3914 ubc_cs_is_range_codesigned(
3915 	vnode_t			vp,
3916 	mach_vm_offset_t	start,
3917 	mach_vm_size_t		size)
3918 {
3919 	struct cs_blob		*csblob;
3920 	mach_vm_offset_t	blob_start;
3921 	mach_vm_offset_t	blob_end;
3922 
3923 	if (vp == NULL) {
3924 		/* no file: no code signature */
3925 		return FALSE;
3926 	}
3927 	if (size == 0) {
3928 		/* no range: no code signature */
3929 		return FALSE;
3930 	}
3931 	if (start + size < start) {
3932 		/* overflow */
3933 		return FALSE;
3934 	}
3935 
3936 	csblob = ubc_cs_blob_get(vp, -1, start);
3937 	if (csblob == NULL) {
3938 		return FALSE;
3939 	}
3940 
3941 	/*
3942 	 * We currently check if the range is covered by a single blob,
3943 	 * which should always be the case for the dyld shared cache.
3944 	 * If we ever want to make this routine handle other cases, we
3945 	 * would have to iterate if the blob does not cover the full range.
3946 	 */
3947 	blob_start = (mach_vm_offset_t) (csblob->csb_base_offset +
3948 					 csblob->csb_start_offset);
3949 	blob_end = (mach_vm_offset_t) (csblob->csb_base_offset +
3950 				       csblob->csb_end_offset);
3951 	if (blob_start > start || blob_end < (start + size)) {
3952 		/* range not fully covered by this code-signing blob */
3953 		return FALSE;
3954 	}
3955 
3956 	return TRUE;
3957 }
3958 
3959 #if CHECK_CS_VALIDATION_BITMAP
3960 #define stob(s)	((atop_64((s)) + 07) >> 3)
3961 extern	boolean_t	root_fs_upgrade_try;
3962 
3963 /*
3964  * Should we use the code-sign bitmap to avoid repeated code-sign validation?
3965  * Depends:
3966  * a) Is the target vnode on the root filesystem?
3967  * b) Has someone tried to mount the root filesystem read-write?
3968  * If answers are (a) yes AND (b) no, then we can use the bitmap.
3969  */
3970 #define USE_CODE_SIGN_BITMAP(vp)	( (vp != NULL) && (vp->v_mount != NULL) && (vp->v_mount->mnt_flag & MNT_ROOTFS) && !root_fs_upgrade_try)
3971 kern_return_t
ubc_cs_validation_bitmap_allocate( vnode_t vp)3972 ubc_cs_validation_bitmap_allocate(
3973 	vnode_t		vp)
3974 {
3975 	kern_return_t	kr = KERN_SUCCESS;
3976 	struct ubc_info *uip;
3977 	char		*target_bitmap;
3978 	vm_object_size_t	bitmap_size;
3979 
3980 	if ( ! USE_CODE_SIGN_BITMAP(vp) || (! UBCINFOEXISTS(vp))) {
3981 		kr = KERN_INVALID_ARGUMENT;
3982 	} else {
3983 		uip = vp->v_ubcinfo;
3984 
3985 		if ( uip->cs_valid_bitmap == NULL ) {
3986 			bitmap_size = stob(uip->ui_size);
3987 			target_bitmap = (char*) kalloc( (vm_size_t)bitmap_size );
3988 			if (target_bitmap == 0) {
3989 				kr = KERN_NO_SPACE;
3990 			} else {
3991 				kr = KERN_SUCCESS;
3992 			}
3993 			if( kr == KERN_SUCCESS ) {
3994 				memset( target_bitmap, 0, (size_t)bitmap_size);
3995 				uip->cs_valid_bitmap = (void*)target_bitmap;
3996 				uip->cs_valid_bitmap_size = bitmap_size;
3997 			}
3998 		}
3999 	}
4000 	return kr;
4001 }
4002 
4003 kern_return_t
ubc_cs_check_validation_bitmap( vnode_t vp, memory_object_offset_t offset, int optype)4004 ubc_cs_check_validation_bitmap (
4005 	vnode_t			vp,
4006 	memory_object_offset_t		offset,
4007 	int			optype)
4008 {
4009 	kern_return_t