[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/security/mac_mls/mac_mls.c

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

    1 /*-
    2  * Copyright (c) 1999-2002 Robert N. M. Watson
    3  * Copyright (c) 2001-2005 McAfee, Inc.
    4  * All rights reserved.
    5  *
    6  * This software was developed by Robert Watson for the TrustedBSD Project.
    7  *
    8  * This software was developed for the FreeBSD Project in part by McAfee
    9  * Research, the Security Research Division of McAfee, Inc. under
   10  * DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA
   11  * CHATS research program.
   12  *
   13  * Redistribution and use in source and binary forms, with or without
   14  * modification, are permitted provided that the following conditions
   15  * are met:
   16  * 1. Redistributions of source code must retain the above copyright
   17  *    notice, this list of conditions and the following disclaimer.
   18  * 2. Redistributions in binary form must reproduce the above copyright
   19  *    notice, this list of conditions and the following disclaimer in the
   20  *    documentation and/or other materials provided with the distribution.
   21  *
   22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   32  * SUCH DAMAGE.
   33  *
   34  * $FreeBSD$
   35  */
   36 
   37 /*
   38  * Developed by the TrustedBSD Project.
   39  * MLS fixed label mandatory confidentiality policy.
   40  */
   41 
   42 #include <sys/types.h>
   43 #include <sys/param.h>
   44 #include <sys/acl.h>
   45 #include <sys/conf.h>
   46 #include <sys/extattr.h>
   47 #include <sys/kernel.h>
   48 #include <sys/mac.h>
   49 #include <sys/mman.h>
   50 #include <sys/malloc.h>
   51 #include <sys/mount.h>
   52 #include <sys/proc.h>
   53 #include <sys/sbuf.h>
   54 #include <sys/systm.h>
   55 #include <sys/sysproto.h>
   56 #include <sys/sysent.h>
   57 #include <sys/systm.h>
   58 #include <sys/vnode.h>
   59 #include <sys/file.h>
   60 #include <sys/socket.h>
   61 #include <sys/socketvar.h>
   62 #include <sys/pipe.h>
   63 #include <sys/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 static void
 1309 mac_mls_create_mbuf_from_firewall(struct mbuf *m, struct label *mbuflabel)
 1310 {
 1311         struct mac_mls *dest;
 1312 
 1313         dest = SLOT(mbuflabel);
 1314 
 1315         /* XXX: where is the label for the firewall really comming from? */
 1316         mac_mls_set_effective(dest, MAC_MLS_TYPE_EQUAL, 0, NULL);
 1317 }
 1318 
 1319 /*
 1320  * Labeling event operations: processes.
 1321  */
 1322 static void
 1323 mac_mls_create_proc0(struct ucred *cred)
 1324 {
 1325         struct mac_mls *dest;
 1326 
 1327         dest = SLOT(cred->cr_label);
 1328 
 1329         mac_mls_set_effective(dest, MAC_MLS_TYPE_EQUAL, 0, NULL);
 1330         mac_mls_set_range(dest, MAC_MLS_TYPE_LOW, 0, NULL, MAC_MLS_TYPE_HIGH,
 1331             0, NULL);
 1332 }
 1333 
 1334 static void
 1335 mac_mls_create_proc1(struct ucred *cred)
 1336 {
 1337         struct mac_mls *dest;
 1338 
 1339         dest = SLOT(cred->cr_label);
 1340 
 1341         mac_mls_set_effective(dest, MAC_MLS_TYPE_LOW, 0, NULL);
 1342         mac_mls_set_range(dest, MAC_MLS_TYPE_LOW, 0, NULL, MAC_MLS_TYPE_HIGH,
 1343             0, NULL);
 1344 }
 1345 
 1346 static void
 1347 mac_mls_relabel_cred(struct ucred *cred, struct label *newlabel)
 1348 {
 1349         struct mac_mls *source, *dest;
 1350 
 1351         source = SLOT(newlabel);
 1352         dest = SLOT(cred->cr_label);
 1353 
 1354         mac_mls_copy(source, dest);
 1355 }
 1356 
 1357 /*
 1358  * Label cleanup/flush operations.
 1359  */
 1360 static void
 1361 mac_mls_cleanup_sysv_msgmsg(struct label *msglabel)
 1362 {
 1363 
 1364         bzero(SLOT(msglabel), sizeof(struct mac_mls));
 1365 }
 1366 
 1367 static void
 1368 mac_mls_cleanup_sysv_msgqueue(struct label *msqlabel)
 1369 {
 1370 
 1371         bzero(SLOT(msqlabel), sizeof(struct mac_mls));
 1372 }
 1373 
 1374 static void
 1375 mac_mls_cleanup_sysv_sem(struct label *semalabel)
 1376 {
 1377 
 1378         bzero(SLOT(semalabel), sizeof(struct mac_mls));
 1379 }
 1380 
 1381 static void
 1382 mac_mls_cleanup_sysv_shm(struct label *shmlabel)
 1383 {
 1384 
 1385         bzero(SLOT(shmlabel), sizeof(struct mac_mls));
 1386 }
 1387 
 1388 /*
 1389  * Access control checks.
 1390  */
 1391 static int
 1392 mac_mls_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel,
 1393      struct ifnet *ifnet, struct label *ifnetlabel)
 1394 {
 1395         struct mac_mls *a, *b;
 1396 
 1397         if (!mac_mls_enabled)
 1398                 return (0);
 1399 
 1400         a = SLOT(bpflabel);
 1401         b = SLOT(ifnetlabel);
 1402 
 1403         if (mac_mls_equal_effective(a, b))
 1404                 return (0);
 1405         return (EACCES);
 1406 }
 1407 
 1408 static int
 1409 mac_mls_check_cred_relabel(struct ucred *cred, struct label *newlabel)
 1410 {
 1411         struct mac_mls *subj, *new;
 1412         int error;
 1413 
 1414         subj = SLOT(cred->cr_label);
 1415         new = SLOT(newlabel);
 1416 
 1417         /*
 1418          * If there is an MLS label update for the credential, it may be
 1419          * an update of effective, range, or both.
 1420          */
 1421         error = mls_atmostflags(new, MAC_MLS_FLAGS_BOTH);
 1422         if (error)
 1423                 return (error);
 1424 
 1425         /*
 1426          * If the MLS label is to be changed, authorize as appropriate.
 1427          */
 1428         if (new->mm_flags & MAC_MLS_FLAGS_BOTH) {
 1429                 /*
 1430                  * If the change request modifies both the MLS label effective
 1431                  * and range, check that the new effective will be in the
 1432                  * new range.
 1433                  */
 1434                 if ((new->mm_flags & MAC_MLS_FLAGS_BOTH) ==
 1435                     MAC_MLS_FLAGS_BOTH &&
 1436                     !mac_mls_effective_in_range(new, new))
 1437                         return (EINVAL);
 1438 
 1439                 /*
 1440                  * To change the MLS effective label on a credential, the
 1441                  * new effective label must be in the current range.
 1442                  */
 1443                 if (new->mm_flags & MAC_MLS_FLAG_EFFECTIVE &&
 1444                     !mac_mls_effective_in_range(new, subj))
 1445                         return (EPERM);
 1446 
 1447                 /*
 1448                  * To change the MLS range label on a credential, the
 1449                  * new range must be in the current range.
 1450                  */
 1451                 if (new->mm_flags & MAC_MLS_FLAG_RANGE &&
 1452                     !mac_mls_range_in_range(new, subj))
 1453                         return (EPERM);
 1454 
 1455                 /*
 1456                  * To have EQUAL in any component of the new credential
 1457                  * MLS label, the subject must already have EQUAL in
 1458                  * their label.
 1459                  */
 1460                 if (mac_mls_contains_equal(new)) {
 1461                         error = mac_mls_subject_privileged(subj);
 1462                         if (error)
 1463                                 return (error);
 1464                 }
 1465         }
 1466 
 1467         return (0);
 1468 }
 1469 
 1470 static int
 1471 mac_mls_check_cred_visible(struct ucred *u1, struct ucred *u2)
 1472 {
 1473         struct mac_mls *subj, *obj;
 1474 
 1475         if (!mac_mls_enabled)
 1476                 return (0);
 1477 
 1478         subj = SLOT(u1->cr_label);
 1479         obj = SLOT(u2->cr_label);
 1480 
 1481         /* XXX: range */
 1482         if (!mac_mls_dominate_effective(subj, obj))
 1483                 return (ESRCH);
 1484 
 1485         return (0);
 1486 }
 1487 
 1488 static int
 1489 mac_mls_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet,
 1490     struct label *ifnetlabel, struct label *newlabel)
 1491 {
 1492         struct mac_mls *subj, *new;
 1493         int error;
 1494 
 1495         subj = SLOT(cred->cr_label);
 1496         new = SLOT(newlabel);
 1497 
 1498         /*
 1499          * If there is an MLS label update for the interface, it may
 1500          * be an update of effective, range, or both.
 1501          */
 1502         error = mls_atmostflags(new, MAC_MLS_FLAGS_BOTH);
 1503         if (error)
 1504                 return (error);
 1505 
 1506         /*
 1507          * Relabeling network interfaces requires MLS privilege.
 1508          */
 1509         return (mac_mls_subject_privileged(subj));
 1510 }
 1511 
 1512 static int
 1513 mac_mls_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel,
 1514     struct mbuf *m, struct label *mbuflabel)
 1515 {
 1516         struct mac_mls *p, *i;
 1517 
 1518         if (!mac_mls_enabled)
 1519                 return (0);
 1520 
 1521         p = SLOT(mbuflabel);
 1522         i = SLOT(ifnetlabel);
 1523 
 1524         return (mac_mls_effective_in_range(p, i) ? 0 : EACCES);
 1525 }
 1526 
 1527 static int
 1528 mac_mls_check_inpcb_deliver(struct inpcb *inp, struct label *inplabel,
 1529     struct mbuf *m, struct label *mlabel)
 1530 {
 1531         struct mac_mls *p, *i;
 1532 
 1533         if (!mac_mls_enabled)
 1534                 return (0);
 1535 
 1536         p = SLOT(mlabel);
 1537         i = SLOT(inplabel);
 1538 
 1539         return (mac_mls_equal_effective(p, i) ? 0 : EACCES);
 1540 }
 1541 
 1542 static int
 1543 mac_mls_check_sysv_msgrcv(struct ucred *cred, struct msg *msgptr,
 1544     struct label *msglabel)
 1545 {
 1546         struct mac_mls *subj, *obj;
 1547 
 1548         if (!mac_mls_enabled)
 1549                 return (0);
 1550 
 1551         subj = SLOT(cred->cr_label);
 1552         obj = SLOT(msglabel);
 1553 
 1554         if (!mac_mls_dominate_effective(subj, obj))
 1555                 return (EACCES);
 1556 
 1557         return (0);
 1558 }
 1559 
 1560 static int
 1561 mac_mls_check_sysv_msgrmid(struct ucred *cred, struct msg *msgptr,
 1562     struct label *msglabel)
 1563 {
 1564         struct mac_mls *subj, *obj;
 1565 
 1566         if (!mac_mls_enabled)
 1567                 return (0);
 1568 
 1569         subj = SLOT(cred->cr_label);
 1570         obj = SLOT(msglabel);
 1571 
 1572         if (!mac_mls_dominate_effective(obj, subj))
 1573                 return (EACCES);
 1574 
 1575         return (0);
 1576 }
 1577 
 1578 static int
 1579 mac_mls_check_sysv_msqget(struct ucred *cred, struct msqid_kernel *msqkptr,
 1580     struct label *msqklabel)
 1581 {
 1582         struct mac_mls *subj, *obj;
 1583 
 1584         if (!mac_mls_enabled)
 1585                 return (0);
 1586 
 1587         subj = SLOT(cred->cr_label);
 1588         obj = SLOT(msqklabel);
 1589 
 1590         if (!mac_mls_dominate_effective(subj, obj))
 1591                 return (EACCES);
 1592 
 1593         return (0);
 1594 }
 1595 
 1596 static int
 1597 mac_mls_check_sysv_msqsnd(struct ucred *cred, struct msqid_kernel *msqkptr,
 1598     struct label *msqklabel)
 1599 {
 1600         struct mac_mls *subj, *obj;
 1601 
 1602         if (!mac_mls_enabled)
 1603                 return (0);
 1604 
 1605         subj = SLOT(cred->cr_label);
 1606         obj = SLOT(msqklabel);
 1607 
 1608         if (!mac_mls_dominate_effective(obj, subj))
 1609                 return (EACCES);
 1610 
 1611         return (0);
 1612 }
 1613 
 1614 static int
 1615 mac_mls_check_sysv_msqrcv(struct ucred *cred, struct msqid_kernel *msqkptr,
 1616     struct label *msqklabel)
 1617 {
 1618         struct mac_mls *subj, *obj;
 1619 
 1620         if (!mac_mls_enabled)
 1621                 return (0);
 1622 
 1623         subj = SLOT(cred->cr_label);
 1624         obj = SLOT(msqklabel);
 1625 
 1626         if (!mac_mls_dominate_effective(subj, obj))
 1627                 return (EACCES);
 1628 
 1629         return (0);
 1630 }
 1631 
 1632 static int
 1633 mac_mls_check_sysv_msqctl(struct ucred *cred, struct msqid_kernel *msqkptr,
 1634     struct label *msqklabel, int cmd)
 1635 {
 1636         struct mac_mls *subj, *obj;
 1637 
 1638         if (!mac_mls_enabled)
 1639                 return (0);
 1640 
 1641         subj = SLOT(cred->cr_label);
 1642         obj = SLOT(msqklabel);
 1643 
 1644         switch(cmd) {
 1645         case IPC_RMID:
 1646         case IPC_SET:
 1647                 if (!mac_mls_dominate_effective(obj, subj))
 1648                         return (EACCES);
 1649                 break;
 1650 
 1651         case IPC_STAT:
 1652                 if (!mac_mls_dominate_effective(subj, obj))
 1653                         return (EACCES);
 1654                 break;
 1655 
 1656         default:
 1657                 return (EACCES);
 1658         }
 1659 
 1660         return (0);
 1661 }
 1662 
 1663 static int
 1664 mac_mls_check_sysv_semctl(struct ucred *cred, struct semid_kernel *semakptr,
 1665     struct label *semaklabel, int cmd)
 1666 {
 1667         struct mac_mls *subj, *obj;
 1668 
 1669         if (!mac_mls_enabled)
 1670                 return (0);
 1671 
 1672         subj = SLOT(cred->cr_label);
 1673         obj = SLOT(semaklabel);
 1674 
 1675         switch(cmd) {
 1676         case IPC_RMID:
 1677         case IPC_SET:
 1678         case SETVAL:
 1679         case SETALL:
 1680                 if (!mac_mls_dominate_effective(obj, subj))
 1681                         return (EACCES);
 1682                 break;
 1683 
 1684         case IPC_STAT:
 1685         case GETVAL:
 1686         case GETPID:
 1687         case GETNCNT:
 1688         case GETZCNT:
 1689         case GETALL:
 1690                 if (!mac_mls_dominate_effective(subj, obj))
 1691                         return (EACCES);
 1692                 break;
 1693 
 1694         default:
 1695                 return (EACCES);
 1696         }
 1697 
 1698         return (0);
 1699 }
 1700 
 1701 static int
 1702 mac_mls_check_sysv_semget(struct ucred *cred, struct semid_kernel *semakptr,
 1703     struct label *semaklabel)
 1704 {
 1705         struct mac_mls *subj, *obj;
 1706 
 1707         if (!mac_mls_enabled)
 1708                 return (0);
 1709 
 1710         subj = SLOT(cred->cr_label);
 1711         obj = SLOT(semaklabel);
 1712 
 1713         if (!mac_mls_dominate_effective(subj, obj))
 1714                 return (EACCES);
 1715 
 1716         return (0);
 1717 }
 1718 
 1719 static int
 1720 mac_mls_check_sysv_semop(struct ucred *cred, struct semid_kernel *semakptr,
 1721     struct label *semaklabel, size_t accesstype)
 1722 {
 1723         struct mac_mls *subj, *obj;
 1724 
 1725         if (!mac_mls_enabled)
 1726                 return (0);
 1727 
 1728         subj = SLOT(cred->cr_label);
 1729         obj = SLOT(semaklabel);
 1730 
 1731         if( accesstype & SEM_R )
 1732                 if (!mac_mls_dominate_effective(subj, obj))
 1733                         return (EACCES);
 1734 
 1735         if( accesstype & SEM_A )
 1736                 if (!mac_mls_dominate_effective(obj, subj))
 1737                         return (EACCES);
 1738 
 1739         return (0);
 1740 }
 1741 
 1742 static int
 1743 mac_mls_check_sysv_shmat(struct ucred *cred, struct shmid_kernel *shmsegptr,
 1744     struct label *shmseglabel, int shmflg)
 1745 {
 1746         struct mac_mls *subj, *obj;
 1747 
 1748         if (!mac_mls_enabled)
 1749                 return (0);
 1750 
 1751         subj = SLOT(cred->cr_label);
 1752         obj = SLOT(shmseglabel);
 1753 
 1754         if (!mac_mls_dominate_effective(subj, obj))
 1755                         return (EACCES);
 1756         if ((shmflg & SHM_RDONLY) == 0)
 1757                 if (!mac_mls_dominate_effective(obj, subj))
 1758                         return (EACCES);
 1759         
 1760         return (0);
 1761 }
 1762 
 1763 static int
 1764 mac_mls_check_sysv_shmctl(struct ucred *cred, struct shmid_kernel *shmsegptr,
 1765     struct label *shmseglabel, int cmd)
 1766 {
 1767         struct mac_mls *subj, *obj;
 1768 
 1769         if (!mac_mls_enabled)
 1770                 return (0);
 1771 
 1772         subj = SLOT(cred->cr_label);
 1773         obj = SLOT(shmseglabel);
 1774 
 1775         switch(cmd) {
 1776         case IPC_RMID:
 1777         case IPC_SET:
 1778                 if (!mac_mls_dominate_effective(obj, subj))
 1779                         return (EACCES);
 1780                 break;
 1781 
 1782         case IPC_STAT:
 1783         case SHM_STAT:
 1784                 if (!mac_mls_dominate_effective(subj, obj))
 1785                         return (EACCES);
 1786                 break;
 1787 
 1788         default:
 1789                 return (EACCES);
 1790         }
 1791 
 1792         return (0);
 1793 }
 1794 
 1795 static int
 1796 mac_mls_check_sysv_shmget(struct ucred *cred, struct shmid_kernel *shmsegptr,
 1797     struct label *shmseglabel, int shmflg)
 1798 {
 1799         struct mac_mls *subj, *obj;
 1800 
 1801         if (!mac_mls_enabled)
 1802                 return (0);
 1803 
 1804         subj = SLOT(cred->cr_label);
 1805         obj = SLOT(shmseglabel);
 1806 
 1807         if (!mac_mls_dominate_effective(obj, subj))
 1808                 return (EACCES);
 1809 
 1810         return (0);
 1811 }
 1812 
 1813 static int
 1814 mac_mls_check_mount_stat(struct ucred *cred, struct mount *mp,
 1815     struct label *mntlabel)
 1816 {
 1817         struct mac_mls *subj, *obj;
 1818 
 1819         if (!mac_mls_enabled)
 1820                 return (0);
 1821 
 1822         subj = SLOT(cred->cr_label);
 1823         obj = SLOT(mntlabel);
 1824 
 1825         if (!mac_mls_dominate_effective(subj, obj))
 1826                 return (EACCES);
 1827 
 1828         return (0);
 1829 }
 1830 
 1831 static int
 1832 mac_mls_check_pipe_ioctl(struct ucred *cred, struct pipepair *pp,
 1833     struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data)
 1834 {
 1835 
 1836         if(!mac_mls_enabled)
 1837                 return (0);
 1838 
 1839         /* XXX: This will be implemented soon... */
 1840 
 1841         return (0);
 1842 }
 1843 
 1844 static int
 1845 mac_mls_check_pipe_poll(struct ucred *cred, struct pipepair *pp,
 1846     struct label *pipelabel)
 1847 {
 1848         struct mac_mls *subj, *obj;
 1849 
 1850         if (!mac_mls_enabled)
 1851                 return (0);
 1852 
 1853         subj = SLOT(cred->cr_label);
 1854         obj = SLOT((pipelabel));
 1855 
 1856         if (!mac_mls_dominate_effective(subj, obj))
 1857                 return (EACCES);
 1858 
 1859         return (0);
 1860 }
 1861 
 1862 static int
 1863 mac_mls_check_pipe_read(struct ucred *cred, struct pipepair *pp,
 1864     struct label *pipelabel)
 1865 {
 1866         struct mac_mls *subj, *obj;
 1867 
 1868         if (!mac_mls_enabled)
 1869                 return (0);
 1870 
 1871         subj = SLOT(cred->cr_label);
 1872         obj = SLOT((pipelabel));
 1873 
 1874         if (!mac_mls_dominate_effective(subj, obj))
 1875                 return (EACCES);
 1876 
 1877         return (0);
 1878 }
 1879 
 1880 static int
 1881 mac_mls_check_pipe_relabel(struct ucred *cred, struct pipepair *pp,
 1882     struct label *pipelabel, struct label *newlabel)
 1883 {
 1884         struct mac_mls *subj, *obj, *new;
 1885         int error;
 1886 
 1887         new = SLOT(newlabel);
 1888         subj = SLOT(cred->cr_label);
 1889         obj = SLOT(pipelabel);
 1890 
 1891         /*
 1892          * If there is an MLS label update for a pipe, it must be a
 1893          * effective update.
 1894          */
 1895         error = mls_atmostflags(new, MAC_MLS_FLAG_EFFECTIVE);
 1896         if (error)
 1897                 return (error);
 1898 
 1899         /*
 1900          * To perform a relabel of a pipe (MLS label or not), MLS must
 1901          * authorize the relabel.
 1902          */
 1903         if (!mac_mls_effective_in_range(obj, subj))
 1904                 return (EPERM);
 1905 
 1906         /*
 1907          * If the MLS label is to be changed, authorize as appropriate.
 1908          */
 1909         if (new->mm_flags & MAC_MLS_FLAG_EFFECTIVE) {
 1910                 /*
 1911                  * To change the MLS label on a pipe, the new pipe label
 1912                  * must be in the subject range.
 1913                  */
 1914                 if (!mac_mls_effective_in_range(new, subj))
 1915                         return (EPERM);
 1916 
 1917                 /*
 1918                  * To change the MLS label on a pipe to be EQUAL, the
 1919                  * subject must have appropriate privilege.
 1920                  */
 1921                 if (mac_mls_contains_equal(new)) {
 1922                         error = mac_mls_subject_privileged(subj);
 1923                         if (error)
 1924                                 return (error);
 1925                 }
 1926         }
 1927 
 1928         return (0);
 1929 }
 1930 
 1931 static int
 1932 mac_mls_check_pipe_stat(struct ucred *cred, struct pipepair *pp,
 1933     struct label *pipelabel)
 1934 {
 1935         struct mac_mls *subj, *obj;
 1936 
 1937         if (!mac_mls_enabled)
 1938                 return (0);
 1939 
 1940         subj = SLOT(cred->cr_label);
 1941         obj = SLOT((pipelabel));
 1942 
 1943         if (!mac_mls_dominate_effective(subj, obj))
 1944                 return (EACCES);
 1945 
 1946         return (0);
 1947 }
 1948 
 1949 static int
 1950 mac_mls_check_pipe_write(struct ucred *cred, struct pipepair *pp,
 1951     struct label *pipelabel)
 1952 {
 1953         struct mac_mls *subj, *obj;
 1954 
 1955         if (!mac_mls_enabled)
 1956                 return (0);
 1957 
 1958         subj = SLOT(cred->cr_label);
 1959         obj = SLOT((pipelabel));
 1960 
 1961         if (!mac_mls_dominate_effective(obj, subj))
 1962                 return (EACCES);
 1963 
 1964         return (0);
 1965 }
 1966 
 1967 static int
 1968 mac_mls_check_posix_sem_write(struct ucred *cred, struct ksem *ksemptr,
 1969     struct label *ks_label)
 1970 {
 1971         struct mac_mls *subj, *obj;
 1972 
 1973         if (!mac_mls_enabled)
 1974                 return (0);
 1975 
 1976         subj = SLOT(cred->cr_label);
 1977         obj = SLOT(ks_label);
 1978 
 1979         if (!mac_mls_dominate_effective(obj, subj))
 1980                 return (EACCES);
 1981 
 1982         return (0);
 1983 }
 1984 
 1985 static int
 1986 mac_mls_check_posix_sem_rdonly(struct ucred *cred, struct ksem *ksemptr,
 1987     struct label *ks_label)
 1988 {
 1989         struct mac_mls *subj, *obj;
 1990 
 1991         if (!mac_mls_enabled)
 1992                 return (0);
 1993 
 1994         subj = SLOT(cred->cr_label);
 1995         obj = SLOT(ks_label);
 1996 
 1997         if (!mac_mls_dominate_effective(subj, obj))
 1998                 return (EACCES);
 1999 
 2000         return (0);
 2001 }
 2002 
 2003 static int
 2004 mac_mls_check_proc_debug(struct ucred *cred, struct proc *proc)
 2005 {
 2006         struct mac_mls *subj, *obj;
 2007 
 2008         if (!mac_mls_enabled)
 2009                 return (0);
 2010 
 2011         subj = SLOT(cred->cr_label);
 2012         obj = SLOT(proc->p_ucred->cr_label);
 2013 
 2014         /* XXX: range checks */
 2015         if (!mac_mls_dominate_effective(subj, obj))
 2016                 return (ESRCH);
 2017         if (!mac_mls_dominate_effective(obj, subj))
 2018                 return (EACCES);
 2019 
 2020         return (0);
 2021 }
 2022 
 2023 static int
 2024 mac_mls_check_proc_sched(struct ucred *cred, struct proc *proc)
 2025 {
 2026         struct mac_mls *subj, *obj;
 2027 
 2028         if (!mac_mls_enabled)
 2029                 return (0);
 2030 
 2031         subj = SLOT(cred->cr_label);
 2032         obj = SLOT(proc->p_ucred->cr_label);
 2033 
 2034         /* XXX: range checks */
 2035         if (!mac_mls_dominate_effective(subj, obj))
 2036                 return (ESRCH);
 2037         if (!mac_mls_dominate_effective(obj, subj))
 2038                 return (EACCES);
 2039 
 2040         return (0);
 2041 }
 2042 
 2043 static int
 2044 mac_mls_check_proc_signal(struct ucred *cred, struct proc *proc, int signum)
 2045 {
 2046         struct mac_mls *subj, *obj;
 2047 
 2048         if (!mac_mls_enabled)
 2049                 return (0);
 2050 
 2051         subj = SLOT(cred->cr_label);
 2052         obj = SLOT(proc->p_ucred->cr_label);
 2053 
 2054         /* XXX: range checks */
 2055         if (!mac_mls_dominate_effective(subj, obj))
 2056                 return (ESRCH);
 2057         if (!mac_mls_dominate_effective(obj, subj))
 2058                 return (EACCES);
 2059 
 2060         return (0);
 2061 }
 2062 
 2063 static int
 2064 mac_mls_check_socket_deliver(struct socket *so, struct label *socketlabel,
 2065     struct mbuf *m, struct label *mbuflabel)
 2066 {
 2067         struct mac_mls *p, *s;
 2068 
 2069         if (!mac_mls_enabled)
 2070                 return (0);
 2071 
 2072         p = SLOT(mbuflabel);
 2073         s = SLOT(socketlabel);
 2074 
 2075         return (mac_mls_equal_effective(p, s) ? 0 : EACCES);
 2076 }
 2077 
 2078 static int
 2079 mac_mls_check_socket_relabel(struct ucred *cred, struct socket *socket,
 2080     struct label *socketlabel, struct label *newlabel)
 2081 {
 2082         struct mac_mls *subj, *obj, *new;
 2083         int error;
 2084 
 2085         new = SLOT(newlabel);
 2086         subj = SLOT(cred->cr_label);
 2087         obj = SLOT(socketlabel);
 2088 
 2089         /*
 2090          * If there is an MLS label update for the socket, it may be
 2091          * an update of effective.
 2092          */
 2093         error = mls_atmostflags(new, MAC_MLS_FLAG_EFFECTIVE);
 2094         if (error)
 2095                 return (error);
 2096 
 2097         /*
 2098          * To relabel a socket, the old socket effective must be in the subject
 2099          * range.
 2100          */
 2101         if (!mac_mls_effective_in_range(obj, subj))
 2102                 return (EPERM);
 2103 
 2104         /*
 2105          * If the MLS label is to be changed, authorize as appropriate.
 2106          */
 2107         if (new->mm_flags & MAC_MLS_FLAG_EFFECTIVE) {
 2108                 /*
 2109                  * To relabel a socket, the new socket effective must be in
 2110                  * the subject range.
 2111                  */
 2112                 if (!mac_mls_effective_in_range(new, subj))
 2113                         return (EPERM);
 2114 
 2115                 /*
 2116                  * To change the MLS label on the socket to contain EQUAL,
 2117                  * the subject must have appropriate privilege.
 2118                  */
 2119                 if (mac_mls_contains_equal(new)) {
 2120                         error = mac_mls_subject_privileged(subj);
 2121                         if (error)
 2122                                 return (error);
 2123                 }
 2124         }
 2125 
 2126         return (0);
 2127 }
 2128 
 2129 static int
 2130 mac_mls_check_socket_visible(struct ucred *cred, struct socket *socket,
 2131     struct label *socketlabel)
 2132 {
 2133         struct mac_mls *subj, *obj;
 2134 
 2135         if (!mac_mls_enabled)
 2136                 return (0);
 2137 
 2138         subj = SLOT(cred->cr_label);
 2139         obj = SLOT(socketlabel);
 2140 
 2141         if (!mac_mls_dominate_effective(subj, obj))
 2142                 return (ENOENT);
 2143 
 2144         return (0);
 2145 }
 2146 
 2147 static int
 2148 mac_mls_check_system_swapon(struct ucred *cred, struct vnode *vp,
 2149     struct label *label)
 2150 {
 2151         struct mac_mls *subj, *obj;
 2152 
 2153         if (!mac_mls_enabled)
 2154                 return (0);
 2155 
 2156         subj = SLOT(cred->cr_label);
 2157         obj = SLOT(label);
 2158 
 2159         if (!mac_mls_dominate_effective(obj, subj) ||
 2160             !mac_mls_dominate_effective(subj, obj))
 2161                 return (EACCES);
 2162 
 2163         return (0);
 2164 }
 2165 
 2166 static int
 2167 mac_mls_check_vnode_chdir(struct ucred *cred, struct vnode *dvp,
 2168     struct label *dlabel)
 2169 {
 2170         struct mac_mls *subj, *obj;
 2171 
 2172         if (!mac_mls_enabled)
 2173                 return (0);
 2174 
 2175         subj = SLOT(cred->cr_label);
 2176         obj = SLOT(dlabel);
 2177 
 2178         if (!mac_mls_dominate_effective(subj, obj))
 2179                 return (EACCES);
 2180 
 2181         return (0);
 2182 }
 2183 
 2184 static int
 2185 mac_mls_check_vnode_chroot(struct ucred *cred, struct vnode *dvp,
 2186     struct label *dlabel)
 2187 {
 2188         struct mac_mls *subj, *obj;
 2189 
 2190         if (!mac_mls_enabled)
 2191                 return (0);
 2192 
 2193         subj = SLOT(cred->cr_label);
 2194         obj = SLOT(dlabel);
 2195 
 2196         if (!mac_mls_dominate_effective(subj, obj))
 2197                 return (EACCES);
 2198 
 2199         return (0);
 2200 }
 2201 
 2202 static int
 2203 mac_mls_check_vnode_create(struct ucred *cred, struct vnode *dvp,
 2204     struct label *dlabel, struct componentname *cnp, struct vattr *vap)
 2205 {
 2206         struct mac_mls *subj, *obj;
 2207 
 2208         if (!mac_mls_enabled)
 2209                 return (0);
 2210 
 2211         subj = SLOT(cred->cr_label);
 2212         obj = SLOT(dlabel);
 2213 
 2214         if (!mac_mls_dominate_effective(obj, subj))
 2215                 return (EACCES);
 2216 
 2217         return (0);
 2218 }
 2219 
 2220 static int
 2221 mac_mls_check_vnode_delete(struct ucred *cred, struct vnode *dvp,
 2222     struct label *dlabel, struct vnode *vp, struct label *label,
 2223     struct componentname *cnp)
 2224 {
 2225         struct mac_mls *subj, *obj;
 2226 
 2227         if (!mac_mls_enabled)
 2228                 return (0);
 2229 
 2230         subj = SLOT(cred->cr_label);
 2231         obj = SLOT(dlabel);
 2232 
 2233         if (!mac_mls_dominate_effective(obj, subj))
 2234                 return (EACCES);
 2235 
 2236         obj = SLOT(label);
 2237 
 2238         if (!mac_mls_dominate_effective(obj, subj))
 2239                 return (EACCES);
 2240 
 2241         return (0);
 2242 }
 2243 
 2244 static int
 2245 mac_mls_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
 2246     struct label *label, acl_type_t type)
 2247 {
 2248         struct mac_mls *subj, *obj;
 2249 
 2250         if (!mac_mls_enabled)
 2251                 return (0);
 2252 
 2253         subj = SLOT(cred->cr_label);
 2254         obj = SLOT(label);
 2255 
 2256         if (!mac_mls_dominate_effective(obj, subj))
 2257                 return (EACCES);
 2258 
 2259         return (0);
 2260 }
 2261 
 2262 static int
 2263 mac_mls_check_vnode_deleteextattr(struct ucred *cred, struct vnode *vp,
 2264     struct label *label, int attrnamespace, const char *name)
 2265 {
 2266         struct mac_mls *subj, *obj;
 2267 
 2268         if (!mac_mls_enabled)
 2269                 return (0);
 2270 
 2271         subj = SLOT(cred->cr_label);
 2272         obj = SLOT(label);
 2273 
 2274         if (!mac_mls_dominate_effective(obj, subj))
 2275                 return (EACCES);
 2276 
 2277         return (0);
 2278 }
 2279 
 2280 static int
 2281 mac_mls_check_vnode_exec(struct ucred *cred, struct vnode *vp,
 2282     struct label *label, struct image_params *imgp,
 2283     struct label *execlabel)
 2284 {
 2285         struct mac_mls *subj, *obj, *exec;
 2286         int error;
 2287 
 2288         if (execlabel != NULL) {
 2289                 /*
 2290                  * We currently don't permit labels to be changed at
 2291                  * exec-time as part of MLS, so disallow non-NULL
 2292                  * MLS label elements in the execlabel.
 2293                  */
 2294                 exec = SLOT(execlabel);
 2295                 error = mls_atmostflags(exec, 0);
 2296                 if (error)
 2297                         return (error);
 2298         }
 2299 
 2300         if (!mac_mls_enabled)
 2301                 return (0);
 2302 
 2303         subj = SLOT(cred->cr_label);
 2304         obj = SLOT(label);
 2305 
 2306         if (!mac_mls_dominate_effective(subj, obj))
 2307                 return (EACCES);
 2308 
 2309         return (0);
 2310 }
 2311 
 2312 static int
 2313 mac_mls_check_vnode_getacl(struct ucred *cred, struct vnode *vp,
 2314     struct label *label, acl_type_t type)
 2315 {
 2316         struct mac_mls *subj, *obj;
 2317 
 2318         if (!mac_mls_enabled)
 2319                 return (0);
 2320 
 2321         subj = SLOT(cred->cr_label);
 2322         obj = SLOT(label);
 2323 
 2324         if (!mac_mls_dominate_effective(subj, obj))
 2325                 return (EACCES);
 2326 
 2327         return (0);
 2328 }
 2329 
 2330 static int
 2331 mac_mls_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
 2332     struct label *label, int attrnamespace, const char *name, struct uio *uio)
 2333 {
 2334         struct mac_mls *subj, *obj;
 2335 
 2336         if (!mac_mls_enabled)
 2337                 return (0);
 2338 
 2339         subj = SLOT(cred->cr_label);
 2340         obj = SLOT(label);
 2341 
 2342         if (!mac_mls_dominate_effective(subj, obj))
 2343                 return (EACCES);
 2344 
 2345         return (0);
 2346 }
 2347 
 2348 static int
 2349 mac_mls_check_vnode_link(struct ucred *cred, struct vnode *dvp,
 2350     struct label *dlabel, struct vnode *vp, struct label *label,
 2351     struct componentname *cnp)
 2352 {
 2353         struct mac_mls *subj, *obj;
 2354 
 2355         if (!mac_mls_enabled)
 2356                 return (0);
 2357 
 2358         subj = SLOT(cred->cr_label);
 2359         obj = SLOT(dlabel);
 2360 
 2361         if (!mac_mls_dominate_effective(obj, subj))
 2362                 return (EACCES);
 2363 
 2364         obj = SLOT(dlabel);
 2365         if (!mac_mls_dominate_effective(obj, subj))
 2366                 return (EACCES);
 2367 
 2368         return (0);
 2369 }
 2370 
 2371 static int
 2372 mac_mls_check_vnode_listextattr(struct ucred *cred, struct vnode *vp,
 2373     struct label *label, int attrnamespace)
 2374 {
 2375 
 2376         struct mac_mls *subj, *obj;
 2377 
 2378         if (!mac_mls_enabled)
 2379                 return (0);
 2380 
 2381         subj = SLOT(cred->cr_label);
 2382         obj = SLOT(label);
 2383 
 2384         if (!mac_mls_dominate_effective(subj, obj))
 2385                 return (EACCES);
 2386 
 2387         return (0);
 2388 }
 2389 
 2390 static int
 2391 mac_mls_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
 2392     struct label *dlabel, struct componentname *cnp)
 2393 {
 2394         struct mac_mls *subj, *obj;
 2395 
 2396         if (!mac_mls_enabled)
 2397                 return (0);
 2398 
 2399         subj = SLOT(cred->cr_label);
 2400         obj = SLOT(dlabel);
 2401 
 2402         if (!mac_mls_dominate_effective(subj, obj))
 2403                 return (EACCES);
 2404 
 2405         return (0);
 2406 }
 2407 
 2408 static int
 2409 mac_mls_check_vnode_mmap(struct ucred *cred, struct vnode *vp,
 2410     struct label *label, int prot, int flags)
 2411 {
 2412         struct mac_mls *subj, *obj;
 2413 
 2414         /*
 2415          * Rely on the use of open()-time protections to handle
 2416          * non-revocation cases.
 2417          */
 2418         if (!mac_mls_enabled || !revocation_enabled)
 2419                 return (0);
 2420 
 2421         subj = SLOT(cred->cr_label);
 2422         obj = SLOT(label);
 2423 
 2424         if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
 2425                 if (!mac_mls_dominate_effective(subj, obj))
 2426                         return (EACCES);
 2427         }
 2428         if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) {
 2429                 if (!mac_mls_dominate_effective(obj, subj))
 2430                         return (EACCES);
 2431         }
 2432 
 2433         return (0);
 2434 }
 2435 
 2436 static int
 2437 mac_mls_check_vnode_open(struct ucred *cred, struct vnode *vp,
 2438     struct label *vnodelabel, int acc_mode)
 2439 {
 2440         struct mac_mls *subj, *obj;
 2441 
 2442         if (!mac_mls_enabled)
 2443                 return (0);
 2444 
 2445         subj = SLOT(cred->cr_label);
 2446         obj = SLOT(vnodelabel);
 2447 
 2448         /* XXX privilege override for admin? */
 2449         if (acc_mode & (VREAD | VEXEC | VSTAT)) {
 2450                 if (!mac_mls_dominate_effective(subj, obj))
 2451                         return (EACCES);
 2452         }
 2453         if (acc_mode & (VWRITE | VAPPEND | VADMIN)) {
 2454                 if (!mac_mls_dominate_effective(obj, subj))
 2455                         return (EACCES);
 2456         }
 2457 
 2458         return (0);
 2459 }
 2460 
 2461 static int
 2462 mac_mls_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred,
 2463     struct vnode *vp, struct label *label)
 2464 {
 2465         struct mac_mls *subj, *obj;
 2466 
 2467         if (!mac_mls_enabled || !revocation_enabled)
 2468                 return (0);
 2469 
 2470         subj = SLOT(active_cred->cr_label);
 2471         obj = SLOT(label);
 2472 
 2473         if (!mac_mls_dominate_effective(subj, obj))
 2474                 return (EACCES);
 2475 
 2476         return (0);
 2477 }
 2478 
 2479 static int
 2480 mac_mls_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
 2481     struct vnode *vp, struct label *label)
 2482 {
 2483         struct mac_mls *subj, *obj;
 2484 
 2485         if (!mac_mls_enabled || !revocation_enabled)
 2486                 return (0);
 2487 
 2488         subj = SLOT(active_cred->cr_label);
 2489         obj = SLOT(label);
 2490 
 2491         if (!mac_mls_dominate_effective(subj, obj))
 2492                 return (EACCES);
 2493 
 2494         return (0);
 2495 }
 2496 
 2497 static int
 2498 mac_mls_check_vnode_readdir(struct ucred *cred, struct vnode *dvp,
 2499     struct label *dlabel)
 2500 {
 2501         struct mac_mls *subj, *obj;
 2502 
 2503         if (!mac_mls_enabled)
 2504                 return (0);
 2505 
 2506         subj = SLOT(cred->cr_label);
 2507         obj = SLOT(dlabel);
 2508 
 2509         if (!mac_mls_dominate_effective(subj, obj))
 2510                 return (EACCES);
 2511 
 2512         return (0);
 2513 }
 2514 
 2515 static int
 2516 mac_mls_check_vnode_readlink(struct ucred *cred, struct vnode *vp,
 2517     struct label *vnodelabel)
 2518 {
 2519         struct mac_mls *subj, *obj;
 2520 
 2521         if (!mac_mls_enabled)
 2522                 return (0);
 2523 
 2524         subj = SLOT(cred->cr_label);
 2525         obj = SLOT(vnodelabel);
 2526 
 2527         if (!mac_mls_dominate_effective(subj, obj))
 2528                 return (EACCES);
 2529 
 2530         return (0);
 2531 }
 2532 
 2533 static int
 2534 mac_mls_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
 2535     struct label *vnodelabel, struct label *newlabel)
 2536 {
 2537         struct mac_mls *old, *new, *subj;
 2538         int error;
 2539 
 2540         old = SLOT(vnodelabel);
 2541         new = SLOT(newlabel);
 2542         subj = SLOT(cred->cr_label);
 2543 
 2544         /*
 2545          * If there is an MLS label update for the vnode, it must be a
 2546          * effective label.
 2547          */
 2548         error = mls_atmostflags(new, MAC_MLS_FLAG_EFFECTIVE);
 2549         if (error)
 2550                 return (error);
 2551 
 2552         /*
 2553          * To perform a relabel of the vnode (MLS label or not), MLS must
 2554          * authorize the relabel.
 2555          */
 2556         if (!mac_mls_effective_in_range(old, subj))
 2557                 return (EPERM);
 2558 
 2559         /*
 2560          * If the MLS label is to be changed, authorize as appropriate.
 2561          */
 2562         if (new->mm_flags & MAC_MLS_FLAG_EFFECTIVE) {
 2563                 /*
 2564                  * To change the MLS label on a vnode, the new vnode label
 2565                  * must be in the subject range.
 2566                  */
 2567                 if (!mac_mls_effective_in_range(new, subj))
 2568                         return (EPERM);
 2569 
 2570                 /*
 2571                  * To change the MLS label on the vnode to be EQUAL,
 2572                  * the subject must have appropriate privilege.
 2573                  */
 2574                 if (mac_mls_contains_equal(new)) {
 2575                         error = mac_mls_subject_privileged(subj);
 2576                         if (error)
 2577                                 return (error);
 2578                 }
 2579         }
 2580 
 2581         return (0);
 2582 }
 2583 
 2584 
 2585 static int
 2586 mac_mls_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
 2587     struct label *dlabel, struct vnode *vp, struct label *label,
 2588     struct componentname *cnp)
 2589 {
 2590         struct mac_mls *subj, *obj;
 2591 
 2592         if (!mac_mls_enabled)
 2593                 return (0);
 2594 
 2595         subj = SLOT(cred->cr_label);
 2596         obj = SLOT(dlabel);
 2597 
 2598         if (!mac_mls_dominate_effective(obj, subj))
 2599                 return (EACCES);
 2600 
 2601         obj = SLOT(label);
 2602 
 2603         if (!mac_mls_dominate_effective(obj, subj))
 2604                 return (EACCES);
 2605 
 2606         return (0);
 2607 }
 2608 
 2609 static int
 2610 mac_mls_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
 2611     struct label *dlabel, struct vnode *vp, struct label *label, int samedir,
 2612     struct componentname *cnp)
 2613 {
 2614         struct mac_mls *subj, *obj;
 2615 
 2616         if (!mac_mls_enabled)
 2617                 return (0);
 2618 
 2619         subj = SLOT(cred->cr_label);
 2620         obj = SLOT(dlabel);
 2621 
 2622         if (!mac_mls_dominate_effective(obj, subj))
 2623                 return (EACCES);
 2624 
 2625         if (vp != NULL) {
 2626                 obj = SLOT(label);
 2627 
 2628                 if (!mac_mls_dominate_effective(obj, subj))
 2629                         return (EACCES);
 2630         }
 2631 
 2632         return (0);
 2633 }
 2634 
 2635 static int
 2636 mac_mls_check_vnode_revoke(struct ucred *cred, struct vnode *vp,
 2637     struct label *label)
 2638 {
 2639         struct mac_mls *subj, *obj;
 2640 
 2641         if (!mac_mls_enabled)
 2642                 return (0);
 2643 
 2644         subj = SLOT(cred->cr_label);
 2645         obj = SLOT(label);
 2646 
 2647         if (!mac_mls_dominate_effective(obj, subj))
 2648                 return (EACCES);
 2649 
 2650         return (0);
 2651 }
 2652 
 2653 static int
 2654 mac_mls_check_vnode_setacl(struct ucred *cred, struct vnode *vp,
 2655     struct label *label, acl_type_t type, struct acl *acl)
 2656 {
 2657         struct mac_mls *subj, *obj;
 2658 
 2659         if (!mac_mls_enabled)
 2660                 return (0);
 2661 
 2662         subj = SLOT(cred->cr_label);
 2663         obj = SLOT(label);
 2664 
 2665         if (!mac_mls_dominate_effective(obj, subj))
 2666                 return (EACCES);
 2667 
 2668         return (0);
 2669 }
 2670 
 2671 static int
 2672 mac_mls_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
 2673     struct label *vnodelabel, int attrnamespace, const char *name,
 2674     struct uio *uio)
 2675 {
 2676         struct mac_mls *subj, *obj;
 2677 
 2678         if (!mac_mls_enabled)
 2679                 return (0);
 2680 
 2681         subj = SLOT(cred->cr_label);
 2682         obj = SLOT(vnodelabel);
 2683 
 2684         if (!mac_mls_dominate_effective(obj, subj))
 2685                 return (EACCES);
 2686 
 2687         /* XXX: protect the MAC EA in a special way? */
 2688 
 2689         return (0);
 2690 }
 2691 
 2692 static int
 2693 mac_mls_check_vnode_setflags(struct ucred *cred, struct vnode *vp,
 2694     struct label *vnodelabel, u_long flags)
 2695 {
 2696         struct mac_mls *subj, *obj;
 2697 
 2698         if (!mac_mls_enabled)
 2699                 return (0);
 2700 
 2701         subj = SLOT(cred->cr_label);
 2702         obj = SLOT(vnodelabel);
 2703 
 2704         if (!mac_mls_dominate_effective(obj, subj))
 2705                 return (EACCES);
 2706 
 2707         return (0);
 2708 }
 2709 
 2710 static int
 2711 mac_mls_check_vnode_setmode(struct ucred *cred, struct vnode *vp,
 2712     struct label *vnodelabel, mode_t mode)
 2713 {
 2714         struct mac_mls *subj, *obj;
 2715 
 2716         if (!mac_mls_enabled)
 2717                 return (0);
 2718 
 2719         subj = SLOT(cred->cr_label);
 2720         obj = SLOT(vnodelabel);
 2721 
 2722         if (!mac_mls_dominate_effective(obj, subj))
 2723                 return (EACCES);
 2724 
 2725         return (0);
 2726 }
 2727 
 2728 static int
 2729 mac_mls_check_vnode_setowner(struct ucred *cred, struct vnode *vp,
 2730     struct label *vnodelabel, uid_t uid, gid_t gid)
 2731 {
 2732         struct mac_mls *subj, *obj;
 2733 
 2734         if (!mac_mls_enabled)
 2735                 return (0);
 2736 
 2737         subj = SLOT(cred->cr_label);
 2738         obj = SLOT(vnodelabel);
 2739 
 2740         if (!mac_mls_dominate_effective(obj, subj))
 2741                 return (EACCES);
 2742 
 2743         return (0);
 2744 }
 2745 
 2746 static int
 2747 mac_mls_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
 2748     struct label *vnodelabel, struct timespec atime, struct timespec mtime)
 2749 {
 2750         struct mac_mls *subj, *obj;
 2751 
 2752         if (!mac_mls_enabled)
 2753                 return (0);
 2754 
 2755         subj = SLOT(cred->cr_label);
 2756         obj = SLOT(vnodelabel);
 2757 
 2758         if (!mac_mls_dominate_effective(obj, subj))
 2759                 return (EACCES);
 2760 
 2761         return (0);
 2762 }
 2763 
 2764 static int
 2765 mac_mls_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
 2766     struct vnode *vp, struct label *vnodelabel)
 2767 {
 2768         struct mac_mls *subj, *obj;
 2769 
 2770         if (!mac_mls_enabled)
 2771                 return (0);
 2772 
 2773         subj = SLOT(active_cred->cr_label);
 2774         obj = SLOT(vnodelabel);
 2775 
 2776         if (!mac_mls_dominate_effective(subj, obj))
 2777                 return (EACCES);
 2778 
 2779         return (0);
 2780 }
 2781 
 2782 static int
 2783 mac_mls_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred,
 2784     struct vnode *vp, struct label *label)
 2785 {
 2786         struct mac_mls *subj, *obj;
 2787 
 2788         if (!mac_mls_enabled || !revocation_enabled)
 2789                 return (0);
 2790 
 2791         subj = SLOT(active_cred->cr_label);
 2792         obj = SLOT(label);
 2793 
 2794         if (!mac_mls_dominate_effective(obj, subj))
 2795                 return (EACCES);
 2796 
 2797         return (0);
 2798 }
 2799 
 2800 static void
 2801 mac_mls_associate_nfsd_label(struct ucred *cred) 
 2802 {
 2803         struct mac_mls *label;
 2804 
 2805         label = SLOT(cred->cr_label);
 2806         mac_mls_set_effective(label, MAC_MLS_TYPE_LOW, 0, NULL);
 2807         mac_mls_set_range(label, MAC_MLS_TYPE_LOW, 0, NULL,
 2808             MAC_MLS_TYPE_HIGH, 0, NULL);
 2809 }
 2810 
 2811 static struct mac_policy_ops mac_mls_ops =
 2812 {
 2813         .mpo_init = mac_mls_init,
 2814         .mpo_init_bpfdesc_label = mac_mls_init_label,
 2815         .mpo_init_cred_label = mac_mls_init_label,
 2816         .mpo_init_devfsdirent_label = mac_mls_init_label,
 2817         .mpo_init_ifnet_label = mac_mls_init_label,
 2818         .mpo_init_inpcb_label = mac_mls_init_label_waitcheck,
 2819         .mpo_init_sysv_msgmsg_label = mac_mls_init_label,
 2820         .mpo_init_sysv_msgqueue_label = mac_mls_init_label,
 2821         .mpo_init_sysv_sem_label = mac_mls_init_label,
 2822         .mpo_init_sysv_shm_label = mac_mls_init_label,
 2823         .mpo_init_ipq_label = mac_mls_init_label_waitcheck,
 2824         .mpo_init_mbuf_label = mac_mls_init_label_waitcheck,
 2825         .mpo_init_mount_label = mac_mls_init_label,
 2826         .mpo_init_mount_fs_label = mac_mls_init_label,
 2827         .mpo_init_pipe_label = mac_mls_init_label,
 2828         .mpo_init_posix_sem_label = mac_mls_init_label,
 2829         .mpo_init_socket_label = mac_mls_init_label_waitcheck,
 2830         .mpo_init_socket_peer_label = mac_mls_init_label_waitcheck,
 2831         .mpo_init_vnode_label = mac_mls_init_label,
 2832         .mpo_destroy_bpfdesc_label = mac_mls_destroy_label,
 2833         .mpo_destroy_cred_label = mac_mls_destroy_label,
 2834         .mpo_destroy_devfsdirent_label = mac_mls_destroy_label,
 2835         .mpo_destroy_ifnet_label = mac_mls_destroy_label,
 2836         .mpo_destroy_inpcb_label = mac_mls_destroy_label,
 2837         .mpo_destroy_sysv_msgmsg_label = mac_mls_destroy_label,
 2838         .mpo_destroy_sysv_msgqueue_label = mac_mls_destroy_label,
 2839         .mpo_destroy_sysv_sem_label = mac_mls_destroy_label,
 2840         .mpo_destroy_sysv_shm_label = mac_mls_destroy_label,
 2841         .mpo_destroy_ipq_label = mac_mls_destroy_label,
 2842         .mpo_destroy_mbuf_label = mac_mls_destroy_label,
 2843         .mpo_destroy_mount_label = mac_mls_destroy_label,
 2844         .mpo_destroy_mount_fs_label = mac_mls_destroy_label,
 2845         .mpo_destroy_pipe_label = mac_mls_destroy_label,
 2846         .mpo_destroy_posix_sem_label = mac_mls_destroy_label,
 2847         .mpo_destroy_socket_label = mac_mls_destroy_label,
 2848         .mpo_destroy_socket_peer_label = mac_mls_destroy_label,
 2849         .mpo_destroy_vnode_label = mac_mls_destroy_label,
 2850         .mpo_copy_cred_label = mac_mls_copy_label,
 2851         .mpo_copy_ifnet_label = mac_mls_copy_label,
 2852         .mpo_copy_mbuf_label = mac_mls_copy_label,
 2853         .mpo_copy_pipe_label = mac_mls_copy_label,
 2854         .mpo_copy_socket_label = mac_mls_copy_label,
 2855         .mpo_copy_vnode_label = mac_mls_copy_label,
 2856         .mpo_externalize_cred_label = mac_mls_externalize_label,
 2857         .mpo_externalize_ifnet_label = mac_mls_externalize_label,
 2858         .mpo_externalize_pipe_label = mac_mls_externalize_label,
 2859         .mpo_externalize_socket_label = mac_mls_externalize_label,
 2860         .mpo_externalize_socket_peer_label = mac_mls_externalize_label,
 2861         .mpo_externalize_vnode_label = mac_mls_externalize_label,
 2862         .mpo_internalize_cred_label = mac_mls_internalize_label,
 2863         .mpo_internalize_ifnet_label = mac_mls_internalize_label,
 2864         .mpo_internalize_pipe_label = mac_mls_internalize_label,
 2865         .mpo_internalize_socket_label = mac_mls_internalize_label,
 2866         .mpo_internalize_vnode_label = mac_mls_internalize_label,
 2867         .mpo_create_devfs_device = mac_mls_create_devfs_device,
 2868         .mpo_create_devfs_directory = mac_mls_create_devfs_directory,
 2869         .mpo_create_devfs_symlink = mac_mls_create_devfs_symlink,
 2870         .mpo_create_mount = mac_mls_create_mount,
 2871         .mpo_relabel_vnode = mac_mls_relabel_vnode,
 2872         .mpo_update_devfsdirent = mac_mls_update_devfsdirent,
 2873         .mpo_associate_vnode_devfs = mac_mls_associate_vnode_devfs,
 2874         .mpo_associate_vnode_extattr = mac_mls_associate_vnode_extattr,
 2875         .mpo_associate_vnode_singlelabel = mac_mls_associate_vnode_singlelabel,
 2876         .mpo_create_vnode_extattr = mac_mls_create_vnode_extattr,
 2877         .mpo_setlabel_vnode_extattr = mac_mls_setlabel_vnode_extattr,
 2878         .mpo_create_mbuf_from_socket = mac_mls_create_mbuf_from_socket,
 2879         .mpo_create_pipe = mac_mls_create_pipe,
 2880         .mpo_create_posix_sem = mac_mls_create_posix_sem,
 2881         .mpo_create_socket = mac_mls_create_socket,
 2882         .mpo_create_socket_from_socket = mac_mls_create_socket_from_socket,
 2883         .mpo_relabel_pipe = mac_mls_relabel_pipe,
 2884         .mpo_relabel_socket = mac_mls_relabel_socket,
 2885         .mpo_set_socket_peer_from_mbuf = mac_mls_set_socket_peer_from_mbuf,
 2886         .mpo_set_socket_peer_from_socket = mac_mls_set_socket_peer_from_socket,
 2887         .mpo_create_bpfdesc = mac_mls_create_bpfdesc,
 2888         .mpo_create_datagram_from_ipq = mac_mls_create_datagram_from_ipq,
 2889         .mpo_create_fragment = mac_mls_create_fragment,
 2890         .mpo_create_ifnet = mac_mls_create_ifnet,
 2891         .mpo_create_inpcb_from_socket = mac_mls_create_inpcb_from_socket,
 2892         .mpo_create_ipq = mac_mls_create_ipq,
 2893         .mpo_create_sysv_msgmsg = mac_mls_create_sysv_msgmsg,
 2894         .mpo_create_sysv_msgqueue = mac_mls_create_sysv_msgqueue,
 2895         .mpo_create_sysv_sem = mac_mls_create_sysv_sem,
 2896         .mpo_create_sysv_shm = mac_mls_create_sysv_shm,
 2897         .mpo_create_mbuf_from_inpcb = mac_mls_create_mbuf_from_inpcb,
 2898         .mpo_create_mbuf_linklayer = mac_mls_create_mbuf_linklayer,
 2899         .mpo_create_mbuf_from_bpfdesc = mac_mls_create_mbuf_from_bpfdesc,
 2900         .mpo_create_mbuf_from_ifnet = mac_mls_create_mbuf_from_ifnet,
 2901         .mpo_create_mbuf_multicast_encap = mac_mls_create_mbuf_multicast_encap,
 2902         .mpo_create_mbuf_netlayer = mac_mls_create_mbuf_netlayer,
 2903         .mpo_fragment_match = mac_mls_fragment_match,
 2904         .mpo_relabel_ifnet = mac_mls_relabel_ifnet,
 2905         .mpo_update_ipq = mac_mls_update_ipq,
 2906         .mpo_inpcb_sosetlabel = mac_mls_inpcb_sosetlabel,
 2907         .mpo_create_proc0 = mac_mls_create_proc0,
 2908         .mpo_create_proc1 = mac_mls_create_proc1,
 2909         .mpo_relabel_cred = mac_mls_relabel_cred,
 2910         .mpo_cleanup_sysv_msgmsg = mac_mls_cleanup_sysv_msgmsg,
 2911         .mpo_cleanup_sysv_msgqueue = mac_mls_cleanup_sysv_msgqueue,
 2912         .mpo_cleanup_sysv_sem = mac_mls_cleanup_sysv_sem,
 2913         .mpo_cleanup_sysv_shm = mac_mls_cleanup_sysv_shm,
 2914         .mpo_check_bpfdesc_receive = mac_mls_check_bpfdesc_receive,
 2915         .mpo_check_cred_relabel = mac_mls_check_cred_relabel,
 2916         .mpo_check_cred_visible = mac_mls_check_cred_visible,
 2917         .mpo_check_ifnet_relabel = mac_mls_check_ifnet_relabel,
 2918         .mpo_check_ifnet_transmit = mac_mls_check_ifnet_transmit,
 2919         .mpo_check_inpcb_deliver = mac_mls_check_inpcb_deliver,
 2920         .mpo_check_sysv_msgrcv = mac_mls_check_sysv_msgrcv,
 2921         .mpo_check_sysv_msgrmid = mac_mls_check_sysv_msgrmid,
 2922         .mpo_check_sysv_msqget = mac_mls_check_sysv_msqget,
 2923         .mpo_check_sysv_msqsnd = mac_mls_check_sysv_msqsnd,
 2924         .mpo_check_sysv_msqrcv = mac_mls_check_sysv_msqrcv,
 2925         .mpo_check_sysv_msqctl = mac_mls_check_sysv_msqctl,
 2926         .mpo_check_sysv_semctl = mac_mls_check_sysv_semctl,
 2927         .mpo_check_sysv_semget = mac_mls_check_sysv_semget,
 2928         .mpo_check_sysv_semop = mac_mls_check_sysv_semop,
 2929         .mpo_check_sysv_shmat = mac_mls_check_sysv_shmat,
 2930         .mpo_check_sysv_shmctl = mac_mls_check_sysv_shmctl,
 2931         .mpo_check_sysv_shmget = mac_mls_check_sysv_shmget,
 2932         .mpo_check_mount_stat = mac_mls_check_mount_stat,
 2933         .mpo_check_pipe_ioctl = mac_mls_check_pipe_ioctl,
 2934         .mpo_check_pipe_poll = mac_mls_check_pipe_poll,
 2935         .mpo_check_pipe_read = mac_mls_check_pipe_read,
 2936         .mpo_check_pipe_relabel = mac_mls_check_pipe_relabel,
 2937         .mpo_check_pipe_stat = mac_mls_check_pipe_stat,
 2938         .mpo_check_pipe_write = mac_mls_check_pipe_write,
 2939         .mpo_check_posix_sem_destroy = mac_mls_check_posix_sem_write,
 2940         .mpo_check_posix_sem_getvalue = mac_mls_check_posix_sem_rdonly,
 2941         .mpo_check_posix_sem_open = mac_mls_check_posix_sem_write,
 2942         .mpo_check_posix_sem_post = mac_mls_check_posix_sem_write,
 2943         .mpo_check_posix_sem_unlink = mac_mls_check_posix_sem_write,
 2944         .mpo_check_posix_sem_wait = mac_mls_check_posix_sem_write,
 2945         .mpo_check_proc_debug = mac_mls_check_proc_debug,
 2946         .mpo_check_proc_sched = mac_mls_check_proc_sched,
 2947         .mpo_check_proc_signal = mac_mls_check_proc_signal,
 2948         .mpo_check_socket_deliver = mac_mls_check_socket_deliver,
 2949         .mpo_check_socket_relabel = mac_mls_check_socket_relabel,
 2950         .mpo_check_socket_visible = mac_mls_check_socket_visible,
 2951         .mpo_check_system_swapon = mac_mls_check_system_swapon,
 2952         .mpo_check_vnode_access = mac_mls_check_vnode_open,
 2953         .mpo_check_vnode_chdir = mac_mls_check_vnode_chdir,
 2954         .mpo_check_vnode_chroot = mac_mls_check_vnode_chroot,
 2955         .mpo_check_vnode_create = mac_mls_check_vnode_create,
 2956         .mpo_check_vnode_delete = mac_mls_check_vnode_delete,
 2957         .mpo_check_vnode_deleteacl = mac_mls_check_vnode_deleteacl,
 2958         .mpo_check_vnode_deleteextattr = mac_mls_check_vnode_deleteextattr,
 2959         .mpo_check_vnode_exec = mac_mls_check_vnode_exec,
 2960         .mpo_check_vnode_getacl = mac_mls_check_vnode_getacl,
 2961         .mpo_check_vnode_getextattr = mac_mls_check_vnode_getextattr,
 2962         .mpo_check_vnode_link = mac_mls_check_vnode_link,
 2963         .mpo_check_vnode_listextattr = mac_mls_check_vnode_listextattr,
 2964         .mpo_check_vnode_lookup = mac_mls_check_vnode_lookup,
 2965         .mpo_check_vnode_mmap = mac_mls_check_vnode_mmap,
 2966         .mpo_check_vnode_open = mac_mls_check_vnode_open,
 2967         .mpo_check_vnode_poll = mac_mls_check_vnode_poll,
 2968         .mpo_check_vnode_read = mac_mls_check_vnode_read,
 2969         .mpo_check_vnode_readdir = mac_mls_check_vnode_readdir,
 2970         .mpo_check_vnode_readlink = mac_mls_check_vnode_readlink,
 2971         .mpo_check_vnode_relabel = mac_mls_check_vnode_relabel,
 2972         .mpo_check_vnode_rename_from = mac_mls_check_vnode_rename_from,
 2973         .mpo_check_vnode_rename_to = mac_mls_check_vnode_rename_to,
 2974         .mpo_check_vnode_revoke = mac_mls_check_vnode_revoke,
 2975         .mpo_check_vnode_setacl = mac_mls_check_vnode_setacl,
 2976         .mpo_check_vnode_setextattr = mac_mls_check_vnode_setextattr,
 2977         .mpo_check_vnode_setflags = mac_mls_check_vnode_setflags,
 2978         .mpo_check_vnode_setmode = mac_mls_check_vnode_setmode,
 2979         .mpo_check_vnode_setowner = mac_mls_check_vnode_setowner,
 2980         .mpo_check_vnode_setutimes = mac_mls_check_vnode_setutimes,
 2981         .mpo_check_vnode_stat = mac_mls_check_vnode_stat,
 2982         .mpo_check_vnode_write = mac_mls_check_vnode_write,
 2983         .mpo_associate_nfsd_label = mac_mls_associate_nfsd_label,
 2984         .mpo_create_mbuf_from_firewall = mac_mls_create_mbuf_from_firewall,
 2985 };
 2986 
 2987 MAC_POLICY_SET(&mac_mls_ops, mac_mls, "TrustedBSD MAC/MLS",
 2988     MPC_LOADTIME_FLAG_NOTLATE | MPC_LOADTIME_FLAG_LABELMBUFS, &mac_mls_slot);

Cache object: 0657752ea9917696da9a0e339f3e80d1


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