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 void
  381 mac_vnode_notify_rename(vfs_context_t ctx, struct vnode *vp,
  382     struct vnode *dvp, struct componentname *cnp)
  383 {
  384         kauth_cred_t cred;
  385 
  386         if (!mac_vnode_enforce ||
  387                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  388                 return;
  389 
  390         cred = vfs_context_ucred(ctx);
  391         MAC_PERFORM(vnode_notify_rename, cred, vp, vp->v_label,
  392             dvp, dvp->v_label, cnp);
  393 }
  394 
  395 /*
  396  * Extended attribute 'name' was updated via
  397  * vn_setxattr() or vn_removexattr().  Allow the
  398  * policy to update the vnode label.
  399  */
  400 void
  401 mac_vnode_label_update_extattr(struct mount *mp, struct vnode *vp,
  402     const char *name)
  403 {
  404         int error = 0;
  405 
  406         if (!mac_vnode_enforce || !mac_label_vnodes)
  407                 return;
  408 
  409         MAC_PERFORM(vnode_label_update_extattr, mp, mp->mnt_mntlabel, vp,
  410                     vp->v_label, name);
  411         if (error == 0)
  412                 return;
  413 
  414         vnode_lock(vp);
  415         vnode_relabel(vp);
  416         vnode_unlock(vp);
  417         return;
  418 }
  419 
  420 static int
  421 mac_vnode_label_store(vfs_context_t ctx, struct vnode *vp,
  422     struct label *intlabel)
  423 {
  424         kauth_cred_t cred;
  425         int error;
  426 
  427         if (!mac_vnode_enforce || !mac_label_vnodes ||
  428             !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  429                 return 0;
  430 
  431         cred = vfs_context_ucred(ctx);
  432         MAC_CHECK(vnode_label_store, cred, vp, vp->v_label, intlabel);
  433 
  434         return (error);
  435 }
  436 
  437 int
  438 mac_cred_label_update_execve(vfs_context_t ctx, kauth_cred_t new, struct vnode *vp,
  439     struct label *scriptvnodelabel, struct label *execl)
  440 {
  441         kauth_cred_t cred;
  442         int disjoint = 0;
  443         posix_cred_t pcred = posix_cred_get(new);
  444 
  445         if (!mac_proc_enforce && !mac_vnode_enforce)
  446                 return disjoint;
  447 
  448         /* mark the new cred to indicate "matching" includes the label */
  449         pcred->cr_flags |= CRF_MAC_ENFORCE;
  450 
  451         cred = vfs_context_ucred(ctx);
  452         MAC_PERFORM(cred_label_update_execve, cred, new, vp, vp->v_label,
  453             scriptvnodelabel, execl, &disjoint);
  454 
  455         return (disjoint);
  456 }
  457 
  458 int
  459 mac_cred_check_label_update_execve(vfs_context_t ctx, struct vnode *vp,
  460     struct label *scriptvnodelabel, struct label *execlabel, struct proc *p)
  461 {
  462         kauth_cred_t cred;
  463         int result = 0;
  464 
  465         if (!mac_proc_enforce && !mac_vnode_enforce)
  466                 return result;
  467 
  468         cred = vfs_context_ucred(ctx);
  469         MAC_BOOLEAN(cred_check_label_update_execve, ||, cred, vp, vp->v_label,
  470                     scriptvnodelabel, execlabel, p);
  471 
  472         return (result);
  473 }
  474 
  475 int
  476 mac_vnode_check_access(vfs_context_t ctx, struct vnode *vp,
  477     int acc_mode)
  478 {
  479         kauth_cred_t cred;
  480         int error;
  481         int mask;
  482 
  483         if (!mac_vnode_enforce ||
  484             !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  485                 return 0;
  486 
  487         cred = vfs_context_ucred(ctx);
  488         /* Convert {R,W,X}_OK values to V{READ,WRITE,EXEC} for entry points */
  489         mask = ACCESS_MODE_TO_VNODE_MASK(acc_mode);
  490         MAC_CHECK(vnode_check_access, cred, vp, vp->v_label, mask);
  491         return (error);
  492  }
  493 
  494 int
  495 mac_vnode_check_chdir(vfs_context_t ctx, struct vnode *dvp)
  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_chdir, cred, dvp, dvp->v_label);
  506         return (error);
  507 }
  508 
  509 int
  510 mac_vnode_check_chroot(vfs_context_t ctx, struct vnode *dvp,
  511     struct componentname *cnp)
  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_chroot, cred, dvp, dvp->v_label, cnp);
  522         return (error);
  523 }
  524 
  525 int
  526 mac_vnode_check_create(vfs_context_t ctx, struct vnode *dvp,
  527     struct componentname *cnp, struct vnode_attr *vap)
  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_create, cred, dvp, dvp->v_label, cnp, vap);
  538         return (error);
  539 }
  540 
  541 int
  542 mac_vnode_check_unlink(vfs_context_t ctx, struct vnode *dvp, struct vnode *vp,
  543     struct componentname *cnp)
  544 {
  545         kauth_cred_t cred;
  546         int error;
  547 
  548         if (!mac_vnode_enforce || 
  549                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  550                 return (0);
  551 
  552         cred = vfs_context_ucred(ctx);
  553         MAC_CHECK(vnode_check_unlink, cred, dvp, dvp->v_label, vp,
  554             vp->v_label, cnp);
  555         return (error);
  556 }
  557 #if 0
  558 int
  559 mac_vnode_check_deleteacl(vfs_context_t ctx, struct vnode *vp,
  560     acl_type_t type)
  561 {
  562         kauth_cred_t cred;
  563         int error;
  564 
  565         if (!mac_vnode_enforce || 
  566                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  567                 return (0);
  568 
  569         cred = vfs_context_ucred(ctx);
  570         MAC_CHECK(vnode_check_deleteacl, cred, vp, vp->v_label, type);
  571         return (error);
  572 }
  573 #endif
  574 
  575 int
  576 mac_vnode_check_deleteextattr(vfs_context_t ctx, struct vnode *vp,
  577     const char *name)
  578 {
  579         kauth_cred_t cred;
  580         int error;
  581 
  582         if (!mac_vnode_enforce || 
  583                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  584                 return (0);
  585 
  586         cred = vfs_context_ucred(ctx);
  587         MAC_CHECK(vnode_check_deleteextattr, cred, vp, vp->v_label, name);
  588         return (error);
  589 }
  590 int
  591 mac_vnode_check_exchangedata(vfs_context_t ctx,
  592     struct vnode *v1, struct vnode *v2)
  593 {
  594         kauth_cred_t cred;
  595         int error;
  596 
  597         if (!mac_vnode_enforce || 
  598                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  599                 return (0);
  600 
  601         cred = vfs_context_ucred(ctx);
  602         MAC_CHECK(vnode_check_exchangedata, cred, v1, v1->v_label, 
  603             v2, v2->v_label);
  604 
  605         return (error);
  606 }
  607 
  608 #if 0
  609 int
  610 mac_vnode_check_getacl(vfs_context_t ctx, struct vnode *vp, acl_type_t type)
  611 {
  612         kauth_cred_t cred;
  613         int error;
  614 
  615         if (!mac_vnode_enforce || 
  616                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  617                 return (0);
  618 
  619         cred = vfs_context_ucred(ctx);
  620         MAC_CHECK(vnode_check_getacl, cred, vp, vp->v_label, type);
  621         return (error);
  622 }
  623 #endif
  624 
  625 int
  626 mac_vnode_check_getattrlist(vfs_context_t ctx, struct vnode *vp,
  627     struct attrlist *alist)
  628 {
  629         kauth_cred_t cred;
  630         int error;
  631 
  632         if (!mac_vnode_enforce || 
  633                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  634                 return (0);
  635 
  636         cred = vfs_context_ucred(ctx);
  637         MAC_CHECK(vnode_check_getattrlist, cred, vp, vp->v_label, alist);
  638 
  639         /* Falsify results instead of returning error? */
  640         return (error);
  641 }
  642 
  643 int
  644 mac_vnode_check_exec(vfs_context_t ctx, struct vnode *vp,
  645     struct image_params *imgp)
  646 {
  647         kauth_cred_t cred;
  648         int error;
  649 
  650         if (!mac_vnode_enforce || !mac_proc_enforce)
  651                 return (0);
  652 
  653         cred = vfs_context_ucred(ctx);
  654         MAC_CHECK(vnode_check_exec, cred, vp, vp->v_label,
  655                   (imgp != NULL) ? imgp->ip_execlabelp : NULL, 
  656                   (imgp != NULL) ? &imgp->ip_ndp->ni_cnd : NULL,
  657                   (imgp != NULL) ? &imgp->ip_csflags : NULL);
  658         return (error);
  659 }
  660 
  661 int
  662 mac_vnode_check_fsgetpath(vfs_context_t ctx, struct vnode *vp)
  663 {
  664         kauth_cred_t cred;
  665         int error;
  666 
  667         if (!mac_vnode_enforce ||
  668                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  669                 return (0);
  670 
  671         cred = vfs_context_ucred(ctx);
  672         MAC_CHECK(vnode_check_fsgetpath, cred, vp, vp->v_label);
  673         return (error);
  674 }
  675 
  676 int
  677 mac_vnode_check_signature(struct vnode *vp, unsigned char *sha1,
  678                           void * signature, size_t size)
  679 {
  680         int error;
  681         
  682         if (!mac_vnode_enforce || !mac_proc_enforce)
  683                 return (0);
  684         
  685         MAC_CHECK(vnode_check_signature, vp, vp->v_label, sha1, signature, size);
  686         return (error);
  687 }
  688 
  689 #if 0
  690 int
  691 mac_vnode_check_getacl(vfs_context_t ctx, struct vnode *vp, acl_type_t type)
  692 {
  693         kauth_cred_t cred;
  694         int error;
  695 
  696         if (!mac_vnode_enforce || 
  697                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  698                 return (0);
  699 
  700         cred = vfs_context_ucred(ctx);
  701         MAC_CHECK(vnode_check_getacl, cred, vp, vp->v_label, type);
  702         return (error);
  703 }
  704 #endif
  705 
  706 int
  707 mac_vnode_check_getextattr(vfs_context_t ctx, struct vnode *vp,
  708     const char *name, struct uio *uio)
  709 {
  710         kauth_cred_t cred;
  711         int error;
  712 
  713         if (!mac_vnode_enforce || 
  714                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  715                 return (0);
  716 
  717         cred = vfs_context_ucred(ctx);
  718         MAC_CHECK(vnode_check_getextattr, cred, vp, vp->v_label,
  719             name, uio);
  720         return (error);
  721 }
  722 
  723 int
  724 mac_vnode_check_ioctl(vfs_context_t ctx, struct vnode *vp, u_int cmd)
  725 {
  726         kauth_cred_t cred;
  727         int error;
  728 
  729         if (!mac_vnode_enforce || 
  730                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  731                 return (0);
  732 
  733         cred = vfs_context_ucred(ctx);
  734         MAC_CHECK(vnode_check_ioctl, cred, vp, vp->v_label, cmd);
  735         return (error);
  736 }
  737 
  738 int
  739 mac_vnode_check_kqfilter(vfs_context_t ctx, kauth_cred_t file_cred,
  740     struct knote *kn, struct vnode *vp)
  741 {
  742         kauth_cred_t cred;
  743         int error;
  744 
  745         if (!mac_vnode_enforce || 
  746                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  747                 return (0);
  748 
  749         cred = vfs_context_ucred(ctx);
  750         MAC_CHECK(vnode_check_kqfilter, cred, file_cred, kn, vp,
  751             vp->v_label);
  752 
  753         return (error);
  754 }
  755 
  756 int
  757 mac_vnode_check_link(vfs_context_t ctx, struct vnode *dvp,
  758     struct vnode *vp, struct componentname *cnp)
  759 {
  760         kauth_cred_t cred;
  761         int error;
  762 
  763         if (!mac_vnode_enforce || 
  764                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  765                 return (0);
  766 
  767         cred = vfs_context_ucred(ctx);
  768         MAC_CHECK(vnode_check_link, cred, dvp, dvp->v_label, vp,
  769             vp->v_label, cnp);
  770         return (error);
  771 }
  772 
  773 int
  774 mac_vnode_check_listextattr(vfs_context_t ctx, struct vnode *vp)
  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_listextattr, cred, vp, vp->v_label);
  785         return (error);
  786 }
  787 
  788 int
  789 mac_vnode_check_lookup(vfs_context_t ctx, struct vnode *dvp,
  790     struct componentname *cnp)
  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_lookup, cred, dvp, dvp->v_label, cnp);
  801         return (error);
  802 }
  803 
  804 int
  805 mac_vnode_check_open(vfs_context_t ctx, struct vnode *vp, int acc_mode)
  806 {
  807         kauth_cred_t cred;
  808         int error;
  809 
  810         if (!mac_vnode_enforce || 
  811                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  812                 return (0);
  813 
  814         cred = vfs_context_ucred(ctx);
  815         MAC_CHECK(vnode_check_open, cred, vp, vp->v_label, acc_mode);
  816         return (error);
  817 }
  818 
  819 int
  820 mac_vnode_check_read(vfs_context_t ctx, struct ucred *file_cred,
  821     struct vnode *vp)
  822 {
  823         kauth_cred_t cred;
  824         int error;
  825 
  826         if (!mac_vnode_enforce || 
  827                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  828                 return (0);
  829 
  830         cred = vfs_context_ucred(ctx);
  831         MAC_CHECK(vnode_check_read, cred, file_cred, vp,
  832             vp->v_label);
  833 
  834         return (error);
  835 }
  836 
  837 int
  838 mac_vnode_check_readdir(vfs_context_t ctx, struct vnode *dvp)
  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_readdir, cred, dvp, dvp->v_label);
  849         return (error);
  850 }
  851 
  852 int
  853 mac_vnode_check_readlink(vfs_context_t ctx, struct vnode *vp)
  854 {
  855         kauth_cred_t cred;
  856         int error;
  857 
  858         if (!mac_vnode_enforce || 
  859                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  860                 return (0);
  861 
  862         cred = vfs_context_ucred(ctx);
  863         MAC_CHECK(vnode_check_readlink, cred, vp, vp->v_label);
  864         return (error);
  865 }
  866 
  867 int
  868 mac_vnode_check_label_update(vfs_context_t ctx, struct vnode *vp,
  869     struct label *newlabel)
  870 {
  871         kauth_cred_t cred;
  872         int error;
  873 
  874         if (!mac_vnode_enforce || 
  875                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  876                 return (0);
  877 
  878         cred = vfs_context_ucred(ctx);
  879         MAC_CHECK(vnode_check_label_update, cred, vp, vp->v_label, newlabel);
  880 
  881         return (error);
  882 }
  883 
  884 int
  885 mac_vnode_check_rename_from(vfs_context_t ctx, struct vnode *dvp,
  886     struct vnode *vp, struct componentname *cnp)
  887 {
  888         kauth_cred_t cred;
  889         int error;
  890 
  891         if (!mac_vnode_enforce || 
  892                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  893                 return (0);
  894 
  895         cred = vfs_context_ucred(ctx);
  896         MAC_CHECK(vnode_check_rename_from, cred, dvp, dvp->v_label, vp,
  897             vp->v_label, cnp);
  898         return (error);
  899 }
  900 
  901 int
  902 mac_vnode_check_rename_to(vfs_context_t ctx, struct vnode *dvp,
  903     struct vnode *vp, int samedir, struct componentname *cnp)
  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_rename_to, cred, dvp, dvp->v_label, vp,
  914             vp != NULL ? vp->v_label : NULL, samedir, cnp);
  915         return (error);
  916 }
  917 
  918 int
  919 mac_vnode_check_revoke(vfs_context_t ctx, struct vnode *vp)
  920 {
  921         kauth_cred_t cred;
  922         int error;
  923 
  924         if (!mac_vnode_enforce || 
  925                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  926                 return (0);
  927 
  928         cred = vfs_context_ucred(ctx);
  929         MAC_CHECK(vnode_check_revoke, cred, vp, vp->v_label);
  930         return (error);
  931 }
  932 
  933 int
  934 mac_vnode_check_searchfs(vfs_context_t ctx, struct vnode *vp, struct attrlist *alist)
  935 {
  936         kauth_cred_t cred;
  937         int error;
  938 
  939         if (!mac_vnode_enforce || 
  940                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  941                 return (0);
  942 
  943         cred = vfs_context_ucred(ctx);
  944         MAC_CHECK(vnode_check_searchfs, cred, vp, vp->v_label, alist);
  945         return (error);
  946 }
  947 
  948 int
  949 mac_vnode_check_select(vfs_context_t ctx, struct vnode *vp, int which)
  950 {
  951         kauth_cred_t cred;
  952         int error;
  953 
  954         if (!mac_vnode_enforce || 
  955                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  956                 return (0);
  957 
  958         cred = vfs_context_ucred(ctx);
  959         MAC_CHECK(vnode_check_select, cred, vp, vp->v_label, which);
  960         return (error);
  961 }
  962 
  963 #if 0
  964 int
  965 mac_vnode_check_setacl(vfs_context_t ctx, struct vnode *vp, acl_type_t type,
  966     struct acl *acl)
  967 {
  968         kauth_cred_t cred;
  969         int error;
  970 
  971         if (!mac_vnode_enforce || 
  972                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  973                 return (0);
  974 
  975         cred = vfs_context_ucred(ctx);
  976         MAC_CHECK(vnode_check_setacl, cred, vp, vp->v_label, type, acl);
  977         return (error);
  978 }
  979 #endif
  980 
  981 int
  982 mac_vnode_check_setattrlist(vfs_context_t ctx, struct vnode *vp,
  983     struct attrlist *alist)
  984 {
  985         kauth_cred_t cred;
  986         int error;
  987 
  988         if (!mac_vnode_enforce || 
  989                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
  990                 return (0);
  991 
  992         cred = vfs_context_ucred(ctx);
  993         MAC_CHECK(vnode_check_setattrlist, cred, vp, vp->v_label, alist);
  994         return (error);
  995 }
  996 
  997 int
  998 mac_vnode_check_setextattr(vfs_context_t ctx, struct vnode *vp,
  999     const char *name, struct uio *uio)
 1000 {
 1001         kauth_cred_t cred;
 1002         int error;
 1003 
 1004         if (!mac_vnode_enforce || 
 1005                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
 1006                 return (0);
 1007 
 1008         cred = vfs_context_ucred(ctx);
 1009         MAC_CHECK(vnode_check_setextattr, cred, vp, vp->v_label,
 1010             name, uio);
 1011         return (error);
 1012 }
 1013 
 1014 int
 1015 mac_vnode_check_setflags(vfs_context_t ctx, struct vnode *vp, u_long flags)
 1016 {
 1017         kauth_cred_t cred;
 1018         int error;
 1019 
 1020         if (!mac_vnode_enforce || 
 1021                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
 1022                 return (0);
 1023 
 1024         cred = vfs_context_ucred(ctx);
 1025         MAC_CHECK(vnode_check_setflags, cred, vp, vp->v_label, flags);
 1026         return (error);
 1027 }
 1028 
 1029 int
 1030 mac_vnode_check_setmode(vfs_context_t ctx, struct vnode *vp, mode_t mode)
 1031 {
 1032         kauth_cred_t cred;
 1033         int error;
 1034 
 1035         if (!mac_vnode_enforce || 
 1036                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
 1037                 return (0);
 1038 
 1039         cred = vfs_context_ucred(ctx);
 1040         MAC_CHECK(vnode_check_setmode, cred, vp, vp->v_label, mode);
 1041         return (error);
 1042 }
 1043 
 1044 int
 1045 mac_vnode_check_setowner(vfs_context_t ctx, struct vnode *vp, uid_t uid,
 1046     gid_t gid)
 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_setowner, cred, vp, vp->v_label, uid, gid);
 1057         return (error);
 1058 }
 1059 
 1060 int
 1061 mac_vnode_check_setutimes(vfs_context_t ctx, struct vnode *vp,
 1062     struct timespec atime, struct timespec mtime)
 1063 {
 1064         kauth_cred_t cred;
 1065         int error;
 1066 
 1067         if (!mac_vnode_enforce || 
 1068                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
 1069                 return (0);
 1070 
 1071         cred = vfs_context_ucred(ctx);
 1072         MAC_CHECK(vnode_check_setutimes, cred, vp, vp->v_label, atime,
 1073             mtime);
 1074         return (error);
 1075 }
 1076 
 1077 int
 1078 mac_vnode_check_stat(vfs_context_t ctx, struct ucred *file_cred,
 1079     struct vnode *vp)
 1080 {
 1081         kauth_cred_t cred;
 1082         int error;
 1083 
 1084         if (!mac_vnode_enforce || 
 1085                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
 1086                 return (0);
 1087 
 1088         cred = vfs_context_ucred(ctx);
 1089         MAC_CHECK(vnode_check_stat, cred, file_cred, vp,
 1090             vp->v_label);
 1091         return (error);
 1092 }
 1093 
 1094 int
 1095 mac_vnode_check_truncate(vfs_context_t ctx, struct ucred *file_cred,
 1096     struct vnode *vp)
 1097 {
 1098         kauth_cred_t cred;
 1099         int error;
 1100 
 1101         if (!mac_vnode_enforce || 
 1102                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
 1103                 return (0);
 1104 
 1105         cred = vfs_context_ucred(ctx);
 1106         MAC_CHECK(vnode_check_truncate, cred, file_cred, vp,
 1107             vp->v_label);
 1108 
 1109         return (error);
 1110 }
 1111 
 1112 int
 1113 mac_vnode_check_write(vfs_context_t ctx, struct ucred *file_cred,
 1114     struct vnode *vp)
 1115 {
 1116         kauth_cred_t cred;
 1117         int error;
 1118 
 1119         if (!mac_vnode_enforce || 
 1120                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
 1121                 return (0);
 1122 
 1123         cred = vfs_context_ucred(ctx);
 1124         MAC_CHECK(vnode_check_write, cred, file_cred, vp, vp->v_label);
 1125 
 1126         return (error);
 1127 }
 1128 
 1129 int
 1130 mac_vnode_check_uipc_bind(vfs_context_t ctx, struct vnode *dvp,
 1131     struct componentname *cnp, struct vnode_attr *vap)
 1132 {
 1133         kauth_cred_t cred;
 1134         int error;
 1135 
 1136         if (!mac_vnode_enforce || 
 1137                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
 1138                 return (0);
 1139 
 1140         cred = vfs_context_ucred(ctx);
 1141         MAC_CHECK(vnode_check_uipc_bind, cred, dvp, dvp->v_label, cnp, vap);
 1142         return (error);
 1143 }
 1144 
 1145 int
 1146 mac_vnode_check_uipc_connect(vfs_context_t ctx, struct vnode *vp)
 1147 {
 1148         kauth_cred_t cred;
 1149         int error;
 1150 
 1151         if (!mac_vnode_enforce || 
 1152                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
 1153                 return (0);
 1154 
 1155         cred = vfs_context_ucred(ctx);
 1156         MAC_CHECK(vnode_check_uipc_connect, cred, vp, vp->v_label);
 1157         return (error);
 1158 }
 1159 
 1160 void
 1161 mac_vnode_label_update(vfs_context_t ctx, struct vnode *vp, struct label *newlabel)
 1162 {
 1163         kauth_cred_t cred = vfs_context_ucred(ctx);
 1164         struct label *tmpl = NULL;
 1165 
 1166         if (vp->v_label == NULL)
 1167                 tmpl = mac_vnode_label_alloc();
 1168 
 1169         vnode_lock(vp);
 1170 
 1171         /* recheck after lock */
 1172         if (vp->v_label == NULL) {
 1173                 vp->v_label = tmpl;
 1174                 tmpl = NULL;
 1175         }
 1176 
 1177         MAC_PERFORM(vnode_label_update, cred, vp, vp->v_label, newlabel);
 1178         vnode_unlock(vp);
 1179 
 1180         if (tmpl != NULL)
 1181                 mac_vnode_label_free(tmpl);
 1182 }
 1183 
 1184 void
 1185 mac_mount_label_associate(vfs_context_t ctx, struct mount *mp)
 1186 {
 1187         kauth_cred_t cred = vfs_context_ucred(ctx);
 1188 
 1189         /* XXX: eventually this logic may be handled by the policy? */
 1190 
 1191         /* We desire MULTILABEL for the root filesystem. */
 1192         if ((mp->mnt_flag & MNT_ROOTFS) && 
 1193             (strcmp(mp->mnt_vfsstat.f_fstypename, "hfs") == 0))
 1194                 mp->mnt_flag |= MNT_MULTILABEL;
 1195 
 1196         /* MULTILABEL on DEVFS. */
 1197         if (strcmp(mp->mnt_vfsstat.f_fstypename, "devfs") == 0)
 1198                 mp->mnt_flag |= MNT_MULTILABEL;
 1199 
 1200         /* MULTILABEL on FDESC pseudo-filesystem. */
 1201         if (strcmp(mp->mnt_vfsstat.f_fstypename, "fdesc") == 0)
 1202                 mp->mnt_flag |= MNT_MULTILABEL;
 1203 
 1204         /* MULTILABEL on all NFS filesystems. */
 1205         if (strcmp(mp->mnt_vfsstat.f_fstypename, "nfs") == 0)
 1206                 mp->mnt_flag |= MNT_MULTILABEL;
 1207 
 1208         /* MULTILABEL on all AFP filesystems. */
 1209         if (strcmp(mp->mnt_vfsstat.f_fstypename, "afpfs") == 0)
 1210                 mp->mnt_flag |= MNT_MULTILABEL;
 1211 
 1212         if (mp->mnt_vtable != NULL) {
 1213                 /* Any filesystem that supports native XATTRs. */
 1214                 if ((mp->mnt_vtable->vfc_vfsflags & VFC_VFSNATIVEXATTR))
 1215                         mp->mnt_flag |= MNT_MULTILABEL;
 1216 
 1217                 /* Filesystem does not support multilabel. */
 1218                 if ((mp->mnt_vtable->vfc_vfsflags & VFC_VFSNOMACLABEL) &&
 1219                     (mp->mnt_flag & MNT_MULTILABEL))
 1220                         mp->mnt_flag &= ~MNT_MULTILABEL;
 1221         }
 1222 
 1223         MAC_PERFORM(mount_label_associate, cred, mp, mp->mnt_mntlabel);
 1224 #if MAC_DEBUG
 1225         printf("MAC Framework enabling %s support: %s -> %s (%s)\n",
 1226                 mp->mnt_flag & MNT_MULTILABEL ? "multilabel" : "singlelabel", 
 1227                 mp->mnt_vfsstat.f_mntfromname,
 1228                 mp->mnt_vfsstat.f_mntonname,
 1229                 mp->mnt_vfsstat.f_fstypename);
 1230 #endif
 1231 }
 1232 
 1233 int
 1234 mac_mount_check_mount(vfs_context_t ctx, struct vnode *vp,
 1235     struct componentname *cnp, const char *vfc_name)
 1236 {
 1237         kauth_cred_t cred;
 1238         int error;
 1239 
 1240         if (!mac_vnode_enforce || 
 1241                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
 1242                 return (0);
 1243 
 1244         cred = vfs_context_ucred(ctx);
 1245         MAC_CHECK(mount_check_mount, cred, vp, vp->v_label, cnp, vfc_name);
 1246 
 1247         return (error);
 1248 }
 1249 
 1250 int
 1251 mac_mount_check_remount(vfs_context_t ctx, struct mount *mp)
 1252 {
 1253         kauth_cred_t cred;
 1254         int error;
 1255 
 1256         if (!mac_vnode_enforce || 
 1257                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
 1258                 return (0);
 1259 
 1260         cred = vfs_context_ucred(ctx);
 1261         MAC_CHECK(mount_check_remount, cred, mp, mp->mnt_mntlabel);
 1262 
 1263         return (error);
 1264 }
 1265 
 1266 int
 1267 mac_mount_check_umount(vfs_context_t ctx, struct mount *mp)
 1268 {
 1269         kauth_cred_t cred;
 1270         int error;
 1271 
 1272         if (!mac_vnode_enforce || 
 1273                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
 1274                 return (0);
 1275 
 1276         cred = vfs_context_ucred(ctx);
 1277         MAC_CHECK(mount_check_umount, cred, mp, mp->mnt_mntlabel);
 1278 
 1279         return (error);
 1280 }
 1281 
 1282 int
 1283 mac_mount_check_getattr(vfs_context_t ctx, struct mount *mp, 
 1284     struct vfs_attr *vfa)
 1285 {
 1286         kauth_cred_t cred;
 1287         int error;
 1288 
 1289         if (!mac_vnode_enforce || 
 1290                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
 1291                 return (0);
 1292 
 1293         cred = vfs_context_ucred(ctx);
 1294         MAC_CHECK(mount_check_getattr, cred, mp, mp->mnt_mntlabel, vfa);
 1295         return (error);
 1296 }
 1297 
 1298 int
 1299 mac_mount_check_setattr(vfs_context_t ctx, struct mount *mp, 
 1300     struct vfs_attr *vfa)
 1301 {
 1302         kauth_cred_t cred;
 1303         int error;
 1304 
 1305         if (!mac_vnode_enforce || 
 1306                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
 1307                 return (0);
 1308 
 1309         cred = vfs_context_ucred(ctx);
 1310         MAC_CHECK(mount_check_setattr, cred, mp, mp->mnt_mntlabel, vfa);
 1311         return (error);
 1312 }
 1313 
 1314 int
 1315 mac_mount_check_stat(vfs_context_t ctx, struct mount *mount)
 1316 {
 1317         kauth_cred_t cred;
 1318         int error;
 1319 
 1320         if (!mac_vnode_enforce || 
 1321                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
 1322                 return (0);
 1323 
 1324         cred = vfs_context_ucred(ctx);
 1325         MAC_CHECK(mount_check_stat, cred, mount, mount->mnt_mntlabel);
 1326 
 1327         return (error);
 1328 }
 1329 
 1330 int
 1331 mac_mount_check_label_update(vfs_context_t ctx, struct mount *mount)
 1332 {
 1333         kauth_cred_t cred;
 1334         int error;
 1335 
 1336         if (!mac_vnode_enforce || 
 1337                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
 1338                 return (0);
 1339 
 1340         cred = vfs_context_ucred(ctx);
 1341         MAC_CHECK(mount_check_label_update, cred, mount, mount->mnt_mntlabel);
 1342 
 1343         return (error);
 1344 }
 1345 
 1346 int
 1347 mac_mount_check_fsctl(vfs_context_t ctx, struct mount *mp, u_int cmd)
 1348 {
 1349         kauth_cred_t cred;
 1350         int error;
 1351 
 1352         if (!mac_vnode_enforce || 
 1353                 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
 1354                 return (0);
 1355 
 1356         cred = vfs_context_ucred(ctx);
 1357         MAC_CHECK(mount_check_fsctl, cred, mp, mp->mnt_mntlabel, cmd);
 1358 
 1359         return (error);
 1360 }
 1361 
 1362 void
 1363 mac_devfs_label_associate_device(dev_t dev, struct devnode *de,
 1364     const char *fullpath)
 1365 {
 1366         if (!mac_device_enforce)
 1367                 return;
 1368 
 1369         MAC_PERFORM(devfs_label_associate_device, dev, de, de->dn_label,
 1370             fullpath);
 1371 }
 1372 
 1373 void
 1374 mac_devfs_label_associate_directory(const char *dirname, int dirnamelen,
 1375     struct devnode *de, const char *fullpath)
 1376 {
 1377         if (!mac_device_enforce)
 1378                 return;
 1379 
 1380         MAC_PERFORM(devfs_label_associate_directory, dirname, dirnamelen, de,
 1381             de->dn_label, fullpath);
 1382 }
 1383 
 1384 int
 1385 vn_setlabel(struct vnode *vp, struct label *intlabel, vfs_context_t context)
 1386 {
 1387         int error;
 1388 
 1389         if (!mac_vnode_enforce || !mac_label_vnodes)
 1390                 return (0);
 1391 
 1392         if (vp->v_mount == NULL) {
 1393                 printf("vn_setlabel: null v_mount\n");
 1394                 if (vp->v_type != VNON)
 1395                         printf("vn_setlabel: null v_mount with non-VNON\n");
 1396                 return (EBADF);
 1397         }
 1398 
 1399         if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0)
 1400                 return (ENOTSUP);
 1401 
 1402         /*
 1403          * Multi-phase commit.  First check the policies to confirm the
 1404          * change is OK.  Then commit via the filesystem.  Finally,
 1405          * update the actual vnode label.  Question: maybe the filesystem
 1406          * should update the vnode at the end as part of VNOP_SETLABEL()?
 1407          */
 1408         error = mac_vnode_check_label_update(context, vp, intlabel);
 1409         if (error)
 1410                 return (error);
 1411 
 1412         error = VNOP_SETLABEL(vp, intlabel, context);
 1413         if (error == ENOTSUP) {
 1414                 error = mac_vnode_label_store(context, vp,
 1415                                                    intlabel);
 1416                 if (error) {
 1417                         printf("%s: mac_vnode_label_store failed %d\n",
 1418                                 __func__, error);
 1419                         return (error);
 1420                 }
 1421                 mac_vnode_label_update(context, vp, intlabel);
 1422         } else
 1423         if (error) {
 1424                 printf("vn_setlabel: vop setlabel failed %d\n", error);
 1425                 return (error);
 1426         }
 1427 
 1428         return (0);
 1429 }
 1430 
 1431 int
 1432 mac_vnode_label_associate_fdesc(struct mount *mp, struct fdescnode *fnp,
 1433     struct vnode *vp, vfs_context_t ctx)
 1434 {
 1435         struct fileproc *fp;
 1436         struct socket *so;
 1437         struct pipe *cpipe;
 1438         struct vnode *fvp;
 1439         struct proc *p;
 1440         int error;
 1441 
 1442         error = 0;
 1443 
 1444         /*
 1445          * If no backing file, let the policy choose which label to use.
 1446          */
 1447         if (fnp->fd_fd == -1) {
 1448                 MAC_PERFORM(vnode_label_associate_file, vfs_context_ucred(ctx),
 1449                     mp, mp->mnt_mntlabel, NULL, NULL, vp, vp->v_label);
 1450                 return (0);
 1451         }
 1452 
 1453         p = vfs_context_proc(ctx);
 1454         error = fp_lookup(p, fnp->fd_fd, &fp, 0);
 1455         if (error)
 1456                 return (error);
 1457 
 1458         if (fp->f_fglob == NULL) {
 1459                 error = EBADF;
 1460                 goto out;
 1461         }
 1462 
 1463         switch (fp->f_fglob->fg_type) {
 1464         case DTYPE_VNODE:
 1465                 fvp = (struct vnode *)fp->f_fglob->fg_data;
 1466                 if ((error = vnode_getwithref(fvp)))
 1467                         goto out;
 1468                 MAC_PERFORM(vnode_label_copy, fvp->v_label, vp->v_label);
 1469                 (void)vnode_put(fvp);
 1470                 break;
 1471         case DTYPE_SOCKET:
 1472                 so = (struct socket *)fp->f_fglob->fg_data;
 1473                 socket_lock(so, 1);
 1474                 MAC_PERFORM(vnode_label_associate_socket,
 1475                             vfs_context_ucred(ctx), (socket_t)so, so->so_label,
 1476                     vp, vp->v_label);
 1477                 socket_unlock(so, 1);
 1478                 break;
 1479         case DTYPE_PSXSHM:
 1480                 pshm_label_associate(fp, vp, ctx);
 1481                 break;
 1482         case DTYPE_PSXSEM:
 1483                 psem_label_associate(fp, vp, ctx);
 1484                 break;
 1485         case DTYPE_PIPE:
 1486                 cpipe = (struct pipe *)fp->f_fglob->fg_data;
 1487                 /* kern/sys_pipe.c:pipe_select() suggests this test. */
 1488                 if (cpipe == (struct pipe *)-1) {
 1489                         error = EINVAL;
 1490                         goto out;
 1491                 }
 1492                 PIPE_LOCK(cpipe);
 1493                 MAC_PERFORM(vnode_label_associate_pipe, vfs_context_ucred(ctx),
 1494                     cpipe, cpipe->pipe_label, vp, vp->v_label);
 1495                 PIPE_UNLOCK(cpipe);
 1496                 break;
 1497         case DTYPE_KQUEUE:
 1498         case DTYPE_FSEVENTS:
 1499         default:
 1500                 MAC_PERFORM(vnode_label_associate_file, vfs_context_ucred(ctx),
 1501                     mp, mp->mnt_mntlabel, fp->f_fglob, fp->f_fglob->fg_label,
 1502                     vp, vp->v_label);
 1503                 break;
 1504         }
 1505 out:
 1506         fp_drop(p, fnp->fd_fd, fp, 0);
 1507         return (error);
 1508 }

Cache object: 48ba3be706c66128331baac310c7a60d


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