xref: /xnu-10063.101.15/security/mac_vfs.c (revision 94d3b452840153a99b38a3a9659680b2a006908e)
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, 0x3130188].
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 				MAC_PERFORM_CALL(vnode_notify_swap, mpc);
494 				mpc->mpc_ops->mpo_vnode_notify_swap(cred, fvp, mac_vnode_label(fvp),
495 					tvp, mac_vnode_label(tvp));
496 				MAC_PERFORM_RSLT(vnode_notify_swap, mpc);
497 			} else if (mpc->mpc_ops->mpo_vnode_notify_rename != NULL) {
498 				MAC_PERFORM_CALL(vnode_notify_swap_rename, mpc);
499 				/* Call notify_rename twice, one for each member of the swap. */
500 				mpc->mpc_ops->mpo_vnode_notify_rename(cred, fvp, mac_vnode_label(fvp),
501 					tdvp, mac_vnode_label(tdvp), tcnp);
502 				mpc->mpc_ops->mpo_vnode_notify_rename(cred, tvp, mac_vnode_label(tvp),
503 					fdvp, mac_vnode_label(fdvp), fcnp);
504 				MAC_PERFORM_RSLT(vnode_notify_swap_rename, mpc);
505 			}
506 		} else if (mpc->mpc_ops->mpo_vnode_notify_rename != NULL) {
507 			MAC_PERFORM_CALL(vnode_notify_rename, mpc);
508 			mpc->mpc_ops->mpo_vnode_notify_rename(cred, fvp, mac_vnode_label(fvp),
509 		            tdvp, mac_vnode_label(tdvp), tcnp);
510 			MAC_PERFORM_RSLT(vnode_notify_rename, mpc);
511 		}
512 		/* END IGNORE CODESTYLE */
513 	});
514 	VFS_KERNEL_DEBUG_END1(13, fvp);
515 }
516 
517 void
mac_vnode_notify_open(vfs_context_t ctx,struct vnode * vp,int acc_flags)518 mac_vnode_notify_open(vfs_context_t ctx, struct vnode *vp, int acc_flags)
519 {
520 	kauth_cred_t cred;
521 
522 #if SECURITY_MAC_CHECK_ENFORCE
523 	/* 21167099 - only check if we allow write */
524 	if (!mac_vnode_enforce) {
525 		return;
526 	}
527 #endif
528 	cred = vfs_context_ucred(ctx);
529 	if (!mac_cred_check_enforce(cred)) {
530 		return;
531 	}
532 	VFS_KERNEL_DEBUG_START1(14, vp);
533 	MAC_PERFORM(vnode_notify_open, cred, vp, mac_vnode_label(vp), acc_flags);
534 	VFS_KERNEL_DEBUG_END1(14, vp);
535 }
536 
537 void
mac_vnode_notify_link(vfs_context_t ctx,struct vnode * vp,struct vnode * dvp,struct componentname * cnp)538 mac_vnode_notify_link(vfs_context_t ctx, struct vnode *vp,
539     struct vnode *dvp, struct componentname *cnp)
540 {
541 	kauth_cred_t cred;
542 
543 #if SECURITY_MAC_CHECK_ENFORCE
544 	/* 21167099 - only check if we allow write */
545 	if (!mac_vnode_enforce) {
546 		return;
547 	}
548 #endif
549 	cred = vfs_context_ucred(ctx);
550 	if (!mac_cred_check_enforce(cred)) {
551 		return;
552 	}
553 	VFS_KERNEL_DEBUG_START1(15, vp);
554 	MAC_PERFORM(vnode_notify_link, cred, dvp, mac_vnode_label(dvp), vp, mac_vnode_label(vp), cnp);
555 	VFS_KERNEL_DEBUG_END1(15, vp);
556 }
557 
558 void
mac_vnode_notify_deleteextattr(vfs_context_t ctx,struct vnode * vp,const char * name)559 mac_vnode_notify_deleteextattr(vfs_context_t ctx, struct vnode *vp, const char *name)
560 {
561 	kauth_cred_t cred;
562 
563 #if SECURITY_MAC_CHECK_ENFORCE
564 	/* 21167099 - only check if we allow write */
565 	if (!mac_vnode_enforce) {
566 		return;
567 	}
568 #endif
569 	cred = vfs_context_ucred(ctx);
570 	if (!mac_cred_check_enforce(cred)) {
571 		return;
572 	}
573 	VFS_KERNEL_DEBUG_START1(16, vp);
574 	MAC_PERFORM(vnode_notify_deleteextattr, cred, vp, mac_vnode_label(vp), name);
575 	VFS_KERNEL_DEBUG_END1(16, vp);
576 }
577 
578 void
mac_vnode_notify_setacl(vfs_context_t ctx,struct vnode * vp,struct kauth_acl * acl)579 mac_vnode_notify_setacl(vfs_context_t ctx, struct vnode *vp, struct kauth_acl *acl)
580 {
581 	kauth_cred_t cred;
582 
583 #if SECURITY_MAC_CHECK_ENFORCE
584 	/* 21167099 - only check if we allow write */
585 	if (!mac_vnode_enforce) {
586 		return;
587 	}
588 #endif
589 	cred = vfs_context_ucred(ctx);
590 	if (!mac_cred_check_enforce(cred)) {
591 		return;
592 	}
593 	VFS_KERNEL_DEBUG_START1(17, vp);
594 	MAC_PERFORM(vnode_notify_setacl, cred, vp, mac_vnode_label(vp), acl);
595 	VFS_KERNEL_DEBUG_END1(17, vp);
596 }
597 
598 void
mac_vnode_notify_setattrlist(vfs_context_t ctx,struct vnode * vp,struct attrlist * alist)599 mac_vnode_notify_setattrlist(vfs_context_t ctx, struct vnode *vp, struct attrlist *alist)
600 {
601 	kauth_cred_t cred;
602 
603 #if SECURITY_MAC_CHECK_ENFORCE
604 	/* 21167099 - only check if we allow write */
605 	if (!mac_vnode_enforce) {
606 		return;
607 	}
608 #endif
609 	cred = vfs_context_ucred(ctx);
610 	if (!mac_cred_check_enforce(cred)) {
611 		return;
612 	}
613 	VFS_KERNEL_DEBUG_START1(18, vp);
614 	MAC_PERFORM(vnode_notify_setattrlist, cred, vp, mac_vnode_label(vp), alist);
615 	VFS_KERNEL_DEBUG_END1(18, vp);
616 }
617 
618 void
mac_vnode_notify_setextattr(vfs_context_t ctx,struct vnode * vp,const char * name,struct uio * uio)619 mac_vnode_notify_setextattr(vfs_context_t ctx, struct vnode *vp, const char *name, struct uio *uio)
620 {
621 	kauth_cred_t cred;
622 
623 #if SECURITY_MAC_CHECK_ENFORCE
624 	/* 21167099 - only check if we allow write */
625 	if (!mac_vnode_enforce) {
626 		return;
627 	}
628 #endif
629 	cred = vfs_context_ucred(ctx);
630 	if (!mac_cred_check_enforce(cred)) {
631 		return;
632 	}
633 	VFS_KERNEL_DEBUG_START1(19, vp);
634 	MAC_PERFORM(vnode_notify_setextattr, cred, vp, mac_vnode_label(vp), name, uio);
635 	VFS_KERNEL_DEBUG_END1(19, vp);
636 }
637 
638 void
mac_vnode_notify_setflags(vfs_context_t ctx,struct vnode * vp,u_long flags)639 mac_vnode_notify_setflags(vfs_context_t ctx, struct vnode *vp, u_long flags)
640 {
641 	kauth_cred_t cred;
642 
643 #if SECURITY_MAC_CHECK_ENFORCE
644 	/* 21167099 - only check if we allow write */
645 	if (!mac_vnode_enforce) {
646 		return;
647 	}
648 #endif
649 	cred = vfs_context_ucred(ctx);
650 	if (!mac_cred_check_enforce(cred)) {
651 		return;
652 	}
653 	VFS_KERNEL_DEBUG_START1(20, vp);
654 	MAC_PERFORM(vnode_notify_setflags, cred, vp, mac_vnode_label(vp), flags);
655 	VFS_KERNEL_DEBUG_END1(20, vp);
656 }
657 
658 void
mac_vnode_notify_setmode(vfs_context_t ctx,struct vnode * vp,mode_t mode)659 mac_vnode_notify_setmode(vfs_context_t ctx, struct vnode *vp, mode_t mode)
660 {
661 	kauth_cred_t cred;
662 
663 #if SECURITY_MAC_CHECK_ENFORCE
664 	/* 21167099 - only check if we allow write */
665 	if (!mac_vnode_enforce) {
666 		return;
667 	}
668 #endif
669 	cred = vfs_context_ucred(ctx);
670 	if (!mac_cred_check_enforce(cred)) {
671 		return;
672 	}
673 	VFS_KERNEL_DEBUG_START1(21, vp);
674 	MAC_PERFORM(vnode_notify_setmode, cred, vp, mac_vnode_label(vp), mode);
675 	VFS_KERNEL_DEBUG_END1(21, vp);
676 }
677 
678 void
mac_vnode_notify_setowner(vfs_context_t ctx,struct vnode * vp,uid_t uid,gid_t gid)679 mac_vnode_notify_setowner(vfs_context_t ctx, struct vnode *vp, uid_t uid, gid_t gid)
680 {
681 	kauth_cred_t cred;
682 
683 #if SECURITY_MAC_CHECK_ENFORCE
684 	/* 21167099 - only check if we allow write */
685 	if (!mac_vnode_enforce) {
686 		return;
687 	}
688 #endif
689 	cred = vfs_context_ucred(ctx);
690 	if (!mac_cred_check_enforce(cred)) {
691 		return;
692 	}
693 	VFS_KERNEL_DEBUG_START1(22, vp);
694 	MAC_PERFORM(vnode_notify_setowner, cred, vp, mac_vnode_label(vp), uid, gid);
695 	VFS_KERNEL_DEBUG_END1(22, vp);
696 }
697 
698 void
mac_vnode_notify_setutimes(vfs_context_t ctx,struct vnode * vp,struct timespec atime,struct timespec mtime)699 mac_vnode_notify_setutimes(vfs_context_t ctx, struct vnode *vp, struct timespec atime, struct timespec mtime)
700 {
701 	kauth_cred_t cred;
702 
703 #if SECURITY_MAC_CHECK_ENFORCE
704 	/* 21167099 - only check if we allow write */
705 	if (!mac_vnode_enforce) {
706 		return;
707 	}
708 #endif
709 	cred = vfs_context_ucred(ctx);
710 	if (!mac_cred_check_enforce(cred)) {
711 		return;
712 	}
713 	VFS_KERNEL_DEBUG_START1(23, vp);
714 	MAC_PERFORM(vnode_notify_setutimes, cred, vp, mac_vnode_label(vp), atime, mtime);
715 	VFS_KERNEL_DEBUG_END1(23, vp);
716 }
717 
718 void
mac_vnode_notify_truncate(vfs_context_t ctx,kauth_cred_t file_cred,struct vnode * vp)719 mac_vnode_notify_truncate(vfs_context_t ctx, kauth_cred_t file_cred, struct vnode *vp)
720 {
721 	kauth_cred_t cred;
722 
723 #if SECURITY_MAC_CHECK_ENFORCE
724 	/* 21167099 - only check if we allow write */
725 	if (!mac_vnode_enforce) {
726 		return;
727 	}
728 #endif
729 	cred = vfs_context_ucred(ctx);
730 	if (!mac_cred_check_enforce(cred)) {
731 		return;
732 	}
733 	VFS_KERNEL_DEBUG_START1(24, vp);
734 	MAC_PERFORM(vnode_notify_truncate, cred, file_cred, vp, mac_vnode_label(vp));
735 	VFS_KERNEL_DEBUG_END1(24, vp);
736 }
737 
738 /*
739  * Extended attribute 'name' was updated via
740  * vn_setxattr() or vn_removexattr().  Allow the
741  * policy to update the vnode label.
742  */
743 void
mac_vnode_label_update_extattr(struct mount * mp,struct vnode * vp,const char * name)744 mac_vnode_label_update_extattr(struct mount *mp, struct vnode *vp,
745     const char *name)
746 {
747 	int error = 0;
748 
749 #if SECURITY_MAC_CHECK_ENFORCE
750 	/* 21167099 - only check if we allow write */
751 	if (!mac_vnode_enforce) {
752 		return;
753 	}
754 #endif
755 	if (!mac_label_vnodes) {
756 		return;
757 	}
758 
759 	VFS_KERNEL_DEBUG_START1(25, vp);
760 	MAC_PERFORM(vnode_label_update_extattr, mp, mac_mount_label(mp), vp,
761 	    mac_vnode_label(vp), name);
762 	VFS_KERNEL_DEBUG_END1(25, vp);
763 	if (error == 0) {
764 		return;
765 	}
766 
767 	vnode_lock(vp);
768 	vnode_relabel(vp);
769 	vnode_unlock(vp);
770 	return;
771 }
772 
773 static int
mac_vnode_label_store(vfs_context_t ctx,struct vnode * vp,struct label * intlabel)774 mac_vnode_label_store(vfs_context_t ctx, struct vnode *vp,
775     struct label *intlabel)
776 {
777 	kauth_cred_t cred;
778 	int error;
779 
780 #if SECURITY_MAC_CHECK_ENFORCE
781 	/* 21167099 - only check if we allow write */
782 	if (!mac_vnode_enforce) {
783 		return 0;
784 	}
785 #endif
786 	if (!mac_label_vnodes) {
787 		return 0;
788 	}
789 
790 	cred = vfs_context_ucred(ctx);
791 	if (!mac_cred_check_enforce(cred)) {
792 		return 0;
793 	}
794 	VFS_KERNEL_DEBUG_START1(26, vp);
795 	MAC_CHECK(vnode_label_store, cred, vp, mac_vnode_label(vp), intlabel);
796 	VFS_KERNEL_DEBUG_END1(26, vp);
797 
798 	return error;
799 }
800 
801 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)802 mac_cred_label_update_execve(vfs_context_t ctx, kauth_cred_t new, struct vnode *vp, off_t offset,
803     struct vnode *scriptvp, struct label *scriptvnodelabel, struct label *execl, u_int *csflags,
804     void *macextensions, int *disjoint, int *labelupdateerror)
805 {
806 	kauth_cred_t cred;
807 	*disjoint = 0;
808 	int error;
809 	posix_cred_t pcred = posix_cred_get(new);
810 
811 #if SECURITY_MAC_CHECK_ENFORCE
812 	/* 21167099 - only check if we allow write */
813 	if (!mac_proc_enforce || !mac_vnode_enforce) {
814 		return;
815 	}
816 #endif
817 
818 	/* mark the new cred to indicate "matching" includes the label */
819 	pcred->cr_flags |= CRF_MAC_ENFORCE;
820 
821 	cred = vfs_context_ucred(ctx);
822 
823 	/*
824 	 * NB: Cannot use MAC_CHECK macro because we need a sequence point after
825 	 *     calling exec_spawnattr_getmacpolicyinfo() and before passing the
826 	 *     spawnattrlen as an argument to the hook.
827 	 */
828 	VFS_KERNEL_DEBUG_START1(27, vp);
829 	{
830 		struct mac_policy_conf *mpc;
831 		u_int i;
832 
833 		error = 0;
834 		for (i = 0; i < mac_policy_list.staticmax; i++) {
835 			mpc = mac_policy_list.entries[i].mpc;
836 			if (mpc == NULL) {
837 				continue;
838 			}
839 
840 			mpo_cred_label_update_execve_t *hook = mpc->mpc_ops->mpo_cred_label_update_execve;
841 			if (hook == NULL) {
842 				continue;
843 			}
844 
845 			size_t spawnattrlen = 0;
846 			void *spawnattr = exec_spawnattr_getmacpolicyinfo(macextensions, mpc->mpc_name, &spawnattrlen);
847 
848 			error = mac_error_select(hook(cred, new, vfs_context_proc(ctx), vp, offset, scriptvp,
849 			    mac_vnode_label(vp), scriptvnodelabel, execl, csflags, spawnattr, spawnattrlen, disjoint),
850 			    error);
851 		}
852 		if (mac_policy_list_conditional_busy() != 0) {
853 			for (; i <= mac_policy_list.maxindex; i++) {
854 				mpc = mac_policy_list.entries[i].mpc;
855 				if (mpc == NULL) {
856 					continue;
857 				}
858 
859 				mpo_cred_label_update_execve_t *hook = mpc->mpc_ops->mpo_cred_label_update_execve;
860 				if (hook == NULL) {
861 					continue;
862 				}
863 
864 				size_t spawnattrlen = 0;
865 				void *spawnattr = exec_spawnattr_getmacpolicyinfo(macextensions, mpc->mpc_name, &spawnattrlen);
866 
867 				error = mac_error_select(hook(cred, new, vfs_context_proc(ctx), vp, offset, scriptvp,
868 				    mac_vnode_label(vp), scriptvnodelabel, execl, csflags, spawnattr, spawnattrlen, disjoint),
869 				    error);
870 			}
871 			mac_policy_list_unbusy();
872 		}
873 	}
874 	*labelupdateerror = error;
875 	VFS_KERNEL_DEBUG_END1(27, vp);
876 }
877 
878 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)879 mac_cred_check_label_update_execve(vfs_context_t ctx, struct vnode *vp, off_t offset,
880     struct vnode *scriptvp, struct label *scriptvnodelabel, struct label *execlabel,
881     struct proc *p, void *macextensions)
882 {
883 	kauth_cred_t cred;
884 	int result = 0;
885 
886 #if SECURITY_MAC_CHECK_ENFORCE
887 	/* 21167099 - only check if we allow write */
888 	if (!mac_proc_enforce || !mac_vnode_enforce) {
889 		return result;
890 	}
891 #endif
892 
893 	cred = vfs_context_ucred(ctx);
894 
895 	VFS_KERNEL_DEBUG_START1(28, vp);
896 	/*
897 	 * NB: Cannot use MAC_BOOLEAN macro because we need a sequence point after
898 	 *     calling exec_spawnattr_getmacpolicyinfo() and before passing the
899 	 *     spawnattrlen as an argument to the hook.
900 	 */
901 	{
902 		struct mac_policy_conf *mpc;
903 		u_int i;
904 
905 		for (i = 0; i < mac_policy_list.staticmax; i++) {
906 			mpc = mac_policy_list.entries[i].mpc;
907 			if (mpc == NULL) {
908 				continue;
909 			}
910 
911 			mpo_cred_check_label_update_execve_t *hook = mpc->mpc_ops->mpo_cred_check_label_update_execve;
912 			if (hook == NULL) {
913 				continue;
914 			}
915 
916 			size_t spawnattrlen = 0;
917 			void *spawnattr = exec_spawnattr_getmacpolicyinfo(macextensions, mpc->mpc_name, &spawnattrlen);
918 
919 			result = result || hook(cred, vp, offset, scriptvp, mac_vnode_label(vp), scriptvnodelabel, execlabel, p, spawnattr, spawnattrlen);
920 		}
921 		if (mac_policy_list_conditional_busy() != 0) {
922 			for (; i <= mac_policy_list.maxindex; i++) {
923 				mpc = mac_policy_list.entries[i].mpc;
924 				if (mpc == NULL) {
925 					continue;
926 				}
927 
928 				mpo_cred_check_label_update_execve_t *hook = mpc->mpc_ops->mpo_cred_check_label_update_execve;
929 				if (hook == NULL) {
930 					continue;
931 				}
932 
933 				size_t spawnattrlen = 0;
934 				void *spawnattr = exec_spawnattr_getmacpolicyinfo(macextensions, mpc->mpc_name, &spawnattrlen);
935 
936 				result = result || hook(cred, vp, offset, scriptvp, mac_vnode_label(vp), scriptvnodelabel, execlabel, p, spawnattr, spawnattrlen);
937 			}
938 			mac_policy_list_unbusy();
939 		}
940 	}
941 	VFS_KERNEL_DEBUG_END1(28, vp);
942 
943 	return result;
944 }
945 
946 int
mac_vnode_check_access(vfs_context_t ctx,struct vnode * vp,int acc_mode)947 mac_vnode_check_access(vfs_context_t ctx, struct vnode *vp,
948     int acc_mode)
949 {
950 	kauth_cred_t cred;
951 	int error;
952 	int mask;
953 
954 #if SECURITY_MAC_CHECK_ENFORCE
955 	/* 21167099 - only check if we allow write */
956 	if (!mac_vnode_enforce) {
957 		return 0;
958 	}
959 #endif
960 	cred = vfs_context_ucred(ctx);
961 	if (!mac_cred_check_enforce(cred)) {
962 		return 0;
963 	}
964 	/* Convert {R,W,X}_OK values to V{READ,WRITE,EXEC} for entry points */
965 	mask = ACCESS_MODE_TO_VNODE_MASK(acc_mode);
966 	VFS_KERNEL_DEBUG_START1(29, vp);
967 	MAC_CHECK(vnode_check_access, cred, vp, mac_vnode_label(vp), mask);
968 	VFS_KERNEL_DEBUG_END1(29, vp);
969 	return error;
970 }
971 
972 int
mac_vnode_check_chdir(vfs_context_t ctx,struct vnode * dvp)973 mac_vnode_check_chdir(vfs_context_t ctx, struct vnode *dvp)
974 {
975 	kauth_cred_t cred;
976 	int error;
977 
978 #if SECURITY_MAC_CHECK_ENFORCE
979 	/* 21167099 - only check if we allow write */
980 	if (!mac_vnode_enforce) {
981 		return 0;
982 	}
983 #endif
984 	cred = vfs_context_ucred(ctx);
985 	if (!mac_cred_check_enforce(cred)) {
986 		return 0;
987 	}
988 	VFS_KERNEL_DEBUG_START1(30, dvp);
989 	MAC_CHECK(vnode_check_chdir, cred, dvp, mac_vnode_label(dvp));
990 	VFS_KERNEL_DEBUG_END1(30, dvp);
991 	return error;
992 }
993 
994 int
mac_vnode_check_chroot(vfs_context_t ctx,struct vnode * dvp,struct componentname * cnp)995 mac_vnode_check_chroot(vfs_context_t ctx, struct vnode *dvp,
996     struct componentname *cnp)
997 {
998 	kauth_cred_t cred;
999 	int error;
1000 
1001 #if SECURITY_MAC_CHECK_ENFORCE
1002 	/* 21167099 - only check if we allow write */
1003 	if (!mac_vnode_enforce) {
1004 		return 0;
1005 	}
1006 #endif
1007 	cred = vfs_context_ucred(ctx);
1008 	if (!mac_cred_check_enforce(cred)) {
1009 		return 0;
1010 	}
1011 	VFS_KERNEL_DEBUG_START1(31, dvp);
1012 	MAC_CHECK(vnode_check_chroot, cred, dvp, mac_vnode_label(dvp), cnp);
1013 	VFS_KERNEL_DEBUG_END1(31, dvp);
1014 	return error;
1015 }
1016 
1017 int
mac_vnode_check_clone(vfs_context_t ctx,struct vnode * dvp,struct vnode * vp,struct componentname * cnp)1018 mac_vnode_check_clone(vfs_context_t ctx, struct vnode *dvp,
1019     struct vnode *vp, struct componentname *cnp)
1020 {
1021 	kauth_cred_t cred;
1022 	int error;
1023 
1024 #if SECURITY_MAC_CHECK_ENFORCE
1025 	/* 21167099 - only check if we allow write */
1026 	if (!mac_vnode_enforce) {
1027 		return 0;
1028 	}
1029 #endif
1030 	cred = vfs_context_ucred(ctx);
1031 	if (!mac_cred_check_enforce(cred)) {
1032 		return 0;
1033 	}
1034 	VFS_KERNEL_DEBUG_START1(32, dvp);
1035 	MAC_CHECK(vnode_check_clone, cred, dvp, mac_vnode_label(dvp), vp,
1036 	    mac_vnode_label(vp), cnp);
1037 	VFS_KERNEL_DEBUG_END1(32, dvp);
1038 	return error;
1039 }
1040 int
mac_vnode_check_create(vfs_context_t ctx,struct vnode * dvp,struct componentname * cnp,struct vnode_attr * vap)1041 mac_vnode_check_create(vfs_context_t ctx, struct vnode *dvp,
1042     struct componentname *cnp, struct vnode_attr *vap)
1043 {
1044 	kauth_cred_t cred;
1045 	int error;
1046 
1047 #if SECURITY_MAC_CHECK_ENFORCE
1048 	/* 21167099 - only check if we allow write */
1049 	if (!mac_vnode_enforce) {
1050 		return 0;
1051 	}
1052 #endif
1053 	cred = vfs_context_ucred(ctx);
1054 	if (!mac_cred_check_enforce(cred)) {
1055 		return 0;
1056 	}
1057 	VFS_KERNEL_DEBUG_START1(33, dvp);
1058 	MAC_CHECK(vnode_check_create, cred, dvp, mac_vnode_label(dvp), cnp, vap);
1059 	VFS_KERNEL_DEBUG_END1(33, dvp);
1060 	return error;
1061 }
1062 
1063 int
mac_vnode_check_unlink(vfs_context_t ctx,struct vnode * dvp,struct vnode * vp,struct componentname * cnp)1064 mac_vnode_check_unlink(vfs_context_t ctx, struct vnode *dvp, struct vnode *vp,
1065     struct componentname *cnp)
1066 {
1067 	kauth_cred_t cred;
1068 	int error;
1069 
1070 #if SECURITY_MAC_CHECK_ENFORCE
1071 	/* 21167099 - only check if we allow write */
1072 	if (!mac_vnode_enforce) {
1073 		return 0;
1074 	}
1075 #endif
1076 	cred = vfs_context_ucred(ctx);
1077 	if (!mac_cred_check_enforce(cred)) {
1078 		return 0;
1079 	}
1080 	VFS_KERNEL_DEBUG_START1(34, dvp);
1081 	MAC_CHECK(vnode_check_unlink, cred, dvp, mac_vnode_label(dvp), vp,
1082 	    mac_vnode_label(vp), cnp);
1083 	VFS_KERNEL_DEBUG_END1(34, dvp);
1084 	return error;
1085 }
1086 #if 0
1087 int
1088 mac_vnode_check_deleteacl(vfs_context_t ctx, struct vnode *vp,
1089     acl_type_t type)
1090 {
1091 	kauth_cred_t cred;
1092 	int error;
1093 
1094 #if SECURITY_MAC_CHECK_ENFORCE
1095 	/* 21167099 - only check if we allow write */
1096 	if (!mac_vnode_enforce) {
1097 		return 0;
1098 	}
1099 #endif
1100 	cred = vfs_context_ucred(ctx);
1101 	if (!mac_cred_check_enforce(cred)) {
1102 		return 0;
1103 	}
1104 	VFS_KERNEL_DEBUG_START1(35, dvp);
1105 	MAC_CHECK(vnode_check_deleteacl, cred, vp, mac_vnode_label(vp), type);
1106 	VFS_KERNEL_DEBUG_END1(35, dvp);
1107 	return error;
1108 }
1109 #endif
1110 
1111 int
mac_vnode_check_deleteextattr(vfs_context_t ctx,struct vnode * vp,const char * name)1112 mac_vnode_check_deleteextattr(vfs_context_t ctx, struct vnode *vp,
1113     const char *name)
1114 {
1115 	kauth_cred_t cred;
1116 	int error;
1117 
1118 #if SECURITY_MAC_CHECK_ENFORCE
1119 	/* 21167099 - only check if we allow write */
1120 	if (!mac_vnode_enforce) {
1121 		return 0;
1122 	}
1123 #endif
1124 	cred = vfs_context_ucred(ctx);
1125 	if (!mac_cred_check_enforce(cred)) {
1126 		return 0;
1127 	}
1128 	VFS_KERNEL_DEBUG_START1(36, vp);
1129 	MAC_CHECK(vnode_check_deleteextattr, cred, vp, mac_vnode_label(vp), name);
1130 	VFS_KERNEL_DEBUG_END1(36, vp);
1131 	return error;
1132 }
1133 int
mac_vnode_check_exchangedata(vfs_context_t ctx,struct vnode * v1,struct vnode * v2)1134 mac_vnode_check_exchangedata(vfs_context_t ctx,
1135     struct vnode *v1, struct vnode *v2)
1136 {
1137 	kauth_cred_t cred;
1138 	int error;
1139 
1140 #if SECURITY_MAC_CHECK_ENFORCE
1141 	/* 21167099 - only check if we allow write */
1142 	if (!mac_vnode_enforce) {
1143 		return 0;
1144 	}
1145 #endif
1146 	cred = vfs_context_ucred(ctx);
1147 	if (!mac_cred_check_enforce(cred)) {
1148 		return 0;
1149 	}
1150 	VFS_KERNEL_DEBUG_START1(37, v1);
1151 	MAC_CHECK(vnode_check_exchangedata, cred, v1, mac_vnode_label(v1),
1152 	    v2, mac_vnode_label(v2));
1153 	VFS_KERNEL_DEBUG_END1(37, v1);
1154 
1155 	return error;
1156 }
1157 
1158 #if 0
1159 int
1160 mac_vnode_check_getacl(vfs_context_t ctx, struct vnode *vp, acl_type_t type)
1161 {
1162 	kauth_cred_t cred;
1163 	int error;
1164 
1165 #if SECURITY_MAC_CHECK_ENFORCE
1166 	/* 21167099 - only check if we allow write */
1167 	if (!mac_vnode_enforce) {
1168 		return 0;
1169 	}
1170 #endif
1171 	cred = vfs_context_ucred(ctx);
1172 	if (!mac_cred_check_enforce(cred)) {
1173 		return 0;
1174 	}
1175 	VFS_KERNEL_DEBUG_START1(38, vp);
1176 	MAC_CHECK(vnode_check_getacl, cred, vp, mac_vnode_label(vp), type);
1177 	VFS_KERNEL_DEBUG_END1(38, vp);
1178 	return error;
1179 }
1180 #endif
1181 
1182 int
mac_vnode_check_getattr(vfs_context_t ctx,struct ucred * file_cred,struct vnode * vp,struct vnode_attr * va)1183 mac_vnode_check_getattr(vfs_context_t ctx, struct ucred *file_cred,
1184     struct vnode *vp, struct vnode_attr *va)
1185 {
1186 	kauth_cred_t cred;
1187 	int error;
1188 
1189 #if SECURITY_MAC_CHECK_ENFORCE
1190 	/* 21167099 - only check if we allow write */
1191 	if (!mac_vnode_enforce) {
1192 		return 0;
1193 	}
1194 #endif
1195 	cred = vfs_context_ucred(ctx);
1196 	if (!mac_cred_check_enforce(cred)) {
1197 		return 0;
1198 	}
1199 	VFS_KERNEL_DEBUG_START1(39, vp);
1200 	MAC_CHECK(vnode_check_getattr, cred, file_cred, vp, mac_vnode_label(vp), va);
1201 	VFS_KERNEL_DEBUG_END1(39, vp);
1202 	return error;
1203 }
1204 
1205 int
mac_vnode_check_getattrlist(vfs_context_t ctx,struct vnode * vp,struct attrlist * alist,uint64_t options)1206 mac_vnode_check_getattrlist(vfs_context_t ctx, struct vnode *vp,
1207     struct attrlist *alist, uint64_t options)
1208 {
1209 	kauth_cred_t cred;
1210 	int error;
1211 
1212 #if SECURITY_MAC_CHECK_ENFORCE
1213 	/* 21167099 - only check if we allow write */
1214 	if (!mac_vnode_enforce) {
1215 		return 0;
1216 	}
1217 #endif
1218 	cred = vfs_context_ucred(ctx);
1219 	if (!mac_cred_check_enforce(cred)) {
1220 		return 0;
1221 	}
1222 	VFS_KERNEL_DEBUG_START1(40, vp);
1223 	MAC_CHECK(vnode_check_getattrlist, cred, vp, mac_vnode_label(vp), alist, options);
1224 	VFS_KERNEL_DEBUG_END1(40, vp);
1225 
1226 	/* Falsify results instead of returning error? */
1227 	return error;
1228 }
1229 
1230 int
mac_vnode_check_exec(vfs_context_t ctx,struct vnode * vp,struct image_params * imgp)1231 mac_vnode_check_exec(vfs_context_t ctx, struct vnode *vp,
1232     struct image_params *imgp)
1233 {
1234 	kauth_cred_t cred;
1235 	int error = 0;
1236 
1237 #if SECURITY_MAC_CHECK_ENFORCE
1238 	/* 21167099 - only check if we allow write */
1239 	if (!mac_proc_enforce || !mac_vnode_enforce) {
1240 		return 0;
1241 	}
1242 #endif
1243 
1244 	cred = vfs_context_ucred(ctx);
1245 
1246 	/*
1247 	 * NB: Cannot use MAC_CHECK macro because we need a sequence point after
1248 	 *     calling exec_spawnattr_getmacpolicyinfo() and before passing the
1249 	 *     spawnattrlen as an argument to the hook.
1250 	 */
1251 	VFS_KERNEL_DEBUG_START1(41, vp);
1252 	{
1253 		struct mac_policy_conf *mpc;
1254 		u_int i;
1255 
1256 		for (i = 0; i < mac_policy_list.staticmax; i++) {
1257 			mpc = mac_policy_list.entries[i].mpc;
1258 			if (mpc == NULL) {
1259 				continue;
1260 			}
1261 
1262 			mpo_vnode_check_exec_t *hook = mpc->mpc_ops->mpo_vnode_check_exec;
1263 			if (hook == NULL) {
1264 				continue;
1265 			}
1266 
1267 			size_t spawnattrlen = 0;
1268 			void *spawnattr = exec_spawnattr_getmacpolicyinfo(&imgp->ip_px_smpx, mpc->mpc_name, &spawnattrlen);
1269 
1270 			error = mac_error_select(
1271 				hook(cred,
1272 				vp, imgp->ip_scriptvp, mac_vnode_label(vp), imgp->ip_scriptlabelp,
1273 				imgp->ip_execlabelp, &imgp->ip_ndp->ni_cnd, &imgp->ip_csflags,
1274 				spawnattr, spawnattrlen), error);
1275 		}
1276 		if (mac_policy_list_conditional_busy() != 0) {
1277 			for (; i <= mac_policy_list.maxindex; i++) {
1278 				mpc = mac_policy_list.entries[i].mpc;
1279 				if (mpc == NULL) {
1280 					continue;
1281 				}
1282 
1283 				mpo_vnode_check_exec_t *hook = mpc->mpc_ops->mpo_vnode_check_exec;
1284 				if (hook == NULL) {
1285 					continue;
1286 				}
1287 
1288 				size_t spawnattrlen = 0;
1289 				void *spawnattr = exec_spawnattr_getmacpolicyinfo(&imgp->ip_px_smpx, mpc->mpc_name, &spawnattrlen);
1290 
1291 				error = mac_error_select(
1292 					hook(cred,
1293 					vp, imgp->ip_scriptvp, mac_vnode_label(vp), imgp->ip_scriptlabelp,
1294 					imgp->ip_execlabelp, &imgp->ip_ndp->ni_cnd, &imgp->ip_csflags,
1295 					spawnattr, spawnattrlen), error);
1296 			}
1297 			mac_policy_list_unbusy();
1298 		}
1299 	}
1300 	VFS_KERNEL_DEBUG_END1(41, vp);
1301 
1302 	return error;
1303 }
1304 
1305 int
mac_vnode_check_fsgetpath(vfs_context_t ctx,struct vnode * vp)1306 mac_vnode_check_fsgetpath(vfs_context_t ctx, struct vnode *vp)
1307 {
1308 	kauth_cred_t cred;
1309 	int error;
1310 
1311 #if SECURITY_MAC_CHECK_ENFORCE
1312 	/* 21167099 - only check if we allow write */
1313 	if (!mac_vnode_enforce) {
1314 		return 0;
1315 	}
1316 #endif
1317 	cred = vfs_context_ucred(ctx);
1318 	if (!mac_cred_check_enforce(cred)) {
1319 		return 0;
1320 	}
1321 	VFS_KERNEL_DEBUG_START1(42, vp);
1322 	MAC_CHECK(vnode_check_fsgetpath, cred, vp, mac_vnode_label(vp));
1323 	VFS_KERNEL_DEBUG_END1(42, vp);
1324 	return error;
1325 }
1326 
1327 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)1328 mac_vnode_check_signature(struct vnode *vp, struct cs_blob *cs_blob,
1329     struct image_params *imgp,
1330     unsigned int *cs_flags, unsigned int *signer_type,
1331     int flags, unsigned int platform)
1332 {
1333 	int error;
1334 	char *fatal_failure_desc = NULL;
1335 	size_t fatal_failure_desc_len = 0;
1336 
1337 	char *vn_path = NULL;
1338 	vm_size_t vn_pathlen = MAXPATHLEN;
1339 	cpu_type_t cpu_type = (imgp == NULL) ? CPU_TYPE_ANY : imgp->ip_origcputype;
1340 
1341 
1342 #if SECURITY_MAC_CHECK_ENFORCE
1343 	/* 21167099 - only check if we allow write */
1344 	if (!mac_proc_enforce || !mac_vnode_enforce) {
1345 		return 0;
1346 	}
1347 #endif
1348 
1349 	VFS_KERNEL_DEBUG_START1(43, vp);
1350 	MAC_CHECK(vnode_check_signature, vp, mac_vnode_label(vp), cpu_type, cs_blob,
1351 	    cs_flags, signer_type, flags, platform, &fatal_failure_desc, &fatal_failure_desc_len);
1352 	VFS_KERNEL_DEBUG_END1(43, vp);
1353 
1354 	if (fatal_failure_desc_len) {
1355 		// A fatal code signature validation failure occured, formulate a crash
1356 		// reason.
1357 
1358 		char const *path = NULL;
1359 
1360 		vn_path = zalloc(ZV_NAMEI);
1361 		if (vn_getpath(vp, vn_path, (int*)&vn_pathlen) == 0) {
1362 			path = vn_path;
1363 		} else {
1364 			path = "(get vnode path failed)";
1365 		}
1366 
1367 		if (error == 0) {
1368 			panic("mac_vnode_check_signature: MAC hook returned no error, "
1369 			    "but status is claimed to be fatal? "
1370 			    "path: '%s', fatal_failure_desc_len: %ld, fatal_failure_desc:\n%s\n",
1371 			    path, fatal_failure_desc_len, fatal_failure_desc);
1372 		}
1373 
1374 		printf("mac_vnode_check_signature: %s: code signature validation failed fatally: %s",
1375 		    path, fatal_failure_desc);
1376 
1377 		if (imgp == NULL) {
1378 			goto out;
1379 		}
1380 
1381 		os_reason_t reason = os_reason_create(OS_REASON_CODESIGNING,
1382 		    CODESIGNING_EXIT_REASON_TASKGATED_INVALID_SIG);
1383 
1384 		if (reason == OS_REASON_NULL) {
1385 			printf("mac_vnode_check_signature: %s: failure to allocate exit reason for validation failure: %s\n",
1386 			    path, fatal_failure_desc);
1387 			goto out;
1388 		}
1389 
1390 		imgp->ip_cs_error = reason;
1391 		reason->osr_flags = (OS_REASON_FLAG_GENERATE_CRASH_REPORT |
1392 		    OS_REASON_FLAG_CONSISTENT_FAILURE);
1393 
1394 		if (fatal_failure_desc == NULL) {
1395 			// This may happen if allocation for the buffer failed.
1396 			printf("mac_vnode_check_signature: %s: fatal failure is missing its description.\n", path);
1397 		} else {
1398 			mach_vm_address_t data_addr = 0;
1399 
1400 			int reason_error = 0;
1401 			int kcdata_error = 0;
1402 
1403 			if ((reason_error = os_reason_alloc_buffer_noblock(reason, kcdata_estimate_required_buffer_size
1404 			    (1, (uint32_t)fatal_failure_desc_len))) == 0 &&
1405 			    (kcdata_error = kcdata_get_memory_addr(&reason->osr_kcd_descriptor,
1406 			    EXIT_REASON_USER_DESC, (uint32_t)fatal_failure_desc_len,
1407 			    &data_addr)) == KERN_SUCCESS) {
1408 				kern_return_t mc_error = kcdata_memcpy(&reason->osr_kcd_descriptor, (mach_vm_address_t)data_addr,
1409 				    fatal_failure_desc, (uint32_t)fatal_failure_desc_len);
1410 
1411 				if (mc_error != KERN_SUCCESS) {
1412 					printf("mac_vnode_check_signature: %s: failed to copy reason string "
1413 					    "(kcdata_memcpy error: %d, length: %ld)\n",
1414 					    path, mc_error, fatal_failure_desc_len);
1415 				}
1416 			} else {
1417 				printf("mac_vnode_check_signature: %s: failed to allocate space for reason string "
1418 				    "(os_reason_alloc_buffer error: %d, kcdata error: %d, length: %ld)\n",
1419 				    path, reason_error, kcdata_error, fatal_failure_desc_len);
1420 			}
1421 		}
1422 	}
1423 
1424 out:
1425 	if (vn_path) {
1426 		zfree(ZV_NAMEI, vn_path);
1427 	}
1428 
1429 	if (fatal_failure_desc_len > 0 && fatal_failure_desc != NULL) {
1430 		/* KERN_AMFI_SUPPORTS_DATA_ALLOC >= 2 */
1431 		kfree_data(fatal_failure_desc, fatal_failure_desc_len);
1432 	}
1433 
1434 	return error;
1435 }
1436 
1437 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)1438 mac_vnode_check_supplemental_signature(struct vnode *vp,
1439     struct cs_blob *cs_blob, struct vnode *linked_vp,
1440     struct cs_blob *linked_cs_blob, unsigned int *signer_type)
1441 {
1442 	int error;
1443 
1444 #if SECURITY_MAC_CHECK_ENFORCE
1445 	/* 21167099 - only check if we allow write */
1446 	if (!mac_proc_enforce || !mac_vnode_enforce) {
1447 		return 0;
1448 	}
1449 #endif
1450 	VFS_KERNEL_DEBUG_START1(93, vp);
1451 	MAC_CHECK(vnode_check_supplemental_signature, vp, mac_vnode_label(vp), cs_blob, linked_vp, linked_cs_blob,
1452 	    signer_type);
1453 	VFS_KERNEL_DEBUG_END1(93, vp);
1454 
1455 	return error;
1456 }
1457 
1458 #if 0
1459 int
1460 mac_vnode_check_getacl(vfs_context_t ctx, struct vnode *vp, acl_type_t type)
1461 {
1462 	kauth_cred_t cred;
1463 	int error;
1464 
1465 #if SECURITY_MAC_CHECK_ENFORCE
1466 	/* 21167099 - only check if we allow write */
1467 	if (!mac_vnode_enforce) {
1468 		return 0;
1469 	}
1470 #endif
1471 	cred = vfs_context_ucred(ctx);
1472 	if (!mac_cred_check_enforce(cred)) {
1473 		return 0;
1474 	}
1475 	VFS_KERNEL_DEBUG_START1(44, vp);
1476 	MAC_CHECK(vnode_check_getacl, cred, vp, mac_vnode_label(vp), type);
1477 	VFS_KERNEL_DEBUG_END1(44, vp);
1478 	return error;
1479 }
1480 #endif
1481 
1482 int
mac_vnode_check_getextattr(vfs_context_t ctx,struct vnode * vp,const char * name,struct uio * uio)1483 mac_vnode_check_getextattr(vfs_context_t ctx, struct vnode *vp,
1484     const char *name, struct uio *uio)
1485 {
1486 	kauth_cred_t cred;
1487 	int error;
1488 
1489 #if SECURITY_MAC_CHECK_ENFORCE
1490 	/* 21167099 - only check if we allow write */
1491 	if (!mac_vnode_enforce) {
1492 		return 0;
1493 	}
1494 #endif
1495 	cred = vfs_context_ucred(ctx);
1496 	if (!mac_cred_check_enforce(cred)) {
1497 		return 0;
1498 	}
1499 	VFS_KERNEL_DEBUG_START1(45, vp);
1500 	MAC_CHECK(vnode_check_getextattr, cred, vp, mac_vnode_label(vp),
1501 	    name, uio);
1502 	VFS_KERNEL_DEBUG_END1(45, vp);
1503 	return error;
1504 }
1505 
1506 int
mac_vnode_check_ioctl(vfs_context_t ctx,struct vnode * vp,u_long cmd)1507 mac_vnode_check_ioctl(vfs_context_t ctx, struct vnode *vp, u_long cmd)
1508 {
1509 	kauth_cred_t cred;
1510 	int error;
1511 
1512 #if SECURITY_MAC_CHECK_ENFORCE
1513 	/* 21167099 - only check if we allow write */
1514 	if (!mac_vnode_enforce) {
1515 		return 0;
1516 	}
1517 #endif
1518 	cred = vfs_context_ucred(ctx);
1519 	if (!mac_cred_check_enforce(cred)) {
1520 		return 0;
1521 	}
1522 	VFS_KERNEL_DEBUG_START1(46, vp);
1523 	MAC_CHECK(vnode_check_ioctl, cred, vp, mac_vnode_label(vp), cmd);
1524 	VFS_KERNEL_DEBUG_END1(46, vp);
1525 	return error;
1526 }
1527 
1528 int
mac_vnode_check_kqfilter(vfs_context_t ctx,kauth_cred_t file_cred,struct knote * kn,struct vnode * vp)1529 mac_vnode_check_kqfilter(vfs_context_t ctx, kauth_cred_t file_cred,
1530     struct knote *kn, struct vnode *vp)
1531 {
1532 	kauth_cred_t cred;
1533 	int error;
1534 
1535 #if SECURITY_MAC_CHECK_ENFORCE
1536 	/* 21167099 - only check if we allow write */
1537 	if (!mac_vnode_enforce) {
1538 		return 0;
1539 	}
1540 #endif
1541 	cred = vfs_context_ucred(ctx);
1542 	if (!mac_cred_check_enforce(cred)) {
1543 		return 0;
1544 	}
1545 	VFS_KERNEL_DEBUG_START1(47, vp);
1546 	MAC_CHECK(vnode_check_kqfilter, cred, file_cred, kn, vp,
1547 	    mac_vnode_label(vp));
1548 	VFS_KERNEL_DEBUG_END1(47, vp);
1549 
1550 	return error;
1551 }
1552 
1553 int
mac_vnode_check_link(vfs_context_t ctx,struct vnode * dvp,struct vnode * vp,struct componentname * cnp)1554 mac_vnode_check_link(vfs_context_t ctx, struct vnode *dvp,
1555     struct vnode *vp, struct componentname *cnp)
1556 {
1557 	kauth_cred_t cred;
1558 	int error;
1559 
1560 #if SECURITY_MAC_CHECK_ENFORCE
1561 	/* 21167099 - only check if we allow write */
1562 	if (!mac_vnode_enforce) {
1563 		return 0;
1564 	}
1565 #endif
1566 	cred = vfs_context_ucred(ctx);
1567 	if (!mac_cred_check_enforce(cred)) {
1568 		return 0;
1569 	}
1570 	VFS_KERNEL_DEBUG_START1(48, vp);
1571 	MAC_CHECK(vnode_check_link, cred, dvp, mac_vnode_label(dvp), vp,
1572 	    mac_vnode_label(vp), cnp);
1573 	VFS_KERNEL_DEBUG_END1(48, vp);
1574 	return error;
1575 }
1576 
1577 int
mac_vnode_check_listextattr(vfs_context_t ctx,struct vnode * vp)1578 mac_vnode_check_listextattr(vfs_context_t ctx, struct vnode *vp)
1579 {
1580 	kauth_cred_t cred;
1581 	int error;
1582 
1583 #if SECURITY_MAC_CHECK_ENFORCE
1584 	/* 21167099 - only check if we allow write */
1585 	if (!mac_vnode_enforce) {
1586 		return 0;
1587 	}
1588 #endif
1589 	cred = vfs_context_ucred(ctx);
1590 	if (!mac_cred_check_enforce(cred)) {
1591 		return 0;
1592 	}
1593 	VFS_KERNEL_DEBUG_START1(49, vp);
1594 	MAC_CHECK(vnode_check_listextattr, cred, vp, mac_vnode_label(vp));
1595 	VFS_KERNEL_DEBUG_END1(49, vp);
1596 	return error;
1597 }
1598 
1599 int
mac_vnode_check_lookup_preflight(vfs_context_t ctx,struct vnode * dvp,const char * path,size_t pathlen)1600 mac_vnode_check_lookup_preflight(vfs_context_t ctx, struct vnode *dvp,
1601     const char *path, size_t pathlen)
1602 {
1603 	kauth_cred_t cred;
1604 	int error;
1605 
1606 #if SECURITY_MAC_CHECK_ENFORCE
1607 	/* 21167099 - only check if we allow write */
1608 	if (!mac_vnode_enforce) {
1609 		return 0;
1610 	}
1611 #endif
1612 	cred = vfs_context_ucred(ctx);
1613 	if (!mac_cred_check_enforce(cred)) {
1614 		return 0;
1615 	}
1616 	VFS_KERNEL_DEBUG_START1(50, dvp);
1617 	MAC_CHECK(vnode_check_lookup_preflight, cred, dvp, mac_vnode_label(dvp), path, pathlen);
1618 	VFS_KERNEL_DEBUG_END1(50, dvp);
1619 	return error;
1620 }
1621 
1622 int
mac_vnode_check_lookup(vfs_context_t ctx,struct vnode * dvp,struct componentname * cnp)1623 mac_vnode_check_lookup(vfs_context_t ctx, struct vnode *dvp,
1624     struct componentname *cnp)
1625 {
1626 	kauth_cred_t cred;
1627 	int error;
1628 
1629 #if SECURITY_MAC_CHECK_ENFORCE
1630 	/* 21167099 - only check if we allow write */
1631 	if (!mac_vnode_enforce) {
1632 		return 0;
1633 	}
1634 #endif
1635 	cred = vfs_context_ucred(ctx);
1636 	if (!mac_cred_check_enforce(cred)) {
1637 		return 0;
1638 	}
1639 	VFS_KERNEL_DEBUG_START1(51, dvp);
1640 	MAC_CHECK(vnode_check_lookup, cred, dvp, mac_vnode_label(dvp), cnp);
1641 	VFS_KERNEL_DEBUG_END1(51, dvp);
1642 	return error;
1643 }
1644 
1645 int
mac_vnode_check_open(vfs_context_t ctx,struct vnode * vp,int acc_mode)1646 mac_vnode_check_open(vfs_context_t ctx, struct vnode *vp, int acc_mode)
1647 {
1648 	kauth_cred_t cred;
1649 	int error;
1650 
1651 #if SECURITY_MAC_CHECK_ENFORCE
1652 	/* 21167099 - only check if we allow write */
1653 	if (!mac_vnode_enforce) {
1654 		return 0;
1655 	}
1656 #endif
1657 	cred = vfs_context_ucred(ctx);
1658 	if (!mac_cred_check_enforce(cred)) {
1659 		return 0;
1660 	}
1661 	VFS_KERNEL_DEBUG_START1(52, vp);
1662 	MAC_CHECK(vnode_check_open, cred, vp, mac_vnode_label(vp), acc_mode);
1663 	VFS_KERNEL_DEBUG_END1(52, vp);
1664 	return error;
1665 }
1666 
1667 int
mac_vnode_check_read(vfs_context_t ctx,struct ucred * file_cred,struct vnode * vp)1668 mac_vnode_check_read(vfs_context_t ctx, struct ucred *file_cred,
1669     struct vnode *vp)
1670 {
1671 	kauth_cred_t cred;
1672 	int error;
1673 
1674 #if SECURITY_MAC_CHECK_ENFORCE
1675 	/* 21167099 - only check if we allow write */
1676 	if (!mac_vnode_enforce) {
1677 		return 0;
1678 	}
1679 #endif
1680 	cred = vfs_context_ucred(ctx);
1681 	if (!mac_cred_check_enforce(cred)) {
1682 		return 0;
1683 	}
1684 	VFS_KERNEL_DEBUG_START1(53, vp);
1685 	MAC_CHECK(vnode_check_read, cred, file_cred, vp,
1686 	    mac_vnode_label(vp));
1687 	VFS_KERNEL_DEBUG_END1(53, vp);
1688 
1689 	return error;
1690 }
1691 
1692 int
mac_vnode_check_readdir(vfs_context_t ctx,struct vnode * dvp)1693 mac_vnode_check_readdir(vfs_context_t ctx, struct vnode *dvp)
1694 {
1695 	kauth_cred_t cred;
1696 	int error;
1697 
1698 #if SECURITY_MAC_CHECK_ENFORCE
1699 	/* 21167099 - only check if we allow write */
1700 	if (!mac_vnode_enforce) {
1701 		return 0;
1702 	}
1703 #endif
1704 	cred = vfs_context_ucred(ctx);
1705 	if (!mac_cred_check_enforce(cred)) {
1706 		return 0;
1707 	}
1708 	VFS_KERNEL_DEBUG_START1(54, dvp);
1709 	MAC_CHECK(vnode_check_readdir, cred, dvp, mac_vnode_label(dvp));
1710 	VFS_KERNEL_DEBUG_END1(54, dvp);
1711 	return error;
1712 }
1713 
1714 int
mac_vnode_check_readlink(vfs_context_t ctx,struct vnode * vp)1715 mac_vnode_check_readlink(vfs_context_t ctx, struct vnode *vp)
1716 {
1717 	kauth_cred_t cred;
1718 	int error;
1719 
1720 #if SECURITY_MAC_CHECK_ENFORCE
1721 	/* 21167099 - only check if we allow write */
1722 	if (!mac_vnode_enforce) {
1723 		return 0;
1724 	}
1725 #endif
1726 	cred = vfs_context_ucred(ctx);
1727 	if (!mac_cred_check_enforce(cred)) {
1728 		return 0;
1729 	}
1730 	VFS_KERNEL_DEBUG_START1(55, vp);
1731 	MAC_CHECK(vnode_check_readlink, cred, vp, mac_vnode_label(vp));
1732 	VFS_KERNEL_DEBUG_END1(55, vp);
1733 	return error;
1734 }
1735 
1736 int
mac_vnode_check_label_update(vfs_context_t ctx,struct vnode * vp,struct label * newlabel)1737 mac_vnode_check_label_update(vfs_context_t ctx, struct vnode *vp,
1738     struct label *newlabel)
1739 {
1740 	kauth_cred_t cred;
1741 	int error;
1742 
1743 #if SECURITY_MAC_CHECK_ENFORCE
1744 	/* 21167099 - only check if we allow write */
1745 	if (!mac_vnode_enforce) {
1746 		return 0;
1747 	}
1748 #endif
1749 	cred = vfs_context_ucred(ctx);
1750 	if (!mac_cred_check_enforce(cred)) {
1751 		return 0;
1752 	}
1753 	VFS_KERNEL_DEBUG_START1(56, vp);
1754 	MAC_CHECK(vnode_check_label_update, cred, vp, mac_vnode_label(vp), newlabel);
1755 	VFS_KERNEL_DEBUG_END1(56, vp);
1756 
1757 	return error;
1758 }
1759 
1760 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)1761 mac_vnode_check_rename(vfs_context_t ctx, struct vnode *dvp,
1762     struct vnode *vp, struct componentname *cnp, struct vnode *tdvp,
1763     struct vnode *tvp, struct componentname *tcnp)
1764 {
1765 	kauth_cred_t cred;
1766 	int error;
1767 
1768 #if SECURITY_MAC_CHECK_ENFORCE
1769 	/* 21167099 - only check if we allow write */
1770 	if (!mac_vnode_enforce) {
1771 		return 0;
1772 	}
1773 #endif
1774 	cred = vfs_context_ucred(ctx);
1775 	if (!mac_cred_check_enforce(cred)) {
1776 		return 0;
1777 	}
1778 
1779 	VFS_KERNEL_DEBUG_START1(57, vp);
1780 	MAC_CHECK(vnode_check_rename_from, cred, dvp, mac_vnode_label(dvp), vp,
1781 	    mac_vnode_label(vp), cnp);
1782 	if (error) {
1783 		VFS_KERNEL_DEBUG_END1(57, vp);
1784 		return error;
1785 	}
1786 
1787 	MAC_CHECK(vnode_check_rename_to, cred, tdvp, mac_vnode_label(tdvp), tvp,
1788 	    tvp != NULL ? mac_vnode_label(tvp) : NULL, dvp == tdvp, tcnp);
1789 	if (error) {
1790 		VFS_KERNEL_DEBUG_END1(57, vp);
1791 		return error;
1792 	}
1793 
1794 	MAC_CHECK(vnode_check_rename, cred, dvp, mac_vnode_label(dvp), vp,
1795 	    mac_vnode_label(vp), cnp, tdvp, mac_vnode_label(tdvp), tvp,
1796 	    tvp != NULL ? mac_vnode_label(tvp) : NULL, tcnp);
1797 	VFS_KERNEL_DEBUG_END1(57, vp);
1798 	return error;
1799 }
1800 
1801 int
mac_vnode_check_revoke(vfs_context_t ctx,struct vnode * vp)1802 mac_vnode_check_revoke(vfs_context_t ctx, struct vnode *vp)
1803 {
1804 	kauth_cred_t cred;
1805 	int error;
1806 
1807 #if SECURITY_MAC_CHECK_ENFORCE
1808 	/* 21167099 - only check if we allow write */
1809 	if (!mac_vnode_enforce) {
1810 		return 0;
1811 	}
1812 #endif
1813 	cred = vfs_context_ucred(ctx);
1814 	if (!mac_cred_check_enforce(cred)) {
1815 		return 0;
1816 	}
1817 	VFS_KERNEL_DEBUG_START1(58, vp);
1818 	MAC_CHECK(vnode_check_revoke, cred, vp, mac_vnode_label(vp));
1819 	VFS_KERNEL_DEBUG_END1(58, vp);
1820 	return error;
1821 }
1822 
1823 int
mac_vnode_check_searchfs(vfs_context_t ctx,struct vnode * vp,struct attrlist * returnattrs,struct attrlist * searchattrs)1824 mac_vnode_check_searchfs(vfs_context_t ctx, struct vnode *vp, struct attrlist *returnattrs,
1825     struct attrlist *searchattrs)
1826 {
1827 	kauth_cred_t cred;
1828 	int error;
1829 
1830 #if SECURITY_MAC_CHECK_ENFORCE
1831 	/* 21167099 - only check if we allow write */
1832 	if (!mac_vnode_enforce) {
1833 		return 0;
1834 	}
1835 #endif
1836 	cred = vfs_context_ucred(ctx);
1837 	if (!mac_cred_check_enforce(cred)) {
1838 		return 0;
1839 	}
1840 	VFS_KERNEL_DEBUG_START1(59, vp);
1841 	MAC_CHECK(vnode_check_searchfs, cred, vp, mac_vnode_label(vp), returnattrs, searchattrs);
1842 	VFS_KERNEL_DEBUG_END1(59, vp);
1843 	return error;
1844 }
1845 
1846 int
mac_vnode_check_select(vfs_context_t ctx,struct vnode * vp,int which)1847 mac_vnode_check_select(vfs_context_t ctx, struct vnode *vp, int which)
1848 {
1849 	kauth_cred_t cred;
1850 	int error;
1851 
1852 #if SECURITY_MAC_CHECK_ENFORCE
1853 	/* 21167099 - only check if we allow write */
1854 	if (!mac_vnode_enforce) {
1855 		return 0;
1856 	}
1857 #endif
1858 	cred = vfs_context_ucred(ctx);
1859 	if (!mac_cred_check_enforce(cred)) {
1860 		return 0;
1861 	}
1862 	VFS_KERNEL_DEBUG_START1(60, vp);
1863 	MAC_CHECK(vnode_check_select, cred, vp, mac_vnode_label(vp), which);
1864 	VFS_KERNEL_DEBUG_END1(60, vp);
1865 	return error;
1866 }
1867 
1868 int
mac_vnode_check_setacl(vfs_context_t ctx,struct vnode * vp,struct kauth_acl * acl)1869 mac_vnode_check_setacl(vfs_context_t ctx, struct vnode *vp,
1870     struct kauth_acl *acl)
1871 {
1872 	kauth_cred_t cred;
1873 	int error;
1874 
1875 #if SECURITY_MAC_CHECK_ENFORCE
1876 	/* 21167099 - only check if we allow write */
1877 	if (!mac_vnode_enforce) {
1878 		return 0;
1879 	}
1880 #endif
1881 	cred = vfs_context_ucred(ctx);
1882 	if (!mac_cred_check_enforce(cred)) {
1883 		return 0;
1884 	}
1885 	VFS_KERNEL_DEBUG_START1(61, vp);
1886 	MAC_CHECK(vnode_check_setacl, cred, vp, mac_vnode_label(vp), acl);
1887 	VFS_KERNEL_DEBUG_END1(61, vp);
1888 	return error;
1889 }
1890 
1891 int
mac_vnode_check_setattrlist(vfs_context_t ctx,struct vnode * vp,struct attrlist * alist)1892 mac_vnode_check_setattrlist(vfs_context_t ctx, struct vnode *vp,
1893     struct attrlist *alist)
1894 {
1895 	kauth_cred_t cred;
1896 	int error;
1897 
1898 #if SECURITY_MAC_CHECK_ENFORCE
1899 	/* 21167099 - only check if we allow write */
1900 	if (!mac_vnode_enforce) {
1901 		return 0;
1902 	}
1903 #endif
1904 	cred = vfs_context_ucred(ctx);
1905 	if (!mac_cred_check_enforce(cred)) {
1906 		return 0;
1907 	}
1908 	VFS_KERNEL_DEBUG_START1(62, vp);
1909 	MAC_CHECK(vnode_check_setattrlist, cred, vp, mac_vnode_label(vp), alist);
1910 	VFS_KERNEL_DEBUG_END1(62, vp);
1911 	return error;
1912 }
1913 
1914 int
mac_vnode_check_setextattr(vfs_context_t ctx,struct vnode * vp,const char * name,struct uio * uio)1915 mac_vnode_check_setextattr(vfs_context_t ctx, struct vnode *vp,
1916     const char *name, struct uio *uio)
1917 {
1918 	kauth_cred_t cred;
1919 	int error;
1920 
1921 #if SECURITY_MAC_CHECK_ENFORCE
1922 	/* 21167099 - only check if we allow write */
1923 	if (!mac_vnode_enforce) {
1924 		return 0;
1925 	}
1926 #endif
1927 	cred = vfs_context_ucred(ctx);
1928 	if (!mac_cred_check_enforce(cred)) {
1929 		return 0;
1930 	}
1931 	VFS_KERNEL_DEBUG_START1(63, vp);
1932 	MAC_CHECK(vnode_check_setextattr, cred, vp, mac_vnode_label(vp),
1933 	    name, uio);
1934 	VFS_KERNEL_DEBUG_END1(63, vp);
1935 	return error;
1936 }
1937 
1938 int
mac_vnode_check_setflags(vfs_context_t ctx,struct vnode * vp,u_long flags)1939 mac_vnode_check_setflags(vfs_context_t ctx, struct vnode *vp, u_long flags)
1940 {
1941 	kauth_cred_t cred;
1942 	int error;
1943 
1944 #if SECURITY_MAC_CHECK_ENFORCE
1945 	/* 21167099 - only check if we allow write */
1946 	if (!mac_vnode_enforce) {
1947 		return 0;
1948 	}
1949 #endif
1950 	cred = vfs_context_ucred(ctx);
1951 	if (!mac_cred_check_enforce(cred)) {
1952 		return 0;
1953 	}
1954 	VFS_KERNEL_DEBUG_START1(64, vp);
1955 	MAC_CHECK(vnode_check_setflags, cred, vp, mac_vnode_label(vp), flags);
1956 	VFS_KERNEL_DEBUG_END1(64, vp);
1957 	return error;
1958 }
1959 
1960 int
mac_vnode_check_setmode(vfs_context_t ctx,struct vnode * vp,mode_t mode)1961 mac_vnode_check_setmode(vfs_context_t ctx, struct vnode *vp, mode_t mode)
1962 {
1963 	kauth_cred_t cred;
1964 	int error;
1965 
1966 #if SECURITY_MAC_CHECK_ENFORCE
1967 	/* 21167099 - only check if we allow write */
1968 	if (!mac_vnode_enforce) {
1969 		return 0;
1970 	}
1971 #endif
1972 	cred = vfs_context_ucred(ctx);
1973 	if (!mac_cred_check_enforce(cred)) {
1974 		return 0;
1975 	}
1976 	VFS_KERNEL_DEBUG_START1(65, vp);
1977 	MAC_CHECK(vnode_check_setmode, cred, vp, mac_vnode_label(vp), mode);
1978 	VFS_KERNEL_DEBUG_END1(65, vp);
1979 	return error;
1980 }
1981 
1982 int
mac_vnode_check_setowner(vfs_context_t ctx,struct vnode * vp,uid_t uid,gid_t gid)1983 mac_vnode_check_setowner(vfs_context_t ctx, struct vnode *vp, uid_t uid,
1984     gid_t gid)
1985 {
1986 	kauth_cred_t cred;
1987 	int error;
1988 
1989 #if SECURITY_MAC_CHECK_ENFORCE
1990 	/* 21167099 - only check if we allow write */
1991 	if (!mac_vnode_enforce) {
1992 		return 0;
1993 	}
1994 #endif
1995 	cred = vfs_context_ucred(ctx);
1996 	if (!mac_cred_check_enforce(cred)) {
1997 		return 0;
1998 	}
1999 	VFS_KERNEL_DEBUG_START1(66, vp);
2000 	MAC_CHECK(vnode_check_setowner, cred, vp, mac_vnode_label(vp), uid, gid);
2001 	VFS_KERNEL_DEBUG_END1(66, vp);
2002 	return error;
2003 }
2004 
2005 int
mac_vnode_check_setutimes(vfs_context_t ctx,struct vnode * vp,struct timespec atime,struct timespec mtime)2006 mac_vnode_check_setutimes(vfs_context_t ctx, struct vnode *vp,
2007     struct timespec atime, struct timespec mtime)
2008 {
2009 	kauth_cred_t cred;
2010 	int error;
2011 
2012 #if SECURITY_MAC_CHECK_ENFORCE
2013 	/* 21167099 - only check if we allow write */
2014 	if (!mac_vnode_enforce) {
2015 		return 0;
2016 	}
2017 #endif
2018 	cred = vfs_context_ucred(ctx);
2019 	if (!mac_cred_check_enforce(cred)) {
2020 		return 0;
2021 	}
2022 	VFS_KERNEL_DEBUG_START1(67, vp);
2023 	MAC_CHECK(vnode_check_setutimes, cred, vp, mac_vnode_label(vp), atime,
2024 	    mtime);
2025 	VFS_KERNEL_DEBUG_END1(67, vp);
2026 	return error;
2027 }
2028 
2029 int
mac_vnode_check_stat(vfs_context_t ctx,struct ucred * file_cred,struct vnode * vp)2030 mac_vnode_check_stat(vfs_context_t ctx, struct ucred *file_cred,
2031     struct vnode *vp)
2032 {
2033 	kauth_cred_t cred;
2034 	int error;
2035 
2036 #if SECURITY_MAC_CHECK_ENFORCE
2037 	/* 21167099 - only check if we allow write */
2038 	if (!mac_vnode_enforce) {
2039 		return 0;
2040 	}
2041 #endif
2042 	cred = vfs_context_ucred(ctx);
2043 	if (!mac_cred_check_enforce(cred)) {
2044 		return 0;
2045 	}
2046 	VFS_KERNEL_DEBUG_START1(68, vp);
2047 	MAC_CHECK(vnode_check_stat, cred, file_cred, vp,
2048 	    mac_vnode_label(vp));
2049 	VFS_KERNEL_DEBUG_END1(68, vp);
2050 	return error;
2051 }
2052 
2053 int
mac_vnode_check_trigger_resolve(vfs_context_t ctx,struct vnode * dvp,struct componentname * cnp)2054 mac_vnode_check_trigger_resolve(vfs_context_t ctx, struct vnode *dvp,
2055     struct componentname *cnp)
2056 {
2057 	kauth_cred_t cred;
2058 	int error;
2059 
2060 #if SECURITY_MAC_CHECK_ENFORCE
2061 	/* 21167099 - only check if we allow write */
2062 	if (!mac_vnode_enforce) {
2063 		return 0;
2064 	}
2065 #endif
2066 	cred = vfs_context_ucred(ctx);
2067 	if (!mac_cred_check_enforce(cred)) {
2068 		return 0;
2069 	}
2070 	VFS_KERNEL_DEBUG_START1(69, dvp);
2071 	MAC_CHECK(vnode_check_trigger_resolve, cred, dvp, mac_vnode_label(dvp), cnp);
2072 	VFS_KERNEL_DEBUG_END1(69, dvp);
2073 	return error;
2074 }
2075 
2076 int
mac_vnode_check_truncate(vfs_context_t ctx,struct ucred * file_cred,struct vnode * vp)2077 mac_vnode_check_truncate(vfs_context_t ctx, struct ucred *file_cred,
2078     struct vnode *vp)
2079 {
2080 	kauth_cred_t cred;
2081 	int error;
2082 
2083 #if SECURITY_MAC_CHECK_ENFORCE
2084 	/* 21167099 - only check if we allow write */
2085 	if (!mac_vnode_enforce) {
2086 		return 0;
2087 	}
2088 #endif
2089 	cred = vfs_context_ucred(ctx);
2090 	if (!mac_cred_check_enforce(cred)) {
2091 		return 0;
2092 	}
2093 	VFS_KERNEL_DEBUG_START1(70, vp);
2094 	MAC_CHECK(vnode_check_truncate, cred, file_cred, vp,
2095 	    mac_vnode_label(vp));
2096 	VFS_KERNEL_DEBUG_END1(70, vp);
2097 
2098 	return error;
2099 }
2100 
2101 int
mac_vnode_check_write(vfs_context_t ctx,struct ucred * file_cred,struct vnode * vp)2102 mac_vnode_check_write(vfs_context_t ctx, struct ucred *file_cred,
2103     struct vnode *vp)
2104 {
2105 	kauth_cred_t cred;
2106 	int error;
2107 
2108 #if SECURITY_MAC_CHECK_ENFORCE
2109 	/* 21167099 - only check if we allow write */
2110 	if (!mac_vnode_enforce) {
2111 		return 0;
2112 	}
2113 #endif
2114 	cred = vfs_context_ucred(ctx);
2115 	if (!mac_cred_check_enforce(cred)) {
2116 		return 0;
2117 	}
2118 	VFS_KERNEL_DEBUG_START1(71, vp);
2119 	MAC_CHECK(vnode_check_write, cred, file_cred, vp, mac_vnode_label(vp));
2120 	VFS_KERNEL_DEBUG_END1(71, vp);
2121 
2122 	return error;
2123 }
2124 
2125 int
mac_vnode_check_uipc_bind(vfs_context_t ctx,struct vnode * dvp,struct componentname * cnp,struct vnode_attr * vap)2126 mac_vnode_check_uipc_bind(vfs_context_t ctx, struct vnode *dvp,
2127     struct componentname *cnp, struct vnode_attr *vap)
2128 {
2129 	kauth_cred_t cred;
2130 	int error;
2131 
2132 #if SECURITY_MAC_CHECK_ENFORCE
2133 	/* 21167099 - only check if we allow write */
2134 	if (!mac_vnode_enforce) {
2135 		return 0;
2136 	}
2137 #endif
2138 	cred = vfs_context_ucred(ctx);
2139 	if (!mac_cred_check_enforce(cred)) {
2140 		return 0;
2141 	}
2142 	VFS_KERNEL_DEBUG_START1(72, dvp);
2143 	MAC_CHECK(vnode_check_uipc_bind, cred, dvp, mac_vnode_label(dvp), cnp, vap);
2144 	VFS_KERNEL_DEBUG_END1(72, dvp);
2145 	return error;
2146 }
2147 
2148 int
mac_vnode_check_uipc_connect(vfs_context_t ctx,struct vnode * vp,struct socket * so)2149 mac_vnode_check_uipc_connect(vfs_context_t ctx, struct vnode *vp, struct socket *so)
2150 {
2151 	kauth_cred_t cred;
2152 	int error;
2153 
2154 #if SECURITY_MAC_CHECK_ENFORCE
2155 	/* 21167099 - only check if we allow write */
2156 	if (!mac_vnode_enforce) {
2157 		return 0;
2158 	}
2159 #endif
2160 	cred = vfs_context_ucred(ctx);
2161 	if (!mac_cred_check_enforce(cred)) {
2162 		return 0;
2163 	}
2164 	VFS_KERNEL_DEBUG_START1(73, vp);
2165 	MAC_CHECK(vnode_check_uipc_connect, cred, vp, mac_vnode_label(vp), (socket_t) so);
2166 	VFS_KERNEL_DEBUG_END1(73, vp);
2167 	return error;
2168 }
2169 
2170 void
mac_vnode_label_update(vfs_context_t ctx,struct vnode * vp,struct label * newlabel)2171 mac_vnode_label_update(vfs_context_t ctx, struct vnode *vp, struct label *newlabel)
2172 {
2173 	kauth_cred_t cred = vfs_context_ucred(ctx);
2174 	struct label *tmpl = NULL;
2175 
2176 	if (mac_vnode_label(vp) == NULL) {
2177 		tmpl = mac_vnode_label_alloc(vp);
2178 	}
2179 
2180 	vnode_lock(vp);
2181 
2182 	/*
2183 	 * Recheck under lock.  We allocate labels for vnodes lazily, so
2184 	 * somebody else might have already got here first.
2185 	 */
2186 	if (mac_vnode_label(vp) == NULL) {
2187 		vp->v_label = tmpl;
2188 		tmpl = NULL;
2189 	}
2190 
2191 	VFS_KERNEL_DEBUG_START1(74, vp);
2192 	MAC_PERFORM(vnode_label_update, cred, vp, mac_vnode_label(vp), newlabel);
2193 	VFS_KERNEL_DEBUG_END1(74, vp);
2194 	vnode_unlock(vp);
2195 
2196 	if (tmpl != NULL) {
2197 		mac_vnode_label_free(tmpl);
2198 	}
2199 }
2200 
2201 int
mac_vnode_find_sigs(struct proc * p,struct vnode * vp,off_t offset)2202 mac_vnode_find_sigs(struct proc *p, struct vnode *vp, off_t offset)
2203 {
2204 	int error;
2205 
2206 #if SECURITY_MAC_CHECK_ENFORCE
2207 	/* 21167099 - only check if we allow write */
2208 	if (!mac_proc_enforce || !mac_vnode_enforce) {
2209 		return 0;
2210 	}
2211 #endif
2212 
2213 	VFS_KERNEL_DEBUG_START1(75, vp);
2214 	MAC_CHECK(vnode_find_sigs, p, vp, offset, mac_vnode_label(vp));
2215 	VFS_KERNEL_DEBUG_END1(75, vp);
2216 
2217 	return error;
2218 }
2219 
2220 void
mac_mount_label_associate(vfs_context_t ctx,struct mount * mp)2221 mac_mount_label_associate(vfs_context_t ctx, struct mount *mp)
2222 {
2223 	kauth_cred_t cred = vfs_context_ucred(ctx);
2224 
2225 	/* XXX: eventually this logic may be handled by the policy? */
2226 
2227 	/* We desire MULTILABEL for the root filesystem. */
2228 	if ((mp->mnt_flag & MNT_ROOTFS) &&
2229 	    (strcmp(mp->mnt_vfsstat.f_fstypename, "hfs") == 0)) {
2230 		mp->mnt_flag |= MNT_MULTILABEL;
2231 	}
2232 
2233 	/* MULTILABEL on DEVFS. */
2234 	if (strcmp(mp->mnt_vfsstat.f_fstypename, "devfs") == 0) {
2235 		mp->mnt_flag |= MNT_MULTILABEL;
2236 	}
2237 
2238 	/* MULTILABEL on FDESC pseudo-filesystem. */
2239 	if (strcmp(mp->mnt_vfsstat.f_fstypename, "fdesc") == 0) {
2240 		mp->mnt_flag |= MNT_MULTILABEL;
2241 	}
2242 
2243 	/* MULTILABEL on all NFS filesystems. */
2244 	if (strcmp(mp->mnt_vfsstat.f_fstypename, "nfs") == 0) {
2245 		mp->mnt_flag |= MNT_MULTILABEL;
2246 	}
2247 
2248 	/* MULTILABEL on all AFP filesystems. */
2249 	if (strcmp(mp->mnt_vfsstat.f_fstypename, "afpfs") == 0) {
2250 		mp->mnt_flag |= MNT_MULTILABEL;
2251 	}
2252 
2253 	if (mp->mnt_vtable != NULL) {
2254 		/* Any filesystem that supports native XATTRs. */
2255 		if ((mp->mnt_vtable->vfc_vfsflags & VFC_VFSNATIVEXATTR)) {
2256 			mp->mnt_flag |= MNT_MULTILABEL;
2257 		}
2258 
2259 		/* Filesystem does not support multilabel. */
2260 		if ((mp->mnt_vtable->vfc_vfsflags & VFC_VFSNOMACLABEL) &&
2261 		    (mp->mnt_flag & MNT_MULTILABEL)) {
2262 			mp->mnt_flag &= ~MNT_MULTILABEL;
2263 		}
2264 	}
2265 
2266 	VFS_KERNEL_DEBUG_START1(76, mp);
2267 	MAC_PERFORM(mount_label_associate, cred, mp, mac_mount_label(mp));
2268 	VFS_KERNEL_DEBUG_END1(76, mp);
2269 #if DEBUG
2270 	printf("MAC Framework enabling %s support: %s -> %s (%s)\n",
2271 	    mp->mnt_flag & MNT_MULTILABEL ? "multilabel" : "singlelabel",
2272 	    mp->mnt_vfsstat.f_mntfromname,
2273 	    mp->mnt_vfsstat.f_mntonname,
2274 	    mp->mnt_vfsstat.f_fstypename);
2275 #endif
2276 }
2277 
2278 int
mac_mount_check_mount(vfs_context_t ctx,struct vnode * vp,struct componentname * cnp,const char * vfc_name)2279 mac_mount_check_mount(vfs_context_t ctx, struct vnode *vp,
2280     struct componentname *cnp, const char *vfc_name)
2281 {
2282 	kauth_cred_t cred;
2283 	int error;
2284 
2285 #if SECURITY_MAC_CHECK_ENFORCE
2286 	/* 21167099 - only check if we allow write */
2287 	if (!mac_vnode_enforce) {
2288 		return 0;
2289 	}
2290 #endif
2291 	cred = vfs_context_ucred(ctx);
2292 	if (!mac_cred_check_enforce(cred)) {
2293 		return 0;
2294 	}
2295 	VFS_KERNEL_DEBUG_START1(77, vp);
2296 	MAC_CHECK(mount_check_mount, cred, vp, mac_vnode_label(vp), cnp, vfc_name);
2297 	VFS_KERNEL_DEBUG_END1(77, vp);
2298 
2299 	return error;
2300 }
2301 
2302 int
mac_mount_check_mount_late(vfs_context_t ctx,struct mount * mp)2303 mac_mount_check_mount_late(vfs_context_t ctx, struct mount *mp)
2304 {
2305 	kauth_cred_t cred;
2306 	int error;
2307 
2308 #if SECURITY_MAC_CHECK_ENFORCE
2309 	/* 21167099 - only check if we allow write */
2310 	if (!mac_vnode_enforce) {
2311 		return 0;
2312 	}
2313 #endif
2314 	cred = vfs_context_ucred(ctx);
2315 	if (!mac_cred_check_enforce(cred)) {
2316 		return 0;
2317 	}
2318 	VFS_KERNEL_DEBUG_START1(78, mp);
2319 	MAC_CHECK(mount_check_mount_late, cred, mp);
2320 	VFS_KERNEL_DEBUG_END1(78, mp);
2321 
2322 	return error;
2323 }
2324 
2325 int
mac_mount_check_snapshot_create(vfs_context_t ctx,struct mount * mp,const char * name)2326 mac_mount_check_snapshot_create(vfs_context_t ctx, struct mount *mp,
2327     const char *name)
2328 {
2329 	kauth_cred_t cred;
2330 	int error;
2331 
2332 #if SECURITY_MAC_CHECK_ENFORCE
2333 	/* 21167099 - only check if we allow write */
2334 	if (!mac_vnode_enforce) {
2335 		return 0;
2336 	}
2337 #endif
2338 	cred = vfs_context_ucred(ctx);
2339 	if (!mac_cred_check_enforce(cred)) {
2340 		return 0;
2341 	}
2342 	VFS_KERNEL_DEBUG_START1(79, mp);
2343 	MAC_CHECK(mount_check_snapshot_create, cred, mp, name);
2344 	VFS_KERNEL_DEBUG_END1(79, mp);
2345 	return error;
2346 }
2347 
2348 int
mac_mount_check_snapshot_delete(vfs_context_t ctx,struct mount * mp,const char * name)2349 mac_mount_check_snapshot_delete(vfs_context_t ctx, struct mount *mp,
2350     const char *name)
2351 {
2352 	kauth_cred_t cred;
2353 	int error;
2354 
2355 #if SECURITY_MAC_CHECK_ENFORCE
2356 	/* 21167099 - only check if we allow write */
2357 	if (!mac_vnode_enforce) {
2358 		return 0;
2359 	}
2360 #endif
2361 	cred = vfs_context_ucred(ctx);
2362 	if (!mac_cred_check_enforce(cred)) {
2363 		return 0;
2364 	}
2365 	VFS_KERNEL_DEBUG_START1(80, mp);
2366 	MAC_CHECK(mount_check_snapshot_delete, cred, mp, name);
2367 	VFS_KERNEL_DEBUG_END1(80, mp);
2368 	return error;
2369 }
2370 
2371 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)2372 mac_mount_check_snapshot_mount(vfs_context_t ctx, struct vnode *rvp, struct vnode *vp, struct componentname *cnp,
2373     const char *name, const char *vfc_name)
2374 {
2375 	kauth_cred_t cred;
2376 	int error;
2377 
2378 #if SECURITY_MAC_CHECK_ENFORCE
2379 	/* 21167099 - only check if we allow write */
2380 	if (!mac_vnode_enforce) {
2381 		return 0;
2382 	}
2383 #endif
2384 	cred = vfs_context_ucred(ctx);
2385 	if (!mac_cred_check_enforce(cred)) {
2386 		return 0;
2387 	}
2388 	VFS_KERNEL_DEBUG_START1(92, vp);
2389 	MAC_CHECK(mount_check_snapshot_mount, cred, rvp, vp, cnp, name, vfc_name);
2390 	VFS_KERNEL_DEBUG_END1(92, vp);
2391 	return error;
2392 }
2393 
2394 int
mac_mount_check_snapshot_revert(vfs_context_t ctx,struct mount * mp,const char * name)2395 mac_mount_check_snapshot_revert(vfs_context_t ctx, struct mount *mp,
2396     const char *name)
2397 {
2398 	kauth_cred_t cred;
2399 	int error;
2400 
2401 #if SECURITY_MAC_CHECK_ENFORCE
2402 	/* 21167099 - only check if we allow write */
2403 	if (!mac_vnode_enforce) {
2404 		return 0;
2405 	}
2406 #endif
2407 	cred = vfs_context_ucred(ctx);
2408 	if (!mac_cred_check_enforce(cred)) {
2409 		return 0;
2410 	}
2411 	VFS_KERNEL_DEBUG_START1(81, mp);
2412 	MAC_CHECK(mount_check_snapshot_revert, cred, mp, name);
2413 	VFS_KERNEL_DEBUG_END1(81, mp);
2414 	return error;
2415 }
2416 
2417 int
mac_mount_check_remount(vfs_context_t ctx,struct mount * mp)2418 mac_mount_check_remount(vfs_context_t ctx, struct mount *mp)
2419 {
2420 	kauth_cred_t cred;
2421 	int error;
2422 
2423 #if SECURITY_MAC_CHECK_ENFORCE
2424 	/* 21167099 - only check if we allow write */
2425 	if (!mac_vnode_enforce) {
2426 		return 0;
2427 	}
2428 #endif
2429 	cred = vfs_context_ucred(ctx);
2430 	if (!mac_cred_check_enforce(cred)) {
2431 		return 0;
2432 	}
2433 	VFS_KERNEL_DEBUG_START1(82, mp);
2434 	MAC_CHECK(mount_check_remount, cred, mp, mac_mount_label(mp));
2435 	VFS_KERNEL_DEBUG_END1(82, mp);
2436 
2437 	return error;
2438 }
2439 
2440 int
mac_mount_check_umount(vfs_context_t ctx,struct mount * mp)2441 mac_mount_check_umount(vfs_context_t ctx, struct mount *mp)
2442 {
2443 	kauth_cred_t cred;
2444 	int error;
2445 
2446 #if SECURITY_MAC_CHECK_ENFORCE
2447 	/* 21167099 - only check if we allow write */
2448 	if (!mac_vnode_enforce) {
2449 		return 0;
2450 	}
2451 #endif
2452 	cred = vfs_context_ucred(ctx);
2453 	if (!mac_cred_check_enforce(cred)) {
2454 		return 0;
2455 	}
2456 	VFS_KERNEL_DEBUG_START1(83, mp);
2457 	MAC_CHECK(mount_check_umount, cred, mp, mac_mount_label(mp));
2458 	VFS_KERNEL_DEBUG_END1(83, mp);
2459 
2460 	return error;
2461 }
2462 
2463 int
mac_mount_check_getattr(vfs_context_t ctx,struct mount * mp,struct vfs_attr * vfa)2464 mac_mount_check_getattr(vfs_context_t ctx, struct mount *mp,
2465     struct vfs_attr *vfa)
2466 {
2467 	kauth_cred_t cred;
2468 	int error;
2469 
2470 #if SECURITY_MAC_CHECK_ENFORCE
2471 	/* 21167099 - only check if we allow write */
2472 	if (!mac_vnode_enforce) {
2473 		return 0;
2474 	}
2475 #endif
2476 	cred = vfs_context_ucred(ctx);
2477 	if (!mac_cred_check_enforce(cred)) {
2478 		return 0;
2479 	}
2480 	VFS_KERNEL_DEBUG_START1(84, mp);
2481 	MAC_CHECK(mount_check_getattr, cred, mp, mac_mount_label(mp), vfa);
2482 	VFS_KERNEL_DEBUG_END1(84, mp);
2483 	return error;
2484 }
2485 
2486 int
mac_mount_check_setattr(vfs_context_t ctx,struct mount * mp,struct vfs_attr * vfa)2487 mac_mount_check_setattr(vfs_context_t ctx, struct mount *mp,
2488     struct vfs_attr *vfa)
2489 {
2490 	kauth_cred_t cred;
2491 	int error;
2492 
2493 #if SECURITY_MAC_CHECK_ENFORCE
2494 	/* 21167099 - only check if we allow write */
2495 	if (!mac_vnode_enforce) {
2496 		return 0;
2497 	}
2498 #endif
2499 	cred = vfs_context_ucred(ctx);
2500 	if (!mac_cred_check_enforce(cred)) {
2501 		return 0;
2502 	}
2503 	VFS_KERNEL_DEBUG_START1(85, mp);
2504 	MAC_CHECK(mount_check_setattr, cred, mp, mac_mount_label(mp), vfa);
2505 	VFS_KERNEL_DEBUG_END1(85, mp);
2506 	return error;
2507 }
2508 
2509 int
mac_mount_check_stat(vfs_context_t ctx,struct mount * mount)2510 mac_mount_check_stat(vfs_context_t ctx, struct mount *mount)
2511 {
2512 	kauth_cred_t cred;
2513 	int error;
2514 
2515 #if SECURITY_MAC_CHECK_ENFORCE
2516 	/* 21167099 - only check if we allow write */
2517 	if (!mac_vnode_enforce) {
2518 		return 0;
2519 	}
2520 #endif
2521 	cred = vfs_context_ucred(ctx);
2522 	if (!mac_cred_check_enforce(cred)) {
2523 		return 0;
2524 	}
2525 	VFS_KERNEL_DEBUG_START1(86, mount);
2526 	MAC_CHECK(mount_check_stat, cred, mount, mac_mount_label(mount));
2527 	VFS_KERNEL_DEBUG_END1(86, mount);
2528 
2529 	return error;
2530 }
2531 
2532 int
mac_mount_check_label_update(vfs_context_t ctx,struct mount * mount)2533 mac_mount_check_label_update(vfs_context_t ctx, struct mount *mount)
2534 {
2535 	kauth_cred_t cred;
2536 	int error;
2537 
2538 #if SECURITY_MAC_CHECK_ENFORCE
2539 	/* 21167099 - only check if we allow write */
2540 	if (!mac_vnode_enforce) {
2541 		return 0;
2542 	}
2543 #endif
2544 	cred = vfs_context_ucred(ctx);
2545 	if (!mac_cred_check_enforce(cred)) {
2546 		return 0;
2547 	}
2548 	VFS_KERNEL_DEBUG_START1(87, mount);
2549 	MAC_CHECK(mount_check_label_update, cred, mount, mac_mount_label(mount));
2550 	VFS_KERNEL_DEBUG_END1(87, mount);
2551 
2552 	return error;
2553 }
2554 
2555 int
mac_mount_check_fsctl(vfs_context_t ctx,struct mount * mp,u_long cmd)2556 mac_mount_check_fsctl(vfs_context_t ctx, struct mount *mp, u_long cmd)
2557 {
2558 	kauth_cred_t cred;
2559 	int error;
2560 
2561 #if SECURITY_MAC_CHECK_ENFORCE
2562 	/* 21167099 - only check if we allow write */
2563 	if (!mac_vnode_enforce) {
2564 		return 0;
2565 	}
2566 #endif
2567 	cred = vfs_context_ucred(ctx);
2568 	if (!mac_cred_check_enforce(cred)) {
2569 		return 0;
2570 	}
2571 	VFS_KERNEL_DEBUG_START1(88, mp);
2572 	MAC_CHECK(mount_check_fsctl, cred, mp, mac_mount_label(mp), cmd);
2573 	VFS_KERNEL_DEBUG_END1(88, mp);
2574 
2575 	return error;
2576 }
2577 
2578 void
mac_devfs_label_associate_device(dev_t dev,struct devnode * de,const char * fullpath)2579 mac_devfs_label_associate_device(dev_t dev, struct devnode *de,
2580     const char *fullpath)
2581 {
2582 #if SECURITY_MAC_CHECK_ENFORCE
2583 	/* 21167099 - only check if we allow write */
2584 	if (!mac_device_enforce) {
2585 		return;
2586 	}
2587 #endif
2588 
2589 	VFS_KERNEL_DEBUG_START1(89, de);
2590 	MAC_PERFORM(devfs_label_associate_device, dev, de, mac_devfs_label(de),
2591 	    fullpath);
2592 	VFS_KERNEL_DEBUG_END1(89, de);
2593 }
2594 
2595 void
mac_devfs_label_associate_directory(const char * dirname,int dirnamelen,struct devnode * de,const char * fullpath)2596 mac_devfs_label_associate_directory(const char *dirname, int dirnamelen,
2597     struct devnode *de, const char *fullpath)
2598 {
2599 #if SECURITY_MAC_CHECK_ENFORCE
2600 	/* 21167099 - only check if we allow write */
2601 	if (!mac_device_enforce) {
2602 		return;
2603 	}
2604 #endif
2605 
2606 	VFS_KERNEL_DEBUG_START1(90, de);
2607 	MAC_PERFORM(devfs_label_associate_directory, dirname, dirnamelen, de,
2608 	    mac_devfs_label(de), fullpath);
2609 	VFS_KERNEL_DEBUG_END1(90, de);
2610 }
2611 
2612 int
vn_setlabel(struct vnode * vp,struct label * intlabel,vfs_context_t context)2613 vn_setlabel(struct vnode *vp, struct label *intlabel, vfs_context_t context)
2614 {
2615 	int error;
2616 
2617 #if SECURITY_MAC_CHECK_ENFORCE
2618 	/* 21167099 - only check if we allow write */
2619 	if (!mac_vnode_enforce) {
2620 		return 0;
2621 	}
2622 #endif
2623 	if (!mac_label_vnodes) {
2624 		return 0;
2625 	}
2626 
2627 	if (vp->v_mount == NULL) {
2628 		printf("vn_setlabel: null v_mount\n");
2629 		if (vp->v_type != VNON) {
2630 			printf("vn_setlabel: null v_mount with non-VNON\n");
2631 		}
2632 		return EBADF;
2633 	}
2634 
2635 	if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) {
2636 		return ENOTSUP;
2637 	}
2638 
2639 	/*
2640 	 * Multi-phase commit.  First check the policies to confirm the
2641 	 * change is OK.  Then commit via the filesystem.  Finally,
2642 	 * update the actual vnode label.  Question: maybe the filesystem
2643 	 * should update the vnode at the end as part of VNOP_SETLABEL()?
2644 	 */
2645 	error = mac_vnode_check_label_update(context, vp, intlabel);
2646 	if (error) {
2647 		return error;
2648 	}
2649 
2650 	error = VNOP_SETLABEL(vp, intlabel, context);
2651 	if (error == ENOTSUP) {
2652 		error = mac_vnode_label_store(context, vp,
2653 		    intlabel);
2654 		if (error) {
2655 			printf("%s: mac_vnode_label_store failed %d\n",
2656 			    __func__, error);
2657 			return error;
2658 		}
2659 		mac_vnode_label_update(context, vp, intlabel);
2660 	} else if (error) {
2661 		printf("vn_setlabel: vop setlabel failed %d\n", error);
2662 		return error;
2663 	}
2664 
2665 	return 0;
2666 }
2667 
2668 int
mac_vnode_label_associate_fdesc(struct mount * mp,struct fdescnode * fnp,struct vnode * vp,vfs_context_t ctx)2669 mac_vnode_label_associate_fdesc(struct mount *mp, struct fdescnode *fnp,
2670     struct vnode *vp, vfs_context_t ctx)
2671 {
2672 	struct fileproc *fp;
2673 #if CONFIG_MACF_SOCKET_SUBSET
2674 	struct socket *so;
2675 #endif
2676 	struct pipe *cpipe;
2677 	struct vnode *fvp;
2678 	struct proc *p;
2679 	int error;
2680 
2681 	error = 0;
2682 
2683 	VFS_KERNEL_DEBUG_START1(91, vp);
2684 	/*
2685 	 * If no backing file, let the policy choose which label to use.
2686 	 */
2687 	if (fnp->fd_fd == -1) {
2688 		MAC_PERFORM(vnode_label_associate_file, vfs_context_ucred(ctx),
2689 		    mp, mac_mount_label(mp), NULL, NULL, vp, mac_vnode_label(vp));
2690 		VFS_KERNEL_DEBUG_END1(91, vp);
2691 		return 0;
2692 	}
2693 
2694 	p = vfs_context_proc(ctx);
2695 	error = fp_lookup(p, fnp->fd_fd, &fp, 0);
2696 	if (error) {
2697 		VFS_KERNEL_DEBUG_END1(91, vp);
2698 		return error;
2699 	}
2700 
2701 	if (fp->fp_glob == NULL) {
2702 		error = EBADF;
2703 		goto out;
2704 	}
2705 
2706 	switch (FILEGLOB_DTYPE(fp->fp_glob)) {
2707 	case DTYPE_VNODE:
2708 		fvp = (struct vnode *)fp_get_data(fp);
2709 		if ((error = vnode_getwithref(fvp))) {
2710 			goto out;
2711 		}
2712 		if (mac_vnode_label(fvp) != NULL) {
2713 			if (mac_label_vnodes != 0 && mac_vnode_label(vp) == NULL) {
2714 				mac_vnode_label_init(vp); /* init dst label */
2715 			}
2716 			MAC_PERFORM(vnode_label_copy, mac_vnode_label(fvp), mac_vnode_label(vp));
2717 		}
2718 		(void)vnode_put(fvp);
2719 		break;
2720 #if CONFIG_MACF_SOCKET_SUBSET
2721 	case DTYPE_SOCKET:
2722 		so = (struct socket *)fp_get_data(fp);
2723 		socket_lock(so, 1);
2724 		MAC_PERFORM(vnode_label_associate_socket,
2725 		    vfs_context_ucred(ctx), (socket_t)so, NULL,
2726 		    vp, mac_vnode_label(vp));
2727 		socket_unlock(so, 1);
2728 		break;
2729 #endif
2730 	case DTYPE_PSXSHM:
2731 		pshm_label_associate(fp, vp, ctx);
2732 		break;
2733 	case DTYPE_PSXSEM:
2734 		psem_label_associate(fp, vp, ctx);
2735 		break;
2736 	case DTYPE_PIPE:
2737 		cpipe = (struct pipe *)fp_get_data(fp);
2738 		/* kern/sys_pipe.c:pipe_select() suggests this test. */
2739 		if (cpipe == (struct pipe *)-1) {
2740 			error = EINVAL;
2741 			goto out;
2742 		}
2743 		PIPE_LOCK(cpipe);
2744 		MAC_PERFORM(vnode_label_associate_pipe, vfs_context_ucred(ctx),
2745 		    cpipe, mac_pipe_label(cpipe), vp, mac_vnode_label(vp));
2746 		PIPE_UNLOCK(cpipe);
2747 		break;
2748 	case DTYPE_KQUEUE:
2749 	case DTYPE_FSEVENTS:
2750 	case DTYPE_ATALK:
2751 	case DTYPE_NETPOLICY:
2752 	case DTYPE_CHANNEL:
2753 	case DTYPE_NEXUS:
2754 	default:
2755 		MAC_PERFORM(vnode_label_associate_file, vfs_context_ucred(ctx),
2756 		    mp, mac_mount_label(mp), fp->fp_glob, NULL,
2757 		    vp, mac_vnode_label(vp));
2758 		break;
2759 	}
2760 out:
2761 	VFS_KERNEL_DEBUG_END1(91, vp);
2762 	fp_drop(p, fnp->fd_fd, fp, 0);
2763 	return error;
2764 }
2765 
2766 intptr_t
mac_vnode_label_get(struct vnode * vp,int slot,intptr_t sentinel)2767 mac_vnode_label_get(struct vnode *vp, int slot, intptr_t sentinel)
2768 {
2769 	struct label *l;
2770 
2771 	KASSERT(vp != NULL, ("mac_vnode_label_get: NULL vnode"));
2772 	l = mac_vnode_label(vp);
2773 	if (l != NULL) {
2774 		return mac_label_get(l, slot);
2775 	} else {
2776 		return sentinel;
2777 	}
2778 }
2779 
2780 void
mac_vnode_label_set(struct vnode * vp,int slot,intptr_t v)2781 mac_vnode_label_set(struct vnode *vp, int slot, intptr_t v)
2782 {
2783 	struct label *l;
2784 	KASSERT(vp != NULL, ("mac_vnode_label_set: NULL vnode"));
2785 	l = mac_vnode_label(vp);
2786 	if (l == NULL) {
2787 		mac_vnode_label_init(vp);
2788 		l = mac_vnode_label(vp);
2789 	}
2790 	mac_label_set(l, slot, v);
2791 }
2792 
2793 void
mac_vnode_notify_reclaim(struct vnode * vp)2794 mac_vnode_notify_reclaim(struct vnode *vp)
2795 {
2796 	VFS_KERNEL_DEBUG_START1(94, vp);
2797 	MAC_PERFORM(vnode_notify_reclaim, vp);
2798 	VFS_KERNEL_DEBUG_END1(94, vp);
2799 }
2800 
2801 int
mac_mount_check_quotactl(vfs_context_t ctx,struct mount * mp,int cmd,int id)2802 mac_mount_check_quotactl(vfs_context_t ctx, struct mount *mp, int cmd, int id)
2803 {
2804 	kauth_cred_t cred;
2805 	int error;
2806 
2807 #if SECURITY_MAC_CHECK_ENFORCE
2808 	/* 21167099 - only check if we allow write */
2809 	if (!mac_vnode_enforce) {
2810 		return 0;
2811 	}
2812 #endif
2813 	cred = vfs_context_ucred(ctx);
2814 	if (!mac_cred_check_enforce(cred)) {
2815 		return 0;
2816 	}
2817 	VFS_KERNEL_DEBUG_START1(95, mp);
2818 	MAC_CHECK(mount_check_quotactl, cred, mp, cmd, id);
2819 	VFS_KERNEL_DEBUG_END1(95, mp);
2820 
2821 	return error;
2822 }
2823 
2824 int
mac_vnode_check_getattrlistbulk(vfs_context_t ctx,struct vnode * vp,struct attrlist * alist,uint64_t options)2825 mac_vnode_check_getattrlistbulk(vfs_context_t ctx, struct vnode *vp, struct attrlist *alist, uint64_t options)
2826 {
2827 	kauth_cred_t cred;
2828 	int error;
2829 
2830 #if SECURITY_MAC_CHECK_ENFORCE
2831 	/* 21167099 - only check if we allow write */
2832 	if (!mac_vnode_enforce) {
2833 		return 0;
2834 	}
2835 #endif
2836 	cred = vfs_context_ucred(ctx);
2837 	if (!mac_cred_check_enforce(cred)) {
2838 		return 0;
2839 	}
2840 	VFS_KERNEL_DEBUG_START1(96, mp);
2841 	MAC_CHECK(vnode_check_getattrlistbulk, cred, vp, alist, options);
2842 	VFS_KERNEL_DEBUG_END1(96, mp);
2843 
2844 	return error;
2845 }
2846 
2847 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)2848 mac_vnode_check_copyfile(vfs_context_t ctx, struct vnode *dvp,
2849     struct vnode *tvp, struct vnode *fvp, struct componentname *cnp,
2850     mode_t mode, int flags)
2851 {
2852 	kauth_cred_t cred;
2853 	int error;
2854 
2855 #if SECURITY_MAC_CHECK_ENFORCE
2856 	/* 21167099 - only check if we allow write */
2857 	if (!mac_vnode_enforce) {
2858 		return 0;
2859 	}
2860 #endif
2861 	cred = vfs_context_ucred(ctx);
2862 	if (!mac_cred_check_enforce(cred)) {
2863 		return 0;
2864 	}
2865 	VFS_KERNEL_DEBUG_START1(97, dvp);
2866 	MAC_CHECK(vnode_check_copyfile, cred, dvp, mac_vnode_label(dvp),
2867 	    tvp, tvp ? mac_vnode_label(tvp) : NULL, fvp, mac_vnode_label(fvp), cnp, mode, flags);
2868 	VFS_KERNEL_DEBUG_END1(97, dvp);
2869 	return error;
2870 }
2871 
2872 void
mac_vnode_notify_unlink(vfs_context_t ctx,struct vnode * dvp,struct vnode * vp,struct componentname * cnp)2873 mac_vnode_notify_unlink(vfs_context_t ctx, struct vnode *dvp, struct vnode *vp,
2874     struct componentname *cnp)
2875 {
2876 	kauth_cred_t cred;
2877 
2878 #if SECURITY_MAC_CHECK_ENFORCE
2879 	/* 21167099 - only check if we allow write */
2880 	if (!mac_vnode_enforce) {
2881 		return;
2882 	}
2883 #endif
2884 	cred = vfs_context_ucred(ctx);
2885 	if (!mac_cred_check_enforce(cred)) {
2886 		return;
2887 	}
2888 	VFS_KERNEL_DEBUG_START1(98, vp);
2889 	MAC_PERFORM(vnode_notify_unlink, cred, dvp, mac_vnode_label(dvp), vp,
2890 	    mac_vnode_label(vp), cnp);
2891 	VFS_KERNEL_DEBUG_END1(98, vp);
2892 }
2893