2 * Copyright (c) 2007-2016 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 <kern/kalloc.h>
67 #include <sys/param.h>
68 #include <sys/systm.h>
69 #include <sys/kernel.h>
71 #include <sys/kauth.h>
73 #include <sys/file_internal.h>
74 #include <sys/imgact.h>
75 #include <sys/namei.h>
76 #include <sys/mount_internal.h>
78 #include <sys/posix_sem.h>
79 #include <sys/posix_shm.h>
80 #include <sys/reason.h>
81 #include <sys/uio_internal.h>
82 #include <sys/vnode_internal.h>
84 #include <miscfs/devfs/devfsdefs.h>
85 #include <miscfs/devfs/fdesc.h>
87 #include <security/mac_internal.h>
89 /* convert {R,W,X}_OK values to V{READ,WRITE,EXEC} */
90 #define ACCESS_MODE_TO_VNODE_MASK(m) (m << 6)
93 mac_devfsdirent_label_alloc(void)
97 label
= mac_labelzone_alloc(MAC_WAITOK
);
100 MAC_PERFORM(devfs_label_init
, label
);
105 mac_devfs_label_init(struct devnode
*de
)
108 de
->dn_label
= mac_devfsdirent_label_alloc();
111 static struct label
*
112 mac_mount_label_alloc(void)
116 label
= mac_labelzone_alloc(MAC_WAITOK
);
119 MAC_PERFORM(mount_label_init
, label
);
124 mac_mount_label_init(struct mount
*mp
)
127 mp
->mnt_mntlabel
= mac_mount_label_alloc();
131 mac_vnode_label_alloc(void)
135 label
= mac_labelzone_alloc(MAC_WAITOK
);
138 MAC_PERFORM(vnode_label_init
, label
);
143 mac_vnode_label_init(vnode_t vp
)
145 vp
->v_label
= mac_vnode_label_alloc();
149 mac_vnode_label_init_needed(vnode_t vp
)
151 return (mac_label_vnodes
!= 0 && vp
->v_label
== NULL
);
155 * vnode labels are allocated at the same time as vnodes, but vnodes are never
156 * freed. Instead, we want to remove any sensitive information before putting
157 * them on the free list for reuse.
160 mac_vnode_label_recycle(vnode_t vp
)
163 MAC_PERFORM(vnode_label_recycle
, vp
->v_label
);
167 mac_devfs_label_free(struct label
*label
)
169 MAC_PERFORM(devfs_label_destroy
, label
);
170 mac_labelzone_free(label
);
174 mac_devfs_label_destroy(struct devnode
*de
)
176 if (de
->dn_label
!= NULL
) {
177 mac_devfs_label_free(de
->dn_label
);
183 mac_mount_label_free(struct label
*label
)
186 MAC_PERFORM(mount_label_destroy
, label
);
187 mac_labelzone_free(label
);
191 mac_mount_label_destroy(struct mount
*mp
)
193 if (mp
->mnt_mntlabel
!= NULL
) {
194 mac_mount_label_free(mp
->mnt_mntlabel
);
195 mp
->mnt_mntlabel
= NULL
;
200 mac_vnode_label_free(struct label
*label
)
202 MAC_PERFORM(vnode_label_destroy
, label
);
203 mac_labelzone_free(label
);
208 mac_vnode_label_destroy(struct vnode
*vp
)
210 if (vp
->v_label
!= NULL
) {
211 mac_vnode_label_free(vp
->v_label
);
218 mac_vnode_label_copy(struct label
*src
, struct label
*dest
)
221 MAC_PERFORM(vnode_label_init
, dest
);
223 MAC_PERFORM(vnode_label_copy
, src
, dest
);
228 mac_vnode_label_externalize_audit(struct vnode
*vp
, struct mac
*mac
)
232 /* It is assumed that any necessary vnode locking is done on entry */
233 error
= MAC_EXTERNALIZE_AUDIT(vnode
, vp
->v_label
,
234 mac
->m_string
, mac
->m_buflen
);
240 mac_vnode_label_externalize(struct label
*label
, char *elements
,
241 char *outbuf
, size_t outbuflen
, int flags __unused
)
245 error
= MAC_EXTERNALIZE(vnode
, label
, elements
, outbuf
, outbuflen
);
251 mac_vnode_label_internalize(struct label
*label
, char *string
)
255 error
= MAC_INTERNALIZE(vnode
, label
, string
);
261 mac_mount_label_internalize(struct label
*label
, char *string
)
265 error
= MAC_INTERNALIZE(mount
, label
, string
);
271 mac_mount_label_externalize(struct label
*label
, char *elements
,
272 char *outbuf
, size_t outbuflen
)
276 error
= MAC_EXTERNALIZE(mount
, label
, elements
, outbuf
, outbuflen
);
282 mac_devfs_label_copy(struct label
*src
, struct label
*dest
)
284 #if SECURITY_MAC_CHECK_ENFORCE
285 /* 21167099 - only check if we allow write */
286 if (!mac_device_enforce
)
290 MAC_PERFORM(devfs_label_copy
, src
, dest
);
294 mac_devfs_label_update(struct mount
*mp
, struct devnode
*de
,
297 #if SECURITY_MAC_CHECK_ENFORCE
298 /* 21167099 - only check if we allow write */
299 if (!mac_device_enforce
)
303 MAC_PERFORM(devfs_label_update
, mp
, de
, de
->dn_label
, vp
,
308 mac_vnode_label_associate(struct mount
*mp
, struct vnode
*vp
, vfs_context_t ctx
)
311 struct fdescnode
*fnp
;
314 #if SECURITY_MAC_CHECK_ENFORCE
315 /* 21167099 - only check if we allow write */
316 if (!mac_vnode_enforce
)
320 /* XXX: should not inspect v_tag in kernel! */
324 mac_vnode_label_associate_devfs(mp
, dnp
, vp
);
328 error
= mac_vnode_label_associate_fdesc(mp
, fnp
, vp
, ctx
);
331 error
= mac_vnode_label_associate_extattr(mp
, vp
);
339 mac_vnode_label_associate_devfs(struct mount
*mp
, struct devnode
*de
,
342 #if SECURITY_MAC_CHECK_ENFORCE
343 /* 21167099 - only check if we allow write */
344 if (!mac_device_enforce
)
348 MAC_PERFORM(vnode_label_associate_devfs
,
349 mp
, mp
? mp
->mnt_mntlabel
: NULL
,
355 mac_vnode_label_associate_extattr(struct mount
*mp
, struct vnode
*vp
)
359 MAC_CHECK(vnode_label_associate_extattr
, mp
, mp
->mnt_mntlabel
, vp
,
366 mac_vnode_label_associate_singlelabel(struct mount
*mp
, struct vnode
*vp
)
368 #if SECURITY_MAC_CHECK_ENFORCE
369 /* 21167099 - only check if we allow write */
370 if (!mac_vnode_enforce
)
373 if (!mac_label_vnodes
)
376 MAC_PERFORM(vnode_label_associate_singlelabel
, mp
,
377 mp
? mp
->mnt_mntlabel
: NULL
, vp
, vp
->v_label
);
381 mac_vnode_notify_create(vfs_context_t ctx
, struct mount
*mp
,
382 struct vnode
*dvp
, struct vnode
*vp
, struct componentname
*cnp
)
387 #if SECURITY_MAC_CHECK_ENFORCE
388 /* 21167099 - only check if we allow write */
389 if (!mac_vnode_enforce
)
392 cred
= vfs_context_ucred(ctx
);
393 if (!mac_cred_check_enforce(cred
))
395 MAC_CHECK(vnode_notify_create
, cred
, mp
, mp
->mnt_mntlabel
,
396 dvp
, dvp
->v_label
, vp
, vp
->v_label
, cnp
);
402 mac_vnode_notify_rename(vfs_context_t ctx
, struct vnode
*vp
,
403 struct vnode
*dvp
, struct componentname
*cnp
)
407 #if SECURITY_MAC_CHECK_ENFORCE
408 /* 21167099 - only check if we allow write */
409 if (!mac_vnode_enforce
)
412 cred
= vfs_context_ucred(ctx
);
413 if (!mac_cred_check_enforce(cred
))
415 MAC_PERFORM(vnode_notify_rename
, cred
, vp
, vp
->v_label
,
416 dvp
, dvp
->v_label
, cnp
);
420 mac_vnode_notify_open(vfs_context_t ctx
, struct vnode
*vp
, int acc_flags
)
424 #if SECURITY_MAC_CHECK_ENFORCE
425 /* 21167099 - only check if we allow write */
426 if (!mac_vnode_enforce
)
429 cred
= vfs_context_ucred(ctx
);
430 if (!mac_cred_check_enforce(cred
))
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 cred
= vfs_context_ucred(ctx
);
447 if (!mac_cred_check_enforce(cred
))
449 MAC_PERFORM(vnode_notify_link
, cred
, dvp
, dvp
->v_label
, vp
, vp
->v_label
, cnp
);
453 mac_vnode_notify_deleteextattr(vfs_context_t ctx
, struct vnode
*vp
, const char *name
)
457 #if SECURITY_MAC_CHECK_ENFORCE
458 /* 21167099 - only check if we allow write */
459 if (!mac_vnode_enforce
)
462 cred
= vfs_context_ucred(ctx
);
463 if (!mac_cred_check_enforce(cred
))
465 MAC_PERFORM(vnode_notify_deleteextattr
, cred
, vp
, vp
->v_label
, name
);
469 mac_vnode_notify_setacl(vfs_context_t ctx
, struct vnode
*vp
, struct kauth_acl
*acl
)
473 #if SECURITY_MAC_CHECK_ENFORCE
474 /* 21167099 - only check if we allow write */
475 if (!mac_vnode_enforce
)
478 cred
= vfs_context_ucred(ctx
);
479 if (!mac_cred_check_enforce(cred
))
481 MAC_PERFORM(vnode_notify_setacl
, cred
, vp
, vp
->v_label
, acl
);
485 mac_vnode_notify_setattrlist(vfs_context_t ctx
, struct vnode
*vp
, struct attrlist
*alist
)
489 #if SECURITY_MAC_CHECK_ENFORCE
490 /* 21167099 - only check if we allow write */
491 if (!mac_vnode_enforce
)
494 cred
= vfs_context_ucred(ctx
);
495 if (!mac_cred_check_enforce(cred
))
497 MAC_PERFORM(vnode_notify_setattrlist
, cred
, vp
, vp
->v_label
, alist
);
501 mac_vnode_notify_setextattr(vfs_context_t ctx
, struct vnode
*vp
, const char *name
, struct uio
*uio
)
505 #if SECURITY_MAC_CHECK_ENFORCE
506 /* 21167099 - only check if we allow write */
507 if (!mac_vnode_enforce
)
510 cred
= vfs_context_ucred(ctx
);
511 if (!mac_cred_check_enforce(cred
))
513 MAC_PERFORM(vnode_notify_setextattr
, cred
, vp
, vp
->v_label
, name
, uio
);
517 mac_vnode_notify_setflags(vfs_context_t ctx
, struct vnode
*vp
, u_long flags
)
521 #if SECURITY_MAC_CHECK_ENFORCE
522 /* 21167099 - only check if we allow write */
523 if (!mac_vnode_enforce
)
526 cred
= vfs_context_ucred(ctx
);
527 if (!mac_cred_check_enforce(cred
))
529 MAC_PERFORM(vnode_notify_setflags
, cred
, vp
, vp
->v_label
, flags
);
533 mac_vnode_notify_setmode(vfs_context_t ctx
, struct vnode
*vp
, mode_t mode
)
537 #if SECURITY_MAC_CHECK_ENFORCE
538 /* 21167099 - only check if we allow write */
539 if (!mac_vnode_enforce
)
542 cred
= vfs_context_ucred(ctx
);
543 if (!mac_cred_check_enforce(cred
))
545 MAC_PERFORM(vnode_notify_setmode
, cred
, vp
, vp
->v_label
, mode
);
549 mac_vnode_notify_setowner(vfs_context_t ctx
, struct vnode
*vp
, uid_t uid
, gid_t gid
)
553 #if SECURITY_MAC_CHECK_ENFORCE
554 /* 21167099 - only check if we allow write */
555 if (!mac_vnode_enforce
)
558 cred
= vfs_context_ucred(ctx
);
559 if (!mac_cred_check_enforce(cred
))
561 MAC_PERFORM(vnode_notify_setowner
, cred
, vp
, vp
->v_label
, uid
, gid
);
565 mac_vnode_notify_setutimes(vfs_context_t ctx
, struct vnode
*vp
, struct timespec atime
, struct timespec mtime
)
569 #if SECURITY_MAC_CHECK_ENFORCE
570 /* 21167099 - only check if we allow write */
571 if (!mac_vnode_enforce
)
574 cred
= vfs_context_ucred(ctx
);
575 if (!mac_cred_check_enforce(cred
))
577 MAC_PERFORM(vnode_notify_setutimes
, cred
, vp
, vp
->v_label
, atime
, mtime
);
581 mac_vnode_notify_truncate(vfs_context_t ctx
, kauth_cred_t file_cred
, struct vnode
*vp
)
585 #if SECURITY_MAC_CHECK_ENFORCE
586 /* 21167099 - only check if we allow write */
587 if (!mac_vnode_enforce
)
590 cred
= vfs_context_ucred(ctx
);
591 if (!mac_cred_check_enforce(cred
))
593 MAC_PERFORM(vnode_notify_truncate
, cred
, file_cred
, vp
, vp
->v_label
);
597 * Extended attribute 'name' was updated via
598 * vn_setxattr() or vn_removexattr(). Allow the
599 * policy to update the vnode label.
602 mac_vnode_label_update_extattr(struct mount
*mp
, struct vnode
*vp
,
607 #if SECURITY_MAC_CHECK_ENFORCE
608 /* 21167099 - only check if we allow write */
609 if (!mac_vnode_enforce
)
612 if (!mac_label_vnodes
)
615 MAC_PERFORM(vnode_label_update_extattr
, mp
, mp
->mnt_mntlabel
, vp
,
627 mac_vnode_label_store(vfs_context_t ctx
, struct vnode
*vp
,
628 struct label
*intlabel
)
633 #if SECURITY_MAC_CHECK_ENFORCE
634 /* 21167099 - only check if we allow write */
635 if (!mac_vnode_enforce
)
638 if (!mac_label_vnodes
)
641 cred
= vfs_context_ucred(ctx
);
642 if (!mac_cred_check_enforce(cred
))
644 MAC_CHECK(vnode_label_store
, cred
, vp
, vp
->v_label
, intlabel
);
650 mac_cred_label_update_execve(vfs_context_t ctx
, kauth_cred_t
new, struct vnode
*vp
, off_t offset
,
651 struct vnode
*scriptvp
, struct label
*scriptvnodelabel
, struct label
*execl
, u_int
*csflags
,
652 void *macextensions
, int *disjoint
, int *labelupdateerror
)
657 posix_cred_t pcred
= posix_cred_get(new);
659 #if SECURITY_MAC_CHECK_ENFORCE
660 /* 21167099 - only check if we allow write */
661 if (!mac_proc_enforce
|| !mac_vnode_enforce
)
665 /* mark the new cred to indicate "matching" includes the label */
666 pcred
->cr_flags
|= CRF_MAC_ENFORCE
;
668 cred
= vfs_context_ucred(ctx
);
671 * NB: Cannot use MAC_CHECK macro because we need a sequence point after
672 * calling exec_spawnattr_getmacpolicyinfo() and before passing the
673 * spawnattrlen as an argument to the hook.
676 struct mac_policy_conf
*mpc
;
680 for (i
= 0; i
< mac_policy_list
.staticmax
; i
++) {
681 mpc
= mac_policy_list
.entries
[i
].mpc
;
685 mpo_cred_label_update_execve_t
*hook
= mpc
->mpc_ops
->mpo_cred_label_update_execve
;
689 size_t spawnattrlen
= 0;
690 void *spawnattr
= exec_spawnattr_getmacpolicyinfo(macextensions
, mpc
->mpc_name
, &spawnattrlen
);
692 error
= mac_error_select(hook(cred
, new, vfs_context_proc(ctx
), vp
, offset
, scriptvp
,
693 vp
->v_label
, scriptvnodelabel
, execl
, csflags
, spawnattr
, spawnattrlen
, disjoint
),
696 if (mac_policy_list_conditional_busy() != 0) {
697 for (; i
<= mac_policy_list
.maxindex
; i
++) {
698 mpc
= mac_policy_list
.entries
[i
].mpc
;
702 mpo_cred_label_update_execve_t
*hook
= mpc
->mpc_ops
->mpo_cred_label_update_execve
;
706 size_t spawnattrlen
= 0;
707 void *spawnattr
= exec_spawnattr_getmacpolicyinfo(macextensions
, mpc
->mpc_name
, &spawnattrlen
);
709 error
= mac_error_select(hook(cred
, new, vfs_context_proc(ctx
), vp
, offset
, scriptvp
,
710 vp
->v_label
, scriptvnodelabel
, execl
, csflags
, spawnattr
, spawnattrlen
, disjoint
),
713 mac_policy_list_unbusy();
716 *labelupdateerror
= error
;
720 mac_cred_check_label_update_execve(vfs_context_t ctx
, struct vnode
*vp
, off_t offset
,
721 struct vnode
*scriptvp
, struct label
*scriptvnodelabel
, struct label
*execlabel
,
722 struct proc
*p
, void *macextensions
)
727 #if SECURITY_MAC_CHECK_ENFORCE
728 /* 21167099 - only check if we allow write */
729 if (!mac_proc_enforce
|| !mac_vnode_enforce
)
733 cred
= vfs_context_ucred(ctx
);
736 * NB: Cannot use MAC_BOOLEAN macro because we need a sequence point after
737 * calling exec_spawnattr_getmacpolicyinfo() and before passing the
738 * spawnattrlen as an argument to the hook.
741 struct mac_policy_conf
*mpc
;
744 for (i
= 0; i
< mac_policy_list
.staticmax
; i
++) {
745 mpc
= mac_policy_list
.entries
[i
].mpc
;
749 mpo_cred_check_label_update_execve_t
*hook
= mpc
->mpc_ops
->mpo_cred_check_label_update_execve
;
753 size_t spawnattrlen
= 0;
754 void *spawnattr
= exec_spawnattr_getmacpolicyinfo(macextensions
, mpc
->mpc_name
, &spawnattrlen
);
756 result
= result
|| hook(cred
, vp
, offset
, scriptvp
, vp
->v_label
, scriptvnodelabel
, execlabel
, p
, spawnattr
, spawnattrlen
);
758 if (mac_policy_list_conditional_busy() != 0) {
759 for (; i
<= mac_policy_list
.maxindex
; i
++) {
760 mpc
= mac_policy_list
.entries
[i
].mpc
;
764 mpo_cred_check_label_update_execve_t
*hook
= mpc
->mpc_ops
->mpo_cred_check_label_update_execve
;
768 size_t spawnattrlen
= 0;
769 void *spawnattr
= exec_spawnattr_getmacpolicyinfo(macextensions
, mpc
->mpc_name
, &spawnattrlen
);
771 result
= result
|| hook(cred
, vp
, offset
, scriptvp
, vp
->v_label
, scriptvnodelabel
, execlabel
, p
, spawnattr
, spawnattrlen
);
773 mac_policy_list_unbusy();
781 mac_vnode_check_access(vfs_context_t ctx
, struct vnode
*vp
,
788 #if SECURITY_MAC_CHECK_ENFORCE
789 /* 21167099 - only check if we allow write */
790 if (!mac_vnode_enforce
)
793 cred
= vfs_context_ucred(ctx
);
794 if (!mac_cred_check_enforce(cred
))
796 /* Convert {R,W,X}_OK values to V{READ,WRITE,EXEC} for entry points */
797 mask
= ACCESS_MODE_TO_VNODE_MASK(acc_mode
);
798 MAC_CHECK(vnode_check_access
, cred
, vp
, vp
->v_label
, mask
);
803 mac_vnode_check_chdir(vfs_context_t ctx
, struct vnode
*dvp
)
808 #if SECURITY_MAC_CHECK_ENFORCE
809 /* 21167099 - only check if we allow write */
810 if (!mac_vnode_enforce
)
813 cred
= vfs_context_ucred(ctx
);
814 if (!mac_cred_check_enforce(cred
))
816 MAC_CHECK(vnode_check_chdir
, cred
, dvp
, dvp
->v_label
);
821 mac_vnode_check_chroot(vfs_context_t ctx
, struct vnode
*dvp
,
822 struct componentname
*cnp
)
827 #if SECURITY_MAC_CHECK_ENFORCE
828 /* 21167099 - only check if we allow write */
829 if (!mac_vnode_enforce
)
832 cred
= vfs_context_ucred(ctx
);
833 if (!mac_cred_check_enforce(cred
))
835 MAC_CHECK(vnode_check_chroot
, cred
, dvp
, dvp
->v_label
, cnp
);
840 mac_vnode_check_clone(vfs_context_t ctx
, struct vnode
*dvp
,
841 struct vnode
*vp
, struct componentname
*cnp
)
846 #if SECURITY_MAC_CHECK_ENFORCE
847 /* 21167099 - only check if we allow write */
848 if (!mac_vnode_enforce
)
851 cred
= vfs_context_ucred(ctx
);
852 if (!mac_cred_check_enforce(cred
))
854 MAC_CHECK(vnode_check_clone
, cred
, dvp
, dvp
->v_label
, vp
,
859 mac_vnode_check_create(vfs_context_t ctx
, struct vnode
*dvp
,
860 struct componentname
*cnp
, struct vnode_attr
*vap
)
865 #if SECURITY_MAC_CHECK_ENFORCE
866 /* 21167099 - only check if we allow write */
867 if (!mac_vnode_enforce
)
870 cred
= vfs_context_ucred(ctx
);
871 if (!mac_cred_check_enforce(cred
))
873 MAC_CHECK(vnode_check_create
, cred
, dvp
, dvp
->v_label
, cnp
, vap
);
878 mac_vnode_check_unlink(vfs_context_t ctx
, struct vnode
*dvp
, struct vnode
*vp
,
879 struct componentname
*cnp
)
884 #if SECURITY_MAC_CHECK_ENFORCE
885 /* 21167099 - only check if we allow write */
886 if (!mac_vnode_enforce
)
889 cred
= vfs_context_ucred(ctx
);
890 if (!mac_cred_check_enforce(cred
))
892 MAC_CHECK(vnode_check_unlink
, cred
, dvp
, dvp
->v_label
, vp
,
898 mac_vnode_check_deleteacl(vfs_context_t ctx
, struct vnode
*vp
,
904 #if SECURITY_MAC_CHECK_ENFORCE
905 /* 21167099 - only check if we allow write */
906 if (!mac_vnode_enforce
)
909 cred
= vfs_context_ucred(ctx
);
910 if (!mac_cred_check_enforce(cred
))
912 MAC_CHECK(vnode_check_deleteacl
, cred
, vp
, vp
->v_label
, type
);
918 mac_vnode_check_deleteextattr(vfs_context_t ctx
, struct vnode
*vp
,
924 #if SECURITY_MAC_CHECK_ENFORCE
925 /* 21167099 - only check if we allow write */
926 if (!mac_vnode_enforce
)
929 cred
= vfs_context_ucred(ctx
);
930 if (!mac_cred_check_enforce(cred
))
932 MAC_CHECK(vnode_check_deleteextattr
, cred
, vp
, vp
->v_label
, name
);
936 mac_vnode_check_exchangedata(vfs_context_t ctx
,
937 struct vnode
*v1
, struct vnode
*v2
)
942 #if SECURITY_MAC_CHECK_ENFORCE
943 /* 21167099 - only check if we allow write */
944 if (!mac_vnode_enforce
)
947 cred
= vfs_context_ucred(ctx
);
948 if (!mac_cred_check_enforce(cred
))
950 MAC_CHECK(vnode_check_exchangedata
, cred
, v1
, v1
->v_label
,
958 mac_vnode_check_getacl(vfs_context_t ctx
, struct vnode
*vp
, acl_type_t type
)
963 #if SECURITY_MAC_CHECK_ENFORCE
964 /* 21167099 - only check if we allow write */
965 if (!mac_vnode_enforce
)
968 cred
= vfs_context_ucred(ctx
);
969 if (!mac_cred_check_enforce(cred
))
971 MAC_CHECK(vnode_check_getacl
, cred
, vp
, vp
->v_label
, type
);
977 mac_vnode_check_getattr(vfs_context_t ctx
, struct ucred
*file_cred
,
978 struct vnode
*vp
, struct vnode_attr
*va
)
983 #if SECURITY_MAC_CHECK_ENFORCE
984 /* 21167099 - only check if we allow write */
985 if (!mac_vnode_enforce
)
988 cred
= vfs_context_ucred(ctx
);
989 if (!mac_cred_check_enforce(cred
))
991 MAC_CHECK(vnode_check_getattr
, cred
, file_cred
, vp
, vp
->v_label
, va
);
996 mac_vnode_check_getattrlist(vfs_context_t ctx
, struct vnode
*vp
,
997 struct attrlist
*alist
)
1002 #if SECURITY_MAC_CHECK_ENFORCE
1003 /* 21167099 - only check if we allow write */
1004 if (!mac_vnode_enforce
)
1007 cred
= vfs_context_ucred(ctx
);
1008 if (!mac_cred_check_enforce(cred
))
1010 MAC_CHECK(vnode_check_getattrlist
, cred
, vp
, vp
->v_label
, alist
);
1012 /* Falsify results instead of returning error? */
1017 mac_vnode_check_exec(vfs_context_t ctx
, struct vnode
*vp
,
1018 struct image_params
*imgp
)
1023 #if SECURITY_MAC_CHECK_ENFORCE
1024 /* 21167099 - only check if we allow write */
1025 if (!mac_proc_enforce
|| !mac_vnode_enforce
)
1029 cred
= vfs_context_ucred(ctx
);
1032 * NB: Cannot use MAC_CHECK macro because we need a sequence point after
1033 * calling exec_spawnattr_getmacpolicyinfo() and before passing the
1034 * spawnattrlen as an argument to the hook.
1037 struct mac_policy_conf
*mpc
;
1040 for (i
= 0; i
< mac_policy_list
.staticmax
; i
++) {
1041 mpc
= mac_policy_list
.entries
[i
].mpc
;
1045 mpo_vnode_check_exec_t
*hook
= mpc
->mpc_ops
->mpo_vnode_check_exec
;
1049 size_t spawnattrlen
= 0;
1050 void *spawnattr
= exec_spawnattr_getmacpolicyinfo(imgp
->ip_px_smpx
, mpc
->mpc_name
, &spawnattrlen
);
1052 error
= mac_error_select(
1054 vp
, imgp
->ip_scriptvp
, vp
->v_label
, imgp
->ip_scriptlabelp
,
1055 imgp
->ip_execlabelp
, &imgp
->ip_ndp
->ni_cnd
, &imgp
->ip_csflags
,
1056 spawnattr
, spawnattrlen
), error
);
1058 if (mac_policy_list_conditional_busy() != 0) {
1059 for (; i
<= mac_policy_list
.maxindex
; i
++) {
1060 mpc
= mac_policy_list
.entries
[i
].mpc
;
1064 mpo_vnode_check_exec_t
*hook
= mpc
->mpc_ops
->mpo_vnode_check_exec
;
1068 size_t spawnattrlen
= 0;
1069 void *spawnattr
= exec_spawnattr_getmacpolicyinfo(imgp
->ip_px_smpx
, mpc
->mpc_name
, &spawnattrlen
);
1071 error
= mac_error_select(
1073 vp
, imgp
->ip_scriptvp
, vp
->v_label
, imgp
->ip_scriptlabelp
,
1074 imgp
->ip_execlabelp
, &imgp
->ip_ndp
->ni_cnd
, &imgp
->ip_csflags
,
1075 spawnattr
, spawnattrlen
), error
);
1077 mac_policy_list_unbusy();
1085 mac_vnode_check_fsgetpath(vfs_context_t ctx
, struct vnode
*vp
)
1090 #if SECURITY_MAC_CHECK_ENFORCE
1091 /* 21167099 - only check if we allow write */
1092 if (!mac_vnode_enforce
)
1095 cred
= vfs_context_ucred(ctx
);
1096 if (!mac_cred_check_enforce(cred
))
1098 MAC_CHECK(vnode_check_fsgetpath
, cred
, vp
, vp
->v_label
);
1103 mac_vnode_check_signature(struct vnode
*vp
, struct cs_blob
*cs_blob
,
1104 struct image_params
*imgp
,
1105 unsigned int *cs_flags
, unsigned int *signer_type
,
1109 char *fatal_failure_desc
= NULL
;
1110 size_t fatal_failure_desc_len
= 0;
1112 char *vn_path
= NULL
;
1113 vm_size_t vn_pathlen
= MAXPATHLEN
;
1114 cpu_type_t cpu_type
= (imgp
== NULL
) ? CPU_TYPE_ANY
: imgp
->ip_origcputype
;
1117 #if SECURITY_MAC_CHECK_ENFORCE
1118 /* 21167099 - only check if we allow write */
1119 if (!mac_proc_enforce
|| !mac_vnode_enforce
)
1123 MAC_CHECK(vnode_check_signature
, vp
, vp
->v_label
, cpu_type
, cs_blob
,
1124 cs_flags
, signer_type
, flags
, &fatal_failure_desc
, &fatal_failure_desc_len
);
1126 if (fatal_failure_desc_len
) {
1127 // A fatal code signature validation failure occured, formulate a crash
1130 char const *path
= NULL
;
1132 vn_path
= (char *)kalloc(MAXPATHLEN
);
1133 if (vn_path
!= NULL
) {
1134 if (vn_getpath(vp
, vn_path
, (int*)&vn_pathlen
) == 0) {
1137 path
= "(get vnode path failed)";
1140 path
= "(path alloc failed)";
1144 panic("mac_vnode_check_signature: MAC hook returned no error, "
1145 "but status is claimed to be fatal? "
1146 "path: '%s', fatal_failure_desc_len: %ld, fatal_failure_desc:\n%s\n",
1147 path
, fatal_failure_desc_len
, fatal_failure_desc
);
1150 printf("mac_vnode_check_signature: %s: code signature validation failed fatally: %s",
1151 path
, fatal_failure_desc
);
1157 os_reason_t reason
= os_reason_create(OS_REASON_CODESIGNING
,
1158 CODESIGNING_EXIT_REASON_TASKGATED_INVALID_SIG
);
1160 if (reason
== OS_REASON_NULL
) {
1161 printf("mac_vnode_check_signature: %s: failure to allocate exit reason for validation failure: %s\n",
1162 path
, fatal_failure_desc
);
1166 imgp
->ip_cs_error
= reason
;
1167 reason
->osr_flags
= (OS_REASON_FLAG_GENERATE_CRASH_REPORT
|
1168 OS_REASON_FLAG_CONSISTENT_FAILURE
);
1170 if (fatal_failure_desc
== NULL
) {
1171 // This may happen if allocation for the buffer failed.
1172 printf("mac_vnode_check_signature: %s: fatal failure is missing its description.\n", path
);
1174 mach_vm_address_t data_addr
= 0;
1176 int reason_error
= 0;
1177 int kcdata_error
= 0;
1179 if ((reason_error
= os_reason_alloc_buffer_noblock(reason
, kcdata_estimate_required_buffer_size
1180 (1, fatal_failure_desc_len
))) == 0 &&
1181 (kcdata_error
= kcdata_get_memory_addr(&reason
->osr_kcd_descriptor
,
1182 EXIT_REASON_USER_DESC
, fatal_failure_desc_len
,
1183 &data_addr
)) == KERN_SUCCESS
) {
1184 kern_return_t mc_error
= kcdata_memcpy(&reason
->osr_kcd_descriptor
, (mach_vm_address_t
)data_addr
,
1185 fatal_failure_desc
, fatal_failure_desc_len
);
1187 if (mc_error
!= KERN_SUCCESS
) {
1188 printf("mac_vnode_check_signature: %s: failed to copy reason string "
1189 "(kcdata_memcpy error: %d, length: %ld)\n",
1190 path
, mc_error
, fatal_failure_desc_len
);
1193 printf("mac_vnode_check_signature: %s: failed to allocate space for reason string "
1194 "(os_reason_alloc_buffer error: %d, kcdata error: %d, length: %ld)\n",
1195 path
, reason_error
, kcdata_error
, fatal_failure_desc_len
);
1203 kfree(vn_path
, MAXPATHLEN
);
1206 if (fatal_failure_desc_len
> 0 && fatal_failure_desc
!= NULL
) {
1207 kfree(fatal_failure_desc
, fatal_failure_desc_len
);
1215 mac_vnode_check_getacl(vfs_context_t ctx
, struct vnode
*vp
, acl_type_t type
)
1220 #if SECURITY_MAC_CHECK_ENFORCE
1221 /* 21167099 - only check if we allow write */
1222 if (!mac_vnode_enforce
)
1225 cred
= vfs_context_ucred(ctx
);
1226 if (!mac_cred_check_enforce(cred
))
1228 MAC_CHECK(vnode_check_getacl
, cred
, vp
, vp
->v_label
, type
);
1234 mac_vnode_check_getextattr(vfs_context_t ctx
, struct vnode
*vp
,
1235 const char *name
, struct uio
*uio
)
1240 #if SECURITY_MAC_CHECK_ENFORCE
1241 /* 21167099 - only check if we allow write */
1242 if (!mac_vnode_enforce
)
1245 cred
= vfs_context_ucred(ctx
);
1246 if (!mac_cred_check_enforce(cred
))
1248 MAC_CHECK(vnode_check_getextattr
, cred
, vp
, vp
->v_label
,
1254 mac_vnode_check_ioctl(vfs_context_t ctx
, struct vnode
*vp
, u_int cmd
)
1259 #if SECURITY_MAC_CHECK_ENFORCE
1260 /* 21167099 - only check if we allow write */
1261 if (!mac_vnode_enforce
)
1264 cred
= vfs_context_ucred(ctx
);
1265 if (!mac_cred_check_enforce(cred
))
1267 MAC_CHECK(vnode_check_ioctl
, cred
, vp
, vp
->v_label
, cmd
);
1272 mac_vnode_check_kqfilter(vfs_context_t ctx
, kauth_cred_t file_cred
,
1273 struct knote
*kn
, struct vnode
*vp
)
1278 #if SECURITY_MAC_CHECK_ENFORCE
1279 /* 21167099 - only check if we allow write */
1280 if (!mac_vnode_enforce
)
1283 cred
= vfs_context_ucred(ctx
);
1284 if (!mac_cred_check_enforce(cred
))
1286 MAC_CHECK(vnode_check_kqfilter
, cred
, file_cred
, kn
, vp
,
1293 mac_vnode_check_link(vfs_context_t ctx
, struct vnode
*dvp
,
1294 struct vnode
*vp
, struct componentname
*cnp
)
1299 #if SECURITY_MAC_CHECK_ENFORCE
1300 /* 21167099 - only check if we allow write */
1301 if (!mac_vnode_enforce
)
1304 cred
= vfs_context_ucred(ctx
);
1305 if (!mac_cred_check_enforce(cred
))
1307 MAC_CHECK(vnode_check_link
, cred
, dvp
, dvp
->v_label
, vp
,
1313 mac_vnode_check_listextattr(vfs_context_t ctx
, struct vnode
*vp
)
1318 #if SECURITY_MAC_CHECK_ENFORCE
1319 /* 21167099 - only check if we allow write */
1320 if (!mac_vnode_enforce
)
1323 cred
= vfs_context_ucred(ctx
);
1324 if (!mac_cred_check_enforce(cred
))
1326 MAC_CHECK(vnode_check_listextattr
, cred
, vp
, vp
->v_label
);
1331 mac_vnode_check_lookup_preflight(vfs_context_t ctx
, struct vnode
*dvp
,
1332 const char *path
, size_t pathlen
)
1337 #if SECURITY_MAC_CHECK_ENFORCE
1338 /* 21167099 - only check if we allow write */
1339 if (!mac_vnode_enforce
)
1342 cred
= vfs_context_ucred(ctx
);
1343 if (!mac_cred_check_enforce(cred
))
1345 MAC_CHECK(vnode_check_lookup_preflight
, cred
, dvp
, dvp
->v_label
, path
, pathlen
);
1350 mac_vnode_check_lookup(vfs_context_t ctx
, struct vnode
*dvp
,
1351 struct componentname
*cnp
)
1356 #if SECURITY_MAC_CHECK_ENFORCE
1357 /* 21167099 - only check if we allow write */
1358 if (!mac_vnode_enforce
)
1361 cred
= vfs_context_ucred(ctx
);
1362 if (!mac_cred_check_enforce(cred
))
1364 MAC_CHECK(vnode_check_lookup
, cred
, dvp
, dvp
->v_label
, cnp
);
1369 mac_vnode_check_open(vfs_context_t ctx
, struct vnode
*vp
, int acc_mode
)
1374 #if SECURITY_MAC_CHECK_ENFORCE
1375 /* 21167099 - only check if we allow write */
1376 if (!mac_vnode_enforce
)
1379 cred
= vfs_context_ucred(ctx
);
1380 if (!mac_cred_check_enforce(cred
))
1382 MAC_CHECK(vnode_check_open
, cred
, vp
, vp
->v_label
, acc_mode
);
1387 mac_vnode_check_read(vfs_context_t ctx
, struct ucred
*file_cred
,
1393 #if SECURITY_MAC_CHECK_ENFORCE
1394 /* 21167099 - only check if we allow write */
1395 if (!mac_vnode_enforce
)
1398 cred
= vfs_context_ucred(ctx
);
1399 if (!mac_cred_check_enforce(cred
))
1401 MAC_CHECK(vnode_check_read
, cred
, file_cred
, vp
,
1408 mac_vnode_check_readdir(vfs_context_t ctx
, struct vnode
*dvp
)
1413 #if SECURITY_MAC_CHECK_ENFORCE
1414 /* 21167099 - only check if we allow write */
1415 if (!mac_vnode_enforce
)
1418 cred
= vfs_context_ucred(ctx
);
1419 if (!mac_cred_check_enforce(cred
))
1421 MAC_CHECK(vnode_check_readdir
, cred
, dvp
, dvp
->v_label
);
1426 mac_vnode_check_readlink(vfs_context_t ctx
, struct vnode
*vp
)
1431 #if SECURITY_MAC_CHECK_ENFORCE
1432 /* 21167099 - only check if we allow write */
1433 if (!mac_vnode_enforce
)
1436 cred
= vfs_context_ucred(ctx
);
1437 if (!mac_cred_check_enforce(cred
))
1439 MAC_CHECK(vnode_check_readlink
, cred
, vp
, vp
->v_label
);
1444 mac_vnode_check_label_update(vfs_context_t ctx
, struct vnode
*vp
,
1445 struct label
*newlabel
)
1450 #if SECURITY_MAC_CHECK_ENFORCE
1451 /* 21167099 - only check if we allow write */
1452 if (!mac_vnode_enforce
)
1455 cred
= vfs_context_ucred(ctx
);
1456 if (!mac_cred_check_enforce(cred
))
1458 MAC_CHECK(vnode_check_label_update
, cred
, vp
, vp
->v_label
, newlabel
);
1464 mac_vnode_check_rename(vfs_context_t ctx
, struct vnode
*dvp
,
1465 struct vnode
*vp
, struct componentname
*cnp
, struct vnode
*tdvp
,
1466 struct vnode
*tvp
, struct componentname
*tcnp
)
1471 #if SECURITY_MAC_CHECK_ENFORCE
1472 /* 21167099 - only check if we allow write */
1473 if (!mac_vnode_enforce
)
1476 cred
= vfs_context_ucred(ctx
);
1477 if (!mac_cred_check_enforce(cred
))
1480 MAC_CHECK(vnode_check_rename_from
, cred
, dvp
, dvp
->v_label
, vp
,
1485 MAC_CHECK(vnode_check_rename_to
, cred
, tdvp
, tdvp
->v_label
, tvp
,
1486 tvp
!= NULL
? tvp
->v_label
: NULL
, dvp
== tdvp
, tcnp
);
1490 MAC_CHECK(vnode_check_rename
, cred
, dvp
, dvp
->v_label
, vp
,
1491 vp
->v_label
, cnp
, tdvp
, tdvp
->v_label
, tvp
,
1492 tvp
!= NULL
? tvp
->v_label
: NULL
, tcnp
);
1497 mac_vnode_check_revoke(vfs_context_t ctx
, struct vnode
*vp
)
1502 #if SECURITY_MAC_CHECK_ENFORCE
1503 /* 21167099 - only check if we allow write */
1504 if (!mac_vnode_enforce
)
1507 cred
= vfs_context_ucred(ctx
);
1508 if (!mac_cred_check_enforce(cred
))
1510 MAC_CHECK(vnode_check_revoke
, cred
, vp
, vp
->v_label
);
1515 mac_vnode_check_searchfs(vfs_context_t ctx
, struct vnode
*vp
, struct attrlist
*alist
)
1520 #if SECURITY_MAC_CHECK_ENFORCE
1521 /* 21167099 - only check if we allow write */
1522 if (!mac_vnode_enforce
)
1525 cred
= vfs_context_ucred(ctx
);
1526 if (!mac_cred_check_enforce(cred
))
1528 MAC_CHECK(vnode_check_searchfs
, cred
, vp
, vp
->v_label
, alist
);
1533 mac_vnode_check_select(vfs_context_t ctx
, struct vnode
*vp
, int which
)
1538 #if SECURITY_MAC_CHECK_ENFORCE
1539 /* 21167099 - only check if we allow write */
1540 if (!mac_vnode_enforce
)
1543 cred
= vfs_context_ucred(ctx
);
1544 if (!mac_cred_check_enforce(cred
))
1546 MAC_CHECK(vnode_check_select
, cred
, vp
, vp
->v_label
, which
);
1551 mac_vnode_check_setacl(vfs_context_t ctx
, struct vnode
*vp
,
1552 struct kauth_acl
*acl
)
1557 #if SECURITY_MAC_CHECK_ENFORCE
1558 /* 21167099 - only check if we allow write */
1559 if (!mac_vnode_enforce
)
1562 cred
= vfs_context_ucred(ctx
);
1563 if (!mac_cred_check_enforce(cred
))
1565 MAC_CHECK(vnode_check_setacl
, cred
, vp
, vp
->v_label
, acl
);
1570 mac_vnode_check_setattrlist(vfs_context_t ctx
, struct vnode
*vp
,
1571 struct attrlist
*alist
)
1576 #if SECURITY_MAC_CHECK_ENFORCE
1577 /* 21167099 - only check if we allow write */
1578 if (!mac_vnode_enforce
)
1581 cred
= vfs_context_ucred(ctx
);
1582 if (!mac_cred_check_enforce(cred
))
1584 MAC_CHECK(vnode_check_setattrlist
, cred
, vp
, vp
->v_label
, alist
);
1589 mac_vnode_check_setextattr(vfs_context_t ctx
, struct vnode
*vp
,
1590 const char *name
, struct uio
*uio
)
1595 #if SECURITY_MAC_CHECK_ENFORCE
1596 /* 21167099 - only check if we allow write */
1597 if (!mac_vnode_enforce
)
1600 cred
= vfs_context_ucred(ctx
);
1601 if (!mac_cred_check_enforce(cred
))
1603 MAC_CHECK(vnode_check_setextattr
, cred
, vp
, vp
->v_label
,
1609 mac_vnode_check_setflags(vfs_context_t ctx
, struct vnode
*vp
, u_long flags
)
1614 #if SECURITY_MAC_CHECK_ENFORCE
1615 /* 21167099 - only check if we allow write */
1616 if (!mac_vnode_enforce
)
1619 cred
= vfs_context_ucred(ctx
);
1620 if (!mac_cred_check_enforce(cred
))
1622 MAC_CHECK(vnode_check_setflags
, cred
, vp
, vp
->v_label
, flags
);
1627 mac_vnode_check_setmode(vfs_context_t ctx
, struct vnode
*vp
, mode_t mode
)
1632 #if SECURITY_MAC_CHECK_ENFORCE
1633 /* 21167099 - only check if we allow write */
1634 if (!mac_vnode_enforce
)
1637 cred
= vfs_context_ucred(ctx
);
1638 if (!mac_cred_check_enforce(cred
))
1640 MAC_CHECK(vnode_check_setmode
, cred
, vp
, vp
->v_label
, mode
);
1645 mac_vnode_check_setowner(vfs_context_t ctx
, struct vnode
*vp
, uid_t uid
,
1651 #if SECURITY_MAC_CHECK_ENFORCE
1652 /* 21167099 - only check if we allow write */
1653 if (!mac_vnode_enforce
)
1656 cred
= vfs_context_ucred(ctx
);
1657 if (!mac_cred_check_enforce(cred
))
1659 MAC_CHECK(vnode_check_setowner
, cred
, vp
, vp
->v_label
, uid
, gid
);
1664 mac_vnode_check_setutimes(vfs_context_t ctx
, struct vnode
*vp
,
1665 struct timespec atime
, struct timespec mtime
)
1670 #if SECURITY_MAC_CHECK_ENFORCE
1671 /* 21167099 - only check if we allow write */
1672 if (!mac_vnode_enforce
)
1675 cred
= vfs_context_ucred(ctx
);
1676 if (!mac_cred_check_enforce(cred
))
1678 MAC_CHECK(vnode_check_setutimes
, cred
, vp
, vp
->v_label
, atime
,
1684 mac_vnode_check_stat(vfs_context_t ctx
, struct ucred
*file_cred
,
1690 #if SECURITY_MAC_CHECK_ENFORCE
1691 /* 21167099 - only check if we allow write */
1692 if (!mac_vnode_enforce
)
1695 cred
= vfs_context_ucred(ctx
);
1696 if (!mac_cred_check_enforce(cred
))
1698 MAC_CHECK(vnode_check_stat
, cred
, file_cred
, vp
,
1704 mac_vnode_check_trigger_resolve(vfs_context_t ctx
, struct vnode
*dvp
,
1705 struct componentname
*cnp
)
1710 #if SECURITY_MAC_CHECK_ENFORCE
1711 /* 21167099 - only check if we allow write */
1712 if (!mac_vnode_enforce
)
1715 cred
= vfs_context_ucred(ctx
);
1716 if (!mac_cred_check_enforce(cred
))
1718 MAC_CHECK(vnode_check_trigger_resolve
, cred
, dvp
, dvp
->v_label
, cnp
);
1723 mac_vnode_check_truncate(vfs_context_t ctx
, struct ucred
*file_cred
,
1729 #if SECURITY_MAC_CHECK_ENFORCE
1730 /* 21167099 - only check if we allow write */
1731 if (!mac_vnode_enforce
)
1734 cred
= vfs_context_ucred(ctx
);
1735 if (!mac_cred_check_enforce(cred
))
1737 MAC_CHECK(vnode_check_truncate
, cred
, file_cred
, vp
,
1744 mac_vnode_check_write(vfs_context_t ctx
, struct ucred
*file_cred
,
1750 #if SECURITY_MAC_CHECK_ENFORCE
1751 /* 21167099 - only check if we allow write */
1752 if (!mac_vnode_enforce
)
1755 cred
= vfs_context_ucred(ctx
);
1756 if (!mac_cred_check_enforce(cred
))
1758 MAC_CHECK(vnode_check_write
, cred
, file_cred
, vp
, vp
->v_label
);
1764 mac_vnode_check_uipc_bind(vfs_context_t ctx
, struct vnode
*dvp
,
1765 struct componentname
*cnp
, struct vnode_attr
*vap
)
1770 #if SECURITY_MAC_CHECK_ENFORCE
1771 /* 21167099 - only check if we allow write */
1772 if (!mac_vnode_enforce
)
1775 cred
= vfs_context_ucred(ctx
);
1776 if (!mac_cred_check_enforce(cred
))
1778 MAC_CHECK(vnode_check_uipc_bind
, cred
, dvp
, dvp
->v_label
, cnp
, vap
);
1783 mac_vnode_check_uipc_connect(vfs_context_t ctx
, struct vnode
*vp
, struct socket
*so
)
1788 #if SECURITY_MAC_CHECK_ENFORCE
1789 /* 21167099 - only check if we allow write */
1790 if (!mac_vnode_enforce
)
1793 cred
= vfs_context_ucred(ctx
);
1794 if (!mac_cred_check_enforce(cred
))
1796 MAC_CHECK(vnode_check_uipc_connect
, cred
, vp
, vp
->v_label
, (socket_t
) so
);
1801 mac_vnode_label_update(vfs_context_t ctx
, struct vnode
*vp
, struct label
*newlabel
)
1803 kauth_cred_t cred
= vfs_context_ucred(ctx
);
1804 struct label
*tmpl
= NULL
;
1806 if (vp
->v_label
== NULL
)
1807 tmpl
= mac_vnode_label_alloc();
1811 /* recheck after lock */
1812 if (vp
->v_label
== NULL
) {
1817 MAC_PERFORM(vnode_label_update
, cred
, vp
, vp
->v_label
, newlabel
);
1821 mac_vnode_label_free(tmpl
);
1825 mac_vnode_find_sigs(struct proc
*p
, struct vnode
*vp
, off_t offset
)
1829 #if SECURITY_MAC_CHECK_ENFORCE
1830 /* 21167099 - only check if we allow write */
1831 if (!mac_proc_enforce
|| !mac_vnode_enforce
)
1835 MAC_CHECK(vnode_find_sigs
, p
, vp
, offset
, vp
->v_label
);
1841 mac_mount_label_associate(vfs_context_t ctx
, struct mount
*mp
)
1843 kauth_cred_t cred
= vfs_context_ucred(ctx
);
1845 /* XXX: eventually this logic may be handled by the policy? */
1847 /* We desire MULTILABEL for the root filesystem. */
1848 if ((mp
->mnt_flag
& MNT_ROOTFS
) &&
1849 (strcmp(mp
->mnt_vfsstat
.f_fstypename
, "hfs") == 0))
1850 mp
->mnt_flag
|= MNT_MULTILABEL
;
1852 /* MULTILABEL on DEVFS. */
1853 if (strcmp(mp
->mnt_vfsstat
.f_fstypename
, "devfs") == 0)
1854 mp
->mnt_flag
|= MNT_MULTILABEL
;
1856 /* MULTILABEL on FDESC pseudo-filesystem. */
1857 if (strcmp(mp
->mnt_vfsstat
.f_fstypename
, "fdesc") == 0)
1858 mp
->mnt_flag
|= MNT_MULTILABEL
;
1860 /* MULTILABEL on all NFS filesystems. */
1861 if (strcmp(mp
->mnt_vfsstat
.f_fstypename
, "nfs") == 0)
1862 mp
->mnt_flag
|= MNT_MULTILABEL
;
1864 /* MULTILABEL on all AFP filesystems. */
1865 if (strcmp(mp
->mnt_vfsstat
.f_fstypename
, "afpfs") == 0)
1866 mp
->mnt_flag
|= MNT_MULTILABEL
;
1868 if (mp
->mnt_vtable
!= NULL
) {
1869 /* Any filesystem that supports native XATTRs. */
1870 if ((mp
->mnt_vtable
->vfc_vfsflags
& VFC_VFSNATIVEXATTR
))
1871 mp
->mnt_flag
|= MNT_MULTILABEL
;
1873 /* Filesystem does not support multilabel. */
1874 if ((mp
->mnt_vtable
->vfc_vfsflags
& VFC_VFSNOMACLABEL
) &&
1875 (mp
->mnt_flag
& MNT_MULTILABEL
))
1876 mp
->mnt_flag
&= ~MNT_MULTILABEL
;
1879 MAC_PERFORM(mount_label_associate
, cred
, mp
, mp
->mnt_mntlabel
);
1881 printf("MAC Framework enabling %s support: %s -> %s (%s)\n",
1882 mp
->mnt_flag
& MNT_MULTILABEL
? "multilabel" : "singlelabel",
1883 mp
->mnt_vfsstat
.f_mntfromname
,
1884 mp
->mnt_vfsstat
.f_mntonname
,
1885 mp
->mnt_vfsstat
.f_fstypename
);
1890 mac_mount_check_mount(vfs_context_t ctx
, struct vnode
*vp
,
1891 struct componentname
*cnp
, const char *vfc_name
)
1896 #if SECURITY_MAC_CHECK_ENFORCE
1897 /* 21167099 - only check if we allow write */
1898 if (!mac_vnode_enforce
)
1901 cred
= vfs_context_ucred(ctx
);
1902 if (!mac_cred_check_enforce(cred
))
1904 MAC_CHECK(mount_check_mount
, cred
, vp
, vp
->v_label
, cnp
, vfc_name
);
1910 mac_mount_check_snapshot_create(vfs_context_t ctx
, struct mount
*mp
,
1916 #if SECURITY_MAC_CHECK_ENFORCE
1917 /* 21167099 - only check if we allow write */
1918 if (!mac_vnode_enforce
)
1921 cred
= vfs_context_ucred(ctx
);
1922 if (!mac_cred_check_enforce(cred
))
1924 MAC_CHECK(mount_check_snapshot_create
, cred
, mp
, name
);
1929 mac_mount_check_snapshot_delete(vfs_context_t ctx
, struct mount
*mp
,
1935 #if SECURITY_MAC_CHECK_ENFORCE
1936 /* 21167099 - only check if we allow write */
1937 if (!mac_vnode_enforce
)
1940 cred
= vfs_context_ucred(ctx
);
1941 if (!mac_cred_check_enforce(cred
))
1943 MAC_CHECK(mount_check_snapshot_delete
, cred
, mp
, name
);
1948 mac_mount_check_snapshot_revert(vfs_context_t ctx
, struct mount
*mp
,
1954 #if SECURITY_MAC_CHECK_ENFORCE
1955 /* 21167099 - only check if we allow write */
1956 if (!mac_vnode_enforce
)
1959 cred
= vfs_context_ucred(ctx
);
1960 if (!mac_cred_check_enforce(cred
))
1962 MAC_CHECK(mount_check_snapshot_revert
, cred
, mp
, name
);
1967 mac_mount_check_remount(vfs_context_t ctx
, struct mount
*mp
)
1972 #if SECURITY_MAC_CHECK_ENFORCE
1973 /* 21167099 - only check if we allow write */
1974 if (!mac_vnode_enforce
)
1977 cred
= vfs_context_ucred(ctx
);
1978 if (!mac_cred_check_enforce(cred
))
1980 MAC_CHECK(mount_check_remount
, cred
, mp
, mp
->mnt_mntlabel
);
1986 mac_mount_check_umount(vfs_context_t ctx
, struct mount
*mp
)
1991 #if SECURITY_MAC_CHECK_ENFORCE
1992 /* 21167099 - only check if we allow write */
1993 if (!mac_vnode_enforce
)
1996 cred
= vfs_context_ucred(ctx
);
1997 if (!mac_cred_check_enforce(cred
))
1999 MAC_CHECK(mount_check_umount
, cred
, mp
, mp
->mnt_mntlabel
);
2005 mac_mount_check_getattr(vfs_context_t ctx
, struct mount
*mp
,
2006 struct vfs_attr
*vfa
)
2011 #if SECURITY_MAC_CHECK_ENFORCE
2012 /* 21167099 - only check if we allow write */
2013 if (!mac_vnode_enforce
)
2016 cred
= vfs_context_ucred(ctx
);
2017 if (!mac_cred_check_enforce(cred
))
2019 MAC_CHECK(mount_check_getattr
, cred
, mp
, mp
->mnt_mntlabel
, vfa
);
2024 mac_mount_check_setattr(vfs_context_t ctx
, struct mount
*mp
,
2025 struct vfs_attr
*vfa
)
2030 #if SECURITY_MAC_CHECK_ENFORCE
2031 /* 21167099 - only check if we allow write */
2032 if (!mac_vnode_enforce
)
2035 cred
= vfs_context_ucred(ctx
);
2036 if (!mac_cred_check_enforce(cred
))
2038 MAC_CHECK(mount_check_setattr
, cred
, mp
, mp
->mnt_mntlabel
, vfa
);
2043 mac_mount_check_stat(vfs_context_t ctx
, struct mount
*mount
)
2048 #if SECURITY_MAC_CHECK_ENFORCE
2049 /* 21167099 - only check if we allow write */
2050 if (!mac_vnode_enforce
)
2053 cred
= vfs_context_ucred(ctx
);
2054 if (!mac_cred_check_enforce(cred
))
2056 MAC_CHECK(mount_check_stat
, cred
, mount
, mount
->mnt_mntlabel
);
2062 mac_mount_check_label_update(vfs_context_t ctx
, struct mount
*mount
)
2067 #if SECURITY_MAC_CHECK_ENFORCE
2068 /* 21167099 - only check if we allow write */
2069 if (!mac_vnode_enforce
)
2072 cred
= vfs_context_ucred(ctx
);
2073 if (!mac_cred_check_enforce(cred
))
2075 MAC_CHECK(mount_check_label_update
, cred
, mount
, mount
->mnt_mntlabel
);
2081 mac_mount_check_fsctl(vfs_context_t ctx
, struct mount
*mp
, u_int cmd
)
2086 #if SECURITY_MAC_CHECK_ENFORCE
2087 /* 21167099 - only check if we allow write */
2088 if (!mac_vnode_enforce
)
2091 cred
= vfs_context_ucred(ctx
);
2092 if (!mac_cred_check_enforce(cred
))
2094 MAC_CHECK(mount_check_fsctl
, cred
, mp
, mp
->mnt_mntlabel
, cmd
);
2100 mac_devfs_label_associate_device(dev_t dev
, struct devnode
*de
,
2101 const char *fullpath
)
2103 #if SECURITY_MAC_CHECK_ENFORCE
2104 /* 21167099 - only check if we allow write */
2105 if (!mac_device_enforce
)
2109 MAC_PERFORM(devfs_label_associate_device
, dev
, de
, de
->dn_label
,
2114 mac_devfs_label_associate_directory(const char *dirname
, int dirnamelen
,
2115 struct devnode
*de
, const char *fullpath
)
2117 #if SECURITY_MAC_CHECK_ENFORCE
2118 /* 21167099 - only check if we allow write */
2119 if (!mac_device_enforce
)
2123 MAC_PERFORM(devfs_label_associate_directory
, dirname
, dirnamelen
, de
,
2124 de
->dn_label
, fullpath
);
2128 vn_setlabel(struct vnode
*vp
, struct label
*intlabel
, vfs_context_t context
)
2132 #if SECURITY_MAC_CHECK_ENFORCE
2133 /* 21167099 - only check if we allow write */
2134 if (!mac_vnode_enforce
)
2137 if (!mac_label_vnodes
)
2140 if (vp
->v_mount
== NULL
) {
2141 printf("vn_setlabel: null v_mount\n");
2142 if (vp
->v_type
!= VNON
)
2143 printf("vn_setlabel: null v_mount with non-VNON\n");
2147 if ((vp
->v_mount
->mnt_flag
& MNT_MULTILABEL
) == 0)
2151 * Multi-phase commit. First check the policies to confirm the
2152 * change is OK. Then commit via the filesystem. Finally,
2153 * update the actual vnode label. Question: maybe the filesystem
2154 * should update the vnode at the end as part of VNOP_SETLABEL()?
2156 error
= mac_vnode_check_label_update(context
, vp
, intlabel
);
2160 error
= VNOP_SETLABEL(vp
, intlabel
, context
);
2161 if (error
== ENOTSUP
) {
2162 error
= mac_vnode_label_store(context
, vp
,
2165 printf("%s: mac_vnode_label_store failed %d\n",
2169 mac_vnode_label_update(context
, vp
, intlabel
);
2172 printf("vn_setlabel: vop setlabel failed %d\n", error
);
2180 mac_vnode_label_associate_fdesc(struct mount
*mp
, struct fdescnode
*fnp
,
2181 struct vnode
*vp
, vfs_context_t ctx
)
2183 struct fileproc
*fp
;
2184 #if CONFIG_MACF_SOCKET_SUBSET
2195 * If no backing file, let the policy choose which label to use.
2197 if (fnp
->fd_fd
== -1) {
2198 MAC_PERFORM(vnode_label_associate_file
, vfs_context_ucred(ctx
),
2199 mp
, mp
->mnt_mntlabel
, NULL
, NULL
, vp
, vp
->v_label
);
2203 p
= vfs_context_proc(ctx
);
2204 error
= fp_lookup(p
, fnp
->fd_fd
, &fp
, 0);
2208 if (fp
->f_fglob
== NULL
) {
2213 switch (FILEGLOB_DTYPE(fp
->f_fglob
)) {
2215 fvp
= (struct vnode
*)fp
->f_fglob
->fg_data
;
2216 if ((error
= vnode_getwithref(fvp
)))
2218 MAC_PERFORM(vnode_label_copy
, fvp
->v_label
, vp
->v_label
);
2219 (void)vnode_put(fvp
);
2221 #if CONFIG_MACF_SOCKET_SUBSET
2223 so
= (struct socket
*)fp
->f_fglob
->fg_data
;
2225 MAC_PERFORM(vnode_label_associate_socket
,
2226 vfs_context_ucred(ctx
), (socket_t
)so
, so
->so_label
,
2228 socket_unlock(so
, 1);
2232 pshm_label_associate(fp
, vp
, ctx
);
2235 psem_label_associate(fp
, vp
, ctx
);
2238 cpipe
= (struct pipe
*)fp
->f_fglob
->fg_data
;
2239 /* kern/sys_pipe.c:pipe_select() suggests this test. */
2240 if (cpipe
== (struct pipe
*)-1) {
2245 MAC_PERFORM(vnode_label_associate_pipe
, vfs_context_ucred(ctx
),
2246 cpipe
, cpipe
->pipe_label
, vp
, vp
->v_label
);
2250 case DTYPE_FSEVENTS
:
2252 case DTYPE_NETPOLICY
:
2254 MAC_PERFORM(vnode_label_associate_file
, vfs_context_ucred(ctx
),
2255 mp
, mp
->mnt_mntlabel
, fp
->f_fglob
, fp
->f_fglob
->fg_label
,
2260 fp_drop(p
, fnp
->fd_fd
, fp
, 0);