[ 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  -  FREEBSD8  -  FREEBSD7  -  FREEBSD72  -  FREEBSD71  -  FREEBSD70  -  FREEBSD6  -  FREEBSD64  -  FREEBSD63  -  FREEBSD62  -  FREEBSD61  -  FREEBSD60  -  FREEBSD5  -  FREEBSD55  -  FREEBSD54  -  FREEBSD53  -  FREEBSD52  -  FREEBSD51  -  FREEBSD50  -  FREEBSD4  -  FREEBSD3  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  OPENSOLARIS  -  minix-3-1-1  -  FREEBSD-LIBC  -  FREEBSD7-LIBC  -  FREEBSD6-LIBC  -  GLIBC27 
SearchContext: -  none  -  excerpts  -  bigexcerpts 

    1 /*-
    2  * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson
    3  * Copyright (c) 2001, 2002, 2003 Networks Associates Technology, Inc.
    4  * All rights reserved.
    5  *
    6  * This software was developed by Robert Watson for the TrustedBSD Project.
    7  *
    8  * This software was developed for the FreeBSD Project in part by Network
    9  * Associates Laboratories, the Security Research Division of Network
   10  * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"),
   11  * as part of the DARPA CHATS research program.
   12  *
   13  * Redistribution and use in source and binary forms, with or without
   14  * modification, are permitted provided that the following conditions
   15  * are met:
   16  * 1. Redistributions of source code must retain the above copyright
   17  *    notice, this list of conditions and the following disclaimer.
   18  * 2. Redistributions in binary form must reproduce the above copyright
   19  *    notice, this list of conditions and the following disclaimer in the
   20  *    documentation and/or other materials provided with the distribution.
   21  *
   22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   32  * SUCH DAMAGE.
   33  *
   34  * $FreeBSD: src/sys/security/mac_mls/mac_mls.c,v 1.59 2003/12/06 21:48:02 rwatson Exp $
   35  */
   36 
   37 /*
   38  * Developed by the TrustedBSD Project.
   39  * MLS fixed label mandatory confidentiality policy.
   40  */
   41 
   42 #include <sys/types.h>
   43 #include <sys/param.h>
   44 #include <sys/acl.h>
   45 #include <sys/conf.h>
   46 #include <sys/extattr.h>
   47 #include <sys/kernel.h>
   48 #include <sys/mac.h>
   49 #include <sys/malloc.h>
   50 #include <sys/mount.h>
   51 #include <sys/proc.h>
   52 #include <sys/sbuf.h>
   53 #include <sys/systm.h>
   54 #include <sys/sysproto.h>
   55 #include <sys/sysent.h>
   56 #include <sys/systm.h>
   57 #include <sys/vnode.h>
   58 #include <sys/file.h>
   59 #include <sys/socket.h>
   60 #include <sys/socketvar.h>
   61 #include <sys/pipe.h>
   62 #include <sys/sysctl.h>
   63 
   64 #include <fs/devfs/devfs.h>
   65 
   66 #include <net/bpfdesc.h>
   67 #include <net/if.h>
   68 #include <net/if_types.h>
   69 #include <net/if_var.h>
   70 
   71 #include <netinet/in.h>
   72 #include <netinet/in_pcb.h>
   73 #include <netinet/ip_var.h>
   74 
   75 #include <vm/uma.h>
   76 #include <vm/vm.h>
   77 
   78 #include <sys/mac_policy.h>
   79 
   80 #include <security/mac_mls/mac_mls.h>
   81 
   82 SYSCTL_DECL(_security_mac);
   83 
   84 SYSCTL_NODE(_security_mac, OID_AUTO, mls, CTLFLAG_RW, 0,
   85     "TrustedBSD mac_mls policy controls");
   86 
   87 static int      mac_mls_label_size = sizeof(struct mac_mls);
   88 SYSCTL_INT(_security_mac_mls, OID_AUTO, label_size, CTLFLAG_RD,
   89     &mac_mls_label_size, 0, "Size of struct mac_mls");
   90 
   91 static int      mac_mls_enabled = 1;
   92 SYSCTL_INT(_security_mac_mls, OID_AUTO, enabled, CTLFLAG_RW,
   93     &mac_mls_enabled, 0, "Enforce MAC/MLS policy");
   94 TUNABLE_INT("security.mac.mls.enabled", &mac_mls_enabled);
   95 
   96 static int      destroyed_not_inited;
   97 SYSCTL_INT(_security_mac_mls, OID_AUTO, destroyed_not_inited, CTLFLAG_RD,
   98     &destroyed_not_inited, 0, "Count of labels destroyed but not inited");
   99 
  100 static int      ptys_equal = 0;
  101 SYSCTL_INT(_security_mac_mls, OID_AUTO, ptys_equal, CTLFLAG_RW,
  102     &ptys_equal, 0, "Label pty devices as mls/equal on create");
  103 TUNABLE_INT("security.mac.mls.ptys_equal", &ptys_equal);
  104 
  105 static int      revocation_enabled = 0;
  106 SYSCTL_INT(_security_mac_mls, OID_AUTO, revocation_enabled, CTLFLAG_RW,
  107     &revocation_enabled, 0, "Revoke access to objects on relabel");
  108 TUNABLE_INT("security.mac.mls.revocation_enabled", &revocation_enabled);
  109 
  110 static int      max_compartments = MAC_MLS_MAX_COMPARTMENTS;
  111 SYSCTL_INT(_security_mac_mls, OID_AUTO, max_compartments, CTLFLAG_RD,
  112     &max_compartments, 0, "Maximum compartments the policy supports");
  113 
  114 static int      mac_mls_slot;
  115 #define SLOT(l) ((struct mac_mls *)LABEL_TO_SLOT((l), mac_mls_slot).l_ptr)
  116 
  117 static uma_zone_t       zone_mls;
  118 
  119 static __inline int
  120 mls_bit_set_empty(u_char *set) {
  121         int i;
  122 
  123         for (i = 0; i < MAC_MLS_MAX_COMPARTMENTS >> 3; i++)
  124                 if (set[i] != 0)
  125                         return (0);
  126         return (1);
  127 }
  128 
  129 static struct mac_mls *
  130 mls_alloc(int flag)
  131 {
  132 
  133         return (uma_zalloc(zone_mls, flag | M_ZERO));
  134 }
  135 
  136 static void
  137 mls_free(struct mac_mls *mac_mls)
  138 {
  139 
  140         if (mac_mls != NULL)
  141                 uma_zfree(zone_mls, mac_mls);
  142         else
  143                 atomic_add_int(&destroyed_not_inited, 1);
  144 }
  145 
  146 static int
  147 mls_atmostflags(struct mac_mls *mac_mls, int flags)
  148 {
  149 
  150         if ((mac_mls->mm_flags & flags) != mac_mls->mm_flags)
  151                 return (EINVAL);
  152         return (0);
  153 }
  154 
  155 static int
  156 mac_mls_dominate_element(struct mac_mls_element *a,
  157     struct mac_mls_element *b)
  158 {
  159         int bit;
  160 
  161         switch (a->mme_type) {
  162         case MAC_MLS_TYPE_EQUAL:
  163         case MAC_MLS_TYPE_HIGH:
  164                 return (1);
  165 
  166         case MAC_MLS_TYPE_LOW:
  167                 switch (b->mme_type) {
  168                 case MAC_MLS_TYPE_LEVEL:
  169                 case MAC_MLS_TYPE_HIGH:
  170                         return (0);
  171 
  172                 case MAC_MLS_TYPE_EQUAL:
  173                 case MAC_MLS_TYPE_LOW:
  174                         return (1);
  175 
  176                 default:
  177                         panic("mac_mls_dominate_element: b->mme_type invalid");
  178                 }
  179 
  180         case MAC_MLS_TYPE_LEVEL:
  181                 switch (b->mme_type) {
  182                 case MAC_MLS_TYPE_EQUAL:
  183                 case MAC_MLS_TYPE_LOW:
  184                         return (1);
  185 
  186                 case MAC_MLS_TYPE_HIGH:
  187                         return (0);
  188 
  189                 case MAC_MLS_TYPE_LEVEL:
  190                         for (bit = 1; bit <= MAC_MLS_MAX_COMPARTMENTS; bit++)
  191                                 if (!MAC_MLS_BIT_TEST(bit,
  192                                     a->mme_compartments) &&
  193                                     MAC_MLS_BIT_TEST(bit, b->mme_compartments))
  194                                         return (0);
  195                         return (a->mme_level >= b->mme_level);
  196 
  197                 default:
  198                         panic("mac_mls_dominate_element: b->mme_type invalid");
  199                 }
  200 
  201         default:
  202                 panic("mac_mls_dominate_element: a->mme_type invalid");
  203         }
  204 
  205         return (0);
  206 }
  207 
  208 static int
  209 mac_mls_range_in_range(struct mac_mls *rangea, struct mac_mls *rangeb)
  210 {
  211 
  212         return (mac_mls_dominate_element(&rangeb->mm_rangehigh,
  213             &rangea->mm_rangehigh) &&
  214             mac_mls_dominate_element(&rangea->mm_rangelow,
  215             &rangeb->mm_rangelow));
  216 }
  217 
  218 static int
  219 mac_mls_single_in_range(struct mac_mls *single, struct mac_mls *range)
  220 {
  221 
  222         KASSERT((single->mm_flags & MAC_MLS_FLAG_SINGLE) != 0,
  223             ("mac_mls_single_in_range: a not single"));
  224         KASSERT((range->mm_flags & MAC_MLS_FLAG_RANGE) != 0,
  225             ("mac_mls_single_in_range: b not range"));
  226 
  227         return (mac_mls_dominate_element(&range->mm_rangehigh,
  228             &single->mm_single) &&
  229             mac_mls_dominate_element(&single->mm_single,
  230             &range->mm_rangelow));
  231 
  232         return (1);
  233 }
  234 
  235 static int
  236 mac_mls_dominate_single(struct mac_mls *a, struct mac_mls *b)
  237 {
  238         KASSERT((a->mm_flags & MAC_MLS_FLAG_SINGLE) != 0,
  239             ("mac_mls_dominate_single: a not single"));
  240         KASSERT((b->mm_flags & MAC_MLS_FLAG_SINGLE) != 0,
  241             ("mac_mls_dominate_single: b not single"));
  242 
  243         return (mac_mls_dominate_element(&a->mm_single, &b->mm_single));
  244 }
  245 
  246 static int
  247 mac_mls_equal_element(struct mac_mls_element *a, struct mac_mls_element *b)
  248 {
  249 
  250         if (a->mme_type == MAC_MLS_TYPE_EQUAL ||
  251             b->mme_type == MAC_MLS_TYPE_EQUAL)
  252                 return (1);
  253 
  254         return (a->mme_type == b->mme_type && a->mme_level == b->mme_level);
  255 }
  256 
  257 static int
  258 mac_mls_equal_single(struct mac_mls *a, struct mac_mls *b)
  259 {
  260 
  261         KASSERT((a->mm_flags & MAC_MLS_FLAG_SINGLE) != 0,
  262             ("mac_mls_equal_single: a not single"));
  263         KASSERT((b->mm_flags & MAC_MLS_FLAG_SINGLE) != 0,
  264             ("mac_mls_equal_single: b not single"));
  265 
  266         return (mac_mls_equal_element(&a->mm_single, &b->mm_single));
  267 }
  268 
  269 static int
  270 mac_mls_contains_equal(struct mac_mls *mac_mls)
  271 {
  272 
  273         if (mac_mls->mm_flags & MAC_MLS_FLAG_SINGLE)
  274                 if (mac_mls->mm_single.mme_type == MAC_MLS_TYPE_EQUAL)
  275                         return (1);
  276 
  277         if (mac_mls->mm_flags & MAC_MLS_FLAG_RANGE) {
  278                 if (mac_mls->mm_rangelow.mme_type == MAC_MLS_TYPE_EQUAL)
  279                         return (1);
  280                 if (mac_mls->mm_rangehigh.mme_type == MAC_MLS_TYPE_EQUAL)
  281                         return (1);
  282         }
  283 
  284         return (0);
  285 }
  286 
  287 static int
  288 mac_mls_subject_privileged(struct mac_mls *mac_mls)
  289 {
  290 
  291         KASSERT((mac_mls->mm_flags & MAC_MLS_FLAGS_BOTH) ==
  292             MAC_MLS_FLAGS_BOTH,
  293             ("mac_mls_subject_privileged: subject doesn't have both labels"));
  294 
  295         /* If the single is EQUAL, it's ok. */
  296         if (mac_mls->mm_single.mme_type == MAC_MLS_TYPE_EQUAL)
  297                 return (0);
  298 
  299         /* If either range endpoint is EQUAL, it's ok. */
  300         if (mac_mls->mm_rangelow.mme_type == MAC_MLS_TYPE_EQUAL ||
  301             mac_mls->mm_rangehigh.mme_type == MAC_MLS_TYPE_EQUAL)
  302                 return (0);
  303 
  304         /* If the range is low-high, it's ok. */
  305         if (mac_mls->mm_rangelow.mme_type == MAC_MLS_TYPE_LOW &&
  306             mac_mls->mm_rangehigh.mme_type == MAC_MLS_TYPE_HIGH)
  307                 return (0);
  308 
  309         /* It's not ok. */
  310         return (EPERM);
  311 }
  312 
  313 static int
  314 mac_mls_valid(struct mac_mls *mac_mls)
  315 {
  316 
  317         if (mac_mls->mm_flags & MAC_MLS_FLAG_SINGLE) {
  318                 switch (mac_mls->mm_single.mme_type) {
  319                 case MAC_MLS_TYPE_LEVEL:
  320                         break;
  321 
  322                 case MAC_MLS_TYPE_EQUAL:
  323                 case MAC_MLS_TYPE_HIGH:
  324                 case MAC_MLS_TYPE_LOW:
  325                         if (mac_mls->mm_single.mme_level != 0 ||
  326                             !MAC_MLS_BIT_SET_EMPTY(
  327                             mac_mls->mm_single.mme_compartments))
  328                                 return (EINVAL);
  329                         break;
  330 
  331                 default:
  332                         return (EINVAL);
  333                 }
  334         } else {
  335                 if (mac_mls->mm_single.mme_type != MAC_MLS_TYPE_UNDEF)
  336                         return (EINVAL);
  337         }
  338 
  339         if (mac_mls->mm_flags & MAC_MLS_FLAG_RANGE) {
  340                 switch (mac_mls->mm_rangelow.mme_type) {
  341                 case MAC_MLS_TYPE_LEVEL:
  342                         break;
  343 
  344                 case MAC_MLS_TYPE_EQUAL:
  345                 case MAC_MLS_TYPE_HIGH:
  346                 case MAC_MLS_TYPE_LOW:
  347                         if (mac_mls->mm_rangelow.mme_level != 0 ||
  348                             !MAC_MLS_BIT_SET_EMPTY(
  349                             mac_mls->mm_rangelow.mme_compartments))
  350                                 return (EINVAL);
  351                         break;
  352 
  353                 default:
  354                         return (EINVAL);
  355                 }
  356 
  357                 switch (mac_mls->mm_rangehigh.mme_type) {
  358                 case MAC_MLS_TYPE_LEVEL:
  359                         break;
  360 
  361                 case MAC_MLS_TYPE_EQUAL:
  362                 case MAC_MLS_TYPE_HIGH:
  363                 case MAC_MLS_TYPE_LOW:
  364                         if (mac_mls->mm_rangehigh.mme_level != 0 ||
  365                             !MAC_MLS_BIT_SET_EMPTY(
  366                             mac_mls->mm_rangehigh.mme_compartments))
  367                                 return (EINVAL);
  368                         break;
  369 
  370                 default:
  371                         return (EINVAL);
  372                 }
  373                 if (!mac_mls_dominate_element(&mac_mls->mm_rangehigh,
  374                     &mac_mls->mm_rangelow))
  375                         return (EINVAL);
  376         } else {
  377                 if (mac_mls->mm_rangelow.mme_type != MAC_MLS_TYPE_UNDEF ||
  378                     mac_mls->mm_rangehigh.mme_type != MAC_MLS_TYPE_UNDEF)
  379                         return (EINVAL);
  380         }
  381 
  382         return (0);
  383 }
  384 
  385 static void
  386 mac_mls_set_range(struct mac_mls *mac_mls, u_short typelow,
  387     u_short levellow, u_char *compartmentslow, u_short typehigh,
  388     u_short levelhigh, u_char *compartmentshigh)
  389 {
  390 
  391         mac_mls->mm_rangelow.mme_type = typelow;
  392         mac_mls->mm_rangelow.mme_level = levellow;
  393         if (compartmentslow != NULL)
  394                 memcpy(mac_mls->mm_rangelow.mme_compartments,
  395                     compartmentslow,
  396                     sizeof(mac_mls->mm_rangelow.mme_compartments));
  397         mac_mls->mm_rangehigh.mme_type = typehigh;
  398         mac_mls->mm_rangehigh.mme_level = levelhigh;
  399         if (compartmentshigh != NULL)
  400                 memcpy(mac_mls->mm_rangehigh.mme_compartments,
  401                     compartmentshigh,
  402                     sizeof(mac_mls->mm_rangehigh.mme_compartments));
  403         mac_mls->mm_flags |= MAC_MLS_FLAG_RANGE;
  404 }
  405 
  406 static void
  407 mac_mls_set_single(struct mac_mls *mac_mls, u_short type, u_short level,
  408     u_char *compartments)
  409 {
  410 
  411         mac_mls->mm_single.mme_type = type;
  412         mac_mls->mm_single.mme_level = level;
  413         if (compartments != NULL)
  414                 memcpy(mac_mls->mm_single.mme_compartments, compartments,
  415                     sizeof(mac_mls->mm_single.mme_compartments));
  416         mac_mls->mm_flags |= MAC_MLS_FLAG_SINGLE;
  417 }
  418 
  419 static void
  420 mac_mls_copy_range(struct mac_mls *labelfrom, struct mac_mls *labelto)
  421 {
  422 
  423         KASSERT((labelfrom->mm_flags & MAC_MLS_FLAG_RANGE) != 0,
  424             ("mac_mls_copy_range: labelfrom not range"));
  425 
  426         labelto->mm_rangelow = labelfrom->mm_rangelow;
  427         labelto->mm_rangehigh = labelfrom->mm_rangehigh;
  428         labelto->mm_flags |= MAC_MLS_FLAG_RANGE;
  429 }
  430 
  431 static void
  432 mac_mls_copy_single(struct mac_mls *labelfrom, struct mac_mls *labelto)
  433 {
  434 
  435         KASSERT((labelfrom->mm_flags & MAC_MLS_FLAG_SINGLE) != 0,
  436             ("mac_mls_copy_single: labelfrom not single"));
  437 
  438         labelto->mm_single = labelfrom->mm_single;
  439         labelto->mm_flags |= MAC_MLS_FLAG_SINGLE;
  440 }
  441 
  442 static void
  443 mac_mls_copy(struct mac_mls *source, struct mac_mls *dest)
  444 {
  445 
  446         if (source->mm_flags & MAC_MLS_FLAG_SINGLE)
  447                 mac_mls_copy_single(source, dest);
  448         if (source->mm_flags & MAC_MLS_FLAG_RANGE)
  449                 mac_mls_copy_range(source, dest);
  450 }
  451 
  452 /*
  453  * Policy module operations.
  454  */
  455 static void
  456 mac_mls_init(struct mac_policy_conf *conf)
  457 {
  458 
  459         zone_mls = uma_zcreate("mac_mls", sizeof(struct mac_mls), NULL,
  460             NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
  461 }
  462 
  463 /*
  464  * Label operations.
  465  */
  466 static void
  467 mac_mls_init_label(struct label *label)
  468 {
  469 
  470         SLOT(label) = mls_alloc(M_WAITOK);
  471 }
  472 
  473 static int
  474 mac_mls_init_label_waitcheck(struct label *label, int flag)
  475 {
  476 
  477         SLOT(label) = mls_alloc(flag);
  478         if (SLOT(label) == NULL)
  479                 return (ENOMEM);
  480 
  481         return (0);
  482 }
  483 
  484 static void
  485 mac_mls_destroy_label(struct label *label)
  486 {
  487 
  488         mls_free(SLOT(label));
  489         SLOT(label) = NULL;
  490 }
  491 
  492 /*
  493  * mac_mls_element_to_string() accepts an sbuf and MLS element.  It
  494  * converts the MLS element to a string and stores the result in the
  495  * sbuf; if there isn't space in the sbuf, -1 is returned.
  496  */
  497 static int
  498 mac_mls_element_to_string(struct sbuf *sb, struct mac_mls_element *element)
  499 {
  500         int i, first;
  501 
  502         switch (element->mme_type) {
  503         case MAC_MLS_TYPE_HIGH:
  504                 return (sbuf_printf(sb, "high"));
  505 
  506         case MAC_MLS_TYPE_LOW:
  507                 return (sbuf_printf(sb, "low"));
  508 
  509         case MAC_MLS_TYPE_EQUAL:
  510                 return (sbuf_printf(sb, "equal"));
  511 
  512         case MAC_MLS_TYPE_LEVEL:
  513                 if (sbuf_printf(sb, "%d", element->mme_level) == -1)
  514                         return (-1);
  515 
  516                 first = 1;
  517                 for (i = 1; i <= MAC_MLS_MAX_COMPARTMENTS; i++) {
  518                         if (MAC_MLS_BIT_TEST(i, element->mme_compartments)) {
  519                                 if (first) {
  520                                         if (sbuf_putc(sb, ':') == -1)
  521                                                 return (-1);
  522                                         if (sbuf_printf(sb, "%d", i) == -1)
  523                                                 return (-1);
  524                                         first = 0;
  525                                 } else {
  526                                         if (sbuf_printf(sb, "+%d", i) == -1)
  527                                                 return (-1);
  528                                 }
  529                         }
  530                 }
  531                 return (0);
  532 
  533         default:
  534                 panic("mac_mls_element_to_string: invalid type (%d)",
  535                     element->mme_type);
  536         }
  537 }
  538 
  539 /*
  540  * mac_mls_to_string() converts an MLS label to a string, and places
  541  * the results in the passed sbuf.  It returns 0 on success, or EINVAL
  542  * if there isn't room in the sbuf.  Note: the sbuf will be modified
  543  * even in a failure case, so the caller may need to revert the sbuf
  544  * by restoring the offset if that's undesired.
  545  */
  546 static int
  547 mac_mls_to_string(struct sbuf *sb, struct mac_mls *mac_mls)
  548 {
  549 
  550         if (mac_mls->mm_flags & MAC_MLS_FLAG_SINGLE) {
  551                 if (mac_mls_element_to_string(sb, &mac_mls->mm_single)
  552                     == -1)
  553                         return (EINVAL);
  554         }
  555 
  556         if (mac_mls->mm_flags & MAC_MLS_FLAG_RANGE) {
  557                 if (sbuf_putc(sb, '(') == -1)
  558                         return (EINVAL);
  559 
  560                 if (mac_mls_element_to_string(sb, &mac_mls->mm_rangelow)
  561                     == -1)
  562                         return (EINVAL);
  563 
  564                 if (sbuf_putc(sb, '-') == -1)
  565                         return (EINVAL);
  566 
  567                 if (mac_mls_element_to_string(sb, &mac_mls->mm_rangehigh)
  568                     == -1)
  569                         return (EINVAL);
  570 
  571                 if (sbuf_putc(sb, ')') == -1)
  572                         return (EINVAL);
  573         }
  574 
  575         return (0);
  576 }
  577 
  578 static int
  579 mac_mls_externalize_label(struct label *label, char *element_name,
  580     struct sbuf *sb, int *claimed)
  581 {
  582         struct mac_mls *mac_mls;
  583 
  584         if (strcmp(MAC_MLS_LABEL_NAME, element_name) != 0)
  585                 return (0);
  586 
  587         (*claimed)++;
  588 
  589         mac_mls = SLOT(label);
  590 
  591         return (mac_mls_to_string(sb, mac_mls));
  592 }
  593 
  594 static int
  595 mac_mls_parse_element(struct mac_mls_element *element, char *string)
  596 {
  597         char *compartment, *end, *level;
  598         int value;
  599 
  600         if (strcmp(string, "high") == 0 ||
  601             strcmp(string, "hi") == 0) {
  602                 element->mme_type = MAC_MLS_TYPE_HIGH;
  603                 element->mme_level = MAC_MLS_TYPE_UNDEF;
  604         } else if (strcmp(string, "low") == 0 ||
  605             strcmp(string, "lo") == 0) {
  606                 element->mme_type = MAC_MLS_TYPE_LOW;
  607                 element->mme_level = MAC_MLS_TYPE_UNDEF;
  608         } else if (strcmp(string, "equal") == 0 ||
  609             strcmp(string, "eq") == 0) {
  610                 element->mme_type = MAC_MLS_TYPE_EQUAL;
  611                 element->mme_level = MAC_MLS_TYPE_UNDEF;
  612         } else {
  613                 element->mme_type = MAC_MLS_TYPE_LEVEL;
  614 
  615                 /*
  616                  * Numeric level piece of the element.
  617                  */
  618                 level = strsep(&string, ":");
  619                 value = strtol(level, &end, 10);
  620                 if (end == level || *end != '\0')
  621                         return (EINVAL);
  622                 if (value < 0 || value > 65535)
  623                         return (EINVAL);
  624                 element->mme_level = value;
  625 
  626                 /*
  627                  * Optional compartment piece of the element.  If none
  628                  * are included, we assume that the label has no
  629                  * compartments.
  630                  */
  631                 if (string == NULL)
  632                         return (0);
  633                 if (*string == '\0')
  634                         return (0);
  635 
  636                 while ((compartment = strsep(&string, "+")) != NULL) {
  637                         value = strtol(compartment, &end, 10);
  638                         if (compartment == end || *end != '\0')
  639                                 return (EINVAL);
  640                         if (value < 1 || value > MAC_MLS_MAX_COMPARTMENTS)
  641                                 return (EINVAL);
  642                         MAC_MLS_BIT_SET(value, element->mme_compartments);
  643                 }
  644         }
  645 
  646         return (0);
  647 }
  648 
  649 /*
  650  * Note: destructively consumes the string, make a local copy before
  651  * calling if that's a problem.
  652  */
  653 static int
  654 mac_mls_parse(struct mac_mls *mac_mls, char *string)
  655 {
  656         char *rangehigh, *rangelow, *single;
  657         int error;
  658 
  659         single = strsep(&string, "(");
  660         if (*single == '\0')
  661                 single = NULL;
  662 
  663         if (string != NULL) {
  664                 rangelow = strsep(&string, "-");
  665                 if (string == NULL)
  666                         return (EINVAL);
  667                 rangehigh = strsep(&string, ")");
  668                 if (string == NULL)
  669                         return (EINVAL);
  670                 if (*string != '\0')
  671                         return (EINVAL);
  672         } else {
  673                 rangelow = NULL;
  674                 rangehigh = NULL;
  675         }
  676 
  677         KASSERT((rangelow != NULL && rangehigh != NULL) ||
  678             (rangelow == NULL && rangehigh == NULL),
  679             ("mac_mls_parse: range mismatch"));
  680 
  681         bzero(mac_mls, sizeof(*mac_mls));
  682         if (single != NULL) {
  683                 error = mac_mls_parse_element(&mac_mls->mm_single, single);
  684                 if (error)
  685                         return (error);
  686                 mac_mls->mm_flags |= MAC_MLS_FLAG_SINGLE;
  687         }
  688 
  689         if (rangelow != NULL) {
  690                 error = mac_mls_parse_element(&mac_mls->mm_rangelow,
  691                     rangelow);
  692                 if (error)
  693                         return (error);
  694                 error = mac_mls_parse_element(&mac_mls->mm_rangehigh,
  695                     rangehigh);
  696                 if (error)
  697                         return (error);
  698                 mac_mls->mm_flags |= MAC_MLS_FLAG_RANGE;
  699         }
  700 
  701         error = mac_mls_valid(mac_mls);
  702         if (error)
  703                 return (error);
  704 
  705         return (0);
  706 }
  707 
  708 static int
  709 mac_mls_internalize_label(struct label *label, char *element_name,
  710     char *element_data, int *claimed)
  711 {
  712         struct mac_mls *mac_mls, mac_mls_temp;
  713         int error;
  714 
  715         if (strcmp(MAC_MLS_LABEL_NAME, element_name) != 0)
  716                 return (0);
  717 
  718         (*claimed)++;
  719 
  720         error = mac_mls_parse(&mac_mls_temp, element_data);
  721         if (error)
  722                 return (error);
  723 
  724         mac_mls = SLOT(label);
  725         *mac_mls = mac_mls_temp;
  726 
  727         return (0);
  728 }
  729 
  730 static void
  731 mac_mls_copy_label(struct label *src, struct label *dest)
  732 {
  733 
  734         *SLOT(dest) = *SLOT(src);
  735 }
  736 
  737 /*
  738  * Labeling event operations: file system objects, and things that look
  739  * a lot like file system objects.
  740  */
  741 static void
  742 mac_mls_create_devfs_device(struct mount *mp, dev_t dev,
  743     struct devfs_dirent *devfs_dirent, struct label *label)
  744 {
  745         struct mac_mls *mac_mls;
  746         int mls_type;
  747 
  748         mac_mls = SLOT(label);
  749         if (strcmp(dev->si_name, "null") == 0 ||
  750             strcmp(dev->si_name, "zero") == 0 ||
  751             strcmp(dev->si_name, "random") == 0 ||
  752             strncmp(dev->si_name, "fd/", strlen("fd/")) == 0)
  753                 mls_type = MAC_MLS_TYPE_EQUAL;
  754         else if (strcmp(dev->si_name, "kmem") == 0 ||
  755             strcmp(dev->si_name, "mem") == 0)
  756                 mls_type = MAC_MLS_TYPE_HIGH;
  757         else if (ptys_equal &&
  758             (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 ||
  759             strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0))
  760                 mls_type = MAC_MLS_TYPE_EQUAL;
  761         else
  762                 mls_type = MAC_MLS_TYPE_LOW;
  763         mac_mls_set_single(mac_mls, mls_type, 0, NULL);
  764 }
  765 
  766 static void
  767 mac_mls_create_devfs_directory(struct mount *mp, char *dirname,
  768     int dirnamelen, struct devfs_dirent *devfs_dirent, struct label *label)
  769 {
  770         struct mac_mls *mac_mls;
  771 
  772         mac_mls = SLOT(label);
  773         mac_mls_set_single(mac_mls, MAC_MLS_TYPE_LOW, 0, NULL);
  774 }
  775 
  776 static void
  777 mac_mls_create_devfs_symlink(struct ucred *cred, struct mount *mp,
  778     struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de,
  779     struct label *delabel)
  780 {
  781         struct mac_mls *source, *dest;
  782 
  783         source = SLOT(cred->cr_label);
  784         dest = SLOT(delabel);
  785 
  786         mac_mls_copy_single(source, dest);
  787 }
  788 
  789 static void
  790 mac_mls_create_mount(struct ucred *cred, struct mount *mp,
  791     struct label *mntlabel, struct label *fslabel)
  792 {
  793         struct mac_mls *source, *dest;
  794 
  795         source = SLOT(cred->cr_label);
  796         dest = SLOT(mntlabel);
  797         mac_mls_copy_single(source, dest);
  798         dest = SLOT(fslabel);
  799         mac_mls_copy_single(source, dest);
  800 }
  801 
  802 static void
  803 mac_mls_create_root_mount(struct ucred *cred, struct mount *mp,
  804     struct label *mntlabel, struct label *fslabel)
  805 {
  806         struct mac_mls *mac_mls;
  807 
  808         /* Always mount root as high integrity. */
  809         mac_mls = SLOT(fslabel);
  810         mac_mls_set_single(mac_mls, MAC_MLS_TYPE_LOW, 0, NULL);
  811         mac_mls = SLOT(mntlabel);
  812         mac_mls_set_single(mac_mls, MAC_MLS_TYPE_LOW, 0, NULL);
  813 }
  814 
  815 static void
  816 mac_mls_relabel_vnode(struct ucred *cred, struct vnode *vp,
  817     struct label *vnodelabel, struct label *label)
  818 {
  819         struct mac_mls *source, *dest;
  820 
  821         source = SLOT(label);
  822         dest = SLOT(vnodelabel);
  823 
  824         mac_mls_copy(source, dest);
  825 }
  826 
  827 static void
  828 mac_mls_update_devfsdirent(struct mount *mp,
  829     struct devfs_dirent *devfs_dirent, struct label *direntlabel,
  830     struct vnode *vp, struct label *vnodelabel)
  831 {
  832         struct mac_mls *source, *dest;
  833 
  834         source = SLOT(vnodelabel);
  835         dest = SLOT(direntlabel);
  836 
  837         mac_mls_copy_single(source, dest);
  838 }
  839 
  840 static void
  841 mac_mls_associate_vnode_devfs(struct mount *mp, struct label *fslabel,
  842     struct devfs_dirent *de, struct label *delabel, struct vnode *vp,
  843     struct label *vlabel)
  844 {
  845         struct mac_mls *source, *dest;
  846 
  847         source = SLOT(delabel);
  848         dest = SLOT(vlabel);
  849 
  850         mac_mls_copy_single(source, dest);
  851 }
  852 
  853 static int
  854 mac_mls_associate_vnode_extattr(struct mount *mp, struct label *fslabel,
  855     struct vnode *vp, struct label *vlabel)
  856 {
  857         struct mac_mls temp, *source, *dest;
  858         int buflen, error;
  859 
  860         source = SLOT(fslabel);
  861         dest = SLOT(vlabel);
  862 
  863         buflen = sizeof(temp);
  864         bzero(&temp, buflen);
  865 
  866         error = vn_extattr_get(vp, IO_NODELOCKED, MAC_MLS_EXTATTR_NAMESPACE,
  867             MAC_MLS_EXTATTR_NAME, &buflen, (char *) &temp, curthread);
  868         if (error == ENOATTR || error == EOPNOTSUPP) {
  869                 /* Fall back to the fslabel. */
  870                 mac_mls_copy_single(source, dest);
  871                 return (0);
  872         } else if (error)
  873                 return (error);
  874 
  875         if (buflen != sizeof(temp)) {
  876                 printf("mac_mls_associate_vnode_extattr: bad size %d\n",
  877                     buflen);
  878                 return (EPERM);
  879         }
  880         if (mac_mls_valid(&temp) != 0) {
  881                 printf("mac_mls_associate_vnode_extattr: invalid\n");
  882                 return (EPERM);
  883         }
  884         if ((temp.mm_flags & MAC_MLS_FLAGS_BOTH) != MAC_MLS_FLAG_SINGLE) {
  885                 printf("mac_mls_associated_vnode_extattr: not single\n");
  886                 return (EPERM);
  887         }
  888 
  889         mac_mls_copy_single(&temp, dest);
  890         return (0);
  891 }
  892 
  893 static void
  894 mac_mls_associate_vnode_singlelabel(struct mount *mp,
  895     struct label *fslabel, struct vnode *vp, struct label *vlabel)
  896 {
  897         struct mac_mls *source, *dest;
  898 
  899         source = SLOT(fslabel);
  900         dest = SLOT(vlabel);
  901 
  902         mac_mls_copy_single(source, dest);
  903 }
  904 
  905 static int
  906 mac_mls_create_vnode_extattr(struct ucred *cred, struct mount *mp,
  907     struct label *fslabel, struct vnode *dvp, struct label *dlabel,
  908     struct vnode *vp, struct label *vlabel, struct componentname *cnp)
  909 {
  910         struct mac_mls *source, *dest, temp;
  911         size_t buflen;
  912         int error;
  913 
  914         buflen = sizeof(temp);
  915         bzero(&temp, buflen);
  916 
  917         source = SLOT(cred->cr_label);
  918         dest = SLOT(vlabel);
  919         mac_mls_copy_single(source, &temp);
  920 
  921         error = vn_extattr_set(vp, IO_NODELOCKED, MAC_MLS_EXTATTR_NAMESPACE,
  922             MAC_MLS_EXTATTR_NAME, buflen, (char *) &temp, curthread);
  923         if (error == 0)
  924                 mac_mls_copy_single(source, dest);
  925         return (error);
  926 }
  927 
  928 static int
  929 mac_mls_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp,
  930     struct label *vlabel, struct label *intlabel)
  931 {
  932         struct mac_mls *source, temp;
  933         size_t buflen;
  934         int error;
  935 
  936         buflen = sizeof(temp);
  937         bzero(&temp, buflen);
  938 
  939         source = SLOT(intlabel);
  940         if ((source->mm_flags & MAC_MLS_FLAG_SINGLE) == 0)
  941                 return (0);
  942 
  943         mac_mls_copy_single(source, &temp);
  944 
  945         error = vn_extattr_set(vp, IO_NODELOCKED, MAC_MLS_EXTATTR_NAMESPACE,
  946             MAC_MLS_EXTATTR_NAME, buflen, (char *) &temp, curthread);
  947         return (error);
  948 }
  949 
  950 /*
  951  * Labeling event operations: IPC object.
  952  */
  953 static void
  954 mac_mls_create_inpcb_from_socket(struct socket *so, struct label *solabel,
  955     struct inpcb *inp, struct label *inplabel)
  956 {
  957         struct mac_mls *source, *dest;
  958 
  959         source = SLOT(solabel);
  960         dest = SLOT(inplabel);
  961 
  962         mac_mls_copy_single(source, dest);
  963 }
  964 
  965 static void
  966 mac_mls_create_mbuf_from_socket(struct socket *so, struct label *socketlabel,
  967     struct mbuf *m, struct label *mbuflabel)
  968 {
  969         struct mac_mls *source, *dest;
  970 
  971         source = SLOT(socketlabel);
  972         dest = SLOT(mbuflabel);
  973 
  974         mac_mls_copy_single(source, dest);
  975 }
  976 
  977 static void
  978 mac_mls_create_socket(struct ucred *cred, struct socket *socket,
  979     struct label *socketlabel)
  980 {
  981         struct mac_mls *source, *dest;
  982 
  983         source = SLOT(cred->cr_label);
  984         dest = SLOT(socketlabel);
  985 
  986         mac_mls_copy_single(source, dest);
  987 }
  988 
  989 static void
  990 mac_mls_create_pipe(struct ucred *cred, struct pipe *pipe,
  991     struct label *pipelabel)
  992 {
  993         struct mac_mls *source, *dest;
  994 
  995         source = SLOT(cred->cr_label);
  996         dest = SLOT(pipelabel);
  997 
  998         mac_mls_copy_single(source, dest);
  999 }
 1000 
 1001 static void
 1002 mac_mls_create_socket_from_socket(struct socket *oldsocket,
 1003     struct label *oldsocketlabel, struct socket *newsocket,
 1004     struct label *newsocketlabel)
 1005 {
 1006         struct mac_mls *source, *dest;
 1007 
 1008         source = SLOT(oldsocketlabel);
 1009         dest = SLOT(newsocketlabel);
 1010 
 1011         mac_mls_copy_single(source, dest);
 1012 }
 1013 
 1014 static void
 1015 mac_mls_relabel_socket(struct ucred *cred, struct socket *socket,
 1016     struct label *socketlabel, struct label *newlabel)
 1017 {
 1018         struct mac_mls *source, *dest;
 1019 
 1020         source = SLOT(newlabel);
 1021         dest = SLOT(socketlabel);
 1022 
 1023         mac_mls_copy(source, dest);
 1024 }
 1025 
 1026 static void
 1027 mac_mls_relabel_pipe(struct ucred *cred, struct pipe *pipe,
 1028     struct label *pipelabel, struct label *newlabel)
 1029 {
 1030         struct mac_mls *source, *dest;
 1031 
 1032         source = SLOT(newlabel);
 1033         dest = SLOT(pipelabel);
 1034 
 1035         mac_mls_copy(source, dest);
 1036 }
 1037 
 1038 static void
 1039 mac_mls_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel,
 1040     struct socket *socket, struct label *socketpeerlabel)
 1041 {
 1042         struct mac_mls *source, *dest;
 1043 
 1044         source = SLOT(mbuflabel);
 1045         dest = SLOT(socketpeerlabel);
 1046 
 1047         mac_mls_copy_single(source, dest);
 1048 }
 1049 
 1050 /*
 1051  * Labeling event operations: network objects.
 1052  */
 1053 static void
 1054 mac_mls_set_socket_peer_from_socket(struct socket *oldsocket,
 1055     struct label *oldsocketlabel, struct socket *newsocket,
 1056     struct label *newsocketpeerlabel)
 1057 {
 1058         struct mac_mls *source, *dest;
 1059 
 1060         source = SLOT(oldsocketlabel);
 1061         dest = SLOT(newsocketpeerlabel);
 1062 
 1063         mac_mls_copy_single(source, dest);
 1064 }
 1065 
 1066 static void
 1067 mac_mls_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d,
 1068     struct label *bpflabel)
 1069 {
 1070         struct mac_mls *source, *dest;
 1071 
 1072         source = SLOT(cred->cr_label);
 1073         dest = SLOT(bpflabel);
 1074 
 1075         mac_mls_copy_single(source, dest);
 1076 }
 1077 
 1078 static void
 1079 mac_mls_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel)
 1080 {
 1081         struct mac_mls *dest;
 1082         int type;
 1083 
 1084         dest = SLOT(ifnetlabel);
 1085 
 1086         if (ifnet->if_type == IFT_LOOP)
 1087                 type = MAC_MLS_TYPE_EQUAL;
 1088         else
 1089                 type = MAC_MLS_TYPE_LOW;
 1090 
 1091         mac_mls_set_single(dest, type, 0, NULL);
 1092         mac_mls_set_range(dest, type, 0, NULL, type, 0, NULL);
 1093 }
 1094 
 1095 static void
 1096 mac_mls_create_ipq(struct mbuf *fragment, struct label *fragmentlabel,
 1097     struct ipq *ipq, struct label *ipqlabel)
 1098 {
 1099         struct mac_mls *source, *dest;
 1100 
 1101         source = SLOT(fragmentlabel);
 1102         dest = SLOT(ipqlabel);
 1103 
 1104         mac_mls_copy_single(source, dest);
 1105 }
 1106 
 1107 static void
 1108 mac_mls_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel,
 1109     struct mbuf *datagram, struct label *datagramlabel)
 1110 {
 1111         struct mac_mls *source, *dest;
 1112 
 1113         source = SLOT(ipqlabel);
 1114         dest = SLOT(datagramlabel);
 1115 
 1116         /* Just use the head, since we require them all to match. */
 1117         mac_mls_copy_single(source, dest);
 1118 }
 1119 
 1120 static void
 1121 mac_mls_create_fragment(struct mbuf *datagram, struct label *datagramlabel,
 1122     struct mbuf *fragment, struct label *fragmentlabel)
 1123 {
 1124         struct mac_mls *source, *dest;
 1125 
 1126         source = SLOT(datagramlabel);
 1127         dest = SLOT(fragmentlabel);
 1128 
 1129         mac_mls_copy_single(source, dest);
 1130 }
 1131 
 1132 static void
 1133 mac_mls_create_mbuf_from_mbuf(struct mbuf *oldmbuf,
 1134     struct label *oldmbuflabel, struct mbuf *newmbuf,
 1135     struct label *newmbuflabel)
 1136 {
 1137         struct mac_mls *source, *dest;
 1138 
 1139         source = SLOT(oldmbuflabel);
 1140         dest = SLOT(newmbuflabel);
 1141 
 1142         /*
 1143          * Because the source mbuf may not yet have been "created",
 1144          * just initialized, we do a conditional copy.  Since we don't
 1145          * allow mbufs to have ranges, do a KASSERT to make sure that
 1146          * doesn't happen.
 1147          */
 1148         KASSERT((source->mm_flags & MAC_MLS_FLAG_RANGE) == 0,
 1149             ("mac_mls_create_mbuf_from_mbuf: source mbuf has range"));
 1150         mac_mls_copy(source, dest);
 1151 }
 1152 
 1153 static void
 1154 mac_mls_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel,
 1155     struct mbuf *mbuf, struct label *mbuflabel)
 1156 {
 1157         struct mac_mls *dest;
 1158 
 1159         dest = SLOT(mbuflabel);
 1160 
 1161         mac_mls_set_single(dest, MAC_MLS_TYPE_EQUAL, 0, NULL);
 1162 }
 1163 
 1164 static void
 1165 mac_mls_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel,
 1166     struct mbuf *mbuf, struct label *mbuflabel)
 1167 {
 1168         struct mac_mls *source, *dest;
 1169 
 1170         source = SLOT(bpflabel);
 1171         dest = SLOT(mbuflabel);
 1172 
 1173         mac_mls_copy_single(source, dest);
 1174 }
 1175 
 1176 static void
 1177 mac_mls_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel,
 1178     struct mbuf *m, struct label *mbuflabel)
 1179 {
 1180         struct mac_mls *source, *dest;
 1181 
 1182         source = SLOT(ifnetlabel);
 1183         dest = SLOT(mbuflabel);
 1184 
 1185         mac_mls_copy_single(source, dest);
 1186 }
 1187 
 1188 static void
 1189 mac_mls_create_mbuf_multicast_encap(struct mbuf *oldmbuf,
 1190     struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel,
 1191     struct mbuf *newmbuf, struct label *newmbuflabel)
 1192 {
 1193         struct mac_mls *source, *dest;
 1194 
 1195         source = SLOT(oldmbuflabel);
 1196         dest = SLOT(newmbuflabel);
 1197 
 1198         mac_mls_copy_single(source, dest);
 1199 }
 1200 
 1201 static void
 1202 mac_mls_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel,
 1203     struct mbuf *newmbuf, struct label *newmbuflabel)
 1204 {
 1205         struct mac_mls *source, *dest;
 1206 
 1207         source = SLOT(oldmbuflabel);
 1208         dest = SLOT(newmbuflabel);
 1209 
 1210         mac_mls_copy_single(source, dest);
 1211 }
 1212 
 1213 static int
 1214 mac_mls_fragment_match(struct mbuf *fragment, struct label *fragmentlabel,
 1215     struct ipq *ipq, struct label *ipqlabel)
 1216 {
 1217         struct mac_mls *a, *b;
 1218 
 1219         a = SLOT(ipqlabel);
 1220         b = SLOT(fragmentlabel);
 1221 
 1222         return (mac_mls_equal_single(a, b));
 1223 }
 1224 
 1225 static void
 1226 mac_mls_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet,
 1227     struct label *ifnetlabel, struct label *newlabel)
 1228 {
 1229         struct mac_mls *source, *dest;
 1230 
 1231         source = SLOT(newlabel);
 1232         dest = SLOT(ifnetlabel);
 1233 
 1234         mac_mls_copy(source, dest);
 1235 }
 1236 
 1237 static void
 1238 mac_mls_update_ipq(struct mbuf *fragment, struct label *fragmentlabel,
 1239     struct ipq *ipq, struct label *ipqlabel)
 1240 {
 1241 
 1242         /* NOOP: we only accept matching labels, so no need to update */
 1243 }
 1244 
 1245 static void
 1246 mac_mls_inpcb_sosetlabel(struct socket *so, struct label *solabel,
 1247     struct inpcb *inp, struct label *inplabel)
 1248 {
 1249         struct mac_mls *source, *dest;
 1250 
 1251         source = SLOT(solabel);
 1252         dest = SLOT(inplabel);
 1253 
 1254         mac_mls_copy(source, dest);
 1255 }
 1256 
 1257 /*
 1258  * Labeling event operations: processes.
 1259  */
 1260 static void
 1261 mac_mls_create_proc0(struct ucred *cred)
 1262 {
 1263         struct mac_mls *dest;
 1264 
 1265         dest = SLOT(cred->cr_label);
 1266 
 1267         mac_mls_set_single(dest, MAC_MLS_TYPE_EQUAL, 0, NULL);
 1268         mac_mls_set_range(dest, MAC_MLS_TYPE_LOW, 0, NULL, MAC_MLS_TYPE_HIGH,
 1269             0, NULL);
 1270 }
 1271 
 1272 static void
 1273 mac_mls_create_proc1(struct ucred *cred)
 1274 {
 1275         struct mac_mls *dest;
 1276 
 1277         dest = SLOT(cred->cr_label);
 1278 
 1279         mac_mls_set_single(dest, MAC_MLS_TYPE_LOW, 0, NULL);
 1280         mac_mls_set_range(dest, MAC_MLS_TYPE_LOW, 0, NULL, MAC_MLS_TYPE_HIGH,
 1281             0, NULL);
 1282 }
 1283 
 1284 static void
 1285 mac_mls_relabel_cred(struct ucred *cred, struct label *newlabel)
 1286 {
 1287         struct mac_mls *source, *dest;
 1288 
 1289         source = SLOT(newlabel);
 1290         dest = SLOT(cred->cr_label);
 1291 
 1292         mac_mls_copy(source, dest);
 1293 }
 1294 
 1295 /*
 1296  * Access control checks.
 1297  */
 1298 static int
 1299 mac_mls_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel,
 1300      struct ifnet *ifnet, struct label *ifnetlabel)
 1301 {
 1302         struct mac_mls *a, *b;
 1303 
 1304         if (!mac_mls_enabled)
 1305                 return (0);
 1306 
 1307         a = SLOT(bpflabel);
 1308         b = SLOT(ifnetlabel);
 1309 
 1310         if (mac_mls_equal_single(a, b))
 1311                 return (0);
 1312         return (EACCES);
 1313 }
 1314 
 1315 static int
 1316 mac_mls_check_cred_relabel(struct ucred *cred, struct label *newlabel)
 1317 {
 1318         struct mac_mls *subj, *new;
 1319         int error;
 1320 
 1321         subj = SLOT(cred->cr_label);
 1322         new = SLOT(newlabel);
 1323 
 1324         /*
 1325          * If there is an MLS label update for the credential, it may be
 1326          * an update of single, range, or both.
 1327          */
 1328         error = mls_atmostflags(new, MAC_MLS_FLAGS_BOTH);
 1329         if (error)
 1330                 return (error);
 1331 
 1332         /*
 1333          * If the MLS label is to be changed, authorize as appropriate.
 1334          */
 1335         if (new->mm_flags & MAC_MLS_FLAGS_BOTH) {
 1336                 /*
 1337                  * If the change request modifies both the MLS label single
 1338                  * and range, check that the new single will be in the
 1339                  * new range.
 1340                  */
 1341                 if ((new->mm_flags & MAC_MLS_FLAGS_BOTH) ==
 1342                     MAC_MLS_FLAGS_BOTH &&
 1343                     !mac_mls_single_in_range(new, new))
 1344                         return (EINVAL);
 1345 
 1346                 /*
 1347                  * To change the MLS single label on a credential, the
 1348                  * new single label must be in the current range.
 1349                  */
 1350                 if (new->mm_flags & MAC_MLS_FLAG_SINGLE &&
 1351                     !mac_mls_single_in_range(new, subj))
 1352                         return (EPERM);
 1353 
 1354                 /*
 1355                  * To change the MLS range label on a credential, the
 1356                  * new range must be in the current range.
 1357                  */
 1358                 if (new->mm_flags & MAC_MLS_FLAG_RANGE &&
 1359                     !mac_mls_range_in_range(new, subj))
 1360                         return (EPERM);
 1361 
 1362                 /*
 1363                  * To have EQUAL in any component of the new credential
 1364                  * MLS label, the subject must already have EQUAL in
 1365                  * their label.
 1366                  */
 1367                 if (mac_mls_contains_equal(new)) {
 1368                         error = mac_mls_subject_privileged(subj);
 1369                         if (error)
 1370                                 return (error);
 1371                 }
 1372         }
 1373 
 1374         return (0);
 1375 }
 1376 
 1377 static int
 1378 mac_mls_check_cred_visible(struct ucred *u1, struct ucred *u2)
 1379 {
 1380         struct mac_mls *subj, *obj;
 1381 
 1382         if (!mac_mls_enabled)
 1383                 return (0);
 1384 
 1385         subj = SLOT(u1->cr_label);
 1386         obj = SLOT(u2->cr_label);
 1387 
 1388         /* XXX: range */
 1389         if (!mac_mls_dominate_single(subj, obj))
 1390                 return (ESRCH);
 1391 
 1392         return (0);
 1393 }
 1394 
 1395 static int
 1396 mac_mls_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet,
 1397     struct label *ifnetlabel, struct label *newlabel)
 1398 {
 1399         struct mac_mls *subj, *new;
 1400         int error;
 1401 
 1402         subj = SLOT(cred->cr_label);
 1403         new = SLOT(newlabel);
 1404 
 1405         /*
 1406          * If there is an MLS label update for the interface, it may
 1407          * be an update of single, range, or both.
 1408          */
 1409         error = mls_atmostflags(new, MAC_MLS_FLAGS_BOTH);
 1410         if (error)
 1411                 return (error);
 1412 
 1413         /*
 1414          * Relabeling network interfaces requires MLS privilege.
 1415          */
 1416         error = mac_mls_subject_privileged(subj);
 1417 
 1418         return (0);
 1419 }
 1420 
 1421 static int
 1422 mac_mls_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel,
 1423     struct mbuf *m, struct label *mbuflabel)
 1424 {
 1425         struct mac_mls *p, *i;
 1426 
 1427         if (!mac_mls_enabled)
 1428                 return (0);
 1429 
 1430         p = SLOT(mbuflabel);
 1431         i = SLOT(ifnetlabel);
 1432 
 1433         return (mac_mls_single_in_range(p, i) ? 0 : EACCES);
 1434 }
 1435 
 1436 static int
 1437 mac_mls_check_inpcb_deliver(struct inpcb *inp, struct label *inplabel,
 1438     struct mbuf *m, struct label *mlabel)
 1439 {
 1440         struct mac_mls *p, *i;
 1441 
 1442         if (!mac_mls_enabled)
 1443                 return (0);
 1444 
 1445         p = SLOT(mlabel);
 1446         i = SLOT(inplabel);
 1447 
 1448         return (mac_mls_equal_single(p, i) ? 0 : EACCES);
 1449 }
 1450 
 1451 static int
 1452 mac_mls_check_mount_stat(struct ucred *cred, struct mount *mp,
 1453     struct label *mntlabel)
 1454 {
 1455         struct mac_mls *subj, *obj;
 1456 
 1457         if (!mac_mls_enabled)
 1458                 return (0);
 1459 
 1460         subj = SLOT(cred->cr_label);
 1461         obj = SLOT(mntlabel);
 1462 
 1463         if (!mac_mls_dominate_single(subj, obj))
 1464                 return (EACCES);
 1465 
 1466         return (0);
 1467 }
 1468 
 1469 static int
 1470 mac_mls_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe,
 1471     struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data)
 1472 {
 1473 
 1474         if(!mac_mls_enabled)
 1475                 return (0);
 1476 
 1477         /* XXX: This will be implemented soon... */
 1478 
 1479         return (0);
 1480 }
 1481 
 1482 static int
 1483 mac_mls_check_pipe_poll(struct ucred *cred, struct pipe *pipe,
 1484     struct label *pipelabel)
 1485 {
 1486         struct mac_mls *subj, *obj;
 1487 
 1488         if (!mac_mls_enabled)
 1489                 return (0);
 1490 
 1491         subj = SLOT(cred->cr_label);
 1492         obj = SLOT((pipelabel));
 1493 
 1494         if (!mac_mls_dominate_single(subj, obj))
 1495                 return (EACCES);
 1496 
 1497         return (0);
 1498 }
 1499 
 1500 static int
 1501 mac_mls_check_pipe_read(struct ucred *cred, struct pipe *pipe,
 1502     struct label *pipelabel)
 1503 {
 1504         struct mac_mls *subj, *obj;
 1505 
 1506         if (!mac_mls_enabled)
 1507                 return (0);
 1508 
 1509         subj = SLOT(cred->cr_label);
 1510         obj = SLOT((pipelabel));
 1511 
 1512         if (!mac_mls_dominate_single(subj, obj))
 1513                 return (EACCES);
 1514 
 1515         return (0);
 1516 }
 1517 
 1518 static int
 1519 mac_mls_check_pipe_relabel(struct ucred *cred, struct pipe *pipe,
 1520     struct label *pipelabel, struct label *newlabel)
 1521 {
 1522         struct mac_mls *subj, *obj, *new;
 1523         int error;
 1524 
 1525         new = SLOT(newlabel);
 1526         subj = SLOT(cred->cr_label);
 1527         obj = SLOT(pipelabel);
 1528 
 1529         /*
 1530          * If there is an MLS label update for a pipe, it must be a
 1531          * single update.
 1532          */
 1533         error = mls_atmostflags(new, MAC_MLS_FLAG_SINGLE);
 1534         if (error)
 1535                 return (error);
 1536 
 1537         /*
 1538          * To perform a relabel of a pipe (MLS label or not), MLS must
 1539          * authorize the relabel.
 1540          */
 1541         if (!mac_mls_single_in_range(obj, subj))
 1542                 return (EPERM);
 1543 
 1544         /*
 1545          * If the MLS label is to be changed, authorize as appropriate.
 1546          */
 1547         if (new->mm_flags & MAC_MLS_FLAG_SINGLE) {
 1548                 /*
 1549                  * To change the MLS label on a pipe, the new pipe label
 1550                  * must be in the subject range.
 1551                  */
 1552                 if (!mac_mls_single_in_range(new, subj))
 1553                         return (EPERM);
 1554 
 1555                 /*
 1556                  * To change the MLS label on a pipe to be EQUAL, the
 1557                  * subject must have appropriate privilege.
 1558                  */
 1559                 if (mac_mls_contains_equal(new)) {
 1560                         error = mac_mls_subject_privileged(subj);
 1561                         if (error)
 1562                                 return (error);
 1563                 }
 1564         }
 1565 
 1566         return (0);
 1567 }
 1568 
 1569 static int
 1570 mac_mls_check_pipe_stat(struct ucred *cred, struct pipe *pipe,
 1571     struct label *pipelabel)
 1572 {
 1573         struct mac_mls *subj, *obj;
 1574 
 1575         if (!mac_mls_enabled)
 1576                 return (0);
 1577 
 1578         subj = SLOT(cred->cr_label);
 1579         obj = SLOT((pipelabel));
 1580 
 1581         if (!mac_mls_dominate_single(subj, obj))
 1582                 return (EACCES);
 1583 
 1584         return (0);
 1585 }
 1586 
 1587 static int
 1588 mac_mls_check_pipe_write(struct ucred *cred, struct pipe *pipe,
 1589     struct label *pipelabel)
 1590 {
 1591         struct mac_mls *subj, *obj;
 1592 
 1593         if (!mac_mls_enabled)
 1594                 return (0);
 1595 
 1596         subj = SLOT(cred->cr_label);
 1597         obj = SLOT((pipelabel));
 1598 
 1599         if (!mac_mls_dominate_single(obj, subj))
 1600                 return (EACCES);
 1601 
 1602         return (0);
 1603 }
 1604 
 1605 static int
 1606 mac_mls_check_proc_debug(struct ucred *cred, struct proc *proc)
 1607 {
 1608         struct mac_mls *subj, *obj;
 1609 
 1610         if (!mac_mls_enabled)
 1611                 return (0);
 1612 
 1613         subj = SLOT(cred->cr_label);
 1614         obj = SLOT(proc->p_ucred->cr_label);
 1615 
 1616         /* XXX: range checks */
 1617         if (!mac_mls_dominate_single(subj, obj))
 1618                 return (ESRCH);
 1619         if (!mac_mls_dominate_single(obj, subj))
 1620                 return (EACCES);
 1621 
 1622         return (0);
 1623 }
 1624 
 1625 static int
 1626 mac_mls_check_proc_sched(struct ucred *cred, struct proc *proc)
 1627 {
 1628         struct mac_mls *subj, *obj;
 1629 
 1630         if (!mac_mls_enabled)
 1631                 return (0);
 1632 
 1633         subj = SLOT(cred->cr_label);
 1634         obj = SLOT(proc->p_ucred->cr_label);
 1635 
 1636         /* XXX: range checks */
 1637         if (!mac_mls_dominate_single(subj, obj))
 1638                 return (ESRCH);
 1639         if (!mac_mls_dominate_single(obj, subj))
 1640                 return (EACCES);
 1641 
 1642         return (0);
 1643 }
 1644 
 1645 static int
 1646 mac_mls_check_proc_signal(struct ucred *cred, struct proc *proc, int signum)
 1647 {
 1648         struct mac_mls *subj, *obj;
 1649 
 1650         if (!mac_mls_enabled)
 1651                 return (0);
 1652 
 1653         subj = SLOT(cred->cr_label);
 1654         obj = SLOT(proc->p_ucred->cr_label);
 1655 
 1656         /* XXX: range checks */
 1657         if (!mac_mls_dominate_single(subj, obj))
 1658                 return (ESRCH);
 1659         if (!mac_mls_dominate_single(obj, subj))
 1660                 return (EACCES);
 1661 
 1662         return (0);
 1663 }
 1664 
 1665 static int
 1666 mac_mls_check_socket_deliver(struct socket *so, struct label *socketlabel,
 1667     struct mbuf *m, struct label *mbuflabel)
 1668 {
 1669         struct mac_mls *p, *s;
 1670 
 1671         if (!mac_mls_enabled)
 1672                 return (0);
 1673 
 1674         p = SLOT(mbuflabel);
 1675         s = SLOT(socketlabel);
 1676 
 1677         return (mac_mls_equal_single(p, s) ? 0 : EACCES);
 1678 }
 1679 
 1680 static int
 1681 mac_mls_check_socket_relabel(struct ucred *cred, struct socket *socket,
 1682     struct label *socketlabel, struct label *newlabel)
 1683 {
 1684         struct mac_mls *subj, *obj, *new;
 1685         int error;
 1686 
 1687         new = SLOT(newlabel);
 1688         subj = SLOT(cred->cr_label);
 1689         obj = SLOT(socketlabel);
 1690 
 1691         /*
 1692          * If there is an MLS label update for the socket, it may be
 1693          * an update of single.
 1694          */
 1695         error = mls_atmostflags(new, MAC_MLS_FLAG_SINGLE);
 1696         if (error)
 1697                 return (error);
 1698 
 1699         /*
 1700          * To relabel a socket, the old socket single must be in the subject
 1701          * range.
 1702          */
 1703         if (!mac_mls_single_in_range(obj, subj))
 1704                 return (EPERM);
 1705 
 1706         /*
 1707          * If the MLS label is to be changed, authorize as appropriate.
 1708          */
 1709         if (new->mm_flags & MAC_MLS_FLAG_SINGLE) {
 1710                 /*
 1711                  * To relabel a socket, the new socket single must be in
 1712                  * the subject range.
 1713                  */
 1714                 if (!mac_mls_single_in_range(new, subj))
 1715                         return (EPERM);
 1716 
 1717                 /*
 1718                  * To change the MLS label on the socket to contain EQUAL,
 1719                  * the subject must have appropriate privilege.
 1720                  */
 1721                 if (mac_mls_contains_equal(new)) {
 1722                         error = mac_mls_subject_privileged(subj);
 1723                         if (error)
 1724                                 return (error);
 1725                 }
 1726         }
 1727 
 1728         return (0);
 1729 }
 1730 
 1731 static int
 1732 mac_mls_check_socket_visible(struct ucred *cred, struct socket *socket,
 1733     struct label *socketlabel)
 1734 {
 1735         struct mac_mls *subj, *obj;
 1736 
 1737         if (!mac_mls_enabled)
 1738                 return (0);
 1739 
 1740         subj = SLOT(cred->cr_label);
 1741         obj = SLOT(socketlabel);
 1742 
 1743         if (!mac_mls_dominate_single(subj, obj))
 1744                 return (ENOENT);
 1745 
 1746         return (0);
 1747 }
 1748 
 1749 static int
 1750 mac_mls_check_system_swapon(struct ucred *cred, struct vnode *vp,
 1751     struct label *label)
 1752 {
 1753         struct mac_mls *subj, *obj;
 1754 
 1755         if (!mac_mls_enabled)
 1756                 return (0);
 1757 
 1758         subj = SLOT(cred->cr_label);
 1759         obj = SLOT(label);
 1760 
 1761         if (!mac_mls_dominate_single(obj, subj) ||
 1762             !mac_mls_dominate_single(subj, obj))
 1763                 return (EACCES);
 1764 
 1765         return (0);
 1766 }
 1767 
 1768 static int
 1769 mac_mls_check_vnode_chdir(struct ucred *cred, struct vnode *dvp,
 1770     struct label *dlabel)
 1771 {
 1772         struct mac_mls *subj, *obj;
 1773 
 1774         if (!mac_mls_enabled)
 1775                 return (0);
 1776 
 1777         subj = SLOT(cred->cr_label);
 1778         obj = SLOT(dlabel);
 1779 
 1780         if (!mac_mls_dominate_single(subj, obj))
 1781                 return (EACCES);
 1782 
 1783         return (0);
 1784 }
 1785 
 1786 static int
 1787 mac_mls_check_vnode_chroot(struct ucred *cred, struct vnode *dvp,
 1788     struct label *dlabel)
 1789 {
 1790         struct mac_mls *subj, *obj;
 1791 
 1792         if (!mac_mls_enabled)
 1793                 return (0);
 1794 
 1795         subj = SLOT(cred->cr_label);
 1796         obj = SLOT(dlabel);
 1797 
 1798         if (!mac_mls_dominate_single(subj, obj))
 1799                 return (EACCES);
 1800 
 1801         return (0);
 1802 }
 1803 
 1804 static int
 1805 mac_mls_check_vnode_create(struct ucred *cred, struct vnode *dvp,
 1806     struct label *dlabel, struct componentname *cnp, struct vattr *vap)
 1807 {
 1808         struct mac_mls *subj, *obj;
 1809 
 1810         if (!mac_mls_enabled)
 1811                 return (0);
 1812 
 1813         subj = SLOT(cred->cr_label);
 1814         obj = SLOT(dlabel);
 1815 
 1816         if (!mac_mls_dominate_single(obj, subj))
 1817                 return (EACCES);
 1818 
 1819         return (0);
 1820 }
 1821 
 1822 static int
 1823 mac_mls_check_vnode_delete(struct ucred *cred, struct vnode *dvp,
 1824     struct label *dlabel, struct vnode *vp, struct label *label,
 1825     struct componentname *cnp)
 1826 {
 1827         struct mac_mls *subj, *obj;
 1828 
 1829         if (!mac_mls_enabled)
 1830                 return (0);
 1831 
 1832         subj = SLOT(cred->cr_label);
 1833         obj = SLOT(dlabel);
 1834 
 1835         if (!mac_mls_dominate_single(obj, subj))
 1836                 return (EACCES);
 1837 
 1838         obj = SLOT(label);
 1839 
 1840         if (!mac_mls_dominate_single(obj, subj))
 1841                 return (EACCES);
 1842 
 1843         return (0);
 1844 }
 1845 
 1846 static int
 1847 mac_mls_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
 1848     struct label *label, acl_type_t type)
 1849 {
 1850         struct mac_mls *subj, *obj;
 1851 
 1852         if (!mac_mls_enabled)
 1853                 return (0);
 1854 
 1855         subj = SLOT(cred->cr_label);
 1856         obj = SLOT(label);
 1857 
 1858         if (!mac_mls_dominate_single(obj, subj))
 1859                 return (EACCES);
 1860 
 1861         return (0);
 1862 }
 1863 
 1864 static int
 1865 mac_mls_check_vnode_deleteextattr(struct ucred *cred, struct vnode *vp,
 1866     struct label *label, int attrnamespace, const char *name)
 1867 {
 1868         struct mac_mls *subj, *obj;
 1869 
 1870         if (!mac_mls_enabled)
 1871                 return (0);
 1872 
 1873         subj = SLOT(cred->cr_label);
 1874         obj = SLOT(label);
 1875 
 1876         if (!mac_mls_dominate_single(obj, subj))
 1877                 return (EACCES);
 1878 
 1879         return (0);
 1880 }
 1881 
 1882 static int
 1883 mac_mls_check_vnode_exec(struct ucred *cred, struct vnode *vp,
 1884     struct label *label, struct image_params *imgp,
 1885     struct label *execlabel)
 1886 {
 1887         struct mac_mls *subj, *obj, *exec;
 1888         int error;
 1889 
 1890         if (execlabel != NULL) {
 1891                 /*
 1892                  * We currently don't permit labels to be changed at
 1893                  * exec-time as part of MLS, so disallow non-NULL
 1894                  * MLS label elements in the execlabel.
 1895                  */
 1896                 exec = SLOT(execlabel);
 1897                 error = mls_atmostflags(exec, 0);
 1898                 if (error)
 1899                         return (error);
 1900         }
 1901 
 1902         if (!mac_mls_enabled)
 1903                 return (0);
 1904 
 1905         subj = SLOT(cred->cr_label);
 1906         obj = SLOT(label);
 1907 
 1908         if (!mac_mls_dominate_single(subj, obj))
 1909                 return (EACCES);
 1910 
 1911         return (0);
 1912 }
 1913 
 1914 static int
 1915 mac_mls_check_vnode_getacl(struct ucred *cred, struct vnode *vp,
 1916     struct label *label, acl_type_t type)
 1917 {
 1918         struct mac_mls *subj, *obj;
 1919 
 1920         if (!mac_mls_enabled)
 1921                 return (0);
 1922 
 1923         subj = SLOT(cred->cr_label);
 1924         obj = SLOT(label);
 1925 
 1926         if (!mac_mls_dominate_single(subj, obj))
 1927                 return (EACCES);
 1928 
 1929         return (0);
 1930 }
 1931 
 1932 static int
 1933 mac_mls_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
 1934     struct label *label, int attrnamespace, const char *name, struct uio *uio)
 1935 {
 1936         struct mac_mls *subj, *obj;
 1937 
 1938         if (!mac_mls_enabled)
 1939                 return (0);
 1940 
 1941         subj = SLOT(cred->cr_label);
 1942         obj = SLOT(label);
 1943 
 1944         if (!mac_mls_dominate_single(subj, obj))
 1945                 return (EACCES);
 1946 
 1947         return (0);
 1948 }
 1949 
 1950 static int
 1951 mac_mls_check_vnode_link(struct ucred *cred, struct vnode *dvp,
 1952     struct label *dlabel, struct vnode *vp, struct label *label,
 1953     struct componentname *cnp)
 1954 {
 1955         struct mac_mls *subj, *obj;
 1956 
 1957         if (!mac_mls_enabled)
 1958                 return (0);
 1959 
 1960         subj = SLOT(cred->cr_label);
 1961         obj = SLOT(dlabel);
 1962 
 1963         if (!mac_mls_dominate_single(obj, subj))
 1964                 return (EACCES);
 1965 
 1966         obj = SLOT(dlabel);
 1967         if (!mac_mls_dominate_single(obj, subj))
 1968                 return (EACCES);
 1969 
 1970         return (0);
 1971 }
 1972 
 1973 static int
 1974 mac_mls_check_vnode_listextattr(struct ucred *cred, struct vnode *vp,
 1975     struct label *label, int attrnamespace)
 1976 {
 1977 
 1978         struct mac_mls *subj, *obj;
 1979 
 1980         if (!mac_mls_enabled)
 1981                 return (0);
 1982 
 1983         subj = SLOT(cred->cr_label);
 1984         obj = SLOT(label);
 1985 
 1986         if (!mac_mls_dominate_single(subj, obj))
 1987                 return (EACCES);
 1988 
 1989         return (0);
 1990 }
 1991 
 1992 static int
 1993 mac_mls_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
 1994     struct label *dlabel, struct componentname *cnp)
 1995 {
 1996         struct mac_mls *subj, *obj;
 1997 
 1998         if (!mac_mls_enabled)
 1999                 return (0);
 2000 
 2001         subj = SLOT(cred->cr_label);
 2002         obj = SLOT(dlabel);
 2003 
 2004         if (!mac_mls_dominate_single(subj, obj))
 2005                 return (EACCES);
 2006 
 2007         return (0);
 2008 }
 2009 
 2010 static int
 2011 mac_mls_check_vnode_mmap(struct ucred *cred, struct vnode *vp,
 2012     struct label *label, int prot)
 2013 {
 2014         struct mac_mls *subj, *obj;
 2015 
 2016         /*
 2017          * Rely on the use of open()-time protections to handle
 2018          * non-revocation cases.
 2019          */
 2020         if (!mac_mls_enabled || !revocation_enabled)
 2021                 return (0);
 2022 
 2023         subj = SLOT(cred->cr_label);
 2024         obj = SLOT(label);
 2025 
 2026         if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
 2027                 if (!mac_mls_dominate_single(subj, obj))
 2028                         return (EACCES);
 2029         }
 2030         if (prot & VM_PROT_WRITE) {
 2031                 if (!mac_mls_dominate_single(obj, subj))
 2032                         return (EACCES);
 2033         }
 2034 
 2035         return (0);
 2036 }
 2037 
 2038 static int
 2039 mac_mls_check_vnode_open(struct ucred *cred, struct vnode *vp,
 2040     struct label *vnodelabel, int acc_mode)
 2041 {
 2042         struct mac_mls *subj, *obj;
 2043 
 2044         if (!mac_mls_enabled)
 2045                 return (0);
 2046 
 2047         subj = SLOT(cred->cr_label);
 2048         obj = SLOT(vnodelabel);
 2049 
 2050         /* XXX privilege override for admin? */
 2051         if (acc_mode & (VREAD | VEXEC | VSTAT)) {
 2052                 if (!mac_mls_dominate_single(subj, obj))
 2053                         return (EACCES);
 2054         }
 2055         if (acc_mode & (VWRITE | VAPPEND | VADMIN)) {
 2056                 if (!mac_mls_dominate_single(obj, subj))
 2057                         return (EACCES);
 2058         }
 2059 
 2060         return (0);
 2061 }
 2062 
 2063 static int
 2064 mac_mls_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred,
 2065     struct vnode *vp, struct label *label)
 2066 {
 2067         struct mac_mls *subj, *obj;
 2068 
 2069         if (!mac_mls_enabled || !revocation_enabled)
 2070                 return (0);
 2071 
 2072         subj = SLOT(active_cred->cr_label);
 2073         obj = SLOT(label);
 2074 
 2075         if (!mac_mls_dominate_single(subj, obj))
 2076                 return (EACCES);
 2077 
 2078         return (0);
 2079 }
 2080 
 2081 static int
 2082 mac_mls_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
 2083     struct vnode *vp, struct label *label)
 2084 {
 2085         struct mac_mls *subj, *obj;
 2086 
 2087         if (!mac_mls_enabled || !revocation_enabled)
 2088                 return (0);
 2089 
 2090         subj = SLOT(active_cred->cr_label);
 2091         obj = SLOT(label);
 2092 
 2093         if (!mac_mls_dominate_single(subj, obj))
 2094                 return (EACCES);
 2095 
 2096         return (0);
 2097 }
 2098 
 2099 static int
 2100 mac_mls_check_vnode_readdir(struct ucred *cred, struct vnode *dvp,
 2101     struct label *dlabel)
 2102 {
 2103         struct mac_mls *subj, *obj;
 2104 
 2105         if (!mac_mls_enabled)
 2106                 return (0);
 2107 
 2108         subj = SLOT(cred->cr_label);
 2109         obj = SLOT(dlabel);
 2110 
 2111         if (!mac_mls_dominate_single(subj, obj))
 2112                 return (EACCES);
 2113 
 2114         return (0);
 2115 }
 2116 
 2117 static int
 2118 mac_mls_check_vnode_readlink(struct ucred *cred, struct vnode *vp,
 2119     struct label *vnodelabel)
 2120 {
 2121         struct mac_mls *subj, *obj;
 2122 
 2123         if (!mac_mls_enabled)
 2124                 return (0);
 2125 
 2126         subj = SLOT(cred->cr_label);
 2127         obj = SLOT(vnodelabel);
 2128 
 2129         if (!mac_mls_dominate_single(subj, obj))
 2130                 return (EACCES);
 2131 
 2132         return (0);
 2133 }
 2134 
 2135 static int
 2136 mac_mls_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
 2137     struct label *vnodelabel, struct label *newlabel)
 2138 {
 2139         struct mac_mls *old, *new, *subj;
 2140         int error;
 2141 
 2142         old = SLOT(vnodelabel);
 2143         new = SLOT(newlabel);
 2144         subj = SLOT(cred->cr_label);
 2145 
 2146         /*
 2147          * If there is an MLS label update for the vnode, it must be a
 2148          * single label.
 2149          */
 2150         error = mls_atmostflags(new, MAC_MLS_FLAG_SINGLE);
 2151         if (error)
 2152                 return (error);
 2153 
 2154         /*
 2155          * To perform a relabel of the vnode (MLS label or not), MLS must
 2156          * authorize the relabel.
 2157          */
 2158         if (!mac_mls_single_in_range(old, subj))
 2159                 return (EPERM);
 2160 
 2161         /*
 2162          * If the MLS label is to be changed, authorize as appropriate.
 2163          */
 2164         if (new->mm_flags & MAC_MLS_FLAG_SINGLE) {
 2165                 /*
 2166                  * To change the MLS label on a vnode, the new vnode label
 2167                  * must be in the subject range.
 2168                  */
 2169                 if (!mac_mls_single_in_range(new, subj))
 2170                         return (EPERM);
 2171 
 2172                 /*
 2173                  * To change the MLS label on the vnode to be EQUAL,
 2174                  * the subject must have appropriate privilege.
 2175                  */
 2176                 if (mac_mls_contains_equal(new)) {
 2177                         error = mac_mls_subject_privileged(subj);
 2178                         if (error)
 2179                                 return (error);
 2180                 }
 2181         }
 2182 
 2183         return (0);
 2184 }
 2185 
 2186 
 2187 static int
 2188 mac_mls_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
 2189     struct label *dlabel, struct vnode *vp, struct label *label,
 2190     struct componentname *cnp)
 2191 {
 2192         struct mac_mls *subj, *obj;
 2193 
 2194         if (!mac_mls_enabled)
 2195                 return (0);
 2196 
 2197         subj = SLOT(cred->cr_label);
 2198         obj = SLOT(dlabel);
 2199 
 2200         if (!mac_mls_dominate_single(obj, subj))
 2201                 return (EACCES);
 2202 
 2203         obj = SLOT(label);
 2204 
 2205         if (!mac_mls_dominate_single(obj, subj))
 2206                 return (EACCES);
 2207 
 2208         return (0);
 2209 }
 2210 
 2211 static int
 2212 mac_mls_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
 2213     struct label *dlabel, struct vnode *vp, struct label *label, int samedir,
 2214     struct componentname *cnp)
 2215 {
 2216         struct mac_mls *subj, *obj;
 2217 
 2218         if (!mac_mls_enabled)
 2219                 return (0);
 2220 
 2221         subj = SLOT(cred->cr_label);
 2222         obj = SLOT(dlabel);
 2223 
 2224         if (!mac_mls_dominate_single(obj, subj))
 2225                 return (EACCES);
 2226 
 2227         if (vp != NULL) {
 2228                 obj = SLOT(label);
 2229 
 2230                 if (!mac_mls_dominate_single(obj, subj))
 2231                         return (EACCES);
 2232         }
 2233 
 2234         return (0);
 2235 }
 2236 
 2237 static int
 2238 mac_mls_check_vnode_revoke(struct ucred *cred, struct vnode *vp,
 2239     struct label *label)
 2240 {
 2241         struct mac_mls *subj, *obj;
 2242 
 2243         if (!mac_mls_enabled)
 2244                 return (0);
 2245 
 2246         subj = SLOT(cred->cr_label);
 2247         obj = SLOT(label);
 2248 
 2249         if (!mac_mls_dominate_single(obj, subj))
 2250                 return (EACCES);
 2251 
 2252         return (0);
 2253 }
 2254 
 2255 static int
 2256 mac_mls_check_vnode_setacl(struct ucred *cred, struct vnode *vp,
 2257     struct label *label, acl_type_t type, struct acl *acl)
 2258 {
 2259         struct mac_mls *subj, *obj;
 2260 
 2261         if (!mac_mls_enabled)
 2262                 return (0);
 2263 
 2264         subj = SLOT(cred->cr_label);
 2265         obj = SLOT(label);
 2266 
 2267         if (!mac_mls_dominate_single(obj, subj))
 2268                 return (EACCES);
 2269 
 2270         return (0);
 2271 }
 2272 
 2273 static int
 2274 mac_mls_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
 2275     struct label *vnodelabel, int attrnamespace, const char *name,
 2276     struct uio *uio)
 2277 {
 2278         struct mac_mls *subj, *obj;
 2279 
 2280         if (!mac_mls_enabled)
 2281                 return (0);
 2282 
 2283         subj = SLOT(cred->cr_label);
 2284         obj = SLOT(vnodelabel);
 2285 
 2286         if (!mac_mls_dominate_single(obj, subj))
 2287                 return (EACCES);
 2288 
 2289         /* XXX: protect the MAC EA in a special way? */
 2290 
 2291         return (0);
 2292 }
 2293 
 2294 static int
 2295 mac_mls_check_vnode_setflags(struct ucred *cred, struct vnode *vp,
 2296     struct label *vnodelabel, u_long flags)
 2297 {
 2298         struct mac_mls *subj, *obj;
 2299 
 2300         if (!mac_mls_enabled)
 2301                 return (0);
 2302 
 2303         subj = SLOT(cred->cr_label);
 2304         obj = SLOT(vnodelabel);
 2305 
 2306         if (!mac_mls_dominate_single(obj, subj))
 2307                 return (EACCES);
 2308 
 2309         return (0);
 2310 }
 2311 
 2312 static int
 2313 mac_mls_check_vnode_setmode(struct ucred *cred, struct vnode *vp,
 2314     struct label *vnodelabel, mode_t mode)
 2315 {
 2316         struct mac_mls *subj, *obj;
 2317 
 2318         if (!mac_mls_enabled)
 2319                 return (0);
 2320 
 2321         subj = SLOT(cred->cr_label);
 2322         obj = SLOT(vnodelabel);
 2323 
 2324         if (!mac_mls_dominate_single(obj, subj))
 2325                 return (EACCES);
 2326 
 2327         return (0);
 2328 }
 2329 
 2330 static int
 2331 mac_mls_check_vnode_setowner(struct ucred *cred, struct vnode *vp,
 2332     struct label *vnodelabel, uid_t uid, gid_t gid)
 2333 {
 2334         struct mac_mls *subj, *obj;
 2335 
 2336         if (!mac_mls_enabled)
 2337                 return (0);
 2338 
 2339         subj = SLOT(cred->cr_label);
 2340         obj = SLOT(vnodelabel);
 2341 
 2342         if (!mac_mls_dominate_single(obj, subj))
 2343                 return (EACCES);
 2344 
 2345         return (0);
 2346 }
 2347 
 2348 static int
 2349 mac_mls_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
 2350     struct label *vnodelabel, struct timespec atime, struct timespec mtime)
 2351 {
 2352         struct mac_mls *subj, *obj;
 2353 
 2354         if (!mac_mls_enabled)
 2355                 return (0);
 2356 
 2357         subj = SLOT(cred->cr_label);
 2358         obj = SLOT(vnodelabel);
 2359 
 2360         if (!mac_mls_dominate_single(obj, subj))
 2361                 return (EACCES);
 2362 
 2363         return (0);
 2364 }
 2365 
 2366 static int
 2367 mac_mls_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
 2368     struct vnode *vp, struct label *vnodelabel)
 2369 {
 2370         struct mac_mls *subj, *obj;
 2371 
 2372         if (!mac_mls_enabled)
 2373                 return (0);
 2374 
 2375         subj = SLOT(active_cred->cr_label);
 2376         obj = SLOT(vnodelabel);
 2377 
 2378         if (!mac_mls_dominate_single(subj, obj))
 2379                 return (EACCES);
 2380 
 2381         return (0);
 2382 }
 2383 
 2384 static int
 2385 mac_mls_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred,
 2386     struct vnode *vp, struct label *label)
 2387 {
 2388         struct mac_mls *subj, *obj;
 2389 
 2390         if (!mac_mls_enabled || !revocation_enabled)
 2391                 return (0);
 2392 
 2393         subj = SLOT(active_cred->cr_label);
 2394         obj = SLOT(label);
 2395 
 2396         if (!mac_mls_dominate_single(obj, subj))
 2397                 return (EACCES);
 2398 
 2399         return (0);
 2400 }
 2401 
 2402 static struct mac_policy_ops mac_mls_ops =
 2403 {
 2404         .mpo_init = mac_mls_init,
 2405         .mpo_init_bpfdesc_label = mac_mls_init_label,
 2406         .mpo_init_cred_label = mac_mls_init_label,
 2407         .mpo_init_devfsdirent_label = mac_mls_init_label,
 2408         .mpo_init_ifnet_label = mac_mls_init_label,
 2409         .mpo_init_inpcb_label = mac_mls_init_label_waitcheck,
 2410         .mpo_init_ipq_label = mac_mls_init_label_waitcheck,
 2411         .mpo_init_mbuf_label = mac_mls_init_label_waitcheck,
 2412         .mpo_init_mount_label = mac_mls_init_label,
 2413         .mpo_init_mount_fs_label = mac_mls_init_label,
 2414         .mpo_init_pipe_label = mac_mls_init_label,
 2415         .mpo_init_socket_label = mac_mls_init_label_waitcheck,
 2416         .mpo_init_socket_peer_label = mac_mls_init_label_waitcheck,
 2417         .mpo_init_vnode_label = mac_mls_init_label,
 2418         .mpo_destroy_bpfdesc_label = mac_mls_destroy_label,
 2419         .mpo_destroy_cred_label = mac_mls_destroy_label,
 2420         .mpo_destroy_devfsdirent_label = mac_mls_destroy_label,
 2421         .mpo_destroy_ifnet_label = mac_mls_destroy_label,
 2422         .mpo_destroy_inpcb_label = mac_mls_destroy_label,
 2423         .mpo_destroy_ipq_label = mac_mls_destroy_label,
 2424         .mpo_destroy_mbuf_label = mac_mls_destroy_label,
 2425         .mpo_destroy_mount_label = mac_mls_destroy_label,
 2426         .mpo_destroy_mount_fs_label = mac_mls_destroy_label,
 2427         .mpo_destroy_pipe_label = mac_mls_destroy_label,
 2428         .mpo_destroy_socket_label = mac_mls_destroy_label,
 2429         .mpo_destroy_socket_peer_label = mac_mls_destroy_label,
 2430         .mpo_destroy_vnode_label = mac_mls_destroy_label,
 2431         .mpo_copy_cred_label = mac_mls_copy_label,
 2432         .mpo_copy_mbuf_label = mac_mls_copy_label,
 2433         .mpo_copy_pipe_label = mac_mls_copy_label,
 2434         .mpo_copy_socket_label = mac_mls_copy_label,
 2435         .mpo_copy_vnode_label = mac_mls_copy_label,
 2436         .mpo_externalize_cred_label = mac_mls_externalize_label,
 2437         .mpo_externalize_ifnet_label = mac_mls_externalize_label,
 2438         .mpo_externalize_pipe_label = mac_mls_externalize_label,
 2439         .mpo_externalize_socket_label = mac_mls_externalize_label,
 2440         .mpo_externalize_socket_peer_label = mac_mls_externalize_label,
 2441         .mpo_externalize_vnode_label = mac_mls_externalize_label,
 2442         .mpo_internalize_cred_label = mac_mls_internalize_label,
 2443         .mpo_internalize_ifnet_label = mac_mls_internalize_label,
 2444         .mpo_internalize_pipe_label = mac_mls_internalize_label,
 2445         .mpo_internalize_socket_label = mac_mls_internalize_label,
 2446         .mpo_internalize_vnode_label = mac_mls_internalize_label,
 2447         .mpo_create_devfs_device = mac_mls_create_devfs_device,
 2448         .mpo_create_devfs_directory = mac_mls_create_devfs_directory,
 2449         .mpo_create_devfs_symlink = mac_mls_create_devfs_symlink,
 2450         .mpo_create_mount = mac_mls_create_mount,
 2451         .mpo_create_root_mount = mac_mls_create_root_mount,
 2452         .mpo_relabel_vnode = mac_mls_relabel_vnode,
 2453         .mpo_update_devfsdirent = mac_mls_update_devfsdirent,
 2454         .mpo_associate_vnode_devfs = mac_mls_associate_vnode_devfs,
 2455         .mpo_associate_vnode_extattr = mac_mls_associate_vnode_extattr,
 2456         .mpo_associate_vnode_singlelabel = mac_mls_associate_vnode_singlelabel,
 2457         .mpo_create_vnode_extattr = mac_mls_create_vnode_extattr,
 2458         .mpo_setlabel_vnode_extattr = mac_mls_setlabel_vnode_extattr,
 2459         .mpo_create_mbuf_from_socket = mac_mls_create_mbuf_from_socket,
 2460         .mpo_create_pipe = mac_mls_create_pipe,
 2461         .mpo_create_socket = mac_mls_create_socket,
 2462         .mpo_create_socket_from_socket = mac_mls_create_socket_from_socket,
 2463         .mpo_relabel_pipe = mac_mls_relabel_pipe,
 2464         .mpo_relabel_socket = mac_mls_relabel_socket,
 2465         .mpo_set_socket_peer_from_mbuf = mac_mls_set_socket_peer_from_mbuf,
 2466         .mpo_set_socket_peer_from_socket = mac_mls_set_socket_peer_from_socket,
 2467         .mpo_create_bpfdesc = mac_mls_create_bpfdesc,
 2468         .mpo_create_datagram_from_ipq = mac_mls_create_datagram_from_ipq,
 2469         .mpo_create_fragment = mac_mls_create_fragment,
 2470         .mpo_create_ifnet = mac_mls_create_ifnet,
 2471         .mpo_create_inpcb_from_socket = mac_mls_create_inpcb_from_socket,
 2472         .mpo_create_ipq = mac_mls_create_ipq,
 2473         .mpo_create_mbuf_from_mbuf = mac_mls_create_mbuf_from_mbuf,
 2474         .mpo_create_mbuf_linklayer = mac_mls_create_mbuf_linklayer,
 2475         .mpo_create_mbuf_from_bpfdesc = mac_mls_create_mbuf_from_bpfdesc,
 2476         .mpo_create_mbuf_from_ifnet = mac_mls_create_mbuf_from_ifnet,
 2477         .mpo_create_mbuf_multicast_encap = mac_mls_create_mbuf_multicast_encap,
 2478         .mpo_create_mbuf_netlayer = mac_mls_create_mbuf_netlayer,
 2479         .mpo_fragment_match = mac_mls_fragment_match,
 2480         .mpo_relabel_ifnet = mac_mls_relabel_ifnet,
 2481         .mpo_update_ipq = mac_mls_update_ipq,
 2482         .mpo_inpcb_sosetlabel = mac_mls_inpcb_sosetlabel,
 2483         .mpo_create_proc0 = mac_mls_create_proc0,
 2484         .mpo_create_proc1 = mac_mls_create_proc1,
 2485         .mpo_relabel_cred = mac_mls_relabel_cred,
 2486         .mpo_check_bpfdesc_receive = mac_mls_check_bpfdesc_receive,
 2487         .mpo_check_cred_relabel = mac_mls_check_cred_relabel,
 2488         .mpo_check_cred_visible = mac_mls_check_cred_visible,
 2489         .mpo_check_ifnet_relabel = mac_mls_check_ifnet_relabel,
 2490         .mpo_check_ifnet_transmit = mac_mls_check_ifnet_transmit,
 2491         .mpo_check_inpcb_deliver = mac_mls_check_inpcb_deliver,
 2492         .mpo_check_mount_stat = mac_mls_check_mount_stat,
 2493         .mpo_check_pipe_ioctl = mac_mls_check_pipe_ioctl,
 2494         .mpo_check_pipe_poll = mac_mls_check_pipe_poll,
 2495         .mpo_check_pipe_read = mac_mls_check_pipe_read,
 2496         .mpo_check_pipe_relabel = mac_mls_check_pipe_relabel,
 2497         .mpo_check_pipe_stat = mac_mls_check_pipe_stat,
 2498         .mpo_check_pipe_write = mac_mls_check_pipe_write,
 2499         .mpo_check_proc_debug = mac_mls_check_proc_debug,
 2500         .mpo_check_proc_sched = mac_mls_check_proc_sched,
 2501         .mpo_check_proc_signal = mac_mls_check_proc_signal,
 2502         .mpo_check_socket_deliver = mac_mls_check_socket_deliver,
 2503         .mpo_check_socket_relabel = mac_mls_check_socket_relabel,
 2504         .mpo_check_socket_visible = mac_mls_check_socket_visible,
 2505         .mpo_check_system_swapon = mac_mls_check_system_swapon,
 2506         .mpo_check_vnode_access = mac_mls_check_vnode_open,
 2507         .mpo_check_vnode_chdir = mac_mls_check_vnode_chdir,
 2508         .mpo_check_vnode_chroot = mac_mls_check_vnode_chroot,
 2509         .mpo_check_vnode_create = mac_mls_check_vnode_create,
 2510         .mpo_check_vnode_delete = mac_mls_check_vnode_delete,
 2511         .mpo_check_vnode_deleteacl = mac_mls_check_vnode_deleteacl,
 2512         .mpo_check_vnode_deleteextattr = mac_mls_check_vnode_deleteextattr,
 2513         .mpo_check_vnode_exec = mac_mls_check_vnode_exec,
 2514         .mpo_check_vnode_getacl = mac_mls_check_vnode_getacl,
 2515         .mpo_check_vnode_getextattr = mac_mls_check_vnode_getextattr,
 2516         .mpo_check_vnode_link = mac_mls_check_vnode_link,
 2517         .mpo_check_vnode_listextattr = mac_mls_check_vnode_listextattr,
 2518         .mpo_check_vnode_lookup = mac_mls_check_vnode_lookup,
 2519         .mpo_check_vnode_mmap = mac_mls_check_vnode_mmap,
 2520         .mpo_check_vnode_mprotect = mac_mls_check_vnode_mmap,
 2521         .mpo_check_vnode_open = mac_mls_check_vnode_open,
 2522         .mpo_check_vnode_poll = mac_mls_check_vnode_poll,
 2523         .mpo_check_vnode_read = mac_mls_check_vnode_read,
 2524         .mpo_check_vnode_readdir = mac_mls_check_vnode_readdir,
 2525         .mpo_check_vnode_readlink = mac_mls_check_vnode_readlink,
 2526         .mpo_check_vnode_relabel = mac_mls_check_vnode_relabel,
 2527         .mpo_check_vnode_rename_from = mac_mls_check_vnode_rename_from,
 2528         .mpo_check_vnode_rename_to = mac_mls_check_vnode_rename_to,
 2529         .mpo_check_vnode_revoke = mac_mls_check_vnode_revoke,
 2530         .mpo_check_vnode_setacl = mac_mls_check_vnode_setacl,
 2531         .mpo_check_vnode_setextattr = mac_mls_check_vnode_setextattr,
 2532         .mpo_check_vnode_setflags = mac_mls_check_vnode_setflags,
 2533         .mpo_check_vnode_setmode = mac_mls_check_vnode_setmode,
 2534         .mpo_check_vnode_setowner = mac_mls_check_vnode_setowner,
 2535         .mpo_check_vnode_setutimes = mac_mls_check_vnode_setutimes,
 2536         .mpo_check_vnode_stat = mac_mls_check_vnode_stat,
 2537         .mpo_check_vnode_write = mac_mls_check_vnode_write,
 2538 };
 2539 
 2540 MAC_POLICY_SET(&mac_mls_ops, mac_mls, "TrustedBSD MAC/MLS",
 2541     MPC_LOADTIME_FLAG_NOTLATE | MPC_LOADTIME_FLAG_LABELMBUFS, &mac_mls_slot);

Cache object: 0979f9952929de5c08e0b6c92768d528


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