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

Cache object: aa0e368d689d4364e486b8e5aaced358


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