2 * Copyright (c) 2007 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
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.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
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.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
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.
34 * This software was developed by Robert Watson and Ilmar Habibulin for the
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.
42 * Redistribution and use in source and binary forms, with or without
43 * modification, are permitted provided that the following conditions
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.
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
65 #include <sys/param.h>
66 #include <sys/systm.h>
67 #include <sys/kernel.h>
69 #include <sys/kauth.h>
71 #include <sys/file_internal.h>
72 #include <sys/imgact.h>
73 #include <sys/namei.h>
74 #include <sys/mount_internal.h>
76 #include <sys/posix_sem.h>
77 #include <sys/posix_shm.h>
78 #include <sys/uio_internal.h>
79 #include <sys/vnode_internal.h>
81 #include <miscfs/devfs/devfsdefs.h>
82 #include <miscfs/devfs/fdesc.h>
84 #include <security/mac_internal.h>
86 /* convert {R,W,X}_OK values to V{READ,WRITE,EXEC} */
87 #define ACCESS_MODE_TO_VNODE_MASK(m) (m << 6)
90 mac_devfsdirent_label_alloc(void)
94 label
= mac_labelzone_alloc(MAC_WAITOK
);
97 MAC_PERFORM(devfs_label_init
, label
);
102 mac_devfs_label_init(struct devnode
*de
)
105 de
->dn_label
= mac_devfsdirent_label_alloc();
108 static struct label
*
109 mac_mount_label_alloc(void)
113 label
= mac_labelzone_alloc(MAC_WAITOK
);
116 MAC_PERFORM(mount_label_init
, label
);
121 mac_mount_label_init(struct mount
*mp
)
124 mp
->mnt_mntlabel
= mac_mount_label_alloc();
128 mac_vnode_label_alloc(void)
132 label
= mac_labelzone_alloc(MAC_WAITOK
);
135 MAC_PERFORM(vnode_label_init
, label
);
140 mac_vnode_label_init(vnode_t vp
)
142 vp
->v_label
= mac_vnode_label_alloc();
146 mac_vnode_label_init_needed(vnode_t vp
)
148 return (mac_label_vnodes
!= 0 && vp
->v_label
== NULL
);
152 * vnode labels are allocated at the same time as vnodes, but vnodes are never
153 * freed. Instead, we want to remove any sensitive information before putting
154 * them on the free list for reuse.
157 mac_vnode_label_recycle(vnode_t vp
)
160 MAC_PERFORM(vnode_label_recycle
, vp
->v_label
);
164 mac_devfs_label_free(struct label
*label
)
166 MAC_PERFORM(devfs_label_destroy
, label
);
167 mac_labelzone_free(label
);
171 mac_devfs_label_destroy(struct devnode
*de
)
173 if (de
->dn_label
!= NULL
) {
174 mac_devfs_label_free(de
->dn_label
);
180 mac_mount_label_free(struct label
*label
)
183 MAC_PERFORM(mount_label_destroy
, label
);
184 mac_labelzone_free(label
);
188 mac_mount_label_destroy(struct mount
*mp
)
190 if (mp
->mnt_mntlabel
!= NULL
) {
191 mac_mount_label_free(mp
->mnt_mntlabel
);
192 mp
->mnt_mntlabel
= NULL
;
197 mac_vnode_label_free(struct label
*label
)
199 MAC_PERFORM(vnode_label_destroy
, label
);
200 mac_labelzone_free(label
);
205 mac_vnode_label_destroy(struct vnode
*vp
)
207 if (vp
->v_label
!= NULL
) {
208 mac_vnode_label_free(vp
->v_label
);
215 mac_vnode_label_copy(struct label
*src
, struct label
*dest
)
218 MAC_PERFORM(vnode_label_init
, dest
);
220 MAC_PERFORM(vnode_label_copy
, src
, dest
);
225 mac_vnode_label_externalize_audit(struct vnode
*vp
, struct mac
*mac
)
229 /* It is assumed that any necessary vnode locking is done on entry */
230 error
= MAC_EXTERNALIZE_AUDIT(vnode
, vp
->v_label
,
231 mac
->m_string
, mac
->m_buflen
);
237 mac_vnode_label_externalize(struct label
*label
, char *elements
,
238 char *outbuf
, size_t outbuflen
, int flags __unused
)
242 error
= MAC_EXTERNALIZE(vnode
, label
, elements
, outbuf
, outbuflen
);
248 mac_vnode_label_internalize(struct label
*label
, char *string
)
252 error
= MAC_INTERNALIZE(vnode
, label
, string
);
258 mac_mount_label_internalize(struct label
*label
, char *string
)
262 error
= MAC_INTERNALIZE(mount
, label
, string
);
268 mac_mount_label_externalize(struct label
*label
, char *elements
,
269 char *outbuf
, size_t outbuflen
)
273 error
= MAC_EXTERNALIZE(mount
, label
, elements
, outbuf
, outbuflen
);
279 mac_devfs_label_copy(struct label
*src
, struct label
*dest
)
281 #if SECURITY_MAC_CHECK_ENFORCE
282 /* 21167099 - only check if we allow write */
283 if (!mac_device_enforce
)
287 MAC_PERFORM(devfs_label_copy
, src
, dest
);
291 mac_devfs_label_update(struct mount
*mp
, struct devnode
*de
,
294 #if SECURITY_MAC_CHECK_ENFORCE
295 /* 21167099 - only check if we allow write */
296 if (!mac_device_enforce
)
300 MAC_PERFORM(devfs_label_update
, mp
, de
, de
->dn_label
, vp
,
305 mac_vnode_label_associate(struct mount
*mp
, struct vnode
*vp
, vfs_context_t ctx
)
308 struct fdescnode
*fnp
;
311 #if SECURITY_MAC_CHECK_ENFORCE
312 /* 21167099 - only check if we allow write */
313 if (!mac_vnode_enforce
)
317 /* XXX: should not inspect v_tag in kernel! */
321 mac_vnode_label_associate_devfs(mp
, dnp
, vp
);
325 error
= mac_vnode_label_associate_fdesc(mp
, fnp
, vp
, ctx
);
328 error
= mac_vnode_label_associate_extattr(mp
, vp
);
336 mac_vnode_label_associate_devfs(struct mount
*mp
, struct devnode
*de
,
339 #if SECURITY_MAC_CHECK_ENFORCE
340 /* 21167099 - only check if we allow write */
341 if (!mac_device_enforce
)
345 MAC_PERFORM(vnode_label_associate_devfs
,
346 mp
, mp
? mp
->mnt_mntlabel
: NULL
,
352 mac_vnode_label_associate_extattr(struct mount
*mp
, struct vnode
*vp
)
356 MAC_CHECK(vnode_label_associate_extattr
, mp
, mp
->mnt_mntlabel
, vp
,
363 mac_vnode_label_associate_singlelabel(struct mount
*mp
, struct vnode
*vp
)
365 #if SECURITY_MAC_CHECK_ENFORCE
366 /* 21167099 - only check if we allow write */
367 if (!mac_vnode_enforce
)
370 if (!mac_label_vnodes
)
373 MAC_PERFORM(vnode_label_associate_singlelabel
, mp
,
374 mp
? mp
->mnt_mntlabel
: NULL
, vp
, vp
->v_label
);
378 mac_vnode_notify_create(vfs_context_t ctx
, struct mount
*mp
,
379 struct vnode
*dvp
, struct vnode
*vp
, struct componentname
*cnp
)
384 #if SECURITY_MAC_CHECK_ENFORCE
385 /* 21167099 - only check if we allow write */
386 if (!mac_vnode_enforce
)
389 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
392 cred
= vfs_context_ucred(ctx
);
393 MAC_CHECK(vnode_notify_create
, cred
, mp
, mp
->mnt_mntlabel
,
394 dvp
, dvp
->v_label
, vp
, vp
->v_label
, cnp
);
400 mac_vnode_notify_rename(vfs_context_t ctx
, struct vnode
*vp
,
401 struct vnode
*dvp
, struct componentname
*cnp
)
405 #if SECURITY_MAC_CHECK_ENFORCE
406 /* 21167099 - only check if we allow write */
407 if (!mac_vnode_enforce
)
410 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
413 cred
= vfs_context_ucred(ctx
);
414 MAC_PERFORM(vnode_notify_rename
, cred
, vp
, vp
->v_label
,
415 dvp
, dvp
->v_label
, cnp
);
419 mac_vnode_notify_open(vfs_context_t ctx
, struct vnode
*vp
, int acc_flags
)
423 #if SECURITY_MAC_CHECK_ENFORCE
424 /* 21167099 - only check if we allow write */
425 if (!mac_vnode_enforce
)
428 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
431 cred
= vfs_context_ucred(ctx
);
432 MAC_PERFORM(vnode_notify_open
, cred
, vp
, vp
->v_label
, acc_flags
);
436 mac_vnode_notify_link(vfs_context_t ctx
, struct vnode
*vp
,
437 struct vnode
*dvp
, struct componentname
*cnp
)
441 #if SECURITY_MAC_CHECK_ENFORCE
442 /* 21167099 - only check if we allow write */
443 if (!mac_vnode_enforce
)
446 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
449 cred
= vfs_context_ucred(ctx
);
450 MAC_PERFORM(vnode_notify_link
, cred
, dvp
, dvp
->v_label
, vp
, vp
->v_label
, cnp
);
454 * Extended attribute 'name' was updated via
455 * vn_setxattr() or vn_removexattr(). Allow the
456 * policy to update the vnode label.
459 mac_vnode_label_update_extattr(struct mount
*mp
, struct vnode
*vp
,
464 #if SECURITY_MAC_CHECK_ENFORCE
465 /* 21167099 - only check if we allow write */
466 if (!mac_vnode_enforce
)
469 if (!mac_label_vnodes
)
472 MAC_PERFORM(vnode_label_update_extattr
, mp
, mp
->mnt_mntlabel
, vp
,
484 mac_vnode_label_store(vfs_context_t ctx
, struct vnode
*vp
,
485 struct label
*intlabel
)
490 #if SECURITY_MAC_CHECK_ENFORCE
491 /* 21167099 - only check if we allow write */
492 if (!mac_vnode_enforce
)
495 if (!mac_label_vnodes
||
496 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
499 cred
= vfs_context_ucred(ctx
);
500 MAC_CHECK(vnode_label_store
, cred
, vp
, vp
->v_label
, intlabel
);
506 mac_cred_label_update_execve(vfs_context_t ctx
, kauth_cred_t
new, struct vnode
*vp
, off_t offset
,
507 struct vnode
*scriptvp
, struct label
*scriptvnodelabel
, struct label
*execl
, u_int
*csflags
,
508 void *macextensions
, int *disjoint
, int *labelupdateerror
)
513 posix_cred_t pcred
= posix_cred_get(new);
515 #if SECURITY_MAC_CHECK_ENFORCE
516 /* 21167099 - only check if we allow write */
517 if (!mac_proc_enforce
|| !mac_vnode_enforce
)
521 /* mark the new cred to indicate "matching" includes the label */
522 pcred
->cr_flags
|= CRF_MAC_ENFORCE
;
524 cred
= vfs_context_ucred(ctx
);
527 * NB: Cannot use MAC_CHECK macro because we need a sequence point after
528 * calling exec_spawnattr_getmacpolicyinfo() and before passing the
529 * spawnattrlen as an argument to the hook.
532 struct mac_policy_conf
*mpc
;
536 for (i
= 0; i
< mac_policy_list
.staticmax
; i
++) {
537 mpc
= mac_policy_list
.entries
[i
].mpc
;
541 mpo_cred_label_update_execve_t
*hook
= mpc
->mpc_ops
->mpo_cred_label_update_execve
;
545 size_t spawnattrlen
= 0;
546 void *spawnattr
= exec_spawnattr_getmacpolicyinfo(macextensions
, mpc
->mpc_name
, &spawnattrlen
);
548 error
= mac_error_select(hook(cred
, new, vfs_context_proc(ctx
), vp
, offset
, scriptvp
,
549 vp
->v_label
, scriptvnodelabel
, execl
, csflags
, spawnattr
, spawnattrlen
, disjoint
),
552 if (mac_policy_list_conditional_busy() != 0) {
553 for (; i
<= mac_policy_list
.maxindex
; i
++) {
554 mpc
= mac_policy_list
.entries
[i
].mpc
;
558 mpo_cred_label_update_execve_t
*hook
= mpc
->mpc_ops
->mpo_cred_label_update_execve
;
562 size_t spawnattrlen
= 0;
563 void *spawnattr
= exec_spawnattr_getmacpolicyinfo(macextensions
, mpc
->mpc_name
, &spawnattrlen
);
565 error
= mac_error_select(hook(cred
, new, vfs_context_proc(ctx
), vp
, offset
, scriptvp
,
566 vp
->v_label
, scriptvnodelabel
, execl
, csflags
, spawnattr
, spawnattrlen
, disjoint
),
569 mac_policy_list_unbusy();
572 *labelupdateerror
= error
;
576 mac_cred_check_label_update_execve(vfs_context_t ctx
, struct vnode
*vp
, off_t offset
,
577 struct vnode
*scriptvp
, struct label
*scriptvnodelabel
, struct label
*execlabel
,
578 struct proc
*p
, void *macextensions
)
583 #if SECURITY_MAC_CHECK_ENFORCE
584 /* 21167099 - only check if we allow write */
585 if (!mac_proc_enforce
|| !mac_vnode_enforce
)
589 cred
= vfs_context_ucred(ctx
);
592 * NB: Cannot use MAC_BOOLEAN macro because we need a sequence point after
593 * calling exec_spawnattr_getmacpolicyinfo() and before passing the
594 * spawnattrlen as an argument to the hook.
597 struct mac_policy_conf
*mpc
;
600 for (i
= 0; i
< mac_policy_list
.staticmax
; i
++) {
601 mpc
= mac_policy_list
.entries
[i
].mpc
;
605 mpo_cred_check_label_update_execve_t
*hook
= mpc
->mpc_ops
->mpo_cred_check_label_update_execve
;
609 size_t spawnattrlen
= 0;
610 void *spawnattr
= exec_spawnattr_getmacpolicyinfo(macextensions
, mpc
->mpc_name
, &spawnattrlen
);
612 result
= result
|| hook(cred
, vp
, offset
, scriptvp
, vp
->v_label
, scriptvnodelabel
, execlabel
, p
, spawnattr
, spawnattrlen
);
614 if (mac_policy_list_conditional_busy() != 0) {
615 for (; i
<= mac_policy_list
.maxindex
; i
++) {
616 mpc
= mac_policy_list
.entries
[i
].mpc
;
620 mpo_cred_check_label_update_execve_t
*hook
= mpc
->mpc_ops
->mpo_cred_check_label_update_execve
;
624 size_t spawnattrlen
= 0;
625 void *spawnattr
= exec_spawnattr_getmacpolicyinfo(macextensions
, mpc
->mpc_name
, &spawnattrlen
);
627 result
= result
|| hook(cred
, vp
, offset
, scriptvp
, vp
->v_label
, scriptvnodelabel
, execlabel
, p
, spawnattr
, spawnattrlen
);
629 mac_policy_list_unbusy();
637 mac_vnode_check_access(vfs_context_t ctx
, struct vnode
*vp
,
644 #if SECURITY_MAC_CHECK_ENFORCE
645 /* 21167099 - only check if we allow write */
646 if (!mac_vnode_enforce
)
649 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
652 cred
= vfs_context_ucred(ctx
);
653 /* Convert {R,W,X}_OK values to V{READ,WRITE,EXEC} for entry points */
654 mask
= ACCESS_MODE_TO_VNODE_MASK(acc_mode
);
655 MAC_CHECK(vnode_check_access
, cred
, vp
, vp
->v_label
, mask
);
660 mac_vnode_check_chdir(vfs_context_t ctx
, struct vnode
*dvp
)
665 #if SECURITY_MAC_CHECK_ENFORCE
666 /* 21167099 - only check if we allow write */
667 if (!mac_vnode_enforce
)
670 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
673 cred
= vfs_context_ucred(ctx
);
674 MAC_CHECK(vnode_check_chdir
, cred
, dvp
, dvp
->v_label
);
679 mac_vnode_check_chroot(vfs_context_t ctx
, struct vnode
*dvp
,
680 struct componentname
*cnp
)
685 #if SECURITY_MAC_CHECK_ENFORCE
686 /* 21167099 - only check if we allow write */
687 if (!mac_vnode_enforce
)
690 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
693 cred
= vfs_context_ucred(ctx
);
694 MAC_CHECK(vnode_check_chroot
, cred
, dvp
, dvp
->v_label
, cnp
);
699 mac_vnode_check_create(vfs_context_t ctx
, struct vnode
*dvp
,
700 struct componentname
*cnp
, struct vnode_attr
*vap
)
705 #if SECURITY_MAC_CHECK_ENFORCE
706 /* 21167099 - only check if we allow write */
707 if (!mac_vnode_enforce
)
710 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
713 cred
= vfs_context_ucred(ctx
);
714 MAC_CHECK(vnode_check_create
, cred
, dvp
, dvp
->v_label
, cnp
, vap
);
719 mac_vnode_check_unlink(vfs_context_t ctx
, struct vnode
*dvp
, struct vnode
*vp
,
720 struct componentname
*cnp
)
725 #if SECURITY_MAC_CHECK_ENFORCE
726 /* 21167099 - only check if we allow write */
727 if (!mac_vnode_enforce
)
730 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
733 cred
= vfs_context_ucred(ctx
);
734 MAC_CHECK(vnode_check_unlink
, cred
, dvp
, dvp
->v_label
, vp
,
740 mac_vnode_check_deleteacl(vfs_context_t ctx
, struct vnode
*vp
,
746 #if SECURITY_MAC_CHECK_ENFORCE
747 /* 21167099 - only check if we allow write */
748 if (!mac_vnode_enforce
)
751 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
754 cred
= vfs_context_ucred(ctx
);
755 MAC_CHECK(vnode_check_deleteacl
, cred
, vp
, vp
->v_label
, type
);
761 mac_vnode_check_deleteextattr(vfs_context_t ctx
, struct vnode
*vp
,
767 #if SECURITY_MAC_CHECK_ENFORCE
768 /* 21167099 - only check if we allow write */
769 if (!mac_vnode_enforce
)
772 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
775 cred
= vfs_context_ucred(ctx
);
776 MAC_CHECK(vnode_check_deleteextattr
, cred
, vp
, vp
->v_label
, name
);
780 mac_vnode_check_exchangedata(vfs_context_t ctx
,
781 struct vnode
*v1
, struct vnode
*v2
)
786 #if SECURITY_MAC_CHECK_ENFORCE
787 /* 21167099 - only check if we allow write */
788 if (!mac_vnode_enforce
)
791 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
794 cred
= vfs_context_ucred(ctx
);
795 MAC_CHECK(vnode_check_exchangedata
, cred
, v1
, v1
->v_label
,
803 mac_vnode_check_getacl(vfs_context_t ctx
, struct vnode
*vp
, acl_type_t type
)
808 #if SECURITY_MAC_CHECK_ENFORCE
809 /* 21167099 - only check if we allow write */
810 if (!mac_vnode_enforce
)
813 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
816 cred
= vfs_context_ucred(ctx
);
817 MAC_CHECK(vnode_check_getacl
, cred
, vp
, vp
->v_label
, type
);
823 mac_vnode_check_getattrlist(vfs_context_t ctx
, struct vnode
*vp
,
824 struct attrlist
*alist
)
829 #if SECURITY_MAC_CHECK_ENFORCE
830 /* 21167099 - only check if we allow write */
831 if (!mac_vnode_enforce
)
834 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
837 cred
= vfs_context_ucred(ctx
);
838 MAC_CHECK(vnode_check_getattrlist
, cred
, vp
, vp
->v_label
, alist
);
840 /* Falsify results instead of returning error? */
845 mac_vnode_check_exec(vfs_context_t ctx
, struct vnode
*vp
,
846 struct image_params
*imgp
)
851 #if SECURITY_MAC_CHECK_ENFORCE
852 /* 21167099 - only check if we allow write */
853 if (!mac_proc_enforce
|| !mac_vnode_enforce
)
857 cred
= vfs_context_ucred(ctx
);
860 * NB: Cannot use MAC_CHECK macro because we need a sequence point after
861 * calling exec_spawnattr_getmacpolicyinfo() and before passing the
862 * spawnattrlen as an argument to the hook.
865 struct mac_policy_conf
*mpc
;
868 for (i
= 0; i
< mac_policy_list
.staticmax
; i
++) {
869 mpc
= mac_policy_list
.entries
[i
].mpc
;
873 mpo_vnode_check_exec_t
*hook
= mpc
->mpc_ops
->mpo_vnode_check_exec
;
877 size_t spawnattrlen
= 0;
878 void *spawnattr
= exec_spawnattr_getmacpolicyinfo(imgp
->ip_px_smpx
, mpc
->mpc_name
, &spawnattrlen
);
880 error
= mac_error_select(
882 vp
, imgp
->ip_scriptvp
, vp
->v_label
, imgp
->ip_scriptlabelp
,
883 imgp
->ip_execlabelp
, &imgp
->ip_ndp
->ni_cnd
, &imgp
->ip_csflags
,
884 spawnattr
, spawnattrlen
), error
);
886 if (mac_policy_list_conditional_busy() != 0) {
887 for (; i
<= mac_policy_list
.maxindex
; i
++) {
888 mpc
= mac_policy_list
.entries
[i
].mpc
;
892 mpo_vnode_check_exec_t
*hook
= mpc
->mpc_ops
->mpo_vnode_check_exec
;
896 size_t spawnattrlen
= 0;
897 void *spawnattr
= exec_spawnattr_getmacpolicyinfo(imgp
->ip_px_smpx
, mpc
->mpc_name
, &spawnattrlen
);
899 error
= mac_error_select(
901 vp
, imgp
->ip_scriptvp
, vp
->v_label
, imgp
->ip_scriptlabelp
,
902 imgp
->ip_execlabelp
, &imgp
->ip_ndp
->ni_cnd
, &imgp
->ip_csflags
,
903 spawnattr
, spawnattrlen
), error
);
905 mac_policy_list_unbusy();
913 mac_vnode_check_fsgetpath(vfs_context_t ctx
, struct vnode
*vp
)
918 #if SECURITY_MAC_CHECK_ENFORCE
919 /* 21167099 - only check if we allow write */
920 if (!mac_vnode_enforce
)
923 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
926 cred
= vfs_context_ucred(ctx
);
927 MAC_CHECK(vnode_check_fsgetpath
, cred
, vp
, vp
->v_label
);
932 mac_vnode_check_signature(struct vnode
*vp
, off_t macho_offset
,
934 const void *signature
, size_t size
,
935 int flags
, int *is_platform_binary
)
939 #if SECURITY_MAC_CHECK_ENFORCE
940 /* 21167099 - only check if we allow write */
941 if (!mac_proc_enforce
|| !mac_vnode_enforce
)
945 MAC_CHECK(vnode_check_signature
, vp
, vp
->v_label
, macho_offset
, sha1
,
947 flags
, is_platform_binary
);
953 mac_vnode_check_getacl(vfs_context_t ctx
, struct vnode
*vp
, acl_type_t type
)
958 #if SECURITY_MAC_CHECK_ENFORCE
959 /* 21167099 - only check if we allow write */
960 if (!mac_vnode_enforce
)
963 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
966 cred
= vfs_context_ucred(ctx
);
967 MAC_CHECK(vnode_check_getacl
, cred
, vp
, vp
->v_label
, type
);
973 mac_vnode_check_getextattr(vfs_context_t ctx
, struct vnode
*vp
,
974 const char *name
, struct uio
*uio
)
979 #if SECURITY_MAC_CHECK_ENFORCE
980 /* 21167099 - only check if we allow write */
981 if (!mac_vnode_enforce
)
984 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
987 cred
= vfs_context_ucred(ctx
);
988 MAC_CHECK(vnode_check_getextattr
, cred
, vp
, vp
->v_label
,
994 mac_vnode_check_ioctl(vfs_context_t ctx
, struct vnode
*vp
, u_int cmd
)
999 #if SECURITY_MAC_CHECK_ENFORCE
1000 /* 21167099 - only check if we allow write */
1001 if (!mac_vnode_enforce
)
1004 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1007 cred
= vfs_context_ucred(ctx
);
1008 MAC_CHECK(vnode_check_ioctl
, cred
, vp
, vp
->v_label
, cmd
);
1013 mac_vnode_check_kqfilter(vfs_context_t ctx
, kauth_cred_t file_cred
,
1014 struct knote
*kn
, struct vnode
*vp
)
1019 #if SECURITY_MAC_CHECK_ENFORCE
1020 /* 21167099 - only check if we allow write */
1021 if (!mac_vnode_enforce
)
1024 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1027 cred
= vfs_context_ucred(ctx
);
1028 MAC_CHECK(vnode_check_kqfilter
, cred
, file_cred
, kn
, vp
,
1035 mac_vnode_check_link(vfs_context_t ctx
, struct vnode
*dvp
,
1036 struct vnode
*vp
, struct componentname
*cnp
)
1041 #if SECURITY_MAC_CHECK_ENFORCE
1042 /* 21167099 - only check if we allow write */
1043 if (!mac_vnode_enforce
)
1046 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1049 cred
= vfs_context_ucred(ctx
);
1050 MAC_CHECK(vnode_check_link
, cred
, dvp
, dvp
->v_label
, vp
,
1056 mac_vnode_check_listextattr(vfs_context_t ctx
, struct vnode
*vp
)
1061 #if SECURITY_MAC_CHECK_ENFORCE
1062 /* 21167099 - only check if we allow write */
1063 if (!mac_vnode_enforce
)
1066 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1069 cred
= vfs_context_ucred(ctx
);
1070 MAC_CHECK(vnode_check_listextattr
, cred
, vp
, vp
->v_label
);
1075 mac_vnode_check_lookup(vfs_context_t ctx
, struct vnode
*dvp
,
1076 struct componentname
*cnp
)
1081 #if SECURITY_MAC_CHECK_ENFORCE
1082 /* 21167099 - only check if we allow write */
1083 if (!mac_vnode_enforce
)
1086 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1089 cred
= vfs_context_ucred(ctx
);
1090 MAC_CHECK(vnode_check_lookup
, cred
, dvp
, dvp
->v_label
, cnp
);
1095 mac_vnode_check_open(vfs_context_t ctx
, struct vnode
*vp
, int acc_mode
)
1100 #if SECURITY_MAC_CHECK_ENFORCE
1101 /* 21167099 - only check if we allow write */
1102 if (!mac_vnode_enforce
)
1105 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1108 cred
= vfs_context_ucred(ctx
);
1109 MAC_CHECK(vnode_check_open
, cred
, vp
, vp
->v_label
, acc_mode
);
1114 mac_vnode_check_read(vfs_context_t ctx
, struct ucred
*file_cred
,
1120 #if SECURITY_MAC_CHECK_ENFORCE
1121 /* 21167099 - only check if we allow write */
1122 if (!mac_vnode_enforce
)
1125 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1128 cred
= vfs_context_ucred(ctx
);
1129 MAC_CHECK(vnode_check_read
, cred
, file_cred
, vp
,
1136 mac_vnode_check_readdir(vfs_context_t ctx
, struct vnode
*dvp
)
1141 #if SECURITY_MAC_CHECK_ENFORCE
1142 /* 21167099 - only check if we allow write */
1143 if (!mac_vnode_enforce
)
1146 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1149 cred
= vfs_context_ucred(ctx
);
1150 MAC_CHECK(vnode_check_readdir
, cred
, dvp
, dvp
->v_label
);
1155 mac_vnode_check_readlink(vfs_context_t ctx
, struct vnode
*vp
)
1160 #if SECURITY_MAC_CHECK_ENFORCE
1161 /* 21167099 - only check if we allow write */
1162 if (!mac_vnode_enforce
)
1165 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1168 cred
= vfs_context_ucred(ctx
);
1169 MAC_CHECK(vnode_check_readlink
, cred
, vp
, vp
->v_label
);
1174 mac_vnode_check_label_update(vfs_context_t ctx
, struct vnode
*vp
,
1175 struct label
*newlabel
)
1180 #if SECURITY_MAC_CHECK_ENFORCE
1181 /* 21167099 - only check if we allow write */
1182 if (!mac_vnode_enforce
)
1185 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1188 cred
= vfs_context_ucred(ctx
);
1189 MAC_CHECK(vnode_check_label_update
, cred
, vp
, vp
->v_label
, newlabel
);
1195 mac_vnode_check_rename(vfs_context_t ctx
, struct vnode
*dvp
,
1196 struct vnode
*vp
, struct componentname
*cnp
, struct vnode
*tdvp
,
1197 struct vnode
*tvp
, struct componentname
*tcnp
)
1202 #if SECURITY_MAC_CHECK_ENFORCE
1203 /* 21167099 - only check if we allow write */
1204 if (!mac_vnode_enforce
)
1207 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1210 cred
= vfs_context_ucred(ctx
);
1212 MAC_CHECK(vnode_check_rename_from
, cred
, dvp
, dvp
->v_label
, vp
,
1217 MAC_CHECK(vnode_check_rename_to
, cred
, tdvp
, tdvp
->v_label
, tvp
,
1218 tvp
!= NULL
? tvp
->v_label
: NULL
, dvp
== tdvp
, tcnp
);
1222 MAC_CHECK(vnode_check_rename
, cred
, dvp
, dvp
->v_label
, vp
,
1223 vp
->v_label
, cnp
, tdvp
, tdvp
->v_label
, tvp
,
1224 tvp
!= NULL
? tvp
->v_label
: NULL
, tcnp
);
1229 mac_vnode_check_revoke(vfs_context_t ctx
, struct vnode
*vp
)
1234 #if SECURITY_MAC_CHECK_ENFORCE
1235 /* 21167099 - only check if we allow write */
1236 if (!mac_vnode_enforce
)
1239 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1242 cred
= vfs_context_ucred(ctx
);
1243 MAC_CHECK(vnode_check_revoke
, cred
, vp
, vp
->v_label
);
1248 mac_vnode_check_searchfs(vfs_context_t ctx
, struct vnode
*vp
, struct attrlist
*alist
)
1253 #if SECURITY_MAC_CHECK_ENFORCE
1254 /* 21167099 - only check if we allow write */
1255 if (!mac_vnode_enforce
)
1258 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1261 cred
= vfs_context_ucred(ctx
);
1262 MAC_CHECK(vnode_check_searchfs
, cred
, vp
, vp
->v_label
, alist
);
1267 mac_vnode_check_select(vfs_context_t ctx
, struct vnode
*vp
, int which
)
1272 #if SECURITY_MAC_CHECK_ENFORCE
1273 /* 21167099 - only check if we allow write */
1274 if (!mac_vnode_enforce
)
1277 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1280 cred
= vfs_context_ucred(ctx
);
1281 MAC_CHECK(vnode_check_select
, cred
, vp
, vp
->v_label
, which
);
1287 mac_vnode_check_setacl(vfs_context_t ctx
, struct vnode
*vp
, acl_type_t type
,
1293 #if SECURITY_MAC_CHECK_ENFORCE
1294 /* 21167099 - only check if we allow write */
1295 if (!mac_vnode_enforce
)
1298 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1301 cred
= vfs_context_ucred(ctx
);
1302 MAC_CHECK(vnode_check_setacl
, cred
, vp
, vp
->v_label
, type
, acl
);
1308 mac_vnode_check_setattrlist(vfs_context_t ctx
, struct vnode
*vp
,
1309 struct attrlist
*alist
)
1314 #if SECURITY_MAC_CHECK_ENFORCE
1315 /* 21167099 - only check if we allow write */
1316 if (!mac_vnode_enforce
)
1319 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1322 cred
= vfs_context_ucred(ctx
);
1323 MAC_CHECK(vnode_check_setattrlist
, cred
, vp
, vp
->v_label
, alist
);
1328 mac_vnode_check_setextattr(vfs_context_t ctx
, struct vnode
*vp
,
1329 const char *name
, struct uio
*uio
)
1334 #if SECURITY_MAC_CHECK_ENFORCE
1335 /* 21167099 - only check if we allow write */
1336 if (!mac_vnode_enforce
)
1339 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1342 cred
= vfs_context_ucred(ctx
);
1343 MAC_CHECK(vnode_check_setextattr
, cred
, vp
, vp
->v_label
,
1349 mac_vnode_check_setflags(vfs_context_t ctx
, struct vnode
*vp
, u_long flags
)
1354 #if SECURITY_MAC_CHECK_ENFORCE
1355 /* 21167099 - only check if we allow write */
1356 if (!mac_vnode_enforce
)
1359 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1362 cred
= vfs_context_ucred(ctx
);
1363 MAC_CHECK(vnode_check_setflags
, cred
, vp
, vp
->v_label
, flags
);
1368 mac_vnode_check_setmode(vfs_context_t ctx
, struct vnode
*vp
, mode_t mode
)
1373 #if SECURITY_MAC_CHECK_ENFORCE
1374 /* 21167099 - only check if we allow write */
1375 if (!mac_vnode_enforce
)
1378 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1381 cred
= vfs_context_ucred(ctx
);
1382 MAC_CHECK(vnode_check_setmode
, cred
, vp
, vp
->v_label
, mode
);
1387 mac_vnode_check_setowner(vfs_context_t ctx
, struct vnode
*vp
, uid_t uid
,
1393 #if SECURITY_MAC_CHECK_ENFORCE
1394 /* 21167099 - only check if we allow write */
1395 if (!mac_vnode_enforce
)
1398 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1401 cred
= vfs_context_ucred(ctx
);
1402 MAC_CHECK(vnode_check_setowner
, cred
, vp
, vp
->v_label
, uid
, gid
);
1407 mac_vnode_check_setutimes(vfs_context_t ctx
, struct vnode
*vp
,
1408 struct timespec atime
, struct timespec mtime
)
1413 #if SECURITY_MAC_CHECK_ENFORCE
1414 /* 21167099 - only check if we allow write */
1415 if (!mac_vnode_enforce
)
1418 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1421 cred
= vfs_context_ucred(ctx
);
1422 MAC_CHECK(vnode_check_setutimes
, cred
, vp
, vp
->v_label
, atime
,
1428 mac_vnode_check_stat(vfs_context_t ctx
, struct ucred
*file_cred
,
1434 #if SECURITY_MAC_CHECK_ENFORCE
1435 /* 21167099 - only check if we allow write */
1436 if (!mac_vnode_enforce
)
1439 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1442 cred
= vfs_context_ucred(ctx
);
1443 MAC_CHECK(vnode_check_stat
, cred
, file_cred
, vp
,
1449 mac_vnode_check_truncate(vfs_context_t ctx
, struct ucred
*file_cred
,
1455 #if SECURITY_MAC_CHECK_ENFORCE
1456 /* 21167099 - only check if we allow write */
1457 if (!mac_vnode_enforce
)
1460 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1463 cred
= vfs_context_ucred(ctx
);
1464 MAC_CHECK(vnode_check_truncate
, cred
, file_cred
, vp
,
1471 mac_vnode_check_write(vfs_context_t ctx
, struct ucred
*file_cred
,
1477 #if SECURITY_MAC_CHECK_ENFORCE
1478 /* 21167099 - only check if we allow write */
1479 if (!mac_vnode_enforce
)
1482 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1485 cred
= vfs_context_ucred(ctx
);
1486 MAC_CHECK(vnode_check_write
, cred
, file_cred
, vp
, vp
->v_label
);
1492 mac_vnode_check_uipc_bind(vfs_context_t ctx
, struct vnode
*dvp
,
1493 struct componentname
*cnp
, struct vnode_attr
*vap
)
1498 #if SECURITY_MAC_CHECK_ENFORCE
1499 /* 21167099 - only check if we allow write */
1500 if (!mac_vnode_enforce
)
1503 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1506 cred
= vfs_context_ucred(ctx
);
1507 MAC_CHECK(vnode_check_uipc_bind
, cred
, dvp
, dvp
->v_label
, cnp
, vap
);
1512 mac_vnode_check_uipc_connect(vfs_context_t ctx
, struct vnode
*vp
)
1517 #if SECURITY_MAC_CHECK_ENFORCE
1518 /* 21167099 - only check if we allow write */
1519 if (!mac_vnode_enforce
)
1522 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1525 cred
= vfs_context_ucred(ctx
);
1526 MAC_CHECK(vnode_check_uipc_connect
, cred
, vp
, vp
->v_label
);
1531 mac_vnode_label_update(vfs_context_t ctx
, struct vnode
*vp
, struct label
*newlabel
)
1533 kauth_cred_t cred
= vfs_context_ucred(ctx
);
1534 struct label
*tmpl
= NULL
;
1536 if (vp
->v_label
== NULL
)
1537 tmpl
= mac_vnode_label_alloc();
1541 /* recheck after lock */
1542 if (vp
->v_label
== NULL
) {
1547 MAC_PERFORM(vnode_label_update
, cred
, vp
, vp
->v_label
, newlabel
);
1551 mac_vnode_label_free(tmpl
);
1555 mac_vnode_find_sigs(struct proc
*p
, struct vnode
*vp
, off_t offset
)
1559 #if SECURITY_MAC_CHECK_ENFORCE
1560 /* 21167099 - only check if we allow write */
1561 if (!mac_proc_enforce
|| !mac_vnode_enforce
)
1565 MAC_CHECK(vnode_find_sigs
, p
, vp
, offset
, vp
->v_label
);
1571 mac_mount_label_associate(vfs_context_t ctx
, struct mount
*mp
)
1573 kauth_cred_t cred
= vfs_context_ucred(ctx
);
1575 /* XXX: eventually this logic may be handled by the policy? */
1577 /* We desire MULTILABEL for the root filesystem. */
1578 if ((mp
->mnt_flag
& MNT_ROOTFS
) &&
1579 (strcmp(mp
->mnt_vfsstat
.f_fstypename
, "hfs") == 0))
1580 mp
->mnt_flag
|= MNT_MULTILABEL
;
1582 /* MULTILABEL on DEVFS. */
1583 if (strcmp(mp
->mnt_vfsstat
.f_fstypename
, "devfs") == 0)
1584 mp
->mnt_flag
|= MNT_MULTILABEL
;
1586 /* MULTILABEL on FDESC pseudo-filesystem. */
1587 if (strcmp(mp
->mnt_vfsstat
.f_fstypename
, "fdesc") == 0)
1588 mp
->mnt_flag
|= MNT_MULTILABEL
;
1590 /* MULTILABEL on all NFS filesystems. */
1591 if (strcmp(mp
->mnt_vfsstat
.f_fstypename
, "nfs") == 0)
1592 mp
->mnt_flag
|= MNT_MULTILABEL
;
1594 /* MULTILABEL on all AFP filesystems. */
1595 if (strcmp(mp
->mnt_vfsstat
.f_fstypename
, "afpfs") == 0)
1596 mp
->mnt_flag
|= MNT_MULTILABEL
;
1598 if (mp
->mnt_vtable
!= NULL
) {
1599 /* Any filesystem that supports native XATTRs. */
1600 if ((mp
->mnt_vtable
->vfc_vfsflags
& VFC_VFSNATIVEXATTR
))
1601 mp
->mnt_flag
|= MNT_MULTILABEL
;
1603 /* Filesystem does not support multilabel. */
1604 if ((mp
->mnt_vtable
->vfc_vfsflags
& VFC_VFSNOMACLABEL
) &&
1605 (mp
->mnt_flag
& MNT_MULTILABEL
))
1606 mp
->mnt_flag
&= ~MNT_MULTILABEL
;
1609 MAC_PERFORM(mount_label_associate
, cred
, mp
, mp
->mnt_mntlabel
);
1611 printf("MAC Framework enabling %s support: %s -> %s (%s)\n",
1612 mp
->mnt_flag
& MNT_MULTILABEL
? "multilabel" : "singlelabel",
1613 mp
->mnt_vfsstat
.f_mntfromname
,
1614 mp
->mnt_vfsstat
.f_mntonname
,
1615 mp
->mnt_vfsstat
.f_fstypename
);
1620 mac_mount_check_mount(vfs_context_t ctx
, struct vnode
*vp
,
1621 struct componentname
*cnp
, const char *vfc_name
)
1626 #if SECURITY_MAC_CHECK_ENFORCE
1627 /* 21167099 - only check if we allow write */
1628 if (!mac_vnode_enforce
)
1631 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1634 cred
= vfs_context_ucred(ctx
);
1635 MAC_CHECK(mount_check_mount
, cred
, vp
, vp
->v_label
, cnp
, vfc_name
);
1641 mac_mount_check_remount(vfs_context_t ctx
, struct mount
*mp
)
1646 #if SECURITY_MAC_CHECK_ENFORCE
1647 /* 21167099 - only check if we allow write */
1648 if (!mac_vnode_enforce
)
1651 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1654 cred
= vfs_context_ucred(ctx
);
1655 MAC_CHECK(mount_check_remount
, cred
, mp
, mp
->mnt_mntlabel
);
1661 mac_mount_check_umount(vfs_context_t ctx
, struct mount
*mp
)
1666 #if SECURITY_MAC_CHECK_ENFORCE
1667 /* 21167099 - only check if we allow write */
1668 if (!mac_vnode_enforce
)
1671 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1674 cred
= vfs_context_ucred(ctx
);
1675 MAC_CHECK(mount_check_umount
, cred
, mp
, mp
->mnt_mntlabel
);
1681 mac_mount_check_getattr(vfs_context_t ctx
, struct mount
*mp
,
1682 struct vfs_attr
*vfa
)
1687 #if SECURITY_MAC_CHECK_ENFORCE
1688 /* 21167099 - only check if we allow write */
1689 if (!mac_vnode_enforce
)
1692 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1695 cred
= vfs_context_ucred(ctx
);
1696 MAC_CHECK(mount_check_getattr
, cred
, mp
, mp
->mnt_mntlabel
, vfa
);
1701 mac_mount_check_setattr(vfs_context_t ctx
, struct mount
*mp
,
1702 struct vfs_attr
*vfa
)
1707 #if SECURITY_MAC_CHECK_ENFORCE
1708 /* 21167099 - only check if we allow write */
1709 if (!mac_vnode_enforce
)
1712 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1715 cred
= vfs_context_ucred(ctx
);
1716 MAC_CHECK(mount_check_setattr
, cred
, mp
, mp
->mnt_mntlabel
, vfa
);
1721 mac_mount_check_stat(vfs_context_t ctx
, struct mount
*mount
)
1726 #if SECURITY_MAC_CHECK_ENFORCE
1727 /* 21167099 - only check if we allow write */
1728 if (!mac_vnode_enforce
)
1731 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1734 cred
= vfs_context_ucred(ctx
);
1735 MAC_CHECK(mount_check_stat
, cred
, mount
, mount
->mnt_mntlabel
);
1741 mac_mount_check_label_update(vfs_context_t ctx
, struct mount
*mount
)
1746 #if SECURITY_MAC_CHECK_ENFORCE
1747 /* 21167099 - only check if we allow write */
1748 if (!mac_vnode_enforce
)
1751 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1754 cred
= vfs_context_ucred(ctx
);
1755 MAC_CHECK(mount_check_label_update
, cred
, mount
, mount
->mnt_mntlabel
);
1761 mac_mount_check_fsctl(vfs_context_t ctx
, struct mount
*mp
, u_int cmd
)
1766 #if SECURITY_MAC_CHECK_ENFORCE
1767 /* 21167099 - only check if we allow write */
1768 if (!mac_vnode_enforce
)
1771 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1774 cred
= vfs_context_ucred(ctx
);
1775 MAC_CHECK(mount_check_fsctl
, cred
, mp
, mp
->mnt_mntlabel
, cmd
);
1781 mac_devfs_label_associate_device(dev_t dev
, struct devnode
*de
,
1782 const char *fullpath
)
1784 #if SECURITY_MAC_CHECK_ENFORCE
1785 /* 21167099 - only check if we allow write */
1786 if (!mac_device_enforce
)
1790 MAC_PERFORM(devfs_label_associate_device
, dev
, de
, de
->dn_label
,
1795 mac_devfs_label_associate_directory(const char *dirname
, int dirnamelen
,
1796 struct devnode
*de
, const char *fullpath
)
1798 #if SECURITY_MAC_CHECK_ENFORCE
1799 /* 21167099 - only check if we allow write */
1800 if (!mac_device_enforce
)
1804 MAC_PERFORM(devfs_label_associate_directory
, dirname
, dirnamelen
, de
,
1805 de
->dn_label
, fullpath
);
1809 vn_setlabel(struct vnode
*vp
, struct label
*intlabel
, vfs_context_t context
)
1813 #if SECURITY_MAC_CHECK_ENFORCE
1814 /* 21167099 - only check if we allow write */
1815 if (!mac_vnode_enforce
)
1818 if (!mac_label_vnodes
)
1821 if (vp
->v_mount
== NULL
) {
1822 printf("vn_setlabel: null v_mount\n");
1823 if (vp
->v_type
!= VNON
)
1824 printf("vn_setlabel: null v_mount with non-VNON\n");
1828 if ((vp
->v_mount
->mnt_flag
& MNT_MULTILABEL
) == 0)
1832 * Multi-phase commit. First check the policies to confirm the
1833 * change is OK. Then commit via the filesystem. Finally,
1834 * update the actual vnode label. Question: maybe the filesystem
1835 * should update the vnode at the end as part of VNOP_SETLABEL()?
1837 error
= mac_vnode_check_label_update(context
, vp
, intlabel
);
1841 error
= VNOP_SETLABEL(vp
, intlabel
, context
);
1842 if (error
== ENOTSUP
) {
1843 error
= mac_vnode_label_store(context
, vp
,
1846 printf("%s: mac_vnode_label_store failed %d\n",
1850 mac_vnode_label_update(context
, vp
, intlabel
);
1853 printf("vn_setlabel: vop setlabel failed %d\n", error
);
1861 mac_vnode_label_associate_fdesc(struct mount
*mp
, struct fdescnode
*fnp
,
1862 struct vnode
*vp
, vfs_context_t ctx
)
1864 struct fileproc
*fp
;
1865 #if CONFIG_MACF_SOCKET_SUBSET
1876 * If no backing file, let the policy choose which label to use.
1878 if (fnp
->fd_fd
== -1) {
1879 MAC_PERFORM(vnode_label_associate_file
, vfs_context_ucred(ctx
),
1880 mp
, mp
->mnt_mntlabel
, NULL
, NULL
, vp
, vp
->v_label
);
1884 p
= vfs_context_proc(ctx
);
1885 error
= fp_lookup(p
, fnp
->fd_fd
, &fp
, 0);
1889 if (fp
->f_fglob
== NULL
) {
1894 switch (FILEGLOB_DTYPE(fp
->f_fglob
)) {
1896 fvp
= (struct vnode
*)fp
->f_fglob
->fg_data
;
1897 if ((error
= vnode_getwithref(fvp
)))
1899 MAC_PERFORM(vnode_label_copy
, fvp
->v_label
, vp
->v_label
);
1900 (void)vnode_put(fvp
);
1902 #if CONFIG_MACF_SOCKET_SUBSET
1904 so
= (struct socket
*)fp
->f_fglob
->fg_data
;
1906 MAC_PERFORM(vnode_label_associate_socket
,
1907 vfs_context_ucred(ctx
), (socket_t
)so
, so
->so_label
,
1909 socket_unlock(so
, 1);
1913 pshm_label_associate(fp
, vp
, ctx
);
1916 psem_label_associate(fp
, vp
, ctx
);
1919 cpipe
= (struct pipe
*)fp
->f_fglob
->fg_data
;
1920 /* kern/sys_pipe.c:pipe_select() suggests this test. */
1921 if (cpipe
== (struct pipe
*)-1) {
1926 MAC_PERFORM(vnode_label_associate_pipe
, vfs_context_ucred(ctx
),
1927 cpipe
, cpipe
->pipe_label
, vp
, vp
->v_label
);
1931 case DTYPE_FSEVENTS
:
1933 MAC_PERFORM(vnode_label_associate_file
, vfs_context_ucred(ctx
),
1934 mp
, mp
->mnt_mntlabel
, fp
->f_fglob
, fp
->f_fglob
->fg_label
,
1939 fp_drop(p
, fnp
->fd_fd
, fp
, 0);