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