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


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

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

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

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

Cache object: 516b2f059fdc4cccb9837366930d65f3


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