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.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 /*-
   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.
   33  *
   34  * This software was developed by Robert Watson and Ilmar Habibulin for the
   35  * TrustedBSD Project.
   36  *
   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.
   41  *
   42  * Redistribution and use in source and binary forms, with or without
   43  * modification, are permitted provided that the following conditions
   44  * are met:
   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.
   50  *
   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
   61  * SUCH DAMAGE.
   62  *
   63  */
   64 
   65 #include <sys/param.h>
   66 #include <sys/systm.h>
   67 #include <sys/kernel.h>
   68 #include <sys/proc.h>
   69 #include <sys/kauth.h>
   70 
   71 #include <sys/file_internal.h>
   72 #include <sys/imgact.h>
   73 #include <sys/namei.h>
   74 #include <sys/mount_internal.h>
   75 #include <sys/pipe.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>
   80 
   81 #include <miscfs/devfs/devfsdefs.h>
   82 #include <miscfs/fdesc/fdesc.h>
   83 
   84 #include <security/mac_internal.h>
   85 
   86 /* convert {R,W,X}_OK values to V{READ,WRITE,EXEC} */
   87 #define ACCESS_MODE_TO_VNODE_MASK(m)    (m << 6)
   88 
   89 static struct label *
   90 mac_devfsdirent_label_alloc(void)
   91 {
   92         struct label *label;
   93 
   94         label = mac_labelzone_alloc(MAC_WAITOK);
   95         if (label == NULL)
   96                 return (NULL);
   97         MAC_PERFORM(devfs_label_init, label);
   98         return (label);
   99 }
  100 
  101 void
  102 mac_devfs_label_init(struct devnode *de)
  103 {
  104 
  105         de->dn_label = mac_devfsdirent_label_alloc();
  106 }
  107 
  108 static struct label *
  109 mac_mount_label_alloc(void)
  110 {
  111         struct label *label;
  112 
  113         label = mac_labelzone_alloc(MAC_WAITOK);
  114         if (label == NULL)
  115                 return (NULL);
  116         MAC_PERFORM(mount_label_init, label);
  117         return (label);
  118 }
  119 
  120 void
  121 mac_mount_label_init(struct mount *mp)
  122 {
  123 
  124         mp->mnt_mntlabel = mac_mount_label_alloc();
  125 }
  126 
  127 struct label *
  128 mac_vnode_label_alloc(void)
  129 {
  130         struct label *label;
  131 
  132         label = mac_labelzone_alloc(MAC_WAITOK);
  133         if (label == NULL)
  134                 return (NULL);
  135         MAC_PERFORM(vnode_label_init, label);
  136         return (label);
  137 }
  138 
  139 void
  140 mac_vnode_label_init(vnode_t vp)
  141 {
  142 
  143         vp->v_label = mac_vnode_label_alloc();
  144 }
  145 
  146 /* 
  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.
  150 */
  151 void
  152 mac_vnode_label_recycle(vnode_t vp)
  153 {
  154 
  155         MAC_PERFORM(vnode_label_recycle, vp->v_label);
  156 }
  157 
  158 static void
  159 mac_devfs_label_free(struct label *label)
  160 {
  161         MAC_PERFORM(devfs_label_destroy, label);
  162         mac_labelzone_free(label);
  163 }
  164 
  165 void
  166 mac_devfs_label_destroy(struct devnode *de)
  167 {
  168         if (de->dn_label != NULL) {
  169                 mac_devfs_label_free(de->dn_label);
  170                 de->dn_label = NULL;
  171         }
  172 }
  173 
  174 static void
  175 mac_mount_label_free(struct label *label)
  176 {
  177 
  178         MAC_PERFORM(mount_label_destroy, label);
  179         mac_labelzone_free(label);
  180 }
  181 
  182 void
  183 mac_mount_label_destroy(struct mount *mp)
  184 {
  185 
  186 
  187         if (mp->mnt_mntlabel != NULL) {
  188                 mac_mount_label_free(mp->mnt_mntlabel);
  189                 mp->mnt_mntlabel = NULL;
  190         }
  191 }
  192 
  193 void
  194 mac_vnode_label_free(struct label *label)
  195 {
  196 
  197         MAC_PERFORM(vnode_label_destroy, label);
  198         mac_labelzone_free(label);
  199 }
  200 
  201 #ifndef __APPLE__
  202 void
  203 mac_vnode_label_destroy(struct vnode *vp)
  204 {
  205 
  206         mac_vnode_label_free(vp->v_label);
  207         vp->v_label = NULL;
  208 }
  209 #endif
  210 
  211 void
  212 mac_vnode_label_copy(struct label *src, struct label *dest)
  213 {
  214 
  215         MAC_PERFORM(vnode_label_copy, src, dest);
  216 }
  217 
  218 int
  219 mac_vnode_label_externalize_audit(struct vnode *vp, struct mac *mac)
  220 {
  221         int error;
  222 
  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);
  226 
  227         return (error);
  228 }
  229 
  230 int
  231 mac_vnode_label_externalize(struct label *label, char *elements,
  232     char *outbuf, size_t outbuflen, int flags __unused)
  233 {
  234         int error;
  235 
  236         error = MAC_EXTERNALIZE(vnode, label, elements, outbuf, outbuflen);
  237 
  238         return (error);
  239 }
  240 
  241 int
  242 mac_vnode_label_internalize(struct label *label, char *string)
  243 {
  244         int error;
  245 
  246         error = MAC_INTERNALIZE(vnode, label, string);
  247 
  248         return (error);
  249 }
  250 
  251 int
  252 mac_mount_label_internalize(struct label *label, char *string)
  253 {
  254         int error;
  255 
  256         error = MAC_INTERNALIZE(mount, label, string);
  257 
  258         return (error);
  259 }
  260 
  261 int
  262 mac_mount_label_externalize(struct label *label, char *elements,
  263     char *outbuf, size_t outbuflen)
  264 {
  265         int error;
  266 
  267         error = MAC_EXTERNALIZE(mount, label, elements, outbuf, outbuflen);
  268 
  269         return (error);
  270 }
  271 
  272 void
  273 mac_devfs_label_copy(struct label *src, struct label *dest)
  274 {
  275         if (!mac_device_enforce)
  276                 return;
  277 
  278         MAC_PERFORM(devfs_label_copy, src, dest);
  279 }
  280 
  281 void
  282 mac_devfs_label_update(struct mount *mp, struct devnode *de,
  283     struct vnode *vp)
  284 {
  285 
  286         if (!mac_device_enforce)
  287                 return;
  288 
  289         MAC_PERFORM(devfs_label_update, mp, de, de->dn_label, vp,
  290             vp->v_label);
  291 }
  292 
  293 int
  294 mac_vnode_label_associate(struct mount *mp, struct vnode *vp, vfs_context_t ctx)
  295 {
  296         struct devnode *dnp;
  297         struct fdescnode *fnp;
  298         int error = 0;
  299 
  300         if (!mac_vnode_enforce)
  301                 return (error);
  302 
  303         /* XXX: should not inspect v_tag in kernel! */
  304         switch (vp->v_tag) {
  305         case VT_DEVFS:
  306                 dnp = VTODN(vp);
  307                 mac_vnode_label_associate_devfs(mp, dnp, vp);
  308                 break;
  309         case VT_FDESC:
  310                 fnp = VTOFDESC(vp);
  311                 error = mac_vnode_label_associate_fdesc(mp, fnp, vp, ctx);
  312                 break;
  313         default:
  314                 error = mac_vnode_label_associate_extattr(mp, vp);
  315                 break;
  316         }
  317 
  318         return (error);
  319 }
  320 
  321 void
  322 mac_vnode_label_associate_devfs(struct mount *mp, struct devnode *de,
  323     struct vnode *vp)
  324 {
  325         if (!mac_device_enforce)
  326                 return;
  327 
  328         MAC_PERFORM(vnode_label_associate_devfs,
  329             mp, mp ? mp->mnt_mntlabel : NULL,
  330             de, de->dn_label,
  331             vp, vp->v_label);
  332 }
  333 
  334 int
  335 mac_vnode_label_associate_extattr(struct mount *mp, struct vnode *vp)
  336 {
  337         int error;
  338 
  339         MAC_CHECK(vnode_label_associate_extattr, mp, mp->mnt_mntlabel, vp,
  340             vp->v_label);
  341 
  342         return (error);
  343 }
  344 
  345 void
  346 mac_vnode_label_associate_singlelabel(struct mount *mp, struct vnode *vp)
  347 {
  348 
  349         if (!mac_vnode_enforce)
  350                 return;
  351 
  352         MAC_PERFORM(vnode_label_associate_singlelabel, mp,
  353             mp ? mp->mnt_mntlabel : NULL, vp, vp->v_label);
  354 }
  355 
  356 int
  357 mac_vnode_notify_create(vfs_context_t ctx, struct mount *mp,
  358     struct vnode *dvp, struct vnode *vp, struct componentname *cnp)
  359 {
  360         kauth_cred_t cred;
  361         int error;
  362 
  363         if (!mac_vnode_enforce || 
  364                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  365                 return (0);
  366 
  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);
  370 
  371         return (error);
  372 }
  373 
  374 /*
  375  * Extended attribute 'name' was updated via
  376  * vn_setxattr() or vn_removexattr().  Allow the
  377  * policy to update the vnode label.
  378  */
  379 void
  380 mac_vnode_label_update_extattr(struct mount *mp, struct vnode *vp,
  381     const char *name)
  382 {
  383         int error = 0;
  384 
  385         if (!mac_vnode_enforce)
  386                 return;
  387 
  388         MAC_PERFORM(vnode_label_update_extattr, mp, mp->mnt_mntlabel, vp,
  389                     vp->v_label, name);
  390         if (error == 0)
  391                 return;
  392 
  393         vnode_lock(vp);
  394         vnode_relabel(vp);
  395         vnode_unlock(vp);
  396         return;
  397 }
  398 
  399 static int
  400 mac_vnode_label_store(vfs_context_t ctx, struct vnode *vp,
  401     struct label *intlabel)
  402 {
  403         kauth_cred_t cred;
  404         int error;
  405 
  406         if (!mac_vnode_enforce &&
  407             !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  408                 return 0;
  409 
  410         cred = vfs_context_ucred(ctx);
  411         MAC_CHECK(vnode_label_store, cred, vp, vp->v_label, intlabel);
  412 
  413         return (error);
  414 }
  415 
  416 void
  417 mac_cred_label_update_execve(vfs_context_t ctx, kauth_cred_t new, struct vnode *vp,
  418     struct label *scriptvnodelabel, struct label *execl)
  419 {
  420         kauth_cred_t cred;
  421 
  422         if (!mac_proc_enforce && !mac_vnode_enforce)
  423                 return; 
  424 
  425         /* mark the new cred to indicate "matching" includes the label */
  426         new->cr_flags |= CRF_MAC_ENFORCE;
  427 
  428         cred = vfs_context_ucred(ctx);
  429         MAC_PERFORM(cred_label_update_execve, cred, new, vp, vp->v_label,
  430             scriptvnodelabel, execl);
  431 }
  432 
  433 int
  434 mac_cred_check_label_update_execve(vfs_context_t ctx, struct vnode *vp,
  435     struct label *scriptvnodelabel, struct label *execlabel, struct proc *p)
  436 {
  437         kauth_cred_t cred;
  438         int result = 0;
  439 
  440         if (!mac_proc_enforce && !mac_vnode_enforce)
  441                 return result;
  442 
  443         cred = vfs_context_ucred(ctx);
  444         MAC_BOOLEAN(cred_check_label_update_execve, ||, cred, vp, vp->v_label,
  445                     scriptvnodelabel, execlabel, p);
  446 
  447         return (result);
  448 }
  449 
  450 int
  451 mac_vnode_check_access(vfs_context_t ctx, struct vnode *vp,
  452     int acc_mode)
  453 {
  454         kauth_cred_t cred;
  455         int error;
  456         int mask;
  457 
  458         if (!mac_vnode_enforce ||
  459             !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  460                 return 0;
  461 
  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);
  466         return (error);
  467  }
  468 
  469 int
  470 mac_vnode_check_chdir(vfs_context_t ctx, struct vnode *dvp)
  471 {
  472         kauth_cred_t cred;
  473         int error;
  474 
  475         if (!mac_vnode_enforce || 
  476             !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  477                 return (0);
  478 
  479         cred = vfs_context_ucred(ctx);
  480         MAC_CHECK(vnode_check_chdir, cred, dvp, dvp->v_label);
  481         return (error);
  482 }
  483 
  484 int
  485 mac_vnode_check_chroot(vfs_context_t ctx, struct vnode *dvp,
  486     struct componentname *cnp)
  487 {
  488         kauth_cred_t cred;
  489         int error;
  490 
  491         if (!mac_vnode_enforce || 
  492                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  493                 return (0);
  494 
  495         cred = vfs_context_ucred(ctx);
  496         MAC_CHECK(vnode_check_chroot, cred, dvp, dvp->v_label, cnp);
  497         return (error);
  498 }
  499 
  500 int
  501 mac_vnode_check_create(vfs_context_t ctx, struct vnode *dvp,
  502     struct componentname *cnp, struct vnode_attr *vap)
  503 {
  504         kauth_cred_t cred;
  505         int error;
  506 
  507         if (!mac_vnode_enforce || 
  508                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  509                 return (0);
  510 
  511         cred = vfs_context_ucred(ctx);
  512         MAC_CHECK(vnode_check_create, cred, dvp, dvp->v_label, cnp, vap);
  513         return (error);
  514 }
  515 
  516 int
  517 mac_vnode_check_unlink(vfs_context_t ctx, struct vnode *dvp, struct vnode *vp,
  518     struct componentname *cnp)
  519 {
  520         kauth_cred_t cred;
  521         int error;
  522 
  523         if (!mac_vnode_enforce || 
  524                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  525                 return (0);
  526 
  527         cred = vfs_context_ucred(ctx);
  528         MAC_CHECK(vnode_check_unlink, cred, dvp, dvp->v_label, vp,
  529             vp->v_label, cnp);
  530         return (error);
  531 }
  532 #if 0
  533 int
  534 mac_vnode_check_deleteacl(vfs_context_t ctx, struct vnode *vp,
  535     acl_type_t type)
  536 {
  537         kauth_cred_t cred;
  538         int error;
  539 
  540         if (!mac_vnode_enforce || 
  541                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  542                 return (0);
  543 
  544         cred = vfs_context_ucred(ctx);
  545         MAC_CHECK(vnode_check_deleteacl, cred, vp, vp->v_label, type);
  546         return (error);
  547 }
  548 #endif
  549 
  550 int
  551 mac_vnode_check_deleteextattr(vfs_context_t ctx, struct vnode *vp,
  552     const char *name)
  553 {
  554         kauth_cred_t cred;
  555         int error;
  556 
  557         if (!mac_vnode_enforce || 
  558                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  559                 return (0);
  560 
  561         cred = vfs_context_ucred(ctx);
  562         MAC_CHECK(vnode_check_deleteextattr, cred, vp, vp->v_label, name);
  563         return (error);
  564 }
  565 int
  566 mac_vnode_check_exchangedata(vfs_context_t ctx,
  567     struct vnode *v1, struct vnode *v2)
  568 {
  569         kauth_cred_t cred;
  570         int error;
  571 
  572         if (!mac_vnode_enforce || 
  573                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  574                 return (0);
  575 
  576         cred = vfs_context_ucred(ctx);
  577         MAC_CHECK(vnode_check_exchangedata, cred, v1, v1->v_label, 
  578             v2, v2->v_label);
  579 
  580         return (error);
  581 }
  582 
  583 #if 0
  584 int
  585 mac_vnode_check_getacl(vfs_context_t ctx, struct vnode *vp, acl_type_t type)
  586 {
  587         kauth_cred_t cred;
  588         int error;
  589 
  590         if (!mac_vnode_enforce || 
  591                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  592                 return (0);
  593 
  594         cred = vfs_context_ucred(ctx);
  595         MAC_CHECK(vnode_check_getacl, cred, vp, vp->v_label, type);
  596         return (error);
  597 }
  598 #endif
  599 
  600 int
  601 mac_vnode_check_getattrlist(vfs_context_t ctx, struct vnode *vp,
  602     struct attrlist *alist)
  603 {
  604         kauth_cred_t cred;
  605         int error;
  606 
  607         if (!mac_vnode_enforce || 
  608                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  609                 return (0);
  610 
  611         cred = vfs_context_ucred(ctx);
  612         MAC_CHECK(vnode_check_getattrlist, cred, vp, vp->v_label, alist);
  613 
  614         /* Falsify results instead of returning error? */
  615         return (error);
  616 }
  617 
  618 int
  619 mac_vnode_check_exec(vfs_context_t ctx, struct vnode *vp,
  620     struct image_params *imgp)
  621 {
  622         kauth_cred_t cred;
  623         int error;
  624 
  625         if (!mac_vnode_enforce || !mac_proc_enforce)
  626                 return (0);
  627 
  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);
  633         return (error);
  634 }
  635 
  636 #if 0
  637 int
  638 mac_vnode_check_getacl(vfs_context_t ctx, struct vnode *vp, acl_type_t type)
  639 {
  640         kauth_cred_t cred;
  641         int error;
  642 
  643         if (!mac_vnode_enforce || 
  644                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  645                 return (0);
  646 
  647         cred = vfs_context_ucred(ctx);
  648         MAC_CHECK(vnode_check_getacl, cred, vp, vp->v_label, type);
  649         return (error);
  650 }
  651 #endif
  652 
  653 int
  654 mac_vnode_check_getextattr(vfs_context_t ctx, struct vnode *vp,
  655     const char *name, struct uio *uio)
  656 {
  657         kauth_cred_t cred;
  658         int error;
  659 
  660         if (!mac_vnode_enforce || 
  661                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  662                 return (0);
  663 
  664         cred = vfs_context_ucred(ctx);
  665         MAC_CHECK(vnode_check_getextattr, cred, vp, vp->v_label,
  666             name, uio);
  667         return (error);
  668 }
  669 
  670 int
  671 mac_vnode_check_ioctl(vfs_context_t ctx, struct vnode *vp, u_int cmd)
  672 {
  673         kauth_cred_t cred;
  674         int error;
  675 
  676         if (!mac_vnode_enforce || 
  677                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  678                 return (0);
  679 
  680         cred = vfs_context_ucred(ctx);
  681         MAC_CHECK(vnode_check_ioctl, cred, vp, vp->v_label, cmd);
  682         return (error);
  683 }
  684 
  685 int
  686 mac_vnode_check_kqfilter(vfs_context_t ctx, kauth_cred_t file_cred,
  687     struct knote *kn, struct vnode *vp)
  688 {
  689         kauth_cred_t cred;
  690         int error;
  691 
  692         if (!mac_vnode_enforce || 
  693                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  694                 return (0);
  695 
  696         cred = vfs_context_ucred(ctx);
  697         MAC_CHECK(vnode_check_kqfilter, cred, file_cred, kn, vp,
  698             vp->v_label);
  699 
  700         return (error);
  701 }
  702 
  703 int
  704 mac_vnode_check_link(vfs_context_t ctx, struct vnode *dvp,
  705     struct vnode *vp, struct componentname *cnp)
  706 {
  707         kauth_cred_t cred;
  708         int error;
  709 
  710         if (!mac_vnode_enforce || 
  711                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  712                 return (0);
  713 
  714         cred = vfs_context_ucred(ctx);
  715         MAC_CHECK(vnode_check_link, cred, dvp, dvp->v_label, vp,
  716             vp->v_label, cnp);
  717         return (error);
  718 }
  719 
  720 int
  721 mac_vnode_check_listextattr(vfs_context_t ctx, struct vnode *vp)
  722 {
  723         kauth_cred_t cred;
  724         int error;
  725 
  726         if (!mac_vnode_enforce || 
  727                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  728                 return (0);
  729 
  730         cred = vfs_context_ucred(ctx);
  731         MAC_CHECK(vnode_check_listextattr, cred, vp, vp->v_label);
  732         return (error);
  733 }
  734 
  735 int
  736 mac_vnode_check_lookup(vfs_context_t ctx, struct vnode *dvp,
  737     struct componentname *cnp)
  738 {
  739         kauth_cred_t cred;
  740         int error;
  741 
  742         if (!mac_vnode_enforce || 
  743                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  744                 return (0);
  745 
  746         cred = vfs_context_ucred(ctx);
  747         MAC_CHECK(vnode_check_lookup, cred, dvp, dvp->v_label, cnp);
  748         return (error);
  749 }
  750 
  751 int
  752 mac_vnode_check_open(vfs_context_t ctx, struct vnode *vp, int acc_mode)
  753 {
  754         kauth_cred_t cred;
  755         int error;
  756 
  757         if (!mac_vnode_enforce || 
  758                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  759                 return (0);
  760 
  761         cred = vfs_context_ucred(ctx);
  762         MAC_CHECK(vnode_check_open, cred, vp, vp->v_label, acc_mode);
  763         return (error);
  764 }
  765 
  766 int
  767 mac_vnode_check_read(vfs_context_t ctx, struct ucred *file_cred,
  768     struct vnode *vp)
  769 {
  770         kauth_cred_t cred;
  771         int error;
  772 
  773         if (!mac_vnode_enforce || 
  774                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  775                 return (0);
  776 
  777         cred = vfs_context_ucred(ctx);
  778         MAC_CHECK(vnode_check_read, cred, file_cred, vp,
  779             vp->v_label);
  780 
  781         return (error);
  782 }
  783 
  784 int
  785 mac_vnode_check_readdir(vfs_context_t ctx, struct vnode *dvp)
  786 {
  787         kauth_cred_t cred;
  788         int error;
  789 
  790         if (!mac_vnode_enforce || 
  791                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  792                 return (0);
  793 
  794         cred = vfs_context_ucred(ctx);
  795         MAC_CHECK(vnode_check_readdir, cred, dvp, dvp->v_label);
  796         return (error);
  797 }
  798 
  799 int
  800 mac_vnode_check_readlink(vfs_context_t ctx, struct vnode *vp)
  801 {
  802         kauth_cred_t cred;
  803         int error;
  804 
  805         if (!mac_vnode_enforce || 
  806                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  807                 return (0);
  808 
  809         cred = vfs_context_ucred(ctx);
  810         MAC_CHECK(vnode_check_readlink, cred, vp, vp->v_label);
  811         return (error);
  812 }
  813 
  814 int
  815 mac_vnode_check_label_update(vfs_context_t ctx, struct vnode *vp,
  816     struct label *newlabel)
  817 {
  818         kauth_cred_t cred;
  819         int error;
  820 
  821         if (!mac_vnode_enforce || 
  822                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  823                 return (0);
  824 
  825         cred = vfs_context_ucred(ctx);
  826         MAC_CHECK(vnode_check_label_update, cred, vp, vp->v_label, newlabel);
  827 
  828         return (error);
  829 }
  830 
  831 int
  832 mac_vnode_check_rename_from(vfs_context_t ctx, struct vnode *dvp,
  833     struct vnode *vp, struct componentname *cnp)
  834 {
  835         kauth_cred_t cred;
  836         int error;
  837 
  838         if (!mac_vnode_enforce || 
  839                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  840                 return (0);
  841 
  842         cred = vfs_context_ucred(ctx);
  843         MAC_CHECK(vnode_check_rename_from, cred, dvp, dvp->v_label, vp,
  844             vp->v_label, cnp);
  845         return (error);
  846 }
  847 
  848 int
  849 mac_vnode_check_rename_to(vfs_context_t ctx, struct vnode *dvp,
  850     struct vnode *vp, int samedir, struct componentname *cnp)
  851 {
  852         kauth_cred_t cred;
  853         int error;
  854 
  855         if (!mac_vnode_enforce || 
  856                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  857                 return (0);
  858 
  859         cred = vfs_context_ucred(ctx);
  860         MAC_CHECK(vnode_check_rename_to, cred, dvp, dvp->v_label, vp,
  861             vp != NULL ? vp->v_label : NULL, samedir, cnp);
  862         return (error);
  863 }
  864 
  865 int
  866 mac_vnode_check_revoke(vfs_context_t ctx, struct vnode *vp)
  867 {
  868         kauth_cred_t cred;
  869         int error;
  870 
  871         if (!mac_vnode_enforce || 
  872                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  873                 return (0);
  874 
  875         cred = vfs_context_ucred(ctx);
  876         MAC_CHECK(vnode_check_revoke, cred, vp, vp->v_label);
  877         return (error);
  878 }
  879 
  880 int
  881 mac_vnode_check_select(vfs_context_t ctx, struct vnode *vp, int which)
  882 {
  883         kauth_cred_t cred;
  884         int error;
  885 
  886         if (!mac_vnode_enforce || 
  887                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  888                 return (0);
  889 
  890         cred = vfs_context_ucred(ctx);
  891         MAC_CHECK(vnode_check_select, cred, vp, vp->v_label, which);
  892         return (error);
  893 }
  894 
  895 #if 0
  896 int
  897 mac_vnode_check_setacl(vfs_context_t ctx, struct vnode *vp, acl_type_t type,
  898     struct acl *acl)
  899 {
  900         kauth_cred_t cred;
  901         int error;
  902 
  903         if (!mac_vnode_enforce || 
  904                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  905                 return (0);
  906 
  907         cred = vfs_context_ucred(ctx);
  908         MAC_CHECK(vnode_check_setacl, cred, vp, vp->v_label, type, acl);
  909         return (error);
  910 }
  911 #endif
  912 
  913 int
  914 mac_vnode_check_setattrlist(vfs_context_t ctx, struct vnode *vp,
  915     struct attrlist *alist)
  916 {
  917         kauth_cred_t cred;
  918         int error;
  919 
  920         if (!mac_vnode_enforce || 
  921                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  922                 return (0);
  923 
  924         cred = vfs_context_ucred(ctx);
  925         MAC_CHECK(vnode_check_setattrlist, cred, vp, vp->v_label, alist);
  926         return (error);
  927 }
  928 
  929 int
  930 mac_vnode_check_setextattr(vfs_context_t ctx, struct vnode *vp,
  931     const char *name, struct uio *uio)
  932 {
  933         kauth_cred_t cred;
  934         int error;
  935 
  936         if (!mac_vnode_enforce || 
  937                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  938                 return (0);
  939 
  940         cred = vfs_context_ucred(ctx);
  941         MAC_CHECK(vnode_check_setextattr, cred, vp, vp->v_label,
  942             name, uio);
  943         return (error);
  944 }
  945 
  946 int
  947 mac_vnode_check_setflags(vfs_context_t ctx, struct vnode *vp, u_long flags)
  948 {
  949         kauth_cred_t cred;
  950         int error;
  951 
  952         if (!mac_vnode_enforce || 
  953                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  954                 return (0);
  955 
  956         cred = vfs_context_ucred(ctx);
  957         MAC_CHECK(vnode_check_setflags, cred, vp, vp->v_label, flags);
  958         return (error);
  959 }
  960 
  961 int
  962 mac_vnode_check_setmode(vfs_context_t ctx, struct vnode *vp, mode_t mode)
  963 {
  964         kauth_cred_t cred;
  965         int error;
  966 
  967         if (!mac_vnode_enforce || 
  968                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  969                 return (0);
  970 
  971         cred = vfs_context_ucred(ctx);
  972         MAC_CHECK(vnode_check_setmode, cred, vp, vp->v_label, mode);
  973         return (error);
  974 }
  975 
  976 int
  977 mac_vnode_check_setowner(vfs_context_t ctx, struct vnode *vp, uid_t uid,
  978     gid_t gid)
  979 {
  980         kauth_cred_t cred;
  981         int error;
  982 
  983         if (!mac_vnode_enforce || 
  984                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  985                 return (0);
  986 
  987         cred = vfs_context_ucred(ctx);
  988         MAC_CHECK(vnode_check_setowner, cred, vp, vp->v_label, uid, gid);
  989         return (error);
  990 }
  991 
  992 int
  993 mac_vnode_check_setutimes(vfs_context_t ctx, struct vnode *vp,
  994     struct timespec atime, struct timespec mtime)
  995 {
  996         kauth_cred_t cred;
  997         int error;
  998 
  999         if (!mac_vnode_enforce || 
 1000                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
 1001                 return (0);
 1002 
 1003         cred = vfs_context_ucred(ctx);
 1004         MAC_CHECK(vnode_check_setutimes, cred, vp, vp->v_label, atime,
 1005             mtime);
 1006         return (error);
 1007 }
 1008 
 1009 int
 1010 mac_vnode_check_stat(vfs_context_t ctx, struct ucred *file_cred,
 1011     struct vnode *vp)
 1012 {
 1013         kauth_cred_t cred;
 1014         int error;
 1015 
 1016         if (!mac_vnode_enforce || 
 1017                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
 1018                 return (0);
 1019 
 1020         cred = vfs_context_ucred(ctx);
 1021         MAC_CHECK(vnode_check_stat, cred, file_cred, vp,
 1022             vp->v_label);
 1023         return (error);
 1024 }
 1025 
 1026 int
 1027 mac_vnode_check_truncate(vfs_context_t ctx, struct ucred *file_cred,
 1028     struct vnode *vp)
 1029 {
 1030         kauth_cred_t cred;
 1031         int error;
 1032 
 1033         if (!mac_vnode_enforce || 
 1034                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
 1035                 return (0);
 1036 
 1037         cred = vfs_context_ucred(ctx);
 1038         MAC_CHECK(vnode_check_truncate, cred, file_cred, vp,
 1039             vp->v_label);
 1040 
 1041         return (error);
 1042 }
 1043 
 1044 int
 1045 mac_vnode_check_write(vfs_context_t ctx, struct ucred *file_cred,
 1046     struct vnode *vp)
 1047 {
 1048         kauth_cred_t cred;
 1049         int error;
 1050 
 1051         if (!mac_vnode_enforce || 
 1052                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
 1053                 return (0);
 1054 
 1055         cred = vfs_context_ucred(ctx);
 1056         MAC_CHECK(vnode_check_write, cred, file_cred, vp, vp->v_label);
 1057 
 1058         return (error);
 1059 }
 1060 
 1061 void
 1062 mac_vnode_label_update(vfs_context_t ctx, struct vnode *vp, struct label *newlabel)
 1063 {
 1064         kauth_cred_t cred = vfs_context_ucred(ctx);
 1065 
 1066         vnode_lock(vp);
 1067         MAC_PERFORM(vnode_label_update, cred, vp, vp->v_label, newlabel);
 1068         vnode_unlock(vp);
 1069 }
 1070 
 1071 void
 1072 mac_mount_label_associate(vfs_context_t ctx, struct mount *mp)
 1073 {
 1074         kauth_cred_t cred = vfs_context_ucred(ctx);
 1075 
 1076         /* XXX: eventually this logic may be handled by the policy? */
 1077 
 1078         /* We desire MULTILABEL for the root filesystem. */
 1079         if ((mp->mnt_flag & MNT_ROOTFS) && 
 1080             (strcmp(mp->mnt_vfsstat.f_fstypename, "hfs") == 0))
 1081                 mp->mnt_flag |= MNT_MULTILABEL;
 1082 
 1083         /* MULTILABEL on DEVFS. */
 1084         if (strcmp(mp->mnt_vfsstat.f_fstypename, "devfs") == 0)
 1085                 mp->mnt_flag |= MNT_MULTILABEL;
 1086 
 1087         /* MULTILABEL on FDESC pseudo-filesystem. */
 1088         if (strcmp(mp->mnt_vfsstat.f_fstypename, "fdesc") == 0)
 1089                 mp->mnt_flag |= MNT_MULTILABEL;
 1090 
 1091         /* MULTILABEL on all NFS filesystems. */
 1092         if (strcmp(mp->mnt_vfsstat.f_fstypename, "nfs") == 0)
 1093                 mp->mnt_flag |= MNT_MULTILABEL;
 1094 
 1095         /* MULTILABEL on all AFP filesystems. */
 1096         if (strcmp(mp->mnt_vfsstat.f_fstypename, "afpfs") == 0)
 1097                 mp->mnt_flag |= MNT_MULTILABEL;
 1098 
 1099         if (mp->mnt_vtable != NULL) {
 1100                 /* Any filesystem that supports native XATTRs. */
 1101                 if ((mp->mnt_vtable->vfc_vfsflags & VFC_VFSNATIVEXATTR))
 1102                         mp->mnt_flag |= MNT_MULTILABEL;
 1103 
 1104                 /* Filesystem does not support multilabel. */
 1105                 if ((mp->mnt_vtable->vfc_vfsflags & VFC_VFSNOMACLABEL) &&
 1106                     (mp->mnt_flag & MNT_MULTILABEL))
 1107                         mp->mnt_flag &= ~MNT_MULTILABEL;
 1108         }
 1109 
 1110         MAC_PERFORM(mount_label_associate, cred, mp, mp->mnt_mntlabel);
 1111 #if MAC_DEBUG
 1112         printf("MAC Framework enabling %s support: %s -> %s (%s)\n",
 1113                 mp->mnt_flag & MNT_MULTILABEL ? "multilabel" : "singlelabel", 
 1114                 mp->mnt_vfsstat.f_mntfromname,
 1115                 mp->mnt_vfsstat.f_mntonname,
 1116                 mp->mnt_vfsstat.f_fstypename);
 1117 #endif
 1118 }
 1119 
 1120 int
 1121 mac_mount_check_mount(vfs_context_t ctx, struct vnode *vp,
 1122     struct componentname *cnp, const char *vfc_name)
 1123 {
 1124         kauth_cred_t cred;
 1125         int error;
 1126 
 1127         if (!mac_vnode_enforce || 
 1128                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
 1129                 return (0);
 1130 
 1131         cred = vfs_context_ucred(ctx);
 1132         MAC_CHECK(mount_check_mount, cred, vp, vp->v_label, cnp, vfc_name);
 1133 
 1134         return (error);
 1135 }
 1136 
 1137 int
 1138 mac_mount_check_remount(vfs_context_t ctx, struct mount *mp)
 1139 {
 1140         kauth_cred_t cred;
 1141         int error;
 1142 
 1143         if (!mac_vnode_enforce || 
 1144                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
 1145                 return (0);
 1146 
 1147         cred = vfs_context_ucred(ctx);
 1148         MAC_CHECK(mount_check_remount, cred, mp, mp->mnt_mntlabel);
 1149 
 1150         return (error);
 1151 }
 1152 
 1153 int
 1154 mac_mount_check_umount(vfs_context_t ctx, struct mount *mp)
 1155 {
 1156         kauth_cred_t cred;
 1157         int error;
 1158 
 1159         if (!mac_vnode_enforce || 
 1160                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
 1161                 return (0);
 1162 
 1163         cred = vfs_context_ucred(ctx);
 1164         MAC_CHECK(mount_check_umount, cred, mp, mp->mnt_mntlabel);
 1165 
 1166         return (error);
 1167 }
 1168 
 1169 int
 1170 mac_mount_check_getattr(vfs_context_t ctx, struct mount *mp, 
 1171     struct vfs_attr *vfa)
 1172 {
 1173         kauth_cred_t cred;
 1174         int error;
 1175 
 1176         if (!mac_vnode_enforce || 
 1177                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
 1178                 return (0);
 1179 
 1180         cred = vfs_context_ucred(ctx);
 1181         MAC_CHECK(mount_check_getattr, cred, mp, mp->mnt_mntlabel, vfa);
 1182         return (error);
 1183 }
 1184 
 1185 int
 1186 mac_mount_check_setattr(vfs_context_t ctx, struct mount *mp, 
 1187     struct vfs_attr *vfa)
 1188 {
 1189         kauth_cred_t cred;
 1190         int error;
 1191 
 1192         if (!mac_vnode_enforce || 
 1193                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
 1194                 return (0);
 1195 
 1196         cred = vfs_context_ucred(ctx);
 1197         MAC_CHECK(mount_check_setattr, cred, mp, mp->mnt_mntlabel, vfa);
 1198         return (error);
 1199 }
 1200 
 1201 int
 1202 mac_mount_check_stat(vfs_context_t ctx, struct mount *mount)
 1203 {
 1204         kauth_cred_t cred;
 1205         int error;
 1206 
 1207         if (!mac_vnode_enforce || 
 1208                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
 1209                 return (0);
 1210 
 1211         cred = vfs_context_ucred(ctx);
 1212         MAC_CHECK(mount_check_stat, cred, mount, mount->mnt_mntlabel);
 1213 
 1214         return (error);
 1215 }
 1216 
 1217 int
 1218 mac_mount_check_label_update(vfs_context_t ctx, struct mount *mount)
 1219 {
 1220         kauth_cred_t cred;
 1221         int error;
 1222 
 1223         if (!mac_vnode_enforce || 
 1224                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
 1225                 return (0);
 1226 
 1227         cred = vfs_context_ucred(ctx);
 1228         MAC_CHECK(mount_check_label_update, cred, mount, mount->mnt_mntlabel);
 1229 
 1230         return (error);
 1231 }
 1232 
 1233 int
 1234 mac_mount_check_fsctl(vfs_context_t ctx, struct mount *mp, u_int cmd)
 1235 {
 1236         kauth_cred_t cred;
 1237         int error;
 1238 
 1239         if (!mac_vnode_enforce || 
 1240                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
 1241                 return (0);
 1242 
 1243         cred = vfs_context_ucred(ctx);
 1244         MAC_CHECK(mount_check_fsctl, cred, mp, mp->mnt_mntlabel, cmd);
 1245 
 1246         return (error);
 1247 }
 1248 
 1249 void
 1250 mac_devfs_label_associate_device(dev_t dev, struct devnode *de,
 1251     const char *fullpath)
 1252 {
 1253         if (!mac_device_enforce)
 1254                 return;
 1255 
 1256         MAC_PERFORM(devfs_label_associate_device, dev, de, de->dn_label,
 1257             fullpath);
 1258 }
 1259 
 1260 void
 1261 mac_devfs_label_associate_directory(const char *dirname, int dirnamelen,
 1262     struct devnode *de, const char *fullpath)
 1263 {
 1264         if (!mac_device_enforce)
 1265                 return;
 1266 
 1267         MAC_PERFORM(devfs_label_associate_directory, dirname, dirnamelen, de,
 1268             de->dn_label, fullpath);
 1269 }
 1270 
 1271 int
 1272 vn_setlabel(struct vnode *vp, struct label *intlabel, vfs_context_t context)
 1273 {
 1274         int error;
 1275 
 1276         if (!mac_vnode_enforce)
 1277                 return (0);
 1278 
 1279         if (vp->v_mount == NULL) {
 1280                 printf("vn_setlabel: null v_mount\n");
 1281                 if (vp->v_type != VNON)
 1282                         printf("vn_setlabel: null v_mount with non-VNON\n");
 1283                 return (EBADF);
 1284         }
 1285 
 1286         if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0)
 1287                 return (ENOTSUP);
 1288 
 1289         /*
 1290          * Multi-phase commit.  First check the policies to confirm the
 1291          * change is OK.  Then commit via the filesystem.  Finally,
 1292          * update the actual vnode label.  Question: maybe the filesystem
 1293          * should update the vnode at the end as part of VNOP_SETLABEL()?
 1294          */
 1295         error = mac_vnode_check_label_update(context, vp, intlabel);
 1296         if (error)
 1297                 return (error);
 1298 
 1299         error = VNOP_SETLABEL(vp, intlabel, context);
 1300         if (error == ENOTSUP) {
 1301                 error = mac_vnode_label_store(context, vp,
 1302                                                    intlabel);
 1303                 if (error) {
 1304                         printf("%s: mac_vnode_label_store failed %d\n",
 1305                                 __func__, error);
 1306                         return (error);
 1307                 }
 1308                 mac_vnode_label_update(context, vp, intlabel);
 1309         } else
 1310         if (error) {
 1311                 printf("vn_setlabel: vop setlabel failed %d\n", error);
 1312                 return (error);
 1313         }
 1314 
 1315         return (0);
 1316 }
 1317 
 1318 int
 1319 mac_vnode_label_associate_fdesc(struct mount *mp, struct fdescnode *fnp,
 1320     struct vnode *vp, vfs_context_t ctx)
 1321 {
 1322         struct fileproc *fp;
 1323         struct socket *so;
 1324         struct pipe *cpipe;
 1325         struct vnode *fvp;
 1326         struct proc *p;
 1327         int error;
 1328 
 1329         error = 0;
 1330 
 1331         /*
 1332          * If no backing file, let the policy choose which label to use.
 1333          */
 1334         if (fnp->fd_fd == -1) {
 1335                 MAC_PERFORM(vnode_label_associate_file, vfs_context_ucred(ctx),
 1336                     mp, mp->mnt_mntlabel, NULL, NULL, vp, vp->v_label);
 1337                 return (0);
 1338         }
 1339 
 1340         p = vfs_context_proc(ctx);
 1341         error = fp_lookup(p, fnp->fd_fd, &fp, 0);
 1342         if (error)
 1343                 return (error);
 1344 
 1345         if (fp->f_fglob == NULL) {
 1346                 error = EBADF;
 1347                 goto out;
 1348         }
 1349 
 1350         switch (fp->f_fglob->fg_type) {
 1351         case DTYPE_VNODE:
 1352                 fvp = (struct vnode *)fp->f_fglob->fg_data;
 1353                 if ((error = vnode_getwithref(fvp)))
 1354                         goto out;
 1355                 MAC_PERFORM(vnode_label_copy, fvp->v_label, vp->v_label);
 1356                 (void)vnode_put(fvp);
 1357                 break;
 1358         case DTYPE_SOCKET:
 1359                 so = (struct socket *)fp->f_fglob->fg_data;
 1360                 socket_lock(so, 1);
 1361                 MAC_PERFORM(vnode_label_associate_socket,
 1362                             vfs_context_ucred(ctx), (socket_t)so, so->so_label,
 1363                     vp, vp->v_label);
 1364                 socket_unlock(so, 1);
 1365                 break;
 1366         case DTYPE_PSXSHM:
 1367                 pshm_label_associate(fp, vp, ctx);
 1368                 break;
 1369         case DTYPE_PSXSEM:
 1370                 psem_label_associate(fp, vp, ctx);
 1371                 break;
 1372         case DTYPE_PIPE:
 1373                 cpipe = (struct pipe *)fp->f_fglob->fg_data;
 1374                 /* kern/sys_pipe.c:pipe_select() suggests this test. */
 1375                 if (cpipe == (struct pipe *)-1) {
 1376                         error = EINVAL;
 1377                         goto out;
 1378                 }
 1379                 PIPE_LOCK(cpipe);
 1380                 MAC_PERFORM(vnode_label_associate_pipe, vfs_context_ucred(ctx),
 1381                     cpipe, cpipe->pipe_label, vp, vp->v_label);
 1382                 PIPE_UNLOCK(cpipe);
 1383                 break;
 1384         case DTYPE_KQUEUE:
 1385         case DTYPE_FSEVENTS:
 1386         default:
 1387                 MAC_PERFORM(vnode_label_associate_file, vfs_context_ucred(ctx),
 1388                     mp, mp->mnt_mntlabel, fp->f_fglob, fp->f_fglob->fg_label,
 1389                     vp, vp->v_label);
 1390                 break;
 1391         }
 1392 out:
 1393         fp_drop(p, fnp->fd_fd, fp, 0);
 1394         return (error);
 1395 }

Cache object: d446f4e4b6a0d4e0bea41e42c7a5fc7f


[ 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.