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
;
1116 #if SECURITY_MAC_CHECK_ENFORCE
1117 /* 21167099 - only check if we allow write */
1118 if (!mac_proc_enforce
|| !mac_vnode_enforce
)
1122 MAC_CHECK(vnode_check_signature
, vp
, vp
->v_label
, cs_blob
,
1123 cs_flags
, signer_type
, flags
, &fatal_failure_desc
, &fatal_failure_desc_len
);
1125 if (fatal_failure_desc_len
) {
1126 // A fatal code signature validation failure occured, formulate a crash
1129 char const *path
= NULL
;
1131 vn_path
= (char *)kalloc(MAXPATHLEN
);
1132 if (vn_path
!= NULL
) {
1133 if (vn_getpath(vp
, vn_path
, (int*)&vn_pathlen
) == 0) {
1136 path
= "(get vnode path failed)";
1139 path
= "(path alloc failed)";
1143 panic("mac_vnode_check_signature: MAC hook returned no error, "
1144 "but status is claimed to be fatal? "
1145 "path: '%s', fatal_failure_desc_len: %ld, fatal_failure_desc:\n%s\n",
1146 path
, fatal_failure_desc_len
, fatal_failure_desc
);
1149 printf("mac_vnode_check_signature: %s: code signature validation failed fatally: %s",
1150 path
, fatal_failure_desc
);
1156 os_reason_t reason
= os_reason_create(OS_REASON_CODESIGNING
,
1157 CODESIGNING_EXIT_REASON_TASKGATED_INVALID_SIG
);
1159 if (reason
== OS_REASON_NULL
) {
1160 printf("mac_vnode_check_signature: %s: failure to allocate exit reason for validation failure: %s\n",
1161 path
, fatal_failure_desc
);
1165 imgp
->ip_cs_error
= reason
;
1166 reason
->osr_flags
= (OS_REASON_FLAG_GENERATE_CRASH_REPORT
|
1167 OS_REASON_FLAG_CONSISTENT_FAILURE
);
1169 if (fatal_failure_desc
== NULL
) {
1170 // This may happen if allocation for the buffer failed.
1171 printf("mac_vnode_check_signature: %s: fatal failure is missing its description.\n", path
);
1173 mach_vm_address_t data_addr
= 0;
1175 int reason_error
= 0;
1176 int kcdata_error
= 0;
1178 if ((reason_error
= os_reason_alloc_buffer_noblock(reason
, kcdata_estimate_required_buffer_size
1179 (1, fatal_failure_desc_len
))) == 0 &&
1180 (kcdata_error
= kcdata_get_memory_addr(&reason
->osr_kcd_descriptor
,
1181 EXIT_REASON_USER_DESC
, fatal_failure_desc_len
,
1182 &data_addr
)) == KERN_SUCCESS
) {
1183 kern_return_t mc_error
= kcdata_memcpy(&reason
->osr_kcd_descriptor
, (mach_vm_address_t
)data_addr
,
1184 fatal_failure_desc
, fatal_failure_desc_len
);
1186 if (mc_error
!= KERN_SUCCESS
) {
1187 printf("mac_vnode_check_signature: %s: failed to copy reason string "
1188 "(kcdata_memcpy error: %d, length: %ld)\n",
1189 path
, mc_error
, fatal_failure_desc_len
);
1192 printf("mac_vnode_check_signature: %s: failed to allocate space for reason string "
1193 "(os_reason_alloc_buffer error: %d, kcdata error: %d, length: %ld)\n",
1194 path
, reason_error
, kcdata_error
, fatal_failure_desc_len
);
1202 kfree(vn_path
, MAXPATHLEN
);
1205 if (fatal_failure_desc_len
> 0 && fatal_failure_desc
!= NULL
) {
1206 kfree(fatal_failure_desc
, fatal_failure_desc_len
);
1214 mac_vnode_check_getacl(vfs_context_t ctx
, struct vnode
*vp
, acl_type_t type
)
1219 #if SECURITY_MAC_CHECK_ENFORCE
1220 /* 21167099 - only check if we allow write */
1221 if (!mac_vnode_enforce
)
1224 cred
= vfs_context_ucred(ctx
);
1225 if (!mac_cred_check_enforce(cred
))
1227 MAC_CHECK(vnode_check_getacl
, cred
, vp
, vp
->v_label
, type
);
1233 mac_vnode_check_getextattr(vfs_context_t ctx
, struct vnode
*vp
,
1234 const char *name
, struct uio
*uio
)
1239 #if SECURITY_MAC_CHECK_ENFORCE
1240 /* 21167099 - only check if we allow write */
1241 if (!mac_vnode_enforce
)
1244 cred
= vfs_context_ucred(ctx
);
1245 if (!mac_cred_check_enforce(cred
))
1247 MAC_CHECK(vnode_check_getextattr
, cred
, vp
, vp
->v_label
,
1253 mac_vnode_check_ioctl(vfs_context_t ctx
, struct vnode
*vp
, u_int cmd
)
1258 #if SECURITY_MAC_CHECK_ENFORCE
1259 /* 21167099 - only check if we allow write */
1260 if (!mac_vnode_enforce
)
1263 cred
= vfs_context_ucred(ctx
);
1264 if (!mac_cred_check_enforce(cred
))
1266 MAC_CHECK(vnode_check_ioctl
, cred
, vp
, vp
->v_label
, cmd
);
1271 mac_vnode_check_kqfilter(vfs_context_t ctx
, kauth_cred_t file_cred
,
1272 struct knote
*kn
, struct vnode
*vp
)
1277 #if SECURITY_MAC_CHECK_ENFORCE
1278 /* 21167099 - only check if we allow write */
1279 if (!mac_vnode_enforce
)
1282 cred
= vfs_context_ucred(ctx
);
1283 if (!mac_cred_check_enforce(cred
))
1285 MAC_CHECK(vnode_check_kqfilter
, cred
, file_cred
, kn
, vp
,
1292 mac_vnode_check_link(vfs_context_t ctx
, struct vnode
*dvp
,
1293 struct vnode
*vp
, struct componentname
*cnp
)
1298 #if SECURITY_MAC_CHECK_ENFORCE
1299 /* 21167099 - only check if we allow write */
1300 if (!mac_vnode_enforce
)
1303 cred
= vfs_context_ucred(ctx
);
1304 if (!mac_cred_check_enforce(cred
))
1306 MAC_CHECK(vnode_check_link
, cred
, dvp
, dvp
->v_label
, vp
,
1312 mac_vnode_check_listextattr(vfs_context_t ctx
, struct vnode
*vp
)
1317 #if SECURITY_MAC_CHECK_ENFORCE
1318 /* 21167099 - only check if we allow write */
1319 if (!mac_vnode_enforce
)
1322 cred
= vfs_context_ucred(ctx
);
1323 if (!mac_cred_check_enforce(cred
))
1325 MAC_CHECK(vnode_check_listextattr
, cred
, vp
, vp
->v_label
);
1330 mac_vnode_check_lookup_preflight(vfs_context_t ctx
, struct vnode
*dvp
,
1331 const char *path
, size_t pathlen
)
1336 #if SECURITY_MAC_CHECK_ENFORCE
1337 /* 21167099 - only check if we allow write */
1338 if (!mac_vnode_enforce
)
1341 cred
= vfs_context_ucred(ctx
);
1342 if (!mac_cred_check_enforce(cred
))
1344 MAC_CHECK(vnode_check_lookup_preflight
, cred
, dvp
, dvp
->v_label
, path
, pathlen
);
1349 mac_vnode_check_lookup(vfs_context_t ctx
, struct vnode
*dvp
,
1350 struct componentname
*cnp
)
1355 #if SECURITY_MAC_CHECK_ENFORCE
1356 /* 21167099 - only check if we allow write */
1357 if (!mac_vnode_enforce
)
1360 cred
= vfs_context_ucred(ctx
);
1361 if (!mac_cred_check_enforce(cred
))
1363 MAC_CHECK(vnode_check_lookup
, cred
, dvp
, dvp
->v_label
, cnp
);
1368 mac_vnode_check_open(vfs_context_t ctx
, struct vnode
*vp
, int acc_mode
)
1373 #if SECURITY_MAC_CHECK_ENFORCE
1374 /* 21167099 - only check if we allow write */
1375 if (!mac_vnode_enforce
)
1378 cred
= vfs_context_ucred(ctx
);
1379 if (!mac_cred_check_enforce(cred
))
1381 MAC_CHECK(vnode_check_open
, cred
, vp
, vp
->v_label
, acc_mode
);
1386 mac_vnode_check_read(vfs_context_t ctx
, struct ucred
*file_cred
,
1392 #if SECURITY_MAC_CHECK_ENFORCE
1393 /* 21167099 - only check if we allow write */
1394 if (!mac_vnode_enforce
)
1397 cred
= vfs_context_ucred(ctx
);
1398 if (!mac_cred_check_enforce(cred
))
1400 MAC_CHECK(vnode_check_read
, cred
, file_cred
, vp
,
1407 mac_vnode_check_readdir(vfs_context_t ctx
, struct vnode
*dvp
)
1412 #if SECURITY_MAC_CHECK_ENFORCE
1413 /* 21167099 - only check if we allow write */
1414 if (!mac_vnode_enforce
)
1417 cred
= vfs_context_ucred(ctx
);
1418 if (!mac_cred_check_enforce(cred
))
1420 MAC_CHECK(vnode_check_readdir
, cred
, dvp
, dvp
->v_label
);
1425 mac_vnode_check_readlink(vfs_context_t ctx
, struct vnode
*vp
)
1430 #if SECURITY_MAC_CHECK_ENFORCE
1431 /* 21167099 - only check if we allow write */
1432 if (!mac_vnode_enforce
)
1435 cred
= vfs_context_ucred(ctx
);
1436 if (!mac_cred_check_enforce(cred
))
1438 MAC_CHECK(vnode_check_readlink
, cred
, vp
, vp
->v_label
);
1443 mac_vnode_check_label_update(vfs_context_t ctx
, struct vnode
*vp
,
1444 struct label
*newlabel
)
1449 #if SECURITY_MAC_CHECK_ENFORCE
1450 /* 21167099 - only check if we allow write */
1451 if (!mac_vnode_enforce
)
1454 cred
= vfs_context_ucred(ctx
);
1455 if (!mac_cred_check_enforce(cred
))
1457 MAC_CHECK(vnode_check_label_update
, cred
, vp
, vp
->v_label
, newlabel
);
1463 mac_vnode_check_rename(vfs_context_t ctx
, struct vnode
*dvp
,
1464 struct vnode
*vp
, struct componentname
*cnp
, struct vnode
*tdvp
,
1465 struct vnode
*tvp
, struct componentname
*tcnp
)
1470 #if SECURITY_MAC_CHECK_ENFORCE
1471 /* 21167099 - only check if we allow write */
1472 if (!mac_vnode_enforce
)
1475 cred
= vfs_context_ucred(ctx
);
1476 if (!mac_cred_check_enforce(cred
))
1479 MAC_CHECK(vnode_check_rename_from
, cred
, dvp
, dvp
->v_label
, vp
,
1484 MAC_CHECK(vnode_check_rename_to
, cred
, tdvp
, tdvp
->v_label
, tvp
,
1485 tvp
!= NULL
? tvp
->v_label
: NULL
, dvp
== tdvp
, tcnp
);
1489 MAC_CHECK(vnode_check_rename
, cred
, dvp
, dvp
->v_label
, vp
,
1490 vp
->v_label
, cnp
, tdvp
, tdvp
->v_label
, tvp
,
1491 tvp
!= NULL
? tvp
->v_label
: NULL
, tcnp
);
1496 mac_vnode_check_revoke(vfs_context_t ctx
, struct vnode
*vp
)
1501 #if SECURITY_MAC_CHECK_ENFORCE
1502 /* 21167099 - only check if we allow write */
1503 if (!mac_vnode_enforce
)
1506 cred
= vfs_context_ucred(ctx
);
1507 if (!mac_cred_check_enforce(cred
))
1509 MAC_CHECK(vnode_check_revoke
, cred
, vp
, vp
->v_label
);
1514 mac_vnode_check_searchfs(vfs_context_t ctx
, struct vnode
*vp
, struct attrlist
*alist
)
1519 #if SECURITY_MAC_CHECK_ENFORCE
1520 /* 21167099 - only check if we allow write */
1521 if (!mac_vnode_enforce
)
1524 cred
= vfs_context_ucred(ctx
);
1525 if (!mac_cred_check_enforce(cred
))
1527 MAC_CHECK(vnode_check_searchfs
, cred
, vp
, vp
->v_label
, alist
);
1532 mac_vnode_check_select(vfs_context_t ctx
, struct vnode
*vp
, int which
)
1537 #if SECURITY_MAC_CHECK_ENFORCE
1538 /* 21167099 - only check if we allow write */
1539 if (!mac_vnode_enforce
)
1542 cred
= vfs_context_ucred(ctx
);
1543 if (!mac_cred_check_enforce(cred
))
1545 MAC_CHECK(vnode_check_select
, cred
, vp
, vp
->v_label
, which
);
1550 mac_vnode_check_setacl(vfs_context_t ctx
, struct vnode
*vp
,
1551 struct kauth_acl
*acl
)
1556 #if SECURITY_MAC_CHECK_ENFORCE
1557 /* 21167099 - only check if we allow write */
1558 if (!mac_vnode_enforce
)
1561 cred
= vfs_context_ucred(ctx
);
1562 if (!mac_cred_check_enforce(cred
))
1564 MAC_CHECK(vnode_check_setacl
, cred
, vp
, vp
->v_label
, acl
);
1569 mac_vnode_check_setattrlist(vfs_context_t ctx
, struct vnode
*vp
,
1570 struct attrlist
*alist
)
1575 #if SECURITY_MAC_CHECK_ENFORCE
1576 /* 21167099 - only check if we allow write */
1577 if (!mac_vnode_enforce
)
1580 cred
= vfs_context_ucred(ctx
);
1581 if (!mac_cred_check_enforce(cred
))
1583 MAC_CHECK(vnode_check_setattrlist
, cred
, vp
, vp
->v_label
, alist
);
1588 mac_vnode_check_setextattr(vfs_context_t ctx
, struct vnode
*vp
,
1589 const char *name
, struct uio
*uio
)
1594 #if SECURITY_MAC_CHECK_ENFORCE
1595 /* 21167099 - only check if we allow write */
1596 if (!mac_vnode_enforce
)
1599 cred
= vfs_context_ucred(ctx
);
1600 if (!mac_cred_check_enforce(cred
))
1602 MAC_CHECK(vnode_check_setextattr
, cred
, vp
, vp
->v_label
,
1608 mac_vnode_check_setflags(vfs_context_t ctx
, struct vnode
*vp
, u_long flags
)
1613 #if SECURITY_MAC_CHECK_ENFORCE
1614 /* 21167099 - only check if we allow write */
1615 if (!mac_vnode_enforce
)
1618 cred
= vfs_context_ucred(ctx
);
1619 if (!mac_cred_check_enforce(cred
))
1621 MAC_CHECK(vnode_check_setflags
, cred
, vp
, vp
->v_label
, flags
);
1626 mac_vnode_check_setmode(vfs_context_t ctx
, struct vnode
*vp
, mode_t mode
)
1631 #if SECURITY_MAC_CHECK_ENFORCE
1632 /* 21167099 - only check if we allow write */
1633 if (!mac_vnode_enforce
)
1636 cred
= vfs_context_ucred(ctx
);
1637 if (!mac_cred_check_enforce(cred
))
1639 MAC_CHECK(vnode_check_setmode
, cred
, vp
, vp
->v_label
, mode
);
1644 mac_vnode_check_setowner(vfs_context_t ctx
, struct vnode
*vp
, uid_t uid
,
1650 #if SECURITY_MAC_CHECK_ENFORCE
1651 /* 21167099 - only check if we allow write */
1652 if (!mac_vnode_enforce
)
1655 cred
= vfs_context_ucred(ctx
);
1656 if (!mac_cred_check_enforce(cred
))
1658 MAC_CHECK(vnode_check_setowner
, cred
, vp
, vp
->v_label
, uid
, gid
);
1663 mac_vnode_check_setutimes(vfs_context_t ctx
, struct vnode
*vp
,
1664 struct timespec atime
, struct timespec mtime
)
1669 #if SECURITY_MAC_CHECK_ENFORCE
1670 /* 21167099 - only check if we allow write */
1671 if (!mac_vnode_enforce
)
1674 cred
= vfs_context_ucred(ctx
);
1675 if (!mac_cred_check_enforce(cred
))
1677 MAC_CHECK(vnode_check_setutimes
, cred
, vp
, vp
->v_label
, atime
,
1683 mac_vnode_check_stat(vfs_context_t ctx
, struct ucred
*file_cred
,
1689 #if SECURITY_MAC_CHECK_ENFORCE
1690 /* 21167099 - only check if we allow write */
1691 if (!mac_vnode_enforce
)
1694 cred
= vfs_context_ucred(ctx
);
1695 if (!mac_cred_check_enforce(cred
))
1697 MAC_CHECK(vnode_check_stat
, cred
, file_cred
, vp
,
1703 mac_vnode_check_trigger_resolve(vfs_context_t ctx
, struct vnode
*dvp
,
1704 struct componentname
*cnp
)
1709 #if SECURITY_MAC_CHECK_ENFORCE
1710 /* 21167099 - only check if we allow write */
1711 if (!mac_vnode_enforce
)
1714 cred
= vfs_context_ucred(ctx
);
1715 if (!mac_cred_check_enforce(cred
))
1717 MAC_CHECK(vnode_check_trigger_resolve
, cred
, dvp
, dvp
->v_label
, cnp
);
1722 mac_vnode_check_truncate(vfs_context_t ctx
, struct ucred
*file_cred
,
1728 #if SECURITY_MAC_CHECK_ENFORCE
1729 /* 21167099 - only check if we allow write */
1730 if (!mac_vnode_enforce
)
1733 cred
= vfs_context_ucred(ctx
);
1734 if (!mac_cred_check_enforce(cred
))
1736 MAC_CHECK(vnode_check_truncate
, cred
, file_cred
, vp
,
1743 mac_vnode_check_write(vfs_context_t ctx
, struct ucred
*file_cred
,
1749 #if SECURITY_MAC_CHECK_ENFORCE
1750 /* 21167099 - only check if we allow write */
1751 if (!mac_vnode_enforce
)
1754 cred
= vfs_context_ucred(ctx
);
1755 if (!mac_cred_check_enforce(cred
))
1757 MAC_CHECK(vnode_check_write
, cred
, file_cred
, vp
, vp
->v_label
);
1763 mac_vnode_check_uipc_bind(vfs_context_t ctx
, struct vnode
*dvp
,
1764 struct componentname
*cnp
, struct vnode_attr
*vap
)
1769 #if SECURITY_MAC_CHECK_ENFORCE
1770 /* 21167099 - only check if we allow write */
1771 if (!mac_vnode_enforce
)
1774 cred
= vfs_context_ucred(ctx
);
1775 if (!mac_cred_check_enforce(cred
))
1777 MAC_CHECK(vnode_check_uipc_bind
, cred
, dvp
, dvp
->v_label
, cnp
, vap
);
1782 mac_vnode_check_uipc_connect(vfs_context_t ctx
, struct vnode
*vp
, struct socket
*so
)
1787 #if SECURITY_MAC_CHECK_ENFORCE
1788 /* 21167099 - only check if we allow write */
1789 if (!mac_vnode_enforce
)
1792 cred
= vfs_context_ucred(ctx
);
1793 if (!mac_cred_check_enforce(cred
))
1795 MAC_CHECK(vnode_check_uipc_connect
, cred
, vp
, vp
->v_label
, (socket_t
) so
);
1800 mac_vnode_label_update(vfs_context_t ctx
, struct vnode
*vp
, struct label
*newlabel
)
1802 kauth_cred_t cred
= vfs_context_ucred(ctx
);
1803 struct label
*tmpl
= NULL
;
1805 if (vp
->v_label
== NULL
)
1806 tmpl
= mac_vnode_label_alloc();
1810 /* recheck after lock */
1811 if (vp
->v_label
== NULL
) {
1816 MAC_PERFORM(vnode_label_update
, cred
, vp
, vp
->v_label
, newlabel
);
1820 mac_vnode_label_free(tmpl
);
1824 mac_vnode_find_sigs(struct proc
*p
, struct vnode
*vp
, off_t offset
)
1828 #if SECURITY_MAC_CHECK_ENFORCE
1829 /* 21167099 - only check if we allow write */
1830 if (!mac_proc_enforce
|| !mac_vnode_enforce
)
1834 MAC_CHECK(vnode_find_sigs
, p
, vp
, offset
, vp
->v_label
);
1840 mac_mount_label_associate(vfs_context_t ctx
, struct mount
*mp
)
1842 kauth_cred_t cred
= vfs_context_ucred(ctx
);
1844 /* XXX: eventually this logic may be handled by the policy? */
1846 /* We desire MULTILABEL for the root filesystem. */
1847 if ((mp
->mnt_flag
& MNT_ROOTFS
) &&
1848 (strcmp(mp
->mnt_vfsstat
.f_fstypename
, "hfs") == 0))
1849 mp
->mnt_flag
|= MNT_MULTILABEL
;
1851 /* MULTILABEL on DEVFS. */
1852 if (strcmp(mp
->mnt_vfsstat
.f_fstypename
, "devfs") == 0)
1853 mp
->mnt_flag
|= MNT_MULTILABEL
;
1855 /* MULTILABEL on FDESC pseudo-filesystem. */
1856 if (strcmp(mp
->mnt_vfsstat
.f_fstypename
, "fdesc") == 0)
1857 mp
->mnt_flag
|= MNT_MULTILABEL
;
1859 /* MULTILABEL on all NFS filesystems. */
1860 if (strcmp(mp
->mnt_vfsstat
.f_fstypename
, "nfs") == 0)
1861 mp
->mnt_flag
|= MNT_MULTILABEL
;
1863 /* MULTILABEL on all AFP filesystems. */
1864 if (strcmp(mp
->mnt_vfsstat
.f_fstypename
, "afpfs") == 0)
1865 mp
->mnt_flag
|= MNT_MULTILABEL
;
1867 if (mp
->mnt_vtable
!= NULL
) {
1868 /* Any filesystem that supports native XATTRs. */
1869 if ((mp
->mnt_vtable
->vfc_vfsflags
& VFC_VFSNATIVEXATTR
))
1870 mp
->mnt_flag
|= MNT_MULTILABEL
;
1872 /* Filesystem does not support multilabel. */
1873 if ((mp
->mnt_vtable
->vfc_vfsflags
& VFC_VFSNOMACLABEL
) &&
1874 (mp
->mnt_flag
& MNT_MULTILABEL
))
1875 mp
->mnt_flag
&= ~MNT_MULTILABEL
;
1878 MAC_PERFORM(mount_label_associate
, cred
, mp
, mp
->mnt_mntlabel
);
1880 printf("MAC Framework enabling %s support: %s -> %s (%s)\n",
1881 mp
->mnt_flag
& MNT_MULTILABEL
? "multilabel" : "singlelabel",
1882 mp
->mnt_vfsstat
.f_mntfromname
,
1883 mp
->mnt_vfsstat
.f_mntonname
,
1884 mp
->mnt_vfsstat
.f_fstypename
);
1889 mac_mount_check_mount(vfs_context_t ctx
, struct vnode
*vp
,
1890 struct componentname
*cnp
, const char *vfc_name
)
1895 #if SECURITY_MAC_CHECK_ENFORCE
1896 /* 21167099 - only check if we allow write */
1897 if (!mac_vnode_enforce
)
1900 cred
= vfs_context_ucred(ctx
);
1901 if (!mac_cred_check_enforce(cred
))
1903 MAC_CHECK(mount_check_mount
, cred
, vp
, vp
->v_label
, cnp
, vfc_name
);
1909 mac_mount_check_snapshot_create(vfs_context_t ctx
, struct mount
*mp
,
1915 #if SECURITY_MAC_CHECK_ENFORCE
1916 /* 21167099 - only check if we allow write */
1917 if (!mac_vnode_enforce
)
1920 cred
= vfs_context_ucred(ctx
);
1921 if (!mac_cred_check_enforce(cred
))
1923 MAC_CHECK(mount_check_snapshot_create
, cred
, mp
, name
);
1928 mac_mount_check_snapshot_delete(vfs_context_t ctx
, struct mount
*mp
,
1934 #if SECURITY_MAC_CHECK_ENFORCE
1935 /* 21167099 - only check if we allow write */
1936 if (!mac_vnode_enforce
)
1939 cred
= vfs_context_ucred(ctx
);
1940 if (!mac_cred_check_enforce(cred
))
1942 MAC_CHECK(mount_check_snapshot_delete
, cred
, mp
, name
);
1947 mac_mount_check_snapshot_revert(vfs_context_t ctx
, struct mount
*mp
,
1953 #if SECURITY_MAC_CHECK_ENFORCE
1954 /* 21167099 - only check if we allow write */
1955 if (!mac_vnode_enforce
)
1958 cred
= vfs_context_ucred(ctx
);
1959 if (!mac_cred_check_enforce(cred
))
1961 MAC_CHECK(mount_check_snapshot_revert
, cred
, mp
, name
);
1966 mac_mount_check_remount(vfs_context_t ctx
, struct mount
*mp
)
1971 #if SECURITY_MAC_CHECK_ENFORCE
1972 /* 21167099 - only check if we allow write */
1973 if (!mac_vnode_enforce
)
1976 cred
= vfs_context_ucred(ctx
);
1977 if (!mac_cred_check_enforce(cred
))
1979 MAC_CHECK(mount_check_remount
, cred
, mp
, mp
->mnt_mntlabel
);
1985 mac_mount_check_umount(vfs_context_t ctx
, struct mount
*mp
)
1990 #if SECURITY_MAC_CHECK_ENFORCE
1991 /* 21167099 - only check if we allow write */
1992 if (!mac_vnode_enforce
)
1995 cred
= vfs_context_ucred(ctx
);
1996 if (!mac_cred_check_enforce(cred
))
1998 MAC_CHECK(mount_check_umount
, cred
, mp
, mp
->mnt_mntlabel
);
2004 mac_mount_check_getattr(vfs_context_t ctx
, struct mount
*mp
,
2005 struct vfs_attr
*vfa
)
2010 #if SECURITY_MAC_CHECK_ENFORCE
2011 /* 21167099 - only check if we allow write */
2012 if (!mac_vnode_enforce
)
2015 cred
= vfs_context_ucred(ctx
);
2016 if (!mac_cred_check_enforce(cred
))
2018 MAC_CHECK(mount_check_getattr
, cred
, mp
, mp
->mnt_mntlabel
, vfa
);
2023 mac_mount_check_setattr(vfs_context_t ctx
, struct mount
*mp
,
2024 struct vfs_attr
*vfa
)
2029 #if SECURITY_MAC_CHECK_ENFORCE
2030 /* 21167099 - only check if we allow write */
2031 if (!mac_vnode_enforce
)
2034 cred
= vfs_context_ucred(ctx
);
2035 if (!mac_cred_check_enforce(cred
))
2037 MAC_CHECK(mount_check_setattr
, cred
, mp
, mp
->mnt_mntlabel
, vfa
);
2042 mac_mount_check_stat(vfs_context_t ctx
, struct mount
*mount
)
2047 #if SECURITY_MAC_CHECK_ENFORCE
2048 /* 21167099 - only check if we allow write */
2049 if (!mac_vnode_enforce
)
2052 cred
= vfs_context_ucred(ctx
);
2053 if (!mac_cred_check_enforce(cred
))
2055 MAC_CHECK(mount_check_stat
, cred
, mount
, mount
->mnt_mntlabel
);
2061 mac_mount_check_label_update(vfs_context_t ctx
, struct mount
*mount
)
2066 #if SECURITY_MAC_CHECK_ENFORCE
2067 /* 21167099 - only check if we allow write */
2068 if (!mac_vnode_enforce
)
2071 cred
= vfs_context_ucred(ctx
);
2072 if (!mac_cred_check_enforce(cred
))
2074 MAC_CHECK(mount_check_label_update
, cred
, mount
, mount
->mnt_mntlabel
);
2080 mac_mount_check_fsctl(vfs_context_t ctx
, struct mount
*mp
, u_int cmd
)
2085 #if SECURITY_MAC_CHECK_ENFORCE
2086 /* 21167099 - only check if we allow write */
2087 if (!mac_vnode_enforce
)
2090 cred
= vfs_context_ucred(ctx
);
2091 if (!mac_cred_check_enforce(cred
))
2093 MAC_CHECK(mount_check_fsctl
, cred
, mp
, mp
->mnt_mntlabel
, cmd
);
2099 mac_devfs_label_associate_device(dev_t dev
, struct devnode
*de
,
2100 const char *fullpath
)
2102 #if SECURITY_MAC_CHECK_ENFORCE
2103 /* 21167099 - only check if we allow write */
2104 if (!mac_device_enforce
)
2108 MAC_PERFORM(devfs_label_associate_device
, dev
, de
, de
->dn_label
,
2113 mac_devfs_label_associate_directory(const char *dirname
, int dirnamelen
,
2114 struct devnode
*de
, const char *fullpath
)
2116 #if SECURITY_MAC_CHECK_ENFORCE
2117 /* 21167099 - only check if we allow write */
2118 if (!mac_device_enforce
)
2122 MAC_PERFORM(devfs_label_associate_directory
, dirname
, dirnamelen
, de
,
2123 de
->dn_label
, fullpath
);
2127 vn_setlabel(struct vnode
*vp
, struct label
*intlabel
, vfs_context_t context
)
2131 #if SECURITY_MAC_CHECK_ENFORCE
2132 /* 21167099 - only check if we allow write */
2133 if (!mac_vnode_enforce
)
2136 if (!mac_label_vnodes
)
2139 if (vp
->v_mount
== NULL
) {
2140 printf("vn_setlabel: null v_mount\n");
2141 if (vp
->v_type
!= VNON
)
2142 printf("vn_setlabel: null v_mount with non-VNON\n");
2146 if ((vp
->v_mount
->mnt_flag
& MNT_MULTILABEL
) == 0)
2150 * Multi-phase commit. First check the policies to confirm the
2151 * change is OK. Then commit via the filesystem. Finally,
2152 * update the actual vnode label. Question: maybe the filesystem
2153 * should update the vnode at the end as part of VNOP_SETLABEL()?
2155 error
= mac_vnode_check_label_update(context
, vp
, intlabel
);
2159 error
= VNOP_SETLABEL(vp
, intlabel
, context
);
2160 if (error
== ENOTSUP
) {
2161 error
= mac_vnode_label_store(context
, vp
,
2164 printf("%s: mac_vnode_label_store failed %d\n",
2168 mac_vnode_label_update(context
, vp
, intlabel
);
2171 printf("vn_setlabel: vop setlabel failed %d\n", error
);
2179 mac_vnode_label_associate_fdesc(struct mount
*mp
, struct fdescnode
*fnp
,
2180 struct vnode
*vp
, vfs_context_t ctx
)
2182 struct fileproc
*fp
;
2183 #if CONFIG_MACF_SOCKET_SUBSET
2194 * If no backing file, let the policy choose which label to use.
2196 if (fnp
->fd_fd
== -1) {
2197 MAC_PERFORM(vnode_label_associate_file
, vfs_context_ucred(ctx
),
2198 mp
, mp
->mnt_mntlabel
, NULL
, NULL
, vp
, vp
->v_label
);
2202 p
= vfs_context_proc(ctx
);
2203 error
= fp_lookup(p
, fnp
->fd_fd
, &fp
, 0);
2207 if (fp
->f_fglob
== NULL
) {
2212 switch (FILEGLOB_DTYPE(fp
->f_fglob
)) {
2214 fvp
= (struct vnode
*)fp
->f_fglob
->fg_data
;
2215 if ((error
= vnode_getwithref(fvp
)))
2217 MAC_PERFORM(vnode_label_copy
, fvp
->v_label
, vp
->v_label
);
2218 (void)vnode_put(fvp
);
2220 #if CONFIG_MACF_SOCKET_SUBSET
2222 so
= (struct socket
*)fp
->f_fglob
->fg_data
;
2224 MAC_PERFORM(vnode_label_associate_socket
,
2225 vfs_context_ucred(ctx
), (socket_t
)so
, so
->so_label
,
2227 socket_unlock(so
, 1);
2231 pshm_label_associate(fp
, vp
, ctx
);
2234 psem_label_associate(fp
, vp
, ctx
);
2237 cpipe
= (struct pipe
*)fp
->f_fglob
->fg_data
;
2238 /* kern/sys_pipe.c:pipe_select() suggests this test. */
2239 if (cpipe
== (struct pipe
*)-1) {
2244 MAC_PERFORM(vnode_label_associate_pipe
, vfs_context_ucred(ctx
),
2245 cpipe
, cpipe
->pipe_label
, vp
, vp
->v_label
);
2249 case DTYPE_FSEVENTS
:
2251 case DTYPE_NETPOLICY
:
2253 MAC_PERFORM(vnode_label_associate_file
, vfs_context_ucred(ctx
),
2254 mp
, mp
->mnt_mntlabel
, fp
->f_fglob
, fp
->f_fglob
->fg_label
,
2259 fp_drop(p
, fnp
->fd_fd
, fp
, 0);