]>
git.saurik.com Git - apple/xnu.git/blob - security/mac_vfs_subr.c
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@
28 #include <sys/param.h>
29 #include <sys/vnode.h>
30 #include <sys/vnode_internal.h>
31 #include <sys/kauth.h>
32 #include <sys/namei.h>
33 #include <sys/mount.h>
34 #include <sys/mount_internal.h>
35 #include <sys/uio_internal.h>
36 #include <sys/xattr.h>
37 #include "../bsd/sys/fsevents.h"
39 #include <security/mac_internal.h>
42 * Caller holds I/O reference on vnode
45 vnode_label(struct mount
*mp
, struct vnode
*dvp
, struct vnode
*vp
,
46 struct componentname
*cnp
, int flags
, vfs_context_t ctx
)
51 /* fast path checks... */
53 /* are we labeling vnodes? If not still notify of create */
54 #if CONFIG_MACF_LAZY_VNODE_LABELS
57 exit_fast
= (mac_label_vnodes
== 0);
60 if (flags
& VNODE_LABEL_CREATE
) {
61 error
= mac_vnode_notify_create(ctx
,
67 /* if already VL_LABELED */
68 if (vp
->v_lflag
& VL_LABELED
) {
75 * must revalidate state once we hold the lock
76 * since we could have blocked and someone else
77 * has since labeled this vnode
79 if (vp
->v_lflag
& VL_LABELED
) {
84 if ((vp
->v_lflag
& VL_LABEL
) == 0) {
85 vp
->v_lflag
|= VL_LABEL
;
87 /* Could sleep on disk I/O, drop lock. */
90 if (vp
->v_label
== NULL
) {
91 vp
->v_label
= mac_vnode_label_alloc();
94 if (flags
& VNODE_LABEL_CREATE
) {
95 error
= mac_vnode_notify_create(ctx
,
98 error
= mac_vnode_label_associate(mp
, vp
, ctx
);
103 if ((error
== 0) && (vp
->v_flag
& VNCACHEABLE
)) {
104 vp
->v_lflag
|= VL_LABELED
;
106 vp
->v_lflag
&= ~VL_LABEL
;
108 if (vp
->v_lflag
& VL_LABELWAIT
) {
109 vp
->v_lflag
&= ~VL_LABELWAIT
;
110 wakeup(&vp
->v_label
);
118 while (vp
->v_lflag
& VL_LABEL
) {
119 vp
->v_lflag
|= VL_LABELWAIT
;
121 error
= msleep(&vp
->v_label
, &vp
->v_lock
, PVFS
| PDROP
,
125 if (error
== EWOULDBLOCK
) {
126 vprint("vnode label timeout", vp
);
130 /* XXX: what should be done if labeling failed (above)? */
139 * Clear the "labeled" flag on a VNODE.
140 * VNODE will have label re-associated upon
141 * next call to lookup().
143 * Caller verifies vfs_flags(vnode_mount(vp)) & MNT_MULTILABEL
144 * Caller holds vnode lock.
147 vnode_relabel(struct vnode
*vp
)
149 /* Wait for any other labeling to complete. */
150 while (vp
->v_lflag
& VL_LABEL
) {
151 vp
->v_lflag
|= VL_LABELWAIT
;
152 (void)msleep(&vp
->v_label
, &vp
->v_lock
, PVFS
, "vnode_relabel", 0);
155 /* Clear labeled flag */
156 vp
->v_lflag
&= ~VL_LABELED
;
166 mac_vnop_setxattr(struct vnode
*vp
, const char *name
, char *buf
, size_t len
)
169 int options
= XATTR_NOSECURITY
;
170 char uio_buf
[UIO_SIZEOF(1)];
174 if (vfs_isrdonly(vp
->v_mount
)) {
178 ctx
= vfs_context_current();
179 auio
= uio_createwithbuffer(1, 0, UIO_SYSSPACE
, UIO_WRITE
,
180 &uio_buf
[0], sizeof(uio_buf
));
181 uio_addiov(auio
, CAST_USER_ADDR_T(buf
), len
);
183 error
= vn_setxattr(vp
, name
, auio
, options
, ctx
);
186 add_fsevent(FSE_XATTR_MODIFIED
, ctx
,
196 mac_vnop_getxattr(struct vnode
*vp
, const char *name
, char *buf
, size_t len
,
199 vfs_context_t ctx
= vfs_context_current();
200 int options
= XATTR_NOSECURITY
;
201 char uio_buf
[UIO_SIZEOF(1)];
205 auio
= uio_createwithbuffer(1, 0, UIO_SYSSPACE
, UIO_READ
,
206 &uio_buf
[0], sizeof(uio_buf
));
207 uio_addiov(auio
, CAST_USER_ADDR_T(buf
), len
);
209 error
= vn_getxattr(vp
, name
, auio
, attrlen
, options
, ctx
);
210 *attrlen
= len
- uio_resid(auio
);
216 mac_vnop_removexattr(struct vnode
*vp
, const char *name
)
218 vfs_context_t ctx
= vfs_context_current();
219 int options
= XATTR_NOSECURITY
;
222 if (vfs_isrdonly(vp
->v_mount
)) {
226 error
= vn_removexattr(vp
, name
, options
, ctx
);
229 add_fsevent(FSE_XATTR_REMOVED
, ctx
,