The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/security/mac_vfs_subr.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (c) 2007 Apple Inc. All rights reserved.
    3  *
    4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
    5  * 
    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.
   14  * 
   15  * Please obtain a copy of the License at
   16  * http://www.opensource.apple.com/apsl/ and read it before using this file.
   17  * 
   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.
   25  * 
   26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
   27  */
   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"
   38 
   39 #include <security/mac_internal.h>
   40 
   41 /*
   42  * Caller holds I/O reference on vnode
   43  */
   44 int
   45 vnode_label(struct mount *mp, struct vnode *dvp, struct vnode *vp,
   46             struct componentname *cnp, int flags, vfs_context_t ctx)
   47 {
   48         int error = 0;
   49 
   50 
   51         /* fast path checks... */
   52 
   53         /* are we labeling vnodes? If not still notify of create */
   54         if (mac_label_vnodes == 0) {
   55                 if (flags & VNODE_LABEL_CREATE)
   56                         error = mac_vnode_notify_create(ctx,
   57                             mp, dvp, vp, cnp);
   58                 return 0;
   59         }
   60 
   61         /* if already VL_LABELED */
   62         if (vp->v_lflag & VL_LABELED)
   63                 return (0);
   64 
   65         vnode_lock_spin(vp);
   66 
   67         /*
   68          * must revalidate state once we hold the lock
   69          * since we could have blocked and someone else
   70          * has since labeled this vnode
   71          */
   72         if (vp->v_lflag & VL_LABELED) {
   73                 vnode_unlock(vp);
   74                 return (0);
   75         }
   76 
   77         if ((vp->v_lflag & VL_LABEL) == 0) {
   78                 vp->v_lflag |= VL_LABEL;
   79 
   80                 /* Could sleep on disk I/O, drop lock. */
   81                 vnode_unlock(vp);
   82 
   83                 if (vp->v_label == NULL)
   84                         vp->v_label = mac_vnode_label_alloc();
   85 
   86                 if (flags & VNODE_LABEL_CREATE)
   87                         error = mac_vnode_notify_create(ctx,
   88                             mp, dvp, vp, cnp);
   89                 else
   90                         error = mac_vnode_label_associate(mp, vp, ctx);
   91 
   92                 vnode_lock_spin(vp);
   93 
   94                 if ((error == 0) && (vp->v_flag & VNCACHEABLE))
   95                         vp->v_lflag |= VL_LABELED;
   96                 vp->v_lflag &= ~VL_LABEL;
   97 
   98                 if (vp->v_lflag & VL_LABELWAIT) {
   99                         vp->v_lflag &= ~VL_LABELWAIT;
  100                         wakeup(&vp->v_label);
  101                 }
  102         } else {
  103                 struct timespec ts;
  104 
  105                 ts.tv_sec = 10;
  106                 ts.tv_nsec = 0;
  107 
  108                 while (vp->v_lflag & VL_LABEL) {
  109                         vp->v_lflag |= VL_LABELWAIT;
  110 
  111                         error = msleep(&vp->v_label, &vp->v_lock, PVFS|PDROP,
  112                                        "vnode_label", &ts);
  113                         vnode_lock_spin(vp);
  114 
  115                         if (error == EWOULDBLOCK) {
  116                                 vprint("vnode label timeout", vp);
  117                                 break;
  118                         }
  119                 }
  120                 /* XXX: what should be done if labeling failed (above)? */
  121         }
  122         vnode_unlock(vp);
  123 
  124         return (error);
  125 }
  126 
  127 
  128 /*
  129  * Clear the "labeled" flag on a VNODE.
  130  * VNODE will have label re-associated upon
  131  * next call to lookup().
  132  *
  133  * Caller verifies vfs_flags(vnode_mount(vp)) & MNT_MULTILABEL
  134  * Caller holds vnode lock.
  135  */
  136 void
  137 vnode_relabel(struct vnode *vp)
  138 {
  139 
  140         /* Wait for any other labeling to complete. */
  141         while (vp->v_lflag & VL_LABEL) {
  142                 vp->v_lflag |= VL_LABELWAIT;
  143                 (void)msleep(&vp->v_label, &vp->v_lock, PVFS, "vnode_relabel", 0);
  144         }
  145 
  146         /* Clear labeled flag */
  147         vp->v_lflag &= ~VL_LABELED;
  148 
  149         return;
  150 }
  151 
  152 /*
  153  * VFS XATTR helpers.
  154  */
  155 
  156 int
  157 mac_vnop_setxattr (struct vnode *vp, const char *name, char *buf, size_t len)
  158 {
  159         vfs_context_t ctx;
  160         int options = XATTR_NOSECURITY;
  161         char uio_buf[ UIO_SIZEOF(1) ];
  162         uio_t auio;
  163         int error;
  164 
  165         if (vfs_isrdonly(vp->v_mount))
  166                 return (EROFS);
  167 
  168         ctx = vfs_context_current();
  169         auio = uio_createwithbuffer(1, 0, UIO_SYSSPACE, UIO_WRITE,
  170                                     &uio_buf[0], sizeof(uio_buf));
  171         uio_addiov(auio, CAST_USER_ADDR_T(buf), len);
  172 
  173         error = vn_setxattr(vp, name, auio, options, ctx);
  174 #if CONFIG_FSE
  175         if (error == 0) {
  176                 add_fsevent(FSE_XATTR_MODIFIED, ctx,
  177                     FSE_ARG_VNODE, vp,
  178                     FSE_ARG_DONE);
  179         }
  180 #endif
  181 
  182         return (error);
  183 }
  184 
  185 int
  186 mac_vnop_getxattr (struct vnode *vp, const char *name, char *buf, size_t len,
  187                    size_t *attrlen)
  188 {
  189         vfs_context_t ctx = vfs_context_current();
  190         int options = XATTR_NOSECURITY;
  191         char uio_buf[ UIO_SIZEOF(1) ];
  192         uio_t auio;
  193         int error;
  194 
  195         auio = uio_createwithbuffer(1, 0, UIO_SYSSPACE, UIO_READ,
  196                                     &uio_buf[0], sizeof(uio_buf));
  197         uio_addiov(auio, CAST_USER_ADDR_T(buf), len);
  198 
  199         error = vn_getxattr(vp, name, auio, attrlen, options, ctx);
  200         *attrlen = len - uio_resid(auio);
  201 
  202         return (error);
  203 }
  204 
  205 int
  206 mac_vnop_removexattr (struct vnode *vp, const char *name)
  207 {
  208         vfs_context_t ctx = vfs_context_current();
  209         int options = XATTR_NOSECURITY;
  210         int error;
  211 
  212         if (vfs_isrdonly(vp->v_mount))
  213                 return (EROFS);
  214 
  215         error = vn_removexattr(vp, name, options, ctx);
  216 #if CONFIG_FSE
  217         if (error == 0) {
  218                 add_fsevent(FSE_XATTR_REMOVED, ctx,
  219                     FSE_ARG_VNODE, vp,
  220                     FSE_ARG_DONE);
  221         }
  222 #endif
  223 
  224         return (error);
  225 }

Cache object: 3042733320220952ddb1d76cdcd0b453


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.