The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


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

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

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 9404fe1f3b8a713aaaac59e3049f1019


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