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

Cache object: 053975446fa8f31af28ee7b024b9def6


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