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
)
423 if (!mac_proc_enforce
&& !mac_vnode_enforce
)
426 /* mark the new cred to indicate "matching" includes the label */
427 new->cr_flags
|= CRF_MAC_ENFORCE
;
429 cred
= vfs_context_ucred(ctx
);
430 MAC_PERFORM(cred_label_update_execve
, cred
, new, vp
, vp
->v_label
,
431 scriptvnodelabel
, execl
, &disjoint
);
437 mac_cred_check_label_update_execve(vfs_context_t ctx
, struct vnode
*vp
,
438 struct label
*scriptvnodelabel
, struct label
*execlabel
, struct proc
*p
)
443 if (!mac_proc_enforce
&& !mac_vnode_enforce
)
446 cred
= vfs_context_ucred(ctx
);
447 MAC_BOOLEAN(cred_check_label_update_execve
, ||, cred
, vp
, vp
->v_label
,
448 scriptvnodelabel
, execlabel
, p
);
454 mac_vnode_check_access(vfs_context_t ctx
, struct vnode
*vp
,
461 if (!mac_vnode_enforce
||
462 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
465 cred
= vfs_context_ucred(ctx
);
466 /* Convert {R,W,X}_OK values to V{READ,WRITE,EXEC} for entry points */
467 mask
= ACCESS_MODE_TO_VNODE_MASK(acc_mode
);
468 MAC_CHECK(vnode_check_access
, cred
, vp
, vp
->v_label
, mask
);
473 mac_vnode_check_chdir(vfs_context_t ctx
, struct vnode
*dvp
)
478 if (!mac_vnode_enforce
||
479 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
482 cred
= vfs_context_ucred(ctx
);
483 MAC_CHECK(vnode_check_chdir
, cred
, dvp
, dvp
->v_label
);
488 mac_vnode_check_chroot(vfs_context_t ctx
, struct vnode
*dvp
,
489 struct componentname
*cnp
)
494 if (!mac_vnode_enforce
||
495 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
498 cred
= vfs_context_ucred(ctx
);
499 MAC_CHECK(vnode_check_chroot
, cred
, dvp
, dvp
->v_label
, cnp
);
504 mac_vnode_check_create(vfs_context_t ctx
, struct vnode
*dvp
,
505 struct componentname
*cnp
, struct vnode_attr
*vap
)
510 if (!mac_vnode_enforce
||
511 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
514 cred
= vfs_context_ucred(ctx
);
515 MAC_CHECK(vnode_check_create
, cred
, dvp
, dvp
->v_label
, cnp
, vap
);
520 mac_vnode_check_unlink(vfs_context_t ctx
, struct vnode
*dvp
, struct vnode
*vp
,
521 struct componentname
*cnp
)
526 if (!mac_vnode_enforce
||
527 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
530 cred
= vfs_context_ucred(ctx
);
531 MAC_CHECK(vnode_check_unlink
, cred
, dvp
, dvp
->v_label
, vp
,
537 mac_vnode_check_deleteacl(vfs_context_t ctx
, struct vnode
*vp
,
543 if (!mac_vnode_enforce
||
544 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
547 cred
= vfs_context_ucred(ctx
);
548 MAC_CHECK(vnode_check_deleteacl
, cred
, vp
, vp
->v_label
, type
);
554 mac_vnode_check_deleteextattr(vfs_context_t ctx
, struct vnode
*vp
,
560 if (!mac_vnode_enforce
||
561 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
564 cred
= vfs_context_ucred(ctx
);
565 MAC_CHECK(vnode_check_deleteextattr
, cred
, vp
, vp
->v_label
, name
);
569 mac_vnode_check_exchangedata(vfs_context_t ctx
,
570 struct vnode
*v1
, struct vnode
*v2
)
575 if (!mac_vnode_enforce
||
576 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
579 cred
= vfs_context_ucred(ctx
);
580 MAC_CHECK(vnode_check_exchangedata
, cred
, v1
, v1
->v_label
,
588 mac_vnode_check_getacl(vfs_context_t ctx
, struct vnode
*vp
, acl_type_t type
)
593 if (!mac_vnode_enforce
||
594 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
597 cred
= vfs_context_ucred(ctx
);
598 MAC_CHECK(vnode_check_getacl
, cred
, vp
, vp
->v_label
, type
);
604 mac_vnode_check_getattrlist(vfs_context_t ctx
, struct vnode
*vp
,
605 struct attrlist
*alist
)
610 if (!mac_vnode_enforce
||
611 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
614 cred
= vfs_context_ucred(ctx
);
615 MAC_CHECK(vnode_check_getattrlist
, cred
, vp
, vp
->v_label
, alist
);
617 /* Falsify results instead of returning error? */
622 mac_vnode_check_exec(vfs_context_t ctx
, struct vnode
*vp
,
623 struct image_params
*imgp
)
628 if (!mac_vnode_enforce
|| !mac_proc_enforce
)
631 cred
= vfs_context_ucred(ctx
);
632 MAC_CHECK(vnode_check_exec
, cred
, vp
, vp
->v_label
,
633 (imgp
!= NULL
) ? imgp
->ip_execlabelp
: NULL
,
634 (imgp
!= NULL
) ? &imgp
->ip_ndp
->ni_cnd
: NULL
,
635 (imgp
!= NULL
) ? &imgp
->ip_csflags
: NULL
);
640 mac_vnode_check_signature(struct vnode
*vp
, unsigned char *sha1
,
641 void * signature
, size_t size
)
645 if (!mac_vnode_enforce
|| !mac_proc_enforce
)
648 MAC_CHECK(vnode_check_signature
, vp
, vp
->v_label
, sha1
, signature
, size
);
654 mac_vnode_check_getacl(vfs_context_t ctx
, struct vnode
*vp
, acl_type_t type
)
659 if (!mac_vnode_enforce
||
660 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
663 cred
= vfs_context_ucred(ctx
);
664 MAC_CHECK(vnode_check_getacl
, cred
, vp
, vp
->v_label
, type
);
670 mac_vnode_check_getextattr(vfs_context_t ctx
, struct vnode
*vp
,
671 const char *name
, struct uio
*uio
)
676 if (!mac_vnode_enforce
||
677 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
680 cred
= vfs_context_ucred(ctx
);
681 MAC_CHECK(vnode_check_getextattr
, cred
, vp
, vp
->v_label
,
687 mac_vnode_check_ioctl(vfs_context_t ctx
, struct vnode
*vp
, u_int cmd
)
692 if (!mac_vnode_enforce
||
693 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
696 cred
= vfs_context_ucred(ctx
);
697 MAC_CHECK(vnode_check_ioctl
, cred
, vp
, vp
->v_label
, cmd
);
702 mac_vnode_check_kqfilter(vfs_context_t ctx
, kauth_cred_t file_cred
,
703 struct knote
*kn
, struct vnode
*vp
)
708 if (!mac_vnode_enforce
||
709 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
712 cred
= vfs_context_ucred(ctx
);
713 MAC_CHECK(vnode_check_kqfilter
, cred
, file_cred
, kn
, vp
,
720 mac_vnode_check_link(vfs_context_t ctx
, struct vnode
*dvp
,
721 struct vnode
*vp
, struct componentname
*cnp
)
726 if (!mac_vnode_enforce
||
727 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
730 cred
= vfs_context_ucred(ctx
);
731 MAC_CHECK(vnode_check_link
, cred
, dvp
, dvp
->v_label
, vp
,
737 mac_vnode_check_listextattr(vfs_context_t ctx
, struct vnode
*vp
)
742 if (!mac_vnode_enforce
||
743 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
746 cred
= vfs_context_ucred(ctx
);
747 MAC_CHECK(vnode_check_listextattr
, cred
, vp
, vp
->v_label
);
752 mac_vnode_check_lookup(vfs_context_t ctx
, struct vnode
*dvp
,
753 struct componentname
*cnp
)
758 if (!mac_vnode_enforce
||
759 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
762 cred
= vfs_context_ucred(ctx
);
763 MAC_CHECK(vnode_check_lookup
, cred
, dvp
, dvp
->v_label
, cnp
);
768 mac_vnode_check_open(vfs_context_t ctx
, struct vnode
*vp
, int acc_mode
)
773 if (!mac_vnode_enforce
||
774 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
777 cred
= vfs_context_ucred(ctx
);
778 MAC_CHECK(vnode_check_open
, cred
, vp
, vp
->v_label
, acc_mode
);
783 mac_vnode_check_read(vfs_context_t ctx
, struct ucred
*file_cred
,
789 if (!mac_vnode_enforce
||
790 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
793 cred
= vfs_context_ucred(ctx
);
794 MAC_CHECK(vnode_check_read
, cred
, file_cred
, vp
,
801 mac_vnode_check_readdir(vfs_context_t ctx
, struct vnode
*dvp
)
806 if (!mac_vnode_enforce
||
807 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
810 cred
= vfs_context_ucred(ctx
);
811 MAC_CHECK(vnode_check_readdir
, cred
, dvp
, dvp
->v_label
);
816 mac_vnode_check_readlink(vfs_context_t ctx
, struct vnode
*vp
)
821 if (!mac_vnode_enforce
||
822 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
825 cred
= vfs_context_ucred(ctx
);
826 MAC_CHECK(vnode_check_readlink
, cred
, vp
, vp
->v_label
);
831 mac_vnode_check_label_update(vfs_context_t ctx
, struct vnode
*vp
,
832 struct label
*newlabel
)
837 if (!mac_vnode_enforce
||
838 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
841 cred
= vfs_context_ucred(ctx
);
842 MAC_CHECK(vnode_check_label_update
, cred
, vp
, vp
->v_label
, newlabel
);
848 mac_vnode_check_rename_from(vfs_context_t ctx
, struct vnode
*dvp
,
849 struct vnode
*vp
, struct componentname
*cnp
)
854 if (!mac_vnode_enforce
||
855 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
858 cred
= vfs_context_ucred(ctx
);
859 MAC_CHECK(vnode_check_rename_from
, cred
, dvp
, dvp
->v_label
, vp
,
865 mac_vnode_check_rename_to(vfs_context_t ctx
, struct vnode
*dvp
,
866 struct vnode
*vp
, int samedir
, struct componentname
*cnp
)
871 if (!mac_vnode_enforce
||
872 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
875 cred
= vfs_context_ucred(ctx
);
876 MAC_CHECK(vnode_check_rename_to
, cred
, dvp
, dvp
->v_label
, vp
,
877 vp
!= NULL
? vp
->v_label
: NULL
, samedir
, cnp
);
882 mac_vnode_check_revoke(vfs_context_t ctx
, struct vnode
*vp
)
887 if (!mac_vnode_enforce
||
888 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
891 cred
= vfs_context_ucred(ctx
);
892 MAC_CHECK(vnode_check_revoke
, cred
, vp
, vp
->v_label
);
897 mac_vnode_check_select(vfs_context_t ctx
, struct vnode
*vp
, int which
)
902 if (!mac_vnode_enforce
||
903 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
906 cred
= vfs_context_ucred(ctx
);
907 MAC_CHECK(vnode_check_select
, cred
, vp
, vp
->v_label
, which
);
913 mac_vnode_check_setacl(vfs_context_t ctx
, struct vnode
*vp
, acl_type_t type
,
919 if (!mac_vnode_enforce
||
920 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
923 cred
= vfs_context_ucred(ctx
);
924 MAC_CHECK(vnode_check_setacl
, cred
, vp
, vp
->v_label
, type
, acl
);
930 mac_vnode_check_setattrlist(vfs_context_t ctx
, struct vnode
*vp
,
931 struct attrlist
*alist
)
936 if (!mac_vnode_enforce
||
937 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
940 cred
= vfs_context_ucred(ctx
);
941 MAC_CHECK(vnode_check_setattrlist
, cred
, vp
, vp
->v_label
, alist
);
946 mac_vnode_check_setextattr(vfs_context_t ctx
, struct vnode
*vp
,
947 const char *name
, struct uio
*uio
)
952 if (!mac_vnode_enforce
||
953 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
956 cred
= vfs_context_ucred(ctx
);
957 MAC_CHECK(vnode_check_setextattr
, cred
, vp
, vp
->v_label
,
963 mac_vnode_check_setflags(vfs_context_t ctx
, struct vnode
*vp
, u_long flags
)
968 if (!mac_vnode_enforce
||
969 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
972 cred
= vfs_context_ucred(ctx
);
973 MAC_CHECK(vnode_check_setflags
, cred
, vp
, vp
->v_label
, flags
);
978 mac_vnode_check_setmode(vfs_context_t ctx
, struct vnode
*vp
, mode_t mode
)
983 if (!mac_vnode_enforce
||
984 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
987 cred
= vfs_context_ucred(ctx
);
988 MAC_CHECK(vnode_check_setmode
, cred
, vp
, vp
->v_label
, mode
);
993 mac_vnode_check_setowner(vfs_context_t ctx
, struct vnode
*vp
, uid_t uid
,
999 if (!mac_vnode_enforce
||
1000 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1003 cred
= vfs_context_ucred(ctx
);
1004 MAC_CHECK(vnode_check_setowner
, cred
, vp
, vp
->v_label
, uid
, gid
);
1009 mac_vnode_check_setutimes(vfs_context_t ctx
, struct vnode
*vp
,
1010 struct timespec atime
, struct timespec mtime
)
1015 if (!mac_vnode_enforce
||
1016 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1019 cred
= vfs_context_ucred(ctx
);
1020 MAC_CHECK(vnode_check_setutimes
, cred
, vp
, vp
->v_label
, atime
,
1026 mac_vnode_check_stat(vfs_context_t ctx
, struct ucred
*file_cred
,
1032 if (!mac_vnode_enforce
||
1033 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1036 cred
= vfs_context_ucred(ctx
);
1037 MAC_CHECK(vnode_check_stat
, cred
, file_cred
, vp
,
1043 mac_vnode_check_truncate(vfs_context_t ctx
, struct ucred
*file_cred
,
1049 if (!mac_vnode_enforce
||
1050 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1053 cred
= vfs_context_ucred(ctx
);
1054 MAC_CHECK(vnode_check_truncate
, cred
, file_cred
, vp
,
1061 mac_vnode_check_write(vfs_context_t ctx
, struct ucred
*file_cred
,
1067 if (!mac_vnode_enforce
||
1068 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1071 cred
= vfs_context_ucred(ctx
);
1072 MAC_CHECK(vnode_check_write
, cred
, file_cred
, vp
, vp
->v_label
);
1078 mac_vnode_label_update(vfs_context_t ctx
, struct vnode
*vp
, struct label
*newlabel
)
1080 kauth_cred_t cred
= vfs_context_ucred(ctx
);
1083 MAC_PERFORM(vnode_label_update
, cred
, vp
, vp
->v_label
, newlabel
);
1088 mac_mount_label_associate(vfs_context_t ctx
, struct mount
*mp
)
1090 kauth_cred_t cred
= vfs_context_ucred(ctx
);
1092 /* XXX: eventually this logic may be handled by the policy? */
1094 /* We desire MULTILABEL for the root filesystem. */
1095 if ((mp
->mnt_flag
& MNT_ROOTFS
) &&
1096 (strcmp(mp
->mnt_vfsstat
.f_fstypename
, "hfs") == 0))
1097 mp
->mnt_flag
|= MNT_MULTILABEL
;
1099 /* MULTILABEL on DEVFS. */
1100 if (strcmp(mp
->mnt_vfsstat
.f_fstypename
, "devfs") == 0)
1101 mp
->mnt_flag
|= MNT_MULTILABEL
;
1103 /* MULTILABEL on FDESC pseudo-filesystem. */
1104 if (strcmp(mp
->mnt_vfsstat
.f_fstypename
, "fdesc") == 0)
1105 mp
->mnt_flag
|= MNT_MULTILABEL
;
1107 /* MULTILABEL on all NFS filesystems. */
1108 if (strcmp(mp
->mnt_vfsstat
.f_fstypename
, "nfs") == 0)
1109 mp
->mnt_flag
|= MNT_MULTILABEL
;
1111 /* MULTILABEL on all AFP filesystems. */
1112 if (strcmp(mp
->mnt_vfsstat
.f_fstypename
, "afpfs") == 0)
1113 mp
->mnt_flag
|= MNT_MULTILABEL
;
1115 if (mp
->mnt_vtable
!= NULL
) {
1116 /* Any filesystem that supports native XATTRs. */
1117 if ((mp
->mnt_vtable
->vfc_vfsflags
& VFC_VFSNATIVEXATTR
))
1118 mp
->mnt_flag
|= MNT_MULTILABEL
;
1120 /* Filesystem does not support multilabel. */
1121 if ((mp
->mnt_vtable
->vfc_vfsflags
& VFC_VFSNOMACLABEL
) &&
1122 (mp
->mnt_flag
& MNT_MULTILABEL
))
1123 mp
->mnt_flag
&= ~MNT_MULTILABEL
;
1126 MAC_PERFORM(mount_label_associate
, cred
, mp
, mp
->mnt_mntlabel
);
1128 printf("MAC Framework enabling %s support: %s -> %s (%s)\n",
1129 mp
->mnt_flag
& MNT_MULTILABEL
? "multilabel" : "singlelabel",
1130 mp
->mnt_vfsstat
.f_mntfromname
,
1131 mp
->mnt_vfsstat
.f_mntonname
,
1132 mp
->mnt_vfsstat
.f_fstypename
);
1137 mac_mount_check_mount(vfs_context_t ctx
, struct vnode
*vp
,
1138 struct componentname
*cnp
, const char *vfc_name
)
1143 if (!mac_vnode_enforce
||
1144 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1147 cred
= vfs_context_ucred(ctx
);
1148 MAC_CHECK(mount_check_mount
, cred
, vp
, vp
->v_label
, cnp
, vfc_name
);
1154 mac_mount_check_remount(vfs_context_t ctx
, struct mount
*mp
)
1159 if (!mac_vnode_enforce
||
1160 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1163 cred
= vfs_context_ucred(ctx
);
1164 MAC_CHECK(mount_check_remount
, cred
, mp
, mp
->mnt_mntlabel
);
1170 mac_mount_check_umount(vfs_context_t ctx
, struct mount
*mp
)
1175 if (!mac_vnode_enforce
||
1176 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1179 cred
= vfs_context_ucred(ctx
);
1180 MAC_CHECK(mount_check_umount
, cred
, mp
, mp
->mnt_mntlabel
);
1186 mac_mount_check_getattr(vfs_context_t ctx
, struct mount
*mp
,
1187 struct vfs_attr
*vfa
)
1192 if (!mac_vnode_enforce
||
1193 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1196 cred
= vfs_context_ucred(ctx
);
1197 MAC_CHECK(mount_check_getattr
, cred
, mp
, mp
->mnt_mntlabel
, vfa
);
1202 mac_mount_check_setattr(vfs_context_t ctx
, struct mount
*mp
,
1203 struct vfs_attr
*vfa
)
1208 if (!mac_vnode_enforce
||
1209 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1212 cred
= vfs_context_ucred(ctx
);
1213 MAC_CHECK(mount_check_setattr
, cred
, mp
, mp
->mnt_mntlabel
, vfa
);
1218 mac_mount_check_stat(vfs_context_t ctx
, struct mount
*mount
)
1223 if (!mac_vnode_enforce
||
1224 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1227 cred
= vfs_context_ucred(ctx
);
1228 MAC_CHECK(mount_check_stat
, cred
, mount
, mount
->mnt_mntlabel
);
1234 mac_mount_check_label_update(vfs_context_t ctx
, struct mount
*mount
)
1239 if (!mac_vnode_enforce
||
1240 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1243 cred
= vfs_context_ucred(ctx
);
1244 MAC_CHECK(mount_check_label_update
, cred
, mount
, mount
->mnt_mntlabel
);
1250 mac_mount_check_fsctl(vfs_context_t ctx
, struct mount
*mp
, u_int cmd
)
1255 if (!mac_vnode_enforce
||
1256 !mac_context_check_enforce(ctx
, MAC_VNODE_ENFORCE
))
1259 cred
= vfs_context_ucred(ctx
);
1260 MAC_CHECK(mount_check_fsctl
, cred
, mp
, mp
->mnt_mntlabel
, cmd
);
1266 mac_devfs_label_associate_device(dev_t dev
, struct devnode
*de
,
1267 const char *fullpath
)
1269 if (!mac_device_enforce
)
1272 MAC_PERFORM(devfs_label_associate_device
, dev
, de
, de
->dn_label
,
1277 mac_devfs_label_associate_directory(const char *dirname
, int dirnamelen
,
1278 struct devnode
*de
, const char *fullpath
)
1280 if (!mac_device_enforce
)
1283 MAC_PERFORM(devfs_label_associate_directory
, dirname
, dirnamelen
, de
,
1284 de
->dn_label
, fullpath
);
1288 vn_setlabel(struct vnode
*vp
, struct label
*intlabel
, vfs_context_t context
)
1292 if (!mac_vnode_enforce
)
1295 if (vp
->v_mount
== NULL
) {
1296 printf("vn_setlabel: null v_mount\n");
1297 if (vp
->v_type
!= VNON
)
1298 printf("vn_setlabel: null v_mount with non-VNON\n");
1302 if ((vp
->v_mount
->mnt_flag
& MNT_MULTILABEL
) == 0)
1306 * Multi-phase commit. First check the policies to confirm the
1307 * change is OK. Then commit via the filesystem. Finally,
1308 * update the actual vnode label. Question: maybe the filesystem
1309 * should update the vnode at the end as part of VNOP_SETLABEL()?
1311 error
= mac_vnode_check_label_update(context
, vp
, intlabel
);
1315 error
= VNOP_SETLABEL(vp
, intlabel
, context
);
1316 if (error
== ENOTSUP
) {
1317 error
= mac_vnode_label_store(context
, vp
,
1320 printf("%s: mac_vnode_label_store failed %d\n",
1324 mac_vnode_label_update(context
, vp
, intlabel
);
1327 printf("vn_setlabel: vop setlabel failed %d\n", error
);
1335 mac_vnode_label_associate_fdesc(struct mount
*mp
, struct fdescnode
*fnp
,
1336 struct vnode
*vp
, vfs_context_t ctx
)
1338 struct fileproc
*fp
;
1348 * If no backing file, let the policy choose which label to use.
1350 if (fnp
->fd_fd
== -1) {
1351 MAC_PERFORM(vnode_label_associate_file
, vfs_context_ucred(ctx
),
1352 mp
, mp
->mnt_mntlabel
, NULL
, NULL
, vp
, vp
->v_label
);
1356 p
= vfs_context_proc(ctx
);
1357 error
= fp_lookup(p
, fnp
->fd_fd
, &fp
, 0);
1361 if (fp
->f_fglob
== NULL
) {
1366 switch (fp
->f_fglob
->fg_type
) {
1368 fvp
= (struct vnode
*)fp
->f_fglob
->fg_data
;
1369 if ((error
= vnode_getwithref(fvp
)))
1371 MAC_PERFORM(vnode_label_copy
, fvp
->v_label
, vp
->v_label
);
1372 (void)vnode_put(fvp
);
1375 so
= (struct socket
*)fp
->f_fglob
->fg_data
;
1377 MAC_PERFORM(vnode_label_associate_socket
,
1378 vfs_context_ucred(ctx
), (socket_t
)so
, so
->so_label
,
1380 socket_unlock(so
, 1);
1383 pshm_label_associate(fp
, vp
, ctx
);
1386 psem_label_associate(fp
, vp
, ctx
);
1389 cpipe
= (struct pipe
*)fp
->f_fglob
->fg_data
;
1390 /* kern/sys_pipe.c:pipe_select() suggests this test. */
1391 if (cpipe
== (struct pipe
*)-1) {
1396 MAC_PERFORM(vnode_label_associate_pipe
, vfs_context_ucred(ctx
),
1397 cpipe
, cpipe
->pipe_label
, vp
, vp
->v_label
);
1401 case DTYPE_FSEVENTS
:
1403 MAC_PERFORM(vnode_label_associate_file
, vfs_context_ucred(ctx
),
1404 mp
, mp
->mnt_mntlabel
, fp
->f_fglob
, fp
->f_fglob
->fg_label
,
1409 fp_drop(p
, fnp
->fd_fd
, fp
, 0);