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_mls/mac_mls.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, 2007-2011 Robert N. M. Watson
    3  * Copyright (c) 2001-2005 McAfee, Inc.
    4  * Copyright (c) 2006 SPARTA, Inc.
    5  * All rights reserved.
    6  *
    7  * This software was developed by Robert Watson for the TrustedBSD Project.
    8  *
    9  * This software was developed for the FreeBSD Project in part by McAfee
   10  * Research, the Security Research Division of McAfee, Inc. under
   11  * DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA
   12  * CHATS research program.
   13  *
   14  * This software was enhanced by SPARTA ISSO under SPAWAR contract
   15  * N66001-04-C-6019 ("SEFOS").
   16  *
   17  * This software was developed at the University of Cambridge Computer
   18  * Laboratory with support from a grant from Google, Inc.
   19  *
   20  * Redistribution and use in source and binary forms, with or without
   21  * modification, are permitted provided that the following conditions
   22  * are met:
   23  * 1. Redistributions of source code must retain the above copyright
   24  *    notice, this list of conditions and the following disclaimer.
   25  * 2. Redistributions in binary form must reproduce the above copyright
   26  *    notice, this list of conditions and the following disclaimer in the
   27  *    documentation and/or other materials provided with the distribution.
   28  *
   29  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   30  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   31  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   32  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   33  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   34  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   35  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   36  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   37  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   38  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   39  * SUCH DAMAGE.
   40  *
   41  * $FreeBSD: releng/9.1/sys/security/mac_mls/mac_mls.c 235511 2012-05-16 19:25:50Z brueffer $
   42  */
   43 
   44 /*
   45  * Developed by the TrustedBSD Project.
   46  *
   47  * MLS fixed label mandatory confidentiality policy.
   48  */
   49 
   50 #include <sys/types.h>
   51 #include <sys/param.h>
   52 #include <sys/acl.h>
   53 #include <sys/conf.h>
   54 #include <sys/extattr.h>
   55 #include <sys/kernel.h>
   56 #include <sys/ksem.h>
   57 #include <sys/mman.h>
   58 #include <sys/malloc.h>
   59 #include <sys/mount.h>
   60 #include <sys/proc.h>
   61 #include <sys/sbuf.h>
   62 #include <sys/systm.h>
   63 #include <sys/sysproto.h>
   64 #include <sys/sysent.h>
   65 #include <sys/systm.h>
   66 #include <sys/vnode.h>
   67 #include <sys/file.h>
   68 #include <sys/socket.h>
   69 #include <sys/socketvar.h>
   70 #include <sys/pipe.h>
   71 #include <sys/sx.h>
   72 #include <sys/sysctl.h>
   73 #include <sys/msg.h>
   74 #include <sys/sem.h>
   75 #include <sys/shm.h>
   76 
   77 #include <fs/devfs/devfs.h>
   78 
   79 #include <net/bpfdesc.h>
   80 #include <net/if.h>
   81 #include <net/if_types.h>
   82 #include <net/if_var.h>
   83 
   84 #include <netinet/in.h>
   85 #include <netinet/in_pcb.h>
   86 #include <netinet/ip_var.h>
   87 
   88 #include <vm/uma.h>
   89 #include <vm/vm.h>
   90 
   91 #include <security/mac/mac_policy.h>
   92 #include <security/mac_mls/mac_mls.h>
   93 
   94 SYSCTL_DECL(_security_mac);
   95 
   96 SYSCTL_NODE(_security_mac, OID_AUTO, mls, CTLFLAG_RW, 0,
   97     "TrustedBSD mac_mls policy controls");
   98 
   99 static int      mls_label_size = sizeof(struct mac_mls);
  100 SYSCTL_INT(_security_mac_mls, OID_AUTO, label_size, CTLFLAG_RD,
  101     &mls_label_size, 0, "Size of struct mac_mls");
  102 
  103 static int      mls_enabled = 1;
  104 SYSCTL_INT(_security_mac_mls, OID_AUTO, enabled, CTLFLAG_RW, &mls_enabled, 0,
  105     "Enforce MAC/MLS policy");
  106 TUNABLE_INT("security.mac.mls.enabled", &mls_enabled);
  107 
  108 static int      destroyed_not_inited;
  109 SYSCTL_INT(_security_mac_mls, OID_AUTO, destroyed_not_inited, CTLFLAG_RD,
  110     &destroyed_not_inited, 0, "Count of labels destroyed but not inited");
  111 
  112 static int      ptys_equal = 0;
  113 SYSCTL_INT(_security_mac_mls, OID_AUTO, ptys_equal, CTLFLAG_RW,
  114     &ptys_equal, 0, "Label pty devices as mls/equal on create");
  115 TUNABLE_INT("security.mac.mls.ptys_equal", &ptys_equal);
  116 
  117 static int      revocation_enabled = 0;
  118 SYSCTL_INT(_security_mac_mls, OID_AUTO, revocation_enabled, CTLFLAG_RW,
  119     &revocation_enabled, 0, "Revoke access to objects on relabel");
  120 TUNABLE_INT("security.mac.mls.revocation_enabled", &revocation_enabled);
  121 
  122 static int      max_compartments = MAC_MLS_MAX_COMPARTMENTS;
  123 SYSCTL_INT(_security_mac_mls, OID_AUTO, max_compartments, CTLFLAG_RD,
  124     &max_compartments, 0, "Maximum compartments the policy supports");
  125 
  126 static int      mls_slot;
  127 #define SLOT(l) ((struct mac_mls *)mac_label_get((l), mls_slot))
  128 #define SLOT_SET(l, val) mac_label_set((l), mls_slot, (uintptr_t)(val))
  129 
  130 static uma_zone_t       zone_mls;
  131 
  132 static __inline int
  133 mls_bit_set_empty(u_char *set) {
  134         int i;
  135 
  136         for (i = 0; i < MAC_MLS_MAX_COMPARTMENTS >> 3; i++)
  137                 if (set[i] != 0)
  138                         return (0);
  139         return (1);
  140 }
  141 
  142 static struct mac_mls *
  143 mls_alloc(int flag)
  144 {
  145 
  146         return (uma_zalloc(zone_mls, flag | M_ZERO));
  147 }
  148 
  149 static void
  150 mls_free(struct mac_mls *mm)
  151 {
  152 
  153         if (mm != NULL)
  154                 uma_zfree(zone_mls, mm);
  155         else
  156                 atomic_add_int(&destroyed_not_inited, 1);
  157 }
  158 
  159 static int
  160 mls_atmostflags(struct mac_mls *mm, int flags)
  161 {
  162 
  163         if ((mm->mm_flags & flags) != mm->mm_flags)
  164                 return (EINVAL);
  165         return (0);
  166 }
  167 
  168 static int
  169 mls_dominate_element(struct mac_mls_element *a, struct mac_mls_element *b)
  170 {
  171         int bit;
  172 
  173         switch (a->mme_type) {
  174         case MAC_MLS_TYPE_EQUAL:
  175         case MAC_MLS_TYPE_HIGH:
  176                 return (1);
  177 
  178         case MAC_MLS_TYPE_LOW:
  179                 switch (b->mme_type) {
  180                 case MAC_MLS_TYPE_LEVEL:
  181                 case MAC_MLS_TYPE_HIGH:
  182                         return (0);
  183 
  184                 case MAC_MLS_TYPE_EQUAL:
  185                 case MAC_MLS_TYPE_LOW:
  186                         return (1);
  187 
  188                 default:
  189                         panic("mls_dominate_element: b->mme_type invalid");
  190                 }
  191 
  192         case MAC_MLS_TYPE_LEVEL:
  193                 switch (b->mme_type) {
  194                 case MAC_MLS_TYPE_EQUAL:
  195                 case MAC_MLS_TYPE_LOW:
  196                         return (1);
  197 
  198                 case MAC_MLS_TYPE_HIGH:
  199                         return (0);
  200 
  201                 case MAC_MLS_TYPE_LEVEL:
  202                         for (bit = 1; bit <= MAC_MLS_MAX_COMPARTMENTS; bit++)
  203                                 if (!MAC_MLS_BIT_TEST(bit,
  204                                     a->mme_compartments) &&
  205                                     MAC_MLS_BIT_TEST(bit, b->mme_compartments))
  206                                         return (0);
  207                         return (a->mme_level >= b->mme_level);
  208 
  209                 default:
  210                         panic("mls_dominate_element: b->mme_type invalid");
  211                 }
  212 
  213         default:
  214                 panic("mls_dominate_element: a->mme_type invalid");
  215         }
  216 
  217         return (0);
  218 }
  219 
  220 static int
  221 mls_range_in_range(struct mac_mls *rangea, struct mac_mls *rangeb)
  222 {
  223 
  224         return (mls_dominate_element(&rangeb->mm_rangehigh,
  225             &rangea->mm_rangehigh) &&
  226             mls_dominate_element(&rangea->mm_rangelow,
  227             &rangeb->mm_rangelow));
  228 }
  229 
  230 static int
  231 mls_effective_in_range(struct mac_mls *effective, struct mac_mls *range)
  232 {
  233 
  234         KASSERT((effective->mm_flags & MAC_MLS_FLAG_EFFECTIVE) != 0,
  235             ("mls_effective_in_range: a not effective"));
  236         KASSERT((range->mm_flags & MAC_MLS_FLAG_RANGE) != 0,
  237             ("mls_effective_in_range: b not range"));
  238 
  239         return (mls_dominate_element(&range->mm_rangehigh,
  240             &effective->mm_effective) &&
  241             mls_dominate_element(&effective->mm_effective,
  242             &range->mm_rangelow));
  243 
  244         return (1);
  245 }
  246 
  247 static int
  248 mls_dominate_effective(struct mac_mls *a, struct mac_mls *b)
  249 {
  250         KASSERT((a->mm_flags & MAC_MLS_FLAG_EFFECTIVE) != 0,
  251             ("mls_dominate_effective: a not effective"));
  252         KASSERT((b->mm_flags & MAC_MLS_FLAG_EFFECTIVE) != 0,
  253             ("mls_dominate_effective: b not effective"));
  254 
  255         return (mls_dominate_element(&a->mm_effective, &b->mm_effective));
  256 }
  257 
  258 static int
  259 mls_equal_element(struct mac_mls_element *a, struct mac_mls_element *b)
  260 {
  261 
  262         if (a->mme_type == MAC_MLS_TYPE_EQUAL ||
  263             b->mme_type == MAC_MLS_TYPE_EQUAL)
  264                 return (1);
  265 
  266         return (a->mme_type == b->mme_type && a->mme_level == b->mme_level);
  267 }
  268 
  269 static int
  270 mls_equal_effective(struct mac_mls *a, struct mac_mls *b)
  271 {
  272 
  273         KASSERT((a->mm_flags & MAC_MLS_FLAG_EFFECTIVE) != 0,
  274             ("mls_equal_effective: a not effective"));
  275         KASSERT((b->mm_flags & MAC_MLS_FLAG_EFFECTIVE) != 0,
  276             ("mls_equal_effective: b not effective"));
  277 
  278         return (mls_equal_element(&a->mm_effective, &b->mm_effective));
  279 }
  280 
  281 static int
  282 mls_contains_equal(struct mac_mls *mm)
  283 {
  284 
  285         if (mm->mm_flags & MAC_MLS_FLAG_EFFECTIVE)
  286                 if (mm->mm_effective.mme_type == MAC_MLS_TYPE_EQUAL)
  287                         return (1);
  288 
  289         if (mm->mm_flags & MAC_MLS_FLAG_RANGE) {
  290                 if (mm->mm_rangelow.mme_type == MAC_MLS_TYPE_EQUAL)
  291                         return (1);
  292                 if (mm->mm_rangehigh.mme_type == MAC_MLS_TYPE_EQUAL)
  293                         return (1);
  294         }
  295 
  296         return (0);
  297 }
  298 
  299 static int
  300 mls_subject_privileged(struct mac_mls *mm)
  301 {
  302 
  303         KASSERT((mm->mm_flags & MAC_MLS_FLAGS_BOTH) == MAC_MLS_FLAGS_BOTH,
  304             ("mls_subject_privileged: subject doesn't have both labels"));
  305 
  306         /* If the effective is EQUAL, it's ok. */
  307         if (mm->mm_effective.mme_type == MAC_MLS_TYPE_EQUAL)
  308                 return (0);
  309 
  310         /* If either range endpoint is EQUAL, it's ok. */
  311         if (mm->mm_rangelow.mme_type == MAC_MLS_TYPE_EQUAL ||
  312             mm->mm_rangehigh.mme_type == MAC_MLS_TYPE_EQUAL)
  313                 return (0);
  314 
  315         /* If the range is low-high, it's ok. */
  316         if (mm->mm_rangelow.mme_type == MAC_MLS_TYPE_LOW &&
  317             mm->mm_rangehigh.mme_type == MAC_MLS_TYPE_HIGH)
  318                 return (0);
  319 
  320         /* It's not ok. */
  321         return (EPERM);
  322 }
  323 
  324 static int
  325 mls_valid(struct mac_mls *mm)
  326 {
  327 
  328         if (mm->mm_flags & MAC_MLS_FLAG_EFFECTIVE) {
  329                 switch (mm->mm_effective.mme_type) {
  330                 case MAC_MLS_TYPE_LEVEL:
  331                         break;
  332 
  333                 case MAC_MLS_TYPE_EQUAL:
  334                 case MAC_MLS_TYPE_HIGH:
  335                 case MAC_MLS_TYPE_LOW:
  336                         if (mm->mm_effective.mme_level != 0 ||
  337                             !MAC_MLS_BIT_SET_EMPTY(
  338                             mm->mm_effective.mme_compartments))
  339                                 return (EINVAL);
  340                         break;
  341 
  342                 default:
  343                         return (EINVAL);
  344                 }
  345         } else {
  346                 if (mm->mm_effective.mme_type != MAC_MLS_TYPE_UNDEF)
  347                         return (EINVAL);
  348         }
  349 
  350         if (mm->mm_flags & MAC_MLS_FLAG_RANGE) {
  351                 switch (mm->mm_rangelow.mme_type) {
  352                 case MAC_MLS_TYPE_LEVEL:
  353                         break;
  354 
  355                 case MAC_MLS_TYPE_EQUAL:
  356                 case MAC_MLS_TYPE_HIGH:
  357                 case MAC_MLS_TYPE_LOW:
  358                         if (mm->mm_rangelow.mme_level != 0 ||
  359                             !MAC_MLS_BIT_SET_EMPTY(
  360                             mm->mm_rangelow.mme_compartments))
  361                                 return (EINVAL);
  362                         break;
  363 
  364                 default:
  365                         return (EINVAL);
  366                 }
  367 
  368                 switch (mm->mm_rangehigh.mme_type) {
  369                 case MAC_MLS_TYPE_LEVEL:
  370                         break;
  371 
  372                 case MAC_MLS_TYPE_EQUAL:
  373                 case MAC_MLS_TYPE_HIGH:
  374                 case MAC_MLS_TYPE_LOW:
  375                         if (mm->mm_rangehigh.mme_level != 0 ||
  376                             !MAC_MLS_BIT_SET_EMPTY(
  377                             mm->mm_rangehigh.mme_compartments))
  378                                 return (EINVAL);
  379                         break;
  380 
  381                 default:
  382                         return (EINVAL);
  383                 }
  384                 if (!mls_dominate_element(&mm->mm_rangehigh,
  385                     &mm->mm_rangelow))
  386                         return (EINVAL);
  387         } else {
  388                 if (mm->mm_rangelow.mme_type != MAC_MLS_TYPE_UNDEF ||
  389                     mm->mm_rangehigh.mme_type != MAC_MLS_TYPE_UNDEF)
  390                         return (EINVAL);
  391         }
  392 
  393         return (0);
  394 }
  395 
  396 static void
  397 mls_set_range(struct mac_mls *mm, u_short typelow, u_short levellow,
  398     u_char *compartmentslow, u_short typehigh, u_short levelhigh,
  399     u_char *compartmentshigh)
  400 {
  401 
  402         mm->mm_rangelow.mme_type = typelow;
  403         mm->mm_rangelow.mme_level = levellow;
  404         if (compartmentslow != NULL)
  405                 memcpy(mm->mm_rangelow.mme_compartments, compartmentslow,
  406                     sizeof(mm->mm_rangelow.mme_compartments));
  407         mm->mm_rangehigh.mme_type = typehigh;
  408         mm->mm_rangehigh.mme_level = levelhigh;
  409         if (compartmentshigh != NULL)
  410                 memcpy(mm->mm_rangehigh.mme_compartments, compartmentshigh,
  411                     sizeof(mm->mm_rangehigh.mme_compartments));
  412         mm->mm_flags |= MAC_MLS_FLAG_RANGE;
  413 }
  414 
  415 static void
  416 mls_set_effective(struct mac_mls *mm, u_short type, u_short level,
  417     u_char *compartments)
  418 {
  419 
  420         mm->mm_effective.mme_type = type;
  421         mm->mm_effective.mme_level = level;
  422         if (compartments != NULL)
  423                 memcpy(mm->mm_effective.mme_compartments, compartments,
  424                     sizeof(mm->mm_effective.mme_compartments));
  425         mm->mm_flags |= MAC_MLS_FLAG_EFFECTIVE;
  426 }
  427 
  428 static void
  429 mls_copy_range(struct mac_mls *labelfrom, struct mac_mls *labelto)
  430 {
  431 
  432         KASSERT((labelfrom->mm_flags & MAC_MLS_FLAG_RANGE) != 0,
  433             ("mls_copy_range: labelfrom not range"));
  434 
  435         labelto->mm_rangelow = labelfrom->mm_rangelow;
  436         labelto->mm_rangehigh = labelfrom->mm_rangehigh;
  437         labelto->mm_flags |= MAC_MLS_FLAG_RANGE;
  438 }
  439 
  440 static void
  441 mls_copy_effective(struct mac_mls *labelfrom, struct mac_mls *labelto)
  442 {
  443 
  444         KASSERT((labelfrom->mm_flags & MAC_MLS_FLAG_EFFECTIVE) != 0,
  445             ("mls_copy_effective: labelfrom not effective"));
  446 
  447         labelto->mm_effective = labelfrom->mm_effective;
  448         labelto->mm_flags |= MAC_MLS_FLAG_EFFECTIVE;
  449 }
  450 
  451 static void
  452 mls_copy(struct mac_mls *source, struct mac_mls *dest)
  453 {
  454 
  455         if (source->mm_flags & MAC_MLS_FLAG_EFFECTIVE)
  456                 mls_copy_effective(source, dest);
  457         if (source->mm_flags & MAC_MLS_FLAG_RANGE)
  458                 mls_copy_range(source, dest);
  459 }
  460 
  461 /*
  462  * Policy module operations.
  463  */
  464 static void
  465 mls_init(struct mac_policy_conf *conf)
  466 {
  467 
  468         zone_mls = uma_zcreate("mac_mls", sizeof(struct mac_mls), NULL,
  469             NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
  470 }
  471 
  472 /*
  473  * Label operations.
  474  */
  475 static void
  476 mls_init_label(struct label *label)
  477 {
  478 
  479         SLOT_SET(label, mls_alloc(M_WAITOK));
  480 }
  481 
  482 static int
  483 mls_init_label_waitcheck(struct label *label, int flag)
  484 {
  485 
  486         SLOT_SET(label, mls_alloc(flag));
  487         if (SLOT(label) == NULL)
  488                 return (ENOMEM);
  489 
  490         return (0);
  491 }
  492 
  493 static void
  494 mls_destroy_label(struct label *label)
  495 {
  496 
  497         mls_free(SLOT(label));
  498         SLOT_SET(label, NULL);
  499 }
  500 
  501 /*
  502  * mls_element_to_string() accepts an sbuf and MLS element.  It converts the
  503  * MLS element to a string and stores the result in the sbuf; if there isn't
  504  * space in the sbuf, -1 is returned.
  505  */
  506 static int
  507 mls_element_to_string(struct sbuf *sb, struct mac_mls_element *element)
  508 {
  509         int i, first;
  510 
  511         switch (element->mme_type) {
  512         case MAC_MLS_TYPE_HIGH:
  513                 return (sbuf_printf(sb, "high"));
  514 
  515         case MAC_MLS_TYPE_LOW:
  516                 return (sbuf_printf(sb, "low"));
  517 
  518         case MAC_MLS_TYPE_EQUAL:
  519                 return (sbuf_printf(sb, "equal"));
  520 
  521         case MAC_MLS_TYPE_LEVEL:
  522                 if (sbuf_printf(sb, "%d", element->mme_level) == -1)
  523                         return (-1);
  524 
  525                 first = 1;
  526                 for (i = 1; i <= MAC_MLS_MAX_COMPARTMENTS; i++) {
  527                         if (MAC_MLS_BIT_TEST(i, element->mme_compartments)) {
  528                                 if (first) {
  529                                         if (sbuf_putc(sb, ':') == -1)
  530                                                 return (-1);
  531                                         if (sbuf_printf(sb, "%d", i) == -1)
  532                                                 return (-1);
  533                                         first = 0;
  534                                 } else {
  535                                         if (sbuf_printf(sb, "+%d", i) == -1)
  536                                                 return (-1);
  537                                 }
  538                         }
  539                 }
  540                 return (0);
  541 
  542         default:
  543                 panic("mls_element_to_string: invalid type (%d)",
  544                     element->mme_type);
  545         }
  546 }
  547 
  548 /*
  549  * mls_to_string() converts an MLS label to a string, and places the results
  550  * in the passed sbuf.  It returns 0 on success, or EINVAL if there isn't
  551  * room in the sbuf.  Note: the sbuf will be modified even in a failure case,
  552  * so the caller may need to revert the sbuf by restoring the offset if
  553  * that's undesired.
  554  */
  555 static int
  556 mls_to_string(struct sbuf *sb, struct mac_mls *mm)
  557 {
  558 
  559         if (mm->mm_flags & MAC_MLS_FLAG_EFFECTIVE) {
  560                 if (mls_element_to_string(sb, &mm->mm_effective) == -1)
  561                         return (EINVAL);
  562         }
  563 
  564         if (mm->mm_flags & MAC_MLS_FLAG_RANGE) {
  565                 if (sbuf_putc(sb, '(') == -1)
  566                         return (EINVAL);
  567 
  568                 if (mls_element_to_string(sb, &mm->mm_rangelow) == -1)
  569                         return (EINVAL);
  570 
  571                 if (sbuf_putc(sb, '-') == -1)
  572                         return (EINVAL);
  573 
  574                 if (mls_element_to_string(sb, &mm->mm_rangehigh) == -1)
  575                         return (EINVAL);
  576 
  577                 if (sbuf_putc(sb, ')') == -1)
  578                         return (EINVAL);
  579         }
  580 
  581         return (0);
  582 }
  583 
  584 static int
  585 mls_externalize_label(struct label *label, char *element_name,
  586     struct sbuf *sb, int *claimed)
  587 {
  588         struct mac_mls *mm;
  589 
  590         if (strcmp(MAC_MLS_LABEL_NAME, element_name) != 0)
  591                 return (0);
  592 
  593         (*claimed)++;
  594 
  595         mm = SLOT(label);
  596 
  597         return (mls_to_string(sb, mm));
  598 }
  599 
  600 static int
  601 mls_parse_element(struct mac_mls_element *element, char *string)
  602 {
  603         char *compartment, *end, *level;
  604         int value;
  605 
  606         if (strcmp(string, "high") == 0 || strcmp(string, "hi") == 0) {
  607                 element->mme_type = MAC_MLS_TYPE_HIGH;
  608                 element->mme_level = MAC_MLS_TYPE_UNDEF;
  609         } else if (strcmp(string, "low") == 0 || strcmp(string, "lo") == 0) {
  610                 element->mme_type = MAC_MLS_TYPE_LOW;
  611                 element->mme_level = MAC_MLS_TYPE_UNDEF;
  612         } else if (strcmp(string, "equal") == 0 ||
  613             strcmp(string, "eq") == 0) {
  614                 element->mme_type = MAC_MLS_TYPE_EQUAL;
  615                 element->mme_level = MAC_MLS_TYPE_UNDEF;
  616         } else {
  617                 element->mme_type = MAC_MLS_TYPE_LEVEL;
  618 
  619                 /*
  620                  * Numeric level piece of the element.
  621                  */
  622                 level = strsep(&string, ":");
  623                 value = strtol(level, &end, 10);
  624                 if (end == level || *end != '\0')
  625                         return (EINVAL);
  626                 if (value < 0 || value > 65535)
  627                         return (EINVAL);
  628                 element->mme_level = value;
  629 
  630                 /*
  631                  * Optional compartment piece of the element.  If none are
  632                  * included, we assume that the label has no compartments.
  633                  */
  634                 if (string == NULL)
  635                         return (0);
  636                 if (*string == '\0')
  637                         return (0);
  638 
  639                 while ((compartment = strsep(&string, "+")) != NULL) {
  640                         value = strtol(compartment, &end, 10);
  641                         if (compartment == end || *end != '\0')
  642                                 return (EINVAL);
  643                         if (value < 1 || value > MAC_MLS_MAX_COMPARTMENTS)
  644                                 return (EINVAL);
  645                         MAC_MLS_BIT_SET(value, element->mme_compartments);
  646                 }
  647         }
  648 
  649         return (0);
  650 }
  651 
  652 /*
  653  * Note: destructively consumes the string, make a local copy before calling
  654  * if that's a problem.
  655  */
  656 static int
  657 mls_parse(struct mac_mls *mm, char *string)
  658 {
  659         char *rangehigh, *rangelow, *effective;
  660         int error;
  661 
  662         effective = strsep(&string, "(");
  663         if (*effective == '\0')
  664                 effective = NULL;
  665 
  666         if (string != NULL) {
  667                 rangelow = strsep(&string, "-");
  668                 if (string == NULL)
  669                         return (EINVAL);
  670                 rangehigh = strsep(&string, ")");
  671                 if (string == NULL)
  672                         return (EINVAL);
  673                 if (*string != '\0')
  674                         return (EINVAL);
  675         } else {
  676                 rangelow = NULL;
  677                 rangehigh = NULL;
  678         }
  679 
  680         KASSERT((rangelow != NULL && rangehigh != NULL) ||
  681             (rangelow == NULL && rangehigh == NULL),
  682             ("mls_parse: range mismatch"));
  683 
  684         bzero(mm, sizeof(*mm));
  685         if (effective != NULL) {
  686                 error = mls_parse_element(&mm->mm_effective, effective);
  687                 if (error)
  688                         return (error);
  689                 mm->mm_flags |= MAC_MLS_FLAG_EFFECTIVE;
  690         }
  691 
  692         if (rangelow != NULL) {
  693                 error = mls_parse_element(&mm->mm_rangelow, rangelow);
  694                 if (error)
  695                         return (error);
  696                 error = mls_parse_element(&mm->mm_rangehigh, rangehigh);
  697                 if (error)
  698                         return (error);
  699                 mm->mm_flags |= MAC_MLS_FLAG_RANGE;
  700         }
  701 
  702         error = mls_valid(mm);
  703         if (error)
  704                 return (error);
  705 
  706         return (0);
  707 }
  708 
  709 static int
  710 mls_internalize_label(struct label *label, char *element_name,
  711     char *element_data, int *claimed)
  712 {
  713         struct mac_mls *mm, mm_temp;
  714         int error;
  715 
  716         if (strcmp(MAC_MLS_LABEL_NAME, element_name) != 0)
  717                 return (0);
  718 
  719         (*claimed)++;
  720 
  721         error = mls_parse(&mm_temp, element_data);
  722         if (error)
  723                 return (error);
  724 
  725         mm = SLOT(label);
  726         *mm = mm_temp;
  727 
  728         return (0);
  729 }
  730 
  731 static void
  732 mls_copy_label(struct label *src, struct label *dest)
  733 {
  734 
  735         *SLOT(dest) = *SLOT(src);
  736 }
  737 
  738 /*
  739  * Object-specific entry point implementations are sorted alphabetically by
  740  * object type name and then by operation.
  741  */
  742 static int
  743 mls_bpfdesc_check_receive(struct bpf_d *d, struct label *dlabel,
  744      struct ifnet *ifp, struct label *ifplabel)
  745 {
  746         struct mac_mls *a, *b;
  747 
  748         if (!mls_enabled)
  749                 return (0);
  750 
  751         a = SLOT(dlabel);
  752         b = SLOT(ifplabel);
  753 
  754         if (mls_equal_effective(a, b))
  755                 return (0);
  756         return (EACCES);
  757 }
  758 
  759 static void
  760 mls_bpfdesc_create(struct ucred *cred, struct bpf_d *d, struct label *dlabel)
  761 {
  762         struct mac_mls *source, *dest;
  763 
  764         source = SLOT(cred->cr_label);
  765         dest = SLOT(dlabel);
  766 
  767         mls_copy_effective(source, dest);
  768 }
  769 
  770 static void
  771 mls_bpfdesc_create_mbuf(struct bpf_d *d, struct label *dlabel,
  772     struct mbuf *m, struct label *mlabel)
  773 {
  774         struct mac_mls *source, *dest;
  775 
  776         source = SLOT(dlabel);
  777         dest = SLOT(mlabel);
  778 
  779         mls_copy_effective(source, dest);
  780 }
  781 
  782 static void
  783 mls_cred_associate_nfsd(struct ucred *cred) 
  784 {
  785         struct mac_mls *label;
  786 
  787         label = SLOT(cred->cr_label);
  788         mls_set_effective(label, MAC_MLS_TYPE_LOW, 0, NULL);
  789         mls_set_range(label, MAC_MLS_TYPE_LOW, 0, NULL, MAC_MLS_TYPE_HIGH, 0,
  790             NULL);
  791 }
  792 
  793 static int
  794 mls_cred_check_relabel(struct ucred *cred, struct label *newlabel)
  795 {
  796         struct mac_mls *subj, *new;
  797         int error;
  798 
  799         subj = SLOT(cred->cr_label);
  800         new = SLOT(newlabel);
  801 
  802         /*
  803          * If there is an MLS label update for the credential, it may be an
  804          * update of effective, range, or both.
  805          */
  806         error = mls_atmostflags(new, MAC_MLS_FLAGS_BOTH);
  807         if (error)
  808                 return (error);
  809 
  810         /*
  811          * If the MLS label is to be changed, authorize as appropriate.
  812          */
  813         if (new->mm_flags & MAC_MLS_FLAGS_BOTH) {
  814                 /*
  815                  * If the change request modifies both the MLS label
  816                  * effective and range, check that the new effective will be
  817                  * in the new range.
  818                  */
  819                 if ((new->mm_flags & MAC_MLS_FLAGS_BOTH) ==
  820                     MAC_MLS_FLAGS_BOTH && !mls_effective_in_range(new, new))
  821                         return (EINVAL);
  822 
  823                 /*
  824                  * To change the MLS effective label on a credential, the new
  825                  * effective label must be in the current range.
  826                  */
  827                 if (new->mm_flags & MAC_MLS_FLAG_EFFECTIVE &&
  828                     !mls_effective_in_range(new, subj))
  829                         return (EPERM);
  830 
  831                 /*
  832                  * To change the MLS range label on a credential, the new
  833                  * range must be in the current range.
  834                  */
  835                 if (new->mm_flags & MAC_MLS_FLAG_RANGE &&
  836                     !mls_range_in_range(new, subj))
  837                         return (EPERM);
  838 
  839                 /*
  840                  * To have EQUAL in any component of the new credential MLS
  841                  * label, the subject must already have EQUAL in their label.
  842                  */
  843                 if (mls_contains_equal(new)) {
  844                         error = mls_subject_privileged(subj);
  845                         if (error)
  846                                 return (error);
  847                 }
  848         }
  849 
  850         return (0);
  851 }
  852 
  853 static int
  854 mls_cred_check_visible(struct ucred *cr1, struct ucred *cr2)
  855 {
  856         struct mac_mls *subj, *obj;
  857 
  858         if (!mls_enabled)
  859                 return (0);
  860 
  861         subj = SLOT(cr1->cr_label);
  862         obj = SLOT(cr2->cr_label);
  863 
  864         /* XXX: range */
  865         if (!mls_dominate_effective(subj, obj))
  866                 return (ESRCH);
  867 
  868         return (0);
  869 }
  870 
  871 static void
  872 mls_cred_create_init(struct ucred *cred)
  873 {
  874         struct mac_mls *dest;
  875 
  876         dest = SLOT(cred->cr_label);
  877 
  878         mls_set_effective(dest, MAC_MLS_TYPE_LOW, 0, NULL);
  879         mls_set_range(dest, MAC_MLS_TYPE_LOW, 0, NULL, MAC_MLS_TYPE_HIGH, 0,
  880             NULL);
  881 }
  882 
  883 static void
  884 mls_cred_create_swapper(struct ucred *cred)
  885 {
  886         struct mac_mls *dest;
  887 
  888         dest = SLOT(cred->cr_label);
  889 
  890         mls_set_effective(dest, MAC_MLS_TYPE_EQUAL, 0, NULL);
  891         mls_set_range(dest, MAC_MLS_TYPE_LOW, 0, NULL, MAC_MLS_TYPE_HIGH, 0,
  892             NULL);
  893 }
  894 
  895 static void
  896 mls_cred_relabel(struct ucred *cred, struct label *newlabel)
  897 {
  898         struct mac_mls *source, *dest;
  899 
  900         source = SLOT(newlabel);
  901         dest = SLOT(cred->cr_label);
  902 
  903         mls_copy(source, dest);
  904 }
  905 
  906 static void
  907 mls_devfs_create_device(struct ucred *cred, struct mount *mp,
  908     struct cdev *dev, struct devfs_dirent *de, struct label *delabel)
  909 {
  910         struct mac_mls *mm;
  911         const char *dn;
  912         int mls_type;
  913 
  914         mm = SLOT(delabel);
  915         dn = devtoname(dev);
  916         if (strcmp(dn, "null") == 0 ||
  917             strcmp(dn, "zero") == 0 ||
  918             strcmp(dn, "random") == 0 ||
  919             strncmp(dn, "fd/", strlen("fd/")) == 0)
  920                 mls_type = MAC_MLS_TYPE_EQUAL;
  921         else if (strcmp(dn, "kmem") == 0 ||
  922             strcmp(dn, "mem") == 0)
  923                 mls_type = MAC_MLS_TYPE_HIGH;
  924         else if (ptys_equal &&
  925             (strncmp(dn, "ttyp", strlen("ttyp")) == 0 ||
  926             strncmp(dn, "pts/", strlen("pts/")) == 0 ||
  927             strncmp(dn, "ptyp", strlen("ptyp")) == 0))
  928                 mls_type = MAC_MLS_TYPE_EQUAL;
  929         else
  930                 mls_type = MAC_MLS_TYPE_LOW;
  931         mls_set_effective(mm, mls_type, 0, NULL);
  932 }
  933 
  934 static void
  935 mls_devfs_create_directory(struct mount *mp, char *dirname, int dirnamelen,
  936     struct devfs_dirent *de, struct label *delabel)
  937 {
  938         struct mac_mls *mm;
  939 
  940         mm = SLOT(delabel);
  941         mls_set_effective(mm, MAC_MLS_TYPE_LOW, 0, NULL);
  942 }
  943 
  944 static void
  945 mls_devfs_create_symlink(struct ucred *cred, struct mount *mp,
  946     struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de,
  947     struct label *delabel)
  948 {
  949         struct mac_mls *source, *dest;
  950 
  951         source = SLOT(cred->cr_label);
  952         dest = SLOT(delabel);
  953 
  954         mls_copy_effective(source, dest);
  955 }
  956 
  957 static void
  958 mls_devfs_update(struct mount *mp, struct devfs_dirent *de,
  959     struct label *delabel, struct vnode *vp, struct label *vplabel)
  960 {
  961         struct mac_mls *source, *dest;
  962 
  963         source = SLOT(vplabel);
  964         dest = SLOT(delabel);
  965 
  966         mls_copy_effective(source, dest);
  967 }
  968 
  969 static void
  970 mls_devfs_vnode_associate(struct mount *mp, struct label *mplabel,
  971     struct devfs_dirent *de, struct label *delabel, struct vnode *vp,
  972     struct label *vplabel)
  973 {
  974         struct mac_mls *source, *dest;
  975 
  976         source = SLOT(delabel);
  977         dest = SLOT(vplabel);
  978 
  979         mls_copy_effective(source, dest);
  980 }
  981 
  982 static int
  983 mls_ifnet_check_relabel(struct ucred *cred, struct ifnet *ifp,
  984     struct label *ifplabel, struct label *newlabel)
  985 {
  986         struct mac_mls *subj, *new;
  987         int error;
  988 
  989         subj = SLOT(cred->cr_label);
  990         new = SLOT(newlabel);
  991 
  992         /*
  993          * If there is an MLS label update for the interface, it may be an
  994          * update of effective, range, or both.
  995          */
  996         error = mls_atmostflags(new, MAC_MLS_FLAGS_BOTH);
  997         if (error)
  998                 return (error);
  999 
 1000         /*
 1001          * Relabeling network interfaces requires MLS privilege.
 1002          */
 1003         return (mls_subject_privileged(subj));
 1004 }
 1005 
 1006 static int
 1007 mls_ifnet_check_transmit(struct ifnet *ifp, struct label *ifplabel,
 1008     struct mbuf *m, struct label *mlabel)
 1009 {
 1010         struct mac_mls *p, *i;
 1011 
 1012         if (!mls_enabled)
 1013                 return (0);
 1014 
 1015         p = SLOT(mlabel);
 1016         i = SLOT(ifplabel);
 1017 
 1018         return (mls_effective_in_range(p, i) ? 0 : EACCES);
 1019 }
 1020 
 1021 static void
 1022 mls_ifnet_create(struct ifnet *ifp, struct label *ifplabel)
 1023 {
 1024         struct mac_mls *dest;
 1025         int type;
 1026 
 1027         dest = SLOT(ifplabel);
 1028 
 1029         if (ifp->if_type == IFT_LOOP)
 1030                 type = MAC_MLS_TYPE_EQUAL;
 1031         else
 1032                 type = MAC_MLS_TYPE_LOW;
 1033 
 1034         mls_set_effective(dest, type, 0, NULL);
 1035         mls_set_range(dest, type, 0, NULL, type, 0, NULL);
 1036 }
 1037 
 1038 static void
 1039 mls_ifnet_create_mbuf(struct ifnet *ifp, struct label *ifplabel,
 1040     struct mbuf *m, struct label *mlabel)
 1041 {
 1042         struct mac_mls *source, *dest;
 1043 
 1044         source = SLOT(ifplabel);
 1045         dest = SLOT(mlabel);
 1046 
 1047         mls_copy_effective(source, dest);
 1048 }
 1049 
 1050 static void
 1051 mls_ifnet_relabel(struct ucred *cred, struct ifnet *ifp,
 1052     struct label *ifplabel, struct label *newlabel)
 1053 {
 1054         struct mac_mls *source, *dest;
 1055 
 1056         source = SLOT(newlabel);
 1057         dest = SLOT(ifplabel);
 1058 
 1059         mls_copy(source, dest);
 1060 }
 1061 
 1062 static int
 1063 mls_inpcb_check_deliver(struct inpcb *inp, struct label *inplabel,
 1064     struct mbuf *m, struct label *mlabel)
 1065 {
 1066         struct mac_mls *p, *i;
 1067 
 1068         if (!mls_enabled)
 1069                 return (0);
 1070 
 1071         p = SLOT(mlabel);
 1072         i = SLOT(inplabel);
 1073 
 1074         return (mls_equal_effective(p, i) ? 0 : EACCES);
 1075 }
 1076 
 1077 static int
 1078 mls_inpcb_check_visible(struct ucred *cred, struct inpcb *inp,
 1079     struct label *inplabel)
 1080 {
 1081         struct mac_mls *subj, *obj;
 1082 
 1083         if (!mls_enabled)
 1084                 return (0);
 1085 
 1086         subj = SLOT(cred->cr_label);
 1087         obj = SLOT(inplabel);
 1088 
 1089         if (!mls_dominate_effective(subj, obj))
 1090                 return (ENOENT);
 1091 
 1092         return (0);
 1093 }
 1094 
 1095 static void
 1096 mls_inpcb_create(struct socket *so, struct label *solabel, struct inpcb *inp,
 1097     struct label *inplabel)
 1098 {
 1099         struct mac_mls *source, *dest;
 1100 
 1101         source = SLOT(solabel);
 1102         dest = SLOT(inplabel);
 1103 
 1104         mls_copy_effective(source, dest);
 1105 }
 1106 
 1107 static void
 1108 mls_inpcb_create_mbuf(struct inpcb *inp, struct label *inplabel,
 1109     struct mbuf *m, struct label *mlabel)
 1110 {
 1111         struct mac_mls *source, *dest;
 1112 
 1113         source = SLOT(inplabel);
 1114         dest = SLOT(mlabel);
 1115 
 1116         mls_copy_effective(source, dest);
 1117 }
 1118 
 1119 static void
 1120 mls_inpcb_sosetlabel(struct socket *so, struct label *solabel,
 1121     struct inpcb *inp, struct label *inplabel)
 1122 {
 1123         struct mac_mls *source, *dest;
 1124 
 1125         SOCK_LOCK_ASSERT(so);
 1126 
 1127         source = SLOT(solabel);
 1128         dest = SLOT(inplabel);
 1129 
 1130         mls_copy(source, dest);
 1131 }
 1132 
 1133 static void
 1134 mls_ip6q_create(struct mbuf *m, struct label *mlabel, struct ip6q *q6,
 1135     struct label *q6label)
 1136 {
 1137         struct mac_mls *source, *dest;
 1138 
 1139         source = SLOT(mlabel);
 1140         dest = SLOT(q6label);
 1141 
 1142         mls_copy_effective(source, dest);
 1143 }
 1144 
 1145 static int
 1146 mls_ip6q_match(struct mbuf *m, struct label *mlabel, struct ip6q *q6,
 1147     struct label *q6label)
 1148 {
 1149         struct mac_mls *a, *b;
 1150 
 1151         a = SLOT(q6label);
 1152         b = SLOT(mlabel);
 1153 
 1154         return (mls_equal_effective(a, b));
 1155 }
 1156 
 1157 static void
 1158 mls_ip6q_reassemble(struct ip6q *q6, struct label *q6label, struct mbuf *m,
 1159     struct label *mlabel)
 1160 {
 1161         struct mac_mls *source, *dest;
 1162 
 1163         source = SLOT(q6label);
 1164         dest = SLOT(mlabel);
 1165 
 1166         /* Just use the head, since we require them all to match. */
 1167         mls_copy_effective(source, dest);
 1168 }
 1169 
 1170 static void
 1171 mls_ip6q_update(struct mbuf *m, struct label *mlabel, struct ip6q *q6,
 1172     struct label *q6label)
 1173 {
 1174 
 1175         /* NOOP: we only accept matching labels, so no need to update */
 1176 }
 1177 
 1178 static void
 1179 mls_ipq_create(struct mbuf *m, struct label *mlabel, struct ipq *q,
 1180     struct label *qlabel)
 1181 {
 1182         struct mac_mls *source, *dest;
 1183 
 1184         source = SLOT(mlabel);
 1185         dest = SLOT(qlabel);
 1186 
 1187         mls_copy_effective(source, dest);
 1188 }
 1189 
 1190 static int
 1191 mls_ipq_match(struct mbuf *m, struct label *mlabel, struct ipq *q,
 1192     struct label *qlabel)
 1193 {
 1194         struct mac_mls *a, *b;
 1195 
 1196         a = SLOT(qlabel);
 1197         b = SLOT(mlabel);
 1198 
 1199         return (mls_equal_effective(a, b));
 1200 }
 1201 
 1202 static void
 1203 mls_ipq_reassemble(struct ipq *q, struct label *qlabel, struct mbuf *m,
 1204     struct label *mlabel)
 1205 {
 1206         struct mac_mls *source, *dest;
 1207 
 1208         source = SLOT(qlabel);
 1209         dest = SLOT(mlabel);
 1210 
 1211         /* Just use the head, since we require them all to match. */
 1212         mls_copy_effective(source, dest);
 1213 }
 1214 
 1215 static void
 1216 mls_ipq_update(struct mbuf *m, struct label *mlabel, struct ipq *q,
 1217     struct label *qlabel)
 1218 {
 1219 
 1220         /* NOOP: we only accept matching labels, so no need to update */
 1221 }
 1222 
 1223 static int
 1224 mls_mount_check_stat(struct ucred *cred, struct mount *mp,
 1225     struct label *mntlabel)
 1226 {
 1227         struct mac_mls *subj, *obj;
 1228 
 1229         if (!mls_enabled)
 1230                 return (0);
 1231 
 1232         subj = SLOT(cred->cr_label);
 1233         obj = SLOT(mntlabel);
 1234 
 1235         if (!mls_dominate_effective(subj, obj))
 1236                 return (EACCES);
 1237 
 1238         return (0);
 1239 }
 1240 
 1241 static void
 1242 mls_mount_create(struct ucred *cred, struct mount *mp, struct label *mplabel)
 1243 {
 1244         struct mac_mls *source, *dest;
 1245 
 1246         source = SLOT(cred->cr_label);
 1247         dest = SLOT(mplabel);
 1248 
 1249         mls_copy_effective(source, dest);
 1250 }
 1251 
 1252 static void
 1253 mls_netatalk_aarp_send(struct ifnet *ifp, struct label *ifplabel,
 1254     struct mbuf *m, struct label *mlabel)
 1255 {
 1256         struct mac_mls *dest;
 1257 
 1258         dest = SLOT(mlabel);
 1259 
 1260         mls_set_effective(dest, MAC_MLS_TYPE_EQUAL, 0, NULL);
 1261 }
 1262 
 1263 static void
 1264 mls_netinet_arp_send(struct ifnet *ifp, struct label *ifplabel,
 1265     struct mbuf *m, struct label *mlabel)
 1266 {
 1267         struct mac_mls *dest;
 1268 
 1269         dest = SLOT(mlabel);
 1270 
 1271         mls_set_effective(dest, MAC_MLS_TYPE_EQUAL, 0, NULL);
 1272 }
 1273 
 1274 static void
 1275 mls_netinet_firewall_reply(struct mbuf *mrecv, struct label *mrecvlabel,
 1276     struct mbuf *msend, struct label *msendlabel)
 1277 {
 1278         struct mac_mls *source, *dest;
 1279 
 1280         source = SLOT(mrecvlabel);
 1281         dest = SLOT(msendlabel);
 1282 
 1283         mls_copy_effective(source, dest);
 1284 }
 1285 
 1286 static void
 1287 mls_netinet_firewall_send(struct mbuf *m, struct label *mlabel)
 1288 {
 1289         struct mac_mls *dest;
 1290 
 1291         dest = SLOT(mlabel);
 1292 
 1293         /* XXX: where is the label for the firewall really comming from? */
 1294         mls_set_effective(dest, MAC_MLS_TYPE_EQUAL, 0, NULL);
 1295 }
 1296 
 1297 static void
 1298 mls_netinet_fragment(struct mbuf *m, struct label *mlabel, struct mbuf *frag,
 1299     struct label *fraglabel)
 1300 {
 1301         struct mac_mls *source, *dest;
 1302 
 1303         source = SLOT(mlabel);
 1304         dest = SLOT(fraglabel);
 1305 
 1306         mls_copy_effective(source, dest);
 1307 }
 1308 
 1309 static void
 1310 mls_netinet_icmp_reply(struct mbuf *mrecv, struct label *mrecvlabel,
 1311     struct mbuf *msend, struct label *msendlabel)
 1312 {
 1313         struct mac_mls *source, *dest;
 1314 
 1315         source = SLOT(mrecvlabel);
 1316         dest = SLOT(msendlabel);
 1317 
 1318         mls_copy_effective(source, dest);
 1319 }
 1320 
 1321 static void
 1322 mls_netinet_igmp_send(struct ifnet *ifp, struct label *ifplabel,
 1323     struct mbuf *m, struct label *mlabel)
 1324 {
 1325         struct mac_mls *dest;
 1326 
 1327         dest = SLOT(mlabel);
 1328 
 1329         mls_set_effective(dest, MAC_MLS_TYPE_EQUAL, 0, NULL);
 1330 }
 1331 
 1332 static void
 1333 mls_netinet6_nd6_send(struct ifnet *ifp, struct label *ifplabel,
 1334     struct mbuf *m, struct label *mlabel)
 1335 {
 1336         struct mac_mls *dest;
 1337 
 1338         dest = SLOT(mlabel);
 1339 
 1340         mls_set_effective(dest, MAC_MLS_TYPE_EQUAL, 0, NULL);
 1341 }
 1342 
 1343 static int
 1344 mls_pipe_check_ioctl(struct ucred *cred, struct pipepair *pp,
 1345     struct label *pplabel, unsigned long cmd, void /* caddr_t */ *data)
 1346 {
 1347 
 1348         if (!mls_enabled)
 1349                 return (0);
 1350 
 1351         /* XXX: This will be implemented soon... */
 1352 
 1353         return (0);
 1354 }
 1355 
 1356 static int
 1357 mls_pipe_check_poll(struct ucred *cred, struct pipepair *pp,
 1358     struct label *pplabel)
 1359 {
 1360         struct mac_mls *subj, *obj;
 1361 
 1362         if (!mls_enabled)
 1363                 return (0);
 1364 
 1365         subj = SLOT(cred->cr_label);
 1366         obj = SLOT(pplabel);
 1367 
 1368         if (!mls_dominate_effective(subj, obj))
 1369                 return (EACCES);
 1370 
 1371         return (0);
 1372 }
 1373 
 1374 static int
 1375 mls_pipe_check_read(struct ucred *cred, struct pipepair *pp,
 1376     struct label *pplabel)
 1377 {
 1378         struct mac_mls *subj, *obj;
 1379 
 1380         if (!mls_enabled)
 1381                 return (0);
 1382 
 1383         subj = SLOT(cred->cr_label);
 1384         obj = SLOT(pplabel);
 1385 
 1386         if (!mls_dominate_effective(subj, obj))
 1387                 return (EACCES);
 1388 
 1389         return (0);
 1390 }
 1391 
 1392 static int
 1393 mls_pipe_check_relabel(struct ucred *cred, struct pipepair *pp,
 1394     struct label *pplabel, struct label *newlabel)
 1395 {
 1396         struct mac_mls *subj, *obj, *new;
 1397         int error;
 1398 
 1399         new = SLOT(newlabel);
 1400         subj = SLOT(cred->cr_label);
 1401         obj = SLOT(pplabel);
 1402 
 1403         /*
 1404          * If there is an MLS label update for a pipe, it must be a effective
 1405          * update.
 1406          */
 1407         error = mls_atmostflags(new, MAC_MLS_FLAG_EFFECTIVE);
 1408         if (error)
 1409                 return (error);
 1410 
 1411         /*
 1412          * To perform a relabel of a pipe (MLS label or not), MLS must
 1413          * authorize the relabel.
 1414          */
 1415         if (!mls_effective_in_range(obj, subj))
 1416                 return (EPERM);
 1417 
 1418         /*
 1419          * If the MLS label is to be changed, authorize as appropriate.
 1420          */
 1421         if (new->mm_flags & MAC_MLS_FLAG_EFFECTIVE) {
 1422                 /*
 1423                  * To change the MLS label on a pipe, the new pipe label must
 1424                  * be in the subject range.
 1425                  */
 1426                 if (!mls_effective_in_range(new, subj))
 1427                         return (EPERM);
 1428 
 1429                 /*
 1430                  * To change the MLS label on a pipe to be EQUAL, the subject
 1431                  * must have appropriate privilege.
 1432                  */
 1433                 if (mls_contains_equal(new)) {
 1434                         error = mls_subject_privileged(subj);
 1435                         if (error)
 1436                                 return (error);
 1437                 }
 1438         }
 1439 
 1440         return (0);
 1441 }
 1442 
 1443 static int
 1444 mls_pipe_check_stat(struct ucred *cred, struct pipepair *pp,
 1445     struct label *pplabel)
 1446 {
 1447         struct mac_mls *subj, *obj;
 1448 
 1449         if (!mls_enabled)
 1450                 return (0);
 1451 
 1452         subj = SLOT(cred->cr_label);
 1453         obj = SLOT(pplabel);
 1454 
 1455         if (!mls_dominate_effective(subj, obj))
 1456                 return (EACCES);
 1457 
 1458         return (0);
 1459 }
 1460 
 1461 static int
 1462 mls_pipe_check_write(struct ucred *cred, struct pipepair *pp,
 1463     struct label *pplabel)
 1464 {
 1465         struct mac_mls *subj, *obj;
 1466 
 1467         if (!mls_enabled)
 1468                 return (0);
 1469 
 1470         subj = SLOT(cred->cr_label);
 1471         obj = SLOT(pplabel);
 1472 
 1473         if (!mls_dominate_effective(obj, subj))
 1474                 return (EACCES);
 1475 
 1476         return (0);
 1477 }
 1478 
 1479 static void
 1480 mls_pipe_create(struct ucred *cred, struct pipepair *pp,
 1481     struct label *pplabel)
 1482 {
 1483         struct mac_mls *source, *dest;
 1484 
 1485         source = SLOT(cred->cr_label);
 1486         dest = SLOT(pplabel);
 1487 
 1488         mls_copy_effective(source, dest);
 1489 }
 1490 
 1491 static void
 1492 mls_pipe_relabel(struct ucred *cred, struct pipepair *pp,
 1493     struct label *pplabel, struct label *newlabel)
 1494 {
 1495         struct mac_mls *source, *dest;
 1496 
 1497         source = SLOT(newlabel);
 1498         dest = SLOT(pplabel);
 1499 
 1500         mls_copy(source, dest);
 1501 }
 1502 
 1503 static int
 1504 mls_posixsem_check_openunlink(struct ucred *cred, struct ksem *ks,
 1505     struct label *kslabel)
 1506 {
 1507         struct mac_mls *subj, *obj;
 1508 
 1509         if (!mls_enabled)
 1510                 return (0);
 1511 
 1512         subj = SLOT(cred->cr_label);
 1513         obj = SLOT(kslabel);
 1514 
 1515         if (!mls_dominate_effective(obj, subj))
 1516                 return (EACCES);
 1517 
 1518         return (0);
 1519 }
 1520 
 1521 static int
 1522 mls_posixsem_check_rdonly(struct ucred *active_cred, struct ucred *file_cred,
 1523     struct ksem *ks, struct label *kslabel)
 1524 {
 1525         struct mac_mls *subj, *obj;
 1526 
 1527         if (!mls_enabled)
 1528                 return (0);
 1529 
 1530         subj = SLOT(active_cred->cr_label);
 1531         obj = SLOT(kslabel);
 1532 
 1533         if (!mls_dominate_effective(subj, obj))
 1534                 return (EACCES);
 1535 
 1536         return (0);
 1537 }
 1538 
 1539 static int
 1540 mls_posixsem_check_setmode(struct ucred *cred, struct ksem *ks,
 1541     struct label *shmlabel, mode_t mode)
 1542 {
 1543         struct mac_mls *subj, *obj;
 1544 
 1545         if (!mls_enabled)
 1546                 return (0);
 1547 
 1548         subj = SLOT(cred->cr_label);
 1549         obj = SLOT(shmlabel);
 1550 
 1551         if (!mls_dominate_effective(obj, subj))
 1552                 return (EACCES);
 1553 
 1554         return (0);
 1555 }
 1556 
 1557 static int
 1558 mls_posixsem_check_setowner(struct ucred *cred, struct ksem *ks,
 1559     struct label *shmlabel, uid_t uid, gid_t gid)
 1560 {
 1561         struct mac_mls *subj, *obj;
 1562 
 1563         if (!mls_enabled)
 1564                 return (0);
 1565 
 1566         subj = SLOT(cred->cr_label);
 1567         obj = SLOT(shmlabel);
 1568 
 1569         if (!mls_dominate_effective(obj, subj))
 1570                 return (EACCES);
 1571 
 1572         return (0);
 1573 }
 1574 
 1575 static int
 1576 mls_posixsem_check_write(struct ucred *active_cred, struct ucred *file_cred,
 1577     struct ksem *ks, struct label *kslabel)
 1578 {
 1579         struct mac_mls *subj, *obj;
 1580 
 1581         if (!mls_enabled)
 1582                 return (0);
 1583 
 1584         subj = SLOT(active_cred->cr_label);
 1585         obj = SLOT(kslabel);
 1586 
 1587         if (!mls_dominate_effective(obj, subj))
 1588                 return (EACCES);
 1589 
 1590         return (0);
 1591 }
 1592 
 1593 static void
 1594 mls_posixsem_create(struct ucred *cred, struct ksem *ks,
 1595     struct label *kslabel)
 1596 {
 1597         struct mac_mls *source, *dest;
 1598 
 1599         source = SLOT(cred->cr_label);
 1600         dest = SLOT(kslabel);
 1601 
 1602         mls_copy_effective(source, dest);
 1603 }
 1604 
 1605 static int
 1606 mls_posixshm_check_mmap(struct ucred *cred, struct shmfd *shmfd,
 1607     struct label *shmlabel, int prot, int flags)
 1608 {
 1609         struct mac_mls *subj, *obj;
 1610 
 1611         if (!mls_enabled)
 1612                 return (0);
 1613 
 1614         subj = SLOT(cred->cr_label);
 1615         obj = SLOT(shmlabel);
 1616 
 1617         if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
 1618                 if (!mls_dominate_effective(subj, obj))
 1619                         return (EACCES);
 1620         }
 1621         if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) {
 1622                 if (!mls_dominate_effective(obj, subj))
 1623                         return (EACCES);
 1624         }
 1625 
 1626         return (0);
 1627 }
 1628 
 1629 static int
 1630 mls_posixshm_check_open(struct ucred *cred, struct shmfd *shmfd,
 1631     struct label *shmlabel, accmode_t accmode)
 1632 {
 1633         struct mac_mls *subj, *obj;
 1634 
 1635         if (!mls_enabled)
 1636                 return (0);
 1637 
 1638         subj = SLOT(cred->cr_label);
 1639         obj = SLOT(shmlabel);
 1640 
 1641         if (accmode & (VREAD | VEXEC | VSTAT_PERMS)) {
 1642                 if (!mls_dominate_effective(subj, obj))
 1643                         return (EACCES);
 1644         }
 1645         if (accmode & VMODIFY_PERMS) {
 1646                 if (!mls_dominate_effective(obj, subj))
 1647                         return (EACCES);
 1648         }
 1649 
 1650         return (0);
 1651 }
 1652 
 1653 static int
 1654 mls_posixshm_check_setmode(struct ucred *cred, struct shmfd *shmfd,
 1655     struct label *shmlabel, mode_t mode)
 1656 {
 1657         struct mac_mls *subj, *obj;
 1658 
 1659         if (!mls_enabled)
 1660                 return (0);
 1661 
 1662         subj = SLOT(cred->cr_label);
 1663         obj = SLOT(shmlabel);
 1664 
 1665         if (!mls_dominate_effective(obj, subj))
 1666                 return (EACCES);
 1667 
 1668         return (0);
 1669 }
 1670 
 1671 static int
 1672 mls_posixshm_check_setowner(struct ucred *cred, struct shmfd *shmfd,
 1673     struct label *shmlabel, uid_t uid, gid_t gid)
 1674 {
 1675         struct mac_mls *subj, *obj;
 1676 
 1677         if (!mls_enabled)
 1678                 return (0);
 1679 
 1680         subj = SLOT(cred->cr_label);
 1681         obj = SLOT(shmlabel);
 1682 
 1683         if (!mls_dominate_effective(obj, subj))
 1684                 return (EACCES);
 1685 
 1686         return (0);
 1687 }
 1688 
 1689 static int
 1690 mls_posixshm_check_stat(struct ucred *active_cred, struct ucred *file_cred,
 1691     struct shmfd *shmfd, struct label *shmlabel)
 1692 {
 1693         struct mac_mls *subj, *obj;
 1694 
 1695         if (!mls_enabled)
 1696                 return (0);
 1697 
 1698         subj = SLOT(active_cred->cr_label);
 1699         obj = SLOT(shmlabel);
 1700 
 1701         if (!mls_dominate_effective(subj, obj))
 1702                 return (EACCES);
 1703 
 1704         return (0);
 1705 }
 1706 
 1707 static int
 1708 mls_posixshm_check_truncate(struct ucred *active_cred,
 1709     struct ucred *file_cred, struct shmfd *shmfd, struct label *shmlabel)
 1710 {
 1711         struct mac_mls *subj, *obj;
 1712 
 1713         if (!mls_enabled)
 1714                 return (0);
 1715 
 1716         subj = SLOT(active_cred->cr_label);
 1717         obj = SLOT(shmlabel);
 1718 
 1719         if (!mls_dominate_effective(obj, subj))
 1720                 return (EACCES);
 1721 
 1722         return (0);
 1723 }
 1724 
 1725 static int
 1726 mls_posixshm_check_unlink(struct ucred *cred, struct shmfd *shmfd,
 1727     struct label *shmlabel)
 1728 {
 1729         struct mac_mls *subj, *obj;
 1730 
 1731         if (!mls_enabled)
 1732                 return (0);
 1733 
 1734         subj = SLOT(cred->cr_label);
 1735         obj = SLOT(shmlabel);
 1736 
 1737         if (!mls_dominate_effective(obj, subj))
 1738                 return (EACCES);
 1739     
 1740         return (0);
 1741 }
 1742 
 1743 static void
 1744 mls_posixshm_create(struct ucred *cred, struct shmfd *shmfd,
 1745     struct label *shmlabel)
 1746 {
 1747         struct mac_mls *source, *dest;
 1748 
 1749         source = SLOT(cred->cr_label);
 1750         dest = SLOT(shmlabel);
 1751 
 1752         mls_copy_effective(source, dest);
 1753 }
 1754 
 1755 static int
 1756 mls_proc_check_debug(struct ucred *cred, struct proc *p)
 1757 {
 1758         struct mac_mls *subj, *obj;
 1759 
 1760         if (!mls_enabled)
 1761                 return (0);
 1762 
 1763         subj = SLOT(cred->cr_label);
 1764         obj = SLOT(p->p_ucred->cr_label);
 1765 
 1766         /* XXX: range checks */
 1767         if (!mls_dominate_effective(subj, obj))
 1768                 return (ESRCH);
 1769         if (!mls_dominate_effective(obj, subj))
 1770                 return (EACCES);
 1771 
 1772         return (0);
 1773 }
 1774 
 1775 static int
 1776 mls_proc_check_sched(struct ucred *cred, struct proc *p)
 1777 {
 1778         struct mac_mls *subj, *obj;
 1779 
 1780         if (!mls_enabled)
 1781                 return (0);
 1782 
 1783         subj = SLOT(cred->cr_label);
 1784         obj = SLOT(p->p_ucred->cr_label);
 1785 
 1786         /* XXX: range checks */
 1787         if (!mls_dominate_effective(subj, obj))
 1788                 return (ESRCH);
 1789         if (!mls_dominate_effective(obj, subj))
 1790                 return (EACCES);
 1791 
 1792         return (0);
 1793 }
 1794 
 1795 static int
 1796 mls_proc_check_signal(struct ucred *cred, struct proc *p, int signum)
 1797 {
 1798         struct mac_mls *subj, *obj;
 1799 
 1800         if (!mls_enabled)
 1801                 return (0);
 1802 
 1803         subj = SLOT(cred->cr_label);
 1804         obj = SLOT(p->p_ucred->cr_label);
 1805 
 1806         /* XXX: range checks */
 1807         if (!mls_dominate_effective(subj, obj))
 1808                 return (ESRCH);
 1809         if (!mls_dominate_effective(obj, subj))
 1810                 return (EACCES);
 1811 
 1812         return (0);
 1813 }
 1814 
 1815 static int
 1816 mls_socket_check_deliver(struct socket *so, struct label *solabel,
 1817     struct mbuf *m, struct label *mlabel)
 1818 {
 1819         struct mac_mls *p, *s;
 1820         int error;
 1821 
 1822         if (!mls_enabled)
 1823                 return (0);
 1824 
 1825         p = SLOT(mlabel);
 1826         s = SLOT(solabel);
 1827 
 1828         SOCK_LOCK(so);
 1829         error = mls_equal_effective(p, s) ? 0 : EACCES;
 1830         SOCK_UNLOCK(so);
 1831 
 1832         return (error);
 1833 }
 1834 
 1835 static int
 1836 mls_socket_check_relabel(struct ucred *cred, struct socket *so,
 1837     struct label *solabel, struct label *newlabel)
 1838 {
 1839         struct mac_mls *subj, *obj, *new;
 1840         int error;
 1841 
 1842         SOCK_LOCK_ASSERT(so);
 1843 
 1844         new = SLOT(newlabel);
 1845         subj = SLOT(cred->cr_label);
 1846         obj = SLOT(solabel);
 1847 
 1848         /*
 1849          * If there is an MLS label update for the socket, it may be an
 1850          * update of effective.
 1851          */
 1852         error = mls_atmostflags(new, MAC_MLS_FLAG_EFFECTIVE);
 1853         if (error)
 1854                 return (error);
 1855 
 1856         /*
 1857          * To relabel a socket, the old socket effective must be in the
 1858          * subject range.
 1859          */
 1860         if (!mls_effective_in_range(obj, subj))
 1861                 return (EPERM);
 1862 
 1863         /*
 1864          * If the MLS label is to be changed, authorize as appropriate.
 1865          */
 1866         if (new->mm_flags & MAC_MLS_FLAG_EFFECTIVE) {
 1867                 /*
 1868                  * To relabel a socket, the new socket effective must be in
 1869                  * the subject range.
 1870                  */
 1871                 if (!mls_effective_in_range(new, subj))
 1872                         return (EPERM);
 1873 
 1874                 /*
 1875                  * To change the MLS label on the socket to contain EQUAL,
 1876                  * the subject must have appropriate privilege.
 1877                  */
 1878                 if (mls_contains_equal(new)) {
 1879                         error = mls_subject_privileged(subj);
 1880                         if (error)
 1881                                 return (error);
 1882                 }
 1883         }
 1884 
 1885         return (0);
 1886 }
 1887 
 1888 static int
 1889 mls_socket_check_visible(struct ucred *cred, struct socket *so,
 1890     struct label *solabel)
 1891 {
 1892         struct mac_mls *subj, *obj;
 1893 
 1894         if (!mls_enabled)
 1895                 return (0);
 1896 
 1897         subj = SLOT(cred->cr_label);
 1898         obj = SLOT(solabel);
 1899 
 1900         SOCK_LOCK(so);
 1901         if (!mls_dominate_effective(subj, obj)) {
 1902                 SOCK_UNLOCK(so);
 1903                 return (ENOENT);
 1904         }
 1905         SOCK_UNLOCK(so);
 1906 
 1907         return (0);
 1908 }
 1909 
 1910 static void
 1911 mls_socket_create(struct ucred *cred, struct socket *so,
 1912     struct label *solabel)
 1913 {
 1914         struct mac_mls *source, *dest;
 1915 
 1916         source = SLOT(cred->cr_label);
 1917         dest = SLOT(solabel);
 1918 
 1919         mls_copy_effective(source, dest);
 1920 }
 1921 
 1922 static void
 1923 mls_socket_create_mbuf(struct socket *so, struct label *solabel,
 1924     struct mbuf *m, struct label *mlabel)
 1925 {
 1926         struct mac_mls *source, *dest;
 1927 
 1928         source = SLOT(solabel);
 1929         dest = SLOT(mlabel);
 1930 
 1931         SOCK_LOCK(so);
 1932         mls_copy_effective(source, dest);
 1933         SOCK_UNLOCK(so);
 1934 }
 1935 
 1936 static void
 1937 mls_socket_newconn(struct socket *oldso, struct label *oldsolabel,
 1938     struct socket *newso, struct label *newsolabel)
 1939 {
 1940         struct mac_mls source, *dest;
 1941 
 1942         SOCK_LOCK(oldso);
 1943         source = *SLOT(oldsolabel);
 1944         SOCK_UNLOCK(oldso);
 1945 
 1946         dest = SLOT(newsolabel);
 1947 
 1948         SOCK_LOCK(newso);
 1949         mls_copy_effective(&source, dest);
 1950         SOCK_UNLOCK(newso);
 1951 }
 1952 
 1953 static void
 1954 mls_socket_relabel(struct ucred *cred, struct socket *so,
 1955     struct label *solabel, struct label *newlabel)
 1956 {
 1957         struct mac_mls *source, *dest;
 1958 
 1959         SOCK_LOCK_ASSERT(so);
 1960 
 1961         source = SLOT(newlabel);
 1962         dest = SLOT(solabel);
 1963 
 1964         mls_copy(source, dest);
 1965 }
 1966 
 1967 static void
 1968 mls_socketpeer_set_from_mbuf(struct mbuf *m, struct label *mlabel,
 1969     struct socket *so, struct label *sopeerlabel)
 1970 {
 1971         struct mac_mls *source, *dest;
 1972 
 1973         source = SLOT(mlabel);
 1974         dest = SLOT(sopeerlabel);
 1975 
 1976         SOCK_LOCK(so);
 1977         mls_copy_effective(source, dest);
 1978         SOCK_UNLOCK(so);
 1979 }
 1980 
 1981 static void
 1982 mls_socketpeer_set_from_socket(struct socket *oldso,
 1983     struct label *oldsolabel, struct socket *newso,
 1984     struct label *newsopeerlabel)
 1985 {
 1986         struct mac_mls source, *dest;
 1987 
 1988         SOCK_LOCK(oldso);
 1989         source = *SLOT(oldsolabel);
 1990         SOCK_UNLOCK(oldso);
 1991 
 1992         dest = SLOT(newsopeerlabel);
 1993 
 1994         SOCK_LOCK(newso);
 1995         mls_copy_effective(&source, dest);
 1996         SOCK_UNLOCK(newso);
 1997 }
 1998 
 1999 static void
 2000 mls_syncache_create(struct label *label, struct inpcb *inp)
 2001 {
 2002         struct mac_mls *source, *dest;
 2003 
 2004         source = SLOT(inp->inp_label);
 2005         dest = SLOT(label);
 2006 
 2007         mls_copy_effective(source, dest);
 2008 }
 2009 
 2010 static void
 2011 mls_syncache_create_mbuf(struct label *sc_label, struct mbuf *m,
 2012     struct label *mlabel)
 2013 {
 2014         struct mac_mls *source, *dest;
 2015 
 2016         source = SLOT(sc_label);
 2017         dest = SLOT(mlabel);
 2018 
 2019         mls_copy_effective(source, dest);
 2020 }
 2021 
 2022 static int
 2023 mls_system_check_acct(struct ucred *cred, struct vnode *vp,
 2024     struct label *vplabel)
 2025 {
 2026         struct mac_mls *subj, *obj;
 2027 
 2028         if (!mls_enabled)
 2029                 return (0);
 2030 
 2031         if (vplabel == NULL)
 2032                 return (0);
 2033 
 2034         subj = SLOT(cred->cr_label);
 2035         obj = SLOT(vplabel);
 2036 
 2037         if (!mls_dominate_effective(obj, subj) ||
 2038             !mls_dominate_effective(subj, obj))
 2039                 return (EACCES);
 2040 
 2041         return (0);
 2042 }
 2043 
 2044 static int
 2045 mls_system_check_auditctl(struct ucred *cred, struct vnode *vp,
 2046     struct label *vplabel)
 2047 {
 2048         struct mac_mls *subj, *obj;
 2049 
 2050         if (!mls_enabled)
 2051                 return (0);
 2052 
 2053         subj = SLOT(cred->cr_label);
 2054         obj = SLOT(vplabel);
 2055 
 2056         if (!mls_dominate_effective(obj, subj) ||
 2057             !mls_dominate_effective(subj, obj))
 2058                 return (EACCES);
 2059 
 2060         return (0);
 2061 }
 2062 
 2063 static int
 2064 mls_system_check_swapon(struct ucred *cred, struct vnode *vp,
 2065     struct label *vplabel)
 2066 {
 2067         struct mac_mls *subj, *obj;
 2068 
 2069         if (!mls_enabled)
 2070                 return (0);
 2071 
 2072         subj = SLOT(cred->cr_label);
 2073         obj = SLOT(vplabel);
 2074 
 2075         if (!mls_dominate_effective(obj, subj) ||
 2076             !mls_dominate_effective(subj, obj))
 2077                 return (EACCES);
 2078 
 2079         return (0);
 2080 }
 2081 
 2082 static void
 2083 mls_sysvmsg_cleanup(struct label *msglabel)
 2084 {
 2085 
 2086         bzero(SLOT(msglabel), sizeof(struct mac_mls));
 2087 }
 2088 
 2089 static void
 2090 mls_sysvmsg_create(struct ucred *cred, struct msqid_kernel *msqkptr,
 2091     struct label *msqlabel, struct msg *msgptr, struct label *msglabel)
 2092 {
 2093         struct mac_mls *source, *dest;
 2094 
 2095         /* Ignore the msgq label. */
 2096         source = SLOT(cred->cr_label);
 2097         dest = SLOT(msglabel);
 2098 
 2099         mls_copy_effective(source, dest);
 2100 }
 2101 
 2102 static int
 2103 mls_sysvmsq_check_msgrcv(struct ucred *cred, struct msg *msgptr,
 2104     struct label *msglabel)
 2105 {
 2106         struct mac_mls *subj, *obj;
 2107 
 2108         if (!mls_enabled)
 2109                 return (0);
 2110 
 2111         subj = SLOT(cred->cr_label);
 2112         obj = SLOT(msglabel);
 2113 
 2114         if (!mls_dominate_effective(subj, obj))
 2115                 return (EACCES);
 2116 
 2117         return (0);
 2118 }
 2119 
 2120 static int
 2121 mls_sysvmsq_check_msgrmid(struct ucred *cred, struct msg *msgptr,
 2122     struct label *msglabel)
 2123 {
 2124         struct mac_mls *subj, *obj;
 2125 
 2126         if (!mls_enabled)
 2127                 return (0);
 2128 
 2129         subj = SLOT(cred->cr_label);
 2130         obj = SLOT(msglabel);
 2131 
 2132         if (!mls_dominate_effective(obj, subj))
 2133                 return (EACCES);
 2134 
 2135         return (0);
 2136 }
 2137 
 2138 static int
 2139 mls_sysvmsq_check_msqget(struct ucred *cred, struct msqid_kernel *msqkptr,
 2140     struct label *msqklabel)
 2141 {
 2142         struct mac_mls *subj, *obj;
 2143 
 2144         if (!mls_enabled)
 2145                 return (0);
 2146 
 2147         subj = SLOT(cred->cr_label);
 2148         obj = SLOT(msqklabel);
 2149 
 2150         if (!mls_dominate_effective(subj, obj))
 2151                 return (EACCES);
 2152 
 2153         return (0);
 2154 }
 2155 
 2156 static int
 2157 mls_sysvmsq_check_msqsnd(struct ucred *cred, struct msqid_kernel *msqkptr,
 2158     struct label *msqklabel)
 2159 {
 2160         struct mac_mls *subj, *obj;
 2161 
 2162         if (!mls_enabled)
 2163                 return (0);
 2164 
 2165         subj = SLOT(cred->cr_label);
 2166         obj = SLOT(msqklabel);
 2167 
 2168         if (!mls_dominate_effective(obj, subj))
 2169                 return (EACCES);
 2170 
 2171         return (0);
 2172 }
 2173 
 2174 static int
 2175 mls_sysvmsq_check_msqrcv(struct ucred *cred, struct msqid_kernel *msqkptr,
 2176     struct label *msqklabel)
 2177 {
 2178         struct mac_mls *subj, *obj;
 2179 
 2180         if (!mls_enabled)
 2181                 return (0);
 2182 
 2183         subj = SLOT(cred->cr_label);
 2184         obj = SLOT(msqklabel);
 2185 
 2186         if (!mls_dominate_effective(subj, obj))
 2187                 return (EACCES);
 2188 
 2189         return (0);
 2190 }
 2191 
 2192 static int
 2193 mls_sysvmsq_check_msqctl(struct ucred *cred, struct msqid_kernel *msqkptr,
 2194     struct label *msqklabel, int cmd)
 2195 {
 2196         struct mac_mls *subj, *obj;
 2197 
 2198         if (!mls_enabled)
 2199                 return (0);
 2200 
 2201         subj = SLOT(cred->cr_label);
 2202         obj = SLOT(msqklabel);
 2203 
 2204         switch(cmd) {
 2205         case IPC_RMID:
 2206         case IPC_SET:
 2207                 if (!mls_dominate_effective(obj, subj))
 2208                         return (EACCES);
 2209                 break;
 2210 
 2211         case IPC_STAT:
 2212                 if (!mls_dominate_effective(subj, obj))
 2213                         return (EACCES);
 2214                 break;
 2215 
 2216         default:
 2217                 return (EACCES);
 2218         }
 2219 
 2220         return (0);
 2221 }
 2222 
 2223 static void
 2224 mls_sysvmsq_cleanup(struct label *msqlabel)
 2225 {
 2226 
 2227         bzero(SLOT(msqlabel), sizeof(struct mac_mls));
 2228 }
 2229 
 2230 static void
 2231 mls_sysvmsq_create(struct ucred *cred, struct msqid_kernel *msqkptr,
 2232     struct label *msqlabel)
 2233 {
 2234         struct mac_mls *source, *dest;
 2235 
 2236         source = SLOT(cred->cr_label);
 2237         dest = SLOT(msqlabel);
 2238 
 2239         mls_copy_effective(source, dest);
 2240 }
 2241 
 2242 static int
 2243 mls_sysvsem_check_semctl(struct ucred *cred, struct semid_kernel *semakptr,
 2244     struct label *semaklabel, int cmd)
 2245 {
 2246         struct mac_mls *subj, *obj;
 2247 
 2248         if (!mls_enabled)
 2249                 return (0);
 2250 
 2251         subj = SLOT(cred->cr_label);
 2252         obj = SLOT(semaklabel);
 2253 
 2254         switch(cmd) {
 2255         case IPC_RMID:
 2256         case IPC_SET:
 2257         case SETVAL:
 2258         case SETALL:
 2259                 if (!mls_dominate_effective(obj, subj))
 2260                         return (EACCES);
 2261                 break;
 2262 
 2263         case IPC_STAT:
 2264         case GETVAL:
 2265         case GETPID:
 2266         case GETNCNT:
 2267         case GETZCNT:
 2268         case GETALL:
 2269                 if (!mls_dominate_effective(subj, obj))
 2270                         return (EACCES);
 2271                 break;
 2272 
 2273         default:
 2274                 return (EACCES);
 2275         }
 2276 
 2277         return (0);
 2278 }
 2279 
 2280 static int
 2281 mls_sysvsem_check_semget(struct ucred *cred, struct semid_kernel *semakptr,
 2282     struct label *semaklabel)
 2283 {
 2284         struct mac_mls *subj, *obj;
 2285 
 2286         if (!mls_enabled)
 2287                 return (0);
 2288 
 2289         subj = SLOT(cred->cr_label);
 2290         obj = SLOT(semaklabel);
 2291 
 2292         if (!mls_dominate_effective(subj, obj))
 2293                 return (EACCES);
 2294 
 2295         return (0);
 2296 }
 2297 
 2298 static int
 2299 mls_sysvsem_check_semop(struct ucred *cred, struct semid_kernel *semakptr,
 2300     struct label *semaklabel, size_t accesstype)
 2301 {
 2302         struct mac_mls *subj, *obj;
 2303 
 2304         if (!mls_enabled)
 2305                 return (0);
 2306 
 2307         subj = SLOT(cred->cr_label);
 2308         obj = SLOT(semaklabel);
 2309 
 2310         if( accesstype & SEM_R )
 2311                 if (!mls_dominate_effective(subj, obj))
 2312                         return (EACCES);
 2313 
 2314         if( accesstype & SEM_A )
 2315                 if (!mls_dominate_effective(obj, subj))
 2316                         return (EACCES);
 2317 
 2318         return (0);
 2319 }
 2320 
 2321 static void
 2322 mls_sysvsem_cleanup(struct label *semalabel)
 2323 {
 2324 
 2325         bzero(SLOT(semalabel), sizeof(struct mac_mls));
 2326 }
 2327 
 2328 static void
 2329 mls_sysvsem_create(struct ucred *cred, struct semid_kernel *semakptr,
 2330     struct label *semalabel)
 2331 {
 2332         struct mac_mls *source, *dest;
 2333 
 2334         source = SLOT(cred->cr_label);
 2335         dest = SLOT(semalabel);
 2336 
 2337         mls_copy_effective(source, dest);
 2338 }
 2339 
 2340 static int
 2341 mls_sysvshm_check_shmat(struct ucred *cred, struct shmid_kernel *shmsegptr,
 2342     struct label *shmseglabel, int shmflg)
 2343 {
 2344         struct mac_mls *subj, *obj;
 2345 
 2346         if (!mls_enabled)
 2347                 return (0);
 2348 
 2349         subj = SLOT(cred->cr_label);
 2350         obj = SLOT(shmseglabel);
 2351 
 2352         if (!mls_dominate_effective(subj, obj))
 2353                 return (EACCES);
 2354         if ((shmflg & SHM_RDONLY) == 0) {
 2355                 if (!mls_dominate_effective(obj, subj))
 2356                         return (EACCES);
 2357         }
 2358         
 2359         return (0);
 2360 }
 2361 
 2362 static int
 2363 mls_sysvshm_check_shmctl(struct ucred *cred, struct shmid_kernel *shmsegptr,
 2364     struct label *shmseglabel, int cmd)
 2365 {
 2366         struct mac_mls *subj, *obj;
 2367 
 2368         if (!mls_enabled)
 2369                 return (0);
 2370 
 2371         subj = SLOT(cred->cr_label);
 2372         obj = SLOT(shmseglabel);
 2373 
 2374         switch(cmd) {
 2375         case IPC_RMID:
 2376         case IPC_SET:
 2377                 if (!mls_dominate_effective(obj, subj))
 2378                         return (EACCES);
 2379                 break;
 2380 
 2381         case IPC_STAT:
 2382         case SHM_STAT:
 2383                 if (!mls_dominate_effective(subj, obj))
 2384                         return (EACCES);
 2385                 break;
 2386 
 2387         default:
 2388                 return (EACCES);
 2389         }
 2390 
 2391         return (0);
 2392 }
 2393 
 2394 static int
 2395 mls_sysvshm_check_shmget(struct ucred *cred, struct shmid_kernel *shmsegptr,
 2396     struct label *shmseglabel, int shmflg)
 2397 {
 2398         struct mac_mls *subj, *obj;
 2399 
 2400         if (!mls_enabled)
 2401                 return (0);
 2402 
 2403         subj = SLOT(cred->cr_label);
 2404         obj = SLOT(shmseglabel);
 2405 
 2406         if (!mls_dominate_effective(obj, subj))
 2407                 return (EACCES);
 2408 
 2409         return (0);
 2410 }
 2411 
 2412 static void
 2413 mls_sysvshm_cleanup(struct label *shmlabel)
 2414 {
 2415 
 2416         bzero(SLOT(shmlabel), sizeof(struct mac_mls));
 2417 }
 2418 
 2419 static void
 2420 mls_sysvshm_create(struct ucred *cred, struct shmid_kernel *shmsegptr,
 2421     struct label *shmlabel)
 2422 {
 2423         struct mac_mls *source, *dest;
 2424 
 2425         source = SLOT(cred->cr_label);
 2426         dest = SLOT(shmlabel);
 2427 
 2428         mls_copy_effective(source, dest);
 2429 }
 2430 
 2431 static int
 2432 mls_vnode_associate_extattr(struct mount *mp, struct label *mplabel,
 2433     struct vnode *vp, struct label *vplabel)
 2434 {
 2435         struct mac_mls mm_temp, *source, *dest;
 2436         int buflen, error;
 2437 
 2438         source = SLOT(mplabel);
 2439         dest = SLOT(vplabel);
 2440 
 2441         buflen = sizeof(mm_temp);
 2442         bzero(&mm_temp, buflen);
 2443 
 2444         error = vn_extattr_get(vp, IO_NODELOCKED, MAC_MLS_EXTATTR_NAMESPACE,
 2445             MAC_MLS_EXTATTR_NAME, &buflen, (char *) &mm_temp, curthread);
 2446         if (error == ENOATTR || error == EOPNOTSUPP) {
 2447                 /* Fall back to the mntlabel. */
 2448                 mls_copy_effective(source, dest);
 2449                 return (0);
 2450         } else if (error)
 2451                 return (error);
 2452 
 2453         if (buflen != sizeof(mm_temp)) {
 2454                 printf("mls_vnode_associate_extattr: bad size %d\n", buflen);
 2455                 return (EPERM);
 2456         }
 2457         if (mls_valid(&mm_temp) != 0) {
 2458                 printf("mls_vnode_associate_extattr: invalid\n");
 2459                 return (EPERM);
 2460         }
 2461         if ((mm_temp.mm_flags & MAC_MLS_FLAGS_BOTH) !=
 2462             MAC_MLS_FLAG_EFFECTIVE) {
 2463                 printf("mls_associated_vnode_extattr: not effective\n");
 2464                 return (EPERM);
 2465         }
 2466 
 2467         mls_copy_effective(&mm_temp, dest);
 2468         return (0);
 2469 }
 2470 
 2471 static void
 2472 mls_vnode_associate_singlelabel(struct mount *mp, struct label *mplabel,
 2473     struct vnode *vp, struct label *vplabel)
 2474 {
 2475         struct mac_mls *source, *dest;
 2476 
 2477         source = SLOT(mplabel);
 2478         dest = SLOT(vplabel);
 2479 
 2480         mls_copy_effective(source, dest);
 2481 }
 2482 
 2483 static int
 2484 mls_vnode_check_chdir(struct ucred *cred, struct vnode *dvp,
 2485     struct label *dvplabel)
 2486 {
 2487         struct mac_mls *subj, *obj;
 2488 
 2489         if (!mls_enabled)
 2490                 return (0);
 2491 
 2492         subj = SLOT(cred->cr_label);
 2493         obj = SLOT(dvplabel);
 2494 
 2495         if (!mls_dominate_effective(subj, obj))
 2496                 return (EACCES);
 2497 
 2498         return (0);
 2499 }
 2500 
 2501 static int
 2502 mls_vnode_check_chroot(struct ucred *cred, struct vnode *dvp,
 2503     struct label *dvplabel)
 2504 {
 2505         struct mac_mls *subj, *obj;
 2506 
 2507         if (!mls_enabled)
 2508                 return (0);
 2509 
 2510         subj = SLOT(cred->cr_label);
 2511         obj = SLOT(dvplabel);
 2512 
 2513         if (!mls_dominate_effective(subj, obj))
 2514                 return (EACCES);
 2515 
 2516         return (0);
 2517 }
 2518 
 2519 static int
 2520 mls_vnode_check_create(struct ucred *cred, struct vnode *dvp,
 2521     struct label *dvplabel, struct componentname *cnp, struct vattr *vap)
 2522 {
 2523         struct mac_mls *subj, *obj;
 2524 
 2525         if (!mls_enabled)
 2526                 return (0);
 2527 
 2528         subj = SLOT(cred->cr_label);
 2529         obj = SLOT(dvplabel);
 2530 
 2531         if (!mls_dominate_effective(obj, subj))
 2532                 return (EACCES);
 2533 
 2534         return (0);
 2535 }
 2536 
 2537 static int
 2538 mls_vnode_check_deleteacl(struct ucred *cred, struct vnode *vp,
 2539     struct label *vplabel, acl_type_t type)
 2540 {
 2541         struct mac_mls *subj, *obj;
 2542 
 2543         if (!mls_enabled)
 2544                 return (0);
 2545 
 2546         subj = SLOT(cred->cr_label);
 2547         obj = SLOT(vplabel);
 2548 
 2549         if (!mls_dominate_effective(obj, subj))
 2550                 return (EACCES);
 2551 
 2552         return (0);
 2553 }
 2554 
 2555 static int
 2556 mls_vnode_check_deleteextattr(struct ucred *cred, struct vnode *vp,
 2557     struct label *vplabel, int attrnamespace, const char *name)
 2558 {
 2559         struct mac_mls *subj, *obj;
 2560 
 2561         if (!mls_enabled)
 2562                 return (0);
 2563 
 2564         subj = SLOT(cred->cr_label);
 2565         obj = SLOT(vplabel);
 2566 
 2567         if (!mls_dominate_effective(obj, subj))
 2568                 return (EACCES);
 2569 
 2570         return (0);
 2571 }
 2572 
 2573 static int
 2574 mls_vnode_check_exec(struct ucred *cred, struct vnode *vp,
 2575     struct label *vplabel, struct image_params *imgp,
 2576     struct label *execlabel)
 2577 {
 2578         struct mac_mls *subj, *obj, *exec;
 2579         int error;
 2580 
 2581         if (execlabel != NULL) {
 2582                 /*
 2583                  * We currently don't permit labels to be changed at
 2584                  * exec-time as part of MLS, so disallow non-NULL MLS label
 2585                  * elements in the execlabel.
 2586                  */
 2587                 exec = SLOT(execlabel);
 2588                 error = mls_atmostflags(exec, 0);
 2589                 if (error)
 2590                         return (error);
 2591         }
 2592 
 2593         if (!mls_enabled)
 2594                 return (0);
 2595 
 2596         subj = SLOT(cred->cr_label);
 2597         obj = SLOT(vplabel);
 2598 
 2599         if (!mls_dominate_effective(subj, obj))
 2600                 return (EACCES);
 2601 
 2602         return (0);
 2603 }
 2604 
 2605 static int
 2606 mls_vnode_check_getacl(struct ucred *cred, struct vnode *vp,
 2607     struct label *vplabel, acl_type_t type)
 2608 {
 2609         struct mac_mls *subj, *obj;
 2610 
 2611         if (!mls_enabled)
 2612                 return (0);
 2613 
 2614         subj = SLOT(cred->cr_label);
 2615         obj = SLOT(vplabel);
 2616 
 2617         if (!mls_dominate_effective(subj, obj))
 2618                 return (EACCES);
 2619 
 2620         return (0);
 2621 }
 2622 
 2623 static int
 2624 mls_vnode_check_getextattr(struct ucred *cred, struct vnode *vp,
 2625     struct label *vplabel, int attrnamespace, const char *name)
 2626 {
 2627         struct mac_mls *subj, *obj;
 2628 
 2629         if (!mls_enabled)
 2630                 return (0);
 2631 
 2632         subj = SLOT(cred->cr_label);
 2633         obj = SLOT(vplabel);
 2634 
 2635         if (!mls_dominate_effective(subj, obj))
 2636                 return (EACCES);
 2637 
 2638         return (0);
 2639 }
 2640 
 2641 static int
 2642 mls_vnode_check_link(struct ucred *cred, struct vnode *dvp,
 2643     struct label *dvplabel, struct vnode *vp, struct label *vplabel,
 2644     struct componentname *cnp)
 2645 {
 2646         struct mac_mls *subj, *obj;
 2647 
 2648         if (!mls_enabled)
 2649                 return (0);
 2650 
 2651         subj = SLOT(cred->cr_label);
 2652         obj = SLOT(dvplabel);
 2653 
 2654         if (!mls_dominate_effective(obj, subj))
 2655                 return (EACCES);
 2656 
 2657         obj = SLOT(vplabel);
 2658         if (!mls_dominate_effective(obj, subj))
 2659                 return (EACCES);
 2660 
 2661         return (0);
 2662 }
 2663 
 2664 static int
 2665 mls_vnode_check_listextattr(struct ucred *cred, struct vnode *vp,
 2666     struct label *vplabel, int attrnamespace)
 2667 {
 2668 
 2669         struct mac_mls *subj, *obj;
 2670 
 2671         if (!mls_enabled)
 2672                 return (0);
 2673 
 2674         subj = SLOT(cred->cr_label);
 2675         obj = SLOT(vplabel);
 2676 
 2677         if (!mls_dominate_effective(subj, obj))
 2678                 return (EACCES);
 2679 
 2680         return (0);
 2681 }
 2682 
 2683 static int
 2684 mls_vnode_check_lookup(struct ucred *cred, struct vnode *dvp,
 2685     struct label *dvplabel, struct componentname *cnp)
 2686 {
 2687         struct mac_mls *subj, *obj;
 2688 
 2689         if (!mls_enabled)
 2690                 return (0);
 2691 
 2692         subj = SLOT(cred->cr_label);
 2693         obj = SLOT(dvplabel);
 2694 
 2695         if (!mls_dominate_effective(subj, obj))
 2696                 return (EACCES);
 2697 
 2698         return (0);
 2699 }
 2700 
 2701 static int
 2702 mls_vnode_check_mmap(struct ucred *cred, struct vnode *vp,
 2703     struct label *vplabel, int prot, int flags)
 2704 {
 2705         struct mac_mls *subj, *obj;
 2706 
 2707         /*
 2708          * Rely on the use of open()-time protections to handle
 2709          * non-revocation cases.
 2710          */
 2711         if (!mls_enabled || !revocation_enabled)
 2712                 return (0);
 2713 
 2714         subj = SLOT(cred->cr_label);
 2715         obj = SLOT(vplabel);
 2716 
 2717         if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
 2718                 if (!mls_dominate_effective(subj, obj))
 2719                         return (EACCES);
 2720         }
 2721         if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) {
 2722                 if (!mls_dominate_effective(obj, subj))
 2723                         return (EACCES);
 2724         }
 2725 
 2726         return (0);
 2727 }
 2728 
 2729 static int
 2730 mls_vnode_check_open(struct ucred *cred, struct vnode *vp,
 2731     struct label *vplabel, accmode_t accmode)
 2732 {
 2733         struct mac_mls *subj, *obj;
 2734 
 2735         if (!mls_enabled)
 2736                 return (0);
 2737 
 2738         subj = SLOT(cred->cr_label);
 2739         obj = SLOT(vplabel);
 2740 
 2741         /* XXX privilege override for admin? */
 2742         if (accmode & (VREAD | VEXEC | VSTAT_PERMS)) {
 2743                 if (!mls_dominate_effective(subj, obj))
 2744                         return (EACCES);
 2745         }
 2746         if (accmode & VMODIFY_PERMS) {
 2747                 if (!mls_dominate_effective(obj, subj))
 2748                         return (EACCES);
 2749         }
 2750 
 2751         return (0);
 2752 }
 2753 
 2754 static int
 2755 mls_vnode_check_poll(struct ucred *active_cred, struct ucred *file_cred,
 2756     struct vnode *vp, struct label *vplabel)
 2757 {
 2758         struct mac_mls *subj, *obj;
 2759 
 2760         if (!mls_enabled || !revocation_enabled)
 2761                 return (0);
 2762 
 2763         subj = SLOT(active_cred->cr_label);
 2764         obj = SLOT(vplabel);
 2765 
 2766         if (!mls_dominate_effective(subj, obj))
 2767                 return (EACCES);
 2768 
 2769         return (0);
 2770 }
 2771 
 2772 static int
 2773 mls_vnode_check_read(struct ucred *active_cred, struct ucred *file_cred,
 2774     struct vnode *vp, struct label *vplabel)
 2775 {
 2776         struct mac_mls *subj, *obj;
 2777 
 2778         if (!mls_enabled || !revocation_enabled)
 2779                 return (0);
 2780 
 2781         subj = SLOT(active_cred->cr_label);
 2782         obj = SLOT(vplabel);
 2783 
 2784         if (!mls_dominate_effective(subj, obj))
 2785                 return (EACCES);
 2786 
 2787         return (0);
 2788 }
 2789 
 2790 static int
 2791 mls_vnode_check_readdir(struct ucred *cred, struct vnode *dvp,
 2792     struct label *dvplabel)
 2793 {
 2794         struct mac_mls *subj, *obj;
 2795 
 2796         if (!mls_enabled)
 2797                 return (0);
 2798 
 2799         subj = SLOT(cred->cr_label);
 2800         obj = SLOT(dvplabel);
 2801 
 2802         if (!mls_dominate_effective(subj, obj))
 2803                 return (EACCES);
 2804 
 2805         return (0);
 2806 }
 2807 
 2808 static int
 2809 mls_vnode_check_readlink(struct ucred *cred, struct vnode *vp,
 2810     struct label *vplabel)
 2811 {
 2812         struct mac_mls *subj, *obj;
 2813 
 2814         if (!mls_enabled)
 2815                 return (0);
 2816 
 2817         subj = SLOT(cred->cr_label);
 2818         obj = SLOT(vplabel);
 2819 
 2820         if (!mls_dominate_effective(subj, obj))
 2821                 return (EACCES);
 2822 
 2823         return (0);
 2824 }
 2825 
 2826 static int
 2827 mls_vnode_check_relabel(struct ucred *cred, struct vnode *vp,
 2828     struct label *vplabel, struct label *newlabel)
 2829 {
 2830         struct mac_mls *old, *new, *subj;
 2831         int error;
 2832 
 2833         old = SLOT(vplabel);
 2834         new = SLOT(newlabel);
 2835         subj = SLOT(cred->cr_label);
 2836 
 2837         /*
 2838          * If there is an MLS label update for the vnode, it must be a
 2839          * effective label.
 2840          */
 2841         error = mls_atmostflags(new, MAC_MLS_FLAG_EFFECTIVE);
 2842         if (error)
 2843                 return (error);
 2844 
 2845         /*
 2846          * To perform a relabel of the vnode (MLS label or not), MLS must
 2847          * authorize the relabel.
 2848          */
 2849         if (!mls_effective_in_range(old, subj))
 2850                 return (EPERM);
 2851 
 2852         /*
 2853          * If the MLS label is to be changed, authorize as appropriate.
 2854          */
 2855         if (new->mm_flags & MAC_MLS_FLAG_EFFECTIVE) {
 2856                 /*
 2857                  * To change the MLS label on a vnode, the new vnode label
 2858                  * must be in the subject range.
 2859                  */
 2860                 if (!mls_effective_in_range(new, subj))
 2861                         return (EPERM);
 2862 
 2863                 /*
 2864                  * To change the MLS label on the vnode to be EQUAL, the
 2865                  * subject must have appropriate privilege.
 2866                  */
 2867                 if (mls_contains_equal(new)) {
 2868                         error = mls_subject_privileged(subj);
 2869                         if (error)
 2870                                 return (error);
 2871                 }
 2872         }
 2873 
 2874         return (0);
 2875 }
 2876 
 2877 static int
 2878 mls_vnode_check_rename_from(struct ucred *cred, struct vnode *dvp,
 2879     struct label *dvplabel, struct vnode *vp, struct label *vplabel,
 2880     struct componentname *cnp)
 2881 {
 2882         struct mac_mls *subj, *obj;
 2883 
 2884         if (!mls_enabled)
 2885                 return (0);
 2886 
 2887         subj = SLOT(cred->cr_label);
 2888         obj = SLOT(dvplabel);
 2889 
 2890         if (!mls_dominate_effective(obj, subj))
 2891                 return (EACCES);
 2892 
 2893         obj = SLOT(vplabel);
 2894 
 2895         if (!mls_dominate_effective(obj, subj))
 2896                 return (EACCES);
 2897 
 2898         return (0);
 2899 }
 2900 
 2901 static int
 2902 mls_vnode_check_rename_to(struct ucred *cred, struct vnode *dvp,
 2903     struct label *dvplabel, struct vnode *vp, struct label *vplabel,
 2904     int samedir, struct componentname *cnp)
 2905 {
 2906         struct mac_mls *subj, *obj;
 2907 
 2908         if (!mls_enabled)
 2909                 return (0);
 2910 
 2911         subj = SLOT(cred->cr_label);
 2912         obj = SLOT(dvplabel);
 2913 
 2914         if (!mls_dominate_effective(obj, subj))
 2915                 return (EACCES);
 2916 
 2917         if (vp != NULL) {
 2918                 obj = SLOT(vplabel);
 2919 
 2920                 if (!mls_dominate_effective(obj, subj))
 2921                         return (EACCES);
 2922         }
 2923 
 2924         return (0);
 2925 }
 2926 
 2927 static int
 2928 mls_vnode_check_revoke(struct ucred *cred, struct vnode *vp,
 2929     struct label *vplabel)
 2930 {
 2931         struct mac_mls *subj, *obj;
 2932 
 2933         if (!mls_enabled)
 2934                 return (0);
 2935 
 2936         subj = SLOT(cred->cr_label);
 2937         obj = SLOT(vplabel);
 2938 
 2939         if (!mls_dominate_effective(obj, subj))
 2940                 return (EACCES);
 2941 
 2942         return (0);
 2943 }
 2944 
 2945 static int
 2946 mls_vnode_check_setacl(struct ucred *cred, struct vnode *vp,
 2947     struct label *vplabel, acl_type_t type, struct acl *acl)
 2948 {
 2949         struct mac_mls *subj, *obj;
 2950 
 2951         if (!mls_enabled)
 2952                 return (0);
 2953 
 2954         subj = SLOT(cred->cr_label);
 2955         obj = SLOT(vplabel);
 2956 
 2957         if (!mls_dominate_effective(obj, subj))
 2958                 return (EACCES);
 2959 
 2960         return (0);
 2961 }
 2962 
 2963 static int
 2964 mls_vnode_check_setextattr(struct ucred *cred, struct vnode *vp,
 2965     struct label *vplabel, int attrnamespace, const char *name)
 2966 {
 2967         struct mac_mls *subj, *obj;
 2968 
 2969         if (!mls_enabled)
 2970                 return (0);
 2971 
 2972         subj = SLOT(cred->cr_label);
 2973         obj = SLOT(vplabel);
 2974 
 2975         if (!mls_dominate_effective(obj, subj))
 2976                 return (EACCES);
 2977 
 2978         /* XXX: protect the MAC EA in a special way? */
 2979 
 2980         return (0);
 2981 }
 2982 
 2983 static int
 2984 mls_vnode_check_setflags(struct ucred *cred, struct vnode *vp,
 2985     struct label *vplabel, u_long flags)
 2986 {
 2987         struct mac_mls *subj, *obj;
 2988 
 2989         if (!mls_enabled)
 2990                 return (0);
 2991 
 2992         subj = SLOT(cred->cr_label);
 2993         obj = SLOT(vplabel);
 2994 
 2995         if (!mls_dominate_effective(obj, subj))
 2996                 return (EACCES);
 2997 
 2998         return (0);
 2999 }
 3000 
 3001 static int
 3002 mls_vnode_check_setmode(struct ucred *cred, struct vnode *vp,
 3003     struct label *vplabel, mode_t mode)
 3004 {
 3005         struct mac_mls *subj, *obj;
 3006 
 3007         if (!mls_enabled)
 3008                 return (0);
 3009 
 3010         subj = SLOT(cred->cr_label);
 3011         obj = SLOT(vplabel);
 3012 
 3013         if (!mls_dominate_effective(obj, subj))
 3014                 return (EACCES);
 3015 
 3016         return (0);
 3017 }
 3018 
 3019 static int
 3020 mls_vnode_check_setowner(struct ucred *cred, struct vnode *vp,
 3021     struct label *vplabel, uid_t uid, gid_t gid)
 3022 {
 3023         struct mac_mls *subj, *obj;
 3024 
 3025         if (!mls_enabled)
 3026                 return (0);
 3027 
 3028         subj = SLOT(cred->cr_label);
 3029         obj = SLOT(vplabel);
 3030 
 3031         if (!mls_dominate_effective(obj, subj))
 3032                 return (EACCES);
 3033 
 3034         return (0);
 3035 }
 3036 
 3037 static int
 3038 mls_vnode_check_setutimes(struct ucred *cred, struct vnode *vp,
 3039     struct label *vplabel, struct timespec atime, struct timespec mtime)
 3040 {
 3041         struct mac_mls *subj, *obj;
 3042 
 3043         if (!mls_enabled)
 3044                 return (0);
 3045 
 3046         subj = SLOT(cred->cr_label);
 3047         obj = SLOT(vplabel);
 3048 
 3049         if (!mls_dominate_effective(obj, subj))
 3050                 return (EACCES);
 3051 
 3052         return (0);
 3053 }
 3054 
 3055 static int
 3056 mls_vnode_check_stat(struct ucred *active_cred, struct ucred *file_cred,
 3057     struct vnode *vp, struct label *vplabel)
 3058 {
 3059         struct mac_mls *subj, *obj;
 3060 
 3061         if (!mls_enabled)
 3062                 return (0);
 3063 
 3064         subj = SLOT(active_cred->cr_label);
 3065         obj = SLOT(vplabel);
 3066 
 3067         if (!mls_dominate_effective(subj, obj))
 3068                 return (EACCES);
 3069 
 3070         return (0);
 3071 }
 3072 
 3073 static int
 3074 mls_vnode_check_unlink(struct ucred *cred, struct vnode *dvp,
 3075     struct label *dvplabel, struct vnode *vp, struct label *vplabel,
 3076     struct componentname *cnp)
 3077 {
 3078         struct mac_mls *subj, *obj;
 3079 
 3080         if (!mls_enabled)
 3081                 return (0);
 3082 
 3083         subj = SLOT(cred->cr_label);
 3084         obj = SLOT(dvplabel);
 3085 
 3086         if (!mls_dominate_effective(obj, subj))
 3087                 return (EACCES);
 3088 
 3089         obj = SLOT(vplabel);
 3090 
 3091         if (!mls_dominate_effective(obj, subj))
 3092                 return (EACCES);
 3093 
 3094         return (0);
 3095 }
 3096 
 3097 static int
 3098 mls_vnode_check_write(struct ucred *active_cred, struct ucred *file_cred,
 3099     struct vnode *vp, struct label *vplabel)
 3100 {
 3101         struct mac_mls *subj, *obj;
 3102 
 3103         if (!mls_enabled || !revocation_enabled)
 3104                 return (0);
 3105 
 3106         subj = SLOT(active_cred->cr_label);
 3107         obj = SLOT(vplabel);
 3108 
 3109         if (!mls_dominate_effective(obj, subj))
 3110                 return (EACCES);
 3111 
 3112         return (0);
 3113 }
 3114 
 3115 static int
 3116 mls_vnode_create_extattr(struct ucred *cred, struct mount *mp,
 3117     struct label *mplabel, struct vnode *dvp, struct label *dvplabel,
 3118     struct vnode *vp, struct label *vplabel, struct componentname *cnp)
 3119 {
 3120         struct mac_mls *source, *dest, mm_temp;
 3121         size_t buflen;
 3122         int error;
 3123 
 3124         buflen = sizeof(mm_temp);
 3125         bzero(&mm_temp, buflen);
 3126 
 3127         source = SLOT(cred->cr_label);
 3128         dest = SLOT(vplabel);
 3129         mls_copy_effective(source, &mm_temp);
 3130 
 3131         error = vn_extattr_set(vp, IO_NODELOCKED, MAC_MLS_EXTATTR_NAMESPACE,
 3132             MAC_MLS_EXTATTR_NAME, buflen, (char *) &mm_temp, curthread);
 3133         if (error == 0)
 3134                 mls_copy_effective(source, dest);
 3135         return (error);
 3136 }
 3137 
 3138 static void
 3139 mls_vnode_relabel(struct ucred *cred, struct vnode *vp,
 3140     struct label *vplabel, struct label *label)
 3141 {
 3142         struct mac_mls *source, *dest;
 3143 
 3144         source = SLOT(label);
 3145         dest = SLOT(vplabel);
 3146 
 3147         mls_copy(source, dest);
 3148 }
 3149 
 3150 static int
 3151 mls_vnode_setlabel_extattr(struct ucred *cred, struct vnode *vp,
 3152     struct label *vplabel, struct label *intlabel)
 3153 {
 3154         struct mac_mls *source, mm_temp;
 3155         size_t buflen;
 3156         int error;
 3157 
 3158         buflen = sizeof(mm_temp);
 3159         bzero(&mm_temp, buflen);
 3160 
 3161         source = SLOT(intlabel);
 3162         if ((source->mm_flags & MAC_MLS_FLAG_EFFECTIVE) == 0)
 3163                 return (0);
 3164 
 3165         mls_copy_effective(source, &mm_temp);
 3166 
 3167         error = vn_extattr_set(vp, IO_NODELOCKED, MAC_MLS_EXTATTR_NAMESPACE,
 3168             MAC_MLS_EXTATTR_NAME, buflen, (char *) &mm_temp, curthread);
 3169         return (error);
 3170 }
 3171 
 3172 static struct mac_policy_ops mls_ops =
 3173 {
 3174         .mpo_init = mls_init,
 3175 
 3176         .mpo_bpfdesc_check_receive = mls_bpfdesc_check_receive,
 3177         .mpo_bpfdesc_create = mls_bpfdesc_create,
 3178         .mpo_bpfdesc_create_mbuf = mls_bpfdesc_create_mbuf,
 3179         .mpo_bpfdesc_destroy_label = mls_destroy_label,
 3180         .mpo_bpfdesc_init_label = mls_init_label,
 3181 
 3182         .mpo_cred_associate_nfsd = mls_cred_associate_nfsd,
 3183         .mpo_cred_check_relabel = mls_cred_check_relabel,
 3184         .mpo_cred_check_visible = mls_cred_check_visible,
 3185         .mpo_cred_copy_label = mls_copy_label,
 3186         .mpo_cred_create_init = mls_cred_create_init,
 3187         .mpo_cred_create_swapper = mls_cred_create_swapper,
 3188         .mpo_cred_destroy_label = mls_destroy_label,
 3189         .mpo_cred_externalize_label = mls_externalize_label,
 3190         .mpo_cred_init_label = mls_init_label,
 3191         .mpo_cred_internalize_label = mls_internalize_label,
 3192         .mpo_cred_relabel = mls_cred_relabel,
 3193 
 3194         .mpo_devfs_create_device = mls_devfs_create_device,
 3195         .mpo_devfs_create_directory = mls_devfs_create_directory,
 3196         .mpo_devfs_create_symlink = mls_devfs_create_symlink,
 3197         .mpo_devfs_destroy_label = mls_destroy_label,
 3198         .mpo_devfs_init_label = mls_init_label,
 3199         .mpo_devfs_update = mls_devfs_update,
 3200         .mpo_devfs_vnode_associate = mls_devfs_vnode_associate,
 3201 
 3202         .mpo_ifnet_check_relabel = mls_ifnet_check_relabel,
 3203         .mpo_ifnet_check_transmit = mls_ifnet_check_transmit,
 3204         .mpo_ifnet_copy_label = mls_copy_label,
 3205         .mpo_ifnet_create = mls_ifnet_create,
 3206         .mpo_ifnet_create_mbuf = mls_ifnet_create_mbuf,
 3207         .mpo_ifnet_destroy_label = mls_destroy_label,
 3208         .mpo_ifnet_externalize_label = mls_externalize_label,
 3209         .mpo_ifnet_init_label = mls_init_label,
 3210         .mpo_ifnet_internalize_label = mls_internalize_label,
 3211         .mpo_ifnet_relabel = mls_ifnet_relabel,
 3212 
 3213         .mpo_inpcb_check_deliver = mls_inpcb_check_deliver,
 3214         .mpo_inpcb_check_visible = mls_inpcb_check_visible,
 3215         .mpo_inpcb_create = mls_inpcb_create,
 3216         .mpo_inpcb_create_mbuf = mls_inpcb_create_mbuf,
 3217         .mpo_inpcb_destroy_label = mls_destroy_label,
 3218         .mpo_inpcb_init_label = mls_init_label_waitcheck,
 3219         .mpo_inpcb_sosetlabel = mls_inpcb_sosetlabel,
 3220 
 3221         .mpo_ip6q_create = mls_ip6q_create,
 3222         .mpo_ip6q_destroy_label = mls_destroy_label,
 3223         .mpo_ip6q_init_label = mls_init_label_waitcheck,
 3224         .mpo_ip6q_match = mls_ip6q_match,
 3225         .mpo_ip6q_reassemble = mls_ip6q_reassemble,
 3226         .mpo_ip6q_update = mls_ip6q_update,
 3227 
 3228         .mpo_ipq_create = mls_ipq_create,
 3229         .mpo_ipq_destroy_label = mls_destroy_label,
 3230         .mpo_ipq_init_label = mls_init_label_waitcheck,
 3231         .mpo_ipq_match = mls_ipq_match,
 3232         .mpo_ipq_reassemble = mls_ipq_reassemble,
 3233         .mpo_ipq_update = mls_ipq_update,
 3234 
 3235         .mpo_mbuf_copy_label = mls_copy_label,
 3236         .mpo_mbuf_destroy_label = mls_destroy_label,
 3237         .mpo_mbuf_init_label = mls_init_label_waitcheck,
 3238 
 3239         .mpo_mount_check_stat = mls_mount_check_stat,
 3240         .mpo_mount_create = mls_mount_create,
 3241         .mpo_mount_destroy_label = mls_destroy_label,
 3242         .mpo_mount_init_label = mls_init_label,
 3243 
 3244         .mpo_netatalk_aarp_send = mls_netatalk_aarp_send,
 3245 
 3246         .mpo_netinet_arp_send = mls_netinet_arp_send,
 3247         .mpo_netinet_firewall_reply = mls_netinet_firewall_reply,
 3248         .mpo_netinet_firewall_send = mls_netinet_firewall_send,
 3249         .mpo_netinet_fragment = mls_netinet_fragment,
 3250         .mpo_netinet_icmp_reply = mls_netinet_icmp_reply,
 3251         .mpo_netinet_igmp_send = mls_netinet_igmp_send,
 3252 
 3253         .mpo_netinet6_nd6_send = mls_netinet6_nd6_send,
 3254 
 3255         .mpo_pipe_check_ioctl = mls_pipe_check_ioctl,
 3256         .mpo_pipe_check_poll = mls_pipe_check_poll,
 3257         .mpo_pipe_check_read = mls_pipe_check_read,
 3258         .mpo_pipe_check_relabel = mls_pipe_check_relabel,
 3259         .mpo_pipe_check_stat = mls_pipe_check_stat,
 3260         .mpo_pipe_check_write = mls_pipe_check_write,
 3261         .mpo_pipe_copy_label = mls_copy_label,
 3262         .mpo_pipe_create = mls_pipe_create,
 3263         .mpo_pipe_destroy_label = mls_destroy_label,
 3264         .mpo_pipe_externalize_label = mls_externalize_label,
 3265         .mpo_pipe_init_label = mls_init_label,
 3266         .mpo_pipe_internalize_label = mls_internalize_label,
 3267         .mpo_pipe_relabel = mls_pipe_relabel,
 3268 
 3269         .mpo_posixsem_check_getvalue = mls_posixsem_check_rdonly,
 3270         .mpo_posixsem_check_open = mls_posixsem_check_openunlink,
 3271         .mpo_posixsem_check_post = mls_posixsem_check_write,
 3272         .mpo_posixsem_check_setmode = mls_posixsem_check_setmode,
 3273         .mpo_posixsem_check_setowner = mls_posixsem_check_setowner,
 3274         .mpo_posixsem_check_stat = mls_posixsem_check_rdonly,
 3275         .mpo_posixsem_check_unlink = mls_posixsem_check_openunlink,
 3276         .mpo_posixsem_check_wait = mls_posixsem_check_write,
 3277         .mpo_posixsem_create = mls_posixsem_create,
 3278         .mpo_posixsem_destroy_label = mls_destroy_label,
 3279         .mpo_posixsem_init_label = mls_init_label,
 3280 
 3281         .mpo_posixshm_check_mmap = mls_posixshm_check_mmap,
 3282         .mpo_posixshm_check_open = mls_posixshm_check_open,
 3283         .mpo_posixshm_check_setmode = mls_posixshm_check_setmode,
 3284         .mpo_posixshm_check_setowner = mls_posixshm_check_setowner,
 3285         .mpo_posixshm_check_stat = mls_posixshm_check_stat,
 3286         .mpo_posixshm_check_truncate = mls_posixshm_check_truncate,
 3287         .mpo_posixshm_check_unlink = mls_posixshm_check_unlink,
 3288         .mpo_posixshm_create = mls_posixshm_create,
 3289         .mpo_posixshm_destroy_label = mls_destroy_label,
 3290         .mpo_posixshm_init_label = mls_init_label,
 3291 
 3292         .mpo_proc_check_debug = mls_proc_check_debug,
 3293         .mpo_proc_check_sched = mls_proc_check_sched,
 3294         .mpo_proc_check_signal = mls_proc_check_signal,
 3295 
 3296         .mpo_socket_check_deliver = mls_socket_check_deliver,
 3297         .mpo_socket_check_relabel = mls_socket_check_relabel,
 3298         .mpo_socket_check_visible = mls_socket_check_visible,
 3299         .mpo_socket_copy_label = mls_copy_label,
 3300         .mpo_socket_create = mls_socket_create,
 3301         .mpo_socket_create_mbuf = mls_socket_create_mbuf,
 3302         .mpo_socket_destroy_label = mls_destroy_label,
 3303         .mpo_socket_externalize_label = mls_externalize_label,
 3304         .mpo_socket_init_label = mls_init_label_waitcheck,
 3305         .mpo_socket_internalize_label = mls_internalize_label,
 3306         .mpo_socket_newconn = mls_socket_newconn,
 3307         .mpo_socket_relabel = mls_socket_relabel,
 3308 
 3309         .mpo_socketpeer_destroy_label = mls_destroy_label,
 3310         .mpo_socketpeer_externalize_label = mls_externalize_label,
 3311         .mpo_socketpeer_init_label = mls_init_label_waitcheck,
 3312         .mpo_socketpeer_set_from_mbuf = mls_socketpeer_set_from_mbuf,
 3313         .mpo_socketpeer_set_from_socket = mls_socketpeer_set_from_socket,
 3314 
 3315         .mpo_syncache_create = mls_syncache_create,
 3316         .mpo_syncache_create_mbuf = mls_syncache_create_mbuf,
 3317         .mpo_syncache_destroy_label = mls_destroy_label,
 3318         .mpo_syncache_init_label = mls_init_label_waitcheck,
 3319 
 3320         .mpo_sysvmsg_cleanup = mls_sysvmsg_cleanup,
 3321         .mpo_sysvmsg_create = mls_sysvmsg_create,
 3322         .mpo_sysvmsg_destroy_label = mls_destroy_label,
 3323         .mpo_sysvmsg_init_label = mls_init_label,
 3324 
 3325         .mpo_sysvmsq_check_msgrcv = mls_sysvmsq_check_msgrcv,
 3326         .mpo_sysvmsq_check_msgrmid = mls_sysvmsq_check_msgrmid,
 3327         .mpo_sysvmsq_check_msqget = mls_sysvmsq_check_msqget,
 3328         .mpo_sysvmsq_check_msqsnd = mls_sysvmsq_check_msqsnd,
 3329         .mpo_sysvmsq_check_msqrcv = mls_sysvmsq_check_msqrcv,
 3330         .mpo_sysvmsq_check_msqctl = mls_sysvmsq_check_msqctl,
 3331         .mpo_sysvmsq_cleanup = mls_sysvmsq_cleanup,
 3332         .mpo_sysvmsq_destroy_label = mls_destroy_label,
 3333         .mpo_sysvmsq_init_label = mls_init_label,
 3334         .mpo_sysvmsq_create = mls_sysvmsq_create,
 3335 
 3336         .mpo_sysvsem_check_semctl = mls_sysvsem_check_semctl,
 3337         .mpo_sysvsem_check_semget = mls_sysvsem_check_semget,
 3338         .mpo_sysvsem_check_semop = mls_sysvsem_check_semop,
 3339         .mpo_sysvsem_cleanup = mls_sysvsem_cleanup,
 3340         .mpo_sysvsem_create = mls_sysvsem_create,
 3341         .mpo_sysvsem_destroy_label = mls_destroy_label,
 3342         .mpo_sysvsem_init_label = mls_init_label,
 3343 
 3344         .mpo_sysvshm_check_shmat = mls_sysvshm_check_shmat,
 3345         .mpo_sysvshm_check_shmctl = mls_sysvshm_check_shmctl,
 3346         .mpo_sysvshm_check_shmget = mls_sysvshm_check_shmget,
 3347         .mpo_sysvshm_cleanup = mls_sysvshm_cleanup,
 3348         .mpo_sysvshm_create = mls_sysvshm_create,
 3349         .mpo_sysvshm_destroy_label = mls_destroy_label,
 3350         .mpo_sysvshm_init_label = mls_init_label,
 3351 
 3352 
 3353         .mpo_system_check_acct = mls_system_check_acct,
 3354         .mpo_system_check_auditctl = mls_system_check_auditctl,
 3355         .mpo_system_check_swapon = mls_system_check_swapon,
 3356 
 3357         .mpo_vnode_associate_extattr = mls_vnode_associate_extattr,
 3358         .mpo_vnode_associate_singlelabel = mls_vnode_associate_singlelabel,
 3359         .mpo_vnode_check_access = mls_vnode_check_open,
 3360         .mpo_vnode_check_chdir = mls_vnode_check_chdir,
 3361         .mpo_vnode_check_chroot = mls_vnode_check_chroot,
 3362         .mpo_vnode_check_create = mls_vnode_check_create,
 3363         .mpo_vnode_check_deleteacl = mls_vnode_check_deleteacl,
 3364         .mpo_vnode_check_deleteextattr = mls_vnode_check_deleteextattr,
 3365         .mpo_vnode_check_exec = mls_vnode_check_exec,
 3366         .mpo_vnode_check_getacl = mls_vnode_check_getacl,
 3367         .mpo_vnode_check_getextattr = mls_vnode_check_getextattr,
 3368         .mpo_vnode_check_link = mls_vnode_check_link,
 3369         .mpo_vnode_check_listextattr = mls_vnode_check_listextattr,
 3370         .mpo_vnode_check_lookup = mls_vnode_check_lookup,
 3371         .mpo_vnode_check_mmap = mls_vnode_check_mmap,
 3372         .mpo_vnode_check_open = mls_vnode_check_open,
 3373         .mpo_vnode_check_poll = mls_vnode_check_poll,
 3374         .mpo_vnode_check_read = mls_vnode_check_read,
 3375         .mpo_vnode_check_readdir = mls_vnode_check_readdir,
 3376         .mpo_vnode_check_readlink = mls_vnode_check_readlink,
 3377         .mpo_vnode_check_relabel = mls_vnode_check_relabel,
 3378         .mpo_vnode_check_rename_from = mls_vnode_check_rename_from,
 3379         .mpo_vnode_check_rename_to = mls_vnode_check_rename_to,
 3380         .mpo_vnode_check_revoke = mls_vnode_check_revoke,
 3381         .mpo_vnode_check_setacl = mls_vnode_check_setacl,
 3382         .mpo_vnode_check_setextattr = mls_vnode_check_setextattr,
 3383         .mpo_vnode_check_setflags = mls_vnode_check_setflags,
 3384         .mpo_vnode_check_setmode = mls_vnode_check_setmode,
 3385         .mpo_vnode_check_setowner = mls_vnode_check_setowner,
 3386         .mpo_vnode_check_setutimes = mls_vnode_check_setutimes,
 3387         .mpo_vnode_check_stat = mls_vnode_check_stat,
 3388         .mpo_vnode_check_unlink = mls_vnode_check_unlink,
 3389         .mpo_vnode_check_write = mls_vnode_check_write,
 3390         .mpo_vnode_copy_label = mls_copy_label,
 3391         .mpo_vnode_create_extattr = mls_vnode_create_extattr,
 3392         .mpo_vnode_destroy_label = mls_destroy_label,
 3393         .mpo_vnode_externalize_label = mls_externalize_label,
 3394         .mpo_vnode_init_label = mls_init_label,
 3395         .mpo_vnode_internalize_label = mls_internalize_label,
 3396         .mpo_vnode_relabel = mls_vnode_relabel,
 3397         .mpo_vnode_setlabel_extattr = mls_vnode_setlabel_extattr,
 3398 };
 3399 
 3400 MAC_POLICY_SET(&mls_ops, mac_mls, "TrustedBSD MAC/MLS",
 3401     MPC_LOADTIME_FLAG_NOTLATE, &mls_slot);

Cache object: 12c6c8ce0304feee07bc0433ada28de0


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