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

Cache object: fa28c6cfe1134580546b0aebdd658770


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