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

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

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

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

Cache object: 2785cec3243dce9331f3cc80e07695a1


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