]>
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>
38 #include <security/mac_internal.h>
41 * Caller holds reference or sets VNODE_LABEL_NEEDREF to non-zero.
43 * Function will drop lock and reference on return.
46 vnode_label(struct mount
*mp
, struct vnode
*dvp
, struct vnode
*vp
,
47 struct componentname
*cnp
, int flags
, vfs_context_t ctx
)
55 if (vp
->v_lflag
& VL_LABELED
) {
56 if (!(flags
& VNODE_LABEL_NEEDREF
))
62 if ((flags
& VNODE_LABEL_NEEDREF
) && vnode_get_locked(vp
)) {
67 if ((vp
->v_lflag
& VL_LABEL
) == 0) {
68 vp
->v_lflag
|= VL_LABEL
;
70 /* Could sleep on disk I/O, drop lock. */
72 if (flags
& VNODE_LABEL_CREATE
)
73 error
= mac_vnode_notify_create(ctx
,
76 error
= mac_vnode_label_associate(mp
, vp
, ctx
);
79 if ((error
== 0) && (vp
->v_flag
& VNCACHEABLE
))
80 vp
->v_lflag
|= VL_LABELED
;
81 vp
->v_lflag
&= ~VL_LABEL
;
83 if (vp
->v_lflag
& VL_LABELWAIT
) {
84 vp
->v_lflag
&= ~VL_LABELWAIT
;
95 while (vp
->v_lflag
& VL_LABEL
) {
96 vp
->v_lflag
|= VL_LABELWAIT
;
97 error
= msleep(vp
->v_label
, &vp
->v_lock
, PVFS
|PDROP
,
100 if (error
== EWOULDBLOCK
) {
101 vprint("vnode label timeout", vp
);
105 /* XXX: what should be done if labeling failed (above)? */
106 vnode_put_locked(vp
);
115 * Clear the "labeled" flag on a VNODE.
116 * VNODE will have label re-associated upon
117 * next call to lookup().
119 * Caller verifies vfs_flags(vnode_mount(vp)) & MNT_MULTILABEL
120 * Caller holds vnode lock.
123 vnode_relabel(struct vnode
*vp
)
126 /* Wait for any other labeling to complete. */
127 while (vp
->v_lflag
& VL_LABEL
) {
128 vp
->v_lflag
|= VL_LABELWAIT
;
129 (void)msleep(vp
->v_label
, &vp
->v_lock
, PVFS
, "vnode_relabel", 0);
132 /* Clear labeled flag */
133 vp
->v_lflag
&= ~VL_LABELED
;
143 mac_vnop_setxattr (struct vnode
*vp
, const char *name
, char *buf
, size_t len
)
146 int options
= XATTR_NOSECURITY
;
147 char uio_buf
[ UIO_SIZEOF(1) ];
151 if (vfs_isrdonly(vp
->v_mount
))
154 ctx
= vfs_context_current();
155 auio
= uio_createwithbuffer(1, 0, UIO_SYSSPACE
, UIO_WRITE
,
156 &uio_buf
[0], sizeof(uio_buf
));
157 uio_addiov(auio
, CAST_USER_ADDR_T(buf
), len
);
159 error
= vn_setxattr(vp
, name
, auio
, options
, ctx
);
165 mac_vnop_getxattr (struct vnode
*vp
, const char *name
, char *buf
, size_t len
,
168 vfs_context_t ctx
= vfs_context_current();
169 int options
= XATTR_NOSECURITY
;
170 char uio_buf
[ UIO_SIZEOF(1) ];
174 auio
= uio_createwithbuffer(1, 0, UIO_SYSSPACE
, UIO_READ
,
175 &uio_buf
[0], sizeof(uio_buf
));
176 uio_addiov(auio
, CAST_USER_ADDR_T(buf
), len
);
178 error
= vn_getxattr(vp
, name
, auio
, attrlen
, options
, ctx
);
179 *attrlen
= len
- uio_resid(auio
);
185 mac_vnop_removexattr (struct vnode
*vp
, const char *name
)
187 vfs_context_t ctx
= vfs_context_current();
188 int options
= XATTR_NOSECURITY
;
191 if (vfs_isrdonly(vp
->v_mount
))
194 error
= vn_removexattr(vp
, name
, options
, ctx
);