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 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
395 cred
= vfs_context_ucred(ctx
);
396 MAC_CHECK(vnode_notify_create
, cred
, mp
, mp
->mnt_mntlabel
,
397 dvp
, dvp
->v_label
, vp
, vp
->v_label
, cnp
);
403 mac_vnode_notify_rename(vfs_context_t ctx
, struct vnode
*vp
,
404 struct vnode
*dvp
, struct componentname
*cnp
)
408 #if SECURITY_MAC_CHECK_ENFORCE
409 /* 21167099 - only check if we allow write */
410 if (!mac_vnode_enforce
)
413 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
416 cred
= vfs_context_ucred(ctx
);
417 MAC_PERFORM(vnode_notify_rename
, cred
, vp
, vp
->v_label
,
418 dvp
, dvp
->v_label
, cnp
);
422 mac_vnode_notify_open(vfs_context_t ctx
, struct vnode
*vp
, int acc_flags
)
426 #if SECURITY_MAC_CHECK_ENFORCE
427 /* 21167099 - only check if we allow write */
428 if (!mac_vnode_enforce
)
431 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
434 cred
= vfs_context_ucred(ctx
);
435 MAC_PERFORM(vnode_notify_open
, cred
, vp
, vp
->v_label
, acc_flags
);
439 mac_vnode_notify_link(vfs_context_t ctx
, struct vnode
*vp
,
440 struct vnode
*dvp
, struct componentname
*cnp
)
444 #if SECURITY_MAC_CHECK_ENFORCE
445 /* 21167099 - only check if we allow write */
446 if (!mac_vnode_enforce
)
449 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
452 cred
= vfs_context_ucred(ctx
);
453 MAC_PERFORM(vnode_notify_link
, cred
, dvp
, dvp
->v_label
, vp
, vp
->v_label
, cnp
);
457 mac_vnode_notify_deleteextattr(vfs_context_t ctx
, struct vnode
*vp
, const char *name
)
461 #if SECURITY_MAC_CHECK_ENFORCE
462 /* 21167099 - only check if we allow write */
463 if (!mac_vnode_enforce
)
466 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
469 cred
= vfs_context_ucred(ctx
);
470 MAC_PERFORM(vnode_notify_deleteextattr
, cred
, vp
, vp
->v_label
, name
);
474 mac_vnode_notify_setacl(vfs_context_t ctx
, struct vnode
*vp
, struct kauth_acl
*acl
)
478 #if SECURITY_MAC_CHECK_ENFORCE
479 /* 21167099 - only check if we allow write */
480 if (!mac_vnode_enforce
)
483 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
486 cred
= vfs_context_ucred(ctx
);
487 MAC_PERFORM(vnode_notify_setacl
, cred
, vp
, vp
->v_label
, acl
);
491 mac_vnode_notify_setattrlist(vfs_context_t ctx
, struct vnode
*vp
, struct attrlist
*alist
)
495 #if SECURITY_MAC_CHECK_ENFORCE
496 /* 21167099 - only check if we allow write */
497 if (!mac_vnode_enforce
)
500 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
503 cred
= vfs_context_ucred(ctx
);
504 MAC_PERFORM(vnode_notify_setattrlist
, cred
, vp
, vp
->v_label
, alist
);
508 mac_vnode_notify_setextattr(vfs_context_t ctx
, struct vnode
*vp
, const char *name
, struct uio
*uio
)
512 #if SECURITY_MAC_CHECK_ENFORCE
513 /* 21167099 - only check if we allow write */
514 if (!mac_vnode_enforce
)
517 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
520 cred
= vfs_context_ucred(ctx
);
521 MAC_PERFORM(vnode_notify_setextattr
, cred
, vp
, vp
->v_label
, name
, uio
);
525 mac_vnode_notify_setflags(vfs_context_t ctx
, struct vnode
*vp
, u_long flags
)
529 #if SECURITY_MAC_CHECK_ENFORCE
530 /* 21167099 - only check if we allow write */
531 if (!mac_vnode_enforce
)
534 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
537 cred
= vfs_context_ucred(ctx
);
538 MAC_PERFORM(vnode_notify_setflags
, cred
, vp
, vp
->v_label
, flags
);
542 mac_vnode_notify_setmode(vfs_context_t ctx
, struct vnode
*vp
, mode_t mode
)
546 #if SECURITY_MAC_CHECK_ENFORCE
547 /* 21167099 - only check if we allow write */
548 if (!mac_vnode_enforce
)
551 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
554 cred
= vfs_context_ucred(ctx
);
555 MAC_PERFORM(vnode_notify_setmode
, cred
, vp
, vp
->v_label
, mode
);
559 mac_vnode_notify_setowner(vfs_context_t ctx
, struct vnode
*vp
, uid_t uid
, gid_t gid
)
563 #if SECURITY_MAC_CHECK_ENFORCE
564 /* 21167099 - only check if we allow write */
565 if (!mac_vnode_enforce
)
568 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
571 cred
= vfs_context_ucred(ctx
);
572 MAC_PERFORM(vnode_notify_setowner
, cred
, vp
, vp
->v_label
, uid
, gid
);
576 mac_vnode_notify_setutimes(vfs_context_t ctx
, struct vnode
*vp
, struct timespec atime
, struct timespec mtime
)
580 #if SECURITY_MAC_CHECK_ENFORCE
581 /* 21167099 - only check if we allow write */
582 if (!mac_vnode_enforce
)
585 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
588 cred
= vfs_context_ucred(ctx
);
589 MAC_PERFORM(vnode_notify_setutimes
, cred
, vp
, vp
->v_label
, atime
, mtime
);
593 mac_vnode_notify_truncate(vfs_context_t ctx
, kauth_cred_t file_cred
, struct vnode
*vp
)
597 #if SECURITY_MAC_CHECK_ENFORCE
598 /* 21167099 - only check if we allow write */
599 if (!mac_vnode_enforce
)
602 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
605 cred
= vfs_context_ucred(ctx
);
606 MAC_PERFORM(vnode_notify_truncate
, cred
, file_cred
, vp
, vp
->v_label
);
610 * Extended attribute 'name' was updated via
611 * vn_setxattr() or vn_removexattr(). Allow the
612 * policy to update the vnode label.
615 mac_vnode_label_update_extattr(struct mount
*mp
, struct vnode
*vp
,
620 #if SECURITY_MAC_CHECK_ENFORCE
621 /* 21167099 - only check if we allow write */
622 if (!mac_vnode_enforce
)
625 if (!mac_label_vnodes
)
628 MAC_PERFORM(vnode_label_update_extattr
, mp
, mp
->mnt_mntlabel
, vp
,
640 mac_vnode_label_store(vfs_context_t ctx
, struct vnode
*vp
,
641 struct label
*intlabel
)
646 #if SECURITY_MAC_CHECK_ENFORCE
647 /* 21167099 - only check if we allow write */
648 if (!mac_vnode_enforce
)
651 if (!mac_label_vnodes
||
652 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
655 cred
= vfs_context_ucred(ctx
);
656 MAC_CHECK(vnode_label_store
, cred
, vp
, vp
->v_label
, intlabel
);
662 mac_cred_label_update_execve(vfs_context_t ctx
, kauth_cred_t
new, struct vnode
*vp
, off_t offset
,
663 struct vnode
*scriptvp
, struct label
*scriptvnodelabel
, struct label
*execl
, u_int
*csflags
,
664 void *macextensions
, int *disjoint
, int *labelupdateerror
)
669 posix_cred_t pcred
= posix_cred_get(new);
671 #if SECURITY_MAC_CHECK_ENFORCE
672 /* 21167099 - only check if we allow write */
673 if (!mac_proc_enforce
|| !mac_vnode_enforce
)
677 /* mark the new cred to indicate "matching" includes the label */
678 pcred
->cr_flags
|= CRF_MAC_ENFORCE
;
680 cred
= vfs_context_ucred(ctx
);
683 * NB: Cannot use MAC_CHECK macro because we need a sequence point after
684 * calling exec_spawnattr_getmacpolicyinfo() and before passing the
685 * spawnattrlen as an argument to the hook.
688 struct mac_policy_conf
*mpc
;
692 for (i
= 0; i
< mac_policy_list
.staticmax
; i
++) {
693 mpc
= mac_policy_list
.entries
[i
].mpc
;
697 mpo_cred_label_update_execve_t
*hook
= mpc
->mpc_ops
->mpo_cred_label_update_execve
;
701 size_t spawnattrlen
= 0;
702 void *spawnattr
= exec_spawnattr_getmacpolicyinfo(macextensions
, mpc
->mpc_name
, &spawnattrlen
);
704 error
= mac_error_select(hook(cred
, new, vfs_context_proc(ctx
), vp
, offset
, scriptvp
,
705 vp
->v_label
, scriptvnodelabel
, execl
, csflags
, spawnattr
, spawnattrlen
, disjoint
),
708 if (mac_policy_list_conditional_busy() != 0) {
709 for (; i
<= mac_policy_list
.maxindex
; i
++) {
710 mpc
= mac_policy_list
.entries
[i
].mpc
;
714 mpo_cred_label_update_execve_t
*hook
= mpc
->mpc_ops
->mpo_cred_label_update_execve
;
718 size_t spawnattrlen
= 0;
719 void *spawnattr
= exec_spawnattr_getmacpolicyinfo(macextensions
, mpc
->mpc_name
, &spawnattrlen
);
721 error
= mac_error_select(hook(cred
, new, vfs_context_proc(ctx
), vp
, offset
, scriptvp
,
722 vp
->v_label
, scriptvnodelabel
, execl
, csflags
, spawnattr
, spawnattrlen
, disjoint
),
725 mac_policy_list_unbusy();
728 *labelupdateerror
= error
;
732 mac_cred_check_label_update_execve(vfs_context_t ctx
, struct vnode
*vp
, off_t offset
,
733 struct vnode
*scriptvp
, struct label
*scriptvnodelabel
, struct label
*execlabel
,
734 struct proc
*p
, void *macextensions
)
739 #if SECURITY_MAC_CHECK_ENFORCE
740 /* 21167099 - only check if we allow write */
741 if (!mac_proc_enforce
|| !mac_vnode_enforce
)
745 cred
= vfs_context_ucred(ctx
);
748 * NB: Cannot use MAC_BOOLEAN macro because we need a sequence point after
749 * calling exec_spawnattr_getmacpolicyinfo() and before passing the
750 * spawnattrlen as an argument to the hook.
753 struct mac_policy_conf
*mpc
;
756 for (i
= 0; i
< mac_policy_list
.staticmax
; i
++) {
757 mpc
= mac_policy_list
.entries
[i
].mpc
;
761 mpo_cred_check_label_update_execve_t
*hook
= mpc
->mpc_ops
->mpo_cred_check_label_update_execve
;
765 size_t spawnattrlen
= 0;
766 void *spawnattr
= exec_spawnattr_getmacpolicyinfo(macextensions
, mpc
->mpc_name
, &spawnattrlen
);
768 result
= result
|| hook(cred
, vp
, offset
, scriptvp
, vp
->v_label
, scriptvnodelabel
, execlabel
, p
, spawnattr
, spawnattrlen
);
770 if (mac_policy_list_conditional_busy() != 0) {
771 for (; i
<= mac_policy_list
.maxindex
; i
++) {
772 mpc
= mac_policy_list
.entries
[i
].mpc
;
776 mpo_cred_check_label_update_execve_t
*hook
= mpc
->mpc_ops
->mpo_cred_check_label_update_execve
;
780 size_t spawnattrlen
= 0;
781 void *spawnattr
= exec_spawnattr_getmacpolicyinfo(macextensions
, mpc
->mpc_name
, &spawnattrlen
);
783 result
= result
|| hook(cred
, vp
, offset
, scriptvp
, vp
->v_label
, scriptvnodelabel
, execlabel
, p
, spawnattr
, spawnattrlen
);
785 mac_policy_list_unbusy();
793 mac_vnode_check_access(vfs_context_t ctx
, struct vnode
*vp
,
800 #if SECURITY_MAC_CHECK_ENFORCE
801 /* 21167099 - only check if we allow write */
802 if (!mac_vnode_enforce
)
805 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
808 cred
= vfs_context_ucred(ctx
);
809 /* Convert {R,W,X}_OK values to V{READ,WRITE,EXEC} for entry points */
810 mask
= ACCESS_MODE_TO_VNODE_MASK(acc_mode
);
811 MAC_CHECK(vnode_check_access
, cred
, vp
, vp
->v_label
, mask
);
816 mac_vnode_check_chdir(vfs_context_t ctx
, struct vnode
*dvp
)
821 #if SECURITY_MAC_CHECK_ENFORCE
822 /* 21167099 - only check if we allow write */
823 if (!mac_vnode_enforce
)
826 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
829 cred
= vfs_context_ucred(ctx
);
830 MAC_CHECK(vnode_check_chdir
, cred
, dvp
, dvp
->v_label
);
835 mac_vnode_check_chroot(vfs_context_t ctx
, struct vnode
*dvp
,
836 struct componentname
*cnp
)
841 #if SECURITY_MAC_CHECK_ENFORCE
842 /* 21167099 - only check if we allow write */
843 if (!mac_vnode_enforce
)
846 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
849 cred
= vfs_context_ucred(ctx
);
850 MAC_CHECK(vnode_check_chroot
, cred
, dvp
, dvp
->v_label
, cnp
);
855 mac_vnode_check_clone(vfs_context_t ctx
, struct vnode
*dvp
,
856 struct vnode
*vp
, struct componentname
*cnp
)
861 #if SECURITY_MAC_CHECK_ENFORCE
862 /* 21167099 - only check if we allow write */
863 if (!mac_vnode_enforce
)
866 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
869 cred
= vfs_context_ucred(ctx
);
870 MAC_CHECK(vnode_check_clone
, cred
, dvp
, dvp
->v_label
, vp
,
875 mac_vnode_check_create(vfs_context_t ctx
, struct vnode
*dvp
,
876 struct componentname
*cnp
, struct vnode_attr
*vap
)
881 #if SECURITY_MAC_CHECK_ENFORCE
882 /* 21167099 - only check if we allow write */
883 if (!mac_vnode_enforce
)
886 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
889 cred
= vfs_context_ucred(ctx
);
890 MAC_CHECK(vnode_check_create
, cred
, dvp
, dvp
->v_label
, cnp
, vap
);
895 mac_vnode_check_unlink(vfs_context_t ctx
, struct vnode
*dvp
, struct vnode
*vp
,
896 struct componentname
*cnp
)
901 #if SECURITY_MAC_CHECK_ENFORCE
902 /* 21167099 - only check if we allow write */
903 if (!mac_vnode_enforce
)
906 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
909 cred
= vfs_context_ucred(ctx
);
910 MAC_CHECK(vnode_check_unlink
, cred
, dvp
, dvp
->v_label
, vp
,
916 mac_vnode_check_deleteacl(vfs_context_t ctx
, struct vnode
*vp
,
922 #if SECURITY_MAC_CHECK_ENFORCE
923 /* 21167099 - only check if we allow write */
924 if (!mac_vnode_enforce
)
927 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
930 cred
= vfs_context_ucred(ctx
);
931 MAC_CHECK(vnode_check_deleteacl
, cred
, vp
, vp
->v_label
, type
);
937 mac_vnode_check_deleteextattr(vfs_context_t ctx
, struct vnode
*vp
,
943 #if SECURITY_MAC_CHECK_ENFORCE
944 /* 21167099 - only check if we allow write */
945 if (!mac_vnode_enforce
)
948 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
951 cred
= vfs_context_ucred(ctx
);
952 MAC_CHECK(vnode_check_deleteextattr
, cred
, vp
, vp
->v_label
, name
);
956 mac_vnode_check_exchangedata(vfs_context_t ctx
,
957 struct vnode
*v1
, struct vnode
*v2
)
962 #if SECURITY_MAC_CHECK_ENFORCE
963 /* 21167099 - only check if we allow write */
964 if (!mac_vnode_enforce
)
967 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
970 cred
= vfs_context_ucred(ctx
);
971 MAC_CHECK(vnode_check_exchangedata
, cred
, v1
, v1
->v_label
,
979 mac_vnode_check_getacl(vfs_context_t ctx
, struct vnode
*vp
, acl_type_t type
)
984 #if SECURITY_MAC_CHECK_ENFORCE
985 /* 21167099 - only check if we allow write */
986 if (!mac_vnode_enforce
)
989 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
992 cred
= vfs_context_ucred(ctx
);
993 MAC_CHECK(vnode_check_getacl
, cred
, vp
, vp
->v_label
, type
);
999 mac_vnode_check_getattr(vfs_context_t ctx
, struct ucred
*file_cred
,
1000 struct vnode
*vp
, struct vnode_attr
*va
)
1005 #if SECURITY_MAC_CHECK_ENFORCE
1006 /* 21167099 - only check if we allow write */
1007 if (!mac_vnode_enforce
)
1010 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1013 cred
= vfs_context_ucred(ctx
);
1014 MAC_CHECK(vnode_check_getattr
, cred
, file_cred
, vp
, vp
->v_label
, va
);
1019 mac_vnode_check_getattrlist(vfs_context_t ctx
, struct vnode
*vp
,
1020 struct attrlist
*alist
)
1025 #if SECURITY_MAC_CHECK_ENFORCE
1026 /* 21167099 - only check if we allow write */
1027 if (!mac_vnode_enforce
)
1030 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1033 cred
= vfs_context_ucred(ctx
);
1034 MAC_CHECK(vnode_check_getattrlist
, cred
, vp
, vp
->v_label
, alist
);
1036 /* Falsify results instead of returning error? */
1041 mac_vnode_check_exec(vfs_context_t ctx
, struct vnode
*vp
,
1042 struct image_params
*imgp
)
1047 #if SECURITY_MAC_CHECK_ENFORCE
1048 /* 21167099 - only check if we allow write */
1049 if (!mac_proc_enforce
|| !mac_vnode_enforce
)
1053 cred
= vfs_context_ucred(ctx
);
1056 * NB: Cannot use MAC_CHECK macro because we need a sequence point after
1057 * calling exec_spawnattr_getmacpolicyinfo() and before passing the
1058 * spawnattrlen as an argument to the hook.
1061 struct mac_policy_conf
*mpc
;
1064 for (i
= 0; i
< mac_policy_list
.staticmax
; i
++) {
1065 mpc
= mac_policy_list
.entries
[i
].mpc
;
1069 mpo_vnode_check_exec_t
*hook
= mpc
->mpc_ops
->mpo_vnode_check_exec
;
1073 size_t spawnattrlen
= 0;
1074 void *spawnattr
= exec_spawnattr_getmacpolicyinfo(imgp
->ip_px_smpx
, mpc
->mpc_name
, &spawnattrlen
);
1076 error
= mac_error_select(
1078 vp
, imgp
->ip_scriptvp
, vp
->v_label
, imgp
->ip_scriptlabelp
,
1079 imgp
->ip_execlabelp
, &imgp
->ip_ndp
->ni_cnd
, &imgp
->ip_csflags
,
1080 spawnattr
, spawnattrlen
), error
);
1082 if (mac_policy_list_conditional_busy() != 0) {
1083 for (; i
<= mac_policy_list
.maxindex
; i
++) {
1084 mpc
= mac_policy_list
.entries
[i
].mpc
;
1088 mpo_vnode_check_exec_t
*hook
= mpc
->mpc_ops
->mpo_vnode_check_exec
;
1092 size_t spawnattrlen
= 0;
1093 void *spawnattr
= exec_spawnattr_getmacpolicyinfo(imgp
->ip_px_smpx
, mpc
->mpc_name
, &spawnattrlen
);
1095 error
= mac_error_select(
1097 vp
, imgp
->ip_scriptvp
, vp
->v_label
, imgp
->ip_scriptlabelp
,
1098 imgp
->ip_execlabelp
, &imgp
->ip_ndp
->ni_cnd
, &imgp
->ip_csflags
,
1099 spawnattr
, spawnattrlen
), error
);
1101 mac_policy_list_unbusy();
1109 mac_vnode_check_fsgetpath(vfs_context_t ctx
, struct vnode
*vp
)
1114 #if SECURITY_MAC_CHECK_ENFORCE
1115 /* 21167099 - only check if we allow write */
1116 if (!mac_vnode_enforce
)
1119 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1122 cred
= vfs_context_ucred(ctx
);
1123 MAC_CHECK(vnode_check_fsgetpath
, cred
, vp
, vp
->v_label
);
1128 mac_vnode_check_signature(struct vnode
*vp
, struct cs_blob
*cs_blob
,
1129 struct image_params
*imgp
,
1130 unsigned int *cs_flags
, int flags
)
1133 char *fatal_failure_desc
= NULL
;
1134 size_t fatal_failure_desc_len
= 0;
1136 char *vn_path
= NULL
;
1137 vm_size_t vn_pathlen
= MAXPATHLEN
;
1140 #if SECURITY_MAC_CHECK_ENFORCE
1141 /* 21167099 - only check if we allow write */
1142 if (!mac_proc_enforce
|| !mac_vnode_enforce
)
1146 MAC_CHECK(vnode_check_signature
, vp
, vp
->v_label
, cs_blob
,
1147 cs_flags
, flags
, &fatal_failure_desc
, &fatal_failure_desc_len
);
1149 if (fatal_failure_desc_len
) {
1150 // A fatal code signature validation failure occured, formulate a crash
1153 char const *path
= NULL
;
1155 vn_path
= (char *)kalloc(MAXPATHLEN
);
1156 if (vn_path
!= NULL
) {
1157 if (vn_getpath(vp
, vn_path
, (int*)&vn_pathlen
) == 0) {
1160 path
= "(get vnode path failed)";
1163 path
= "(path alloc failed)";
1167 panic("mac_vnode_check_signature: MAC hook returned no error, "
1168 "but status is claimed to be fatal? "
1169 "path: '%s', fatal_failure_desc_len: %ld, fatal_failure_desc:\n%s\n",
1170 path
, fatal_failure_desc_len
, fatal_failure_desc
);
1173 printf("mac_vnode_check_signature: %s: code signature validation failed fatally: %s",
1174 path
, fatal_failure_desc
);
1180 os_reason_t reason
= os_reason_create(OS_REASON_CODESIGNING
,
1181 CODESIGNING_EXIT_REASON_TASKGATED_INVALID_SIG
);
1183 if (reason
== OS_REASON_NULL
) {
1184 printf("mac_vnode_check_signature: %s: failure to allocate exit reason for validation failure: %s\n",
1185 path
, fatal_failure_desc
);
1189 imgp
->ip_cs_error
= reason
;
1190 reason
->osr_flags
= (OS_REASON_FLAG_GENERATE_CRASH_REPORT
|
1191 OS_REASON_FLAG_CONSISTENT_FAILURE
);
1193 if (fatal_failure_desc
== NULL
) {
1194 // This may happen if allocation for the buffer failed.
1195 printf("mac_vnode_check_signature: %s: fatal failure is missing its description.\n", path
);
1197 mach_vm_address_t data_addr
= 0;
1199 int reason_error
= 0;
1200 int kcdata_error
= 0;
1202 if ((reason_error
= os_reason_alloc_buffer(reason
, kcdata_estimate_required_buffer_size
1203 (1, fatal_failure_desc_len
))) == 0 &&
1204 (kcdata_error
= kcdata_get_memory_addr(&reason
->osr_kcd_descriptor
,
1205 EXIT_REASON_USER_DESC
, fatal_failure_desc_len
,
1206 &data_addr
)) == KERN_SUCCESS
) {
1207 kern_return_t mc_error
= kcdata_memcpy(&reason
->osr_kcd_descriptor
, (mach_vm_address_t
)data_addr
,
1208 fatal_failure_desc
, fatal_failure_desc_len
);
1210 if (mc_error
!= KERN_SUCCESS
) {
1211 printf("mac_vnode_check_signature: %s: failed to copy reason string "
1212 "(kcdata_memcpy error: %d, length: %ld)\n",
1213 path
, mc_error
, fatal_failure_desc_len
);
1216 printf("mac_vnode_check_signature: %s: failed to allocate space for reason string "
1217 "(os_reason_alloc_buffer error: %d, kcdata error: %d, length: %ld)\n",
1218 path
, reason_error
, kcdata_error
, fatal_failure_desc_len
);
1226 kfree(vn_path
, MAXPATHLEN
);
1229 if (fatal_failure_desc_len
> 0 && fatal_failure_desc
!= NULL
) {
1230 kfree(fatal_failure_desc
, fatal_failure_desc_len
);
1238 mac_vnode_check_getacl(vfs_context_t ctx
, struct vnode
*vp
, acl_type_t type
)
1243 #if SECURITY_MAC_CHECK_ENFORCE
1244 /* 21167099 - only check if we allow write */
1245 if (!mac_vnode_enforce
)
1248 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1251 cred
= vfs_context_ucred(ctx
);
1252 MAC_CHECK(vnode_check_getacl
, cred
, vp
, vp
->v_label
, type
);
1258 mac_vnode_check_getextattr(vfs_context_t ctx
, struct vnode
*vp
,
1259 const char *name
, struct uio
*uio
)
1264 #if SECURITY_MAC_CHECK_ENFORCE
1265 /* 21167099 - only check if we allow write */
1266 if (!mac_vnode_enforce
)
1269 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1272 cred
= vfs_context_ucred(ctx
);
1273 MAC_CHECK(vnode_check_getextattr
, cred
, vp
, vp
->v_label
,
1279 mac_vnode_check_ioctl(vfs_context_t ctx
, struct vnode
*vp
, u_int cmd
)
1284 #if SECURITY_MAC_CHECK_ENFORCE
1285 /* 21167099 - only check if we allow write */
1286 if (!mac_vnode_enforce
)
1289 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1292 cred
= vfs_context_ucred(ctx
);
1293 MAC_CHECK(vnode_check_ioctl
, cred
, vp
, vp
->v_label
, cmd
);
1298 mac_vnode_check_kqfilter(vfs_context_t ctx
, kauth_cred_t file_cred
,
1299 struct knote
*kn
, struct vnode
*vp
)
1304 #if SECURITY_MAC_CHECK_ENFORCE
1305 /* 21167099 - only check if we allow write */
1306 if (!mac_vnode_enforce
)
1309 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1312 cred
= vfs_context_ucred(ctx
);
1313 MAC_CHECK(vnode_check_kqfilter
, cred
, file_cred
, kn
, vp
,
1320 mac_vnode_check_link(vfs_context_t ctx
, struct vnode
*dvp
,
1321 struct vnode
*vp
, struct componentname
*cnp
)
1326 #if SECURITY_MAC_CHECK_ENFORCE
1327 /* 21167099 - only check if we allow write */
1328 if (!mac_vnode_enforce
)
1331 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1334 cred
= vfs_context_ucred(ctx
);
1335 MAC_CHECK(vnode_check_link
, cred
, dvp
, dvp
->v_label
, vp
,
1341 mac_vnode_check_listextattr(vfs_context_t ctx
, struct vnode
*vp
)
1346 #if SECURITY_MAC_CHECK_ENFORCE
1347 /* 21167099 - only check if we allow write */
1348 if (!mac_vnode_enforce
)
1351 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1354 cred
= vfs_context_ucred(ctx
);
1355 MAC_CHECK(vnode_check_listextattr
, cred
, vp
, vp
->v_label
);
1360 mac_vnode_check_lookup(vfs_context_t ctx
, struct vnode
*dvp
,
1361 struct componentname
*cnp
)
1366 #if SECURITY_MAC_CHECK_ENFORCE
1367 /* 21167099 - only check if we allow write */
1368 if (!mac_vnode_enforce
)
1371 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1374 cred
= vfs_context_ucred(ctx
);
1375 MAC_CHECK(vnode_check_lookup
, cred
, dvp
, dvp
->v_label
, cnp
);
1380 mac_vnode_check_open(vfs_context_t ctx
, struct vnode
*vp
, int acc_mode
)
1385 #if SECURITY_MAC_CHECK_ENFORCE
1386 /* 21167099 - only check if we allow write */
1387 if (!mac_vnode_enforce
)
1390 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1393 cred
= vfs_context_ucred(ctx
);
1394 MAC_CHECK(vnode_check_open
, cred
, vp
, vp
->v_label
, acc_mode
);
1399 mac_vnode_check_read(vfs_context_t ctx
, struct ucred
*file_cred
,
1405 #if SECURITY_MAC_CHECK_ENFORCE
1406 /* 21167099 - only check if we allow write */
1407 if (!mac_vnode_enforce
)
1410 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1413 cred
= vfs_context_ucred(ctx
);
1414 MAC_CHECK(vnode_check_read
, cred
, file_cred
, vp
,
1421 mac_vnode_check_readdir(vfs_context_t ctx
, struct vnode
*dvp
)
1426 #if SECURITY_MAC_CHECK_ENFORCE
1427 /* 21167099 - only check if we allow write */
1428 if (!mac_vnode_enforce
)
1431 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1434 cred
= vfs_context_ucred(ctx
);
1435 MAC_CHECK(vnode_check_readdir
, cred
, dvp
, dvp
->v_label
);
1440 mac_vnode_check_readlink(vfs_context_t ctx
, struct vnode
*vp
)
1445 #if SECURITY_MAC_CHECK_ENFORCE
1446 /* 21167099 - only check if we allow write */
1447 if (!mac_vnode_enforce
)
1450 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1453 cred
= vfs_context_ucred(ctx
);
1454 MAC_CHECK(vnode_check_readlink
, cred
, vp
, vp
->v_label
);
1459 mac_vnode_check_label_update(vfs_context_t ctx
, struct vnode
*vp
,
1460 struct label
*newlabel
)
1465 #if SECURITY_MAC_CHECK_ENFORCE
1466 /* 21167099 - only check if we allow write */
1467 if (!mac_vnode_enforce
)
1470 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1473 cred
= vfs_context_ucred(ctx
);
1474 MAC_CHECK(vnode_check_label_update
, cred
, vp
, vp
->v_label
, newlabel
);
1480 mac_vnode_check_rename(vfs_context_t ctx
, struct vnode
*dvp
,
1481 struct vnode
*vp
, struct componentname
*cnp
, struct vnode
*tdvp
,
1482 struct vnode
*tvp
, struct componentname
*tcnp
)
1487 #if SECURITY_MAC_CHECK_ENFORCE
1488 /* 21167099 - only check if we allow write */
1489 if (!mac_vnode_enforce
)
1492 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1495 cred
= vfs_context_ucred(ctx
);
1497 MAC_CHECK(vnode_check_rename_from
, cred
, dvp
, dvp
->v_label
, vp
,
1502 MAC_CHECK(vnode_check_rename_to
, cred
, tdvp
, tdvp
->v_label
, tvp
,
1503 tvp
!= NULL
? tvp
->v_label
: NULL
, dvp
== tdvp
, tcnp
);
1507 MAC_CHECK(vnode_check_rename
, cred
, dvp
, dvp
->v_label
, vp
,
1508 vp
->v_label
, cnp
, tdvp
, tdvp
->v_label
, tvp
,
1509 tvp
!= NULL
? tvp
->v_label
: NULL
, tcnp
);
1514 mac_vnode_check_revoke(vfs_context_t ctx
, struct vnode
*vp
)
1519 #if SECURITY_MAC_CHECK_ENFORCE
1520 /* 21167099 - only check if we allow write */
1521 if (!mac_vnode_enforce
)
1524 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1527 cred
= vfs_context_ucred(ctx
);
1528 MAC_CHECK(vnode_check_revoke
, cred
, vp
, vp
->v_label
);
1533 mac_vnode_check_searchfs(vfs_context_t ctx
, struct vnode
*vp
, struct attrlist
*alist
)
1538 #if SECURITY_MAC_CHECK_ENFORCE
1539 /* 21167099 - only check if we allow write */
1540 if (!mac_vnode_enforce
)
1543 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1546 cred
= vfs_context_ucred(ctx
);
1547 MAC_CHECK(vnode_check_searchfs
, cred
, vp
, vp
->v_label
, alist
);
1552 mac_vnode_check_select(vfs_context_t ctx
, struct vnode
*vp
, int which
)
1557 #if SECURITY_MAC_CHECK_ENFORCE
1558 /* 21167099 - only check if we allow write */
1559 if (!mac_vnode_enforce
)
1562 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1565 cred
= vfs_context_ucred(ctx
);
1566 MAC_CHECK(vnode_check_select
, cred
, vp
, vp
->v_label
, which
);
1571 mac_vnode_check_setacl(vfs_context_t ctx
, struct vnode
*vp
,
1572 struct kauth_acl
*acl
)
1577 #if SECURITY_MAC_CHECK_ENFORCE
1578 /* 21167099 - only check if we allow write */
1579 if (!mac_vnode_enforce
)
1582 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1585 cred
= vfs_context_ucred(ctx
);
1586 MAC_CHECK(vnode_check_setacl
, cred
, vp
, vp
->v_label
, acl
);
1591 mac_vnode_check_setattrlist(vfs_context_t ctx
, struct vnode
*vp
,
1592 struct attrlist
*alist
)
1597 #if SECURITY_MAC_CHECK_ENFORCE
1598 /* 21167099 - only check if we allow write */
1599 if (!mac_vnode_enforce
)
1602 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1605 cred
= vfs_context_ucred(ctx
);
1606 MAC_CHECK(vnode_check_setattrlist
, cred
, vp
, vp
->v_label
, alist
);
1611 mac_vnode_check_setextattr(vfs_context_t ctx
, struct vnode
*vp
,
1612 const char *name
, struct uio
*uio
)
1617 #if SECURITY_MAC_CHECK_ENFORCE
1618 /* 21167099 - only check if we allow write */
1619 if (!mac_vnode_enforce
)
1622 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1625 cred
= vfs_context_ucred(ctx
);
1626 MAC_CHECK(vnode_check_setextattr
, cred
, vp
, vp
->v_label
,
1632 mac_vnode_check_setflags(vfs_context_t ctx
, struct vnode
*vp
, u_long flags
)
1637 #if SECURITY_MAC_CHECK_ENFORCE
1638 /* 21167099 - only check if we allow write */
1639 if (!mac_vnode_enforce
)
1642 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1645 cred
= vfs_context_ucred(ctx
);
1646 MAC_CHECK(vnode_check_setflags
, cred
, vp
, vp
->v_label
, flags
);
1651 mac_vnode_check_setmode(vfs_context_t ctx
, struct vnode
*vp
, mode_t mode
)
1656 #if SECURITY_MAC_CHECK_ENFORCE
1657 /* 21167099 - only check if we allow write */
1658 if (!mac_vnode_enforce
)
1661 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1664 cred
= vfs_context_ucred(ctx
);
1665 MAC_CHECK(vnode_check_setmode
, cred
, vp
, vp
->v_label
, mode
);
1670 mac_vnode_check_setowner(vfs_context_t ctx
, struct vnode
*vp
, uid_t uid
,
1676 #if SECURITY_MAC_CHECK_ENFORCE
1677 /* 21167099 - only check if we allow write */
1678 if (!mac_vnode_enforce
)
1681 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1684 cred
= vfs_context_ucred(ctx
);
1685 MAC_CHECK(vnode_check_setowner
, cred
, vp
, vp
->v_label
, uid
, gid
);
1690 mac_vnode_check_setutimes(vfs_context_t ctx
, struct vnode
*vp
,
1691 struct timespec atime
, struct timespec mtime
)
1696 #if SECURITY_MAC_CHECK_ENFORCE
1697 /* 21167099 - only check if we allow write */
1698 if (!mac_vnode_enforce
)
1701 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1704 cred
= vfs_context_ucred(ctx
);
1705 MAC_CHECK(vnode_check_setutimes
, cred
, vp
, vp
->v_label
, atime
,
1711 mac_vnode_check_stat(vfs_context_t ctx
, struct ucred
*file_cred
,
1717 #if SECURITY_MAC_CHECK_ENFORCE
1718 /* 21167099 - only check if we allow write */
1719 if (!mac_vnode_enforce
)
1722 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1725 cred
= vfs_context_ucred(ctx
);
1726 MAC_CHECK(vnode_check_stat
, cred
, file_cred
, vp
,
1732 mac_vnode_check_truncate(vfs_context_t ctx
, struct ucred
*file_cred
,
1738 #if SECURITY_MAC_CHECK_ENFORCE
1739 /* 21167099 - only check if we allow write */
1740 if (!mac_vnode_enforce
)
1743 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1746 cred
= vfs_context_ucred(ctx
);
1747 MAC_CHECK(vnode_check_truncate
, cred
, file_cred
, vp
,
1754 mac_vnode_check_write(vfs_context_t ctx
, struct ucred
*file_cred
,
1760 #if SECURITY_MAC_CHECK_ENFORCE
1761 /* 21167099 - only check if we allow write */
1762 if (!mac_vnode_enforce
)
1765 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1768 cred
= vfs_context_ucred(ctx
);
1769 MAC_CHECK(vnode_check_write
, cred
, file_cred
, vp
, vp
->v_label
);
1775 mac_vnode_check_uipc_bind(vfs_context_t ctx
, struct vnode
*dvp
,
1776 struct componentname
*cnp
, struct vnode_attr
*vap
)
1781 #if SECURITY_MAC_CHECK_ENFORCE
1782 /* 21167099 - only check if we allow write */
1783 if (!mac_vnode_enforce
)
1786 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1789 cred
= vfs_context_ucred(ctx
);
1790 MAC_CHECK(vnode_check_uipc_bind
, cred
, dvp
, dvp
->v_label
, cnp
, vap
);
1795 mac_vnode_check_uipc_connect(vfs_context_t ctx
, struct vnode
*vp
, struct socket
*so
)
1800 #if SECURITY_MAC_CHECK_ENFORCE
1801 /* 21167099 - only check if we allow write */
1802 if (!mac_vnode_enforce
)
1805 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1808 cred
= vfs_context_ucred(ctx
);
1809 MAC_CHECK(vnode_check_uipc_connect
, cred
, vp
, vp
->v_label
, (socket_t
) so
);
1814 mac_vnode_label_update(vfs_context_t ctx
, struct vnode
*vp
, struct label
*newlabel
)
1816 kauth_cred_t cred
= vfs_context_ucred(ctx
);
1817 struct label
*tmpl
= NULL
;
1819 if (vp
->v_label
== NULL
)
1820 tmpl
= mac_vnode_label_alloc();
1824 /* recheck after lock */
1825 if (vp
->v_label
== NULL
) {
1830 MAC_PERFORM(vnode_label_update
, cred
, vp
, vp
->v_label
, newlabel
);
1834 mac_vnode_label_free(tmpl
);
1838 mac_vnode_find_sigs(struct proc
*p
, struct vnode
*vp
, off_t offset
)
1842 #if SECURITY_MAC_CHECK_ENFORCE
1843 /* 21167099 - only check if we allow write */
1844 if (!mac_proc_enforce
|| !mac_vnode_enforce
)
1848 MAC_CHECK(vnode_find_sigs
, p
, vp
, offset
, vp
->v_label
);
1854 mac_mount_label_associate(vfs_context_t ctx
, struct mount
*mp
)
1856 kauth_cred_t cred
= vfs_context_ucred(ctx
);
1858 /* XXX: eventually this logic may be handled by the policy? */
1860 /* We desire MULTILABEL for the root filesystem. */
1861 if ((mp
->mnt_flag
& MNT_ROOTFS
) &&
1862 (strcmp(mp
->mnt_vfsstat
.f_fstypename
, "hfs") == 0))
1863 mp
->mnt_flag
|= MNT_MULTILABEL
;
1865 /* MULTILABEL on DEVFS. */
1866 if (strcmp(mp
->mnt_vfsstat
.f_fstypename
, "devfs") == 0)
1867 mp
->mnt_flag
|= MNT_MULTILABEL
;
1869 /* MULTILABEL on FDESC pseudo-filesystem. */
1870 if (strcmp(mp
->mnt_vfsstat
.f_fstypename
, "fdesc") == 0)
1871 mp
->mnt_flag
|= MNT_MULTILABEL
;
1873 /* MULTILABEL on all NFS filesystems. */
1874 if (strcmp(mp
->mnt_vfsstat
.f_fstypename
, "nfs") == 0)
1875 mp
->mnt_flag
|= MNT_MULTILABEL
;
1877 /* MULTILABEL on all AFP filesystems. */
1878 if (strcmp(mp
->mnt_vfsstat
.f_fstypename
, "afpfs") == 0)
1879 mp
->mnt_flag
|= MNT_MULTILABEL
;
1881 if (mp
->mnt_vtable
!= NULL
) {
1882 /* Any filesystem that supports native XATTRs. */
1883 if ((mp
->mnt_vtable
->vfc_vfsflags
& VFC_VFSNATIVEXATTR
))
1884 mp
->mnt_flag
|= MNT_MULTILABEL
;
1886 /* Filesystem does not support multilabel. */
1887 if ((mp
->mnt_vtable
->vfc_vfsflags
& VFC_VFSNOMACLABEL
) &&
1888 (mp
->mnt_flag
& MNT_MULTILABEL
))
1889 mp
->mnt_flag
&= ~MNT_MULTILABEL
;
1892 MAC_PERFORM(mount_label_associate
, cred
, mp
, mp
->mnt_mntlabel
);
1894 printf("MAC Framework enabling %s support: %s -> %s (%s)\n",
1895 mp
->mnt_flag
& MNT_MULTILABEL
? "multilabel" : "singlelabel",
1896 mp
->mnt_vfsstat
.f_mntfromname
,
1897 mp
->mnt_vfsstat
.f_mntonname
,
1898 mp
->mnt_vfsstat
.f_fstypename
);
1903 mac_mount_check_mount(vfs_context_t ctx
, struct vnode
*vp
,
1904 struct componentname
*cnp
, const char *vfc_name
)
1909 #if SECURITY_MAC_CHECK_ENFORCE
1910 /* 21167099 - only check if we allow write */
1911 if (!mac_vnode_enforce
)
1914 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1917 cred
= vfs_context_ucred(ctx
);
1918 MAC_CHECK(mount_check_mount
, cred
, vp
, vp
->v_label
, cnp
, vfc_name
);
1924 mac_mount_check_snapshot_create(vfs_context_t ctx
, struct mount
*mp
,
1930 #if SECURITY_MAC_CHECK_ENFORCE
1931 /* 21167099 - only check if we allow write */
1932 if (!mac_vnode_enforce
)
1935 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1938 cred
= vfs_context_ucred(ctx
);
1939 MAC_CHECK(mount_check_snapshot_create
, cred
, mp
, name
);
1944 mac_mount_check_snapshot_delete(vfs_context_t ctx
, struct mount
*mp
,
1950 #if SECURITY_MAC_CHECK_ENFORCE
1951 /* 21167099 - only check if we allow write */
1952 if (!mac_vnode_enforce
)
1955 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1958 cred
= vfs_context_ucred(ctx
);
1959 MAC_CHECK(mount_check_snapshot_delete
, cred
, mp
, name
);
1964 mac_mount_check_remount(vfs_context_t ctx
, struct mount
*mp
)
1969 #if SECURITY_MAC_CHECK_ENFORCE
1970 /* 21167099 - only check if we allow write */
1971 if (!mac_vnode_enforce
)
1974 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1977 cred
= vfs_context_ucred(ctx
);
1978 MAC_CHECK(mount_check_remount
, cred
, mp
, mp
->mnt_mntlabel
);
1984 mac_mount_check_umount(vfs_context_t ctx
, struct mount
*mp
)
1989 #if SECURITY_MAC_CHECK_ENFORCE
1990 /* 21167099 - only check if we allow write */
1991 if (!mac_vnode_enforce
)
1994 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1997 cred
= vfs_context_ucred(ctx
);
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 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
2018 cred
= vfs_context_ucred(ctx
);
2019 MAC_CHECK(mount_check_getattr
, cred
, mp
, mp
->mnt_mntlabel
, vfa
);
2024 mac_mount_check_setattr(vfs_context_t ctx
, struct mount
*mp
,
2025 struct vfs_attr
*vfa
)
2030 #if SECURITY_MAC_CHECK_ENFORCE
2031 /* 21167099 - only check if we allow write */
2032 if (!mac_vnode_enforce
)
2035 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
2038 cred
= vfs_context_ucred(ctx
);
2039 MAC_CHECK(mount_check_setattr
, cred
, mp
, mp
->mnt_mntlabel
, vfa
);
2044 mac_mount_check_stat(vfs_context_t ctx
, struct mount
*mount
)
2049 #if SECURITY_MAC_CHECK_ENFORCE
2050 /* 21167099 - only check if we allow write */
2051 if (!mac_vnode_enforce
)
2054 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
2057 cred
= vfs_context_ucred(ctx
);
2058 MAC_CHECK(mount_check_stat
, cred
, mount
, mount
->mnt_mntlabel
);
2064 mac_mount_check_label_update(vfs_context_t ctx
, struct mount
*mount
)
2069 #if SECURITY_MAC_CHECK_ENFORCE
2070 /* 21167099 - only check if we allow write */
2071 if (!mac_vnode_enforce
)
2074 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
2077 cred
= vfs_context_ucred(ctx
);
2078 MAC_CHECK(mount_check_label_update
, cred
, mount
, mount
->mnt_mntlabel
);
2084 mac_mount_check_fsctl(vfs_context_t ctx
, struct mount
*mp
, u_int cmd
)
2089 #if SECURITY_MAC_CHECK_ENFORCE
2090 /* 21167099 - only check if we allow write */
2091 if (!mac_vnode_enforce
)
2094 if (!mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
2097 cred
= vfs_context_ucred(ctx
);
2098 MAC_CHECK(mount_check_fsctl
, cred
, mp
, mp
->mnt_mntlabel
, cmd
);
2104 mac_devfs_label_associate_device(dev_t dev
, struct devnode
*de
,
2105 const char *fullpath
)
2107 #if SECURITY_MAC_CHECK_ENFORCE
2108 /* 21167099 - only check if we allow write */
2109 if (!mac_device_enforce
)
2113 MAC_PERFORM(devfs_label_associate_device
, dev
, de
, de
->dn_label
,
2118 mac_devfs_label_associate_directory(const char *dirname
, int dirnamelen
,
2119 struct devnode
*de
, const char *fullpath
)
2121 #if SECURITY_MAC_CHECK_ENFORCE
2122 /* 21167099 - only check if we allow write */
2123 if (!mac_device_enforce
)
2127 MAC_PERFORM(devfs_label_associate_directory
, dirname
, dirnamelen
, de
,
2128 de
->dn_label
, fullpath
);
2132 vn_setlabel(struct vnode
*vp
, struct label
*intlabel
, vfs_context_t context
)
2136 #if SECURITY_MAC_CHECK_ENFORCE
2137 /* 21167099 - only check if we allow write */
2138 if (!mac_vnode_enforce
)
2141 if (!mac_label_vnodes
)
2144 if (vp
->v_mount
== NULL
) {
2145 printf("vn_setlabel: null v_mount\n");
2146 if (vp
->v_type
!= VNON
)
2147 printf("vn_setlabel: null v_mount with non-VNON\n");
2151 if ((vp
->v_mount
->mnt_flag
& MNT_MULTILABEL
) == 0)
2155 * Multi-phase commit. First check the policies to confirm the
2156 * change is OK. Then commit via the filesystem. Finally,
2157 * update the actual vnode label. Question: maybe the filesystem
2158 * should update the vnode at the end as part of VNOP_SETLABEL()?
2160 error
= mac_vnode_check_label_update(context
, vp
, intlabel
);
2164 error
= VNOP_SETLABEL(vp
, intlabel
, context
);
2165 if (error
== ENOTSUP
) {
2166 error
= mac_vnode_label_store(context
, vp
,
2169 printf("%s: mac_vnode_label_store failed %d\n",
2173 mac_vnode_label_update(context
, vp
, intlabel
);
2176 printf("vn_setlabel: vop setlabel failed %d\n", error
);
2184 mac_vnode_label_associate_fdesc(struct mount
*mp
, struct fdescnode
*fnp
,
2185 struct vnode
*vp
, vfs_context_t ctx
)
2187 struct fileproc
*fp
;
2188 #if CONFIG_MACF_SOCKET_SUBSET
2199 * If no backing file, let the policy choose which label to use.
2201 if (fnp
->fd_fd
== -1) {
2202 MAC_PERFORM(vnode_label_associate_file
, vfs_context_ucred(ctx
),
2203 mp
, mp
->mnt_mntlabel
, NULL
, NULL
, vp
, vp
->v_label
);
2207 p
= vfs_context_proc(ctx
);
2208 error
= fp_lookup(p
, fnp
->fd_fd
, &fp
, 0);
2212 if (fp
->f_fglob
== NULL
) {
2217 switch (FILEGLOB_DTYPE(fp
->f_fglob
)) {
2219 fvp
= (struct vnode
*)fp
->f_fglob
->fg_data
;
2220 if ((error
= vnode_getwithref(fvp
)))
2222 MAC_PERFORM(vnode_label_copy
, fvp
->v_label
, vp
->v_label
);
2223 (void)vnode_put(fvp
);
2225 #if CONFIG_MACF_SOCKET_SUBSET
2227 so
= (struct socket
*)fp
->f_fglob
->fg_data
;
2229 MAC_PERFORM(vnode_label_associate_socket
,
2230 vfs_context_ucred(ctx
), (socket_t
)so
, so
->so_label
,
2232 socket_unlock(so
, 1);
2236 pshm_label_associate(fp
, vp
, ctx
);
2239 psem_label_associate(fp
, vp
, ctx
);
2242 cpipe
= (struct pipe
*)fp
->f_fglob
->fg_data
;
2243 /* kern/sys_pipe.c:pipe_select() suggests this test. */
2244 if (cpipe
== (struct pipe
*)-1) {
2249 MAC_PERFORM(vnode_label_associate_pipe
, vfs_context_ucred(ctx
),
2250 cpipe
, cpipe
->pipe_label
, vp
, vp
->v_label
);
2254 case DTYPE_FSEVENTS
:
2256 case DTYPE_NETPOLICY
:
2258 MAC_PERFORM(vnode_label_associate_file
, vfs_context_ucred(ctx
),
2259 mp
, mp
->mnt_mntlabel
, fp
->f_fglob
, fp
->f_fglob
->fg_label
,
2264 fp_drop(p
, fnp
->fd_fd
, fp
, 0);