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
);
101 MAC_PERFORM(devfs_label_init
, label
);
106 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
);
120 MAC_PERFORM(mount_label_init
, label
);
125 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
);
139 MAC_PERFORM(vnode_label_init
, label
);
144 mac_vnode_label_init(vnode_t vp
)
146 vp
->v_label
= mac_vnode_label_alloc();
150 mac_vnode_label_init_needed(vnode_t vp
)
152 return mac_label_vnodes
!= 0 && vp
->v_label
== NULL
;
156 * vnode labels are allocated at the same time as vnodes, but vnodes are never
157 * freed. Instead, we want to remove any sensitive information before putting
158 * them on the free list for reuse.
161 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
)
185 MAC_PERFORM(mount_label_destroy
, label
);
186 mac_labelzone_free(label
);
190 mac_mount_label_destroy(struct mount
*mp
)
192 if (mp
->mnt_mntlabel
!= NULL
) {
193 mac_mount_label_free(mp
->mnt_mntlabel
);
194 mp
->mnt_mntlabel
= NULL
;
199 mac_vnode_label_free(struct label
*label
)
201 MAC_PERFORM(vnode_label_destroy
, label
);
202 mac_labelzone_free(label
);
207 mac_vnode_label_destroy(struct vnode
*vp
)
209 if (vp
->v_label
!= NULL
) {
210 mac_vnode_label_free(vp
->v_label
);
217 mac_vnode_label_copy(struct label
*src
, struct label
*dest
)
220 MAC_PERFORM(vnode_label_init
, dest
);
222 MAC_PERFORM(vnode_label_copy
, src
, dest
);
227 mac_vnode_label_externalize_audit(struct vnode
*vp
, struct mac
*mac
)
231 /* It is assumed that any necessary vnode locking is done on entry */
232 error
= MAC_EXTERNALIZE_AUDIT(vnode
, vp
->v_label
,
233 mac
->m_string
, mac
->m_buflen
);
239 mac_vnode_label_externalize(struct label
*label
, char *elements
,
240 char *outbuf
, size_t outbuflen
, int flags __unused
)
244 error
= MAC_EXTERNALIZE(vnode
, label
, elements
, outbuf
, outbuflen
);
250 mac_vnode_label_internalize(struct label
*label
, char *string
)
254 error
= MAC_INTERNALIZE(vnode
, label
, string
);
260 mac_mount_label_internalize(struct label
*label
, char *string
)
264 error
= MAC_INTERNALIZE(mount
, label
, string
);
270 mac_mount_label_externalize(struct label
*label
, char *elements
,
271 char *outbuf
, size_t outbuflen
)
275 error
= MAC_EXTERNALIZE(mount
, label
, elements
, outbuf
, outbuflen
);
281 mac_devfs_label_copy(struct label
*src
, struct label
*dest
)
283 #if SECURITY_MAC_CHECK_ENFORCE
284 /* 21167099 - only check if we allow write */
285 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
) {
304 MAC_PERFORM(devfs_label_update
, mp
, de
, de
->dn_label
, vp
,
309 mac_vnode_label_associate(struct mount
*mp
, struct vnode
*vp
, vfs_context_t ctx
)
312 struct fdescnode
*fnp
;
315 #if SECURITY_MAC_CHECK_ENFORCE
316 /* 21167099 - only check if we allow write */
317 if (!mac_vnode_enforce
) {
322 /* XXX: should not inspect v_tag in kernel! */
326 mac_vnode_label_associate_devfs(mp
, dnp
, vp
);
330 error
= mac_vnode_label_associate_fdesc(mp
, fnp
, vp
, ctx
);
333 error
= mac_vnode_label_associate_extattr(mp
, vp
);
341 mac_vnode_label_associate_devfs(struct mount
*mp
, struct devnode
*de
,
344 #if SECURITY_MAC_CHECK_ENFORCE
345 /* 21167099 - only check if we allow write */
346 if (!mac_device_enforce
) {
351 MAC_PERFORM(vnode_label_associate_devfs
,
352 mp
, mp
? mp
->mnt_mntlabel
: NULL
,
358 mac_vnode_label_associate_extattr(struct mount
*mp
, struct vnode
*vp
)
362 MAC_CHECK(vnode_label_associate_extattr
, mp
, mp
->mnt_mntlabel
, vp
,
369 mac_vnode_label_associate_singlelabel(struct mount
*mp
, struct vnode
*vp
)
371 #if SECURITY_MAC_CHECK_ENFORCE
372 /* 21167099 - only check if we allow write */
373 if (!mac_vnode_enforce
) {
377 if (!mac_label_vnodes
) {
381 MAC_PERFORM(vnode_label_associate_singlelabel
, mp
,
382 mp
? mp
->mnt_mntlabel
: NULL
, vp
, vp
->v_label
);
386 mac_vnode_notify_create(vfs_context_t ctx
, struct mount
*mp
,
387 struct vnode
*dvp
, struct vnode
*vp
, struct componentname
*cnp
)
392 #if SECURITY_MAC_CHECK_ENFORCE
393 /* 21167099 - only check if we allow write */
394 if (!mac_vnode_enforce
) {
398 cred
= vfs_context_ucred(ctx
);
399 if (!mac_cred_check_enforce(cred
)) {
402 MAC_CHECK(vnode_notify_create
, cred
, mp
, mp
->mnt_mntlabel
,
403 dvp
, dvp
->v_label
, vp
, vp
->v_label
, cnp
);
409 mac_vnode_notify_rename(vfs_context_t ctx
, struct vnode
*vp
,
410 struct vnode
*dvp
, struct componentname
*cnp
)
414 #if SECURITY_MAC_CHECK_ENFORCE
415 /* 21167099 - only check if we allow write */
416 if (!mac_vnode_enforce
) {
420 cred
= vfs_context_ucred(ctx
);
421 if (!mac_cred_check_enforce(cred
)) {
424 MAC_PERFORM(vnode_notify_rename
, cred
, vp
, vp
->v_label
,
425 dvp
, dvp
->v_label
, cnp
);
429 mac_vnode_notify_open(vfs_context_t ctx
, struct vnode
*vp
, int acc_flags
)
433 #if SECURITY_MAC_CHECK_ENFORCE
434 /* 21167099 - only check if we allow write */
435 if (!mac_vnode_enforce
) {
439 cred
= vfs_context_ucred(ctx
);
440 if (!mac_cred_check_enforce(cred
)) {
443 MAC_PERFORM(vnode_notify_open
, cred
, vp
, vp
->v_label
, acc_flags
);
447 mac_vnode_notify_link(vfs_context_t ctx
, struct vnode
*vp
,
448 struct vnode
*dvp
, struct componentname
*cnp
)
452 #if SECURITY_MAC_CHECK_ENFORCE
453 /* 21167099 - only check if we allow write */
454 if (!mac_vnode_enforce
) {
458 cred
= vfs_context_ucred(ctx
);
459 if (!mac_cred_check_enforce(cred
)) {
462 MAC_PERFORM(vnode_notify_link
, cred
, dvp
, dvp
->v_label
, vp
, vp
->v_label
, cnp
);
466 mac_vnode_notify_deleteextattr(vfs_context_t ctx
, struct vnode
*vp
, const char *name
)
470 #if SECURITY_MAC_CHECK_ENFORCE
471 /* 21167099 - only check if we allow write */
472 if (!mac_vnode_enforce
) {
476 cred
= vfs_context_ucred(ctx
);
477 if (!mac_cred_check_enforce(cred
)) {
480 MAC_PERFORM(vnode_notify_deleteextattr
, cred
, vp
, vp
->v_label
, name
);
484 mac_vnode_notify_setacl(vfs_context_t ctx
, struct vnode
*vp
, struct kauth_acl
*acl
)
488 #if SECURITY_MAC_CHECK_ENFORCE
489 /* 21167099 - only check if we allow write */
490 if (!mac_vnode_enforce
) {
494 cred
= vfs_context_ucred(ctx
);
495 if (!mac_cred_check_enforce(cred
)) {
498 MAC_PERFORM(vnode_notify_setacl
, cred
, vp
, vp
->v_label
, acl
);
502 mac_vnode_notify_setattrlist(vfs_context_t ctx
, struct vnode
*vp
, struct attrlist
*alist
)
506 #if SECURITY_MAC_CHECK_ENFORCE
507 /* 21167099 - only check if we allow write */
508 if (!mac_vnode_enforce
) {
512 cred
= vfs_context_ucred(ctx
);
513 if (!mac_cred_check_enforce(cred
)) {
516 MAC_PERFORM(vnode_notify_setattrlist
, cred
, vp
, vp
->v_label
, alist
);
520 mac_vnode_notify_setextattr(vfs_context_t ctx
, struct vnode
*vp
, const char *name
, struct uio
*uio
)
524 #if SECURITY_MAC_CHECK_ENFORCE
525 /* 21167099 - only check if we allow write */
526 if (!mac_vnode_enforce
) {
530 cred
= vfs_context_ucred(ctx
);
531 if (!mac_cred_check_enforce(cred
)) {
534 MAC_PERFORM(vnode_notify_setextattr
, cred
, vp
, vp
->v_label
, name
, uio
);
538 mac_vnode_notify_setflags(vfs_context_t ctx
, struct vnode
*vp
, u_long flags
)
542 #if SECURITY_MAC_CHECK_ENFORCE
543 /* 21167099 - only check if we allow write */
544 if (!mac_vnode_enforce
) {
548 cred
= vfs_context_ucred(ctx
);
549 if (!mac_cred_check_enforce(cred
)) {
552 MAC_PERFORM(vnode_notify_setflags
, cred
, vp
, vp
->v_label
, flags
);
556 mac_vnode_notify_setmode(vfs_context_t ctx
, struct vnode
*vp
, mode_t mode
)
560 #if SECURITY_MAC_CHECK_ENFORCE
561 /* 21167099 - only check if we allow write */
562 if (!mac_vnode_enforce
) {
566 cred
= vfs_context_ucred(ctx
);
567 if (!mac_cred_check_enforce(cred
)) {
570 MAC_PERFORM(vnode_notify_setmode
, cred
, vp
, vp
->v_label
, mode
);
574 mac_vnode_notify_setowner(vfs_context_t ctx
, struct vnode
*vp
, uid_t uid
, gid_t gid
)
578 #if SECURITY_MAC_CHECK_ENFORCE
579 /* 21167099 - only check if we allow write */
580 if (!mac_vnode_enforce
) {
584 cred
= vfs_context_ucred(ctx
);
585 if (!mac_cred_check_enforce(cred
)) {
588 MAC_PERFORM(vnode_notify_setowner
, cred
, vp
, vp
->v_label
, uid
, gid
);
592 mac_vnode_notify_setutimes(vfs_context_t ctx
, struct vnode
*vp
, struct timespec atime
, struct timespec mtime
)
596 #if SECURITY_MAC_CHECK_ENFORCE
597 /* 21167099 - only check if we allow write */
598 if (!mac_vnode_enforce
) {
602 cred
= vfs_context_ucred(ctx
);
603 if (!mac_cred_check_enforce(cred
)) {
606 MAC_PERFORM(vnode_notify_setutimes
, cred
, vp
, vp
->v_label
, atime
, mtime
);
610 mac_vnode_notify_truncate(vfs_context_t ctx
, kauth_cred_t file_cred
, struct vnode
*vp
)
614 #if SECURITY_MAC_CHECK_ENFORCE
615 /* 21167099 - only check if we allow write */
616 if (!mac_vnode_enforce
) {
620 cred
= vfs_context_ucred(ctx
);
621 if (!mac_cred_check_enforce(cred
)) {
624 MAC_PERFORM(vnode_notify_truncate
, cred
, file_cred
, vp
, vp
->v_label
);
628 * Extended attribute 'name' was updated via
629 * vn_setxattr() or vn_removexattr(). Allow the
630 * policy to update the vnode label.
633 mac_vnode_label_update_extattr(struct mount
*mp
, struct vnode
*vp
,
638 #if SECURITY_MAC_CHECK_ENFORCE
639 /* 21167099 - only check if we allow write */
640 if (!mac_vnode_enforce
) {
644 if (!mac_label_vnodes
) {
648 MAC_PERFORM(vnode_label_update_extattr
, mp
, mp
->mnt_mntlabel
, vp
,
661 mac_vnode_label_store(vfs_context_t ctx
, struct vnode
*vp
,
662 struct label
*intlabel
)
667 #if SECURITY_MAC_CHECK_ENFORCE
668 /* 21167099 - only check if we allow write */
669 if (!mac_vnode_enforce
) {
673 if (!mac_label_vnodes
) {
677 cred
= vfs_context_ucred(ctx
);
678 if (!mac_cred_check_enforce(cred
)) {
681 MAC_CHECK(vnode_label_store
, cred
, vp
, vp
->v_label
, intlabel
);
687 mac_cred_label_update_execve(vfs_context_t ctx
, kauth_cred_t
new, struct vnode
*vp
, off_t offset
,
688 struct vnode
*scriptvp
, struct label
*scriptvnodelabel
, struct label
*execl
, u_int
*csflags
,
689 void *macextensions
, int *disjoint
, int *labelupdateerror
)
694 posix_cred_t pcred
= posix_cred_get(new);
696 #if SECURITY_MAC_CHECK_ENFORCE
697 /* 21167099 - only check if we allow write */
698 if (!mac_proc_enforce
|| !mac_vnode_enforce
) {
703 /* mark the new cred to indicate "matching" includes the label */
704 pcred
->cr_flags
|= CRF_MAC_ENFORCE
;
706 cred
= vfs_context_ucred(ctx
);
709 * NB: Cannot use MAC_CHECK macro because we need a sequence point after
710 * calling exec_spawnattr_getmacpolicyinfo() and before passing the
711 * spawnattrlen as an argument to the hook.
714 struct mac_policy_conf
*mpc
;
718 for (i
= 0; i
< mac_policy_list
.staticmax
; i
++) {
719 mpc
= mac_policy_list
.entries
[i
].mpc
;
724 mpo_cred_label_update_execve_t
*hook
= mpc
->mpc_ops
->mpo_cred_label_update_execve
;
729 size_t spawnattrlen
= 0;
730 void *spawnattr
= exec_spawnattr_getmacpolicyinfo(macextensions
, mpc
->mpc_name
, &spawnattrlen
);
732 error
= mac_error_select(hook(cred
, new, vfs_context_proc(ctx
), vp
, offset
, scriptvp
,
733 vp
->v_label
, scriptvnodelabel
, execl
, csflags
, spawnattr
, spawnattrlen
, disjoint
),
736 if (mac_policy_list_conditional_busy() != 0) {
737 for (; i
<= mac_policy_list
.maxindex
; i
++) {
738 mpc
= mac_policy_list
.entries
[i
].mpc
;
743 mpo_cred_label_update_execve_t
*hook
= mpc
->mpc_ops
->mpo_cred_label_update_execve
;
748 size_t spawnattrlen
= 0;
749 void *spawnattr
= exec_spawnattr_getmacpolicyinfo(macextensions
, mpc
->mpc_name
, &spawnattrlen
);
751 error
= mac_error_select(hook(cred
, new, vfs_context_proc(ctx
), vp
, offset
, scriptvp
,
752 vp
->v_label
, scriptvnodelabel
, execl
, csflags
, spawnattr
, spawnattrlen
, disjoint
),
755 mac_policy_list_unbusy();
758 *labelupdateerror
= error
;
762 mac_cred_check_label_update_execve(vfs_context_t ctx
, struct vnode
*vp
, off_t offset
,
763 struct vnode
*scriptvp
, struct label
*scriptvnodelabel
, struct label
*execlabel
,
764 struct proc
*p
, void *macextensions
)
769 #if SECURITY_MAC_CHECK_ENFORCE
770 /* 21167099 - only check if we allow write */
771 if (!mac_proc_enforce
|| !mac_vnode_enforce
) {
776 cred
= vfs_context_ucred(ctx
);
779 * NB: Cannot use MAC_BOOLEAN macro because we need a sequence point after
780 * calling exec_spawnattr_getmacpolicyinfo() and before passing the
781 * spawnattrlen as an argument to the hook.
784 struct mac_policy_conf
*mpc
;
787 for (i
= 0; i
< mac_policy_list
.staticmax
; i
++) {
788 mpc
= mac_policy_list
.entries
[i
].mpc
;
793 mpo_cred_check_label_update_execve_t
*hook
= mpc
->mpc_ops
->mpo_cred_check_label_update_execve
;
798 size_t spawnattrlen
= 0;
799 void *spawnattr
= exec_spawnattr_getmacpolicyinfo(macextensions
, mpc
->mpc_name
, &spawnattrlen
);
801 result
= result
|| hook(cred
, vp
, offset
, scriptvp
, vp
->v_label
, scriptvnodelabel
, execlabel
, p
, spawnattr
, spawnattrlen
);
803 if (mac_policy_list_conditional_busy() != 0) {
804 for (; i
<= mac_policy_list
.maxindex
; i
++) {
805 mpc
= mac_policy_list
.entries
[i
].mpc
;
810 mpo_cred_check_label_update_execve_t
*hook
= mpc
->mpc_ops
->mpo_cred_check_label_update_execve
;
815 size_t spawnattrlen
= 0;
816 void *spawnattr
= exec_spawnattr_getmacpolicyinfo(macextensions
, mpc
->mpc_name
, &spawnattrlen
);
818 result
= result
|| hook(cred
, vp
, offset
, scriptvp
, vp
->v_label
, scriptvnodelabel
, execlabel
, p
, spawnattr
, spawnattrlen
);
820 mac_policy_list_unbusy();
828 mac_vnode_check_access(vfs_context_t ctx
, struct vnode
*vp
,
835 #if SECURITY_MAC_CHECK_ENFORCE
836 /* 21167099 - only check if we allow write */
837 if (!mac_vnode_enforce
) {
841 cred
= vfs_context_ucred(ctx
);
842 if (!mac_cred_check_enforce(cred
)) {
845 /* Convert {R,W,X}_OK values to V{READ,WRITE,EXEC} for entry points */
846 mask
= ACCESS_MODE_TO_VNODE_MASK(acc_mode
);
847 MAC_CHECK(vnode_check_access
, cred
, vp
, vp
->v_label
, mask
);
852 mac_vnode_check_chdir(vfs_context_t ctx
, struct vnode
*dvp
)
857 #if SECURITY_MAC_CHECK_ENFORCE
858 /* 21167099 - only check if we allow write */
859 if (!mac_vnode_enforce
) {
863 cred
= vfs_context_ucred(ctx
);
864 if (!mac_cred_check_enforce(cred
)) {
867 MAC_CHECK(vnode_check_chdir
, cred
, dvp
, dvp
->v_label
);
872 mac_vnode_check_chroot(vfs_context_t ctx
, struct vnode
*dvp
,
873 struct componentname
*cnp
)
878 #if SECURITY_MAC_CHECK_ENFORCE
879 /* 21167099 - only check if we allow write */
880 if (!mac_vnode_enforce
) {
884 cred
= vfs_context_ucred(ctx
);
885 if (!mac_cred_check_enforce(cred
)) {
888 MAC_CHECK(vnode_check_chroot
, cred
, dvp
, dvp
->v_label
, cnp
);
893 mac_vnode_check_clone(vfs_context_t ctx
, struct vnode
*dvp
,
894 struct vnode
*vp
, struct componentname
*cnp
)
899 #if SECURITY_MAC_CHECK_ENFORCE
900 /* 21167099 - only check if we allow write */
901 if (!mac_vnode_enforce
) {
905 cred
= vfs_context_ucred(ctx
);
906 if (!mac_cred_check_enforce(cred
)) {
909 MAC_CHECK(vnode_check_clone
, cred
, dvp
, dvp
->v_label
, vp
,
914 mac_vnode_check_create(vfs_context_t ctx
, struct vnode
*dvp
,
915 struct componentname
*cnp
, struct vnode_attr
*vap
)
920 #if SECURITY_MAC_CHECK_ENFORCE
921 /* 21167099 - only check if we allow write */
922 if (!mac_vnode_enforce
) {
926 cred
= vfs_context_ucred(ctx
);
927 if (!mac_cred_check_enforce(cred
)) {
930 MAC_CHECK(vnode_check_create
, cred
, dvp
, dvp
->v_label
, cnp
, vap
);
935 mac_vnode_check_unlink(vfs_context_t ctx
, struct vnode
*dvp
, struct vnode
*vp
,
936 struct componentname
*cnp
)
941 #if SECURITY_MAC_CHECK_ENFORCE
942 /* 21167099 - only check if we allow write */
943 if (!mac_vnode_enforce
) {
947 cred
= vfs_context_ucred(ctx
);
948 if (!mac_cred_check_enforce(cred
)) {
951 MAC_CHECK(vnode_check_unlink
, cred
, dvp
, dvp
->v_label
, vp
,
957 mac_vnode_check_deleteacl(vfs_context_t ctx
, struct vnode
*vp
,
963 #if SECURITY_MAC_CHECK_ENFORCE
964 /* 21167099 - only check if we allow write */
965 if (!mac_vnode_enforce
) {
969 cred
= vfs_context_ucred(ctx
);
970 if (!mac_cred_check_enforce(cred
)) {
973 MAC_CHECK(vnode_check_deleteacl
, cred
, vp
, vp
->v_label
, type
);
979 mac_vnode_check_deleteextattr(vfs_context_t ctx
, struct vnode
*vp
,
985 #if SECURITY_MAC_CHECK_ENFORCE
986 /* 21167099 - only check if we allow write */
987 if (!mac_vnode_enforce
) {
991 cred
= vfs_context_ucred(ctx
);
992 if (!mac_cred_check_enforce(cred
)) {
995 MAC_CHECK(vnode_check_deleteextattr
, cred
, vp
, vp
->v_label
, name
);
999 mac_vnode_check_exchangedata(vfs_context_t ctx
,
1000 struct vnode
*v1
, struct vnode
*v2
)
1005 #if SECURITY_MAC_CHECK_ENFORCE
1006 /* 21167099 - only check if we allow write */
1007 if (!mac_vnode_enforce
) {
1011 cred
= vfs_context_ucred(ctx
);
1012 if (!mac_cred_check_enforce(cred
)) {
1015 MAC_CHECK(vnode_check_exchangedata
, cred
, v1
, v1
->v_label
,
1023 mac_vnode_check_getacl(vfs_context_t ctx
, struct vnode
*vp
, acl_type_t type
)
1028 #if SECURITY_MAC_CHECK_ENFORCE
1029 /* 21167099 - only check if we allow write */
1030 if (!mac_vnode_enforce
) {
1034 cred
= vfs_context_ucred(ctx
);
1035 if (!mac_cred_check_enforce(cred
)) {
1038 MAC_CHECK(vnode_check_getacl
, cred
, vp
, vp
->v_label
, type
);
1044 mac_vnode_check_getattr(vfs_context_t ctx
, struct ucred
*file_cred
,
1045 struct vnode
*vp
, struct vnode_attr
*va
)
1050 #if SECURITY_MAC_CHECK_ENFORCE
1051 /* 21167099 - only check if we allow write */
1052 if (!mac_vnode_enforce
) {
1056 cred
= vfs_context_ucred(ctx
);
1057 if (!mac_cred_check_enforce(cred
)) {
1060 MAC_CHECK(vnode_check_getattr
, cred
, file_cred
, vp
, vp
->v_label
, va
);
1065 mac_vnode_check_getattrlist(vfs_context_t ctx
, struct vnode
*vp
,
1066 struct attrlist
*alist
)
1071 #if SECURITY_MAC_CHECK_ENFORCE
1072 /* 21167099 - only check if we allow write */
1073 if (!mac_vnode_enforce
) {
1077 cred
= vfs_context_ucred(ctx
);
1078 if (!mac_cred_check_enforce(cred
)) {
1081 MAC_CHECK(vnode_check_getattrlist
, cred
, vp
, vp
->v_label
, alist
);
1083 /* Falsify results instead of returning error? */
1088 mac_vnode_check_exec(vfs_context_t ctx
, struct vnode
*vp
,
1089 struct image_params
*imgp
)
1094 #if SECURITY_MAC_CHECK_ENFORCE
1095 /* 21167099 - only check if we allow write */
1096 if (!mac_proc_enforce
|| !mac_vnode_enforce
) {
1101 cred
= vfs_context_ucred(ctx
);
1104 * NB: Cannot use MAC_CHECK macro because we need a sequence point after
1105 * calling exec_spawnattr_getmacpolicyinfo() and before passing the
1106 * spawnattrlen as an argument to the hook.
1109 struct mac_policy_conf
*mpc
;
1112 for (i
= 0; i
< mac_policy_list
.staticmax
; i
++) {
1113 mpc
= mac_policy_list
.entries
[i
].mpc
;
1118 mpo_vnode_check_exec_t
*hook
= mpc
->mpc_ops
->mpo_vnode_check_exec
;
1123 size_t spawnattrlen
= 0;
1124 void *spawnattr
= exec_spawnattr_getmacpolicyinfo(imgp
->ip_px_smpx
, mpc
->mpc_name
, &spawnattrlen
);
1126 error
= mac_error_select(
1128 vp
, imgp
->ip_scriptvp
, vp
->v_label
, imgp
->ip_scriptlabelp
,
1129 imgp
->ip_execlabelp
, &imgp
->ip_ndp
->ni_cnd
, &imgp
->ip_csflags
,
1130 spawnattr
, spawnattrlen
), error
);
1132 if (mac_policy_list_conditional_busy() != 0) {
1133 for (; i
<= mac_policy_list
.maxindex
; i
++) {
1134 mpc
= mac_policy_list
.entries
[i
].mpc
;
1139 mpo_vnode_check_exec_t
*hook
= mpc
->mpc_ops
->mpo_vnode_check_exec
;
1144 size_t spawnattrlen
= 0;
1145 void *spawnattr
= exec_spawnattr_getmacpolicyinfo(imgp
->ip_px_smpx
, mpc
->mpc_name
, &spawnattrlen
);
1147 error
= mac_error_select(
1149 vp
, imgp
->ip_scriptvp
, vp
->v_label
, imgp
->ip_scriptlabelp
,
1150 imgp
->ip_execlabelp
, &imgp
->ip_ndp
->ni_cnd
, &imgp
->ip_csflags
,
1151 spawnattr
, spawnattrlen
), error
);
1153 mac_policy_list_unbusy();
1161 mac_vnode_check_fsgetpath(vfs_context_t ctx
, struct vnode
*vp
)
1166 #if SECURITY_MAC_CHECK_ENFORCE
1167 /* 21167099 - only check if we allow write */
1168 if (!mac_vnode_enforce
) {
1172 cred
= vfs_context_ucred(ctx
);
1173 if (!mac_cred_check_enforce(cred
)) {
1176 MAC_CHECK(vnode_check_fsgetpath
, cred
, vp
, vp
->v_label
);
1181 mac_vnode_check_signature(struct vnode
*vp
, struct cs_blob
*cs_blob
,
1182 struct image_params
*imgp
,
1183 unsigned int *cs_flags
, unsigned int *signer_type
,
1187 char *fatal_failure_desc
= NULL
;
1188 size_t fatal_failure_desc_len
= 0;
1190 char *vn_path
= NULL
;
1191 vm_size_t vn_pathlen
= MAXPATHLEN
;
1192 cpu_type_t cpu_type
= (imgp
== NULL
) ? CPU_TYPE_ANY
: imgp
->ip_origcputype
;
1195 #if SECURITY_MAC_CHECK_ENFORCE
1196 /* 21167099 - only check if we allow write */
1197 if (!mac_proc_enforce
|| !mac_vnode_enforce
) {
1202 MAC_CHECK(vnode_check_signature
, vp
, vp
->v_label
, cpu_type
, cs_blob
,
1203 cs_flags
, signer_type
, flags
, &fatal_failure_desc
, &fatal_failure_desc_len
);
1205 if (fatal_failure_desc_len
) {
1206 // A fatal code signature validation failure occured, formulate a crash
1209 char const *path
= NULL
;
1211 vn_path
= (char *)kalloc(MAXPATHLEN
);
1212 if (vn_path
!= NULL
) {
1213 if (vn_getpath(vp
, vn_path
, (int*)&vn_pathlen
) == 0) {
1216 path
= "(get vnode path failed)";
1219 path
= "(path alloc failed)";
1223 panic("mac_vnode_check_signature: MAC hook returned no error, "
1224 "but status is claimed to be fatal? "
1225 "path: '%s', fatal_failure_desc_len: %ld, fatal_failure_desc:\n%s\n",
1226 path
, fatal_failure_desc_len
, fatal_failure_desc
);
1229 printf("mac_vnode_check_signature: %s: code signature validation failed fatally: %s",
1230 path
, fatal_failure_desc
);
1236 os_reason_t reason
= os_reason_create(OS_REASON_CODESIGNING
,
1237 CODESIGNING_EXIT_REASON_TASKGATED_INVALID_SIG
);
1239 if (reason
== OS_REASON_NULL
) {
1240 printf("mac_vnode_check_signature: %s: failure to allocate exit reason for validation failure: %s\n",
1241 path
, fatal_failure_desc
);
1245 imgp
->ip_cs_error
= reason
;
1246 reason
->osr_flags
= (OS_REASON_FLAG_GENERATE_CRASH_REPORT
|
1247 OS_REASON_FLAG_CONSISTENT_FAILURE
);
1249 if (fatal_failure_desc
== NULL
) {
1250 // This may happen if allocation for the buffer failed.
1251 printf("mac_vnode_check_signature: %s: fatal failure is missing its description.\n", path
);
1253 mach_vm_address_t data_addr
= 0;
1255 int reason_error
= 0;
1256 int kcdata_error
= 0;
1258 if ((reason_error
= os_reason_alloc_buffer_noblock(reason
, kcdata_estimate_required_buffer_size
1259 (1, fatal_failure_desc_len
))) == 0 &&
1260 (kcdata_error
= kcdata_get_memory_addr(&reason
->osr_kcd_descriptor
,
1261 EXIT_REASON_USER_DESC
, fatal_failure_desc_len
,
1262 &data_addr
)) == KERN_SUCCESS
) {
1263 kern_return_t mc_error
= kcdata_memcpy(&reason
->osr_kcd_descriptor
, (mach_vm_address_t
)data_addr
,
1264 fatal_failure_desc
, fatal_failure_desc_len
);
1266 if (mc_error
!= KERN_SUCCESS
) {
1267 printf("mac_vnode_check_signature: %s: failed to copy reason string "
1268 "(kcdata_memcpy error: %d, length: %ld)\n",
1269 path
, mc_error
, fatal_failure_desc_len
);
1272 printf("mac_vnode_check_signature: %s: failed to allocate space for reason string "
1273 "(os_reason_alloc_buffer error: %d, kcdata error: %d, length: %ld)\n",
1274 path
, reason_error
, kcdata_error
, fatal_failure_desc_len
);
1281 kfree(vn_path
, MAXPATHLEN
);
1284 if (fatal_failure_desc_len
> 0 && fatal_failure_desc
!= NULL
) {
1285 kfree(fatal_failure_desc
, fatal_failure_desc_len
);
1293 mac_vnode_check_getacl(vfs_context_t ctx
, struct vnode
*vp
, acl_type_t type
)
1298 #if SECURITY_MAC_CHECK_ENFORCE
1299 /* 21167099 - only check if we allow write */
1300 if (!mac_vnode_enforce
) {
1304 cred
= vfs_context_ucred(ctx
);
1305 if (!mac_cred_check_enforce(cred
)) {
1308 MAC_CHECK(vnode_check_getacl
, cred
, vp
, vp
->v_label
, type
);
1314 mac_vnode_check_getextattr(vfs_context_t ctx
, struct vnode
*vp
,
1315 const char *name
, struct uio
*uio
)
1320 #if SECURITY_MAC_CHECK_ENFORCE
1321 /* 21167099 - only check if we allow write */
1322 if (!mac_vnode_enforce
) {
1326 cred
= vfs_context_ucred(ctx
);
1327 if (!mac_cred_check_enforce(cred
)) {
1330 MAC_CHECK(vnode_check_getextattr
, cred
, vp
, vp
->v_label
,
1336 mac_vnode_check_ioctl(vfs_context_t ctx
, struct vnode
*vp
, u_int cmd
)
1341 #if SECURITY_MAC_CHECK_ENFORCE
1342 /* 21167099 - only check if we allow write */
1343 if (!mac_vnode_enforce
) {
1347 cred
= vfs_context_ucred(ctx
);
1348 if (!mac_cred_check_enforce(cred
)) {
1351 MAC_CHECK(vnode_check_ioctl
, cred
, vp
, vp
->v_label
, cmd
);
1356 mac_vnode_check_kqfilter(vfs_context_t ctx
, kauth_cred_t file_cred
,
1357 struct knote
*kn
, struct vnode
*vp
)
1362 #if SECURITY_MAC_CHECK_ENFORCE
1363 /* 21167099 - only check if we allow write */
1364 if (!mac_vnode_enforce
) {
1368 cred
= vfs_context_ucred(ctx
);
1369 if (!mac_cred_check_enforce(cred
)) {
1372 MAC_CHECK(vnode_check_kqfilter
, cred
, file_cred
, kn
, vp
,
1379 mac_vnode_check_link(vfs_context_t ctx
, struct vnode
*dvp
,
1380 struct vnode
*vp
, struct componentname
*cnp
)
1385 #if SECURITY_MAC_CHECK_ENFORCE
1386 /* 21167099 - only check if we allow write */
1387 if (!mac_vnode_enforce
) {
1391 cred
= vfs_context_ucred(ctx
);
1392 if (!mac_cred_check_enforce(cred
)) {
1395 MAC_CHECK(vnode_check_link
, cred
, dvp
, dvp
->v_label
, vp
,
1401 mac_vnode_check_listextattr(vfs_context_t ctx
, struct vnode
*vp
)
1406 #if SECURITY_MAC_CHECK_ENFORCE
1407 /* 21167099 - only check if we allow write */
1408 if (!mac_vnode_enforce
) {
1412 cred
= vfs_context_ucred(ctx
);
1413 if (!mac_cred_check_enforce(cred
)) {
1416 MAC_CHECK(vnode_check_listextattr
, cred
, vp
, vp
->v_label
);
1421 mac_vnode_check_lookup_preflight(vfs_context_t ctx
, struct vnode
*dvp
,
1422 const char *path
, size_t pathlen
)
1427 #if SECURITY_MAC_CHECK_ENFORCE
1428 /* 21167099 - only check if we allow write */
1429 if (!mac_vnode_enforce
) {
1433 cred
= vfs_context_ucred(ctx
);
1434 if (!mac_cred_check_enforce(cred
)) {
1437 MAC_CHECK(vnode_check_lookup_preflight
, cred
, dvp
, dvp
->v_label
, path
, pathlen
);
1442 mac_vnode_check_lookup(vfs_context_t ctx
, struct vnode
*dvp
,
1443 struct componentname
*cnp
)
1448 #if SECURITY_MAC_CHECK_ENFORCE
1449 /* 21167099 - only check if we allow write */
1450 if (!mac_vnode_enforce
) {
1454 cred
= vfs_context_ucred(ctx
);
1455 if (!mac_cred_check_enforce(cred
)) {
1458 MAC_CHECK(vnode_check_lookup
, cred
, dvp
, dvp
->v_label
, cnp
);
1463 mac_vnode_check_open(vfs_context_t ctx
, struct vnode
*vp
, int acc_mode
)
1468 #if SECURITY_MAC_CHECK_ENFORCE
1469 /* 21167099 - only check if we allow write */
1470 if (!mac_vnode_enforce
) {
1474 cred
= vfs_context_ucred(ctx
);
1475 if (!mac_cred_check_enforce(cred
)) {
1478 MAC_CHECK(vnode_check_open
, cred
, vp
, vp
->v_label
, acc_mode
);
1483 mac_vnode_check_read(vfs_context_t ctx
, struct ucred
*file_cred
,
1489 #if SECURITY_MAC_CHECK_ENFORCE
1490 /* 21167099 - only check if we allow write */
1491 if (!mac_vnode_enforce
) {
1495 cred
= vfs_context_ucred(ctx
);
1496 if (!mac_cred_check_enforce(cred
)) {
1499 MAC_CHECK(vnode_check_read
, cred
, file_cred
, vp
,
1506 mac_vnode_check_readdir(vfs_context_t ctx
, struct vnode
*dvp
)
1511 #if SECURITY_MAC_CHECK_ENFORCE
1512 /* 21167099 - only check if we allow write */
1513 if (!mac_vnode_enforce
) {
1517 cred
= vfs_context_ucred(ctx
);
1518 if (!mac_cred_check_enforce(cred
)) {
1521 MAC_CHECK(vnode_check_readdir
, cred
, dvp
, dvp
->v_label
);
1526 mac_vnode_check_readlink(vfs_context_t ctx
, struct vnode
*vp
)
1531 #if SECURITY_MAC_CHECK_ENFORCE
1532 /* 21167099 - only check if we allow write */
1533 if (!mac_vnode_enforce
) {
1537 cred
= vfs_context_ucred(ctx
);
1538 if (!mac_cred_check_enforce(cred
)) {
1541 MAC_CHECK(vnode_check_readlink
, cred
, vp
, vp
->v_label
);
1546 mac_vnode_check_label_update(vfs_context_t ctx
, struct vnode
*vp
,
1547 struct label
*newlabel
)
1552 #if SECURITY_MAC_CHECK_ENFORCE
1553 /* 21167099 - only check if we allow write */
1554 if (!mac_vnode_enforce
) {
1558 cred
= vfs_context_ucred(ctx
);
1559 if (!mac_cred_check_enforce(cred
)) {
1562 MAC_CHECK(vnode_check_label_update
, cred
, vp
, vp
->v_label
, newlabel
);
1568 mac_vnode_check_rename(vfs_context_t ctx
, struct vnode
*dvp
,
1569 struct vnode
*vp
, struct componentname
*cnp
, struct vnode
*tdvp
,
1570 struct vnode
*tvp
, struct componentname
*tcnp
)
1575 #if SECURITY_MAC_CHECK_ENFORCE
1576 /* 21167099 - only check if we allow write */
1577 if (!mac_vnode_enforce
) {
1581 cred
= vfs_context_ucred(ctx
);
1582 if (!mac_cred_check_enforce(cred
)) {
1586 MAC_CHECK(vnode_check_rename_from
, cred
, dvp
, dvp
->v_label
, vp
,
1592 MAC_CHECK(vnode_check_rename_to
, cred
, tdvp
, tdvp
->v_label
, tvp
,
1593 tvp
!= NULL
? tvp
->v_label
: NULL
, dvp
== tdvp
, tcnp
);
1598 MAC_CHECK(vnode_check_rename
, cred
, dvp
, dvp
->v_label
, vp
,
1599 vp
->v_label
, cnp
, tdvp
, tdvp
->v_label
, tvp
,
1600 tvp
!= NULL
? tvp
->v_label
: NULL
, tcnp
);
1605 mac_vnode_check_revoke(vfs_context_t ctx
, struct vnode
*vp
)
1610 #if SECURITY_MAC_CHECK_ENFORCE
1611 /* 21167099 - only check if we allow write */
1612 if (!mac_vnode_enforce
) {
1616 cred
= vfs_context_ucred(ctx
);
1617 if (!mac_cred_check_enforce(cred
)) {
1620 MAC_CHECK(vnode_check_revoke
, cred
, vp
, vp
->v_label
);
1625 mac_vnode_check_searchfs(vfs_context_t ctx
, struct vnode
*vp
, struct attrlist
*alist
)
1630 #if SECURITY_MAC_CHECK_ENFORCE
1631 /* 21167099 - only check if we allow write */
1632 if (!mac_vnode_enforce
) {
1636 cred
= vfs_context_ucred(ctx
);
1637 if (!mac_cred_check_enforce(cred
)) {
1640 MAC_CHECK(vnode_check_searchfs
, cred
, vp
, vp
->v_label
, alist
);
1645 mac_vnode_check_select(vfs_context_t ctx
, struct vnode
*vp
, int which
)
1650 #if SECURITY_MAC_CHECK_ENFORCE
1651 /* 21167099 - only check if we allow write */
1652 if (!mac_vnode_enforce
) {
1656 cred
= vfs_context_ucred(ctx
);
1657 if (!mac_cred_check_enforce(cred
)) {
1660 MAC_CHECK(vnode_check_select
, cred
, vp
, vp
->v_label
, which
);
1665 mac_vnode_check_setacl(vfs_context_t ctx
, struct vnode
*vp
,
1666 struct kauth_acl
*acl
)
1671 #if SECURITY_MAC_CHECK_ENFORCE
1672 /* 21167099 - only check if we allow write */
1673 if (!mac_vnode_enforce
) {
1677 cred
= vfs_context_ucred(ctx
);
1678 if (!mac_cred_check_enforce(cred
)) {
1681 MAC_CHECK(vnode_check_setacl
, cred
, vp
, vp
->v_label
, acl
);
1686 mac_vnode_check_setattrlist(vfs_context_t ctx
, struct vnode
*vp
,
1687 struct attrlist
*alist
)
1692 #if SECURITY_MAC_CHECK_ENFORCE
1693 /* 21167099 - only check if we allow write */
1694 if (!mac_vnode_enforce
) {
1698 cred
= vfs_context_ucred(ctx
);
1699 if (!mac_cred_check_enforce(cred
)) {
1702 MAC_CHECK(vnode_check_setattrlist
, cred
, vp
, vp
->v_label
, alist
);
1707 mac_vnode_check_setextattr(vfs_context_t ctx
, struct vnode
*vp
,
1708 const char *name
, struct uio
*uio
)
1713 #if SECURITY_MAC_CHECK_ENFORCE
1714 /* 21167099 - only check if we allow write */
1715 if (!mac_vnode_enforce
) {
1719 cred
= vfs_context_ucred(ctx
);
1720 if (!mac_cred_check_enforce(cred
)) {
1723 MAC_CHECK(vnode_check_setextattr
, cred
, vp
, vp
->v_label
,
1729 mac_vnode_check_setflags(vfs_context_t ctx
, struct vnode
*vp
, u_long flags
)
1734 #if SECURITY_MAC_CHECK_ENFORCE
1735 /* 21167099 - only check if we allow write */
1736 if (!mac_vnode_enforce
) {
1740 cred
= vfs_context_ucred(ctx
);
1741 if (!mac_cred_check_enforce(cred
)) {
1744 MAC_CHECK(vnode_check_setflags
, cred
, vp
, vp
->v_label
, flags
);
1749 mac_vnode_check_setmode(vfs_context_t ctx
, struct vnode
*vp
, mode_t mode
)
1754 #if SECURITY_MAC_CHECK_ENFORCE
1755 /* 21167099 - only check if we allow write */
1756 if (!mac_vnode_enforce
) {
1760 cred
= vfs_context_ucred(ctx
);
1761 if (!mac_cred_check_enforce(cred
)) {
1764 MAC_CHECK(vnode_check_setmode
, cred
, vp
, vp
->v_label
, mode
);
1769 mac_vnode_check_setowner(vfs_context_t ctx
, struct vnode
*vp
, uid_t uid
,
1775 #if SECURITY_MAC_CHECK_ENFORCE
1776 /* 21167099 - only check if we allow write */
1777 if (!mac_vnode_enforce
) {
1781 cred
= vfs_context_ucred(ctx
);
1782 if (!mac_cred_check_enforce(cred
)) {
1785 MAC_CHECK(vnode_check_setowner
, cred
, vp
, vp
->v_label
, uid
, gid
);
1790 mac_vnode_check_setutimes(vfs_context_t ctx
, struct vnode
*vp
,
1791 struct timespec atime
, struct timespec mtime
)
1796 #if SECURITY_MAC_CHECK_ENFORCE
1797 /* 21167099 - only check if we allow write */
1798 if (!mac_vnode_enforce
) {
1802 cred
= vfs_context_ucred(ctx
);
1803 if (!mac_cred_check_enforce(cred
)) {
1806 MAC_CHECK(vnode_check_setutimes
, cred
, vp
, vp
->v_label
, atime
,
1812 mac_vnode_check_stat(vfs_context_t ctx
, struct ucred
*file_cred
,
1818 #if SECURITY_MAC_CHECK_ENFORCE
1819 /* 21167099 - only check if we allow write */
1820 if (!mac_vnode_enforce
) {
1824 cred
= vfs_context_ucred(ctx
);
1825 if (!mac_cred_check_enforce(cred
)) {
1828 MAC_CHECK(vnode_check_stat
, cred
, file_cred
, vp
,
1834 mac_vnode_check_trigger_resolve(vfs_context_t ctx
, struct vnode
*dvp
,
1835 struct componentname
*cnp
)
1840 #if SECURITY_MAC_CHECK_ENFORCE
1841 /* 21167099 - only check if we allow write */
1842 if (!mac_vnode_enforce
) {
1846 cred
= vfs_context_ucred(ctx
);
1847 if (!mac_cred_check_enforce(cred
)) {
1850 MAC_CHECK(vnode_check_trigger_resolve
, cred
, dvp
, dvp
->v_label
, cnp
);
1855 mac_vnode_check_truncate(vfs_context_t ctx
, struct ucred
*file_cred
,
1861 #if SECURITY_MAC_CHECK_ENFORCE
1862 /* 21167099 - only check if we allow write */
1863 if (!mac_vnode_enforce
) {
1867 cred
= vfs_context_ucred(ctx
);
1868 if (!mac_cred_check_enforce(cred
)) {
1871 MAC_CHECK(vnode_check_truncate
, cred
, file_cred
, vp
,
1878 mac_vnode_check_write(vfs_context_t ctx
, struct ucred
*file_cred
,
1884 #if SECURITY_MAC_CHECK_ENFORCE
1885 /* 21167099 - only check if we allow write */
1886 if (!mac_vnode_enforce
) {
1890 cred
= vfs_context_ucred(ctx
);
1891 if (!mac_cred_check_enforce(cred
)) {
1894 MAC_CHECK(vnode_check_write
, cred
, file_cred
, vp
, vp
->v_label
);
1900 mac_vnode_check_uipc_bind(vfs_context_t ctx
, struct vnode
*dvp
,
1901 struct componentname
*cnp
, struct vnode_attr
*vap
)
1906 #if SECURITY_MAC_CHECK_ENFORCE
1907 /* 21167099 - only check if we allow write */
1908 if (!mac_vnode_enforce
) {
1912 cred
= vfs_context_ucred(ctx
);
1913 if (!mac_cred_check_enforce(cred
)) {
1916 MAC_CHECK(vnode_check_uipc_bind
, cred
, dvp
, dvp
->v_label
, cnp
, vap
);
1921 mac_vnode_check_uipc_connect(vfs_context_t ctx
, struct vnode
*vp
, struct socket
*so
)
1926 #if SECURITY_MAC_CHECK_ENFORCE
1927 /* 21167099 - only check if we allow write */
1928 if (!mac_vnode_enforce
) {
1932 cred
= vfs_context_ucred(ctx
);
1933 if (!mac_cred_check_enforce(cred
)) {
1936 MAC_CHECK(vnode_check_uipc_connect
, cred
, vp
, vp
->v_label
, (socket_t
) so
);
1941 mac_vnode_label_update(vfs_context_t ctx
, struct vnode
*vp
, struct label
*newlabel
)
1943 kauth_cred_t cred
= vfs_context_ucred(ctx
);
1944 struct label
*tmpl
= NULL
;
1946 if (vp
->v_label
== NULL
) {
1947 tmpl
= mac_vnode_label_alloc();
1952 /* recheck after lock */
1953 if (vp
->v_label
== NULL
) {
1958 MAC_PERFORM(vnode_label_update
, cred
, vp
, vp
->v_label
, newlabel
);
1962 mac_vnode_label_free(tmpl
);
1967 mac_vnode_find_sigs(struct proc
*p
, struct vnode
*vp
, off_t offset
)
1971 #if SECURITY_MAC_CHECK_ENFORCE
1972 /* 21167099 - only check if we allow write */
1973 if (!mac_proc_enforce
|| !mac_vnode_enforce
) {
1978 MAC_CHECK(vnode_find_sigs
, p
, vp
, offset
, vp
->v_label
);
1984 mac_mount_label_associate(vfs_context_t ctx
, struct mount
*mp
)
1986 kauth_cred_t cred
= vfs_context_ucred(ctx
);
1988 /* XXX: eventually this logic may be handled by the policy? */
1990 /* We desire MULTILABEL for the root filesystem. */
1991 if ((mp
->mnt_flag
& MNT_ROOTFS
) &&
1992 (strcmp(mp
->mnt_vfsstat
.f_fstypename
, "hfs") == 0)) {
1993 mp
->mnt_flag
|= MNT_MULTILABEL
;
1996 /* MULTILABEL on DEVFS. */
1997 if (strcmp(mp
->mnt_vfsstat
.f_fstypename
, "devfs") == 0) {
1998 mp
->mnt_flag
|= MNT_MULTILABEL
;
2001 /* MULTILABEL on FDESC pseudo-filesystem. */
2002 if (strcmp(mp
->mnt_vfsstat
.f_fstypename
, "fdesc") == 0) {
2003 mp
->mnt_flag
|= MNT_MULTILABEL
;
2006 /* MULTILABEL on all NFS filesystems. */
2007 if (strcmp(mp
->mnt_vfsstat
.f_fstypename
, "nfs") == 0) {
2008 mp
->mnt_flag
|= MNT_MULTILABEL
;
2011 /* MULTILABEL on all AFP filesystems. */
2012 if (strcmp(mp
->mnt_vfsstat
.f_fstypename
, "afpfs") == 0) {
2013 mp
->mnt_flag
|= MNT_MULTILABEL
;
2016 if (mp
->mnt_vtable
!= NULL
) {
2017 /* Any filesystem that supports native XATTRs. */
2018 if ((mp
->mnt_vtable
->vfc_vfsflags
& VFC_VFSNATIVEXATTR
)) {
2019 mp
->mnt_flag
|= MNT_MULTILABEL
;
2022 /* Filesystem does not support multilabel. */
2023 if ((mp
->mnt_vtable
->vfc_vfsflags
& VFC_VFSNOMACLABEL
) &&
2024 (mp
->mnt_flag
& MNT_MULTILABEL
)) {
2025 mp
->mnt_flag
&= ~MNT_MULTILABEL
;
2029 MAC_PERFORM(mount_label_associate
, cred
, mp
, mp
->mnt_mntlabel
);
2031 printf("MAC Framework enabling %s support: %s -> %s (%s)\n",
2032 mp
->mnt_flag
& MNT_MULTILABEL
? "multilabel" : "singlelabel",
2033 mp
->mnt_vfsstat
.f_mntfromname
,
2034 mp
->mnt_vfsstat
.f_mntonname
,
2035 mp
->mnt_vfsstat
.f_fstypename
);
2040 mac_mount_check_mount(vfs_context_t ctx
, struct vnode
*vp
,
2041 struct componentname
*cnp
, const char *vfc_name
)
2046 #if SECURITY_MAC_CHECK_ENFORCE
2047 /* 21167099 - only check if we allow write */
2048 if (!mac_vnode_enforce
) {
2052 cred
= vfs_context_ucred(ctx
);
2053 if (!mac_cred_check_enforce(cred
)) {
2056 MAC_CHECK(mount_check_mount
, cred
, vp
, vp
->v_label
, cnp
, vfc_name
);
2062 mac_mount_check_snapshot_create(vfs_context_t ctx
, struct mount
*mp
,
2068 #if SECURITY_MAC_CHECK_ENFORCE
2069 /* 21167099 - only check if we allow write */
2070 if (!mac_vnode_enforce
) {
2074 cred
= vfs_context_ucred(ctx
);
2075 if (!mac_cred_check_enforce(cred
)) {
2078 MAC_CHECK(mount_check_snapshot_create
, cred
, mp
, name
);
2083 mac_mount_check_snapshot_delete(vfs_context_t ctx
, struct mount
*mp
,
2089 #if SECURITY_MAC_CHECK_ENFORCE
2090 /* 21167099 - only check if we allow write */
2091 if (!mac_vnode_enforce
) {
2095 cred
= vfs_context_ucred(ctx
);
2096 if (!mac_cred_check_enforce(cred
)) {
2099 MAC_CHECK(mount_check_snapshot_delete
, cred
, mp
, name
);
2104 mac_mount_check_snapshot_revert(vfs_context_t ctx
, struct mount
*mp
,
2110 #if SECURITY_MAC_CHECK_ENFORCE
2111 /* 21167099 - only check if we allow write */
2112 if (!mac_vnode_enforce
) {
2116 cred
= vfs_context_ucred(ctx
);
2117 if (!mac_cred_check_enforce(cred
)) {
2120 MAC_CHECK(mount_check_snapshot_revert
, cred
, mp
, name
);
2125 mac_mount_check_remount(vfs_context_t ctx
, struct mount
*mp
)
2130 #if SECURITY_MAC_CHECK_ENFORCE
2131 /* 21167099 - only check if we allow write */
2132 if (!mac_vnode_enforce
) {
2136 cred
= vfs_context_ucred(ctx
);
2137 if (!mac_cred_check_enforce(cred
)) {
2140 MAC_CHECK(mount_check_remount
, cred
, mp
, mp
->mnt_mntlabel
);
2146 mac_mount_check_umount(vfs_context_t ctx
, struct mount
*mp
)
2151 #if SECURITY_MAC_CHECK_ENFORCE
2152 /* 21167099 - only check if we allow write */
2153 if (!mac_vnode_enforce
) {
2157 cred
= vfs_context_ucred(ctx
);
2158 if (!mac_cred_check_enforce(cred
)) {
2161 MAC_CHECK(mount_check_umount
, cred
, mp
, mp
->mnt_mntlabel
);
2167 mac_mount_check_getattr(vfs_context_t ctx
, struct mount
*mp
,
2168 struct vfs_attr
*vfa
)
2173 #if SECURITY_MAC_CHECK_ENFORCE
2174 /* 21167099 - only check if we allow write */
2175 if (!mac_vnode_enforce
) {
2179 cred
= vfs_context_ucred(ctx
);
2180 if (!mac_cred_check_enforce(cred
)) {
2183 MAC_CHECK(mount_check_getattr
, cred
, mp
, mp
->mnt_mntlabel
, vfa
);
2188 mac_mount_check_setattr(vfs_context_t ctx
, struct mount
*mp
,
2189 struct vfs_attr
*vfa
)
2194 #if SECURITY_MAC_CHECK_ENFORCE
2195 /* 21167099 - only check if we allow write */
2196 if (!mac_vnode_enforce
) {
2200 cred
= vfs_context_ucred(ctx
);
2201 if (!mac_cred_check_enforce(cred
)) {
2204 MAC_CHECK(mount_check_setattr
, cred
, mp
, mp
->mnt_mntlabel
, vfa
);
2209 mac_mount_check_stat(vfs_context_t ctx
, struct mount
*mount
)
2214 #if SECURITY_MAC_CHECK_ENFORCE
2215 /* 21167099 - only check if we allow write */
2216 if (!mac_vnode_enforce
) {
2220 cred
= vfs_context_ucred(ctx
);
2221 if (!mac_cred_check_enforce(cred
)) {
2224 MAC_CHECK(mount_check_stat
, cred
, mount
, mount
->mnt_mntlabel
);
2230 mac_mount_check_label_update(vfs_context_t ctx
, struct mount
*mount
)
2235 #if SECURITY_MAC_CHECK_ENFORCE
2236 /* 21167099 - only check if we allow write */
2237 if (!mac_vnode_enforce
) {
2241 cred
= vfs_context_ucred(ctx
);
2242 if (!mac_cred_check_enforce(cred
)) {
2245 MAC_CHECK(mount_check_label_update
, cred
, mount
, mount
->mnt_mntlabel
);
2251 mac_mount_check_fsctl(vfs_context_t ctx
, struct mount
*mp
, u_int cmd
)
2256 #if SECURITY_MAC_CHECK_ENFORCE
2257 /* 21167099 - only check if we allow write */
2258 if (!mac_vnode_enforce
) {
2262 cred
= vfs_context_ucred(ctx
);
2263 if (!mac_cred_check_enforce(cred
)) {
2266 MAC_CHECK(mount_check_fsctl
, cred
, mp
, mp
->mnt_mntlabel
, cmd
);
2272 mac_devfs_label_associate_device(dev_t dev
, struct devnode
*de
,
2273 const char *fullpath
)
2275 #if SECURITY_MAC_CHECK_ENFORCE
2276 /* 21167099 - only check if we allow write */
2277 if (!mac_device_enforce
) {
2282 MAC_PERFORM(devfs_label_associate_device
, dev
, de
, de
->dn_label
,
2287 mac_devfs_label_associate_directory(const char *dirname
, int dirnamelen
,
2288 struct devnode
*de
, const char *fullpath
)
2290 #if SECURITY_MAC_CHECK_ENFORCE
2291 /* 21167099 - only check if we allow write */
2292 if (!mac_device_enforce
) {
2297 MAC_PERFORM(devfs_label_associate_directory
, dirname
, dirnamelen
, de
,
2298 de
->dn_label
, fullpath
);
2302 vn_setlabel(struct vnode
*vp
, struct label
*intlabel
, vfs_context_t context
)
2306 #if SECURITY_MAC_CHECK_ENFORCE
2307 /* 21167099 - only check if we allow write */
2308 if (!mac_vnode_enforce
) {
2312 if (!mac_label_vnodes
) {
2316 if (vp
->v_mount
== NULL
) {
2317 printf("vn_setlabel: null v_mount\n");
2318 if (vp
->v_type
!= VNON
) {
2319 printf("vn_setlabel: null v_mount with non-VNON\n");
2324 if ((vp
->v_mount
->mnt_flag
& MNT_MULTILABEL
) == 0) {
2329 * Multi-phase commit. First check the policies to confirm the
2330 * change is OK. Then commit via the filesystem. Finally,
2331 * update the actual vnode label. Question: maybe the filesystem
2332 * should update the vnode at the end as part of VNOP_SETLABEL()?
2334 error
= mac_vnode_check_label_update(context
, vp
, intlabel
);
2339 error
= VNOP_SETLABEL(vp
, intlabel
, context
);
2340 if (error
== ENOTSUP
) {
2341 error
= mac_vnode_label_store(context
, vp
,
2344 printf("%s: mac_vnode_label_store failed %d\n",
2348 mac_vnode_label_update(context
, vp
, intlabel
);
2350 printf("vn_setlabel: vop setlabel failed %d\n", error
);
2358 mac_vnode_label_associate_fdesc(struct mount
*mp
, struct fdescnode
*fnp
,
2359 struct vnode
*vp
, vfs_context_t ctx
)
2361 struct fileproc
*fp
;
2362 #if CONFIG_MACF_SOCKET_SUBSET
2373 * If no backing file, let the policy choose which label to use.
2375 if (fnp
->fd_fd
== -1) {
2376 MAC_PERFORM(vnode_label_associate_file
, vfs_context_ucred(ctx
),
2377 mp
, mp
->mnt_mntlabel
, NULL
, NULL
, vp
, vp
->v_label
);
2381 p
= vfs_context_proc(ctx
);
2382 error
= fp_lookup(p
, fnp
->fd_fd
, &fp
, 0);
2387 if (fp
->f_fglob
== NULL
) {
2392 switch (FILEGLOB_DTYPE(fp
->f_fglob
)) {
2394 fvp
= (struct vnode
*)fp
->f_fglob
->fg_data
;
2395 if ((error
= vnode_getwithref(fvp
))) {
2398 MAC_PERFORM(vnode_label_copy
, fvp
->v_label
, vp
->v_label
);
2399 (void)vnode_put(fvp
);
2401 #if CONFIG_MACF_SOCKET_SUBSET
2403 so
= (struct socket
*)fp
->f_fglob
->fg_data
;
2405 MAC_PERFORM(vnode_label_associate_socket
,
2406 vfs_context_ucred(ctx
), (socket_t
)so
, so
->so_label
,
2408 socket_unlock(so
, 1);
2412 pshm_label_associate(fp
, vp
, ctx
);
2415 psem_label_associate(fp
, vp
, ctx
);
2418 cpipe
= (struct pipe
*)fp
->f_fglob
->fg_data
;
2419 /* kern/sys_pipe.c:pipe_select() suggests this test. */
2420 if (cpipe
== (struct pipe
*)-1) {
2425 MAC_PERFORM(vnode_label_associate_pipe
, vfs_context_ucred(ctx
),
2426 cpipe
, cpipe
->pipe_label
, vp
, vp
->v_label
);
2430 case DTYPE_FSEVENTS
:
2432 case DTYPE_NETPOLICY
:
2434 MAC_PERFORM(vnode_label_associate_file
, vfs_context_ucred(ctx
),
2435 mp
, mp
->mnt_mntlabel
, fp
->f_fglob
, fp
->f_fglob
->fg_label
,
2440 fp_drop(p
, fnp
->fd_fd
, fp
, 0);