xref: /xnu-8019.80.24/security/mac_vfs.c (revision a325d9c4a84054e40bbe985afedcb50ab80993ea)
1 /*
2  * Copyright (c) 2007-2016 Apple Inc. All rights reserved.
3  *
4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5  *
6  * This file contains Original Code and/or Modifications of Original Code
7  * as defined in and that are subject to the Apple Public Source License
8  * Version 2.0 (the 'License'). You may not use this file except in
9  * compliance with the License. The rights granted to you under the License
10  * may not be used to create, or enable the creation or redistribution of,
11  * unlawful or unlicensed copies of an Apple operating system, or to
12  * circumvent, violate, or enable the circumvention or violation of, any
13  * terms of an Apple operating system software license agreement.
14  *
15  * Please obtain a copy of the License at
16  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17  *
18  * The Original Code and all software distributed under the License are
19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23  * Please see the License for the specific language governing rights and
24  * limitations under the License.
25  *
26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27  */
28 /*-
29  * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson
30  * Copyright (c) 2001 Ilmar S. Habibulin
31  * Copyright (c) 2001, 2002, 2003, 2004 Networks Associates Technology, Inc.
32  * Copyright (c) 2005 SPARTA, Inc.
33  *
34  * This software was developed by Robert Watson and Ilmar Habibulin for the
35  * TrustedBSD Project.
36  *
37  * This software was developed for the FreeBSD Project in part by Network
38  * Associates Laboratories, the Security Research Division of Network
39  * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"),
40  * as part of the DARPA CHATS research program.
41  *
42  * Redistribution and use in source and binary forms, with or without
43  * modification, are permitted provided that the following conditions
44  * are met:
45  * 1. Redistributions of source code must retain the above copyright
46  *    notice, this list of conditions and the following disclaimer.
47  * 2. Redistributions in binary form must reproduce the above copyright
48  *    notice, this list of conditions and the following disclaimer in the
49  *    documentation and/or other materials provided with the distribution.
50  *
51  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
52  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
53  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
54  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
55  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
56  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
57  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
58  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
59  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
60  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
61  * SUCH DAMAGE.
62  *
63  */
64 
65 #include <kern/kalloc.h>
66 #include <libkern/OSAtomic.h>
67 
68 #include <sys/param.h>
69 #include <sys/systm.h>
70 #include <sys/kernel.h>
71 #include <sys/proc.h>
72 #include <sys/kauth.h>
73 
74 #include <sys/file_internal.h>
75 #include <sys/imgact.h>
76 #include <sys/namei.h>
77 #include <sys/mount_internal.h>
78 #include <sys/pipe.h>
79 #include <sys/posix_sem.h>
80 #include <sys/posix_shm.h>
81 #include <sys/reason.h>
82 #include <sys/uio_internal.h>
83 #include <sys/vnode_internal.h>
84 #include <sys/kdebug.h>
85 
86 
87 #include <miscfs/devfs/devfsdefs.h>
88 #include <miscfs/devfs/fdesc.h>
89 
90 #include <security/mac_internal.h>
91 
92 /* convert {R,W,X}_OK values to V{READ,WRITE,EXEC} */
93 #define ACCESS_MODE_TO_VNODE_MASK(m)    (m << 6)
94 
95 
96 /*
97  * Optional tracing of policy operations. Define VFS_TRACE_POLICY_OPS to trace the operations.
98  *
99  * Along with DBG_FSYSTEM and DBG_VFS, dcode in the macros below is used to construct
100  * KDBG_EVENTID(DBG_FSYSTEM, DBG_VFS, dcode) global event id, see bsd/sys/kdebug.h.
101  * Note that dcode is multiplied by 4 and ORed as part of the construction. See bsd/kern/trace_codes
102  * for list of system-wide {global event id, name} pairs. Currently DBG_VFS event ids are in range
103  * [0x3130000, 0x3130184].
104  */
105 
106 //#define VFS_TRACE_POLICY_OPS
107 
108 #ifdef VFS_TRACE_POLICY_OPS
109 #define DBG_VFS_CODE(dcode)                     FSDBG_CODE(DBG_VFS, dcode)
110 #define VFS_KERNEL_DEBUG_START0(dcode)          KERNEL_DEBUG_CONSTANT(DBG_VFS_CODE(dcode) | DBG_FUNC_START, 0, 0, 0, 0, 0)
111 #define VFS_KERNEL_DEBUG_END0(dcode)            KERNEL_DEBUG_CONSTANT(DBG_VFS_CODE(dcode) | DBG_FUNC_END, 0, 0, 0, 0, 0)
112 #define VFS_KERNEL_DEBUG_START1(dcode, darg)    KERNEL_DEBUG_CONSTANT(DBG_VFS_CODE(dcode) | DBG_FUNC_START, darg, 0, 0, 0, 0)
113 #define VFS_KERNEL_DEBUG_END1(dcode, darg)      KERNEL_DEBUG_CONSTANT(DBG_VFS_CODE(dcode) | DBG_FUNC_END, darg, 0, 0, 0, 0)
114 #else
115 #define VFS_KERNEL_DEBUG_START0(dcode)          do {} while (0)
116 #define VFS_KERNEL_DEBUG_END0(dcode)            do {} while (0)
117 #define VFS_KERNEL_DEBUG_START1(dcode, darg)    do {} while (0)
118 #define VFS_KERNEL_DEBUG_END1(dcode, darg)      do {} while (0)
119 #endif
120 
121 void
mac_devfs_label_init(struct devnode * de)122 mac_devfs_label_init(struct devnode *de)
123 {
124 	mac_labelzone_alloc_owned(&de->dn_label, MAC_WAITOK, ^(struct label *label) {
125 		VFS_KERNEL_DEBUG_START0(0);
126 		MAC_PERFORM(devfs_label_init, label);
127 		VFS_KERNEL_DEBUG_END0(0);
128 	});
129 }
130 
131 struct label *
mac_devfs_label(struct devnode * de)132 mac_devfs_label(struct devnode *de)
133 {
134 	return mac_label_verify(&de->dn_label);
135 }
136 
137 void
mac_devfs_label_destroy(struct devnode * de)138 mac_devfs_label_destroy(struct devnode *de)
139 {
140 	mac_labelzone_free_owned(&de->dn_label, ^(struct label *label) {
141 		VFS_KERNEL_DEBUG_START1(3, label);
142 		MAC_PERFORM(devfs_label_destroy, label);
143 		VFS_KERNEL_DEBUG_END1(3, label);
144 	});
145 }
146 
147 void
mac_mount_label_init(struct mount * mp)148 mac_mount_label_init(struct mount *mp)
149 {
150 	mac_labelzone_alloc_owned(&mp->mnt_mntlabel, MAC_WAITOK, ^(struct label *label) {
151 		VFS_KERNEL_DEBUG_START0(1);
152 		MAC_PERFORM(mount_label_init, label);
153 		VFS_KERNEL_DEBUG_END0(1);
154 	});
155 }
156 
157 struct label *
mac_mount_label(struct mount * mp)158 mac_mount_label(struct mount *mp)
159 {
160 	return mac_label_verify(&mp->mnt_mntlabel);
161 }
162 
163 void
mac_mount_label_destroy(struct mount * mp)164 mac_mount_label_destroy(struct mount *mp)
165 {
166 	mac_labelzone_free_owned(&mp->mnt_mntlabel, ^(struct label *label) {
167 		VFS_KERNEL_DEBUG_START1(4, label);
168 		MAC_PERFORM(mount_label_destroy, label);
169 		VFS_KERNEL_DEBUG_END1(4, label);
170 	});
171 }
172 
173 struct label *
mac_vnode_label_alloc(vnode_t vp)174 mac_vnode_label_alloc(vnode_t vp)
175 {
176 	return mac_labelzone_alloc_for_owner(vp ? &vp->v_label : NULL, MAC_WAITOK, ^(struct label *label) {
177 		VFS_KERNEL_DEBUG_START0(2);
178 		MAC_PERFORM(vnode_label_init, label);
179 		VFS_KERNEL_DEBUG_END0(2);
180 		OSIncrementAtomic(&mac_vnode_label_count);
181 	});
182 }
183 
184 void
mac_vnode_label_init(vnode_t vp)185 mac_vnode_label_init(vnode_t vp)
186 {
187 	struct label *label;
188 
189 	label = mac_vnode_label_alloc(vp);
190 	vp->v_label = label;
191 }
192 
193 struct label *
mac_vnode_label(vnode_t vp)194 mac_vnode_label(vnode_t vp)
195 {
196 	return mac_label_verify(&vp->v_label);
197 }
198 
199 static void
mac_vnode_label_cleanup(struct label * label)200 mac_vnode_label_cleanup(struct label *label)
201 {
202 	VFS_KERNEL_DEBUG_START1(5, label);
203 	MAC_PERFORM(vnode_label_destroy, label);
204 	VFS_KERNEL_DEBUG_END1(5, label);
205 	OSDecrementAtomic(&mac_vnode_label_count);
206 }
207 
208 void
mac_vnode_label_free(struct label * label)209 mac_vnode_label_free(struct label *label)
210 {
211 	if (label != NULL) {
212 		mac_vnode_label_cleanup(label);
213 		mac_labelzone_free(label);
214 	}
215 }
216 
217 void
mac_vnode_label_destroy(struct vnode * vp)218 mac_vnode_label_destroy(struct vnode *vp)
219 {
220 	mac_labelzone_free_owned(&vp->v_label, ^(struct label *label) {
221 		mac_vnode_label_cleanup(label);
222 	});
223 }
224 
225 int
mac_vnode_label_init_needed(vnode_t vp)226 mac_vnode_label_init_needed(vnode_t vp)
227 {
228 #if CONFIG_MACF_LAZY_VNODE_LABELS
229 	(void)vp;
230 	return false;
231 #else
232 	return mac_label_vnodes != 0 && mac_vnode_label(vp) == NULL;
233 #endif
234 }
235 
236 struct label *
mac_vnode_label_allocate(vnode_t vp)237 mac_vnode_label_allocate(vnode_t vp)
238 {
239 	if (mac_vnode_label_init_needed(vp)) {
240 		mac_vnode_label_init(vp);
241 	}
242 	return mac_vnode_label(vp);
243 }
244 
245 /*
246  * vnode labels are allocated at the same time as vnodes, but vnodes are never
247  * freed.  Instead, we want to remove any sensitive information before putting
248  * them on the free list for reuse.
249  */
250 void
mac_vnode_label_recycle(vnode_t vp)251 mac_vnode_label_recycle(vnode_t vp)
252 {
253 	struct label *v_label = mac_vnode_label(vp);
254 
255 	MAC_PERFORM(vnode_label_recycle, v_label);
256 #if CONFIG_MACF_LAZY_VNODE_LABELS
257 	if (v_label) {
258 		mac_vnode_label_destroy(vp);
259 		vp->v_lflag &= ~VL_LABELED;
260 	}
261 #endif
262 }
263 
264 void
mac_vnode_label_copy(struct label * src,struct label * dest)265 mac_vnode_label_copy(struct label *src, struct label *dest)
266 {
267 	VFS_KERNEL_DEBUG_START1(6, src);
268 	if (src == NULL) {
269 		MAC_PERFORM(vnode_label_init, dest);
270 	} else {
271 		MAC_PERFORM(vnode_label_copy, src, dest);
272 	}
273 	VFS_KERNEL_DEBUG_END1(6, src);
274 }
275 
276 int
mac_vnode_label_externalize_audit(struct vnode * vp,struct mac * mac)277 mac_vnode_label_externalize_audit(struct vnode *vp, struct mac *mac)
278 {
279 	int error;
280 
281 	/* It is assumed that any necessary vnode locking is done on entry */
282 	error = MAC_EXTERNALIZE_AUDIT(vnode, mac_vnode_label(vp),
283 	    mac->m_string, mac->m_buflen);
284 
285 	return error;
286 }
287 
288 int
mac_vnode_label_externalize(struct label * label,char * elements,char * outbuf,size_t outbuflen,int flags __unused)289 mac_vnode_label_externalize(struct label *label, char *elements,
290     char *outbuf, size_t outbuflen, int flags __unused)
291 {
292 	int error;
293 
294 	error = MAC_EXTERNALIZE(vnode, label, elements, outbuf, outbuflen);
295 
296 	return error;
297 }
298 
299 int
mac_vnode_label_internalize(struct label * label,char * string)300 mac_vnode_label_internalize(struct label *label, char *string)
301 {
302 	int error;
303 
304 	error = MAC_INTERNALIZE(vnode, label, string);
305 
306 	return error;
307 }
308 
309 int
mac_mount_label_internalize(struct label * label,char * string)310 mac_mount_label_internalize(struct label *label, char *string)
311 {
312 	int error;
313 
314 	error = MAC_INTERNALIZE(mount, label, string);
315 
316 	return error;
317 }
318 
319 int
mac_mount_label_externalize(struct label * label,char * elements,char * outbuf,size_t outbuflen)320 mac_mount_label_externalize(struct label *label, char *elements,
321     char *outbuf, size_t outbuflen)
322 {
323 	int error;
324 
325 	error = MAC_EXTERNALIZE(mount, label, elements, outbuf, outbuflen);
326 
327 	return error;
328 }
329 
330 void
mac_devfs_label_copy(struct label * src,struct label * dest)331 mac_devfs_label_copy(struct label *src, struct label *dest)
332 {
333 #if SECURITY_MAC_CHECK_ENFORCE
334 	/* 21167099 - only check if we allow write */
335 	if (!mac_device_enforce) {
336 		return;
337 	}
338 #endif
339 
340 	VFS_KERNEL_DEBUG_START1(7, src);
341 	MAC_PERFORM(devfs_label_copy, src, dest);
342 	VFS_KERNEL_DEBUG_END1(7, src);
343 }
344 
345 void
mac_devfs_label_update(struct mount * mp,struct devnode * de,struct vnode * vp)346 mac_devfs_label_update(struct mount *mp, struct devnode *de,
347     struct vnode *vp)
348 {
349 #if SECURITY_MAC_CHECK_ENFORCE
350 	/* 21167099 - only check if we allow write */
351 	if (!mac_device_enforce) {
352 		return;
353 	}
354 #endif
355 
356 	VFS_KERNEL_DEBUG_START1(8, vp);
357 	MAC_PERFORM(devfs_label_update, mp, de, mac_devfs_label(de), vp,
358 	    mac_vnode_label(vp));
359 	VFS_KERNEL_DEBUG_END1(8, vp);
360 }
361 
362 int
mac_vnode_label_associate(struct mount * mp,struct vnode * vp,vfs_context_t ctx)363 mac_vnode_label_associate(struct mount *mp, struct vnode *vp, vfs_context_t ctx)
364 {
365 	struct devnode *dnp;
366 	struct fdescnode *fnp;
367 	int error = 0;
368 
369 #if SECURITY_MAC_CHECK_ENFORCE
370 	/* 21167099 - only check if we allow write */
371 	if (!mac_vnode_enforce) {
372 		return error;
373 	}
374 #endif
375 
376 	/* XXX: should not inspect v_tag in kernel! */
377 	switch (vp->v_tag) {
378 	case VT_DEVFS:
379 		dnp = VTODN(vp);
380 		mac_vnode_label_associate_devfs(mp, dnp, vp);
381 		break;
382 	case VT_FDESC:
383 		fnp = VTOFDESC(vp);
384 		error = mac_vnode_label_associate_fdesc(mp, fnp, vp, ctx);
385 		break;
386 	default:
387 		error = mac_vnode_label_associate_extattr(mp, vp);
388 		break;
389 	}
390 
391 	return error;
392 }
393 
394 void
mac_vnode_label_associate_devfs(struct mount * mp,struct devnode * de,struct vnode * vp)395 mac_vnode_label_associate_devfs(struct mount *mp, struct devnode *de,
396     struct vnode *vp)
397 {
398 #if SECURITY_MAC_CHECK_ENFORCE
399 	/* 21167099 - only check if we allow write */
400 	if (!mac_device_enforce) {
401 		return;
402 	}
403 #endif
404 
405 	VFS_KERNEL_DEBUG_START1(9, vp);
406 	MAC_PERFORM(vnode_label_associate_devfs,
407 	    mp, mp ? mac_mount_label(mp) : NULL,
408 	    de, mac_devfs_label(de),
409 	    vp, mac_vnode_label(vp));
410 	VFS_KERNEL_DEBUG_END1(9, vp);
411 }
412 
413 int
mac_vnode_label_associate_extattr(struct mount * mp,struct vnode * vp)414 mac_vnode_label_associate_extattr(struct mount *mp, struct vnode *vp)
415 {
416 	int error;
417 
418 	VFS_KERNEL_DEBUG_START1(10, vp);
419 	MAC_CHECK(vnode_label_associate_extattr, mp, mac_mount_label(mp), vp,
420 	    mac_vnode_label(vp));
421 	VFS_KERNEL_DEBUG_END1(10, vp);
422 
423 	return error;
424 }
425 
426 void
mac_vnode_label_associate_singlelabel(struct mount * mp,struct vnode * vp)427 mac_vnode_label_associate_singlelabel(struct mount *mp, struct vnode *vp)
428 {
429 #if SECURITY_MAC_CHECK_ENFORCE
430 	/* 21167099 - only check if we allow write */
431 	if (!mac_vnode_enforce) {
432 		return;
433 	}
434 #endif
435 	if (!mac_label_vnodes) {
436 		return;
437 	}
438 
439 	VFS_KERNEL_DEBUG_START1(11, vp);
440 	MAC_PERFORM(vnode_label_associate_singlelabel, mp,
441 	    mp ? mac_mount_label(mp) : NULL, vp, mac_vnode_label(vp));
442 	VFS_KERNEL_DEBUG_END1(11, vp);
443 }
444 
445 int
mac_vnode_notify_create(vfs_context_t ctx,struct mount * mp,struct vnode * dvp,struct vnode * vp,struct componentname * cnp)446 mac_vnode_notify_create(vfs_context_t ctx, struct mount *mp,
447     struct vnode *dvp, struct vnode *vp, struct componentname *cnp)
448 {
449 	kauth_cred_t cred;
450 	int error;
451 
452 #if SECURITY_MAC_CHECK_ENFORCE
453 	/* 21167099 - only check if we allow write */
454 	if (!mac_vnode_enforce) {
455 		return 0;
456 	}
457 #endif
458 	cred = vfs_context_ucred(ctx);
459 	if (!mac_cred_check_enforce(cred)) {
460 		return 0;
461 	}
462 	VFS_KERNEL_DEBUG_START1(12, vp);
463 	MAC_CHECK(vnode_notify_create, cred, mp, mac_mount_label(mp),
464 	    dvp, mac_vnode_label(dvp), vp, mac_vnode_label(vp), cnp);
465 	VFS_KERNEL_DEBUG_END1(12, vp);
466 
467 	return error;
468 }
469 
470 void
mac_vnode_notify_rename(vfs_context_t ctx,struct vnode * fvp,struct vnode * fdvp,struct componentname * fcnp,struct vnode * tvp,struct vnode * tdvp,struct componentname * tcnp,bool swap)471 mac_vnode_notify_rename(vfs_context_t ctx, struct vnode *fvp,
472     struct vnode *fdvp, struct componentname *fcnp, struct vnode *tvp,
473     struct vnode *tdvp, struct componentname *tcnp, bool swap)
474 {
475 	kauth_cred_t cred;
476 
477 #if SECURITY_MAC_CHECK_ENFORCE
478 	/* 21167099 - only check if we allow write */
479 	if (!mac_vnode_enforce) {
480 		return;
481 	}
482 #endif
483 	cred = vfs_context_ucred(ctx);
484 	if (!mac_cred_check_enforce(cred)) {
485 		return;
486 	}
487 
488 	VFS_KERNEL_DEBUG_START1(13, fvp);
489 	MAC_POLICY_ITERATE({
490 		/* BEGIN IGNORE CODESTYLE */
491 		if (swap) {
492 			if (mpc->mpc_ops->mpo_vnode_notify_swap != NULL) {
493 				mpc->mpc_ops->mpo_vnode_notify_swap(cred, fvp, mac_vnode_label(fvp),
494 					tvp, mac_vnode_label(tvp));
495 			} else if (mpc->mpc_ops->mpo_vnode_notify_rename != NULL) {
496 				/* Call notify_rename twice, one for each member of the swap. */
497 				mpc->mpc_ops->mpo_vnode_notify_rename(cred, fvp, mac_vnode_label(fvp),
498 					tdvp, mac_vnode_label(tdvp), tcnp);
499 				mpc->mpc_ops->mpo_vnode_notify_rename(cred, tvp, mac_vnode_label(tvp),
500 					fdvp, mac_vnode_label(fdvp), fcnp);
501 			}
502 		} else if (mpc->mpc_ops->mpo_vnode_notify_rename != NULL) {
503 			mpc->mpc_ops->mpo_vnode_notify_rename(cred, fvp, mac_vnode_label(fvp),
504 		        tdvp, mac_vnode_label(tdvp), tcnp);
505 		}
506 		/* END IGNORE CODESTYLE */
507 	});
508 	VFS_KERNEL_DEBUG_END1(13, fvp);
509 }
510 
511 void
mac_vnode_notify_open(vfs_context_t ctx,struct vnode * vp,int acc_flags)512 mac_vnode_notify_open(vfs_context_t ctx, struct vnode *vp, int acc_flags)
513 {
514 	kauth_cred_t cred;
515 
516 #if SECURITY_MAC_CHECK_ENFORCE
517 	/* 21167099 - only check if we allow write */
518 	if (!mac_vnode_enforce) {
519 		return;
520 	}
521 #endif
522 	cred = vfs_context_ucred(ctx);
523 	if (!mac_cred_check_enforce(cred)) {
524 		return;
525 	}
526 	VFS_KERNEL_DEBUG_START1(14, vp);
527 	MAC_PERFORM(vnode_notify_open, cred, vp, mac_vnode_label(vp), acc_flags);
528 	VFS_KERNEL_DEBUG_END1(14, vp);
529 }
530 
531 void
mac_vnode_notify_link(vfs_context_t ctx,struct vnode * vp,struct vnode * dvp,struct componentname * cnp)532 mac_vnode_notify_link(vfs_context_t ctx, struct vnode *vp,
533     struct vnode *dvp, struct componentname *cnp)
534 {
535 	kauth_cred_t cred;
536 
537 #if SECURITY_MAC_CHECK_ENFORCE
538 	/* 21167099 - only check if we allow write */
539 	if (!mac_vnode_enforce) {
540 		return;
541 	}
542 #endif
543 	cred = vfs_context_ucred(ctx);
544 	if (!mac_cred_check_enforce(cred)) {
545 		return;
546 	}
547 	VFS_KERNEL_DEBUG_START1(15, vp);
548 	MAC_PERFORM(vnode_notify_link, cred, dvp, mac_vnode_label(dvp), vp, mac_vnode_label(vp), cnp);
549 	VFS_KERNEL_DEBUG_END1(15, vp);
550 }
551 
552 void
mac_vnode_notify_deleteextattr(vfs_context_t ctx,struct vnode * vp,const char * name)553 mac_vnode_notify_deleteextattr(vfs_context_t ctx, struct vnode *vp, const char *name)
554 {
555 	kauth_cred_t cred;
556 
557 #if SECURITY_MAC_CHECK_ENFORCE
558 	/* 21167099 - only check if we allow write */
559 	if (!mac_vnode_enforce) {
560 		return;
561 	}
562 #endif
563 	cred = vfs_context_ucred(ctx);
564 	if (!mac_cred_check_enforce(cred)) {
565 		return;
566 	}
567 	VFS_KERNEL_DEBUG_START1(16, vp);
568 	MAC_PERFORM(vnode_notify_deleteextattr, cred, vp, mac_vnode_label(vp), name);
569 	VFS_KERNEL_DEBUG_END1(16, vp);
570 }
571 
572 void
mac_vnode_notify_setacl(vfs_context_t ctx,struct vnode * vp,struct kauth_acl * acl)573 mac_vnode_notify_setacl(vfs_context_t ctx, struct vnode *vp, struct kauth_acl *acl)
574 {
575 	kauth_cred_t cred;
576 
577 #if SECURITY_MAC_CHECK_ENFORCE
578 	/* 21167099 - only check if we allow write */
579 	if (!mac_vnode_enforce) {
580 		return;
581 	}
582 #endif
583 	cred = vfs_context_ucred(ctx);
584 	if (!mac_cred_check_enforce(cred)) {
585 		return;
586 	}
587 	VFS_KERNEL_DEBUG_START1(17, vp);
588 	MAC_PERFORM(vnode_notify_setacl, cred, vp, mac_vnode_label(vp), acl);
589 	VFS_KERNEL_DEBUG_END1(17, vp);
590 }
591 
592 void
mac_vnode_notify_setattrlist(vfs_context_t ctx,struct vnode * vp,struct attrlist * alist)593 mac_vnode_notify_setattrlist(vfs_context_t ctx, struct vnode *vp, struct attrlist *alist)
594 {
595 	kauth_cred_t cred;
596 
597 #if SECURITY_MAC_CHECK_ENFORCE
598 	/* 21167099 - only check if we allow write */
599 	if (!mac_vnode_enforce) {
600 		return;
601 	}
602 #endif
603 	cred = vfs_context_ucred(ctx);
604 	if (!mac_cred_check_enforce(cred)) {
605 		return;
606 	}
607 	VFS_KERNEL_DEBUG_START1(18, vp);
608 	MAC_PERFORM(vnode_notify_setattrlist, cred, vp, mac_vnode_label(vp), alist);
609 	VFS_KERNEL_DEBUG_END1(18, vp);
610 }
611 
612 void
mac_vnode_notify_setextattr(vfs_context_t ctx,struct vnode * vp,const char * name,struct uio * uio)613 mac_vnode_notify_setextattr(vfs_context_t ctx, struct vnode *vp, const char *name, struct uio *uio)
614 {
615 	kauth_cred_t cred;
616 
617 #if SECURITY_MAC_CHECK_ENFORCE
618 	/* 21167099 - only check if we allow write */
619 	if (!mac_vnode_enforce) {
620 		return;
621 	}
622 #endif
623 	cred = vfs_context_ucred(ctx);
624 	if (!mac_cred_check_enforce(cred)) {
625 		return;
626 	}
627 	VFS_KERNEL_DEBUG_START1(19, vp);
628 	MAC_PERFORM(vnode_notify_setextattr, cred, vp, mac_vnode_label(vp), name, uio);
629 	VFS_KERNEL_DEBUG_END1(19, vp);
630 }
631 
632 void
mac_vnode_notify_setflags(vfs_context_t ctx,struct vnode * vp,u_long flags)633 mac_vnode_notify_setflags(vfs_context_t ctx, struct vnode *vp, u_long flags)
634 {
635 	kauth_cred_t cred;
636 
637 #if SECURITY_MAC_CHECK_ENFORCE
638 	/* 21167099 - only check if we allow write */
639 	if (!mac_vnode_enforce) {
640 		return;
641 	}
642 #endif
643 	cred = vfs_context_ucred(ctx);
644 	if (!mac_cred_check_enforce(cred)) {
645 		return;
646 	}
647 	VFS_KERNEL_DEBUG_START1(20, vp);
648 	MAC_PERFORM(vnode_notify_setflags, cred, vp, mac_vnode_label(vp), flags);
649 	VFS_KERNEL_DEBUG_END1(20, vp);
650 }
651 
652 void
mac_vnode_notify_setmode(vfs_context_t ctx,struct vnode * vp,mode_t mode)653 mac_vnode_notify_setmode(vfs_context_t ctx, struct vnode *vp, mode_t mode)
654 {
655 	kauth_cred_t cred;
656 
657 #if SECURITY_MAC_CHECK_ENFORCE
658 	/* 21167099 - only check if we allow write */
659 	if (!mac_vnode_enforce) {
660 		return;
661 	}
662 #endif
663 	cred = vfs_context_ucred(ctx);
664 	if (!mac_cred_check_enforce(cred)) {
665 		return;
666 	}
667 	VFS_KERNEL_DEBUG_START1(21, vp);
668 	MAC_PERFORM(vnode_notify_setmode, cred, vp, mac_vnode_label(vp), mode);
669 	VFS_KERNEL_DEBUG_END1(21, vp);
670 }
671 
672 void
mac_vnode_notify_setowner(vfs_context_t ctx,struct vnode * vp,uid_t uid,gid_t gid)673 mac_vnode_notify_setowner(vfs_context_t ctx, struct vnode *vp, uid_t uid, gid_t gid)
674 {
675 	kauth_cred_t cred;
676 
677 #if SECURITY_MAC_CHECK_ENFORCE
678 	/* 21167099 - only check if we allow write */
679 	if (!mac_vnode_enforce) {
680 		return;
681 	}
682 #endif
683 	cred = vfs_context_ucred(ctx);
684 	if (!mac_cred_check_enforce(cred)) {
685 		return;
686 	}
687 	VFS_KERNEL_DEBUG_START1(22, vp);
688 	MAC_PERFORM(vnode_notify_setowner, cred, vp, mac_vnode_label(vp), uid, gid);
689 	VFS_KERNEL_DEBUG_END1(22, vp);
690 }
691 
692 void
mac_vnode_notify_setutimes(vfs_context_t ctx,struct vnode * vp,struct timespec atime,struct timespec mtime)693 mac_vnode_notify_setutimes(vfs_context_t ctx, struct vnode *vp, struct timespec atime, struct timespec mtime)
694 {
695 	kauth_cred_t cred;
696 
697 #if SECURITY_MAC_CHECK_ENFORCE
698 	/* 21167099 - only check if we allow write */
699 	if (!mac_vnode_enforce) {
700 		return;
701 	}
702 #endif
703 	cred = vfs_context_ucred(ctx);
704 	if (!mac_cred_check_enforce(cred)) {
705 		return;
706 	}
707 	VFS_KERNEL_DEBUG_START1(23, vp);
708 	MAC_PERFORM(vnode_notify_setutimes, cred, vp, mac_vnode_label(vp), atime, mtime);
709 	VFS_KERNEL_DEBUG_END1(23, vp);
710 }
711 
712 void
mac_vnode_notify_truncate(vfs_context_t ctx,kauth_cred_t file_cred,struct vnode * vp)713 mac_vnode_notify_truncate(vfs_context_t ctx, kauth_cred_t file_cred, struct vnode *vp)
714 {
715 	kauth_cred_t cred;
716 
717 #if SECURITY_MAC_CHECK_ENFORCE
718 	/* 21167099 - only check if we allow write */
719 	if (!mac_vnode_enforce) {
720 		return;
721 	}
722 #endif
723 	cred = vfs_context_ucred(ctx);
724 	if (!mac_cred_check_enforce(cred)) {
725 		return;
726 	}
727 	VFS_KERNEL_DEBUG_START1(24, vp);
728 	MAC_PERFORM(vnode_notify_truncate, cred, file_cred, vp, mac_vnode_label(vp));
729 	VFS_KERNEL_DEBUG_END1(24, vp);
730 }
731 
732 /*
733  * Extended attribute 'name' was updated via
734  * vn_setxattr() or vn_removexattr().  Allow the
735  * policy to update the vnode label.
736  */
737 void
mac_vnode_label_update_extattr(struct mount * mp,struct vnode * vp,const char * name)738 mac_vnode_label_update_extattr(struct mount *mp, struct vnode *vp,
739     const char *name)
740 {
741 	int error = 0;
742 
743 #if SECURITY_MAC_CHECK_ENFORCE
744 	/* 21167099 - only check if we allow write */
745 	if (!mac_vnode_enforce) {
746 		return;
747 	}
748 #endif
749 	if (!mac_label_vnodes) {
750 		return;
751 	}
752 
753 	VFS_KERNEL_DEBUG_START1(25, vp);
754 	MAC_PERFORM(vnode_label_update_extattr, mp, mac_mount_label(mp), vp,
755 	    mac_vnode_label(vp), name);
756 	VFS_KERNEL_DEBUG_END1(25, vp);
757 	if (error == 0) {
758 		return;
759 	}
760 
761 	vnode_lock(vp);
762 	vnode_relabel(vp);
763 	vnode_unlock(vp);
764 	return;
765 }
766 
767 static int
mac_vnode_label_store(vfs_context_t ctx,struct vnode * vp,struct label * intlabel)768 mac_vnode_label_store(vfs_context_t ctx, struct vnode *vp,
769     struct label *intlabel)
770 {
771 	kauth_cred_t cred;
772 	int error;
773 
774 #if SECURITY_MAC_CHECK_ENFORCE
775 	/* 21167099 - only check if we allow write */
776 	if (!mac_vnode_enforce) {
777 		return 0;
778 	}
779 #endif
780 	if (!mac_label_vnodes) {
781 		return 0;
782 	}
783 
784 	cred = vfs_context_ucred(ctx);
785 	if (!mac_cred_check_enforce(cred)) {
786 		return 0;
787 	}
788 	VFS_KERNEL_DEBUG_START1(26, vp);
789 	MAC_CHECK(vnode_label_store, cred, vp, mac_vnode_label(vp), intlabel);
790 	VFS_KERNEL_DEBUG_END1(26, vp);
791 
792 	return error;
793 }
794 
795 void
mac_cred_label_update_execve(vfs_context_t ctx,kauth_cred_t new,struct vnode * vp,off_t offset,struct vnode * scriptvp,struct label * scriptvnodelabel,struct label * execl,u_int * csflags,void * macextensions,int * disjoint,int * labelupdateerror)796 mac_cred_label_update_execve(vfs_context_t ctx, kauth_cred_t new, struct vnode *vp, off_t offset,
797     struct vnode *scriptvp, struct label *scriptvnodelabel, struct label *execl, u_int *csflags,
798     void *macextensions, int *disjoint, int *labelupdateerror)
799 {
800 	kauth_cred_t cred;
801 	*disjoint = 0;
802 	int error;
803 	posix_cred_t pcred = posix_cred_get(new);
804 
805 #if SECURITY_MAC_CHECK_ENFORCE
806 	/* 21167099 - only check if we allow write */
807 	if (!mac_proc_enforce || !mac_vnode_enforce) {
808 		return;
809 	}
810 #endif
811 
812 	/* mark the new cred to indicate "matching" includes the label */
813 	pcred->cr_flags |= CRF_MAC_ENFORCE;
814 
815 	cred = vfs_context_ucred(ctx);
816 
817 	/*
818 	 * NB: Cannot use MAC_CHECK macro because we need a sequence point after
819 	 *     calling exec_spawnattr_getmacpolicyinfo() and before passing the
820 	 *     spawnattrlen as an argument to the hook.
821 	 */
822 	VFS_KERNEL_DEBUG_START1(27, vp);
823 	{
824 		struct mac_policy_conf *mpc;
825 		u_int i;
826 
827 		error = 0;
828 		for (i = 0; i < mac_policy_list.staticmax; i++) {
829 			mpc = mac_policy_list.entries[i].mpc;
830 			if (mpc == NULL) {
831 				continue;
832 			}
833 
834 			mpo_cred_label_update_execve_t *hook = mpc->mpc_ops->mpo_cred_label_update_execve;
835 			if (hook == NULL) {
836 				continue;
837 			}
838 
839 			size_t spawnattrlen = 0;
840 			void *spawnattr = exec_spawnattr_getmacpolicyinfo(macextensions, mpc->mpc_name, &spawnattrlen);
841 
842 			error = mac_error_select(hook(cred, new, vfs_context_proc(ctx), vp, offset, scriptvp,
843 			    mac_vnode_label(vp), scriptvnodelabel, execl, csflags, spawnattr, spawnattrlen, disjoint),
844 			    error);
845 		}
846 		if (mac_policy_list_conditional_busy() != 0) {
847 			for (; i <= mac_policy_list.maxindex; i++) {
848 				mpc = mac_policy_list.entries[i].mpc;
849 				if (mpc == NULL) {
850 					continue;
851 				}
852 
853 				mpo_cred_label_update_execve_t *hook = mpc->mpc_ops->mpo_cred_label_update_execve;
854 				if (hook == NULL) {
855 					continue;
856 				}
857 
858 				size_t spawnattrlen = 0;
859 				void *spawnattr = exec_spawnattr_getmacpolicyinfo(macextensions, mpc->mpc_name, &spawnattrlen);
860 
861 				error = mac_error_select(hook(cred, new, vfs_context_proc(ctx), vp, offset, scriptvp,
862 				    mac_vnode_label(vp), scriptvnodelabel, execl, csflags, spawnattr, spawnattrlen, disjoint),
863 				    error);
864 			}
865 			mac_policy_list_unbusy();
866 		}
867 	}
868 	*labelupdateerror = error;
869 	VFS_KERNEL_DEBUG_END1(27, vp);
870 }
871 
872 int
mac_cred_check_label_update_execve(vfs_context_t ctx,struct vnode * vp,off_t offset,struct vnode * scriptvp,struct label * scriptvnodelabel,struct label * execlabel,struct proc * p,void * macextensions)873 mac_cred_check_label_update_execve(vfs_context_t ctx, struct vnode *vp, off_t offset,
874     struct vnode *scriptvp, struct label *scriptvnodelabel, struct label *execlabel,
875     struct proc *p, void *macextensions)
876 {
877 	kauth_cred_t cred;
878 	int result = 0;
879 
880 #if SECURITY_MAC_CHECK_ENFORCE
881 	/* 21167099 - only check if we allow write */
882 	if (!mac_proc_enforce || !mac_vnode_enforce) {
883 		return result;
884 	}
885 #endif
886 
887 	cred = vfs_context_ucred(ctx);
888 
889 	VFS_KERNEL_DEBUG_START1(28, vp);
890 	/*
891 	 * NB: Cannot use MAC_BOOLEAN macro because we need a sequence point after
892 	 *     calling exec_spawnattr_getmacpolicyinfo() and before passing the
893 	 *     spawnattrlen as an argument to the hook.
894 	 */
895 	{
896 		struct mac_policy_conf *mpc;
897 		u_int i;
898 
899 		for (i = 0; i < mac_policy_list.staticmax; i++) {
900 			mpc = mac_policy_list.entries[i].mpc;
901 			if (mpc == NULL) {
902 				continue;
903 			}
904 
905 			mpo_cred_check_label_update_execve_t *hook = mpc->mpc_ops->mpo_cred_check_label_update_execve;
906 			if (hook == NULL) {
907 				continue;
908 			}
909 
910 			size_t spawnattrlen = 0;
911 			void *spawnattr = exec_spawnattr_getmacpolicyinfo(macextensions, mpc->mpc_name, &spawnattrlen);
912 
913 			result = result || hook(cred, vp, offset, scriptvp, mac_vnode_label(vp), scriptvnodelabel, execlabel, p, spawnattr, spawnattrlen);
914 		}
915 		if (mac_policy_list_conditional_busy() != 0) {
916 			for (; i <= mac_policy_list.maxindex; i++) {
917 				mpc = mac_policy_list.entries[i].mpc;
918 				if (mpc == NULL) {
919 					continue;
920 				}
921 
922 				mpo_cred_check_label_update_execve_t *hook = mpc->mpc_ops->mpo_cred_check_label_update_execve;
923 				if (hook == NULL) {
924 					continue;
925 				}
926 
927 				size_t spawnattrlen = 0;
928 				void *spawnattr = exec_spawnattr_getmacpolicyinfo(macextensions, mpc->mpc_name, &spawnattrlen);
929 
930 				result = result || hook(cred, vp, offset, scriptvp, mac_vnode_label(vp), scriptvnodelabel, execlabel, p, spawnattr, spawnattrlen);
931 			}
932 			mac_policy_list_unbusy();
933 		}
934 	}
935 	VFS_KERNEL_DEBUG_END1(28, vp);
936 
937 	return result;
938 }
939 
940 int
mac_vnode_check_access(vfs_context_t ctx,struct vnode * vp,int acc_mode)941 mac_vnode_check_access(vfs_context_t ctx, struct vnode *vp,
942     int acc_mode)
943 {
944 	kauth_cred_t cred;
945 	int error;
946 	int mask;
947 
948 #if SECURITY_MAC_CHECK_ENFORCE
949 	/* 21167099 - only check if we allow write */
950 	if (!mac_vnode_enforce) {
951 		return 0;
952 	}
953 #endif
954 	cred = vfs_context_ucred(ctx);
955 	if (!mac_cred_check_enforce(cred)) {
956 		return 0;
957 	}
958 	/* Convert {R,W,X}_OK values to V{READ,WRITE,EXEC} for entry points */
959 	mask = ACCESS_MODE_TO_VNODE_MASK(acc_mode);
960 	VFS_KERNEL_DEBUG_START1(29, vp);
961 	MAC_CHECK(vnode_check_access, cred, vp, mac_vnode_label(vp), mask);
962 	VFS_KERNEL_DEBUG_END1(29, vp);
963 	return error;
964 }
965 
966 int
mac_vnode_check_chdir(vfs_context_t ctx,struct vnode * dvp)967 mac_vnode_check_chdir(vfs_context_t ctx, struct vnode *dvp)
968 {
969 	kauth_cred_t cred;
970 	int error;
971 
972 #if SECURITY_MAC_CHECK_ENFORCE
973 	/* 21167099 - only check if we allow write */
974 	if (!mac_vnode_enforce) {
975 		return 0;
976 	}
977 #endif
978 	cred = vfs_context_ucred(ctx);
979 	if (!mac_cred_check_enforce(cred)) {
980 		return 0;
981 	}
982 	VFS_KERNEL_DEBUG_START1(30, dvp);
983 	MAC_CHECK(vnode_check_chdir, cred, dvp, mac_vnode_label(dvp));
984 	VFS_KERNEL_DEBUG_END1(30, dvp);
985 	return error;
986 }
987 
988 int
mac_vnode_check_chroot(vfs_context_t ctx,struct vnode * dvp,struct componentname * cnp)989 mac_vnode_check_chroot(vfs_context_t ctx, struct vnode *dvp,
990     struct componentname *cnp)
991 {
992 	kauth_cred_t cred;
993 	int error;
994 
995 #if SECURITY_MAC_CHECK_ENFORCE
996 	/* 21167099 - only check if we allow write */
997 	if (!mac_vnode_enforce) {
998 		return 0;
999 	}
1000 #endif
1001 	cred = vfs_context_ucred(ctx);
1002 	if (!mac_cred_check_enforce(cred)) {
1003 		return 0;
1004 	}
1005 	VFS_KERNEL_DEBUG_START1(31, dvp);
1006 	MAC_CHECK(vnode_check_chroot, cred, dvp, mac_vnode_label(dvp), cnp);
1007 	VFS_KERNEL_DEBUG_END1(31, dvp);
1008 	return error;
1009 }
1010 
1011 int
mac_vnode_check_clone(vfs_context_t ctx,struct vnode * dvp,struct vnode * vp,struct componentname * cnp)1012 mac_vnode_check_clone(vfs_context_t ctx, struct vnode *dvp,
1013     struct vnode *vp, struct componentname *cnp)
1014 {
1015 	kauth_cred_t cred;
1016 	int error;
1017 
1018 #if SECURITY_MAC_CHECK_ENFORCE
1019 	/* 21167099 - only check if we allow write */
1020 	if (!mac_vnode_enforce) {
1021 		return 0;
1022 	}
1023 #endif
1024 	cred = vfs_context_ucred(ctx);
1025 	if (!mac_cred_check_enforce(cred)) {
1026 		return 0;
1027 	}
1028 	VFS_KERNEL_DEBUG_START1(32, dvp);
1029 	MAC_CHECK(vnode_check_clone, cred, dvp, mac_vnode_label(dvp), vp,
1030 	    mac_vnode_label(vp), cnp);
1031 	VFS_KERNEL_DEBUG_END1(32, dvp);
1032 	return error;
1033 }
1034 int
mac_vnode_check_create(vfs_context_t ctx,struct vnode * dvp,struct componentname * cnp,struct vnode_attr * vap)1035 mac_vnode_check_create(vfs_context_t ctx, struct vnode *dvp,
1036     struct componentname *cnp, struct vnode_attr *vap)
1037 {
1038 	kauth_cred_t cred;
1039 	int error;
1040 
1041 #if SECURITY_MAC_CHECK_ENFORCE
1042 	/* 21167099 - only check if we allow write */
1043 	if (!mac_vnode_enforce) {
1044 		return 0;
1045 	}
1046 #endif
1047 	cred = vfs_context_ucred(ctx);
1048 	if (!mac_cred_check_enforce(cred)) {
1049 		return 0;
1050 	}
1051 	VFS_KERNEL_DEBUG_START1(33, dvp);
1052 	MAC_CHECK(vnode_check_create, cred, dvp, mac_vnode_label(dvp), cnp, vap);
1053 	VFS_KERNEL_DEBUG_END1(33, dvp);
1054 	return error;
1055 }
1056 
1057 int
mac_vnode_check_unlink(vfs_context_t ctx,struct vnode * dvp,struct vnode * vp,struct componentname * cnp)1058 mac_vnode_check_unlink(vfs_context_t ctx, struct vnode *dvp, struct vnode *vp,
1059     struct componentname *cnp)
1060 {
1061 	kauth_cred_t cred;
1062 	int error;
1063 
1064 #if SECURITY_MAC_CHECK_ENFORCE
1065 	/* 21167099 - only check if we allow write */
1066 	if (!mac_vnode_enforce) {
1067 		return 0;
1068 	}
1069 #endif
1070 	cred = vfs_context_ucred(ctx);
1071 	if (!mac_cred_check_enforce(cred)) {
1072 		return 0;
1073 	}
1074 	VFS_KERNEL_DEBUG_START1(34, dvp);
1075 	MAC_CHECK(vnode_check_unlink, cred, dvp, mac_vnode_label(dvp), vp,
1076 	    mac_vnode_label(vp), cnp);
1077 	VFS_KERNEL_DEBUG_END1(34, dvp);
1078 	return error;
1079 }
1080 #if 0
1081 int
1082 mac_vnode_check_deleteacl(vfs_context_t ctx, struct vnode *vp,
1083     acl_type_t type)
1084 {
1085 	kauth_cred_t cred;
1086 	int error;
1087 
1088 #if SECURITY_MAC_CHECK_ENFORCE
1089 	/* 21167099 - only check if we allow write */
1090 	if (!mac_vnode_enforce) {
1091 		return 0;
1092 	}
1093 #endif
1094 	cred = vfs_context_ucred(ctx);
1095 	if (!mac_cred_check_enforce(cred)) {
1096 		return 0;
1097 	}
1098 	VFS_KERNEL_DEBUG_START1(35, dvp);
1099 	MAC_CHECK(vnode_check_deleteacl, cred, vp, mac_vnode_label(vp), type);
1100 	VFS_KERNEL_DEBUG_END1(35, dvp);
1101 	return error;
1102 }
1103 #endif
1104 
1105 int
mac_vnode_check_deleteextattr(vfs_context_t ctx,struct vnode * vp,const char * name)1106 mac_vnode_check_deleteextattr(vfs_context_t ctx, struct vnode *vp,
1107     const char *name)
1108 {
1109 	kauth_cred_t cred;
1110 	int error;
1111 
1112 #if SECURITY_MAC_CHECK_ENFORCE
1113 	/* 21167099 - only check if we allow write */
1114 	if (!mac_vnode_enforce) {
1115 		return 0;
1116 	}
1117 #endif
1118 	cred = vfs_context_ucred(ctx);
1119 	if (!mac_cred_check_enforce(cred)) {
1120 		return 0;
1121 	}
1122 	VFS_KERNEL_DEBUG_START1(36, vp);
1123 	MAC_CHECK(vnode_check_deleteextattr, cred, vp, mac_vnode_label(vp), name);
1124 	VFS_KERNEL_DEBUG_END1(36, vp);
1125 	return error;
1126 }
1127 int
mac_vnode_check_exchangedata(vfs_context_t ctx,struct vnode * v1,struct vnode * v2)1128 mac_vnode_check_exchangedata(vfs_context_t ctx,
1129     struct vnode *v1, struct vnode *v2)
1130 {
1131 	kauth_cred_t cred;
1132 	int error;
1133 
1134 #if SECURITY_MAC_CHECK_ENFORCE
1135 	/* 21167099 - only check if we allow write */
1136 	if (!mac_vnode_enforce) {
1137 		return 0;
1138 	}
1139 #endif
1140 	cred = vfs_context_ucred(ctx);
1141 	if (!mac_cred_check_enforce(cred)) {
1142 		return 0;
1143 	}
1144 	VFS_KERNEL_DEBUG_START1(37, v1);
1145 	MAC_CHECK(vnode_check_exchangedata, cred, v1, mac_vnode_label(v1),
1146 	    v2, mac_vnode_label(v2));
1147 	VFS_KERNEL_DEBUG_END1(37, v1);
1148 
1149 	return error;
1150 }
1151 
1152 #if 0
1153 int
1154 mac_vnode_check_getacl(vfs_context_t ctx, struct vnode *vp, acl_type_t type)
1155 {
1156 	kauth_cred_t cred;
1157 	int error;
1158 
1159 #if SECURITY_MAC_CHECK_ENFORCE
1160 	/* 21167099 - only check if we allow write */
1161 	if (!mac_vnode_enforce) {
1162 		return 0;
1163 	}
1164 #endif
1165 	cred = vfs_context_ucred(ctx);
1166 	if (!mac_cred_check_enforce(cred)) {
1167 		return 0;
1168 	}
1169 	VFS_KERNEL_DEBUG_START1(38, vp);
1170 	MAC_CHECK(vnode_check_getacl, cred, vp, mac_vnode_label(vp), type);
1171 	VFS_KERNEL_DEBUG_END1(38, vp);
1172 	return error;
1173 }
1174 #endif
1175 
1176 int
mac_vnode_check_getattr(vfs_context_t ctx,struct ucred * file_cred,struct vnode * vp,struct vnode_attr * va)1177 mac_vnode_check_getattr(vfs_context_t ctx, struct ucred *file_cred,
1178     struct vnode *vp, struct vnode_attr *va)
1179 {
1180 	kauth_cred_t cred;
1181 	int error;
1182 
1183 #if SECURITY_MAC_CHECK_ENFORCE
1184 	/* 21167099 - only check if we allow write */
1185 	if (!mac_vnode_enforce) {
1186 		return 0;
1187 	}
1188 #endif
1189 	cred = vfs_context_ucred(ctx);
1190 	if (!mac_cred_check_enforce(cred)) {
1191 		return 0;
1192 	}
1193 	VFS_KERNEL_DEBUG_START1(39, vp);
1194 	MAC_CHECK(vnode_check_getattr, cred, file_cred, vp, mac_vnode_label(vp), va);
1195 	VFS_KERNEL_DEBUG_END1(39, vp);
1196 	return error;
1197 }
1198 
1199 int
mac_vnode_check_getattrlist(vfs_context_t ctx,struct vnode * vp,struct attrlist * alist,uint64_t options)1200 mac_vnode_check_getattrlist(vfs_context_t ctx, struct vnode *vp,
1201     struct attrlist *alist, uint64_t options)
1202 {
1203 	kauth_cred_t cred;
1204 	int error;
1205 
1206 #if SECURITY_MAC_CHECK_ENFORCE
1207 	/* 21167099 - only check if we allow write */
1208 	if (!mac_vnode_enforce) {
1209 		return 0;
1210 	}
1211 #endif
1212 	cred = vfs_context_ucred(ctx);
1213 	if (!mac_cred_check_enforce(cred)) {
1214 		return 0;
1215 	}
1216 	VFS_KERNEL_DEBUG_START1(40, vp);
1217 	MAC_CHECK(vnode_check_getattrlist, cred, vp, mac_vnode_label(vp), alist, options);
1218 	VFS_KERNEL_DEBUG_END1(40, vp);
1219 
1220 	/* Falsify results instead of returning error? */
1221 	return error;
1222 }
1223 
1224 int
mac_vnode_check_exec(vfs_context_t ctx,struct vnode * vp,struct image_params * imgp)1225 mac_vnode_check_exec(vfs_context_t ctx, struct vnode *vp,
1226     struct image_params *imgp)
1227 {
1228 	kauth_cred_t cred;
1229 	int error = 0;
1230 
1231 #if SECURITY_MAC_CHECK_ENFORCE
1232 	/* 21167099 - only check if we allow write */
1233 	if (!mac_proc_enforce || !mac_vnode_enforce) {
1234 		return 0;
1235 	}
1236 #endif
1237 
1238 	cred = vfs_context_ucred(ctx);
1239 
1240 	/*
1241 	 * NB: Cannot use MAC_CHECK macro because we need a sequence point after
1242 	 *     calling exec_spawnattr_getmacpolicyinfo() and before passing the
1243 	 *     spawnattrlen as an argument to the hook.
1244 	 */
1245 	VFS_KERNEL_DEBUG_START1(41, vp);
1246 	{
1247 		struct mac_policy_conf *mpc;
1248 		u_int i;
1249 
1250 		for (i = 0; i < mac_policy_list.staticmax; i++) {
1251 			mpc = mac_policy_list.entries[i].mpc;
1252 			if (mpc == NULL) {
1253 				continue;
1254 			}
1255 
1256 			mpo_vnode_check_exec_t *hook = mpc->mpc_ops->mpo_vnode_check_exec;
1257 			if (hook == NULL) {
1258 				continue;
1259 			}
1260 
1261 			size_t spawnattrlen = 0;
1262 			void *spawnattr = exec_spawnattr_getmacpolicyinfo(&imgp->ip_px_smpx, mpc->mpc_name, &spawnattrlen);
1263 
1264 			error = mac_error_select(
1265 				hook(cred,
1266 				vp, imgp->ip_scriptvp, mac_vnode_label(vp), imgp->ip_scriptlabelp,
1267 				imgp->ip_execlabelp, &imgp->ip_ndp->ni_cnd, &imgp->ip_csflags,
1268 				spawnattr, spawnattrlen), error);
1269 		}
1270 		if (mac_policy_list_conditional_busy() != 0) {
1271 			for (; i <= mac_policy_list.maxindex; i++) {
1272 				mpc = mac_policy_list.entries[i].mpc;
1273 				if (mpc == NULL) {
1274 					continue;
1275 				}
1276 
1277 				mpo_vnode_check_exec_t *hook = mpc->mpc_ops->mpo_vnode_check_exec;
1278 				if (hook == NULL) {
1279 					continue;
1280 				}
1281 
1282 				size_t spawnattrlen = 0;
1283 				void *spawnattr = exec_spawnattr_getmacpolicyinfo(&imgp->ip_px_smpx, mpc->mpc_name, &spawnattrlen);
1284 
1285 				error = mac_error_select(
1286 					hook(cred,
1287 					vp, imgp->ip_scriptvp, mac_vnode_label(vp), imgp->ip_scriptlabelp,
1288 					imgp->ip_execlabelp, &imgp->ip_ndp->ni_cnd, &imgp->ip_csflags,
1289 					spawnattr, spawnattrlen), error);
1290 			}
1291 			mac_policy_list_unbusy();
1292 		}
1293 	}
1294 	VFS_KERNEL_DEBUG_END1(41, vp);
1295 
1296 	return error;
1297 }
1298 
1299 int
mac_vnode_check_fsgetpath(vfs_context_t ctx,struct vnode * vp)1300 mac_vnode_check_fsgetpath(vfs_context_t ctx, struct vnode *vp)
1301 {
1302 	kauth_cred_t cred;
1303 	int error;
1304 
1305 #if SECURITY_MAC_CHECK_ENFORCE
1306 	/* 21167099 - only check if we allow write */
1307 	if (!mac_vnode_enforce) {
1308 		return 0;
1309 	}
1310 #endif
1311 	cred = vfs_context_ucred(ctx);
1312 	if (!mac_cred_check_enforce(cred)) {
1313 		return 0;
1314 	}
1315 	VFS_KERNEL_DEBUG_START1(42, vp);
1316 	MAC_CHECK(vnode_check_fsgetpath, cred, vp, mac_vnode_label(vp));
1317 	VFS_KERNEL_DEBUG_END1(42, vp);
1318 	return error;
1319 }
1320 
1321 int
mac_vnode_check_signature(struct vnode * vp,struct cs_blob * cs_blob,struct image_params * imgp,unsigned int * cs_flags,unsigned int * signer_type,int flags,unsigned int platform)1322 mac_vnode_check_signature(struct vnode *vp, struct cs_blob *cs_blob,
1323     struct image_params *imgp,
1324     unsigned int *cs_flags, unsigned int *signer_type,
1325     int flags, unsigned int platform)
1326 {
1327 	int error;
1328 	char *fatal_failure_desc = NULL;
1329 	size_t fatal_failure_desc_len = 0;
1330 
1331 	char *vn_path = NULL;
1332 	vm_size_t vn_pathlen = MAXPATHLEN;
1333 	cpu_type_t cpu_type = (imgp == NULL) ? CPU_TYPE_ANY : imgp->ip_origcputype;
1334 
1335 
1336 #if SECURITY_MAC_CHECK_ENFORCE
1337 	/* 21167099 - only check if we allow write */
1338 	if (!mac_proc_enforce || !mac_vnode_enforce) {
1339 		return 0;
1340 	}
1341 #endif
1342 
1343 	VFS_KERNEL_DEBUG_START1(43, vp);
1344 	MAC_CHECK(vnode_check_signature, vp, mac_vnode_label(vp), cpu_type, cs_blob,
1345 	    cs_flags, signer_type, flags, platform, &fatal_failure_desc, &fatal_failure_desc_len);
1346 	VFS_KERNEL_DEBUG_END1(43, vp);
1347 
1348 	if (fatal_failure_desc_len) {
1349 		// A fatal code signature validation failure occured, formulate a crash
1350 		// reason.
1351 
1352 		char const *path = NULL;
1353 
1354 		vn_path = zalloc(ZV_NAMEI);
1355 		if (vn_getpath(vp, vn_path, (int*)&vn_pathlen) == 0) {
1356 			path = vn_path;
1357 		} else {
1358 			path = "(get vnode path failed)";
1359 		}
1360 
1361 		if (error == 0) {
1362 			panic("mac_vnode_check_signature: MAC hook returned no error, "
1363 			    "but status is claimed to be fatal? "
1364 			    "path: '%s', fatal_failure_desc_len: %ld, fatal_failure_desc:\n%s\n",
1365 			    path, fatal_failure_desc_len, fatal_failure_desc);
1366 		}
1367 
1368 		printf("mac_vnode_check_signature: %s: code signature validation failed fatally: %s",
1369 		    path, fatal_failure_desc);
1370 
1371 		if (imgp == NULL) {
1372 			goto out;
1373 		}
1374 
1375 		os_reason_t reason = os_reason_create(OS_REASON_CODESIGNING,
1376 		    CODESIGNING_EXIT_REASON_TASKGATED_INVALID_SIG);
1377 
1378 		if (reason == OS_REASON_NULL) {
1379 			printf("mac_vnode_check_signature: %s: failure to allocate exit reason for validation failure: %s\n",
1380 			    path, fatal_failure_desc);
1381 			goto out;
1382 		}
1383 
1384 		imgp->ip_cs_error = reason;
1385 		reason->osr_flags = (OS_REASON_FLAG_GENERATE_CRASH_REPORT |
1386 		    OS_REASON_FLAG_CONSISTENT_FAILURE);
1387 
1388 		if (fatal_failure_desc == NULL) {
1389 			// This may happen if allocation for the buffer failed.
1390 			printf("mac_vnode_check_signature: %s: fatal failure is missing its description.\n", path);
1391 		} else {
1392 			mach_vm_address_t data_addr = 0;
1393 
1394 			int reason_error = 0;
1395 			int kcdata_error = 0;
1396 
1397 			if ((reason_error = os_reason_alloc_buffer_noblock(reason, kcdata_estimate_required_buffer_size
1398 			    (1, (uint32_t)fatal_failure_desc_len))) == 0 &&
1399 			    (kcdata_error = kcdata_get_memory_addr(&reason->osr_kcd_descriptor,
1400 			    EXIT_REASON_USER_DESC, (uint32_t)fatal_failure_desc_len,
1401 			    &data_addr)) == KERN_SUCCESS) {
1402 				kern_return_t mc_error = kcdata_memcpy(&reason->osr_kcd_descriptor, (mach_vm_address_t)data_addr,
1403 				    fatal_failure_desc, (uint32_t)fatal_failure_desc_len);
1404 
1405 				if (mc_error != KERN_SUCCESS) {
1406 					printf("mac_vnode_check_signature: %s: failed to copy reason string "
1407 					    "(kcdata_memcpy error: %d, length: %ld)\n",
1408 					    path, mc_error, fatal_failure_desc_len);
1409 				}
1410 			} else {
1411 				printf("mac_vnode_check_signature: %s: failed to allocate space for reason string "
1412 				    "(os_reason_alloc_buffer error: %d, kcdata error: %d, length: %ld)\n",
1413 				    path, reason_error, kcdata_error, fatal_failure_desc_len);
1414 			}
1415 		}
1416 	}
1417 
1418 out:
1419 	if (vn_path) {
1420 		zfree(ZV_NAMEI, vn_path);
1421 	}
1422 
1423 	if (fatal_failure_desc_len > 0 && fatal_failure_desc != NULL) {
1424 		/* AMFI uses kalloc() which for kexts is redirected to KHEAP_KEXT */
1425 		kheap_free(KHEAP_KEXT, fatal_failure_desc, fatal_failure_desc_len);
1426 	}
1427 
1428 	return error;
1429 }
1430 
1431 int
mac_vnode_check_supplemental_signature(struct vnode * vp,struct cs_blob * cs_blob,struct vnode * linked_vp,struct cs_blob * linked_cs_blob,unsigned int * signer_type)1432 mac_vnode_check_supplemental_signature(struct vnode *vp,
1433     struct cs_blob *cs_blob, struct vnode *linked_vp,
1434     struct cs_blob *linked_cs_blob, unsigned int *signer_type)
1435 {
1436 	int error;
1437 
1438 #if SECURITY_MAC_CHECK_ENFORCE
1439 	/* 21167099 - only check if we allow write */
1440 	if (!mac_proc_enforce || !mac_vnode_enforce) {
1441 		return 0;
1442 	}
1443 #endif
1444 	VFS_KERNEL_DEBUG_START1(93, vp);
1445 	MAC_CHECK(vnode_check_supplemental_signature, vp, mac_vnode_label(vp), cs_blob, linked_vp, linked_cs_blob,
1446 	    signer_type);
1447 	VFS_KERNEL_DEBUG_END1(93, vp);
1448 
1449 	return error;
1450 }
1451 
1452 #if 0
1453 int
1454 mac_vnode_check_getacl(vfs_context_t ctx, struct vnode *vp, acl_type_t type)
1455 {
1456 	kauth_cred_t cred;
1457 	int error;
1458 
1459 #if SECURITY_MAC_CHECK_ENFORCE
1460 	/* 21167099 - only check if we allow write */
1461 	if (!mac_vnode_enforce) {
1462 		return 0;
1463 	}
1464 #endif
1465 	cred = vfs_context_ucred(ctx);
1466 	if (!mac_cred_check_enforce(cred)) {
1467 		return 0;
1468 	}
1469 	VFS_KERNEL_DEBUG_START1(44, vp);
1470 	MAC_CHECK(vnode_check_getacl, cred, vp, mac_vnode_label(vp), type);
1471 	VFS_KERNEL_DEBUG_END1(44, vp);
1472 	return error;
1473 }
1474 #endif
1475 
1476 int
mac_vnode_check_getextattr(vfs_context_t ctx,struct vnode * vp,const char * name,struct uio * uio)1477 mac_vnode_check_getextattr(vfs_context_t ctx, struct vnode *vp,
1478     const char *name, struct uio *uio)
1479 {
1480 	kauth_cred_t cred;
1481 	int error;
1482 
1483 #if SECURITY_MAC_CHECK_ENFORCE
1484 	/* 21167099 - only check if we allow write */
1485 	if (!mac_vnode_enforce) {
1486 		return 0;
1487 	}
1488 #endif
1489 	cred = vfs_context_ucred(ctx);
1490 	if (!mac_cred_check_enforce(cred)) {
1491 		return 0;
1492 	}
1493 	VFS_KERNEL_DEBUG_START1(45, vp);
1494 	MAC_CHECK(vnode_check_getextattr, cred, vp, mac_vnode_label(vp),
1495 	    name, uio);
1496 	VFS_KERNEL_DEBUG_END1(45, vp);
1497 	return error;
1498 }
1499 
1500 int
mac_vnode_check_ioctl(vfs_context_t ctx,struct vnode * vp,u_long cmd)1501 mac_vnode_check_ioctl(vfs_context_t ctx, struct vnode *vp, u_long cmd)
1502 {
1503 	kauth_cred_t cred;
1504 	int error;
1505 
1506 #if SECURITY_MAC_CHECK_ENFORCE
1507 	/* 21167099 - only check if we allow write */
1508 	if (!mac_vnode_enforce) {
1509 		return 0;
1510 	}
1511 #endif
1512 	cred = vfs_context_ucred(ctx);
1513 	if (!mac_cred_check_enforce(cred)) {
1514 		return 0;
1515 	}
1516 	VFS_KERNEL_DEBUG_START1(46, vp);
1517 	MAC_CHECK(vnode_check_ioctl, cred, vp, mac_vnode_label(vp), cmd);
1518 	VFS_KERNEL_DEBUG_END1(46, vp);
1519 	return error;
1520 }
1521 
1522 int
mac_vnode_check_kqfilter(vfs_context_t ctx,kauth_cred_t file_cred,struct knote * kn,struct vnode * vp)1523 mac_vnode_check_kqfilter(vfs_context_t ctx, kauth_cred_t file_cred,
1524     struct knote *kn, struct vnode *vp)
1525 {
1526 	kauth_cred_t cred;
1527 	int error;
1528 
1529 #if SECURITY_MAC_CHECK_ENFORCE
1530 	/* 21167099 - only check if we allow write */
1531 	if (!mac_vnode_enforce) {
1532 		return 0;
1533 	}
1534 #endif
1535 	cred = vfs_context_ucred(ctx);
1536 	if (!mac_cred_check_enforce(cred)) {
1537 		return 0;
1538 	}
1539 	VFS_KERNEL_DEBUG_START1(47, vp);
1540 	MAC_CHECK(vnode_check_kqfilter, cred, file_cred, kn, vp,
1541 	    mac_vnode_label(vp));
1542 	VFS_KERNEL_DEBUG_END1(47, vp);
1543 
1544 	return error;
1545 }
1546 
1547 int
mac_vnode_check_link(vfs_context_t ctx,struct vnode * dvp,struct vnode * vp,struct componentname * cnp)1548 mac_vnode_check_link(vfs_context_t ctx, struct vnode *dvp,
1549     struct vnode *vp, struct componentname *cnp)
1550 {
1551 	kauth_cred_t cred;
1552 	int error;
1553 
1554 #if SECURITY_MAC_CHECK_ENFORCE
1555 	/* 21167099 - only check if we allow write */
1556 	if (!mac_vnode_enforce) {
1557 		return 0;
1558 	}
1559 #endif
1560 	cred = vfs_context_ucred(ctx);
1561 	if (!mac_cred_check_enforce(cred)) {
1562 		return 0;
1563 	}
1564 	VFS_KERNEL_DEBUG_START1(48, vp);
1565 	MAC_CHECK(vnode_check_link, cred, dvp, mac_vnode_label(dvp), vp,
1566 	    mac_vnode_label(vp), cnp);
1567 	VFS_KERNEL_DEBUG_END1(48, vp);
1568 	return error;
1569 }
1570 
1571 int
mac_vnode_check_listextattr(vfs_context_t ctx,struct vnode * vp)1572 mac_vnode_check_listextattr(vfs_context_t ctx, struct vnode *vp)
1573 {
1574 	kauth_cred_t cred;
1575 	int error;
1576 
1577 #if SECURITY_MAC_CHECK_ENFORCE
1578 	/* 21167099 - only check if we allow write */
1579 	if (!mac_vnode_enforce) {
1580 		return 0;
1581 	}
1582 #endif
1583 	cred = vfs_context_ucred(ctx);
1584 	if (!mac_cred_check_enforce(cred)) {
1585 		return 0;
1586 	}
1587 	VFS_KERNEL_DEBUG_START1(49, vp);
1588 	MAC_CHECK(vnode_check_listextattr, cred, vp, mac_vnode_label(vp));
1589 	VFS_KERNEL_DEBUG_END1(49, vp);
1590 	return error;
1591 }
1592 
1593 int
mac_vnode_check_lookup_preflight(vfs_context_t ctx,struct vnode * dvp,const char * path,size_t pathlen)1594 mac_vnode_check_lookup_preflight(vfs_context_t ctx, struct vnode *dvp,
1595     const char *path, size_t pathlen)
1596 {
1597 	kauth_cred_t cred;
1598 	int error;
1599 
1600 #if SECURITY_MAC_CHECK_ENFORCE
1601 	/* 21167099 - only check if we allow write */
1602 	if (!mac_vnode_enforce) {
1603 		return 0;
1604 	}
1605 #endif
1606 	cred = vfs_context_ucred(ctx);
1607 	if (!mac_cred_check_enforce(cred)) {
1608 		return 0;
1609 	}
1610 	VFS_KERNEL_DEBUG_START1(50, dvp);
1611 	MAC_CHECK(vnode_check_lookup_preflight, cred, dvp, mac_vnode_label(dvp), path, pathlen);
1612 	VFS_KERNEL_DEBUG_END1(50, dvp);
1613 	return error;
1614 }
1615 
1616 int
mac_vnode_check_lookup(vfs_context_t ctx,struct vnode * dvp,struct componentname * cnp)1617 mac_vnode_check_lookup(vfs_context_t ctx, struct vnode *dvp,
1618     struct componentname *cnp)
1619 {
1620 	kauth_cred_t cred;
1621 	int error;
1622 
1623 #if SECURITY_MAC_CHECK_ENFORCE
1624 	/* 21167099 - only check if we allow write */
1625 	if (!mac_vnode_enforce) {
1626 		return 0;
1627 	}
1628 #endif
1629 	cred = vfs_context_ucred(ctx);
1630 	if (!mac_cred_check_enforce(cred)) {
1631 		return 0;
1632 	}
1633 	VFS_KERNEL_DEBUG_START1(51, dvp);
1634 	MAC_CHECK(vnode_check_lookup, cred, dvp, mac_vnode_label(dvp), cnp);
1635 	VFS_KERNEL_DEBUG_END1(51, dvp);
1636 	return error;
1637 }
1638 
1639 int
mac_vnode_check_open(vfs_context_t ctx,struct vnode * vp,int acc_mode)1640 mac_vnode_check_open(vfs_context_t ctx, struct vnode *vp, int acc_mode)
1641 {
1642 	kauth_cred_t cred;
1643 	int error;
1644 
1645 #if SECURITY_MAC_CHECK_ENFORCE
1646 	/* 21167099 - only check if we allow write */
1647 	if (!mac_vnode_enforce) {
1648 		return 0;
1649 	}
1650 #endif
1651 	cred = vfs_context_ucred(ctx);
1652 	if (!mac_cred_check_enforce(cred)) {
1653 		return 0;
1654 	}
1655 	VFS_KERNEL_DEBUG_START1(52, vp);
1656 	MAC_CHECK(vnode_check_open, cred, vp, mac_vnode_label(vp), acc_mode);
1657 	VFS_KERNEL_DEBUG_END1(52, vp);
1658 	return error;
1659 }
1660 
1661 int
mac_vnode_check_read(vfs_context_t ctx,struct ucred * file_cred,struct vnode * vp)1662 mac_vnode_check_read(vfs_context_t ctx, struct ucred *file_cred,
1663     struct vnode *vp)
1664 {
1665 	kauth_cred_t cred;
1666 	int error;
1667 
1668 #if SECURITY_MAC_CHECK_ENFORCE
1669 	/* 21167099 - only check if we allow write */
1670 	if (!mac_vnode_enforce) {
1671 		return 0;
1672 	}
1673 #endif
1674 	cred = vfs_context_ucred(ctx);
1675 	if (!mac_cred_check_enforce(cred)) {
1676 		return 0;
1677 	}
1678 	VFS_KERNEL_DEBUG_START1(53, vp);
1679 	MAC_CHECK(vnode_check_read, cred, file_cred, vp,
1680 	    mac_vnode_label(vp));
1681 	VFS_KERNEL_DEBUG_END1(53, vp);
1682 
1683 	return error;
1684 }
1685 
1686 int
mac_vnode_check_readdir(vfs_context_t ctx,struct vnode * dvp)1687 mac_vnode_check_readdir(vfs_context_t ctx, struct vnode *dvp)
1688 {
1689 	kauth_cred_t cred;
1690 	int error;
1691 
1692 #if SECURITY_MAC_CHECK_ENFORCE
1693 	/* 21167099 - only check if we allow write */
1694 	if (!mac_vnode_enforce) {
1695 		return 0;
1696 	}
1697 #endif
1698 	cred = vfs_context_ucred(ctx);
1699 	if (!mac_cred_check_enforce(cred)) {
1700 		return 0;
1701 	}
1702 	VFS_KERNEL_DEBUG_START1(54, dvp);
1703 	MAC_CHECK(vnode_check_readdir, cred, dvp, mac_vnode_label(dvp));
1704 	VFS_KERNEL_DEBUG_END1(54, dvp);
1705 	return error;
1706 }
1707 
1708 int
mac_vnode_check_readlink(vfs_context_t ctx,struct vnode * vp)1709 mac_vnode_check_readlink(vfs_context_t ctx, struct vnode *vp)
1710 {
1711 	kauth_cred_t cred;
1712 	int error;
1713 
1714 #if SECURITY_MAC_CHECK_ENFORCE
1715 	/* 21167099 - only check if we allow write */
1716 	if (!mac_vnode_enforce) {
1717 		return 0;
1718 	}
1719 #endif
1720 	cred = vfs_context_ucred(ctx);
1721 	if (!mac_cred_check_enforce(cred)) {
1722 		return 0;
1723 	}
1724 	VFS_KERNEL_DEBUG_START1(55, vp);
1725 	MAC_CHECK(vnode_check_readlink, cred, vp, mac_vnode_label(vp));
1726 	VFS_KERNEL_DEBUG_END1(55, vp);
1727 	return error;
1728 }
1729 
1730 int
mac_vnode_check_label_update(vfs_context_t ctx,struct vnode * vp,struct label * newlabel)1731 mac_vnode_check_label_update(vfs_context_t ctx, struct vnode *vp,
1732     struct label *newlabel)
1733 {
1734 	kauth_cred_t cred;
1735 	int error;
1736 
1737 #if SECURITY_MAC_CHECK_ENFORCE
1738 	/* 21167099 - only check if we allow write */
1739 	if (!mac_vnode_enforce) {
1740 		return 0;
1741 	}
1742 #endif
1743 	cred = vfs_context_ucred(ctx);
1744 	if (!mac_cred_check_enforce(cred)) {
1745 		return 0;
1746 	}
1747 	VFS_KERNEL_DEBUG_START1(56, vp);
1748 	MAC_CHECK(vnode_check_label_update, cred, vp, mac_vnode_label(vp), newlabel);
1749 	VFS_KERNEL_DEBUG_END1(56, vp);
1750 
1751 	return error;
1752 }
1753 
1754 int
mac_vnode_check_rename(vfs_context_t ctx,struct vnode * dvp,struct vnode * vp,struct componentname * cnp,struct vnode * tdvp,struct vnode * tvp,struct componentname * tcnp)1755 mac_vnode_check_rename(vfs_context_t ctx, struct vnode *dvp,
1756     struct vnode *vp, struct componentname *cnp, struct vnode *tdvp,
1757     struct vnode *tvp, struct componentname *tcnp)
1758 {
1759 	kauth_cred_t cred;
1760 	int error;
1761 
1762 #if SECURITY_MAC_CHECK_ENFORCE
1763 	/* 21167099 - only check if we allow write */
1764 	if (!mac_vnode_enforce) {
1765 		return 0;
1766 	}
1767 #endif
1768 	cred = vfs_context_ucred(ctx);
1769 	if (!mac_cred_check_enforce(cred)) {
1770 		return 0;
1771 	}
1772 
1773 	VFS_KERNEL_DEBUG_START1(57, vp);
1774 	MAC_CHECK(vnode_check_rename_from, cred, dvp, mac_vnode_label(dvp), vp,
1775 	    mac_vnode_label(vp), cnp);
1776 	if (error) {
1777 		VFS_KERNEL_DEBUG_END1(57, vp);
1778 		return error;
1779 	}
1780 
1781 	MAC_CHECK(vnode_check_rename_to, cred, tdvp, mac_vnode_label(tdvp), tvp,
1782 	    tvp != NULL ? mac_vnode_label(tvp) : NULL, dvp == tdvp, tcnp);
1783 	if (error) {
1784 		VFS_KERNEL_DEBUG_END1(57, vp);
1785 		return error;
1786 	}
1787 
1788 	MAC_CHECK(vnode_check_rename, cred, dvp, mac_vnode_label(dvp), vp,
1789 	    mac_vnode_label(vp), cnp, tdvp, mac_vnode_label(tdvp), tvp,
1790 	    tvp != NULL ? mac_vnode_label(tvp) : NULL, tcnp);
1791 	VFS_KERNEL_DEBUG_END1(57, vp);
1792 	return error;
1793 }
1794 
1795 int
mac_vnode_check_revoke(vfs_context_t ctx,struct vnode * vp)1796 mac_vnode_check_revoke(vfs_context_t ctx, struct vnode *vp)
1797 {
1798 	kauth_cred_t cred;
1799 	int error;
1800 
1801 #if SECURITY_MAC_CHECK_ENFORCE
1802 	/* 21167099 - only check if we allow write */
1803 	if (!mac_vnode_enforce) {
1804 		return 0;
1805 	}
1806 #endif
1807 	cred = vfs_context_ucred(ctx);
1808 	if (!mac_cred_check_enforce(cred)) {
1809 		return 0;
1810 	}
1811 	VFS_KERNEL_DEBUG_START1(58, vp);
1812 	MAC_CHECK(vnode_check_revoke, cred, vp, mac_vnode_label(vp));
1813 	VFS_KERNEL_DEBUG_END1(58, vp);
1814 	return error;
1815 }
1816 
1817 int
mac_vnode_check_searchfs(vfs_context_t ctx,struct vnode * vp,struct attrlist * returnattrs,struct attrlist * searchattrs)1818 mac_vnode_check_searchfs(vfs_context_t ctx, struct vnode *vp, struct attrlist *returnattrs,
1819     struct attrlist *searchattrs)
1820 {
1821 	kauth_cred_t cred;
1822 	int error;
1823 
1824 #if SECURITY_MAC_CHECK_ENFORCE
1825 	/* 21167099 - only check if we allow write */
1826 	if (!mac_vnode_enforce) {
1827 		return 0;
1828 	}
1829 #endif
1830 	cred = vfs_context_ucred(ctx);
1831 	if (!mac_cred_check_enforce(cred)) {
1832 		return 0;
1833 	}
1834 	VFS_KERNEL_DEBUG_START1(59, vp);
1835 	MAC_CHECK(vnode_check_searchfs, cred, vp, mac_vnode_label(vp), returnattrs, searchattrs);
1836 	VFS_KERNEL_DEBUG_END1(59, vp);
1837 	return error;
1838 }
1839 
1840 int
mac_vnode_check_select(vfs_context_t ctx,struct vnode * vp,int which)1841 mac_vnode_check_select(vfs_context_t ctx, struct vnode *vp, int which)
1842 {
1843 	kauth_cred_t cred;
1844 	int error;
1845 
1846 #if SECURITY_MAC_CHECK_ENFORCE
1847 	/* 21167099 - only check if we allow write */
1848 	if (!mac_vnode_enforce) {
1849 		return 0;
1850 	}
1851 #endif
1852 	cred = vfs_context_ucred(ctx);
1853 	if (!mac_cred_check_enforce(cred)) {
1854 		return 0;
1855 	}
1856 	VFS_KERNEL_DEBUG_START1(60, vp);
1857 	MAC_CHECK(vnode_check_select, cred, vp, mac_vnode_label(vp), which);
1858 	VFS_KERNEL_DEBUG_END1(60, vp);
1859 	return error;
1860 }
1861 
1862 int
mac_vnode_check_setacl(vfs_context_t ctx,struct vnode * vp,struct kauth_acl * acl)1863 mac_vnode_check_setacl(vfs_context_t ctx, struct vnode *vp,
1864     struct kauth_acl *acl)
1865 {
1866 	kauth_cred_t cred;
1867 	int error;
1868 
1869 #if SECURITY_MAC_CHECK_ENFORCE
1870 	/* 21167099 - only check if we allow write */
1871 	if (!mac_vnode_enforce) {
1872 		return 0;
1873 	}
1874 #endif
1875 	cred = vfs_context_ucred(ctx);
1876 	if (!mac_cred_check_enforce(cred)) {
1877 		return 0;
1878 	}
1879 	VFS_KERNEL_DEBUG_START1(61, vp);
1880 	MAC_CHECK(vnode_check_setacl, cred, vp, mac_vnode_label(vp), acl);
1881 	VFS_KERNEL_DEBUG_END1(61, vp);
1882 	return error;
1883 }
1884 
1885 int
mac_vnode_check_setattrlist(vfs_context_t ctx,struct vnode * vp,struct attrlist * alist)1886 mac_vnode_check_setattrlist(vfs_context_t ctx, struct vnode *vp,
1887     struct attrlist *alist)
1888 {
1889 	kauth_cred_t cred;
1890 	int error;
1891 
1892 #if SECURITY_MAC_CHECK_ENFORCE
1893 	/* 21167099 - only check if we allow write */
1894 	if (!mac_vnode_enforce) {
1895 		return 0;
1896 	}
1897 #endif
1898 	cred = vfs_context_ucred(ctx);
1899 	if (!mac_cred_check_enforce(cred)) {
1900 		return 0;
1901 	}
1902 	VFS_KERNEL_DEBUG_START1(62, vp);
1903 	MAC_CHECK(vnode_check_setattrlist, cred, vp, mac_vnode_label(vp), alist);
1904 	VFS_KERNEL_DEBUG_END1(62, vp);
1905 	return error;
1906 }
1907 
1908 int
mac_vnode_check_setextattr(vfs_context_t ctx,struct vnode * vp,const char * name,struct uio * uio)1909 mac_vnode_check_setextattr(vfs_context_t ctx, struct vnode *vp,
1910     const char *name, struct uio *uio)
1911 {
1912 	kauth_cred_t cred;
1913 	int error;
1914 
1915 #if SECURITY_MAC_CHECK_ENFORCE
1916 	/* 21167099 - only check if we allow write */
1917 	if (!mac_vnode_enforce) {
1918 		return 0;
1919 	}
1920 #endif
1921 	cred = vfs_context_ucred(ctx);
1922 	if (!mac_cred_check_enforce(cred)) {
1923 		return 0;
1924 	}
1925 	VFS_KERNEL_DEBUG_START1(63, vp);
1926 	MAC_CHECK(vnode_check_setextattr, cred, vp, mac_vnode_label(vp),
1927 	    name, uio);
1928 	VFS_KERNEL_DEBUG_END1(63, vp);
1929 	return error;
1930 }
1931 
1932 int
mac_vnode_check_setflags(vfs_context_t ctx,struct vnode * vp,u_long flags)1933 mac_vnode_check_setflags(vfs_context_t ctx, struct vnode *vp, u_long flags)
1934 {
1935 	kauth_cred_t cred;
1936 	int error;
1937 
1938 #if SECURITY_MAC_CHECK_ENFORCE
1939 	/* 21167099 - only check if we allow write */
1940 	if (!mac_vnode_enforce) {
1941 		return 0;
1942 	}
1943 #endif
1944 	cred = vfs_context_ucred(ctx);
1945 	if (!mac_cred_check_enforce(cred)) {
1946 		return 0;
1947 	}
1948 	VFS_KERNEL_DEBUG_START1(64, vp);
1949 	MAC_CHECK(vnode_check_setflags, cred, vp, mac_vnode_label(vp), flags);
1950 	VFS_KERNEL_DEBUG_END1(64, vp);
1951 	return error;
1952 }
1953 
1954 int
mac_vnode_check_setmode(vfs_context_t ctx,struct vnode * vp,mode_t mode)1955 mac_vnode_check_setmode(vfs_context_t ctx, struct vnode *vp, mode_t mode)
1956 {
1957 	kauth_cred_t cred;
1958 	int error;
1959 
1960 #if SECURITY_MAC_CHECK_ENFORCE
1961 	/* 21167099 - only check if we allow write */
1962 	if (!mac_vnode_enforce) {
1963 		return 0;
1964 	}
1965 #endif
1966 	cred = vfs_context_ucred(ctx);
1967 	if (!mac_cred_check_enforce(cred)) {
1968 		return 0;
1969 	}
1970 	VFS_KERNEL_DEBUG_START1(65, vp);
1971 	MAC_CHECK(vnode_check_setmode, cred, vp, mac_vnode_label(vp), mode);
1972 	VFS_KERNEL_DEBUG_END1(65, vp);
1973 	return error;
1974 }
1975 
1976 int
mac_vnode_check_setowner(vfs_context_t ctx,struct vnode * vp,uid_t uid,gid_t gid)1977 mac_vnode_check_setowner(vfs_context_t ctx, struct vnode *vp, uid_t uid,
1978     gid_t gid)
1979 {
1980 	kauth_cred_t cred;
1981 	int error;
1982 
1983 #if SECURITY_MAC_CHECK_ENFORCE
1984 	/* 21167099 - only check if we allow write */
1985 	if (!mac_vnode_enforce) {
1986 		return 0;
1987 	}
1988 #endif
1989 	cred = vfs_context_ucred(ctx);
1990 	if (!mac_cred_check_enforce(cred)) {
1991 		return 0;
1992 	}
1993 	VFS_KERNEL_DEBUG_START1(66, vp);
1994 	MAC_CHECK(vnode_check_setowner, cred, vp, mac_vnode_label(vp), uid, gid);
1995 	VFS_KERNEL_DEBUG_END1(66, vp);
1996 	return error;
1997 }
1998 
1999 int
mac_vnode_check_setutimes(vfs_context_t ctx,struct vnode * vp,struct timespec atime,struct timespec mtime)2000 mac_vnode_check_setutimes(vfs_context_t ctx, struct vnode *vp,
2001     struct timespec atime, struct timespec mtime)
2002 {
2003 	kauth_cred_t cred;
2004 	int error;
2005 
2006 #if SECURITY_MAC_CHECK_ENFORCE
2007 	/* 21167099 - only check if we allow write */
2008 	if (!mac_vnode_enforce) {
2009 		return 0;
2010 	}
2011 #endif
2012 	cred = vfs_context_ucred(ctx);
2013 	if (!mac_cred_check_enforce(cred)) {
2014 		return 0;
2015 	}
2016 	VFS_KERNEL_DEBUG_START1(67, vp);
2017 	MAC_CHECK(vnode_check_setutimes, cred, vp, mac_vnode_label(vp), atime,
2018 	    mtime);
2019 	VFS_KERNEL_DEBUG_END1(67, vp);
2020 	return error;
2021 }
2022 
2023 int
mac_vnode_check_stat(vfs_context_t ctx,struct ucred * file_cred,struct vnode * vp)2024 mac_vnode_check_stat(vfs_context_t ctx, struct ucred *file_cred,
2025     struct vnode *vp)
2026 {
2027 	kauth_cred_t cred;
2028 	int error;
2029 
2030 #if SECURITY_MAC_CHECK_ENFORCE
2031 	/* 21167099 - only check if we allow write */
2032 	if (!mac_vnode_enforce) {
2033 		return 0;
2034 	}
2035 #endif
2036 	cred = vfs_context_ucred(ctx);
2037 	if (!mac_cred_check_enforce(cred)) {
2038 		return 0;
2039 	}
2040 	VFS_KERNEL_DEBUG_START1(68, vp);
2041 	MAC_CHECK(vnode_check_stat, cred, file_cred, vp,
2042 	    mac_vnode_label(vp));
2043 	VFS_KERNEL_DEBUG_END1(68, vp);
2044 	return error;
2045 }
2046 
2047 int
mac_vnode_check_trigger_resolve(vfs_context_t ctx,struct vnode * dvp,struct componentname * cnp)2048 mac_vnode_check_trigger_resolve(vfs_context_t ctx, struct vnode *dvp,
2049     struct componentname *cnp)
2050 {
2051 	kauth_cred_t cred;
2052 	int error;
2053 
2054 #if SECURITY_MAC_CHECK_ENFORCE
2055 	/* 21167099 - only check if we allow write */
2056 	if (!mac_vnode_enforce) {
2057 		return 0;
2058 	}
2059 #endif
2060 	cred = vfs_context_ucred(ctx);
2061 	if (!mac_cred_check_enforce(cred)) {
2062 		return 0;
2063 	}
2064 	VFS_KERNEL_DEBUG_START1(69, dvp);
2065 	MAC_CHECK(vnode_check_trigger_resolve, cred, dvp, mac_vnode_label(dvp), cnp);
2066 	VFS_KERNEL_DEBUG_END1(69, dvp);
2067 	return error;
2068 }
2069 
2070 int
mac_vnode_check_truncate(vfs_context_t ctx,struct ucred * file_cred,struct vnode * vp)2071 mac_vnode_check_truncate(vfs_context_t ctx, struct ucred *file_cred,
2072     struct vnode *vp)
2073 {
2074 	kauth_cred_t cred;
2075 	int error;
2076 
2077 #if SECURITY_MAC_CHECK_ENFORCE
2078 	/* 21167099 - only check if we allow write */
2079 	if (!mac_vnode_enforce) {
2080 		return 0;
2081 	}
2082 #endif
2083 	cred = vfs_context_ucred(ctx);
2084 	if (!mac_cred_check_enforce(cred)) {
2085 		return 0;
2086 	}
2087 	VFS_KERNEL_DEBUG_START1(70, vp);
2088 	MAC_CHECK(vnode_check_truncate, cred, file_cred, vp,
2089 	    mac_vnode_label(vp));
2090 	VFS_KERNEL_DEBUG_END1(70, vp);
2091 
2092 	return error;
2093 }
2094 
2095 int
mac_vnode_check_write(vfs_context_t ctx,struct ucred * file_cred,struct vnode * vp)2096 mac_vnode_check_write(vfs_context_t ctx, struct ucred *file_cred,
2097     struct vnode *vp)
2098 {
2099 	kauth_cred_t cred;
2100 	int error;
2101 
2102 #if SECURITY_MAC_CHECK_ENFORCE
2103 	/* 21167099 - only check if we allow write */
2104 	if (!mac_vnode_enforce) {
2105 		return 0;
2106 	}
2107 #endif
2108 	cred = vfs_context_ucred(ctx);
2109 	if (!mac_cred_check_enforce(cred)) {
2110 		return 0;
2111 	}
2112 	VFS_KERNEL_DEBUG_START1(71, vp);
2113 	MAC_CHECK(vnode_check_write, cred, file_cred, vp, mac_vnode_label(vp));
2114 	VFS_KERNEL_DEBUG_END1(71, vp);
2115 
2116 	return error;
2117 }
2118 
2119 int
mac_vnode_check_uipc_bind(vfs_context_t ctx,struct vnode * dvp,struct componentname * cnp,struct vnode_attr * vap)2120 mac_vnode_check_uipc_bind(vfs_context_t ctx, struct vnode *dvp,
2121     struct componentname *cnp, struct vnode_attr *vap)
2122 {
2123 	kauth_cred_t cred;
2124 	int error;
2125 
2126 #if SECURITY_MAC_CHECK_ENFORCE
2127 	/* 21167099 - only check if we allow write */
2128 	if (!mac_vnode_enforce) {
2129 		return 0;
2130 	}
2131 #endif
2132 	cred = vfs_context_ucred(ctx);
2133 	if (!mac_cred_check_enforce(cred)) {
2134 		return 0;
2135 	}
2136 	VFS_KERNEL_DEBUG_START1(72, dvp);
2137 	MAC_CHECK(vnode_check_uipc_bind, cred, dvp, mac_vnode_label(dvp), cnp, vap);
2138 	VFS_KERNEL_DEBUG_END1(72, dvp);
2139 	return error;
2140 }
2141 
2142 int
mac_vnode_check_uipc_connect(vfs_context_t ctx,struct vnode * vp,struct socket * so)2143 mac_vnode_check_uipc_connect(vfs_context_t ctx, struct vnode *vp, struct socket *so)
2144 {
2145 	kauth_cred_t cred;
2146 	int error;
2147 
2148 #if SECURITY_MAC_CHECK_ENFORCE
2149 	/* 21167099 - only check if we allow write */
2150 	if (!mac_vnode_enforce) {
2151 		return 0;
2152 	}
2153 #endif
2154 	cred = vfs_context_ucred(ctx);
2155 	if (!mac_cred_check_enforce(cred)) {
2156 		return 0;
2157 	}
2158 	VFS_KERNEL_DEBUG_START1(73, vp);
2159 	MAC_CHECK(vnode_check_uipc_connect, cred, vp, mac_vnode_label(vp), (socket_t) so);
2160 	VFS_KERNEL_DEBUG_END1(73, vp);
2161 	return error;
2162 }
2163 
2164 void
mac_vnode_label_update(vfs_context_t ctx,struct vnode * vp,struct label * newlabel)2165 mac_vnode_label_update(vfs_context_t ctx, struct vnode *vp, struct label *newlabel)
2166 {
2167 	kauth_cred_t cred = vfs_context_ucred(ctx);
2168 	struct label *tmpl = NULL;
2169 
2170 	if (mac_vnode_label(vp) == NULL) {
2171 		tmpl = mac_vnode_label_alloc(vp);
2172 	}
2173 
2174 	vnode_lock(vp);
2175 
2176 	/*
2177 	 * Recheck under lock.  We allocate labels for vnodes lazily, so
2178 	 * somebody else might have already got here first.
2179 	 */
2180 	if (mac_vnode_label(vp) == NULL) {
2181 		vp->v_label = tmpl;
2182 		tmpl = NULL;
2183 	}
2184 
2185 	VFS_KERNEL_DEBUG_START1(74, vp);
2186 	MAC_PERFORM(vnode_label_update, cred, vp, mac_vnode_label(vp), newlabel);
2187 	VFS_KERNEL_DEBUG_END1(74, vp);
2188 	vnode_unlock(vp);
2189 
2190 	if (tmpl != NULL) {
2191 		mac_vnode_label_free(tmpl);
2192 	}
2193 }
2194 
2195 int
mac_vnode_find_sigs(struct proc * p,struct vnode * vp,off_t offset)2196 mac_vnode_find_sigs(struct proc *p, struct vnode *vp, off_t offset)
2197 {
2198 	int error;
2199 
2200 #if SECURITY_MAC_CHECK_ENFORCE
2201 	/* 21167099 - only check if we allow write */
2202 	if (!mac_proc_enforce || !mac_vnode_enforce) {
2203 		return 0;
2204 	}
2205 #endif
2206 
2207 	VFS_KERNEL_DEBUG_START1(75, vp);
2208 	MAC_CHECK(vnode_find_sigs, p, vp, offset, mac_vnode_label(vp));
2209 	VFS_KERNEL_DEBUG_END1(75, vp);
2210 
2211 	return error;
2212 }
2213 
2214 void
mac_mount_label_associate(vfs_context_t ctx,struct mount * mp)2215 mac_mount_label_associate(vfs_context_t ctx, struct mount *mp)
2216 {
2217 	kauth_cred_t cred = vfs_context_ucred(ctx);
2218 
2219 	/* XXX: eventually this logic may be handled by the policy? */
2220 
2221 	/* We desire MULTILABEL for the root filesystem. */
2222 	if ((mp->mnt_flag & MNT_ROOTFS) &&
2223 	    (strcmp(mp->mnt_vfsstat.f_fstypename, "hfs") == 0)) {
2224 		mp->mnt_flag |= MNT_MULTILABEL;
2225 	}
2226 
2227 	/* MULTILABEL on DEVFS. */
2228 	if (strcmp(mp->mnt_vfsstat.f_fstypename, "devfs") == 0) {
2229 		mp->mnt_flag |= MNT_MULTILABEL;
2230 	}
2231 
2232 	/* MULTILABEL on FDESC pseudo-filesystem. */
2233 	if (strcmp(mp->mnt_vfsstat.f_fstypename, "fdesc") == 0) {
2234 		mp->mnt_flag |= MNT_MULTILABEL;
2235 	}
2236 
2237 	/* MULTILABEL on all NFS filesystems. */
2238 	if (strcmp(mp->mnt_vfsstat.f_fstypename, "nfs") == 0) {
2239 		mp->mnt_flag |= MNT_MULTILABEL;
2240 	}
2241 
2242 	/* MULTILABEL on all AFP filesystems. */
2243 	if (strcmp(mp->mnt_vfsstat.f_fstypename, "afpfs") == 0) {
2244 		mp->mnt_flag |= MNT_MULTILABEL;
2245 	}
2246 
2247 	if (mp->mnt_vtable != NULL) {
2248 		/* Any filesystem that supports native XATTRs. */
2249 		if ((mp->mnt_vtable->vfc_vfsflags & VFC_VFSNATIVEXATTR)) {
2250 			mp->mnt_flag |= MNT_MULTILABEL;
2251 		}
2252 
2253 		/* Filesystem does not support multilabel. */
2254 		if ((mp->mnt_vtable->vfc_vfsflags & VFC_VFSNOMACLABEL) &&
2255 		    (mp->mnt_flag & MNT_MULTILABEL)) {
2256 			mp->mnt_flag &= ~MNT_MULTILABEL;
2257 		}
2258 	}
2259 
2260 	VFS_KERNEL_DEBUG_START1(76, mp);
2261 	MAC_PERFORM(mount_label_associate, cred, mp, mac_mount_label(mp));
2262 	VFS_KERNEL_DEBUG_END1(76, mp);
2263 #if DEBUG
2264 	printf("MAC Framework enabling %s support: %s -> %s (%s)\n",
2265 	    mp->mnt_flag & MNT_MULTILABEL ? "multilabel" : "singlelabel",
2266 	    mp->mnt_vfsstat.f_mntfromname,
2267 	    mp->mnt_vfsstat.f_mntonname,
2268 	    mp->mnt_vfsstat.f_fstypename);
2269 #endif
2270 }
2271 
2272 int
mac_mount_check_mount(vfs_context_t ctx,struct vnode * vp,struct componentname * cnp,const char * vfc_name)2273 mac_mount_check_mount(vfs_context_t ctx, struct vnode *vp,
2274     struct componentname *cnp, const char *vfc_name)
2275 {
2276 	kauth_cred_t cred;
2277 	int error;
2278 
2279 #if SECURITY_MAC_CHECK_ENFORCE
2280 	/* 21167099 - only check if we allow write */
2281 	if (!mac_vnode_enforce) {
2282 		return 0;
2283 	}
2284 #endif
2285 	cred = vfs_context_ucred(ctx);
2286 	if (!mac_cred_check_enforce(cred)) {
2287 		return 0;
2288 	}
2289 	VFS_KERNEL_DEBUG_START1(77, vp);
2290 	MAC_CHECK(mount_check_mount, cred, vp, mac_vnode_label(vp), cnp, vfc_name);
2291 	VFS_KERNEL_DEBUG_END1(77, vp);
2292 
2293 	return error;
2294 }
2295 
2296 int
mac_mount_check_mount_late(vfs_context_t ctx,struct mount * mp)2297 mac_mount_check_mount_late(vfs_context_t ctx, struct mount *mp)
2298 {
2299 	kauth_cred_t cred;
2300 	int error;
2301 
2302 #if SECURITY_MAC_CHECK_ENFORCE
2303 	/* 21167099 - only check if we allow write */
2304 	if (!mac_vnode_enforce) {
2305 		return 0;
2306 	}
2307 #endif
2308 	cred = vfs_context_ucred(ctx);
2309 	if (!mac_cred_check_enforce(cred)) {
2310 		return 0;
2311 	}
2312 	VFS_KERNEL_DEBUG_START1(78, mp);
2313 	MAC_CHECK(mount_check_mount_late, cred, mp);
2314 	VFS_KERNEL_DEBUG_END1(78, mp);
2315 
2316 	return error;
2317 }
2318 
2319 int
mac_mount_check_snapshot_create(vfs_context_t ctx,struct mount * mp,const char * name)2320 mac_mount_check_snapshot_create(vfs_context_t ctx, struct mount *mp,
2321     const char *name)
2322 {
2323 	kauth_cred_t cred;
2324 	int error;
2325 
2326 #if SECURITY_MAC_CHECK_ENFORCE
2327 	/* 21167099 - only check if we allow write */
2328 	if (!mac_vnode_enforce) {
2329 		return 0;
2330 	}
2331 #endif
2332 	cred = vfs_context_ucred(ctx);
2333 	if (!mac_cred_check_enforce(cred)) {
2334 		return 0;
2335 	}
2336 	VFS_KERNEL_DEBUG_START1(79, mp);
2337 	MAC_CHECK(mount_check_snapshot_create, cred, mp, name);
2338 	VFS_KERNEL_DEBUG_END1(79, mp);
2339 	return error;
2340 }
2341 
2342 int
mac_mount_check_snapshot_delete(vfs_context_t ctx,struct mount * mp,const char * name)2343 mac_mount_check_snapshot_delete(vfs_context_t ctx, struct mount *mp,
2344     const char *name)
2345 {
2346 	kauth_cred_t cred;
2347 	int error;
2348 
2349 #if SECURITY_MAC_CHECK_ENFORCE
2350 	/* 21167099 - only check if we allow write */
2351 	if (!mac_vnode_enforce) {
2352 		return 0;
2353 	}
2354 #endif
2355 	cred = vfs_context_ucred(ctx);
2356 	if (!mac_cred_check_enforce(cred)) {
2357 		return 0;
2358 	}
2359 	VFS_KERNEL_DEBUG_START1(80, mp);
2360 	MAC_CHECK(mount_check_snapshot_delete, cred, mp, name);
2361 	VFS_KERNEL_DEBUG_END1(80, mp);
2362 	return error;
2363 }
2364 
2365 int
mac_mount_check_snapshot_mount(vfs_context_t ctx,struct vnode * rvp,struct vnode * vp,struct componentname * cnp,const char * name,const char * vfc_name)2366 mac_mount_check_snapshot_mount(vfs_context_t ctx, struct vnode *rvp, struct vnode *vp, struct componentname *cnp,
2367     const char *name, const char *vfc_name)
2368 {
2369 	kauth_cred_t cred;
2370 	int error;
2371 
2372 #if SECURITY_MAC_CHECK_ENFORCE
2373 	/* 21167099 - only check if we allow write */
2374 	if (!mac_vnode_enforce) {
2375 		return 0;
2376 	}
2377 #endif
2378 	cred = vfs_context_ucred(ctx);
2379 	if (!mac_cred_check_enforce(cred)) {
2380 		return 0;
2381 	}
2382 	VFS_KERNEL_DEBUG_START1(92, vp);
2383 	MAC_CHECK(mount_check_snapshot_mount, cred, rvp, vp, cnp, name, vfc_name);
2384 	VFS_KERNEL_DEBUG_END1(92, vp);
2385 	return error;
2386 }
2387 
2388 int
mac_mount_check_snapshot_revert(vfs_context_t ctx,struct mount * mp,const char * name)2389 mac_mount_check_snapshot_revert(vfs_context_t ctx, struct mount *mp,
2390     const char *name)
2391 {
2392 	kauth_cred_t cred;
2393 	int error;
2394 
2395 #if SECURITY_MAC_CHECK_ENFORCE
2396 	/* 21167099 - only check if we allow write */
2397 	if (!mac_vnode_enforce) {
2398 		return 0;
2399 	}
2400 #endif
2401 	cred = vfs_context_ucred(ctx);
2402 	if (!mac_cred_check_enforce(cred)) {
2403 		return 0;
2404 	}
2405 	VFS_KERNEL_DEBUG_START1(81, mp);
2406 	MAC_CHECK(mount_check_snapshot_revert, cred, mp, name);
2407 	VFS_KERNEL_DEBUG_END1(81, mp);
2408 	return error;
2409 }
2410 
2411 int
mac_mount_check_remount(vfs_context_t ctx,struct mount * mp)2412 mac_mount_check_remount(vfs_context_t ctx, struct mount *mp)
2413 {
2414 	kauth_cred_t cred;
2415 	int error;
2416 
2417 #if SECURITY_MAC_CHECK_ENFORCE
2418 	/* 21167099 - only check if we allow write */
2419 	if (!mac_vnode_enforce) {
2420 		return 0;
2421 	}
2422 #endif
2423 	cred = vfs_context_ucred(ctx);
2424 	if (!mac_cred_check_enforce(cred)) {
2425 		return 0;
2426 	}
2427 	VFS_KERNEL_DEBUG_START1(82, mp);
2428 	MAC_CHECK(mount_check_remount, cred, mp, mac_mount_label(mp));
2429 	VFS_KERNEL_DEBUG_END1(82, mp);
2430 
2431 	return error;
2432 }
2433 
2434 int
mac_mount_check_umount(vfs_context_t ctx,struct mount * mp)2435 mac_mount_check_umount(vfs_context_t ctx, struct mount *mp)
2436 {
2437 	kauth_cred_t cred;
2438 	int error;
2439 
2440 #if SECURITY_MAC_CHECK_ENFORCE
2441 	/* 21167099 - only check if we allow write */
2442 	if (!mac_vnode_enforce) {
2443 		return 0;
2444 	}
2445 #endif
2446 	cred = vfs_context_ucred(ctx);
2447 	if (!mac_cred_check_enforce(cred)) {
2448 		return 0;
2449 	}
2450 	VFS_KERNEL_DEBUG_START1(83, mp);
2451 	MAC_CHECK(mount_check_umount, cred, mp, mac_mount_label(mp));
2452 	VFS_KERNEL_DEBUG_END1(83, mp);
2453 
2454 	return error;
2455 }
2456 
2457 int
mac_mount_check_getattr(vfs_context_t ctx,struct mount * mp,struct vfs_attr * vfa)2458 mac_mount_check_getattr(vfs_context_t ctx, struct mount *mp,
2459     struct vfs_attr *vfa)
2460 {
2461 	kauth_cred_t cred;
2462 	int error;
2463 
2464 #if SECURITY_MAC_CHECK_ENFORCE
2465 	/* 21167099 - only check if we allow write */
2466 	if (!mac_vnode_enforce) {
2467 		return 0;
2468 	}
2469 #endif
2470 	cred = vfs_context_ucred(ctx);
2471 	if (!mac_cred_check_enforce(cred)) {
2472 		return 0;
2473 	}
2474 	VFS_KERNEL_DEBUG_START1(84, mp);
2475 	MAC_CHECK(mount_check_getattr, cred, mp, mac_mount_label(mp), vfa);
2476 	VFS_KERNEL_DEBUG_END1(84, mp);
2477 	return error;
2478 }
2479 
2480 int
mac_mount_check_setattr(vfs_context_t ctx,struct mount * mp,struct vfs_attr * vfa)2481 mac_mount_check_setattr(vfs_context_t ctx, struct mount *mp,
2482     struct vfs_attr *vfa)
2483 {
2484 	kauth_cred_t cred;
2485 	int error;
2486 
2487 #if SECURITY_MAC_CHECK_ENFORCE
2488 	/* 21167099 - only check if we allow write */
2489 	if (!mac_vnode_enforce) {
2490 		return 0;
2491 	}
2492 #endif
2493 	cred = vfs_context_ucred(ctx);
2494 	if (!mac_cred_check_enforce(cred)) {
2495 		return 0;
2496 	}
2497 	VFS_KERNEL_DEBUG_START1(85, mp);
2498 	MAC_CHECK(mount_check_setattr, cred, mp, mac_mount_label(mp), vfa);
2499 	VFS_KERNEL_DEBUG_END1(85, mp);
2500 	return error;
2501 }
2502 
2503 int
mac_mount_check_stat(vfs_context_t ctx,struct mount * mount)2504 mac_mount_check_stat(vfs_context_t ctx, struct mount *mount)
2505 {
2506 	kauth_cred_t cred;
2507 	int error;
2508 
2509 #if SECURITY_MAC_CHECK_ENFORCE
2510 	/* 21167099 - only check if we allow write */
2511 	if (!mac_vnode_enforce) {
2512 		return 0;
2513 	}
2514 #endif
2515 	cred = vfs_context_ucred(ctx);
2516 	if (!mac_cred_check_enforce(cred)) {
2517 		return 0;
2518 	}
2519 	VFS_KERNEL_DEBUG_START1(86, mount);
2520 	MAC_CHECK(mount_check_stat, cred, mount, mac_mount_label(mount));
2521 	VFS_KERNEL_DEBUG_END1(86, mount);
2522 
2523 	return error;
2524 }
2525 
2526 int
mac_mount_check_label_update(vfs_context_t ctx,struct mount * mount)2527 mac_mount_check_label_update(vfs_context_t ctx, struct mount *mount)
2528 {
2529 	kauth_cred_t cred;
2530 	int error;
2531 
2532 #if SECURITY_MAC_CHECK_ENFORCE
2533 	/* 21167099 - only check if we allow write */
2534 	if (!mac_vnode_enforce) {
2535 		return 0;
2536 	}
2537 #endif
2538 	cred = vfs_context_ucred(ctx);
2539 	if (!mac_cred_check_enforce(cred)) {
2540 		return 0;
2541 	}
2542 	VFS_KERNEL_DEBUG_START1(87, mount);
2543 	MAC_CHECK(mount_check_label_update, cred, mount, mac_mount_label(mount));
2544 	VFS_KERNEL_DEBUG_END1(87, mount);
2545 
2546 	return error;
2547 }
2548 
2549 int
mac_mount_check_fsctl(vfs_context_t ctx,struct mount * mp,u_long cmd)2550 mac_mount_check_fsctl(vfs_context_t ctx, struct mount *mp, u_long cmd)
2551 {
2552 	kauth_cred_t cred;
2553 	int error;
2554 
2555 #if SECURITY_MAC_CHECK_ENFORCE
2556 	/* 21167099 - only check if we allow write */
2557 	if (!mac_vnode_enforce) {
2558 		return 0;
2559 	}
2560 #endif
2561 	cred = vfs_context_ucred(ctx);
2562 	if (!mac_cred_check_enforce(cred)) {
2563 		return 0;
2564 	}
2565 	VFS_KERNEL_DEBUG_START1(88, mp);
2566 	MAC_CHECK(mount_check_fsctl, cred, mp, mac_mount_label(mp), cmd);
2567 	VFS_KERNEL_DEBUG_END1(88, mp);
2568 
2569 	return error;
2570 }
2571 
2572 void
mac_devfs_label_associate_device(dev_t dev,struct devnode * de,const char * fullpath)2573 mac_devfs_label_associate_device(dev_t dev, struct devnode *de,
2574     const char *fullpath)
2575 {
2576 #if SECURITY_MAC_CHECK_ENFORCE
2577 	/* 21167099 - only check if we allow write */
2578 	if (!mac_device_enforce) {
2579 		return;
2580 	}
2581 #endif
2582 
2583 	VFS_KERNEL_DEBUG_START1(89, de);
2584 	MAC_PERFORM(devfs_label_associate_device, dev, de, mac_devfs_label(de),
2585 	    fullpath);
2586 	VFS_KERNEL_DEBUG_END1(89, de);
2587 }
2588 
2589 void
mac_devfs_label_associate_directory(const char * dirname,int dirnamelen,struct devnode * de,const char * fullpath)2590 mac_devfs_label_associate_directory(const char *dirname, int dirnamelen,
2591     struct devnode *de, const char *fullpath)
2592 {
2593 #if SECURITY_MAC_CHECK_ENFORCE
2594 	/* 21167099 - only check if we allow write */
2595 	if (!mac_device_enforce) {
2596 		return;
2597 	}
2598 #endif
2599 
2600 	VFS_KERNEL_DEBUG_START1(90, de);
2601 	MAC_PERFORM(devfs_label_associate_directory, dirname, dirnamelen, de,
2602 	    mac_devfs_label(de), fullpath);
2603 	VFS_KERNEL_DEBUG_END1(90, de);
2604 }
2605 
2606 int
vn_setlabel(struct vnode * vp,struct label * intlabel,vfs_context_t context)2607 vn_setlabel(struct vnode *vp, struct label *intlabel, vfs_context_t context)
2608 {
2609 	int error;
2610 
2611 #if SECURITY_MAC_CHECK_ENFORCE
2612 	/* 21167099 - only check if we allow write */
2613 	if (!mac_vnode_enforce) {
2614 		return 0;
2615 	}
2616 #endif
2617 	if (!mac_label_vnodes) {
2618 		return 0;
2619 	}
2620 
2621 	if (vp->v_mount == NULL) {
2622 		printf("vn_setlabel: null v_mount\n");
2623 		if (vp->v_type != VNON) {
2624 			printf("vn_setlabel: null v_mount with non-VNON\n");
2625 		}
2626 		return EBADF;
2627 	}
2628 
2629 	if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) {
2630 		return ENOTSUP;
2631 	}
2632 
2633 	/*
2634 	 * Multi-phase commit.  First check the policies to confirm the
2635 	 * change is OK.  Then commit via the filesystem.  Finally,
2636 	 * update the actual vnode label.  Question: maybe the filesystem
2637 	 * should update the vnode at the end as part of VNOP_SETLABEL()?
2638 	 */
2639 	error = mac_vnode_check_label_update(context, vp, intlabel);
2640 	if (error) {
2641 		return error;
2642 	}
2643 
2644 	error = VNOP_SETLABEL(vp, intlabel, context);
2645 	if (error == ENOTSUP) {
2646 		error = mac_vnode_label_store(context, vp,
2647 		    intlabel);
2648 		if (error) {
2649 			printf("%s: mac_vnode_label_store failed %d\n",
2650 			    __func__, error);
2651 			return error;
2652 		}
2653 		mac_vnode_label_update(context, vp, intlabel);
2654 	} else if (error) {
2655 		printf("vn_setlabel: vop setlabel failed %d\n", error);
2656 		return error;
2657 	}
2658 
2659 	return 0;
2660 }
2661 
2662 int
mac_vnode_label_associate_fdesc(struct mount * mp,struct fdescnode * fnp,struct vnode * vp,vfs_context_t ctx)2663 mac_vnode_label_associate_fdesc(struct mount *mp, struct fdescnode *fnp,
2664     struct vnode *vp, vfs_context_t ctx)
2665 {
2666 	struct fileproc *fp;
2667 #if CONFIG_MACF_SOCKET_SUBSET
2668 	struct socket *so;
2669 #endif
2670 	struct pipe *cpipe;
2671 	struct vnode *fvp;
2672 	struct proc *p;
2673 	int error;
2674 
2675 	error = 0;
2676 
2677 	VFS_KERNEL_DEBUG_START1(91, vp);
2678 	/*
2679 	 * If no backing file, let the policy choose which label to use.
2680 	 */
2681 	if (fnp->fd_fd == -1) {
2682 		MAC_PERFORM(vnode_label_associate_file, vfs_context_ucred(ctx),
2683 		    mp, mac_mount_label(mp), NULL, NULL, vp, mac_vnode_label(vp));
2684 		VFS_KERNEL_DEBUG_END1(91, vp);
2685 		return 0;
2686 	}
2687 
2688 	p = vfs_context_proc(ctx);
2689 	error = fp_lookup(p, fnp->fd_fd, &fp, 0);
2690 	if (error) {
2691 		VFS_KERNEL_DEBUG_END1(91, vp);
2692 		return error;
2693 	}
2694 
2695 	if (fp->fp_glob == NULL) {
2696 		error = EBADF;
2697 		goto out;
2698 	}
2699 
2700 	switch (FILEGLOB_DTYPE(fp->fp_glob)) {
2701 	case DTYPE_VNODE:
2702 		fvp = (struct vnode *)fp_get_data(fp);
2703 		if ((error = vnode_getwithref(fvp))) {
2704 			goto out;
2705 		}
2706 		if (mac_vnode_label(fvp) != NULL) {
2707 			if (mac_label_vnodes != 0 && mac_vnode_label(vp) == NULL) {
2708 				mac_vnode_label_init(vp); /* init dst label */
2709 			}
2710 			MAC_PERFORM(vnode_label_copy, mac_vnode_label(fvp), mac_vnode_label(vp));
2711 		}
2712 		(void)vnode_put(fvp);
2713 		break;
2714 #if CONFIG_MACF_SOCKET_SUBSET
2715 	case DTYPE_SOCKET:
2716 		so = (struct socket *)fp_get_data(fp);
2717 		socket_lock(so, 1);
2718 		MAC_PERFORM(vnode_label_associate_socket,
2719 		    vfs_context_ucred(ctx), (socket_t)so, NULL,
2720 		    vp, mac_vnode_label(vp));
2721 		socket_unlock(so, 1);
2722 		break;
2723 #endif
2724 	case DTYPE_PSXSHM:
2725 		pshm_label_associate(fp, vp, ctx);
2726 		break;
2727 	case DTYPE_PSXSEM:
2728 		psem_label_associate(fp, vp, ctx);
2729 		break;
2730 	case DTYPE_PIPE:
2731 		cpipe = (struct pipe *)fp_get_data(fp);
2732 		/* kern/sys_pipe.c:pipe_select() suggests this test. */
2733 		if (cpipe == (struct pipe *)-1) {
2734 			error = EINVAL;
2735 			goto out;
2736 		}
2737 		PIPE_LOCK(cpipe);
2738 		MAC_PERFORM(vnode_label_associate_pipe, vfs_context_ucred(ctx),
2739 		    cpipe, mac_pipe_label(cpipe), vp, mac_vnode_label(vp));
2740 		PIPE_UNLOCK(cpipe);
2741 		break;
2742 	case DTYPE_KQUEUE:
2743 	case DTYPE_FSEVENTS:
2744 	case DTYPE_ATALK:
2745 	case DTYPE_NETPOLICY:
2746 	default:
2747 		MAC_PERFORM(vnode_label_associate_file, vfs_context_ucred(ctx),
2748 		    mp, mac_mount_label(mp), fp->fp_glob, NULL,
2749 		    vp, mac_vnode_label(vp));
2750 		break;
2751 	}
2752 out:
2753 	VFS_KERNEL_DEBUG_END1(91, vp);
2754 	fp_drop(p, fnp->fd_fd, fp, 0);
2755 	return error;
2756 }
2757 
2758 intptr_t
mac_vnode_label_get(struct vnode * vp,int slot,intptr_t sentinel)2759 mac_vnode_label_get(struct vnode *vp, int slot, intptr_t sentinel)
2760 {
2761 	struct label *l;
2762 
2763 	KASSERT(vp != NULL, ("mac_vnode_label_get: NULL vnode"));
2764 	l = mac_vnode_label(vp);
2765 	if (l != NULL) {
2766 		return mac_label_get(l, slot);
2767 	} else {
2768 		return sentinel;
2769 	}
2770 }
2771 
2772 void
mac_vnode_label_set(struct vnode * vp,int slot,intptr_t v)2773 mac_vnode_label_set(struct vnode *vp, int slot, intptr_t v)
2774 {
2775 	struct label *l;
2776 	KASSERT(vp != NULL, ("mac_vnode_label_set: NULL vnode"));
2777 	l = mac_vnode_label(vp);
2778 	if (l == NULL) {
2779 		mac_vnode_label_init(vp);
2780 		l = mac_vnode_label(vp);
2781 	}
2782 	mac_label_set(l, slot, v);
2783 }
2784 
2785 void
mac_vnode_notify_reclaim(struct vnode * vp)2786 mac_vnode_notify_reclaim(struct vnode *vp)
2787 {
2788 	VFS_KERNEL_DEBUG_START1(94, vp);
2789 	MAC_PERFORM(vnode_notify_reclaim, vp);
2790 	VFS_KERNEL_DEBUG_END1(94, vp);
2791 }
2792 
2793 int
mac_mount_check_quotactl(vfs_context_t ctx,struct mount * mp,int cmd,int id)2794 mac_mount_check_quotactl(vfs_context_t ctx, struct mount *mp, int cmd, int id)
2795 {
2796 	kauth_cred_t cred;
2797 	int error;
2798 
2799 #if SECURITY_MAC_CHECK_ENFORCE
2800 	/* 21167099 - only check if we allow write */
2801 	if (!mac_vnode_enforce) {
2802 		return 0;
2803 	}
2804 #endif
2805 	cred = vfs_context_ucred(ctx);
2806 	if (!mac_cred_check_enforce(cred)) {
2807 		return 0;
2808 	}
2809 	VFS_KERNEL_DEBUG_START1(95, mp);
2810 	MAC_CHECK(mount_check_quotactl, cred, mp, cmd, id);
2811 	VFS_KERNEL_DEBUG_END1(95, mp);
2812 
2813 	return error;
2814 }
2815 
2816 int
mac_vnode_check_getattrlistbulk(vfs_context_t ctx,struct vnode * vp,struct attrlist * alist,uint64_t options)2817 mac_vnode_check_getattrlistbulk(vfs_context_t ctx, struct vnode *vp, struct attrlist *alist, uint64_t options)
2818 {
2819 	kauth_cred_t cred;
2820 	int error;
2821 
2822 #if SECURITY_MAC_CHECK_ENFORCE
2823 	/* 21167099 - only check if we allow write */
2824 	if (!mac_vnode_enforce) {
2825 		return 0;
2826 	}
2827 #endif
2828 	cred = vfs_context_ucred(ctx);
2829 	if (!mac_cred_check_enforce(cred)) {
2830 		return 0;
2831 	}
2832 	VFS_KERNEL_DEBUG_START1(96, mp);
2833 	MAC_CHECK(vnode_check_getattrlistbulk, cred, vp, alist, options);
2834 	VFS_KERNEL_DEBUG_END1(96, mp);
2835 
2836 	return error;
2837 }
2838 
2839 int
mac_vnode_check_copyfile(vfs_context_t ctx,struct vnode * dvp,struct vnode * tvp,struct vnode * fvp,struct componentname * cnp,mode_t mode,int flags)2840 mac_vnode_check_copyfile(vfs_context_t ctx, struct vnode *dvp,
2841     struct vnode *tvp, struct vnode *fvp, struct componentname *cnp,
2842     mode_t mode, int flags)
2843 {
2844 	kauth_cred_t cred;
2845 	int error;
2846 
2847 #if SECURITY_MAC_CHECK_ENFORCE
2848 	/* 21167099 - only check if we allow write */
2849 	if (!mac_vnode_enforce) {
2850 		return 0;
2851 	}
2852 #endif
2853 	cred = vfs_context_ucred(ctx);
2854 	if (!mac_cred_check_enforce(cred)) {
2855 		return 0;
2856 	}
2857 	VFS_KERNEL_DEBUG_START1(97, dvp);
2858 	MAC_CHECK(vnode_check_copyfile, cred, dvp, mac_vnode_label(dvp),
2859 	    tvp, tvp ? mac_vnode_label(tvp) : NULL, fvp, mac_vnode_label(fvp), cnp, mode, flags);
2860 	VFS_KERNEL_DEBUG_END1(97, dvp);
2861 	return error;
2862 }
2863