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

Cache object: f6af173c714cd56678b3c5eebf9ca1aa


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