2 * Copyright (c) 2007 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson
30 * Copyright (c) 2001 Ilmar S. Habibulin
31 * Copyright (c) 2001, 2002, 2003, 2004 Networks Associates Technology, Inc.
32 * Copyright (c) 2005 SPARTA, Inc.
34 * This software was developed by Robert Watson and Ilmar Habibulin for the
37 * This software was developed for the FreeBSD Project in part by Network
38 * Associates Laboratories, the Security Research Division of Network
39 * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"),
40 * as part of the DARPA CHATS research program.
42 * Redistribution and use in source and binary forms, with or without
43 * modification, are permitted provided that the following conditions
45 * 1. Redistributions of source code must retain the above copyright
46 * notice, this list of conditions and the following disclaimer.
47 * 2. Redistributions in binary form must reproduce the above copyright
48 * notice, this list of conditions and the following disclaimer in the
49 * documentation and/or other materials provided with the distribution.
51 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
52 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
53 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
54 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
55 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
56 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
57 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
58 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
59 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
60 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
65 #include <sys/param.h>
66 #include <sys/systm.h>
67 #include <sys/kernel.h>
69 #include <sys/kauth.h>
71 #include <sys/file_internal.h>
72 #include <sys/imgact.h>
73 #include <sys/namei.h>
74 #include <sys/mount_internal.h>
76 #include <sys/posix_sem.h>
77 #include <sys/posix_shm.h>
78 #include <sys/uio_internal.h>
79 #include <sys/vnode_internal.h>
81 #include <miscfs/devfs/devfsdefs.h>
82 #include <miscfs/fdesc/fdesc.h>
84 #include <security/mac_internal.h>
86 /* convert {R,W,X}_OK values to V{READ,WRITE,EXEC} */
87 #define ACCESS_MODE_TO_VNODE_MASK(m) (m << 6)
90 mac_devfsdirent_label_alloc(void)
94 label
= mac_labelzone_alloc(MAC_WAITOK
);
97 MAC_PERFORM(devfs_label_init
, label
);
102 mac_devfs_label_init(struct devnode
*de
)
105 de
->dn_label
= mac_devfsdirent_label_alloc();
108 static struct label
*
109 mac_mount_label_alloc(void)
113 label
= mac_labelzone_alloc(MAC_WAITOK
);
116 MAC_PERFORM(mount_label_init
, label
);
121 mac_mount_label_init(struct mount
*mp
)
124 mp
->mnt_mntlabel
= mac_mount_label_alloc();
128 mac_vnode_label_alloc(void)
132 label
= mac_labelzone_alloc(MAC_WAITOK
);
135 MAC_PERFORM(vnode_label_init
, label
);
140 mac_vnode_label_init(vnode_t vp
)
143 vp
->v_label
= mac_vnode_label_alloc();
147 * vnode labels are allocated at the same time as vnodes, but vnodes are never
148 * freed. Instead, we want to remove any sensitive information before putting
149 * them on the free list for reuse.
152 mac_vnode_label_recycle(vnode_t vp
)
155 MAC_PERFORM(vnode_label_recycle
, vp
->v_label
);
159 mac_devfs_label_free(struct label
*label
)
161 MAC_PERFORM(devfs_label_destroy
, label
);
162 mac_labelzone_free(label
);
166 mac_devfs_label_destroy(struct devnode
*de
)
168 if (de
->dn_label
!= NULL
) {
169 mac_devfs_label_free(de
->dn_label
);
175 mac_mount_label_free(struct label
*label
)
178 MAC_PERFORM(mount_label_destroy
, label
);
179 mac_labelzone_free(label
);
183 mac_mount_label_destroy(struct mount
*mp
)
187 if (mp
->mnt_mntlabel
!= NULL
) {
188 mac_mount_label_free(mp
->mnt_mntlabel
);
189 mp
->mnt_mntlabel
= NULL
;
194 mac_vnode_label_free(struct label
*label
)
197 MAC_PERFORM(vnode_label_destroy
, label
);
198 mac_labelzone_free(label
);
203 mac_vnode_label_destroy(struct vnode
*vp
)
206 mac_vnode_label_free(vp
->v_label
);
212 mac_vnode_label_copy(struct label
*src
, struct label
*dest
)
215 MAC_PERFORM(vnode_label_copy
, src
, dest
);
219 mac_vnode_label_externalize_audit(struct vnode
*vp
, struct mac
*mac
)
223 /* It is assumed that any necessary vnode locking is done on entry */
224 error
= MAC_EXTERNALIZE_AUDIT(vnode
, vp
->v_label
,
225 mac
->m_string
, mac
->m_buflen
);
231 mac_vnode_label_externalize(struct label
*label
, char *elements
,
232 char *outbuf
, size_t outbuflen
, int flags __unused
)
236 error
= MAC_EXTERNALIZE(vnode
, label
, elements
, outbuf
, outbuflen
);
242 mac_vnode_label_internalize(struct label
*label
, char *string
)
246 error
= MAC_INTERNALIZE(vnode
, label
, string
);
252 mac_mount_label_internalize(struct label
*label
, char *string
)
256 error
= MAC_INTERNALIZE(mount
, label
, string
);
262 mac_mount_label_externalize(struct label
*label
, char *elements
,
263 char *outbuf
, size_t outbuflen
)
267 error
= MAC_EXTERNALIZE(mount
, label
, elements
, outbuf
, outbuflen
);
273 mac_devfs_label_copy(struct label
*src
, struct label
*dest
)
275 if (!mac_device_enforce
)
278 MAC_PERFORM(devfs_label_copy
, src
, dest
);
282 mac_devfs_label_update(struct mount
*mp
, struct devnode
*de
,
286 if (!mac_device_enforce
)
289 MAC_PERFORM(devfs_label_update
, mp
, de
, de
->dn_label
, vp
,
294 mac_vnode_label_associate(struct mount
*mp
, struct vnode
*vp
, vfs_context_t ctx
)
297 struct fdescnode
*fnp
;
300 if (!mac_vnode_enforce
)
303 /* XXX: should not inspect v_tag in kernel! */
307 mac_vnode_label_associate_devfs(mp
, dnp
, vp
);
311 error
= mac_vnode_label_associate_fdesc(mp
, fnp
, vp
, ctx
);
314 error
= mac_vnode_label_associate_extattr(mp
, vp
);
322 mac_vnode_label_associate_devfs(struct mount
*mp
, struct devnode
*de
,
325 if (!mac_device_enforce
)
328 MAC_PERFORM(vnode_label_associate_devfs
,
329 mp
, mp
? mp
->mnt_mntlabel
: NULL
,
335 mac_vnode_label_associate_extattr(struct mount
*mp
, struct vnode
*vp
)
339 MAC_CHECK(vnode_label_associate_extattr
, mp
, mp
->mnt_mntlabel
, vp
,
346 mac_vnode_label_associate_singlelabel(struct mount
*mp
, struct vnode
*vp
)
349 if (!mac_vnode_enforce
)
352 MAC_PERFORM(vnode_label_associate_singlelabel
, mp
,
353 mp
? mp
->mnt_mntlabel
: NULL
, vp
, vp
->v_label
);
357 mac_vnode_notify_create(vfs_context_t ctx
, struct mount
*mp
,
358 struct vnode
*dvp
, struct vnode
*vp
, struct componentname
*cnp
)
363 if (!mac_vnode_enforce
||
364 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
367 cred
= vfs_context_ucred(ctx
);
368 MAC_CHECK(vnode_notify_create
, cred
, mp
, mp
->mnt_mntlabel
,
369 dvp
, dvp
->v_label
, vp
, vp
->v_label
, cnp
);
375 * Extended attribute 'name' was updated via
376 * vn_setxattr() or vn_removexattr(). Allow the
377 * policy to update the vnode label.
380 mac_vnode_label_update_extattr(struct mount
*mp
, struct vnode
*vp
,
385 if (!mac_vnode_enforce
)
388 MAC_PERFORM(vnode_label_update_extattr
, mp
, mp
->mnt_mntlabel
, vp
,
400 mac_vnode_label_store(vfs_context_t ctx
, struct vnode
*vp
,
401 struct label
*intlabel
)
406 if (!mac_vnode_enforce
&&
407 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
410 cred
= vfs_context_ucred(ctx
);
411 MAC_CHECK(vnode_label_store
, cred
, vp
, vp
->v_label
, intlabel
);
417 mac_cred_label_update_execve(vfs_context_t ctx
, kauth_cred_t
new, struct vnode
*vp
,
418 struct label
*scriptvnodelabel
, struct label
*execl
)
422 if (!mac_proc_enforce
&& !mac_vnode_enforce
)
425 /* mark the new cred to indicate "matching" includes the label */
426 new->cr_flags
|= CRF_MAC_ENFORCE
;
428 cred
= vfs_context_ucred(ctx
);
429 MAC_PERFORM(cred_label_update_execve
, cred
, new, vp
, vp
->v_label
,
430 scriptvnodelabel
, execl
);
434 mac_cred_check_label_update_execve(vfs_context_t ctx
, struct vnode
*vp
,
435 struct label
*scriptvnodelabel
, struct label
*execlabel
, struct proc
*p
)
440 if (!mac_proc_enforce
&& !mac_vnode_enforce
)
443 cred
= vfs_context_ucred(ctx
);
444 MAC_BOOLEAN(cred_check_label_update_execve
, ||, cred
, vp
, vp
->v_label
,
445 scriptvnodelabel
, execlabel
, p
);
451 mac_vnode_check_access(vfs_context_t ctx
, struct vnode
*vp
,
458 if (!mac_vnode_enforce
||
459 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
462 cred
= vfs_context_ucred(ctx
);
463 /* Convert {R,W,X}_OK values to V{READ,WRITE,EXEC} for entry points */
464 mask
= ACCESS_MODE_TO_VNODE_MASK(acc_mode
);
465 MAC_CHECK(vnode_check_access
, cred
, vp
, vp
->v_label
, mask
);
470 mac_vnode_check_chdir(vfs_context_t ctx
, struct vnode
*dvp
)
475 if (!mac_vnode_enforce
||
476 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
479 cred
= vfs_context_ucred(ctx
);
480 MAC_CHECK(vnode_check_chdir
, cred
, dvp
, dvp
->v_label
);
485 mac_vnode_check_chroot(vfs_context_t ctx
, struct vnode
*dvp
,
486 struct componentname
*cnp
)
491 if (!mac_vnode_enforce
||
492 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
495 cred
= vfs_context_ucred(ctx
);
496 MAC_CHECK(vnode_check_chroot
, cred
, dvp
, dvp
->v_label
, cnp
);
501 mac_vnode_check_create(vfs_context_t ctx
, struct vnode
*dvp
,
502 struct componentname
*cnp
, struct vnode_attr
*vap
)
507 if (!mac_vnode_enforce
||
508 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
511 cred
= vfs_context_ucred(ctx
);
512 MAC_CHECK(vnode_check_create
, cred
, dvp
, dvp
->v_label
, cnp
, vap
);
517 mac_vnode_check_unlink(vfs_context_t ctx
, struct vnode
*dvp
, struct vnode
*vp
,
518 struct componentname
*cnp
)
523 if (!mac_vnode_enforce
||
524 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
527 cred
= vfs_context_ucred(ctx
);
528 MAC_CHECK(vnode_check_unlink
, cred
, dvp
, dvp
->v_label
, vp
,
534 mac_vnode_check_deleteacl(vfs_context_t ctx
, struct vnode
*vp
,
540 if (!mac_vnode_enforce
||
541 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
544 cred
= vfs_context_ucred(ctx
);
545 MAC_CHECK(vnode_check_deleteacl
, cred
, vp
, vp
->v_label
, type
);
551 mac_vnode_check_deleteextattr(vfs_context_t ctx
, struct vnode
*vp
,
557 if (!mac_vnode_enforce
||
558 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
561 cred
= vfs_context_ucred(ctx
);
562 MAC_CHECK(vnode_check_deleteextattr
, cred
, vp
, vp
->v_label
, name
);
566 mac_vnode_check_exchangedata(vfs_context_t ctx
,
567 struct vnode
*v1
, struct vnode
*v2
)
572 if (!mac_vnode_enforce
||
573 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
576 cred
= vfs_context_ucred(ctx
);
577 MAC_CHECK(vnode_check_exchangedata
, cred
, v1
, v1
->v_label
,
585 mac_vnode_check_getacl(vfs_context_t ctx
, struct vnode
*vp
, acl_type_t type
)
590 if (!mac_vnode_enforce
||
591 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
594 cred
= vfs_context_ucred(ctx
);
595 MAC_CHECK(vnode_check_getacl
, cred
, vp
, vp
->v_label
, type
);
601 mac_vnode_check_getattrlist(vfs_context_t ctx
, struct vnode
*vp
,
602 struct attrlist
*alist
)
607 if (!mac_vnode_enforce
||
608 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
611 cred
= vfs_context_ucred(ctx
);
612 MAC_CHECK(vnode_check_getattrlist
, cred
, vp
, vp
->v_label
, alist
);
614 /* Falsify results instead of returning error? */
619 mac_vnode_check_exec(vfs_context_t ctx
, struct vnode
*vp
,
620 struct image_params
*imgp
)
625 if (!mac_vnode_enforce
|| !mac_proc_enforce
)
628 cred
= vfs_context_ucred(ctx
);
629 MAC_CHECK(vnode_check_exec
, cred
, vp
, vp
->v_label
,
630 (imgp
!= NULL
) ? imgp
->ip_execlabelp
: NULL
,
631 (imgp
!= NULL
) ? &imgp
->ip_ndp
->ni_cnd
: NULL
,
632 (imgp
!= NULL
) ? &imgp
->ip_csflags
: NULL
);
637 mac_vnode_check_signature(struct vnode
*vp
, unsigned char *sha1
,
638 void * signature
, size_t size
)
642 if (!mac_vnode_enforce
|| !mac_proc_enforce
)
645 MAC_CHECK(vnode_check_signature
, vp
, vp
->v_label
, sha1
, signature
, size
);
651 mac_vnode_check_getacl(vfs_context_t ctx
, struct vnode
*vp
, acl_type_t type
)
656 if (!mac_vnode_enforce
||
657 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
660 cred
= vfs_context_ucred(ctx
);
661 MAC_CHECK(vnode_check_getacl
, cred
, vp
, vp
->v_label
, type
);
667 mac_vnode_check_getextattr(vfs_context_t ctx
, struct vnode
*vp
,
668 const char *name
, struct uio
*uio
)
673 if (!mac_vnode_enforce
||
674 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
677 cred
= vfs_context_ucred(ctx
);
678 MAC_CHECK(vnode_check_getextattr
, cred
, vp
, vp
->v_label
,
684 mac_vnode_check_ioctl(vfs_context_t ctx
, struct vnode
*vp
, u_int cmd
)
689 if (!mac_vnode_enforce
||
690 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
693 cred
= vfs_context_ucred(ctx
);
694 MAC_CHECK(vnode_check_ioctl
, cred
, vp
, vp
->v_label
, cmd
);
699 mac_vnode_check_kqfilter(vfs_context_t ctx
, kauth_cred_t file_cred
,
700 struct knote
*kn
, struct vnode
*vp
)
705 if (!mac_vnode_enforce
||
706 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
709 cred
= vfs_context_ucred(ctx
);
710 MAC_CHECK(vnode_check_kqfilter
, cred
, file_cred
, kn
, vp
,
717 mac_vnode_check_link(vfs_context_t ctx
, struct vnode
*dvp
,
718 struct vnode
*vp
, struct componentname
*cnp
)
723 if (!mac_vnode_enforce
||
724 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
727 cred
= vfs_context_ucred(ctx
);
728 MAC_CHECK(vnode_check_link
, cred
, dvp
, dvp
->v_label
, vp
,
734 mac_vnode_check_listextattr(vfs_context_t ctx
, struct vnode
*vp
)
739 if (!mac_vnode_enforce
||
740 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
743 cred
= vfs_context_ucred(ctx
);
744 MAC_CHECK(vnode_check_listextattr
, cred
, vp
, vp
->v_label
);
749 mac_vnode_check_lookup(vfs_context_t ctx
, struct vnode
*dvp
,
750 struct componentname
*cnp
)
755 if (!mac_vnode_enforce
||
756 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
759 cred
= vfs_context_ucred(ctx
);
760 MAC_CHECK(vnode_check_lookup
, cred
, dvp
, dvp
->v_label
, cnp
);
765 mac_vnode_check_open(vfs_context_t ctx
, struct vnode
*vp
, int acc_mode
)
770 if (!mac_vnode_enforce
||
771 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
774 cred
= vfs_context_ucred(ctx
);
775 MAC_CHECK(vnode_check_open
, cred
, vp
, vp
->v_label
, acc_mode
);
780 mac_vnode_check_read(vfs_context_t ctx
, struct ucred
*file_cred
,
786 if (!mac_vnode_enforce
||
787 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
790 cred
= vfs_context_ucred(ctx
);
791 MAC_CHECK(vnode_check_read
, cred
, file_cred
, vp
,
798 mac_vnode_check_readdir(vfs_context_t ctx
, struct vnode
*dvp
)
803 if (!mac_vnode_enforce
||
804 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
807 cred
= vfs_context_ucred(ctx
);
808 MAC_CHECK(vnode_check_readdir
, cred
, dvp
, dvp
->v_label
);
813 mac_vnode_check_readlink(vfs_context_t ctx
, struct vnode
*vp
)
818 if (!mac_vnode_enforce
||
819 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
822 cred
= vfs_context_ucred(ctx
);
823 MAC_CHECK(vnode_check_readlink
, cred
, vp
, vp
->v_label
);
828 mac_vnode_check_label_update(vfs_context_t ctx
, struct vnode
*vp
,
829 struct label
*newlabel
)
834 if (!mac_vnode_enforce
||
835 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
838 cred
= vfs_context_ucred(ctx
);
839 MAC_CHECK(vnode_check_label_update
, cred
, vp
, vp
->v_label
, newlabel
);
845 mac_vnode_check_rename_from(vfs_context_t ctx
, struct vnode
*dvp
,
846 struct vnode
*vp
, struct componentname
*cnp
)
851 if (!mac_vnode_enforce
||
852 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
855 cred
= vfs_context_ucred(ctx
);
856 MAC_CHECK(vnode_check_rename_from
, cred
, dvp
, dvp
->v_label
, vp
,
862 mac_vnode_check_rename_to(vfs_context_t ctx
, struct vnode
*dvp
,
863 struct vnode
*vp
, int samedir
, struct componentname
*cnp
)
868 if (!mac_vnode_enforce
||
869 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
872 cred
= vfs_context_ucred(ctx
);
873 MAC_CHECK(vnode_check_rename_to
, cred
, dvp
, dvp
->v_label
, vp
,
874 vp
!= NULL
? vp
->v_label
: NULL
, samedir
, cnp
);
879 mac_vnode_check_revoke(vfs_context_t ctx
, struct vnode
*vp
)
884 if (!mac_vnode_enforce
||
885 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
888 cred
= vfs_context_ucred(ctx
);
889 MAC_CHECK(vnode_check_revoke
, cred
, vp
, vp
->v_label
);
894 mac_vnode_check_select(vfs_context_t ctx
, struct vnode
*vp
, int which
)
899 if (!mac_vnode_enforce
||
900 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
903 cred
= vfs_context_ucred(ctx
);
904 MAC_CHECK(vnode_check_select
, cred
, vp
, vp
->v_label
, which
);
910 mac_vnode_check_setacl(vfs_context_t ctx
, struct vnode
*vp
, acl_type_t type
,
916 if (!mac_vnode_enforce
||
917 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
920 cred
= vfs_context_ucred(ctx
);
921 MAC_CHECK(vnode_check_setacl
, cred
, vp
, vp
->v_label
, type
, acl
);
927 mac_vnode_check_setattrlist(vfs_context_t ctx
, struct vnode
*vp
,
928 struct attrlist
*alist
)
933 if (!mac_vnode_enforce
||
934 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
937 cred
= vfs_context_ucred(ctx
);
938 MAC_CHECK(vnode_check_setattrlist
, cred
, vp
, vp
->v_label
, alist
);
943 mac_vnode_check_setextattr(vfs_context_t ctx
, struct vnode
*vp
,
944 const char *name
, struct uio
*uio
)
949 if (!mac_vnode_enforce
||
950 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
953 cred
= vfs_context_ucred(ctx
);
954 MAC_CHECK(vnode_check_setextattr
, cred
, vp
, vp
->v_label
,
960 mac_vnode_check_setflags(vfs_context_t ctx
, struct vnode
*vp
, u_long flags
)
965 if (!mac_vnode_enforce
||
966 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
969 cred
= vfs_context_ucred(ctx
);
970 MAC_CHECK(vnode_check_setflags
, cred
, vp
, vp
->v_label
, flags
);
975 mac_vnode_check_setmode(vfs_context_t ctx
, struct vnode
*vp
, mode_t mode
)
980 if (!mac_vnode_enforce
||
981 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
984 cred
= vfs_context_ucred(ctx
);
985 MAC_CHECK(vnode_check_setmode
, cred
, vp
, vp
->v_label
, mode
);
990 mac_vnode_check_setowner(vfs_context_t ctx
, struct vnode
*vp
, uid_t uid
,
996 if (!mac_vnode_enforce
||
997 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1000 cred
= vfs_context_ucred(ctx
);
1001 MAC_CHECK(vnode_check_setowner
, cred
, vp
, vp
->v_label
, uid
, gid
);
1006 mac_vnode_check_setutimes(vfs_context_t ctx
, struct vnode
*vp
,
1007 struct timespec atime
, struct timespec mtime
)
1012 if (!mac_vnode_enforce
||
1013 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1016 cred
= vfs_context_ucred(ctx
);
1017 MAC_CHECK(vnode_check_setutimes
, cred
, vp
, vp
->v_label
, atime
,
1023 mac_vnode_check_stat(vfs_context_t ctx
, struct ucred
*file_cred
,
1029 if (!mac_vnode_enforce
||
1030 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1033 cred
= vfs_context_ucred(ctx
);
1034 MAC_CHECK(vnode_check_stat
, cred
, file_cred
, vp
,
1040 mac_vnode_check_truncate(vfs_context_t ctx
, struct ucred
*file_cred
,
1046 if (!mac_vnode_enforce
||
1047 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1050 cred
= vfs_context_ucred(ctx
);
1051 MAC_CHECK(vnode_check_truncate
, cred
, file_cred
, vp
,
1058 mac_vnode_check_write(vfs_context_t ctx
, struct ucred
*file_cred
,
1064 if (!mac_vnode_enforce
||
1065 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1068 cred
= vfs_context_ucred(ctx
);
1069 MAC_CHECK(vnode_check_write
, cred
, file_cred
, vp
, vp
->v_label
);
1075 mac_vnode_label_update(vfs_context_t ctx
, struct vnode
*vp
, struct label
*newlabel
)
1077 kauth_cred_t cred
= vfs_context_ucred(ctx
);
1080 MAC_PERFORM(vnode_label_update
, cred
, vp
, vp
->v_label
, newlabel
);
1085 mac_mount_label_associate(vfs_context_t ctx
, struct mount
*mp
)
1087 kauth_cred_t cred
= vfs_context_ucred(ctx
);
1089 /* XXX: eventually this logic may be handled by the policy? */
1091 /* We desire MULTILABEL for the root filesystem. */
1092 if ((mp
->mnt_flag
& MNT_ROOTFS
) &&
1093 (strcmp(mp
->mnt_vfsstat
.f_fstypename
, "hfs") == 0))
1094 mp
->mnt_flag
|= MNT_MULTILABEL
;
1096 /* MULTILABEL on DEVFS. */
1097 if (strcmp(mp
->mnt_vfsstat
.f_fstypename
, "devfs") == 0)
1098 mp
->mnt_flag
|= MNT_MULTILABEL
;
1100 /* MULTILABEL on FDESC pseudo-filesystem. */
1101 if (strcmp(mp
->mnt_vfsstat
.f_fstypename
, "fdesc") == 0)
1102 mp
->mnt_flag
|= MNT_MULTILABEL
;
1104 /* MULTILABEL on all NFS filesystems. */
1105 if (strcmp(mp
->mnt_vfsstat
.f_fstypename
, "nfs") == 0)
1106 mp
->mnt_flag
|= MNT_MULTILABEL
;
1108 /* MULTILABEL on all AFP filesystems. */
1109 if (strcmp(mp
->mnt_vfsstat
.f_fstypename
, "afpfs") == 0)
1110 mp
->mnt_flag
|= MNT_MULTILABEL
;
1112 if (mp
->mnt_vtable
!= NULL
) {
1113 /* Any filesystem that supports native XATTRs. */
1114 if ((mp
->mnt_vtable
->vfc_vfsflags
& VFC_VFSNATIVEXATTR
))
1115 mp
->mnt_flag
|= MNT_MULTILABEL
;
1117 /* Filesystem does not support multilabel. */
1118 if ((mp
->mnt_vtable
->vfc_vfsflags
& VFC_VFSNOMACLABEL
) &&
1119 (mp
->mnt_flag
& MNT_MULTILABEL
))
1120 mp
->mnt_flag
&= ~MNT_MULTILABEL
;
1123 MAC_PERFORM(mount_label_associate
, cred
, mp
, mp
->mnt_mntlabel
);
1125 printf("MAC Framework enabling %s support: %s -> %s (%s)\n",
1126 mp
->mnt_flag
& MNT_MULTILABEL
? "multilabel" : "singlelabel",
1127 mp
->mnt_vfsstat
.f_mntfromname
,
1128 mp
->mnt_vfsstat
.f_mntonname
,
1129 mp
->mnt_vfsstat
.f_fstypename
);
1134 mac_mount_check_mount(vfs_context_t ctx
, struct vnode
*vp
,
1135 struct componentname
*cnp
, const char *vfc_name
)
1140 if (!mac_vnode_enforce
||
1141 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1144 cred
= vfs_context_ucred(ctx
);
1145 MAC_CHECK(mount_check_mount
, cred
, vp
, vp
->v_label
, cnp
, vfc_name
);
1151 mac_mount_check_remount(vfs_context_t ctx
, struct mount
*mp
)
1156 if (!mac_vnode_enforce
||
1157 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1160 cred
= vfs_context_ucred(ctx
);
1161 MAC_CHECK(mount_check_remount
, cred
, mp
, mp
->mnt_mntlabel
);
1167 mac_mount_check_umount(vfs_context_t ctx
, struct mount
*mp
)
1172 if (!mac_vnode_enforce
||
1173 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1176 cred
= vfs_context_ucred(ctx
);
1177 MAC_CHECK(mount_check_umount
, cred
, mp
, mp
->mnt_mntlabel
);
1183 mac_mount_check_getattr(vfs_context_t ctx
, struct mount
*mp
,
1184 struct vfs_attr
*vfa
)
1189 if (!mac_vnode_enforce
||
1190 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1193 cred
= vfs_context_ucred(ctx
);
1194 MAC_CHECK(mount_check_getattr
, cred
, mp
, mp
->mnt_mntlabel
, vfa
);
1199 mac_mount_check_setattr(vfs_context_t ctx
, struct mount
*mp
,
1200 struct vfs_attr
*vfa
)
1205 if (!mac_vnode_enforce
||
1206 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1209 cred
= vfs_context_ucred(ctx
);
1210 MAC_CHECK(mount_check_setattr
, cred
, mp
, mp
->mnt_mntlabel
, vfa
);
1215 mac_mount_check_stat(vfs_context_t ctx
, struct mount
*mount
)
1220 if (!mac_vnode_enforce
||
1221 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1224 cred
= vfs_context_ucred(ctx
);
1225 MAC_CHECK(mount_check_stat
, cred
, mount
, mount
->mnt_mntlabel
);
1231 mac_mount_check_label_update(vfs_context_t ctx
, struct mount
*mount
)
1236 if (!mac_vnode_enforce
||
1237 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1240 cred
= vfs_context_ucred(ctx
);
1241 MAC_CHECK(mount_check_label_update
, cred
, mount
, mount
->mnt_mntlabel
);
1247 mac_mount_check_fsctl(vfs_context_t ctx
, struct mount
*mp
, u_int cmd
)
1252 if (!mac_vnode_enforce
||
1253 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1256 cred
= vfs_context_ucred(ctx
);
1257 MAC_CHECK(mount_check_fsctl
, cred
, mp
, mp
->mnt_mntlabel
, cmd
);
1263 mac_devfs_label_associate_device(dev_t dev
, struct devnode
*de
,
1264 const char *fullpath
)
1266 if (!mac_device_enforce
)
1269 MAC_PERFORM(devfs_label_associate_device
, dev
, de
, de
->dn_label
,
1274 mac_devfs_label_associate_directory(const char *dirname
, int dirnamelen
,
1275 struct devnode
*de
, const char *fullpath
)
1277 if (!mac_device_enforce
)
1280 MAC_PERFORM(devfs_label_associate_directory
, dirname
, dirnamelen
, de
,
1281 de
->dn_label
, fullpath
);
1285 vn_setlabel(struct vnode
*vp
, struct label
*intlabel
, vfs_context_t context
)
1289 if (!mac_vnode_enforce
)
1292 if (vp
->v_mount
== NULL
) {
1293 printf("vn_setlabel: null v_mount\n");
1294 if (vp
->v_type
!= VNON
)
1295 printf("vn_setlabel: null v_mount with non-VNON\n");
1299 if ((vp
->v_mount
->mnt_flag
& MNT_MULTILABEL
) == 0)
1303 * Multi-phase commit. First check the policies to confirm the
1304 * change is OK. Then commit via the filesystem. Finally,
1305 * update the actual vnode label. Question: maybe the filesystem
1306 * should update the vnode at the end as part of VNOP_SETLABEL()?
1308 error
= mac_vnode_check_label_update(context
, vp
, intlabel
);
1312 error
= VNOP_SETLABEL(vp
, intlabel
, context
);
1313 if (error
== ENOTSUP
) {
1314 error
= mac_vnode_label_store(context
, vp
,
1317 printf("%s: mac_vnode_label_store failed %d\n",
1321 mac_vnode_label_update(context
, vp
, intlabel
);
1324 printf("vn_setlabel: vop setlabel failed %d\n", error
);
1332 mac_vnode_label_associate_fdesc(struct mount
*mp
, struct fdescnode
*fnp
,
1333 struct vnode
*vp
, vfs_context_t ctx
)
1335 struct fileproc
*fp
;
1345 * If no backing file, let the policy choose which label to use.
1347 if (fnp
->fd_fd
== -1) {
1348 MAC_PERFORM(vnode_label_associate_file
, vfs_context_ucred(ctx
),
1349 mp
, mp
->mnt_mntlabel
, NULL
, NULL
, vp
, vp
->v_label
);
1353 p
= vfs_context_proc(ctx
);
1354 error
= fp_lookup(p
, fnp
->fd_fd
, &fp
, 0);
1358 if (fp
->f_fglob
== NULL
) {
1363 switch (fp
->f_fglob
->fg_type
) {
1365 fvp
= (struct vnode
*)fp
->f_fglob
->fg_data
;
1366 if ((error
= vnode_getwithref(fvp
)))
1368 MAC_PERFORM(vnode_label_copy
, fvp
->v_label
, vp
->v_label
);
1369 (void)vnode_put(fvp
);
1372 so
= (struct socket
*)fp
->f_fglob
->fg_data
;
1374 MAC_PERFORM(vnode_label_associate_socket
,
1375 vfs_context_ucred(ctx
), (socket_t
)so
, so
->so_label
,
1377 socket_unlock(so
, 1);
1380 pshm_label_associate(fp
, vp
, ctx
);
1383 psem_label_associate(fp
, vp
, ctx
);
1386 cpipe
= (struct pipe
*)fp
->f_fglob
->fg_data
;
1387 /* kern/sys_pipe.c:pipe_select() suggests this test. */
1388 if (cpipe
== (struct pipe
*)-1) {
1393 MAC_PERFORM(vnode_label_associate_pipe
, vfs_context_ucred(ctx
),
1394 cpipe
, cpipe
->pipe_label
, vp
, vp
->v_label
);
1398 case DTYPE_FSEVENTS
:
1400 MAC_PERFORM(vnode_label_associate_file
, vfs_context_ucred(ctx
),
1401 mp
, mp
->mnt_mntlabel
, fp
->f_fglob
, fp
->f_fglob
->fg_label
,
1406 fp_drop(p
, fnp
->fd_fd
, fp
, 0);