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 Robert N. M. Watson
    3  * Copyright (c) 2001 Ilmar S. Habibulin
    4  * Copyright (c) 2001-2005 McAfee, Inc.
    5  * Copyright (c) 2005 SPARTA, Inc.
    6  * All rights reserved.
    7  *
    8  * This software was developed by Robert Watson and Ilmar Habibulin for the
    9  * TrustedBSD Project.
   10  *
   11  * This software was developed for the FreeBSD Project in part by McAfee
   12  * Research, the Security Research Division of McAfee, Inc. under
   13  * DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA
   14  * CHATS research program.
   15  *
   16  * This software was enhanced by SPARTA ISSO under SPAWAR contract 
   17  * N66001-04-C-6019 ("SEFOS").
   18  *
   19  * Redistribution and use in source and binary forms, with or without
   20  * modification, are permitted provided that the following conditions
   21  * are met:
   22  * 1. Redistributions of source code must retain the above copyright
   23  *    notice, this list of conditions and the following disclaimer.
   24  * 2. Redistributions in binary form must reproduce the above copyright
   25  *    notice, this list of conditions and the following disclaimer in the
   26  *    documentation and/or other materials provided with the distribution.
   27  *
   28  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   29  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   30  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   31  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   32  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   33  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   34  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   35  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   36  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   37  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   38  * SUCH DAMAGE.
   39  */
   40 
   41 #include <sys/cdefs.h>
   42 __FBSDID("$FreeBSD: releng/6.2/sys/security/mac/mac_vfs.c 161925 2006-09-02 23:58:21Z csjp $");
   43 
   44 #include "opt_mac.h"
   45 #include "opt_devfs.h"
   46 
   47 #include <sys/param.h>
   48 #include <sys/condvar.h>
   49 #include <sys/extattr.h>
   50 #include <sys/imgact.h>
   51 #include <sys/kernel.h>
   52 #include <sys/lock.h>
   53 #include <sys/malloc.h>
   54 #include <sys/mutex.h>
   55 #include <sys/mac.h>
   56 #include <sys/proc.h>
   57 #include <sys/sbuf.h>
   58 #include <sys/systm.h>
   59 #include <sys/vnode.h>
   60 #include <sys/mount.h>
   61 #include <sys/file.h>
   62 #include <sys/namei.h>
   63 #include <sys/sysctl.h>
   64 
   65 #include <vm/vm.h>
   66 #include <vm/pmap.h>
   67 #include <vm/vm_map.h>
   68 #include <vm/vm_object.h>
   69 
   70 #include <sys/mac_policy.h>
   71 
   72 #include <fs/devfs/devfs.h>
   73 
   74 #include <security/mac/mac_internal.h>
   75 
   76 /*
   77  * Warn about EA transactions only the first time they happen.
   78  * Weak coherency, no locking.
   79  */
   80 static int      ea_warn_once = 0;
   81 
   82 static int      mac_enforce_fs = 1;
   83 SYSCTL_INT(_security_mac, OID_AUTO, enforce_fs, CTLFLAG_RW,
   84     &mac_enforce_fs, 0, "Enforce MAC policy on file system objects");
   85 TUNABLE_INT("security.mac.enforce_fs", &mac_enforce_fs);
   86 
   87 #ifdef MAC_DEBUG
   88 static int      mac_debug_label_fallback = 0;
   89 SYSCTL_INT(_security_mac_debug, OID_AUTO, label_fallback, CTLFLAG_RW,
   90     &mac_debug_label_fallback, 0, "Filesystems should fall back to fs label"
   91     "when label is corrupted.");
   92 TUNABLE_INT("security.mac.debug_label_fallback",
   93     &mac_debug_label_fallback);
   94 
   95 static unsigned int nmacmounts, nmacvnodes, nmacdevfsdirents;
   96 SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, mounts, CTLFLAG_RD,
   97     &nmacmounts, 0, "number of mounts in use");
   98 SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, vnodes, CTLFLAG_RD,
   99     &nmacvnodes, 0, "number of vnodes in use");
  100 SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, devfsdirents, CTLFLAG_RD,
  101     &nmacdevfsdirents, 0, "number of devfs dirents inuse");
  102 #endif
  103 
  104 static int      mac_setlabel_vnode_extattr(struct ucred *cred,
  105                     struct vnode *vp, struct label *intlabel);
  106 
  107 static struct label *
  108 mac_devfsdirent_label_alloc(void)
  109 {
  110         struct label *label;
  111 
  112         label = mac_labelzone_alloc(M_WAITOK);
  113         MAC_PERFORM(init_devfsdirent_label, label);
  114         MAC_DEBUG_COUNTER_INC(&nmacdevfsdirents);
  115         return (label);
  116 }
  117 
  118 void
  119 mac_init_devfsdirent(struct devfs_dirent *de)
  120 {
  121 
  122         de->de_label = mac_devfsdirent_label_alloc();
  123 }
  124 
  125 static struct label *
  126 mac_mount_label_alloc(void)
  127 {
  128         struct label *label;
  129 
  130         label = mac_labelzone_alloc(M_WAITOK);
  131         MAC_PERFORM(init_mount_label, label);
  132         MAC_DEBUG_COUNTER_INC(&nmacmounts);
  133         return (label);
  134 }
  135 
  136 static struct label *
  137 mac_mount_fs_label_alloc(void)
  138 {
  139         struct label *label;
  140 
  141         label = mac_labelzone_alloc(M_WAITOK);
  142         MAC_PERFORM(init_mount_fs_label, label);
  143         MAC_DEBUG_COUNTER_INC(&nmacmounts);
  144         return (label);
  145 }
  146 
  147 void
  148 mac_init_mount(struct mount *mp)
  149 {
  150 
  151         mp->mnt_mntlabel = mac_mount_label_alloc();
  152         mp->mnt_fslabel = mac_mount_fs_label_alloc();
  153 }
  154 
  155 struct label *
  156 mac_vnode_label_alloc(void)
  157 {
  158         struct label *label;
  159 
  160         label = mac_labelzone_alloc(M_WAITOK);
  161         MAC_PERFORM(init_vnode_label, label);
  162         MAC_DEBUG_COUNTER_INC(&nmacvnodes);
  163         return (label);
  164 }
  165 
  166 void
  167 mac_init_vnode(struct vnode *vp)
  168 {
  169 
  170         vp->v_label = mac_vnode_label_alloc();
  171 }
  172 
  173 static void
  174 mac_devfsdirent_label_free(struct label *label)
  175 {
  176 
  177         MAC_PERFORM(destroy_devfsdirent_label, label);
  178         mac_labelzone_free(label);
  179         MAC_DEBUG_COUNTER_DEC(&nmacdevfsdirents);
  180 }
  181 
  182 void
  183 mac_destroy_devfsdirent(struct devfs_dirent *de)
  184 {
  185 
  186         mac_devfsdirent_label_free(de->de_label);
  187         de->de_label = NULL;
  188 }
  189 
  190 static void
  191 mac_mount_label_free(struct label *label)
  192 {
  193 
  194         MAC_PERFORM(destroy_mount_label, label);
  195         mac_labelzone_free(label);
  196         MAC_DEBUG_COUNTER_DEC(&nmacmounts);
  197 }
  198 
  199 static void
  200 mac_mount_fs_label_free(struct label *label)
  201 {
  202 
  203         MAC_PERFORM(destroy_mount_fs_label, label);
  204         mac_labelzone_free(label);
  205         MAC_DEBUG_COUNTER_DEC(&nmacmounts);
  206 }
  207 
  208 void
  209 mac_destroy_mount(struct mount *mp)
  210 {
  211 
  212         mac_mount_fs_label_free(mp->mnt_fslabel);
  213         mp->mnt_fslabel = NULL;
  214         mac_mount_label_free(mp->mnt_mntlabel);
  215         mp->mnt_mntlabel = NULL;
  216 }
  217 
  218 void
  219 mac_vnode_label_free(struct label *label)
  220 {
  221 
  222         MAC_PERFORM(destroy_vnode_label, label);
  223         mac_labelzone_free(label);
  224         MAC_DEBUG_COUNTER_DEC(&nmacvnodes);
  225 }
  226 
  227 void
  228 mac_destroy_vnode(struct vnode *vp)
  229 {
  230 
  231         mac_vnode_label_free(vp->v_label);
  232         vp->v_label = NULL;
  233 }
  234 
  235 void
  236 mac_copy_vnode_label(struct label *src, struct label *dest)
  237 {
  238 
  239         MAC_PERFORM(copy_vnode_label, src, dest);
  240 }
  241 
  242 int
  243 mac_externalize_vnode_label(struct label *label, char *elements,
  244     char *outbuf, size_t outbuflen)
  245 {
  246         int error;
  247 
  248         MAC_EXTERNALIZE(vnode, label, elements, outbuf, outbuflen);
  249 
  250         return (error);
  251 }
  252 
  253 int
  254 mac_internalize_vnode_label(struct label *label, char *string)
  255 {
  256         int error;
  257 
  258         MAC_INTERNALIZE(vnode, label, string);
  259 
  260         return (error);
  261 }
  262 
  263 void
  264 mac_update_devfsdirent(struct mount *mp, struct devfs_dirent *de,
  265     struct vnode *vp)
  266 {
  267 
  268         MAC_PERFORM(update_devfsdirent, mp, de, de->de_label, vp,
  269             vp->v_label);
  270 }
  271 
  272 void
  273 mac_associate_vnode_devfs(struct mount *mp, struct devfs_dirent *de,
  274     struct vnode *vp)
  275 {
  276 
  277         MAC_PERFORM(associate_vnode_devfs, mp, mp->mnt_fslabel, de,
  278             de->de_label, vp, vp->v_label);
  279 }
  280 
  281 int
  282 mac_associate_vnode_extattr(struct mount *mp, struct vnode *vp)
  283 {
  284         int error;
  285 
  286         ASSERT_VOP_LOCKED(vp, "mac_associate_vnode_extattr");
  287 
  288         MAC_CHECK(associate_vnode_extattr, mp, mp->mnt_fslabel, vp,
  289             vp->v_label);
  290 
  291         return (error);
  292 }
  293 
  294 void
  295 mac_associate_vnode_singlelabel(struct mount *mp, struct vnode *vp)
  296 {
  297 
  298         MAC_PERFORM(associate_vnode_singlelabel, mp, mp->mnt_fslabel, vp,
  299             vp->v_label);
  300 }
  301 
  302 int
  303 mac_create_vnode_extattr(struct ucred *cred, struct mount *mp,
  304     struct vnode *dvp, struct vnode *vp, struct componentname *cnp)
  305 {
  306         int error;
  307 
  308         ASSERT_VOP_LOCKED(dvp, "mac_create_vnode_extattr");
  309         ASSERT_VOP_LOCKED(vp, "mac_create_vnode_extattr");
  310 
  311         error = VOP_OPENEXTATTR(vp, cred, curthread);
  312         if (error == EOPNOTSUPP) {
  313                 /* XXX: Optionally abort if transactions not supported. */
  314                 if (ea_warn_once == 0) {
  315                         printf("Warning: transactions not supported "
  316                             "in EA write.\n");
  317                         ea_warn_once = 1;
  318                 }
  319         } else if (error)
  320                 return (error);
  321 
  322         MAC_CHECK(create_vnode_extattr, cred, mp, mp->mnt_fslabel,
  323             dvp, dvp->v_label, vp, vp->v_label, cnp);
  324 
  325         if (error) {
  326                 VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread);
  327                 return (error);
  328         }
  329 
  330         error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread);
  331 
  332         if (error == EOPNOTSUPP)
  333                 error = 0;                              /* XXX */
  334 
  335         return (error);
  336 }
  337 
  338 static int
  339 mac_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp,
  340     struct label *intlabel)
  341 {
  342         int error;
  343 
  344         ASSERT_VOP_LOCKED(vp, "mac_setlabel_vnode_extattr");
  345 
  346         error = VOP_OPENEXTATTR(vp, cred, curthread);
  347         if (error == EOPNOTSUPP) {
  348                 /* XXX: Optionally abort if transactions not supported. */
  349                 if (ea_warn_once == 0) {
  350                         printf("Warning: transactions not supported "
  351                             "in EA write.\n");
  352                         ea_warn_once = 1;
  353                 }
  354         } else if (error)
  355                 return (error);
  356 
  357         MAC_CHECK(setlabel_vnode_extattr, cred, vp, vp->v_label, intlabel);
  358 
  359         if (error) {
  360                 VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread);
  361                 return (error);
  362         }
  363 
  364         error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread);
  365 
  366         if (error == EOPNOTSUPP)
  367                 error = 0;                              /* XXX */
  368 
  369         return (error);
  370 }
  371 
  372 void
  373 mac_execve_transition(struct ucred *old, struct ucred *new, struct vnode *vp,
  374     struct label *interpvnodelabel, struct image_params *imgp)
  375 {
  376 
  377         ASSERT_VOP_LOCKED(vp, "mac_execve_transition");
  378 
  379         if (!mac_enforce_process && !mac_enforce_fs)
  380                 return;
  381 
  382         MAC_PERFORM(execve_transition, old, new, vp, vp->v_label,
  383             interpvnodelabel, imgp, imgp->execlabel);
  384 }
  385 
  386 int
  387 mac_execve_will_transition(struct ucred *old, struct vnode *vp,
  388     struct label *interpvnodelabel, struct image_params *imgp)
  389 {
  390         int result;
  391 
  392         ASSERT_VOP_LOCKED(vp, "mac_execve_will_transition");
  393 
  394         if (!mac_enforce_process && !mac_enforce_fs)
  395                 return (0);
  396 
  397         result = 0;
  398         MAC_BOOLEAN(execve_will_transition, ||, old, vp, vp->v_label,
  399             interpvnodelabel, imgp, imgp->execlabel);
  400 
  401         return (result);
  402 }
  403 
  404 int
  405 mac_check_vnode_access(struct ucred *cred, struct vnode *vp, int acc_mode)
  406 {
  407         int error;
  408 
  409         ASSERT_VOP_LOCKED(vp, "mac_check_vnode_access");
  410 
  411         if (!mac_enforce_fs)
  412                 return (0);
  413 
  414         MAC_CHECK(check_vnode_access, cred, vp, vp->v_label, acc_mode);
  415         return (error);
  416 }
  417 
  418 int
  419 mac_check_vnode_chdir(struct ucred *cred, struct vnode *dvp)
  420 {
  421         int error;
  422 
  423         ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chdir");
  424 
  425         if (!mac_enforce_fs)
  426                 return (0);
  427 
  428         MAC_CHECK(check_vnode_chdir, cred, dvp, dvp->v_label);
  429         return (error);
  430 }
  431 
  432 int
  433 mac_check_vnode_chroot(struct ucred *cred, struct vnode *dvp)
  434 {
  435         int error;
  436 
  437         ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chroot");
  438 
  439         if (!mac_enforce_fs)
  440                 return (0);
  441 
  442         MAC_CHECK(check_vnode_chroot, cred, dvp, dvp->v_label);
  443         return (error);
  444 }
  445 
  446 int
  447 mac_check_vnode_create(struct ucred *cred, struct vnode *dvp,
  448     struct componentname *cnp, struct vattr *vap)
  449 {
  450         int error;
  451 
  452         ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_create");
  453 
  454         if (!mac_enforce_fs)
  455                 return (0);
  456 
  457         MAC_CHECK(check_vnode_create, cred, dvp, dvp->v_label, cnp, vap);
  458         return (error);
  459 }
  460 
  461 int
  462 mac_check_vnode_delete(struct ucred *cred, struct vnode *dvp, struct vnode *vp,
  463     struct componentname *cnp)
  464 {
  465         int error;
  466 
  467         ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_delete");
  468         ASSERT_VOP_LOCKED(vp, "mac_check_vnode_delete");
  469 
  470         if (!mac_enforce_fs)
  471                 return (0);
  472 
  473         MAC_CHECK(check_vnode_delete, cred, dvp, dvp->v_label, vp,
  474             vp->v_label, cnp);
  475         return (error);
  476 }
  477 
  478 int
  479 mac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
  480     acl_type_t type)
  481 {
  482         int error;
  483 
  484         ASSERT_VOP_LOCKED(vp, "mac_check_vnode_deleteacl");
  485 
  486         if (!mac_enforce_fs)
  487                 return (0);
  488 
  489         MAC_CHECK(check_vnode_deleteacl, cred, vp, vp->v_label, type);
  490         return (error);
  491 }
  492 
  493 int
  494 mac_check_vnode_deleteextattr(struct ucred *cred, struct vnode *vp,
  495     int attrnamespace, const char *name)
  496 {
  497         int error;
  498 
  499         ASSERT_VOP_LOCKED(vp, "mac_check_vnode_deleteextattr");
  500 
  501         if (!mac_enforce_fs)
  502                 return (0);
  503 
  504         MAC_CHECK(check_vnode_deleteextattr, cred, vp, vp->v_label,
  505             attrnamespace, name);
  506         return (error);
  507 }
  508 
  509 int
  510 mac_check_vnode_exec(struct ucred *cred, struct vnode *vp,
  511     struct image_params *imgp)
  512 {
  513         int error;
  514 
  515         ASSERT_VOP_LOCKED(vp, "mac_check_vnode_exec");
  516 
  517         if (!mac_enforce_process && !mac_enforce_fs)
  518                 return (0);
  519 
  520         MAC_CHECK(check_vnode_exec, cred, vp, vp->v_label, imgp,
  521             imgp->execlabel);
  522 
  523         return (error);
  524 }
  525 
  526 int
  527 mac_check_vnode_getacl(struct ucred *cred, struct vnode *vp, acl_type_t type)
  528 {
  529         int error;
  530 
  531         ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getacl");
  532 
  533         if (!mac_enforce_fs)
  534                 return (0);
  535 
  536         MAC_CHECK(check_vnode_getacl, cred, vp, vp->v_label, type);
  537         return (error);
  538 }
  539 
  540 int
  541 mac_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
  542     int attrnamespace, const char *name, struct uio *uio)
  543 {
  544         int error;
  545 
  546         ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getextattr");
  547 
  548         if (!mac_enforce_fs)
  549                 return (0);
  550 
  551         MAC_CHECK(check_vnode_getextattr, cred, vp, vp->v_label,
  552             attrnamespace, name, uio);
  553         return (error);
  554 }
  555 
  556 int
  557 mac_check_vnode_link(struct ucred *cred, struct vnode *dvp,
  558     struct vnode *vp, struct componentname *cnp)
  559 {
  560         int error;
  561 
  562         ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_link");
  563         ASSERT_VOP_LOCKED(vp, "mac_check_vnode_link");
  564 
  565         if (!mac_enforce_fs)
  566                 return (0);
  567 
  568         MAC_CHECK(check_vnode_link, cred, dvp, dvp->v_label, vp,
  569             vp->v_label, cnp);
  570         return (error);
  571 }
  572 
  573 int
  574 mac_check_vnode_listextattr(struct ucred *cred, struct vnode *vp,
  575     int attrnamespace)
  576 {
  577         int error;
  578 
  579         ASSERT_VOP_LOCKED(vp, "mac_check_vnode_listextattr");
  580 
  581         if (!mac_enforce_fs)
  582                 return (0);
  583 
  584         MAC_CHECK(check_vnode_listextattr, cred, vp, vp->v_label,
  585             attrnamespace);
  586         return (error);
  587 }
  588 
  589 int
  590 mac_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
  591     struct componentname *cnp)
  592 {
  593         int error;
  594 
  595         ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_lookup");
  596 
  597         if (!mac_enforce_fs)
  598                 return (0);
  599 
  600         MAC_CHECK(check_vnode_lookup, cred, dvp, dvp->v_label, cnp);
  601         return (error);
  602 }
  603 
  604 int
  605 mac_check_vnode_mmap(struct ucred *cred, struct vnode *vp,
  606     int prot, int flags)
  607 {
  608         int error;
  609 
  610         ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap");
  611 
  612         if (!mac_enforce_fs || !mac_enforce_vm)
  613                 return (0);
  614 
  615         MAC_CHECK(check_vnode_mmap, cred, vp, vp->v_label, prot, flags);
  616         return (error);
  617 }
  618 
  619 void
  620 mac_check_vnode_mmap_downgrade(struct ucred *cred, struct vnode *vp, int *prot)
  621 {
  622         int result = *prot;
  623 
  624         ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap_downgrade");
  625 
  626         if (!mac_enforce_fs || !mac_enforce_vm)
  627                 return;
  628 
  629         MAC_PERFORM(check_vnode_mmap_downgrade, cred, vp, vp->v_label,
  630             &result);
  631 
  632         *prot = result;
  633 }
  634 
  635 int
  636 mac_check_vnode_mprotect(struct ucred *cred, struct vnode *vp, int prot)
  637 {
  638         int error;
  639 
  640         ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mprotect");
  641 
  642         if (!mac_enforce_fs || !mac_enforce_vm)
  643                 return (0);
  644 
  645         MAC_CHECK(check_vnode_mprotect, cred, vp, vp->v_label, prot);
  646         return (error);
  647 }
  648 
  649 int
  650 mac_check_vnode_open(struct ucred *cred, struct vnode *vp, int acc_mode)
  651 {
  652         int error;
  653 
  654         ASSERT_VOP_LOCKED(vp, "mac_check_vnode_open");
  655 
  656         if (!mac_enforce_fs)
  657                 return (0);
  658 
  659         MAC_CHECK(check_vnode_open, cred, vp, vp->v_label, acc_mode);
  660         return (error);
  661 }
  662 
  663 int
  664 mac_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred,
  665     struct vnode *vp)
  666 {
  667         int error;
  668 
  669         ASSERT_VOP_LOCKED(vp, "mac_check_vnode_poll");
  670 
  671         if (!mac_enforce_fs)
  672                 return (0);
  673 
  674         MAC_CHECK(check_vnode_poll, active_cred, file_cred, vp,
  675             vp->v_label);
  676 
  677         return (error);
  678 }
  679 
  680 int
  681 mac_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
  682     struct vnode *vp)
  683 {
  684         int error;
  685 
  686         ASSERT_VOP_LOCKED(vp, "mac_check_vnode_read");
  687 
  688         if (!mac_enforce_fs)
  689                 return (0);
  690 
  691         MAC_CHECK(check_vnode_read, active_cred, file_cred, vp,
  692             vp->v_label);
  693 
  694         return (error);
  695 }
  696 
  697 int
  698 mac_check_vnode_readdir(struct ucred *cred, struct vnode *dvp)
  699 {
  700         int error;
  701 
  702         ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_readdir");
  703 
  704         if (!mac_enforce_fs)
  705                 return (0);
  706 
  707         MAC_CHECK(check_vnode_readdir, cred, dvp, dvp->v_label);
  708         return (error);
  709 }
  710 
  711 int
  712 mac_check_vnode_readlink(struct ucred *cred, struct vnode *vp)
  713 {
  714         int error;
  715 
  716         ASSERT_VOP_LOCKED(vp, "mac_check_vnode_readlink");
  717 
  718         if (!mac_enforce_fs)
  719                 return (0);
  720 
  721         MAC_CHECK(check_vnode_readlink, cred, vp, vp->v_label);
  722         return (error);
  723 }
  724 
  725 static int
  726 mac_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
  727     struct label *newlabel)
  728 {
  729         int error;
  730 
  731         ASSERT_VOP_LOCKED(vp, "mac_check_vnode_relabel");
  732 
  733         MAC_CHECK(check_vnode_relabel, cred, vp, vp->v_label, newlabel);
  734 
  735         return (error);
  736 }
  737 
  738 int
  739 mac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
  740     struct vnode *vp, struct componentname *cnp)
  741 {
  742         int error;
  743 
  744         ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_from");
  745         ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_from");
  746 
  747         if (!mac_enforce_fs)
  748                 return (0);
  749 
  750         MAC_CHECK(check_vnode_rename_from, cred, dvp, dvp->v_label, vp,
  751             vp->v_label, cnp);
  752         return (error);
  753 }
  754 
  755 int
  756 mac_check_vnode_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_check_vnode_rename_to");
  762         ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_to");
  763 
  764         if (!mac_enforce_fs)
  765                 return (0);
  766 
  767         MAC_CHECK(check_vnode_rename_to, cred, dvp, dvp->v_label, vp,
  768             vp != NULL ? vp->v_label : NULL, samedir, cnp);
  769         return (error);
  770 }
  771 
  772 int
  773 mac_check_vnode_revoke(struct ucred *cred, struct vnode *vp)
  774 {
  775         int error;
  776 
  777         ASSERT_VOP_LOCKED(vp, "mac_check_vnode_revoke");
  778 
  779         if (!mac_enforce_fs)
  780                 return (0);
  781 
  782         MAC_CHECK(check_vnode_revoke, cred, vp, vp->v_label);
  783         return (error);
  784 }
  785 
  786 int
  787 mac_check_vnode_setacl(struct ucred *cred, struct vnode *vp, acl_type_t type,
  788     struct acl *acl)
  789 {
  790         int error;
  791 
  792         ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setacl");
  793 
  794         if (!mac_enforce_fs)
  795                 return (0);
  796 
  797         MAC_CHECK(check_vnode_setacl, cred, vp, vp->v_label, type, acl);
  798         return (error);
  799 }
  800 
  801 int
  802 mac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
  803     int attrnamespace, const char *name, struct uio *uio)
  804 {
  805         int error;
  806 
  807         ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setextattr");
  808 
  809         if (!mac_enforce_fs)
  810                 return (0);
  811 
  812         MAC_CHECK(check_vnode_setextattr, cred, vp, vp->v_label,
  813             attrnamespace, name, uio);
  814         return (error);
  815 }
  816 
  817 int
  818 mac_check_vnode_setflags(struct ucred *cred, struct vnode *vp, u_long flags)
  819 {
  820         int error;
  821 
  822         ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setflags");
  823 
  824         if (!mac_enforce_fs)
  825                 return (0);
  826 
  827         MAC_CHECK(check_vnode_setflags, cred, vp, vp->v_label, flags);
  828         return (error);
  829 }
  830 
  831 int
  832 mac_check_vnode_setmode(struct ucred *cred, struct vnode *vp, mode_t mode)
  833 {
  834         int error;
  835 
  836         ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setmode");
  837 
  838         if (!mac_enforce_fs)
  839                 return (0);
  840 
  841         MAC_CHECK(check_vnode_setmode, cred, vp, vp->v_label, mode);
  842         return (error);
  843 }
  844 
  845 int
  846 mac_check_vnode_setowner(struct ucred *cred, struct vnode *vp, uid_t uid,
  847     gid_t gid)
  848 {
  849         int error;
  850 
  851         ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setowner");
  852 
  853         if (!mac_enforce_fs)
  854                 return (0);
  855 
  856         MAC_CHECK(check_vnode_setowner, cred, vp, vp->v_label, uid, gid);
  857         return (error);
  858 }
  859 
  860 int
  861 mac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
  862     struct timespec atime, struct timespec mtime)
  863 {
  864         int error;
  865 
  866         ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setutimes");
  867 
  868         if (!mac_enforce_fs)
  869                 return (0);
  870 
  871         MAC_CHECK(check_vnode_setutimes, cred, vp, vp->v_label, atime,
  872             mtime);
  873         return (error);
  874 }
  875 
  876 int
  877 mac_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
  878     struct vnode *vp)
  879 {
  880         int error;
  881 
  882         ASSERT_VOP_LOCKED(vp, "mac_check_vnode_stat");
  883 
  884         if (!mac_enforce_fs)
  885                 return (0);
  886 
  887         MAC_CHECK(check_vnode_stat, active_cred, file_cred, vp,
  888             vp->v_label);
  889         return (error);
  890 }
  891 
  892 int
  893 mac_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred,
  894     struct vnode *vp)
  895 {
  896         int error;
  897 
  898         ASSERT_VOP_LOCKED(vp, "mac_check_vnode_write");
  899 
  900         if (!mac_enforce_fs)
  901                 return (0);
  902 
  903         MAC_CHECK(check_vnode_write, active_cred, file_cred, vp,
  904             vp->v_label);
  905 
  906         return (error);
  907 }
  908 
  909 void
  910 mac_relabel_vnode(struct ucred *cred, struct vnode *vp, struct label *newlabel)
  911 {
  912 
  913         MAC_PERFORM(relabel_vnode, cred, vp, vp->v_label, newlabel);
  914 }
  915 
  916 void
  917 mac_create_mount(struct ucred *cred, struct mount *mp)
  918 {
  919 
  920         MAC_PERFORM(create_mount, cred, mp, mp->mnt_mntlabel,
  921             mp->mnt_fslabel);
  922 }
  923 
  924 int
  925 mac_check_mount_stat(struct ucred *cred, struct mount *mount)
  926 {
  927         int error;
  928 
  929         if (!mac_enforce_fs)
  930                 return (0);
  931 
  932         MAC_CHECK(check_mount_stat, cred, mount, mount->mnt_mntlabel);
  933 
  934         return (error);
  935 }
  936 
  937 void
  938 mac_create_devfs_device(struct ucred *cred, struct mount *mp,
  939     struct cdev *dev, struct devfs_dirent *de)
  940 {
  941 
  942         MAC_PERFORM(create_devfs_device, cred, mp, dev, de, de->de_label);
  943 }
  944 
  945 void
  946 mac_create_devfs_symlink(struct ucred *cred, struct mount *mp,
  947     struct devfs_dirent *dd, struct devfs_dirent *de)
  948 {
  949 
  950         MAC_PERFORM(create_devfs_symlink, cred, mp, dd, dd->de_label, de,
  951             de->de_label);
  952 }
  953 
  954 void
  955 mac_create_devfs_directory(struct mount *mp, char *dirname, int dirnamelen,
  956     struct devfs_dirent *de)
  957 {
  958 
  959         MAC_PERFORM(create_devfs_directory, mp, dirname, dirnamelen, de,
  960             de->de_label);
  961 }
  962 
  963 /*
  964  * Implementation of VOP_SETLABEL() that relies on extended attributes
  965  * to store label data.  Can be referenced by filesystems supporting
  966  * extended attributes.
  967  */
  968 int
  969 vop_stdsetlabel_ea(struct vop_setlabel_args *ap)
  970 {
  971         struct vnode *vp = ap->a_vp;
  972         struct label *intlabel = ap->a_label;
  973         int error;
  974 
  975         ASSERT_VOP_LOCKED(vp, "vop_stdsetlabel_ea");
  976 
  977         if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0)
  978                 return (EOPNOTSUPP);
  979 
  980         error = mac_setlabel_vnode_extattr(ap->a_cred, vp, intlabel);
  981         if (error)
  982                 return (error);
  983 
  984         mac_relabel_vnode(ap->a_cred, vp, intlabel);
  985 
  986         return (0);
  987 }
  988 
  989 int
  990 vn_setlabel(struct vnode *vp, struct label *intlabel, struct ucred *cred)
  991 {
  992         int error;
  993 
  994         if (vp->v_mount == NULL) {
  995                 /* printf("vn_setlabel: null v_mount\n"); */
  996                 if (vp->v_type != VNON)
  997                         printf("vn_setlabel: null v_mount with non-VNON\n");
  998                 return (EBADF);
  999         }
 1000 
 1001         if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0)
 1002                 return (EOPNOTSUPP);
 1003 
 1004         /*
 1005          * Multi-phase commit.  First check the policies to confirm the
 1006          * change is OK.  Then commit via the filesystem.  Finally,
 1007          * update the actual vnode label.  Question: maybe the filesystem
 1008          * should update the vnode at the end as part of VOP_SETLABEL()?
 1009          */
 1010         error = mac_check_vnode_relabel(cred, vp, intlabel);
 1011         if (error)
 1012                 return (error);
 1013 
 1014         /*
 1015          * VADMIN provides the opportunity for the filesystem to make
 1016          * decisions about who is and is not able to modify labels
 1017          * and protections on files.  This might not be right.  We can't
 1018          * assume VOP_SETLABEL() will do it, because we might implement
 1019          * that as part of vop_stdsetlabel_ea().
 1020          */
 1021         error = VOP_ACCESS(vp, VADMIN, cred, curthread);
 1022         if (error)
 1023                 return (error);
 1024 
 1025         error = VOP_SETLABEL(vp, intlabel, cred, curthread);
 1026         if (error)
 1027                 return (error);
 1028 
 1029         return (0);
 1030 }
 1031 
 1032 void
 1033 mac_associate_nfsd_label(struct ucred *cred)
 1034 {
 1035 
 1036         MAC_PERFORM(associate_nfsd_label, cred);
 1037 }

Cache object: 314f546eec3c49df36cde8c2b794c365


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