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/10.0/sys/security/mac_mls/mac_mls.c 254603 2013-08-21 17:45:00Z kib $
   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 static 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_read(struct ucred *active_cred, struct ucred *file_cred,
 1655     struct shmfd *shm, struct label *shmlabel)
 1656 {
 1657         struct mac_mls *subj, *obj;
 1658 
 1659         if (!mls_enabled || !revocation_enabled)
 1660                 return (0);
 1661 
 1662         subj = SLOT(active_cred->cr_label);
 1663         obj = SLOT(shmlabel);
 1664 
 1665         if (!mls_dominate_effective(subj, obj))
 1666                 return (EACCES);
 1667 
 1668         return (0);
 1669 }
 1670 
 1671 static int
 1672 mls_posixshm_check_setmode(struct ucred *cred, struct shmfd *shmfd,
 1673     struct label *shmlabel, mode_t mode)
 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_setowner(struct ucred *cred, struct shmfd *shmfd,
 1691     struct label *shmlabel, uid_t uid, gid_t gid)
 1692 {
 1693         struct mac_mls *subj, *obj;
 1694 
 1695         if (!mls_enabled)
 1696                 return (0);
 1697 
 1698         subj = SLOT(cred->cr_label);
 1699         obj = SLOT(shmlabel);
 1700 
 1701         if (!mls_dominate_effective(obj, subj))
 1702                 return (EACCES);
 1703 
 1704         return (0);
 1705 }
 1706 
 1707 static int
 1708 mls_posixshm_check_stat(struct ucred *active_cred, struct ucred *file_cred,
 1709     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(subj, obj))
 1720                 return (EACCES);
 1721 
 1722         return (0);
 1723 }
 1724 
 1725 static int
 1726 mls_posixshm_check_truncate(struct ucred *active_cred,
 1727     struct ucred *file_cred, struct shmfd *shmfd, struct label *shmlabel)
 1728 {
 1729         struct mac_mls *subj, *obj;
 1730 
 1731         if (!mls_enabled)
 1732                 return (0);
 1733 
 1734         subj = SLOT(active_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 int
 1744 mls_posixshm_check_unlink(struct ucred *cred, struct shmfd *shmfd,
 1745     struct label *shmlabel)
 1746 {
 1747         struct mac_mls *subj, *obj;
 1748 
 1749         if (!mls_enabled)
 1750                 return (0);
 1751 
 1752         subj = SLOT(cred->cr_label);
 1753         obj = SLOT(shmlabel);
 1754 
 1755         if (!mls_dominate_effective(obj, subj))
 1756                 return (EACCES);
 1757     
 1758         return (0);
 1759 }
 1760 
 1761 static int
 1762 mls_posixshm_check_write(struct ucred *active_cred, struct ucred *file_cred,
 1763     struct shmfd *shm, struct label *shmlabel)
 1764 {
 1765         struct mac_mls *subj, *obj;
 1766 
 1767         if (!mls_enabled || !revocation_enabled)
 1768                 return (0);
 1769 
 1770         subj = SLOT(active_cred->cr_label);
 1771         obj = SLOT(shmlabel);
 1772 
 1773         if (!mls_dominate_effective(subj, obj))
 1774                 return (EACCES);
 1775 
 1776         return (0);
 1777 }
 1778 
 1779 static void
 1780 mls_posixshm_create(struct ucred *cred, struct shmfd *shmfd,
 1781     struct label *shmlabel)
 1782 {
 1783         struct mac_mls *source, *dest;
 1784 
 1785         source = SLOT(cred->cr_label);
 1786         dest = SLOT(shmlabel);
 1787 
 1788         mls_copy_effective(source, dest);
 1789 }
 1790 
 1791 static int
 1792 mls_proc_check_debug(struct ucred *cred, struct proc *p)
 1793 {
 1794         struct mac_mls *subj, *obj;
 1795 
 1796         if (!mls_enabled)
 1797                 return (0);
 1798 
 1799         subj = SLOT(cred->cr_label);
 1800         obj = SLOT(p->p_ucred->cr_label);
 1801 
 1802         /* XXX: range checks */
 1803         if (!mls_dominate_effective(subj, obj))
 1804                 return (ESRCH);
 1805         if (!mls_dominate_effective(obj, subj))
 1806                 return (EACCES);
 1807 
 1808         return (0);
 1809 }
 1810 
 1811 static int
 1812 mls_proc_check_sched(struct ucred *cred, struct proc *p)
 1813 {
 1814         struct mac_mls *subj, *obj;
 1815 
 1816         if (!mls_enabled)
 1817                 return (0);
 1818 
 1819         subj = SLOT(cred->cr_label);
 1820         obj = SLOT(p->p_ucred->cr_label);
 1821 
 1822         /* XXX: range checks */
 1823         if (!mls_dominate_effective(subj, obj))
 1824                 return (ESRCH);
 1825         if (!mls_dominate_effective(obj, subj))
 1826                 return (EACCES);
 1827 
 1828         return (0);
 1829 }
 1830 
 1831 static int
 1832 mls_proc_check_signal(struct ucred *cred, struct proc *p, int signum)
 1833 {
 1834         struct mac_mls *subj, *obj;
 1835 
 1836         if (!mls_enabled)
 1837                 return (0);
 1838 
 1839         subj = SLOT(cred->cr_label);
 1840         obj = SLOT(p->p_ucred->cr_label);
 1841 
 1842         /* XXX: range checks */
 1843         if (!mls_dominate_effective(subj, obj))
 1844                 return (ESRCH);
 1845         if (!mls_dominate_effective(obj, subj))
 1846                 return (EACCES);
 1847 
 1848         return (0);
 1849 }
 1850 
 1851 static int
 1852 mls_socket_check_deliver(struct socket *so, struct label *solabel,
 1853     struct mbuf *m, struct label *mlabel)
 1854 {
 1855         struct mac_mls *p, *s;
 1856         int error;
 1857 
 1858         if (!mls_enabled)
 1859                 return (0);
 1860 
 1861         p = SLOT(mlabel);
 1862         s = SLOT(solabel);
 1863 
 1864         SOCK_LOCK(so);
 1865         error = mls_equal_effective(p, s) ? 0 : EACCES;
 1866         SOCK_UNLOCK(so);
 1867 
 1868         return (error);
 1869 }
 1870 
 1871 static int
 1872 mls_socket_check_relabel(struct ucred *cred, struct socket *so,
 1873     struct label *solabel, struct label *newlabel)
 1874 {
 1875         struct mac_mls *subj, *obj, *new;
 1876         int error;
 1877 
 1878         SOCK_LOCK_ASSERT(so);
 1879 
 1880         new = SLOT(newlabel);
 1881         subj = SLOT(cred->cr_label);
 1882         obj = SLOT(solabel);
 1883 
 1884         /*
 1885          * If there is an MLS label update for the socket, it may be an
 1886          * update of effective.
 1887          */
 1888         error = mls_atmostflags(new, MAC_MLS_FLAG_EFFECTIVE);
 1889         if (error)
 1890                 return (error);
 1891 
 1892         /*
 1893          * To relabel a socket, the old socket effective must be in the
 1894          * subject range.
 1895          */
 1896         if (!mls_effective_in_range(obj, subj))
 1897                 return (EPERM);
 1898 
 1899         /*
 1900          * If the MLS label is to be changed, authorize as appropriate.
 1901          */
 1902         if (new->mm_flags & MAC_MLS_FLAG_EFFECTIVE) {
 1903                 /*
 1904                  * To relabel a socket, the new socket effective must be in
 1905                  * the subject range.
 1906                  */
 1907                 if (!mls_effective_in_range(new, subj))
 1908                         return (EPERM);
 1909 
 1910                 /*
 1911                  * To change the MLS label on the socket to contain EQUAL,
 1912                  * the subject must have appropriate privilege.
 1913                  */
 1914                 if (mls_contains_equal(new)) {
 1915                         error = mls_subject_privileged(subj);
 1916                         if (error)
 1917                                 return (error);
 1918                 }
 1919         }
 1920 
 1921         return (0);
 1922 }
 1923 
 1924 static int
 1925 mls_socket_check_visible(struct ucred *cred, struct socket *so,
 1926     struct label *solabel)
 1927 {
 1928         struct mac_mls *subj, *obj;
 1929 
 1930         if (!mls_enabled)
 1931                 return (0);
 1932 
 1933         subj = SLOT(cred->cr_label);
 1934         obj = SLOT(solabel);
 1935 
 1936         SOCK_LOCK(so);
 1937         if (!mls_dominate_effective(subj, obj)) {
 1938                 SOCK_UNLOCK(so);
 1939                 return (ENOENT);
 1940         }
 1941         SOCK_UNLOCK(so);
 1942 
 1943         return (0);
 1944 }
 1945 
 1946 static void
 1947 mls_socket_create(struct ucred *cred, struct socket *so,
 1948     struct label *solabel)
 1949 {
 1950         struct mac_mls *source, *dest;
 1951 
 1952         source = SLOT(cred->cr_label);
 1953         dest = SLOT(solabel);
 1954 
 1955         mls_copy_effective(source, dest);
 1956 }
 1957 
 1958 static void
 1959 mls_socket_create_mbuf(struct socket *so, struct label *solabel,
 1960     struct mbuf *m, struct label *mlabel)
 1961 {
 1962         struct mac_mls *source, *dest;
 1963 
 1964         source = SLOT(solabel);
 1965         dest = SLOT(mlabel);
 1966 
 1967         SOCK_LOCK(so);
 1968         mls_copy_effective(source, dest);
 1969         SOCK_UNLOCK(so);
 1970 }
 1971 
 1972 static void
 1973 mls_socket_newconn(struct socket *oldso, struct label *oldsolabel,
 1974     struct socket *newso, struct label *newsolabel)
 1975 {
 1976         struct mac_mls source, *dest;
 1977 
 1978         SOCK_LOCK(oldso);
 1979         source = *SLOT(oldsolabel);
 1980         SOCK_UNLOCK(oldso);
 1981 
 1982         dest = SLOT(newsolabel);
 1983 
 1984         SOCK_LOCK(newso);
 1985         mls_copy_effective(&source, dest);
 1986         SOCK_UNLOCK(newso);
 1987 }
 1988 
 1989 static void
 1990 mls_socket_relabel(struct ucred *cred, struct socket *so,
 1991     struct label *solabel, struct label *newlabel)
 1992 {
 1993         struct mac_mls *source, *dest;
 1994 
 1995         SOCK_LOCK_ASSERT(so);
 1996 
 1997         source = SLOT(newlabel);
 1998         dest = SLOT(solabel);
 1999 
 2000         mls_copy(source, dest);
 2001 }
 2002 
 2003 static void
 2004 mls_socketpeer_set_from_mbuf(struct mbuf *m, struct label *mlabel,
 2005     struct socket *so, struct label *sopeerlabel)
 2006 {
 2007         struct mac_mls *source, *dest;
 2008 
 2009         source = SLOT(mlabel);
 2010         dest = SLOT(sopeerlabel);
 2011 
 2012         SOCK_LOCK(so);
 2013         mls_copy_effective(source, dest);
 2014         SOCK_UNLOCK(so);
 2015 }
 2016 
 2017 static void
 2018 mls_socketpeer_set_from_socket(struct socket *oldso,
 2019     struct label *oldsolabel, struct socket *newso,
 2020     struct label *newsopeerlabel)
 2021 {
 2022         struct mac_mls source, *dest;
 2023 
 2024         SOCK_LOCK(oldso);
 2025         source = *SLOT(oldsolabel);
 2026         SOCK_UNLOCK(oldso);
 2027 
 2028         dest = SLOT(newsopeerlabel);
 2029 
 2030         SOCK_LOCK(newso);
 2031         mls_copy_effective(&source, dest);
 2032         SOCK_UNLOCK(newso);
 2033 }
 2034 
 2035 static void
 2036 mls_syncache_create(struct label *label, struct inpcb *inp)
 2037 {
 2038         struct mac_mls *source, *dest;
 2039 
 2040         source = SLOT(inp->inp_label);
 2041         dest = SLOT(label);
 2042 
 2043         mls_copy_effective(source, dest);
 2044 }
 2045 
 2046 static void
 2047 mls_syncache_create_mbuf(struct label *sc_label, struct mbuf *m,
 2048     struct label *mlabel)
 2049 {
 2050         struct mac_mls *source, *dest;
 2051 
 2052         source = SLOT(sc_label);
 2053         dest = SLOT(mlabel);
 2054 
 2055         mls_copy_effective(source, dest);
 2056 }
 2057 
 2058 static int
 2059 mls_system_check_acct(struct ucred *cred, struct vnode *vp,
 2060     struct label *vplabel)
 2061 {
 2062         struct mac_mls *subj, *obj;
 2063 
 2064         if (!mls_enabled)
 2065                 return (0);
 2066 
 2067         if (vplabel == NULL)
 2068                 return (0);
 2069 
 2070         subj = SLOT(cred->cr_label);
 2071         obj = SLOT(vplabel);
 2072 
 2073         if (!mls_dominate_effective(obj, subj) ||
 2074             !mls_dominate_effective(subj, obj))
 2075                 return (EACCES);
 2076 
 2077         return (0);
 2078 }
 2079 
 2080 static int
 2081 mls_system_check_auditctl(struct ucred *cred, struct vnode *vp,
 2082     struct label *vplabel)
 2083 {
 2084         struct mac_mls *subj, *obj;
 2085 
 2086         if (!mls_enabled)
 2087                 return (0);
 2088 
 2089         subj = SLOT(cred->cr_label);
 2090         obj = SLOT(vplabel);
 2091 
 2092         if (!mls_dominate_effective(obj, subj) ||
 2093             !mls_dominate_effective(subj, obj))
 2094                 return (EACCES);
 2095 
 2096         return (0);
 2097 }
 2098 
 2099 static int
 2100 mls_system_check_swapon(struct ucred *cred, struct vnode *vp,
 2101     struct label *vplabel)
 2102 {
 2103         struct mac_mls *subj, *obj;
 2104 
 2105         if (!mls_enabled)
 2106                 return (0);
 2107 
 2108         subj = SLOT(cred->cr_label);
 2109         obj = SLOT(vplabel);
 2110 
 2111         if (!mls_dominate_effective(obj, subj) ||
 2112             !mls_dominate_effective(subj, obj))
 2113                 return (EACCES);
 2114 
 2115         return (0);
 2116 }
 2117 
 2118 static void
 2119 mls_sysvmsg_cleanup(struct label *msglabel)
 2120 {
 2121 
 2122         bzero(SLOT(msglabel), sizeof(struct mac_mls));
 2123 }
 2124 
 2125 static void
 2126 mls_sysvmsg_create(struct ucred *cred, struct msqid_kernel *msqkptr,
 2127     struct label *msqlabel, struct msg *msgptr, struct label *msglabel)
 2128 {
 2129         struct mac_mls *source, *dest;
 2130 
 2131         /* Ignore the msgq label. */
 2132         source = SLOT(cred->cr_label);
 2133         dest = SLOT(msglabel);
 2134 
 2135         mls_copy_effective(source, dest);
 2136 }
 2137 
 2138 static int
 2139 mls_sysvmsq_check_msgrcv(struct ucred *cred, struct msg *msgptr,
 2140     struct label *msglabel)
 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(msglabel);
 2149 
 2150         if (!mls_dominate_effective(subj, obj))
 2151                 return (EACCES);
 2152 
 2153         return (0);
 2154 }
 2155 
 2156 static int
 2157 mls_sysvmsq_check_msgrmid(struct ucred *cred, struct msg *msgptr,
 2158     struct label *msglabel)
 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(msglabel);
 2167 
 2168         if (!mls_dominate_effective(obj, subj))
 2169                 return (EACCES);
 2170 
 2171         return (0);
 2172 }
 2173 
 2174 static int
 2175 mls_sysvmsq_check_msqget(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_msqsnd(struct ucred *cred, struct msqid_kernel *msqkptr,
 2194     struct label *msqklabel)
 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         if (!mls_dominate_effective(obj, subj))
 2205                 return (EACCES);
 2206 
 2207         return (0);
 2208 }
 2209 
 2210 static int
 2211 mls_sysvmsq_check_msqrcv(struct ucred *cred, struct msqid_kernel *msqkptr,
 2212     struct label *msqklabel)
 2213 {
 2214         struct mac_mls *subj, *obj;
 2215 
 2216         if (!mls_enabled)
 2217                 return (0);
 2218 
 2219         subj = SLOT(cred->cr_label);
 2220         obj = SLOT(msqklabel);
 2221 
 2222         if (!mls_dominate_effective(subj, obj))
 2223                 return (EACCES);
 2224 
 2225         return (0);
 2226 }
 2227 
 2228 static int
 2229 mls_sysvmsq_check_msqctl(struct ucred *cred, struct msqid_kernel *msqkptr,
 2230     struct label *msqklabel, int cmd)
 2231 {
 2232         struct mac_mls *subj, *obj;
 2233 
 2234         if (!mls_enabled)
 2235                 return (0);
 2236 
 2237         subj = SLOT(cred->cr_label);
 2238         obj = SLOT(msqklabel);
 2239 
 2240         switch(cmd) {
 2241         case IPC_RMID:
 2242         case IPC_SET:
 2243                 if (!mls_dominate_effective(obj, subj))
 2244                         return (EACCES);
 2245                 break;
 2246 
 2247         case IPC_STAT:
 2248                 if (!mls_dominate_effective(subj, obj))
 2249                         return (EACCES);
 2250                 break;
 2251 
 2252         default:
 2253                 return (EACCES);
 2254         }
 2255 
 2256         return (0);
 2257 }
 2258 
 2259 static void
 2260 mls_sysvmsq_cleanup(struct label *msqlabel)
 2261 {
 2262 
 2263         bzero(SLOT(msqlabel), sizeof(struct mac_mls));
 2264 }
 2265 
 2266 static void
 2267 mls_sysvmsq_create(struct ucred *cred, struct msqid_kernel *msqkptr,
 2268     struct label *msqlabel)
 2269 {
 2270         struct mac_mls *source, *dest;
 2271 
 2272         source = SLOT(cred->cr_label);
 2273         dest = SLOT(msqlabel);
 2274 
 2275         mls_copy_effective(source, dest);
 2276 }
 2277 
 2278 static int
 2279 mls_sysvsem_check_semctl(struct ucred *cred, struct semid_kernel *semakptr,
 2280     struct label *semaklabel, int cmd)
 2281 {
 2282         struct mac_mls *subj, *obj;
 2283 
 2284         if (!mls_enabled)
 2285                 return (0);
 2286 
 2287         subj = SLOT(cred->cr_label);
 2288         obj = SLOT(semaklabel);
 2289 
 2290         switch(cmd) {
 2291         case IPC_RMID:
 2292         case IPC_SET:
 2293         case SETVAL:
 2294         case SETALL:
 2295                 if (!mls_dominate_effective(obj, subj))
 2296                         return (EACCES);
 2297                 break;
 2298 
 2299         case IPC_STAT:
 2300         case GETVAL:
 2301         case GETPID:
 2302         case GETNCNT:
 2303         case GETZCNT:
 2304         case GETALL:
 2305                 if (!mls_dominate_effective(subj, obj))
 2306                         return (EACCES);
 2307                 break;
 2308 
 2309         default:
 2310                 return (EACCES);
 2311         }
 2312 
 2313         return (0);
 2314 }
 2315 
 2316 static int
 2317 mls_sysvsem_check_semget(struct ucred *cred, struct semid_kernel *semakptr,
 2318     struct label *semaklabel)
 2319 {
 2320         struct mac_mls *subj, *obj;
 2321 
 2322         if (!mls_enabled)
 2323                 return (0);
 2324 
 2325         subj = SLOT(cred->cr_label);
 2326         obj = SLOT(semaklabel);
 2327 
 2328         if (!mls_dominate_effective(subj, obj))
 2329                 return (EACCES);
 2330 
 2331         return (0);
 2332 }
 2333 
 2334 static int
 2335 mls_sysvsem_check_semop(struct ucred *cred, struct semid_kernel *semakptr,
 2336     struct label *semaklabel, size_t accesstype)
 2337 {
 2338         struct mac_mls *subj, *obj;
 2339 
 2340         if (!mls_enabled)
 2341                 return (0);
 2342 
 2343         subj = SLOT(cred->cr_label);
 2344         obj = SLOT(semaklabel);
 2345 
 2346         if( accesstype & SEM_R )
 2347                 if (!mls_dominate_effective(subj, obj))
 2348                         return (EACCES);
 2349 
 2350         if( accesstype & SEM_A )
 2351                 if (!mls_dominate_effective(obj, subj))
 2352                         return (EACCES);
 2353 
 2354         return (0);
 2355 }
 2356 
 2357 static void
 2358 mls_sysvsem_cleanup(struct label *semalabel)
 2359 {
 2360 
 2361         bzero(SLOT(semalabel), sizeof(struct mac_mls));
 2362 }
 2363 
 2364 static void
 2365 mls_sysvsem_create(struct ucred *cred, struct semid_kernel *semakptr,
 2366     struct label *semalabel)
 2367 {
 2368         struct mac_mls *source, *dest;
 2369 
 2370         source = SLOT(cred->cr_label);
 2371         dest = SLOT(semalabel);
 2372 
 2373         mls_copy_effective(source, dest);
 2374 }
 2375 
 2376 static int
 2377 mls_sysvshm_check_shmat(struct ucred *cred, struct shmid_kernel *shmsegptr,
 2378     struct label *shmseglabel, int shmflg)
 2379 {
 2380         struct mac_mls *subj, *obj;
 2381 
 2382         if (!mls_enabled)
 2383                 return (0);
 2384 
 2385         subj = SLOT(cred->cr_label);
 2386         obj = SLOT(shmseglabel);
 2387 
 2388         if (!mls_dominate_effective(subj, obj))
 2389                 return (EACCES);
 2390         if ((shmflg & SHM_RDONLY) == 0) {
 2391                 if (!mls_dominate_effective(obj, subj))
 2392                         return (EACCES);
 2393         }
 2394         
 2395         return (0);
 2396 }
 2397 
 2398 static int
 2399 mls_sysvshm_check_shmctl(struct ucred *cred, struct shmid_kernel *shmsegptr,
 2400     struct label *shmseglabel, int cmd)
 2401 {
 2402         struct mac_mls *subj, *obj;
 2403 
 2404         if (!mls_enabled)
 2405                 return (0);
 2406 
 2407         subj = SLOT(cred->cr_label);
 2408         obj = SLOT(shmseglabel);
 2409 
 2410         switch(cmd) {
 2411         case IPC_RMID:
 2412         case IPC_SET:
 2413                 if (!mls_dominate_effective(obj, subj))
 2414                         return (EACCES);
 2415                 break;
 2416 
 2417         case IPC_STAT:
 2418         case SHM_STAT:
 2419                 if (!mls_dominate_effective(subj, obj))
 2420                         return (EACCES);
 2421                 break;
 2422 
 2423         default:
 2424                 return (EACCES);
 2425         }
 2426 
 2427         return (0);
 2428 }
 2429 
 2430 static int
 2431 mls_sysvshm_check_shmget(struct ucred *cred, struct shmid_kernel *shmsegptr,
 2432     struct label *shmseglabel, int shmflg)
 2433 {
 2434         struct mac_mls *subj, *obj;
 2435 
 2436         if (!mls_enabled)
 2437                 return (0);
 2438 
 2439         subj = SLOT(cred->cr_label);
 2440         obj = SLOT(shmseglabel);
 2441 
 2442         if (!mls_dominate_effective(obj, subj))
 2443                 return (EACCES);
 2444 
 2445         return (0);
 2446 }
 2447 
 2448 static void
 2449 mls_sysvshm_cleanup(struct label *shmlabel)
 2450 {
 2451 
 2452         bzero(SLOT(shmlabel), sizeof(struct mac_mls));
 2453 }
 2454 
 2455 static void
 2456 mls_sysvshm_create(struct ucred *cred, struct shmid_kernel *shmsegptr,
 2457     struct label *shmlabel)
 2458 {
 2459         struct mac_mls *source, *dest;
 2460 
 2461         source = SLOT(cred->cr_label);
 2462         dest = SLOT(shmlabel);
 2463 
 2464         mls_copy_effective(source, dest);
 2465 }
 2466 
 2467 static int
 2468 mls_vnode_associate_extattr(struct mount *mp, struct label *mplabel,
 2469     struct vnode *vp, struct label *vplabel)
 2470 {
 2471         struct mac_mls mm_temp, *source, *dest;
 2472         int buflen, error;
 2473 
 2474         source = SLOT(mplabel);
 2475         dest = SLOT(vplabel);
 2476 
 2477         buflen = sizeof(mm_temp);
 2478         bzero(&mm_temp, buflen);
 2479 
 2480         error = vn_extattr_get(vp, IO_NODELOCKED, MAC_MLS_EXTATTR_NAMESPACE,
 2481             MAC_MLS_EXTATTR_NAME, &buflen, (char *) &mm_temp, curthread);
 2482         if (error == ENOATTR || error == EOPNOTSUPP) {
 2483                 /* Fall back to the mntlabel. */
 2484                 mls_copy_effective(source, dest);
 2485                 return (0);
 2486         } else if (error)
 2487                 return (error);
 2488 
 2489         if (buflen != sizeof(mm_temp)) {
 2490                 printf("mls_vnode_associate_extattr: bad size %d\n", buflen);
 2491                 return (EPERM);
 2492         }
 2493         if (mls_valid(&mm_temp) != 0) {
 2494                 printf("mls_vnode_associate_extattr: invalid\n");
 2495                 return (EPERM);
 2496         }
 2497         if ((mm_temp.mm_flags & MAC_MLS_FLAGS_BOTH) !=
 2498             MAC_MLS_FLAG_EFFECTIVE) {
 2499                 printf("mls_associated_vnode_extattr: not effective\n");
 2500                 return (EPERM);
 2501         }
 2502 
 2503         mls_copy_effective(&mm_temp, dest);
 2504         return (0);
 2505 }
 2506 
 2507 static void
 2508 mls_vnode_associate_singlelabel(struct mount *mp, struct label *mplabel,
 2509     struct vnode *vp, struct label *vplabel)
 2510 {
 2511         struct mac_mls *source, *dest;
 2512 
 2513         source = SLOT(mplabel);
 2514         dest = SLOT(vplabel);
 2515 
 2516         mls_copy_effective(source, dest);
 2517 }
 2518 
 2519 static int
 2520 mls_vnode_check_chdir(struct ucred *cred, struct vnode *dvp,
 2521     struct label *dvplabel)
 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(subj, obj))
 2532                 return (EACCES);
 2533 
 2534         return (0);
 2535 }
 2536 
 2537 static int
 2538 mls_vnode_check_chroot(struct ucred *cred, struct vnode *dvp,
 2539     struct label *dvplabel)
 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(dvplabel);
 2548 
 2549         if (!mls_dominate_effective(subj, obj))
 2550                 return (EACCES);
 2551 
 2552         return (0);
 2553 }
 2554 
 2555 static int
 2556 mls_vnode_check_create(struct ucred *cred, struct vnode *dvp,
 2557     struct label *dvplabel, struct componentname *cnp, struct vattr *vap)
 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(dvplabel);
 2566 
 2567         if (!mls_dominate_effective(obj, subj))
 2568                 return (EACCES);
 2569 
 2570         return (0);
 2571 }
 2572 
 2573 static int
 2574 mls_vnode_check_deleteacl(struct ucred *cred, struct vnode *vp,
 2575     struct label *vplabel, acl_type_t type)
 2576 {
 2577         struct mac_mls *subj, *obj;
 2578 
 2579         if (!mls_enabled)
 2580                 return (0);
 2581 
 2582         subj = SLOT(cred->cr_label);
 2583         obj = SLOT(vplabel);
 2584 
 2585         if (!mls_dominate_effective(obj, subj))
 2586                 return (EACCES);
 2587 
 2588         return (0);
 2589 }
 2590 
 2591 static int
 2592 mls_vnode_check_deleteextattr(struct ucred *cred, struct vnode *vp,
 2593     struct label *vplabel, int attrnamespace, const char *name)
 2594 {
 2595         struct mac_mls *subj, *obj;
 2596 
 2597         if (!mls_enabled)
 2598                 return (0);
 2599 
 2600         subj = SLOT(cred->cr_label);
 2601         obj = SLOT(vplabel);
 2602 
 2603         if (!mls_dominate_effective(obj, subj))
 2604                 return (EACCES);
 2605 
 2606         return (0);
 2607 }
 2608 
 2609 static int
 2610 mls_vnode_check_exec(struct ucred *cred, struct vnode *vp,
 2611     struct label *vplabel, struct image_params *imgp,
 2612     struct label *execlabel)
 2613 {
 2614         struct mac_mls *subj, *obj, *exec;
 2615         int error;
 2616 
 2617         if (execlabel != NULL) {
 2618                 /*
 2619                  * We currently don't permit labels to be changed at
 2620                  * exec-time as part of MLS, so disallow non-NULL MLS label
 2621                  * elements in the execlabel.
 2622                  */
 2623                 exec = SLOT(execlabel);
 2624                 error = mls_atmostflags(exec, 0);
 2625                 if (error)
 2626                         return (error);
 2627         }
 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_getacl(struct ucred *cred, struct vnode *vp,
 2643     struct label *vplabel, acl_type_t type)
 2644 {
 2645         struct mac_mls *subj, *obj;
 2646 
 2647         if (!mls_enabled)
 2648                 return (0);
 2649 
 2650         subj = SLOT(cred->cr_label);
 2651         obj = SLOT(vplabel);
 2652 
 2653         if (!mls_dominate_effective(subj, obj))
 2654                 return (EACCES);
 2655 
 2656         return (0);
 2657 }
 2658 
 2659 static int
 2660 mls_vnode_check_getextattr(struct ucred *cred, struct vnode *vp,
 2661     struct label *vplabel, int attrnamespace, const char *name)
 2662 {
 2663         struct mac_mls *subj, *obj;
 2664 
 2665         if (!mls_enabled)
 2666                 return (0);
 2667 
 2668         subj = SLOT(cred->cr_label);
 2669         obj = SLOT(vplabel);
 2670 
 2671         if (!mls_dominate_effective(subj, obj))
 2672                 return (EACCES);
 2673 
 2674         return (0);
 2675 }
 2676 
 2677 static int
 2678 mls_vnode_check_link(struct ucred *cred, struct vnode *dvp,
 2679     struct label *dvplabel, struct vnode *vp, struct label *vplabel,
 2680     struct componentname *cnp)
 2681 {
 2682         struct mac_mls *subj, *obj;
 2683 
 2684         if (!mls_enabled)
 2685                 return (0);
 2686 
 2687         subj = SLOT(cred->cr_label);
 2688         obj = SLOT(dvplabel);
 2689 
 2690         if (!mls_dominate_effective(obj, subj))
 2691                 return (EACCES);
 2692 
 2693         obj = SLOT(vplabel);
 2694         if (!mls_dominate_effective(obj, subj))
 2695                 return (EACCES);
 2696 
 2697         return (0);
 2698 }
 2699 
 2700 static int
 2701 mls_vnode_check_listextattr(struct ucred *cred, struct vnode *vp,
 2702     struct label *vplabel, int attrnamespace)
 2703 {
 2704 
 2705         struct mac_mls *subj, *obj;
 2706 
 2707         if (!mls_enabled)
 2708                 return (0);
 2709 
 2710         subj = SLOT(cred->cr_label);
 2711         obj = SLOT(vplabel);
 2712 
 2713         if (!mls_dominate_effective(subj, obj))
 2714                 return (EACCES);
 2715 
 2716         return (0);
 2717 }
 2718 
 2719 static int
 2720 mls_vnode_check_lookup(struct ucred *cred, struct vnode *dvp,
 2721     struct label *dvplabel, struct componentname *cnp)
 2722 {
 2723         struct mac_mls *subj, *obj;
 2724 
 2725         if (!mls_enabled)
 2726                 return (0);
 2727 
 2728         subj = SLOT(cred->cr_label);
 2729         obj = SLOT(dvplabel);
 2730 
 2731         if (!mls_dominate_effective(subj, obj))
 2732                 return (EACCES);
 2733 
 2734         return (0);
 2735 }
 2736 
 2737 static int
 2738 mls_vnode_check_mmap(struct ucred *cred, struct vnode *vp,
 2739     struct label *vplabel, int prot, int flags)
 2740 {
 2741         struct mac_mls *subj, *obj;
 2742 
 2743         /*
 2744          * Rely on the use of open()-time protections to handle
 2745          * non-revocation cases.
 2746          */
 2747         if (!mls_enabled || !revocation_enabled)
 2748                 return (0);
 2749 
 2750         subj = SLOT(cred->cr_label);
 2751         obj = SLOT(vplabel);
 2752 
 2753         if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
 2754                 if (!mls_dominate_effective(subj, obj))
 2755                         return (EACCES);
 2756         }
 2757         if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) {
 2758                 if (!mls_dominate_effective(obj, subj))
 2759                         return (EACCES);
 2760         }
 2761 
 2762         return (0);
 2763 }
 2764 
 2765 static int
 2766 mls_vnode_check_open(struct ucred *cred, struct vnode *vp,
 2767     struct label *vplabel, accmode_t accmode)
 2768 {
 2769         struct mac_mls *subj, *obj;
 2770 
 2771         if (!mls_enabled)
 2772                 return (0);
 2773 
 2774         subj = SLOT(cred->cr_label);
 2775         obj = SLOT(vplabel);
 2776 
 2777         /* XXX privilege override for admin? */
 2778         if (accmode & (VREAD | VEXEC | VSTAT_PERMS)) {
 2779                 if (!mls_dominate_effective(subj, obj))
 2780                         return (EACCES);
 2781         }
 2782         if (accmode & VMODIFY_PERMS) {
 2783                 if (!mls_dominate_effective(obj, subj))
 2784                         return (EACCES);
 2785         }
 2786 
 2787         return (0);
 2788 }
 2789 
 2790 static int
 2791 mls_vnode_check_poll(struct ucred *active_cred, struct ucred *file_cred,
 2792     struct vnode *vp, struct label *vplabel)
 2793 {
 2794         struct mac_mls *subj, *obj;
 2795 
 2796         if (!mls_enabled || !revocation_enabled)
 2797                 return (0);
 2798 
 2799         subj = SLOT(active_cred->cr_label);
 2800         obj = SLOT(vplabel);
 2801 
 2802         if (!mls_dominate_effective(subj, obj))
 2803                 return (EACCES);
 2804 
 2805         return (0);
 2806 }
 2807 
 2808 static int
 2809 mls_vnode_check_read(struct ucred *active_cred, struct ucred *file_cred,
 2810     struct vnode *vp, struct label *vplabel)
 2811 {
 2812         struct mac_mls *subj, *obj;
 2813 
 2814         if (!mls_enabled || !revocation_enabled)
 2815                 return (0);
 2816 
 2817         subj = SLOT(active_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_readdir(struct ucred *cred, struct vnode *dvp,
 2828     struct label *dvplabel)
 2829 {
 2830         struct mac_mls *subj, *obj;
 2831 
 2832         if (!mls_enabled)
 2833                 return (0);
 2834 
 2835         subj = SLOT(cred->cr_label);
 2836         obj = SLOT(dvplabel);
 2837 
 2838         if (!mls_dominate_effective(subj, obj))
 2839                 return (EACCES);
 2840 
 2841         return (0);
 2842 }
 2843 
 2844 static int
 2845 mls_vnode_check_readlink(struct ucred *cred, struct vnode *vp,
 2846     struct label *vplabel)
 2847 {
 2848         struct mac_mls *subj, *obj;
 2849 
 2850         if (!mls_enabled)
 2851                 return (0);
 2852 
 2853         subj = SLOT(cred->cr_label);
 2854         obj = SLOT(vplabel);
 2855 
 2856         if (!mls_dominate_effective(subj, obj))
 2857                 return (EACCES);
 2858 
 2859         return (0);
 2860 }
 2861 
 2862 static int
 2863 mls_vnode_check_relabel(struct ucred *cred, struct vnode *vp,
 2864     struct label *vplabel, struct label *newlabel)
 2865 {
 2866         struct mac_mls *old, *new, *subj;
 2867         int error;
 2868 
 2869         old = SLOT(vplabel);
 2870         new = SLOT(newlabel);
 2871         subj = SLOT(cred->cr_label);
 2872 
 2873         /*
 2874          * If there is an MLS label update for the vnode, it must be a
 2875          * effective label.
 2876          */
 2877         error = mls_atmostflags(new, MAC_MLS_FLAG_EFFECTIVE);
 2878         if (error)
 2879                 return (error);
 2880 
 2881         /*
 2882          * To perform a relabel of the vnode (MLS label or not), MLS must
 2883          * authorize the relabel.
 2884          */
 2885         if (!mls_effective_in_range(old, subj))
 2886                 return (EPERM);
 2887 
 2888         /*
 2889          * If the MLS label is to be changed, authorize as appropriate.
 2890          */
 2891         if (new->mm_flags & MAC_MLS_FLAG_EFFECTIVE) {
 2892                 /*
 2893                  * To change the MLS label on a vnode, the new vnode label
 2894                  * must be in the subject range.
 2895                  */
 2896                 if (!mls_effective_in_range(new, subj))
 2897                         return (EPERM);
 2898 
 2899                 /*
 2900                  * To change the MLS label on the vnode to be EQUAL, the
 2901                  * subject must have appropriate privilege.
 2902                  */
 2903                 if (mls_contains_equal(new)) {
 2904                         error = mls_subject_privileged(subj);
 2905                         if (error)
 2906                                 return (error);
 2907                 }
 2908         }
 2909 
 2910         return (0);
 2911 }
 2912 
 2913 static int
 2914 mls_vnode_check_rename_from(struct ucred *cred, struct vnode *dvp,
 2915     struct label *dvplabel, struct vnode *vp, struct label *vplabel,
 2916     struct componentname *cnp)
 2917 {
 2918         struct mac_mls *subj, *obj;
 2919 
 2920         if (!mls_enabled)
 2921                 return (0);
 2922 
 2923         subj = SLOT(cred->cr_label);
 2924         obj = SLOT(dvplabel);
 2925 
 2926         if (!mls_dominate_effective(obj, subj))
 2927                 return (EACCES);
 2928 
 2929         obj = SLOT(vplabel);
 2930 
 2931         if (!mls_dominate_effective(obj, subj))
 2932                 return (EACCES);
 2933 
 2934         return (0);
 2935 }
 2936 
 2937 static int
 2938 mls_vnode_check_rename_to(struct ucred *cred, struct vnode *dvp,
 2939     struct label *dvplabel, struct vnode *vp, struct label *vplabel,
 2940     int samedir, struct componentname *cnp)
 2941 {
 2942         struct mac_mls *subj, *obj;
 2943 
 2944         if (!mls_enabled)
 2945                 return (0);
 2946 
 2947         subj = SLOT(cred->cr_label);
 2948         obj = SLOT(dvplabel);
 2949 
 2950         if (!mls_dominate_effective(obj, subj))
 2951                 return (EACCES);
 2952 
 2953         if (vp != NULL) {
 2954                 obj = SLOT(vplabel);
 2955 
 2956                 if (!mls_dominate_effective(obj, subj))
 2957                         return (EACCES);
 2958         }
 2959 
 2960         return (0);
 2961 }
 2962 
 2963 static int
 2964 mls_vnode_check_revoke(struct ucred *cred, struct vnode *vp,
 2965     struct label *vplabel)
 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         return (0);
 2979 }
 2980 
 2981 static int
 2982 mls_vnode_check_setacl(struct ucred *cred, struct vnode *vp,
 2983     struct label *vplabel, acl_type_t type, struct acl *acl)
 2984 {
 2985         struct mac_mls *subj, *obj;
 2986 
 2987         if (!mls_enabled)
 2988                 return (0);
 2989 
 2990         subj = SLOT(cred->cr_label);
 2991         obj = SLOT(vplabel);
 2992 
 2993         if (!mls_dominate_effective(obj, subj))
 2994                 return (EACCES);
 2995 
 2996         return (0);
 2997 }
 2998 
 2999 static int
 3000 mls_vnode_check_setextattr(struct ucred *cred, struct vnode *vp,
 3001     struct label *vplabel, int attrnamespace, const char *name)
 3002 {
 3003         struct mac_mls *subj, *obj;
 3004 
 3005         if (!mls_enabled)
 3006                 return (0);
 3007 
 3008         subj = SLOT(cred->cr_label);
 3009         obj = SLOT(vplabel);
 3010 
 3011         if (!mls_dominate_effective(obj, subj))
 3012                 return (EACCES);
 3013 
 3014         /* XXX: protect the MAC EA in a special way? */
 3015 
 3016         return (0);
 3017 }
 3018 
 3019 static int
 3020 mls_vnode_check_setflags(struct ucred *cred, struct vnode *vp,
 3021     struct label *vplabel, u_long flags)
 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_setmode(struct ucred *cred, struct vnode *vp,
 3039     struct label *vplabel, mode_t mode)
 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_setowner(struct ucred *cred, struct vnode *vp,
 3057     struct label *vplabel, uid_t uid, gid_t gid)
 3058 {
 3059         struct mac_mls *subj, *obj;
 3060 
 3061         if (!mls_enabled)
 3062                 return (0);
 3063 
 3064         subj = SLOT(cred->cr_label);
 3065         obj = SLOT(vplabel);
 3066 
 3067         if (!mls_dominate_effective(obj, subj))
 3068                 return (EACCES);
 3069 
 3070         return (0);
 3071 }
 3072 
 3073 static int
 3074 mls_vnode_check_setutimes(struct ucred *cred, struct vnode *vp,
 3075     struct label *vplabel, struct timespec atime, struct timespec mtime)
 3076 {
 3077         struct mac_mls *subj, *obj;
 3078 
 3079         if (!mls_enabled)
 3080                 return (0);
 3081 
 3082         subj = SLOT(cred->cr_label);
 3083         obj = SLOT(vplabel);
 3084 
 3085         if (!mls_dominate_effective(obj, subj))
 3086                 return (EACCES);
 3087 
 3088         return (0);
 3089 }
 3090 
 3091 static int
 3092 mls_vnode_check_stat(struct ucred *active_cred, struct ucred *file_cred,
 3093     struct vnode *vp, struct label *vplabel)
 3094 {
 3095         struct mac_mls *subj, *obj;
 3096 
 3097         if (!mls_enabled)
 3098                 return (0);
 3099 
 3100         subj = SLOT(active_cred->cr_label);
 3101         obj = SLOT(vplabel);
 3102 
 3103         if (!mls_dominate_effective(subj, obj))
 3104                 return (EACCES);
 3105 
 3106         return (0);
 3107 }
 3108 
 3109 static int
 3110 mls_vnode_check_unlink(struct ucred *cred, struct vnode *dvp,
 3111     struct label *dvplabel, struct vnode *vp, struct label *vplabel,
 3112     struct componentname *cnp)
 3113 {
 3114         struct mac_mls *subj, *obj;
 3115 
 3116         if (!mls_enabled)
 3117                 return (0);
 3118 
 3119         subj = SLOT(cred->cr_label);
 3120         obj = SLOT(dvplabel);
 3121 
 3122         if (!mls_dominate_effective(obj, subj))
 3123                 return (EACCES);
 3124 
 3125         obj = SLOT(vplabel);
 3126 
 3127         if (!mls_dominate_effective(obj, subj))
 3128                 return (EACCES);
 3129 
 3130         return (0);
 3131 }
 3132 
 3133 static int
 3134 mls_vnode_check_write(struct ucred *active_cred, struct ucred *file_cred,
 3135     struct vnode *vp, struct label *vplabel)
 3136 {
 3137         struct mac_mls *subj, *obj;
 3138 
 3139         if (!mls_enabled || !revocation_enabled)
 3140                 return (0);
 3141 
 3142         subj = SLOT(active_cred->cr_label);
 3143         obj = SLOT(vplabel);
 3144 
 3145         if (!mls_dominate_effective(obj, subj))
 3146                 return (EACCES);
 3147 
 3148         return (0);
 3149 }
 3150 
 3151 static int
 3152 mls_vnode_create_extattr(struct ucred *cred, struct mount *mp,
 3153     struct label *mplabel, struct vnode *dvp, struct label *dvplabel,
 3154     struct vnode *vp, struct label *vplabel, struct componentname *cnp)
 3155 {
 3156         struct mac_mls *source, *dest, mm_temp;
 3157         size_t buflen;
 3158         int error;
 3159 
 3160         buflen = sizeof(mm_temp);
 3161         bzero(&mm_temp, buflen);
 3162 
 3163         source = SLOT(cred->cr_label);
 3164         dest = SLOT(vplabel);
 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         if (error == 0)
 3170                 mls_copy_effective(source, dest);
 3171         return (error);
 3172 }
 3173 
 3174 static void
 3175 mls_vnode_relabel(struct ucred *cred, struct vnode *vp,
 3176     struct label *vplabel, struct label *label)
 3177 {
 3178         struct mac_mls *source, *dest;
 3179 
 3180         source = SLOT(label);
 3181         dest = SLOT(vplabel);
 3182 
 3183         mls_copy(source, dest);
 3184 }
 3185 
 3186 static int
 3187 mls_vnode_setlabel_extattr(struct ucred *cred, struct vnode *vp,
 3188     struct label *vplabel, struct label *intlabel)
 3189 {
 3190         struct mac_mls *source, mm_temp;
 3191         size_t buflen;
 3192         int error;
 3193 
 3194         buflen = sizeof(mm_temp);
 3195         bzero(&mm_temp, buflen);
 3196 
 3197         source = SLOT(intlabel);
 3198         if ((source->mm_flags & MAC_MLS_FLAG_EFFECTIVE) == 0)
 3199                 return (0);
 3200 
 3201         mls_copy_effective(source, &mm_temp);
 3202 
 3203         error = vn_extattr_set(vp, IO_NODELOCKED, MAC_MLS_EXTATTR_NAMESPACE,
 3204             MAC_MLS_EXTATTR_NAME, buflen, (char *) &mm_temp, curthread);
 3205         return (error);
 3206 }
 3207 
 3208 static struct mac_policy_ops mls_ops =
 3209 {
 3210         .mpo_init = mls_init,
 3211 
 3212         .mpo_bpfdesc_check_receive = mls_bpfdesc_check_receive,
 3213         .mpo_bpfdesc_create = mls_bpfdesc_create,
 3214         .mpo_bpfdesc_create_mbuf = mls_bpfdesc_create_mbuf,
 3215         .mpo_bpfdesc_destroy_label = mls_destroy_label,
 3216         .mpo_bpfdesc_init_label = mls_init_label,
 3217 
 3218         .mpo_cred_associate_nfsd = mls_cred_associate_nfsd,
 3219         .mpo_cred_check_relabel = mls_cred_check_relabel,
 3220         .mpo_cred_check_visible = mls_cred_check_visible,
 3221         .mpo_cred_copy_label = mls_copy_label,
 3222         .mpo_cred_create_init = mls_cred_create_init,
 3223         .mpo_cred_create_swapper = mls_cred_create_swapper,
 3224         .mpo_cred_destroy_label = mls_destroy_label,
 3225         .mpo_cred_externalize_label = mls_externalize_label,
 3226         .mpo_cred_init_label = mls_init_label,
 3227         .mpo_cred_internalize_label = mls_internalize_label,
 3228         .mpo_cred_relabel = mls_cred_relabel,
 3229 
 3230         .mpo_devfs_create_device = mls_devfs_create_device,
 3231         .mpo_devfs_create_directory = mls_devfs_create_directory,
 3232         .mpo_devfs_create_symlink = mls_devfs_create_symlink,
 3233         .mpo_devfs_destroy_label = mls_destroy_label,
 3234         .mpo_devfs_init_label = mls_init_label,
 3235         .mpo_devfs_update = mls_devfs_update,
 3236         .mpo_devfs_vnode_associate = mls_devfs_vnode_associate,
 3237 
 3238         .mpo_ifnet_check_relabel = mls_ifnet_check_relabel,
 3239         .mpo_ifnet_check_transmit = mls_ifnet_check_transmit,
 3240         .mpo_ifnet_copy_label = mls_copy_label,
 3241         .mpo_ifnet_create = mls_ifnet_create,
 3242         .mpo_ifnet_create_mbuf = mls_ifnet_create_mbuf,
 3243         .mpo_ifnet_destroy_label = mls_destroy_label,
 3244         .mpo_ifnet_externalize_label = mls_externalize_label,
 3245         .mpo_ifnet_init_label = mls_init_label,
 3246         .mpo_ifnet_internalize_label = mls_internalize_label,
 3247         .mpo_ifnet_relabel = mls_ifnet_relabel,
 3248 
 3249         .mpo_inpcb_check_deliver = mls_inpcb_check_deliver,
 3250         .mpo_inpcb_check_visible = mls_inpcb_check_visible,
 3251         .mpo_inpcb_create = mls_inpcb_create,
 3252         .mpo_inpcb_create_mbuf = mls_inpcb_create_mbuf,
 3253         .mpo_inpcb_destroy_label = mls_destroy_label,
 3254         .mpo_inpcb_init_label = mls_init_label_waitcheck,
 3255         .mpo_inpcb_sosetlabel = mls_inpcb_sosetlabel,
 3256 
 3257         .mpo_ip6q_create = mls_ip6q_create,
 3258         .mpo_ip6q_destroy_label = mls_destroy_label,
 3259         .mpo_ip6q_init_label = mls_init_label_waitcheck,
 3260         .mpo_ip6q_match = mls_ip6q_match,
 3261         .mpo_ip6q_reassemble = mls_ip6q_reassemble,
 3262         .mpo_ip6q_update = mls_ip6q_update,
 3263 
 3264         .mpo_ipq_create = mls_ipq_create,
 3265         .mpo_ipq_destroy_label = mls_destroy_label,
 3266         .mpo_ipq_init_label = mls_init_label_waitcheck,
 3267         .mpo_ipq_match = mls_ipq_match,
 3268         .mpo_ipq_reassemble = mls_ipq_reassemble,
 3269         .mpo_ipq_update = mls_ipq_update,
 3270 
 3271         .mpo_mbuf_copy_label = mls_copy_label,
 3272         .mpo_mbuf_destroy_label = mls_destroy_label,
 3273         .mpo_mbuf_init_label = mls_init_label_waitcheck,
 3274 
 3275         .mpo_mount_check_stat = mls_mount_check_stat,
 3276         .mpo_mount_create = mls_mount_create,
 3277         .mpo_mount_destroy_label = mls_destroy_label,
 3278         .mpo_mount_init_label = mls_init_label,
 3279 
 3280         .mpo_netatalk_aarp_send = mls_netatalk_aarp_send,
 3281 
 3282         .mpo_netinet_arp_send = mls_netinet_arp_send,
 3283         .mpo_netinet_firewall_reply = mls_netinet_firewall_reply,
 3284         .mpo_netinet_firewall_send = mls_netinet_firewall_send,
 3285         .mpo_netinet_fragment = mls_netinet_fragment,
 3286         .mpo_netinet_icmp_reply = mls_netinet_icmp_reply,
 3287         .mpo_netinet_igmp_send = mls_netinet_igmp_send,
 3288 
 3289         .mpo_netinet6_nd6_send = mls_netinet6_nd6_send,
 3290 
 3291         .mpo_pipe_check_ioctl = mls_pipe_check_ioctl,
 3292         .mpo_pipe_check_poll = mls_pipe_check_poll,
 3293         .mpo_pipe_check_read = mls_pipe_check_read,
 3294         .mpo_pipe_check_relabel = mls_pipe_check_relabel,
 3295         .mpo_pipe_check_stat = mls_pipe_check_stat,
 3296         .mpo_pipe_check_write = mls_pipe_check_write,
 3297         .mpo_pipe_copy_label = mls_copy_label,
 3298         .mpo_pipe_create = mls_pipe_create,
 3299         .mpo_pipe_destroy_label = mls_destroy_label,
 3300         .mpo_pipe_externalize_label = mls_externalize_label,
 3301         .mpo_pipe_init_label = mls_init_label,
 3302         .mpo_pipe_internalize_label = mls_internalize_label,
 3303         .mpo_pipe_relabel = mls_pipe_relabel,
 3304 
 3305         .mpo_posixsem_check_getvalue = mls_posixsem_check_rdonly,
 3306         .mpo_posixsem_check_open = mls_posixsem_check_openunlink,
 3307         .mpo_posixsem_check_post = mls_posixsem_check_write,
 3308         .mpo_posixsem_check_setmode = mls_posixsem_check_setmode,
 3309         .mpo_posixsem_check_setowner = mls_posixsem_check_setowner,
 3310         .mpo_posixsem_check_stat = mls_posixsem_check_rdonly,
 3311         .mpo_posixsem_check_unlink = mls_posixsem_check_openunlink,
 3312         .mpo_posixsem_check_wait = mls_posixsem_check_write,
 3313         .mpo_posixsem_create = mls_posixsem_create,
 3314         .mpo_posixsem_destroy_label = mls_destroy_label,
 3315         .mpo_posixsem_init_label = mls_init_label,
 3316 
 3317         .mpo_posixshm_check_mmap = mls_posixshm_check_mmap,
 3318         .mpo_posixshm_check_open = mls_posixshm_check_open,
 3319         .mpo_posixshm_check_read = mls_posixshm_check_read,
 3320         .mpo_posixshm_check_setmode = mls_posixshm_check_setmode,
 3321         .mpo_posixshm_check_setowner = mls_posixshm_check_setowner,
 3322         .mpo_posixshm_check_stat = mls_posixshm_check_stat,
 3323         .mpo_posixshm_check_truncate = mls_posixshm_check_truncate,
 3324         .mpo_posixshm_check_unlink = mls_posixshm_check_unlink,
 3325         .mpo_posixshm_check_write = mls_posixshm_check_write,
 3326         .mpo_posixshm_create = mls_posixshm_create,
 3327         .mpo_posixshm_destroy_label = mls_destroy_label,
 3328         .mpo_posixshm_init_label = mls_init_label,
 3329 
 3330         .mpo_proc_check_debug = mls_proc_check_debug,
 3331         .mpo_proc_check_sched = mls_proc_check_sched,
 3332         .mpo_proc_check_signal = mls_proc_check_signal,
 3333 
 3334         .mpo_socket_check_deliver = mls_socket_check_deliver,
 3335         .mpo_socket_check_relabel = mls_socket_check_relabel,
 3336         .mpo_socket_check_visible = mls_socket_check_visible,
 3337         .mpo_socket_copy_label = mls_copy_label,
 3338         .mpo_socket_create = mls_socket_create,
 3339         .mpo_socket_create_mbuf = mls_socket_create_mbuf,
 3340         .mpo_socket_destroy_label = mls_destroy_label,
 3341         .mpo_socket_externalize_label = mls_externalize_label,
 3342         .mpo_socket_init_label = mls_init_label_waitcheck,
 3343         .mpo_socket_internalize_label = mls_internalize_label,
 3344         .mpo_socket_newconn = mls_socket_newconn,
 3345         .mpo_socket_relabel = mls_socket_relabel,
 3346 
 3347         .mpo_socketpeer_destroy_label = mls_destroy_label,
 3348         .mpo_socketpeer_externalize_label = mls_externalize_label,
 3349         .mpo_socketpeer_init_label = mls_init_label_waitcheck,
 3350         .mpo_socketpeer_set_from_mbuf = mls_socketpeer_set_from_mbuf,
 3351         .mpo_socketpeer_set_from_socket = mls_socketpeer_set_from_socket,
 3352 
 3353         .mpo_syncache_create = mls_syncache_create,
 3354         .mpo_syncache_create_mbuf = mls_syncache_create_mbuf,
 3355         .mpo_syncache_destroy_label = mls_destroy_label,
 3356         .mpo_syncache_init_label = mls_init_label_waitcheck,
 3357 
 3358         .mpo_sysvmsg_cleanup = mls_sysvmsg_cleanup,
 3359         .mpo_sysvmsg_create = mls_sysvmsg_create,
 3360         .mpo_sysvmsg_destroy_label = mls_destroy_label,
 3361         .mpo_sysvmsg_init_label = mls_init_label,
 3362 
 3363         .mpo_sysvmsq_check_msgrcv = mls_sysvmsq_check_msgrcv,
 3364         .mpo_sysvmsq_check_msgrmid = mls_sysvmsq_check_msgrmid,
 3365         .mpo_sysvmsq_check_msqget = mls_sysvmsq_check_msqget,
 3366         .mpo_sysvmsq_check_msqsnd = mls_sysvmsq_check_msqsnd,
 3367         .mpo_sysvmsq_check_msqrcv = mls_sysvmsq_check_msqrcv,
 3368         .mpo_sysvmsq_check_msqctl = mls_sysvmsq_check_msqctl,
 3369         .mpo_sysvmsq_cleanup = mls_sysvmsq_cleanup,
 3370         .mpo_sysvmsq_destroy_label = mls_destroy_label,
 3371         .mpo_sysvmsq_init_label = mls_init_label,
 3372         .mpo_sysvmsq_create = mls_sysvmsq_create,
 3373 
 3374         .mpo_sysvsem_check_semctl = mls_sysvsem_check_semctl,
 3375         .mpo_sysvsem_check_semget = mls_sysvsem_check_semget,
 3376         .mpo_sysvsem_check_semop = mls_sysvsem_check_semop,
 3377         .mpo_sysvsem_cleanup = mls_sysvsem_cleanup,
 3378         .mpo_sysvsem_create = mls_sysvsem_create,
 3379         .mpo_sysvsem_destroy_label = mls_destroy_label,
 3380         .mpo_sysvsem_init_label = mls_init_label,
 3381 
 3382         .mpo_sysvshm_check_shmat = mls_sysvshm_check_shmat,
 3383         .mpo_sysvshm_check_shmctl = mls_sysvshm_check_shmctl,
 3384         .mpo_sysvshm_check_shmget = mls_sysvshm_check_shmget,
 3385         .mpo_sysvshm_cleanup = mls_sysvshm_cleanup,
 3386         .mpo_sysvshm_create = mls_sysvshm_create,
 3387         .mpo_sysvshm_destroy_label = mls_destroy_label,
 3388         .mpo_sysvshm_init_label = mls_init_label,
 3389 
 3390 
 3391         .mpo_system_check_acct = mls_system_check_acct,
 3392         .mpo_system_check_auditctl = mls_system_check_auditctl,
 3393         .mpo_system_check_swapon = mls_system_check_swapon,
 3394 
 3395         .mpo_vnode_associate_extattr = mls_vnode_associate_extattr,
 3396         .mpo_vnode_associate_singlelabel = mls_vnode_associate_singlelabel,
 3397         .mpo_vnode_check_access = mls_vnode_check_open,
 3398         .mpo_vnode_check_chdir = mls_vnode_check_chdir,
 3399         .mpo_vnode_check_chroot = mls_vnode_check_chroot,
 3400         .mpo_vnode_check_create = mls_vnode_check_create,
 3401         .mpo_vnode_check_deleteacl = mls_vnode_check_deleteacl,
 3402         .mpo_vnode_check_deleteextattr = mls_vnode_check_deleteextattr,
 3403         .mpo_vnode_check_exec = mls_vnode_check_exec,
 3404         .mpo_vnode_check_getacl = mls_vnode_check_getacl,
 3405         .mpo_vnode_check_getextattr = mls_vnode_check_getextattr,
 3406         .mpo_vnode_check_link = mls_vnode_check_link,
 3407         .mpo_vnode_check_listextattr = mls_vnode_check_listextattr,
 3408         .mpo_vnode_check_lookup = mls_vnode_check_lookup,
 3409         .mpo_vnode_check_mmap = mls_vnode_check_mmap,
 3410         .mpo_vnode_check_open = mls_vnode_check_open,
 3411         .mpo_vnode_check_poll = mls_vnode_check_poll,
 3412         .mpo_vnode_check_read = mls_vnode_check_read,
 3413         .mpo_vnode_check_readdir = mls_vnode_check_readdir,
 3414         .mpo_vnode_check_readlink = mls_vnode_check_readlink,
 3415         .mpo_vnode_check_relabel = mls_vnode_check_relabel,
 3416         .mpo_vnode_check_rename_from = mls_vnode_check_rename_from,
 3417         .mpo_vnode_check_rename_to = mls_vnode_check_rename_to,
 3418         .mpo_vnode_check_revoke = mls_vnode_check_revoke,
 3419         .mpo_vnode_check_setacl = mls_vnode_check_setacl,
 3420         .mpo_vnode_check_setextattr = mls_vnode_check_setextattr,
 3421         .mpo_vnode_check_setflags = mls_vnode_check_setflags,
 3422         .mpo_vnode_check_setmode = mls_vnode_check_setmode,
 3423         .mpo_vnode_check_setowner = mls_vnode_check_setowner,
 3424         .mpo_vnode_check_setutimes = mls_vnode_check_setutimes,
 3425         .mpo_vnode_check_stat = mls_vnode_check_stat,
 3426         .mpo_vnode_check_unlink = mls_vnode_check_unlink,
 3427         .mpo_vnode_check_write = mls_vnode_check_write,
 3428         .mpo_vnode_copy_label = mls_copy_label,
 3429         .mpo_vnode_create_extattr = mls_vnode_create_extattr,
 3430         .mpo_vnode_destroy_label = mls_destroy_label,
 3431         .mpo_vnode_externalize_label = mls_externalize_label,
 3432         .mpo_vnode_init_label = mls_init_label,
 3433         .mpo_vnode_internalize_label = mls_internalize_label,
 3434         .mpo_vnode_relabel = mls_vnode_relabel,
 3435         .mpo_vnode_setlabel_extattr = mls_vnode_setlabel_extattr,
 3436 };
 3437 
 3438 MAC_POLICY_SET(&mls_ops, mac_mls, "TrustedBSD MAC/MLS",
 3439     MPC_LOADTIME_FLAG_NOTLATE, &mls_slot);

Cache object: 1b599fb34222f7860ab85ade20510a10


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