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/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) 1999-2002, 2009 Robert N. M. Watson
    3  * Copyright (c) 2001 Ilmar S. Habibulin
    4  * Copyright (c) 2001-2005 McAfee, Inc.
    5  * Copyright (c) 2005-2006 SPARTA, Inc.
    6  * Copyright (c) 2008 Apple Inc.
    7  * All rights reserved.
    8  *
    9  * This software was developed by Robert Watson and Ilmar Habibulin for the
   10  * TrustedBSD Project.
   11  *
   12  * This software was developed for the FreeBSD Project in part by McAfee
   13  * Research, the Security Research Division of McAfee, Inc. under
   14  * DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA
   15  * CHATS research program.
   16  *
   17  * This software was enhanced by SPARTA ISSO under SPAWAR contract
   18  * N66001-04-C-6019 ("SEFOS").
   19  *
   20  * This software was developed at the University of Cambridge Computer
   21  * Laboratory with support from a grant from Google, Inc. 
   22  *
   23  * Redistribution and use in source and binary forms, with or without
   24  * modification, are permitted provided that the following conditions
   25  * are met:
   26  * 1. Redistributions of source code must retain the above copyright
   27  *    notice, this list of conditions and the following disclaimer.
   28  * 2. Redistributions in binary form must reproduce the above copyright
   29  *    notice, this list of conditions and the following disclaimer in the
   30  *    documentation and/or other materials provided with the distribution.
   31  *
   32  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   33  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   34  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   35  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   36  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   37  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   38  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   39  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   40  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   41  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   42  * SUCH DAMAGE.
   43  */
   44 
   45 #include <sys/cdefs.h>
   46 __FBSDID("$FreeBSD$");
   47 
   48 #include "opt_mac.h"
   49 
   50 #include <sys/param.h>
   51 #include <sys/condvar.h>
   52 #include <sys/extattr.h>
   53 #include <sys/imgact.h>
   54 #include <sys/kernel.h>
   55 #include <sys/lock.h>
   56 #include <sys/malloc.h>
   57 #include <sys/mutex.h>
   58 #include <sys/proc.h>
   59 #include <sys/sbuf.h>
   60 #include <sys/systm.h>
   61 #include <sys/vnode.h>
   62 #include <sys/mount.h>
   63 #include <sys/file.h>
   64 #include <sys/namei.h>
   65 #include <sys/sdt.h>
   66 #include <sys/sysctl.h>
   67 
   68 #include <vm/vm.h>
   69 #include <vm/pmap.h>
   70 #include <vm/vm_map.h>
   71 #include <vm/vm_object.h>
   72 
   73 #include <fs/devfs/devfs.h>
   74 
   75 #include <security/mac/mac_framework.h>
   76 #include <security/mac/mac_internal.h>
   77 #include <security/mac/mac_policy.h>
   78 
   79 /*
   80  * Warn about EA transactions only the first time they happen.  No locking on
   81  * this variable.
   82  */
   83 static int      ea_warn_once = 0;
   84 
   85 static int      mac_vnode_setlabel_extattr(struct ucred *cred,
   86                     struct vnode *vp, struct label *intlabel);
   87 
   88 static struct label *
   89 mac_devfs_label_alloc(void)
   90 {
   91         struct label *label;
   92 
   93         label = mac_labelzone_alloc(M_WAITOK);
   94         MAC_POLICY_PERFORM(devfs_init_label, label);
   95         return (label);
   96 }
   97 
   98 void
   99 mac_devfs_init(struct devfs_dirent *de)
  100 {
  101 
  102         if (mac_labeled & MPC_OBJECT_DEVFS)
  103                 de->de_label = mac_devfs_label_alloc();
  104         else
  105                 de->de_label = NULL;
  106 }
  107 
  108 static struct label *
  109 mac_mount_label_alloc(void)
  110 {
  111         struct label *label;
  112 
  113         label = mac_labelzone_alloc(M_WAITOK);
  114         MAC_POLICY_PERFORM(mount_init_label, label);
  115         return (label);
  116 }
  117 
  118 void
  119 mac_mount_init(struct mount *mp)
  120 {
  121 
  122         if (mac_labeled & MPC_OBJECT_MOUNT)
  123                 mp->mnt_label = mac_mount_label_alloc();
  124         else
  125                 mp->mnt_label = NULL;
  126 }
  127 
  128 struct label *
  129 mac_vnode_label_alloc(void)
  130 {
  131         struct label *label;
  132 
  133         label = mac_labelzone_alloc(M_WAITOK);
  134         MAC_POLICY_PERFORM(vnode_init_label, label);
  135         return (label);
  136 }
  137 
  138 void
  139 mac_vnode_init(struct vnode *vp)
  140 {
  141 
  142         if (mac_labeled & MPC_OBJECT_VNODE)
  143                 vp->v_label = mac_vnode_label_alloc();
  144         else
  145                 vp->v_label = NULL;
  146 }
  147 
  148 static void
  149 mac_devfs_label_free(struct label *label)
  150 {
  151 
  152         MAC_POLICY_PERFORM_NOSLEEP(devfs_destroy_label, label);
  153         mac_labelzone_free(label);
  154 }
  155 
  156 void
  157 mac_devfs_destroy(struct devfs_dirent *de)
  158 {
  159 
  160         if (de->de_label != NULL) {
  161                 mac_devfs_label_free(de->de_label);
  162                 de->de_label = NULL;
  163         }
  164 }
  165 
  166 static void
  167 mac_mount_label_free(struct label *label)
  168 {
  169 
  170         MAC_POLICY_PERFORM_NOSLEEP(mount_destroy_label, label);
  171         mac_labelzone_free(label);
  172 }
  173 
  174 void
  175 mac_mount_destroy(struct mount *mp)
  176 {
  177 
  178         if (mp->mnt_label != NULL) {
  179                 mac_mount_label_free(mp->mnt_label);
  180                 mp->mnt_label = NULL;
  181         }
  182 }
  183 
  184 void
  185 mac_vnode_label_free(struct label *label)
  186 {
  187 
  188         MAC_POLICY_PERFORM_NOSLEEP(vnode_destroy_label, label);
  189         mac_labelzone_free(label);
  190 }
  191 
  192 void
  193 mac_vnode_destroy(struct vnode *vp)
  194 {
  195 
  196         if (vp->v_label != NULL) {
  197                 mac_vnode_label_free(vp->v_label);
  198                 vp->v_label = NULL;
  199         }
  200 }
  201 
  202 void
  203 mac_vnode_copy_label(struct label *src, struct label *dest)
  204 {
  205 
  206         MAC_POLICY_PERFORM_NOSLEEP(vnode_copy_label, src, dest);
  207 }
  208 
  209 int
  210 mac_vnode_externalize_label(struct label *label, char *elements,
  211     char *outbuf, size_t outbuflen)
  212 {
  213         int error;
  214 
  215         MAC_POLICY_EXTERNALIZE(vnode, label, elements, outbuf, outbuflen);
  216 
  217         return (error);
  218 }
  219 
  220 int
  221 mac_vnode_internalize_label(struct label *label, char *string)
  222 {
  223         int error;
  224 
  225         MAC_POLICY_INTERNALIZE(vnode, label, string);
  226 
  227         return (error);
  228 }
  229 
  230 void
  231 mac_devfs_update(struct mount *mp, struct devfs_dirent *de, struct vnode *vp)
  232 {
  233 
  234         MAC_POLICY_PERFORM_NOSLEEP(devfs_update, mp, de, de->de_label, vp,
  235             vp->v_label);
  236 }
  237 
  238 void
  239 mac_devfs_vnode_associate(struct mount *mp, struct devfs_dirent *de,
  240     struct vnode *vp)
  241 {
  242 
  243         MAC_POLICY_PERFORM_NOSLEEP(devfs_vnode_associate, mp, mp->mnt_label,
  244             de, de->de_label, vp, vp->v_label);
  245 }
  246 
  247 int
  248 mac_vnode_associate_extattr(struct mount *mp, struct vnode *vp)
  249 {
  250         int error;
  251 
  252         ASSERT_VOP_LOCKED(vp, "mac_vnode_associate_extattr");
  253 
  254         MAC_POLICY_CHECK(vnode_associate_extattr, mp, mp->mnt_label, vp,
  255             vp->v_label);
  256 
  257         return (error);
  258 }
  259 
  260 void
  261 mac_vnode_associate_singlelabel(struct mount *mp, struct vnode *vp)
  262 {
  263 
  264         MAC_POLICY_PERFORM_NOSLEEP(vnode_associate_singlelabel, mp,
  265             mp->mnt_label, vp, vp->v_label);
  266 }
  267 
  268 /*
  269  * Functions implementing extended-attribute backed labels for file systems
  270  * that support it.
  271  *
  272  * Where possible, we use EA transactions to make writes to multiple
  273  * attributes across difference policies mutually atomic.  We allow work to
  274  * continue on file systems not supporting EA transactions, but generate a
  275  * printf warning.
  276  */
  277 int
  278 mac_vnode_create_extattr(struct ucred *cred, struct mount *mp,
  279     struct vnode *dvp, struct vnode *vp, struct componentname *cnp)
  280 {
  281         int error;
  282 
  283         ASSERT_VOP_LOCKED(dvp, "mac_vnode_create_extattr");
  284         ASSERT_VOP_LOCKED(vp, "mac_vnode_create_extattr");
  285 
  286         error = VOP_OPENEXTATTR(vp, cred, curthread);
  287         if (error == EOPNOTSUPP) {
  288                 if (ea_warn_once == 0) {
  289                         printf("Warning: transactions not supported "
  290                             "in EA write.\n");
  291                         ea_warn_once = 1;
  292                 }
  293         } else if (error)
  294                 return (error);
  295 
  296         MAC_POLICY_CHECK(vnode_create_extattr, cred, mp, mp->mnt_label, dvp,
  297             dvp->v_label, vp, vp->v_label, cnp);
  298 
  299         if (error) {
  300                 VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread);
  301                 return (error);
  302         }
  303 
  304         error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread);
  305         if (error == EOPNOTSUPP)
  306                 error = 0;
  307 
  308         return (error);
  309 }
  310 
  311 static int
  312 mac_vnode_setlabel_extattr(struct ucred *cred, struct vnode *vp,
  313     struct label *intlabel)
  314 {
  315         int error;
  316 
  317         ASSERT_VOP_LOCKED(vp, "mac_vnode_setlabel_extattr");
  318 
  319         error = VOP_OPENEXTATTR(vp, cred, curthread);
  320         if (error == EOPNOTSUPP) {
  321                 if (ea_warn_once == 0) {
  322                         printf("Warning: transactions not supported "
  323                             "in EA write.\n");
  324                         ea_warn_once = 1;
  325                 }
  326         } else if (error)
  327                 return (error);
  328 
  329         MAC_POLICY_CHECK(vnode_setlabel_extattr, cred, vp, vp->v_label,
  330             intlabel);
  331 
  332         if (error) {
  333                 VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread);
  334                 return (error);
  335         }
  336 
  337         error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread);
  338         if (error == EOPNOTSUPP)
  339                 error = 0;
  340 
  341         return (error);
  342 }
  343 
  344 void
  345 mac_vnode_execve_transition(struct ucred *old, struct ucred *new,
  346     struct vnode *vp, struct label *interpvplabel, struct image_params *imgp)
  347 {
  348 
  349         ASSERT_VOP_LOCKED(vp, "mac_vnode_execve_transition");
  350 
  351         MAC_POLICY_PERFORM(vnode_execve_transition, old, new, vp,
  352             vp->v_label, interpvplabel, imgp, imgp->execlabel);
  353 }
  354 
  355 int
  356 mac_vnode_execve_will_transition(struct ucred *old, struct vnode *vp,
  357     struct label *interpvplabel, struct image_params *imgp)
  358 {
  359         int result;
  360 
  361         ASSERT_VOP_LOCKED(vp, "mac_vnode_execve_will_transition");
  362 
  363         result = 0;
  364         /* No sleeping since the process lock will be held by the caller. */
  365         MAC_POLICY_BOOLEAN_NOSLEEP(vnode_execve_will_transition, ||, old, vp,
  366             vp->v_label, interpvplabel, imgp, imgp->execlabel);
  367 
  368         return (result);
  369 }
  370 
  371 MAC_CHECK_PROBE_DEFINE3(vnode_check_access, "struct ucred *",
  372     "struct vnode *", "accmode_t");
  373 
  374 int
  375 mac_vnode_check_access_impl(struct ucred *cred, struct vnode *vp, accmode_t accmode)
  376 {
  377         int error;
  378 
  379         ASSERT_VOP_LOCKED(vp, "mac_vnode_check_access");
  380 
  381         MAC_POLICY_CHECK(vnode_check_access, cred, vp, vp->v_label, accmode);
  382         MAC_CHECK_PROBE3(vnode_check_access, error, cred, vp, accmode);
  383 
  384         return (error);
  385 }
  386 
  387 MAC_CHECK_PROBE_DEFINE2(vnode_check_chdir, "struct ucred *",
  388     "struct vnode *");
  389 
  390 int
  391 mac_vnode_check_chdir(struct ucred *cred, struct vnode *dvp)
  392 {
  393         int error;
  394 
  395         ASSERT_VOP_LOCKED(dvp, "mac_vnode_check_chdir");
  396 
  397         MAC_POLICY_CHECK(vnode_check_chdir, cred, dvp, dvp->v_label);
  398         MAC_CHECK_PROBE2(vnode_check_chdir, error, cred, dvp);
  399 
  400         return (error);
  401 }
  402 
  403 MAC_CHECK_PROBE_DEFINE2(vnode_check_chroot, "struct ucred *",
  404     "struct vnode *");
  405 
  406 int
  407 mac_vnode_check_chroot(struct ucred *cred, struct vnode *dvp)
  408 {
  409         int error;
  410 
  411         ASSERT_VOP_LOCKED(dvp, "mac_vnode_check_chroot");
  412 
  413         MAC_POLICY_CHECK(vnode_check_chroot, cred, dvp, dvp->v_label);
  414         MAC_CHECK_PROBE2(vnode_check_chroot, error, cred, dvp);
  415 
  416         return (error);
  417 }
  418 
  419 MAC_CHECK_PROBE_DEFINE4(vnode_check_create, "struct ucred *",
  420     "struct vnode *", "struct componentname *", "struct vattr *");
  421 
  422 int
  423 mac_vnode_check_create(struct ucred *cred, struct vnode *dvp,
  424     struct componentname *cnp, struct vattr *vap)
  425 {
  426         int error;
  427 
  428         ASSERT_VOP_LOCKED(dvp, "mac_vnode_check_create");
  429 
  430         MAC_POLICY_CHECK(vnode_check_create, cred, dvp, dvp->v_label, cnp,
  431             vap);
  432         MAC_CHECK_PROBE4(vnode_check_create, error, cred, dvp, cnp, vap);
  433 
  434         return (error);
  435 }
  436 
  437 MAC_CHECK_PROBE_DEFINE3(vnode_check_deleteacl, "struct ucred *",
  438     "struct vnode *", "acl_type_t");
  439 
  440 int
  441 mac_vnode_check_deleteacl(struct ucred *cred, struct vnode *vp,
  442     acl_type_t type)
  443 {
  444         int error;
  445 
  446         ASSERT_VOP_LOCKED(vp, "mac_vnode_check_deleteacl");
  447 
  448         MAC_POLICY_CHECK(vnode_check_deleteacl, cred, vp, vp->v_label, type);
  449         MAC_CHECK_PROBE3(vnode_check_deleteacl, error, cred, vp, type);
  450 
  451         return (error);
  452 }
  453 
  454 MAC_CHECK_PROBE_DEFINE4(vnode_check_deleteextattr, "struct ucred *",
  455     "struct vnode *", "int", "const char *");
  456 
  457 int
  458 mac_vnode_check_deleteextattr(struct ucred *cred, struct vnode *vp,
  459     int attrnamespace, const char *name)
  460 {
  461         int error;
  462 
  463         ASSERT_VOP_LOCKED(vp, "mac_vnode_check_deleteextattr");
  464 
  465         MAC_POLICY_CHECK(vnode_check_deleteextattr, cred, vp, vp->v_label,
  466             attrnamespace, name);
  467         MAC_CHECK_PROBE4(vnode_check_deleteextattr, error, cred, vp,
  468             attrnamespace, name);
  469 
  470         return (error);
  471 }
  472 
  473 MAC_CHECK_PROBE_DEFINE3(vnode_check_exec, "struct ucred *", "struct vnode *",
  474     "struct image_params *");
  475 
  476 int
  477 mac_vnode_check_exec(struct ucred *cred, struct vnode *vp,
  478     struct image_params *imgp)
  479 {
  480         int error;
  481 
  482         ASSERT_VOP_LOCKED(vp, "mac_vnode_check_exec");
  483 
  484         MAC_POLICY_CHECK(vnode_check_exec, cred, vp, vp->v_label, imgp,
  485             imgp->execlabel);
  486         MAC_CHECK_PROBE3(vnode_check_exec, error, cred, vp, imgp);
  487 
  488         return (error);
  489 }
  490 
  491 MAC_CHECK_PROBE_DEFINE3(vnode_check_getacl, "struct ucred *",
  492     "struct vnode *", "acl_type_t");
  493 
  494 int
  495 mac_vnode_check_getacl(struct ucred *cred, struct vnode *vp, acl_type_t type)
  496 {
  497         int error;
  498 
  499         ASSERT_VOP_LOCKED(vp, "mac_vnode_check_getacl");
  500 
  501         MAC_POLICY_CHECK(vnode_check_getacl, cred, vp, vp->v_label, type);
  502         MAC_CHECK_PROBE3(vnode_check_getacl, error, cred, vp, type);
  503 
  504         return (error);
  505 }
  506 
  507 MAC_CHECK_PROBE_DEFINE4(vnode_check_getextattr, "struct ucred *",
  508     "struct vnode *", "int", "const char *");
  509 
  510 int
  511 mac_vnode_check_getextattr(struct ucred *cred, struct vnode *vp,
  512     int attrnamespace, const char *name)
  513 {
  514         int error;
  515 
  516         ASSERT_VOP_LOCKED(vp, "mac_vnode_check_getextattr");
  517 
  518         MAC_POLICY_CHECK(vnode_check_getextattr, cred, vp, vp->v_label,
  519             attrnamespace, name);
  520         MAC_CHECK_PROBE4(vnode_check_getextattr, error, cred, vp,
  521             attrnamespace, name);
  522 
  523         return (error);
  524 }
  525 
  526 MAC_CHECK_PROBE_DEFINE4(vnode_check_link, "struct ucred *", "struct vnode *",
  527     "struct vnode *", "struct componentname *");
  528 
  529 int
  530 mac_vnode_check_link(struct ucred *cred, struct vnode *dvp,
  531     struct vnode *vp, struct componentname *cnp)
  532 {
  533         int error;
  534 
  535         ASSERT_VOP_LOCKED(dvp, "mac_vnode_check_link");
  536         ASSERT_VOP_LOCKED(vp, "mac_vnode_check_link");
  537 
  538         MAC_POLICY_CHECK(vnode_check_link, cred, dvp, dvp->v_label, vp,
  539             vp->v_label, cnp);
  540         MAC_CHECK_PROBE4(vnode_check_link, error, cred, dvp, vp, cnp);
  541 
  542         return (error);
  543 }
  544 
  545 MAC_CHECK_PROBE_DEFINE3(vnode_check_listextattr, "struct ucred *",
  546     "struct vnode *", "int");
  547 
  548 int
  549 mac_vnode_check_listextattr(struct ucred *cred, struct vnode *vp,
  550     int attrnamespace)
  551 {
  552         int error;
  553 
  554         ASSERT_VOP_LOCKED(vp, "mac_vnode_check_listextattr");
  555 
  556         MAC_POLICY_CHECK(vnode_check_listextattr, cred, vp, vp->v_label,
  557             attrnamespace);
  558         MAC_CHECK_PROBE3(vnode_check_listextattr, error, cred, vp,
  559             attrnamespace);
  560 
  561         return (error);
  562 }
  563 
  564 MAC_CHECK_PROBE_DEFINE3(vnode_check_lookup, "struct ucred *",
  565     "struct vnode *", "struct componentname *");
  566 
  567 int
  568 mac_vnode_check_lookup_impl(struct ucred *cred, struct vnode *dvp,
  569     struct componentname *cnp)
  570 {
  571         int error;
  572 
  573         ASSERT_VOP_LOCKED(dvp, "mac_vnode_check_lookup");
  574 
  575         if ((cnp->cn_flags & NOMACCHECK) != 0)
  576                 return (0);
  577         MAC_POLICY_CHECK(vnode_check_lookup, cred, dvp, dvp->v_label, cnp);
  578         MAC_CHECK_PROBE3(vnode_check_lookup, error, cred, dvp, cnp);
  579 
  580         return (error);
  581 }
  582 
  583 MAC_CHECK_PROBE_DEFINE4(vnode_check_mmap, "struct ucred *", "struct vnode *",
  584     "int", "int");
  585 
  586 int
  587 mac_vnode_check_mmap_impl(struct ucred *cred, struct vnode *vp, int prot,
  588     int flags)
  589 {
  590         int error;
  591 
  592         ASSERT_VOP_LOCKED(vp, "mac_vnode_check_mmap");
  593 
  594         MAC_POLICY_CHECK(vnode_check_mmap, cred, vp, vp->v_label, prot, flags);
  595         MAC_CHECK_PROBE4(vnode_check_mmap, error, cred, vp, prot, flags);
  596 
  597         return (error);
  598 }
  599 
  600 void
  601 mac_vnode_check_mmap_downgrade(struct ucred *cred, struct vnode *vp,
  602     int *prot)
  603 {
  604         int result = *prot;
  605 
  606         ASSERT_VOP_LOCKED(vp, "mac_vnode_check_mmap_downgrade");
  607 
  608         MAC_POLICY_PERFORM(vnode_check_mmap_downgrade, cred, vp, vp->v_label,
  609             &result);
  610 
  611         *prot = result;
  612 }
  613 
  614 MAC_CHECK_PROBE_DEFINE3(vnode_check_mprotect, "struct ucred *",
  615     "struct vnode *", "int");
  616 
  617 int
  618 mac_vnode_check_mprotect(struct ucred *cred, struct vnode *vp, int prot)
  619 {
  620         int error;
  621 
  622         ASSERT_VOP_LOCKED(vp, "mac_vnode_check_mprotect");
  623 
  624         MAC_POLICY_CHECK(vnode_check_mprotect, cred, vp, vp->v_label, prot);
  625         MAC_CHECK_PROBE3(vnode_check_mprotect, error, cred, vp, prot);
  626 
  627         return (error);
  628 }
  629 
  630 MAC_CHECK_PROBE_DEFINE3(vnode_check_open, "struct ucred *", "struct vnode *",
  631     "accmode_t");
  632 
  633 int
  634 mac_vnode_check_open_impl(struct ucred *cred, struct vnode *vp, accmode_t accmode)
  635 {
  636         int error;
  637 
  638         ASSERT_VOP_LOCKED(vp, "mac_vnode_check_open");
  639 
  640         MAC_POLICY_CHECK(vnode_check_open, cred, vp, vp->v_label, accmode);
  641         MAC_CHECK_PROBE3(vnode_check_open, error, cred, vp, accmode);
  642 
  643         return (error);
  644 }
  645 
  646 MAC_CHECK_PROBE_DEFINE3(vnode_check_poll, "struct ucred *", "struct ucred *",
  647     "struct vnode *");
  648 
  649 int
  650 mac_vnode_check_poll(struct ucred *active_cred, struct ucred *file_cred,
  651     struct vnode *vp)
  652 {
  653         int error;
  654 
  655         ASSERT_VOP_LOCKED(vp, "mac_vnode_check_poll");
  656 
  657         MAC_POLICY_CHECK(vnode_check_poll, active_cred, file_cred, vp,
  658             vp->v_label);
  659         MAC_CHECK_PROBE3(vnode_check_poll, error, active_cred, file_cred,
  660             vp);
  661 
  662         return (error);
  663 }
  664 
  665 MAC_CHECK_PROBE_DEFINE3(vnode_check_read, "struct ucred *", "struct ucred *",
  666     "struct vnode *");
  667 
  668 int
  669 mac_vnode_check_read_impl(struct ucred *active_cred, struct ucred *file_cred,
  670     struct vnode *vp)
  671 {
  672         int error;
  673 
  674         ASSERT_VOP_LOCKED(vp, "mac_vnode_check_read");
  675 
  676         MAC_POLICY_CHECK(vnode_check_read, active_cred, file_cred, vp,
  677             vp->v_label);
  678         MAC_CHECK_PROBE3(vnode_check_read, error, active_cred, file_cred,
  679             vp);
  680 
  681         return (error);
  682 }
  683 
  684 MAC_CHECK_PROBE_DEFINE2(vnode_check_readdir, "struct ucred *",
  685     "struct vnode *");
  686 
  687 int
  688 mac_vnode_check_readdir(struct ucred *cred, struct vnode *dvp)
  689 {
  690         int error;
  691 
  692         ASSERT_VOP_LOCKED(dvp, "mac_vnode_check_readdir");
  693 
  694         MAC_POLICY_CHECK(vnode_check_readdir, cred, dvp, dvp->v_label);
  695         MAC_CHECK_PROBE2(vnode_check_readdir, error, cred, dvp);
  696 
  697         return (error);
  698 }
  699 
  700 MAC_CHECK_PROBE_DEFINE2(vnode_check_readlink, "struct ucred *",
  701     "struct vnode *");
  702 
  703 int
  704 mac_vnode_check_readlink_impl(struct ucred *cred, struct vnode *vp)
  705 {
  706         int error;
  707 
  708         ASSERT_VOP_LOCKED(vp, "mac_vnode_check_readlink");
  709 
  710         MAC_POLICY_CHECK(vnode_check_readlink, cred, vp, vp->v_label);
  711         MAC_CHECK_PROBE2(vnode_check_readlink, error, cred, vp);
  712 
  713         return (error);
  714 }
  715 
  716 MAC_CHECK_PROBE_DEFINE3(vnode_check_relabel, "struct ucred *",
  717     "struct vnode *", "struct label *");
  718 
  719 static int
  720 mac_vnode_check_relabel(struct ucred *cred, struct vnode *vp,
  721     struct label *newlabel)
  722 {
  723         int error;
  724 
  725         ASSERT_VOP_LOCKED(vp, "mac_vnode_check_relabel");
  726 
  727         MAC_POLICY_CHECK(vnode_check_relabel, cred, vp, vp->v_label, newlabel);
  728         MAC_CHECK_PROBE3(vnode_check_relabel, error, cred, vp, newlabel);
  729 
  730         return (error);
  731 }
  732 
  733 MAC_CHECK_PROBE_DEFINE4(vnode_check_rename_from, "struct ucred *",
  734     "struct vnode *", "struct vnode *", "struct componentname *");
  735 
  736 int
  737 mac_vnode_check_rename_from(struct ucred *cred, struct vnode *dvp,
  738     struct vnode *vp, struct componentname *cnp)
  739 {
  740         int error;
  741 
  742         ASSERT_VOP_LOCKED(dvp, "mac_vnode_check_rename_from");
  743         ASSERT_VOP_LOCKED(vp, "mac_vnode_check_rename_from");
  744 
  745         MAC_POLICY_CHECK(vnode_check_rename_from, cred, dvp, dvp->v_label, vp,
  746             vp->v_label, cnp);
  747         MAC_CHECK_PROBE4(vnode_check_rename_from, error, cred, dvp, vp, cnp);
  748 
  749         return (error);
  750 }
  751 
  752 MAC_CHECK_PROBE_DEFINE4(vnode_check_rename_to, "struct ucred *",
  753     "struct vnode *", "struct vnode *", "struct componentname *");
  754 
  755 int
  756 mac_vnode_check_rename_to(struct ucred *cred, struct vnode *dvp,
  757     struct vnode *vp, int samedir, struct componentname *cnp)
  758 {
  759         int error;
  760 
  761         ASSERT_VOP_LOCKED(dvp, "mac_vnode_check_rename_to");
  762         ASSERT_VOP_LOCKED(vp, "mac_vnode_check_rename_to");
  763 
  764         MAC_POLICY_CHECK(vnode_check_rename_to, cred, dvp, dvp->v_label, vp,
  765             vp != NULL ? vp->v_label : NULL, samedir, cnp);
  766         MAC_CHECK_PROBE4(vnode_check_rename_to, error, cred, dvp, vp, cnp);
  767         return (error);
  768 }
  769 
  770 MAC_CHECK_PROBE_DEFINE2(vnode_check_revoke, "struct ucred *",
  771     "struct vnode *");
  772 
  773 int
  774 mac_vnode_check_revoke(struct ucred *cred, struct vnode *vp)
  775 {
  776         int error;
  777 
  778         ASSERT_VOP_LOCKED(vp, "mac_vnode_check_revoke");
  779 
  780         MAC_POLICY_CHECK(vnode_check_revoke, cred, vp, vp->v_label);
  781         MAC_CHECK_PROBE2(vnode_check_revoke, error, cred, vp);
  782 
  783         return (error);
  784 }
  785 
  786 MAC_CHECK_PROBE_DEFINE4(vnode_check_setacl, "struct ucred *",
  787     "struct vnode *", "acl_type_t", "struct acl *");
  788 
  789 int
  790 mac_vnode_check_setacl(struct ucred *cred, struct vnode *vp, acl_type_t type,
  791     struct acl *acl)
  792 {
  793         int error;
  794 
  795         ASSERT_VOP_LOCKED(vp, "mac_vnode_check_setacl");
  796 
  797         MAC_POLICY_CHECK(vnode_check_setacl, cred, vp, vp->v_label, type, acl);
  798         MAC_CHECK_PROBE4(vnode_check_setacl, error, cred, vp, type, acl);
  799 
  800         return (error);
  801 }
  802 
  803 MAC_CHECK_PROBE_DEFINE4(vnode_check_setextattr, "struct ucred *",
  804     "struct vnode *", "int", "const char *");
  805 
  806 int
  807 mac_vnode_check_setextattr(struct ucred *cred, struct vnode *vp,
  808     int attrnamespace, const char *name)
  809 {
  810         int error;
  811 
  812         ASSERT_VOP_LOCKED(vp, "mac_vnode_check_setextattr");
  813 
  814         MAC_POLICY_CHECK(vnode_check_setextattr, cred, vp, vp->v_label,
  815             attrnamespace, name);
  816         MAC_CHECK_PROBE4(vnode_check_setextattr, error, cred, vp,
  817             attrnamespace, name);
  818 
  819         return (error);
  820 }
  821 
  822 MAC_CHECK_PROBE_DEFINE3(vnode_check_setflags, "struct ucred *",
  823     "struct vnode *", "u_long");
  824 
  825 int
  826 mac_vnode_check_setflags(struct ucred *cred, struct vnode *vp, u_long flags)
  827 {
  828         int error;
  829 
  830         ASSERT_VOP_LOCKED(vp, "mac_vnode_check_setflags");
  831 
  832         MAC_POLICY_CHECK(vnode_check_setflags, cred, vp, vp->v_label, flags);
  833         MAC_CHECK_PROBE3(vnode_check_setflags, error, cred, vp, flags);
  834 
  835         return (error);
  836 }
  837 
  838 MAC_CHECK_PROBE_DEFINE3(vnode_check_setmode, "struct ucred *",
  839     "struct vnode *", "mode_t");
  840 
  841 int
  842 mac_vnode_check_setmode(struct ucred *cred, struct vnode *vp, mode_t mode)
  843 {
  844         int error;
  845 
  846         ASSERT_VOP_LOCKED(vp, "mac_vnode_check_setmode");
  847 
  848         MAC_POLICY_CHECK(vnode_check_setmode, cred, vp, vp->v_label, mode);
  849         MAC_CHECK_PROBE3(vnode_check_setmode, error, cred, vp, mode);
  850 
  851         return (error);
  852 }
  853 
  854 MAC_CHECK_PROBE_DEFINE4(vnode_check_setowner, "struct ucred *",
  855     "struct vnode *", "uid_t", "gid_t");
  856 
  857 int
  858 mac_vnode_check_setowner(struct ucred *cred, struct vnode *vp, uid_t uid,
  859     gid_t gid)
  860 {
  861         int error;
  862 
  863         ASSERT_VOP_LOCKED(vp, "mac_vnode_check_setowner");
  864 
  865         MAC_POLICY_CHECK(vnode_check_setowner, cred, vp, vp->v_label, uid, gid);
  866         MAC_CHECK_PROBE4(vnode_check_setowner, error, cred, vp, uid, gid);
  867 
  868         return (error);
  869 }
  870 
  871 MAC_CHECK_PROBE_DEFINE4(vnode_check_setutimes, "struct ucred *",
  872     "struct vnode *", "struct timespec *", "struct timespec *");
  873 
  874 int
  875 mac_vnode_check_setutimes(struct ucred *cred, struct vnode *vp,
  876     struct timespec atime, struct timespec mtime)
  877 {
  878         int error;
  879 
  880         ASSERT_VOP_LOCKED(vp, "mac_vnode_check_setutimes");
  881 
  882         MAC_POLICY_CHECK(vnode_check_setutimes, cred, vp, vp->v_label, atime,
  883             mtime);
  884         MAC_CHECK_PROBE4(vnode_check_setutimes, error, cred, vp, &atime,
  885             &mtime);
  886 
  887         return (error);
  888 }
  889 
  890 MAC_CHECK_PROBE_DEFINE3(vnode_check_stat, "struct ucred *", "struct ucred *",
  891     "struct vnode *");
  892 
  893 int
  894 mac_vnode_check_stat_impl(struct ucred *active_cred, struct ucred *file_cred,
  895     struct vnode *vp)
  896 {
  897         int error;
  898 
  899         ASSERT_VOP_LOCKED(vp, "mac_vnode_check_stat");
  900 
  901         MAC_POLICY_CHECK(vnode_check_stat, active_cred, file_cred, vp,
  902             vp->v_label);
  903         MAC_CHECK_PROBE3(vnode_check_stat, error, active_cred, file_cred,
  904             vp);
  905 
  906         return (error);
  907 }
  908 
  909 MAC_CHECK_PROBE_DEFINE4(vnode_check_unlink, "struct ucred *",
  910     "struct vnode *", "struct vnode *", "struct componentname *");
  911 
  912 int
  913 mac_vnode_check_unlink(struct ucred *cred, struct vnode *dvp,
  914     struct vnode *vp, struct componentname *cnp)
  915 {
  916         int error;
  917 
  918         ASSERT_VOP_LOCKED(dvp, "mac_vnode_check_unlink");
  919         ASSERT_VOP_LOCKED(vp, "mac_vnode_check_unlink");
  920 
  921         MAC_POLICY_CHECK(vnode_check_unlink, cred, dvp, dvp->v_label, vp,
  922             vp->v_label, cnp);
  923         MAC_CHECK_PROBE4(vnode_check_unlink, error, cred, dvp, vp, cnp);
  924 
  925         return (error);
  926 }
  927 
  928 MAC_CHECK_PROBE_DEFINE3(vnode_check_write, "struct ucred *",
  929     "struct ucred *", "struct vnode *");
  930 
  931 int
  932 mac_vnode_check_write_impl(struct ucred *active_cred, struct ucred *file_cred,
  933     struct vnode *vp)
  934 {
  935         int error;
  936 
  937         ASSERT_VOP_LOCKED(vp, "mac_vnode_check_write");
  938 
  939         MAC_POLICY_CHECK(vnode_check_write, active_cred, file_cred, vp,
  940             vp->v_label);
  941         MAC_CHECK_PROBE3(vnode_check_write, error, active_cred, file_cred,
  942             vp);
  943 
  944         return (error);
  945 }
  946 
  947 void
  948 mac_vnode_relabel(struct ucred *cred, struct vnode *vp,
  949     struct label *newlabel)
  950 {
  951 
  952         MAC_POLICY_PERFORM(vnode_relabel, cred, vp, vp->v_label, newlabel);
  953 }
  954 
  955 void
  956 mac_mount_create(struct ucred *cred, struct mount *mp)
  957 {
  958 
  959         MAC_POLICY_PERFORM(mount_create, cred, mp, mp->mnt_label);
  960 }
  961 
  962 MAC_CHECK_PROBE_DEFINE2(mount_check_stat, "struct ucred *",
  963     "struct mount *");
  964 
  965 int
  966 mac_mount_check_stat(struct ucred *cred, struct mount *mount)
  967 {
  968         int error;
  969 
  970         MAC_POLICY_CHECK_NOSLEEP(mount_check_stat, cred, mount, mount->mnt_label);
  971         MAC_CHECK_PROBE2(mount_check_stat, error, cred, mount);
  972 
  973         return (error);
  974 }
  975 
  976 void
  977 mac_devfs_create_device(struct ucred *cred, struct mount *mp,
  978     struct cdev *dev, struct devfs_dirent *de)
  979 {
  980 
  981         MAC_POLICY_PERFORM_NOSLEEP(devfs_create_device, cred, mp, dev, de,
  982             de->de_label);
  983 }
  984 
  985 void
  986 mac_devfs_create_symlink(struct ucred *cred, struct mount *mp,
  987     struct devfs_dirent *dd, struct devfs_dirent *de)
  988 {
  989 
  990         MAC_POLICY_PERFORM_NOSLEEP(devfs_create_symlink, cred, mp, dd,
  991             dd->de_label, de, de->de_label);
  992 }
  993 
  994 void
  995 mac_devfs_create_directory(struct mount *mp, char *dirname, int dirnamelen,
  996     struct devfs_dirent *de)
  997 {
  998 
  999         MAC_POLICY_PERFORM_NOSLEEP(devfs_create_directory, mp, dirname,
 1000             dirnamelen, de, de->de_label);
 1001 }
 1002 
 1003 /*
 1004  * Implementation of VOP_SETLABEL() that relies on extended attributes to
 1005  * store label data.  Can be referenced by filesystems supporting extended
 1006  * attributes.
 1007  */
 1008 int
 1009 vop_stdsetlabel_ea(struct vop_setlabel_args *ap)
 1010 {
 1011         struct vnode *vp = ap->a_vp;
 1012         struct label *intlabel = ap->a_label;
 1013         int error;
 1014 
 1015         ASSERT_VOP_LOCKED(vp, "vop_stdsetlabel_ea");
 1016 
 1017         if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0)
 1018                 return (EOPNOTSUPP);
 1019 
 1020         error = mac_vnode_setlabel_extattr(ap->a_cred, vp, intlabel);
 1021         if (error)
 1022                 return (error);
 1023 
 1024         /*
 1025          * XXXRW: See the comment below in vn_setlabel() as to why this might
 1026          * be the wrong place to call mac_vnode_relabel().
 1027          */
 1028         mac_vnode_relabel(ap->a_cred, vp, intlabel);
 1029 
 1030         return (0);
 1031 }
 1032 
 1033 int
 1034 vn_setlabel(struct vnode *vp, struct label *intlabel, struct ucred *cred)
 1035 {
 1036         int error;
 1037 
 1038         if (vp->v_mount == NULL) {
 1039                 /* printf("vn_setlabel: null v_mount\n"); */
 1040                 if (vp->v_type != VNON)
 1041                         printf("vn_setlabel: null v_mount with non-VNON\n");
 1042                 return (EBADF);
 1043         }
 1044 
 1045         if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0)
 1046                 return (EOPNOTSUPP);
 1047 
 1048         /*
 1049          * Multi-phase commit.  First check the policies to confirm the
 1050          * change is OK.  Then commit via the filesystem.  Finally, update
 1051          * the actual vnode label.
 1052          */
 1053         error = mac_vnode_check_relabel(cred, vp, intlabel);
 1054         if (error)
 1055                 return (error);
 1056 
 1057         /*
 1058          * VADMIN provides the opportunity for the filesystem to make
 1059          * decisions about who is and is not able to modify labels and
 1060          * protections on files.  This might not be right.  We can't assume
 1061          * VOP_SETLABEL() will do it, because we might implement that as part
 1062          * of vop_stdsetlabel_ea().
 1063          */
 1064         error = VOP_ACCESS(vp, VADMIN, cred, curthread);
 1065         if (error)
 1066                 return (error);
 1067 
 1068         error = VOP_SETLABEL(vp, intlabel, cred, curthread);
 1069         if (error)
 1070                 return (error);
 1071 
 1072         /*
 1073          * It would be more symmetric if mac_vnode_relabel() was called here
 1074          * rather than in VOP_SETLABEL(), but we don't for historical reasons.
 1075          * We should think about moving it so that the filesystem is
 1076          * responsible only for persistence in VOP_SETLABEL(), not the vnode
 1077          * label update itself.
 1078          */
 1079 
 1080         return (0);
 1081 }
 1082 
 1083 #ifdef DEBUG_VFS_LOCKS
 1084 void
 1085 mac_vnode_assert_locked(struct vnode *vp, const char *func)
 1086 {
 1087 
 1088         ASSERT_VOP_LOCKED(vp, func);
 1089 }
 1090 #endif

Cache object: 86463fbed2157c317f983e89924c01d0


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