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_lomac/mac_lomac.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, 2007 Robert N. M. Watson
    3  * Copyright (c) 2001-2005 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 NAI Labs,
    9  * the Security Research Division of Network Associates, 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  * Low-watermark floating label mandatory integrity 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/malloc.h>
   50 #include <sys/mman.h>
   51 #include <sys/mount.h>
   52 #include <sys/priv.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/sx.h>
   64 #include <sys/pipe.h>
   65 #include <sys/sysctl.h>
   66 #include <sys/syslog.h>
   67 
   68 #include <fs/devfs/devfs.h>
   69 
   70 #include <net/bpfdesc.h>
   71 #include <net/if.h>
   72 #include <net/if_types.h>
   73 #include <net/if_var.h>
   74 
   75 #include <netinet/in.h>
   76 #include <netinet/in_pcb.h>
   77 #include <netinet/ip_var.h>
   78 
   79 #include <vm/vm.h>
   80 
   81 #include <security/mac/mac_policy.h>
   82 #include <security/mac/mac_framework.h>
   83 #include <security/mac_lomac/mac_lomac.h>
   84 
   85 struct mac_lomac_proc {
   86         struct mac_lomac mac_lomac;
   87         struct mtx mtx;
   88 };
   89 
   90 SYSCTL_DECL(_security_mac);
   91 
   92 SYSCTL_NODE(_security_mac, OID_AUTO, lomac, CTLFLAG_RW, 0,
   93     "TrustedBSD mac_lomac policy controls");
   94 
   95 static int      mac_lomac_label_size = sizeof(struct mac_lomac);
   96 SYSCTL_INT(_security_mac_lomac, OID_AUTO, label_size, CTLFLAG_RD,
   97     &mac_lomac_label_size, 0, "Size of struct mac_lomac");
   98 
   99 static int      mac_lomac_enabled = 1;
  100 SYSCTL_INT(_security_mac_lomac, OID_AUTO, enabled, CTLFLAG_RW,
  101     &mac_lomac_enabled, 0, "Enforce MAC/LOMAC policy");
  102 TUNABLE_INT("security.mac.lomac.enabled", &mac_lomac_enabled);
  103 
  104 static int      destroyed_not_inited;
  105 SYSCTL_INT(_security_mac_lomac, OID_AUTO, destroyed_not_inited, CTLFLAG_RD,
  106     &destroyed_not_inited, 0, "Count of labels destroyed but not inited");
  107 
  108 static int      trust_all_interfaces = 0;
  109 SYSCTL_INT(_security_mac_lomac, OID_AUTO, trust_all_interfaces, CTLFLAG_RD,
  110     &trust_all_interfaces, 0, "Consider all interfaces 'trusted' by MAC/LOMAC");
  111 TUNABLE_INT("security.mac.lomac.trust_all_interfaces", &trust_all_interfaces);
  112 
  113 static char     trusted_interfaces[128];
  114 SYSCTL_STRING(_security_mac_lomac, OID_AUTO, trusted_interfaces, CTLFLAG_RD,
  115     trusted_interfaces, 0, "Interfaces considered 'trusted' by MAC/LOMAC");
  116 TUNABLE_STR("security.mac.lomac.trusted_interfaces", trusted_interfaces,
  117     sizeof(trusted_interfaces));
  118 
  119 static int      ptys_equal = 0;
  120 SYSCTL_INT(_security_mac_lomac, OID_AUTO, ptys_equal, CTLFLAG_RW,
  121     &ptys_equal, 0, "Label pty devices as lomac/equal on create");
  122 TUNABLE_INT("security.mac.lomac.ptys_equal", &ptys_equal);
  123 
  124 static int      revocation_enabled = 1;
  125 SYSCTL_INT(_security_mac_lomac, OID_AUTO, revocation_enabled, CTLFLAG_RW,
  126     &revocation_enabled, 0, "Revoke access to objects on relabel");
  127 TUNABLE_INT("security.mac.lomac.revocation_enabled", &revocation_enabled);
  128 
  129 static int      mac_lomac_slot;
  130 #define SLOT(l) ((struct mac_lomac *)mac_label_get((l), mac_lomac_slot))
  131 #define SLOT_SET(l, val) mac_label_set((l), mac_lomac_slot, (uintptr_t)(val))
  132 #define PSLOT(l) ((struct mac_lomac_proc *)                             \
  133     mac_label_get((l), mac_lomac_slot))
  134 #define PSLOT_SET(l, val) mac_label_set((l), mac_lomac_slot, (uintptr_t)(val))
  135 
  136 MALLOC_DEFINE(M_MACLOMAC, "mac_lomac_label", "MAC/LOMAC labels");
  137 
  138 static struct mac_lomac *
  139 lomac_alloc(int flag)
  140 {
  141         struct mac_lomac *mac_lomac;
  142 
  143         mac_lomac = malloc(sizeof(struct mac_lomac), M_MACLOMAC, M_ZERO | flag);
  144 
  145         return (mac_lomac);
  146 }
  147 
  148 static void
  149 lomac_free(struct mac_lomac *mac_lomac)
  150 {
  151 
  152         if (mac_lomac != NULL)
  153                 free(mac_lomac, M_MACLOMAC);
  154         else
  155                 atomic_add_int(&destroyed_not_inited, 1);
  156 }
  157 
  158 static int
  159 lomac_atmostflags(struct mac_lomac *mac_lomac, int flags)
  160 {
  161 
  162         if ((mac_lomac->ml_flags & flags) != mac_lomac->ml_flags)
  163                 return (EINVAL);
  164         return (0);
  165 }
  166 
  167 static int
  168 mac_lomac_dominate_element(struct mac_lomac_element *a,
  169     struct mac_lomac_element *b)
  170 {
  171 
  172         switch (a->mle_type) {
  173         case MAC_LOMAC_TYPE_EQUAL:
  174         case MAC_LOMAC_TYPE_HIGH:
  175                 return (1);
  176 
  177         case MAC_LOMAC_TYPE_LOW:
  178                 switch (b->mle_type) {
  179                 case MAC_LOMAC_TYPE_GRADE:
  180                 case MAC_LOMAC_TYPE_HIGH:
  181                         return (0);
  182 
  183                 case MAC_LOMAC_TYPE_EQUAL:
  184                 case MAC_LOMAC_TYPE_LOW:
  185                         return (1);
  186 
  187                 default:
  188                         panic("mac_lomac_dominate_element: b->mle_type invalid");
  189                 }
  190 
  191         case MAC_LOMAC_TYPE_GRADE:
  192                 switch (b->mle_type) {
  193                 case MAC_LOMAC_TYPE_EQUAL:
  194                 case MAC_LOMAC_TYPE_LOW:
  195                         return (1);
  196 
  197                 case MAC_LOMAC_TYPE_HIGH:
  198                         return (0);
  199 
  200                 case MAC_LOMAC_TYPE_GRADE:
  201                         return (a->mle_grade >= b->mle_grade);
  202 
  203                 default:
  204                         panic("mac_lomac_dominate_element: b->mle_type invalid");
  205                 }
  206 
  207         default:
  208                 panic("mac_lomac_dominate_element: a->mle_type invalid");
  209         }
  210 }
  211 
  212 static int
  213 mac_lomac_range_in_range(struct mac_lomac *rangea, struct mac_lomac *rangeb)
  214 {
  215 
  216         return (mac_lomac_dominate_element(&rangeb->ml_rangehigh,
  217             &rangea->ml_rangehigh) &&
  218             mac_lomac_dominate_element(&rangea->ml_rangelow,
  219             &rangeb->ml_rangelow));
  220 }
  221 
  222 static int
  223 mac_lomac_single_in_range(struct mac_lomac *single, struct mac_lomac *range)
  224 {
  225 
  226         KASSERT((single->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0,
  227             ("mac_lomac_single_in_range: a not single"));
  228         KASSERT((range->ml_flags & MAC_LOMAC_FLAG_RANGE) != 0,
  229             ("mac_lomac_single_in_range: b not range"));
  230 
  231         return (mac_lomac_dominate_element(&range->ml_rangehigh,
  232             &single->ml_single) &&
  233             mac_lomac_dominate_element(&single->ml_single,
  234             &range->ml_rangelow));
  235 }
  236 
  237 static int
  238 mac_lomac_auxsingle_in_range(struct mac_lomac *single, struct mac_lomac *range)
  239 {
  240 
  241         KASSERT((single->ml_flags & MAC_LOMAC_FLAG_AUX) != 0,
  242             ("mac_lomac_single_in_range: a not auxsingle"));
  243         KASSERT((range->ml_flags & MAC_LOMAC_FLAG_RANGE) != 0,
  244             ("mac_lomac_single_in_range: b not range"));
  245 
  246         return (mac_lomac_dominate_element(&range->ml_rangehigh,
  247             &single->ml_auxsingle) &&
  248             mac_lomac_dominate_element(&single->ml_auxsingle,
  249             &range->ml_rangelow));
  250 }
  251 
  252 static int
  253 mac_lomac_dominate_single(struct mac_lomac *a, struct mac_lomac *b)
  254 {
  255         KASSERT((a->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0,
  256             ("mac_lomac_dominate_single: a not single"));
  257         KASSERT((b->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0,
  258             ("mac_lomac_dominate_single: b not single"));
  259 
  260         return (mac_lomac_dominate_element(&a->ml_single, &b->ml_single));
  261 }
  262 
  263 static int
  264 mac_lomac_subject_dominate(struct mac_lomac *a, struct mac_lomac *b)
  265 {
  266         KASSERT((~a->ml_flags &
  267             (MAC_LOMAC_FLAG_SINGLE | MAC_LOMAC_FLAG_RANGE)) == 0,
  268             ("mac_lomac_dominate_single: a not subject"));
  269         KASSERT((b->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0,
  270             ("mac_lomac_dominate_single: b not single"));
  271 
  272         return (mac_lomac_dominate_element(&a->ml_rangehigh,
  273             &b->ml_single));
  274 }
  275 
  276 static int
  277 mac_lomac_equal_element(struct mac_lomac_element *a, struct mac_lomac_element *b)
  278 {
  279 
  280         if (a->mle_type == MAC_LOMAC_TYPE_EQUAL ||
  281             b->mle_type == MAC_LOMAC_TYPE_EQUAL)
  282                 return (1);
  283 
  284         return (a->mle_type == b->mle_type && a->mle_grade == b->mle_grade);
  285 }
  286 
  287 static int
  288 mac_lomac_equal_single(struct mac_lomac *a, struct mac_lomac *b)
  289 {
  290 
  291         KASSERT((a->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0,
  292             ("mac_lomac_equal_single: a not single"));
  293         KASSERT((b->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0,
  294             ("mac_lomac_equal_single: b not single"));
  295 
  296         return (mac_lomac_equal_element(&a->ml_single, &b->ml_single));
  297 }
  298 
  299 static int
  300 mac_lomac_contains_equal(struct mac_lomac *mac_lomac)
  301 {
  302 
  303         if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_SINGLE)
  304                 if (mac_lomac->ml_single.mle_type == MAC_LOMAC_TYPE_EQUAL)
  305                         return (1);
  306         if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_AUX)
  307                 if (mac_lomac->ml_auxsingle.mle_type == MAC_LOMAC_TYPE_EQUAL)
  308                         return (1);
  309 
  310         if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_RANGE) {
  311                 if (mac_lomac->ml_rangelow.mle_type == MAC_LOMAC_TYPE_EQUAL)
  312                         return (1);
  313                 if (mac_lomac->ml_rangehigh.mle_type == MAC_LOMAC_TYPE_EQUAL)
  314                         return (1);
  315         }
  316 
  317         return (0);
  318 }
  319 
  320 static int
  321 mac_lomac_subject_privileged(struct mac_lomac *mac_lomac)
  322 {
  323 
  324         KASSERT((mac_lomac->ml_flags & MAC_LOMAC_FLAGS_BOTH) ==
  325             MAC_LOMAC_FLAGS_BOTH,
  326             ("mac_lomac_subject_privileged: subject doesn't have both labels"));
  327 
  328         /* If the single is EQUAL, it's ok. */
  329         if (mac_lomac->ml_single.mle_type == MAC_LOMAC_TYPE_EQUAL)
  330                 return (0);
  331 
  332         /* If either range endpoint is EQUAL, it's ok. */
  333         if (mac_lomac->ml_rangelow.mle_type == MAC_LOMAC_TYPE_EQUAL ||
  334             mac_lomac->ml_rangehigh.mle_type == MAC_LOMAC_TYPE_EQUAL)
  335                 return (0);
  336 
  337         /* If the range is low-high, it's ok. */
  338         if (mac_lomac->ml_rangelow.mle_type == MAC_LOMAC_TYPE_LOW &&
  339             mac_lomac->ml_rangehigh.mle_type == MAC_LOMAC_TYPE_HIGH)
  340                 return (0);
  341 
  342         /* It's not ok. */
  343         return (EPERM);
  344 }
  345 
  346 static int
  347 mac_lomac_high_single(struct mac_lomac *mac_lomac)
  348 {
  349 
  350         KASSERT((mac_lomac->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0,
  351             ("mac_lomac_high_single: mac_lomac not single"));
  352 
  353         return (mac_lomac->ml_single.mle_type == MAC_LOMAC_TYPE_HIGH);
  354 }
  355 
  356 static int
  357 mac_lomac_valid(struct mac_lomac *mac_lomac)
  358 {
  359 
  360         if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_SINGLE) {
  361                 switch (mac_lomac->ml_single.mle_type) {
  362                 case MAC_LOMAC_TYPE_GRADE:
  363                 case MAC_LOMAC_TYPE_EQUAL:
  364                 case MAC_LOMAC_TYPE_HIGH:
  365                 case MAC_LOMAC_TYPE_LOW:
  366                         break;
  367 
  368                 default:
  369                         return (EINVAL);
  370                 }
  371         } else {
  372                 if (mac_lomac->ml_single.mle_type != MAC_LOMAC_TYPE_UNDEF)
  373                         return (EINVAL);
  374         }
  375 
  376         if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_AUX) {
  377                 switch (mac_lomac->ml_auxsingle.mle_type) {
  378                 case MAC_LOMAC_TYPE_GRADE:
  379                 case MAC_LOMAC_TYPE_EQUAL:
  380                 case MAC_LOMAC_TYPE_HIGH:
  381                 case MAC_LOMAC_TYPE_LOW:
  382                         break;
  383 
  384                 default:
  385                         return (EINVAL);
  386                 }
  387         } else {
  388                 if (mac_lomac->ml_auxsingle.mle_type != MAC_LOMAC_TYPE_UNDEF)
  389                         return (EINVAL);
  390         }
  391 
  392         if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_RANGE) {
  393                 switch (mac_lomac->ml_rangelow.mle_type) {
  394                 case MAC_LOMAC_TYPE_GRADE:
  395                 case MAC_LOMAC_TYPE_EQUAL:
  396                 case MAC_LOMAC_TYPE_HIGH:
  397                 case MAC_LOMAC_TYPE_LOW:
  398                         break;
  399 
  400                 default:
  401                         return (EINVAL);
  402                 }
  403 
  404                 switch (mac_lomac->ml_rangehigh.mle_type) {
  405                 case MAC_LOMAC_TYPE_GRADE:
  406                 case MAC_LOMAC_TYPE_EQUAL:
  407                 case MAC_LOMAC_TYPE_HIGH:
  408                 case MAC_LOMAC_TYPE_LOW:
  409                         break;
  410 
  411                 default:
  412                         return (EINVAL);
  413                 }
  414                 if (!mac_lomac_dominate_element(&mac_lomac->ml_rangehigh,
  415                     &mac_lomac->ml_rangelow))
  416                         return (EINVAL);
  417         } else {
  418                 if (mac_lomac->ml_rangelow.mle_type != MAC_LOMAC_TYPE_UNDEF ||
  419                     mac_lomac->ml_rangehigh.mle_type != MAC_LOMAC_TYPE_UNDEF)
  420                         return (EINVAL);
  421         }
  422 
  423         return (0);
  424 }
  425 
  426 static void
  427 mac_lomac_set_range(struct mac_lomac *mac_lomac, u_short typelow,
  428     u_short gradelow, u_short typehigh, u_short gradehigh)
  429 {
  430 
  431         mac_lomac->ml_rangelow.mle_type = typelow;
  432         mac_lomac->ml_rangelow.mle_grade = gradelow;
  433         mac_lomac->ml_rangehigh.mle_type = typehigh;
  434         mac_lomac->ml_rangehigh.mle_grade = gradehigh;
  435         mac_lomac->ml_flags |= MAC_LOMAC_FLAG_RANGE;
  436 }
  437 
  438 static void
  439 mac_lomac_set_single(struct mac_lomac *mac_lomac, u_short type, u_short grade)
  440 {
  441 
  442         mac_lomac->ml_single.mle_type = type;
  443         mac_lomac->ml_single.mle_grade = grade;
  444         mac_lomac->ml_flags |= MAC_LOMAC_FLAG_SINGLE;
  445 }
  446 
  447 static void
  448 mac_lomac_copy_range(struct mac_lomac *labelfrom, struct mac_lomac *labelto)
  449 {
  450 
  451         KASSERT((labelfrom->ml_flags & MAC_LOMAC_FLAG_RANGE) != 0,
  452             ("mac_lomac_copy_range: labelfrom not range"));
  453 
  454         labelto->ml_rangelow = labelfrom->ml_rangelow;
  455         labelto->ml_rangehigh = labelfrom->ml_rangehigh;
  456         labelto->ml_flags |= MAC_LOMAC_FLAG_RANGE;
  457 }
  458 
  459 static void
  460 mac_lomac_copy_single(struct mac_lomac *labelfrom, struct mac_lomac *labelto)
  461 {
  462 
  463         KASSERT((labelfrom->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0,
  464             ("mac_lomac_copy_single: labelfrom not single"));
  465 
  466         labelto->ml_single = labelfrom->ml_single;
  467         labelto->ml_flags |= MAC_LOMAC_FLAG_SINGLE;
  468 }
  469 
  470 static void
  471 mac_lomac_copy_auxsingle(struct mac_lomac *labelfrom, struct mac_lomac *labelto)
  472 {
  473 
  474         KASSERT((labelfrom->ml_flags & MAC_LOMAC_FLAG_AUX) != 0,
  475             ("mac_lomac_copy_auxsingle: labelfrom not auxsingle"));
  476 
  477         labelto->ml_auxsingle = labelfrom->ml_auxsingle;
  478         labelto->ml_flags |= MAC_LOMAC_FLAG_AUX;
  479 }
  480 
  481 static void
  482 mac_lomac_copy(struct mac_lomac *source, struct mac_lomac *dest)
  483 {
  484 
  485         if (source->ml_flags & MAC_LOMAC_FLAG_SINGLE)
  486                 mac_lomac_copy_single(source, dest);
  487         if (source->ml_flags & MAC_LOMAC_FLAG_AUX)
  488                 mac_lomac_copy_auxsingle(source, dest);
  489         if (source->ml_flags & MAC_LOMAC_FLAG_RANGE)
  490                 mac_lomac_copy_range(source, dest);
  491 }
  492 
  493 static int      mac_lomac_to_string(struct sbuf *sb,
  494                     struct mac_lomac *mac_lomac);
  495 
  496 static int
  497 maybe_demote(struct mac_lomac *subjlabel, struct mac_lomac *objlabel,
  498     const char *actionname, const char *objname, struct vnode *vp)
  499 {
  500         struct sbuf subjlabel_sb, subjtext_sb, objlabel_sb;
  501         char *subjlabeltext, *objlabeltext, *subjtext;
  502         struct mac_lomac cached_subjlabel;
  503         struct mac_lomac_proc *subj;
  504         struct vattr va;
  505         struct proc *p;
  506         pid_t pgid;
  507 
  508         subj = PSLOT(curthread->td_proc->p_label);
  509 
  510         p = curthread->td_proc;
  511         mtx_lock(&subj->mtx);
  512         if (subj->mac_lomac.ml_flags & MAC_LOMAC_FLAG_UPDATE) {
  513                 /*
  514                  * Check to see if the pending demotion would be more or
  515                  * less severe than this one, and keep the more severe.
  516                  * This can only happen for a multi-threaded application.
  517                  */
  518                 if (mac_lomac_dominate_single(objlabel, &subj->mac_lomac)) {
  519                         mtx_unlock(&subj->mtx);
  520                         return (0);
  521                 }
  522         }
  523         bzero(&subj->mac_lomac, sizeof(subj->mac_lomac));
  524         /*
  525          * Always demote the single label.
  526          */
  527         mac_lomac_copy_single(objlabel, &subj->mac_lomac);
  528         /*
  529          * Start with the original range, then minimize each side of
  530          * the range to the point of not dominating the object.  The
  531          * high side will always be demoted, of course.
  532          */
  533         mac_lomac_copy_range(subjlabel, &subj->mac_lomac);
  534         if (!mac_lomac_dominate_element(&objlabel->ml_single,
  535             &subj->mac_lomac.ml_rangelow))
  536                 subj->mac_lomac.ml_rangelow = objlabel->ml_single;
  537         subj->mac_lomac.ml_rangehigh = objlabel->ml_single;
  538         subj->mac_lomac.ml_flags |= MAC_LOMAC_FLAG_UPDATE;
  539         thread_lock(curthread);
  540         curthread->td_flags |= TDF_ASTPENDING | TDF_MACPEND;
  541         thread_unlock(curthread);
  542 
  543         /*
  544          * Avoid memory allocation while holding a mutex; cache the
  545          * label.
  546          */
  547         mac_lomac_copy_single(&subj->mac_lomac, &cached_subjlabel);
  548         mtx_unlock(&subj->mtx);
  549 
  550         sbuf_new(&subjlabel_sb, NULL, 0, SBUF_AUTOEXTEND);
  551         mac_lomac_to_string(&subjlabel_sb, subjlabel);
  552         sbuf_finish(&subjlabel_sb);
  553         subjlabeltext = sbuf_data(&subjlabel_sb);
  554 
  555         sbuf_new(&subjtext_sb, NULL, 0, SBUF_AUTOEXTEND);
  556         mac_lomac_to_string(&subjtext_sb, &subj->mac_lomac);
  557         sbuf_finish(&subjtext_sb);
  558         subjtext = sbuf_data(&subjtext_sb);
  559 
  560         sbuf_new(&objlabel_sb, NULL, 0, SBUF_AUTOEXTEND);
  561         mac_lomac_to_string(&objlabel_sb, objlabel);
  562         sbuf_finish(&objlabel_sb);
  563         objlabeltext = sbuf_data(&objlabel_sb);
  564 
  565         pgid = p->p_pgrp->pg_id;                /* XXX could be stale? */
  566         if (vp != NULL && VOP_GETATTR(vp, &va, curthread->td_ucred,
  567             curthread) == 0) {
  568                 log(LOG_INFO, "LOMAC: level-%s subject p%dg%du%d:%s demoted to"
  569                     " level %s after %s a level-%s %s (inode=%ld, "
  570                     "mountpount=%s)\n",
  571                     subjlabeltext, p->p_pid, pgid, curthread->td_ucred->cr_uid,
  572                     p->p_comm, subjtext, actionname, objlabeltext, objname,
  573                     va.va_fileid, vp->v_mount->mnt_stat.f_mntonname);
  574         } else {
  575                 log(LOG_INFO, "LOMAC: level-%s subject p%dg%du%d:%s demoted to"
  576                     " level %s after %s a level-%s %s\n",
  577                     subjlabeltext, p->p_pid, pgid, curthread->td_ucred->cr_uid,
  578                     p->p_comm, subjtext, actionname, objlabeltext, objname);
  579         }
  580 
  581         sbuf_delete(&subjlabel_sb);
  582         sbuf_delete(&subjtext_sb);
  583         sbuf_delete(&objlabel_sb);
  584                 
  585         return (0);
  586 }
  587 
  588 /*
  589  * Relabel "to" to "from" only if "from" is a valid label (contains
  590  * at least a single), as for a relabel operation which may or may
  591  * not involve a relevant label.
  592  */
  593 static void
  594 try_relabel(struct mac_lomac *from, struct mac_lomac *to)
  595 {
  596 
  597         if (from->ml_flags & MAC_LOMAC_FLAG_SINGLE) {
  598                 bzero(to, sizeof(*to));
  599                 mac_lomac_copy(from, to);
  600         }
  601 }
  602 
  603 /*
  604  * Policy module operations.
  605  */
  606 static void
  607 mac_lomac_init(struct mac_policy_conf *conf)
  608 {
  609 
  610 }
  611 
  612 /*
  613  * Label operations.
  614  */
  615 static void
  616 mac_lomac_init_label(struct label *label)
  617 {
  618 
  619         SLOT_SET(label, lomac_alloc(M_WAITOK));
  620 }
  621 
  622 static int
  623 mac_lomac_init_label_waitcheck(struct label *label, int flag)
  624 {
  625 
  626         SLOT_SET(label, lomac_alloc(flag));
  627         if (SLOT(label) == NULL)
  628                 return (ENOMEM);
  629 
  630         return (0);
  631 }
  632 
  633 static void
  634 mac_lomac_init_proc_label(struct label *label)
  635 {
  636 
  637         PSLOT_SET(label, malloc(sizeof(struct mac_lomac_proc), M_MACLOMAC,
  638             M_ZERO | M_WAITOK));
  639         mtx_init(&PSLOT(label)->mtx, "MAC/Lomac proc lock", NULL, MTX_DEF);
  640 }
  641 
  642 static void
  643 mac_lomac_destroy_label(struct label *label)
  644 {
  645 
  646         lomac_free(SLOT(label));
  647         SLOT_SET(label, NULL);
  648 }
  649 
  650 static void
  651 mac_lomac_destroy_proc_label(struct label *label)
  652 {
  653 
  654         mtx_destroy(&PSLOT(label)->mtx);
  655         FREE(PSLOT(label), M_MACLOMAC);
  656         PSLOT_SET(label, NULL);
  657 }
  658 
  659 static int
  660 mac_lomac_element_to_string(struct sbuf *sb, struct mac_lomac_element *element)
  661 {
  662 
  663         switch (element->mle_type) {
  664         case MAC_LOMAC_TYPE_HIGH:
  665                 return (sbuf_printf(sb, "high"));
  666 
  667         case MAC_LOMAC_TYPE_LOW:
  668                 return (sbuf_printf(sb, "low"));
  669 
  670         case MAC_LOMAC_TYPE_EQUAL:
  671                 return (sbuf_printf(sb, "equal"));
  672 
  673         case MAC_LOMAC_TYPE_GRADE:
  674                 return (sbuf_printf(sb, "%d", element->mle_grade));
  675 
  676         default:
  677                 panic("mac_lomac_element_to_string: invalid type (%d)",
  678                     element->mle_type);
  679         }
  680 }
  681 
  682 static int
  683 mac_lomac_to_string(struct sbuf *sb, struct mac_lomac *mac_lomac)
  684 {
  685 
  686         if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_SINGLE) {
  687                 if (mac_lomac_element_to_string(sb, &mac_lomac->ml_single)
  688                     == -1)
  689                         return (EINVAL);
  690         }
  691 
  692         if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_AUX) {
  693                 if (sbuf_putc(sb, '[') == -1)
  694                         return (EINVAL);
  695 
  696                 if (mac_lomac_element_to_string(sb, &mac_lomac->ml_auxsingle)
  697                     == -1)
  698                         return (EINVAL);
  699 
  700                 if (sbuf_putc(sb, ']') == -1)
  701                         return (EINVAL);
  702         }
  703 
  704         if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_RANGE) {
  705                 if (sbuf_putc(sb, '(') == -1)
  706                         return (EINVAL);
  707 
  708                 if (mac_lomac_element_to_string(sb, &mac_lomac->ml_rangelow)
  709                     == -1)
  710                         return (EINVAL);
  711 
  712                 if (sbuf_putc(sb, '-') == -1)
  713                         return (EINVAL);
  714 
  715                 if (mac_lomac_element_to_string(sb, &mac_lomac->ml_rangehigh)
  716                     == -1)
  717                         return (EINVAL);
  718 
  719                 if (sbuf_putc(sb, ')') == -1)
  720                         return (EINVAL);
  721         }
  722 
  723         return (0);
  724 }
  725 
  726 static int
  727 mac_lomac_externalize_label(struct label *label, char *element_name,
  728     struct sbuf *sb, int *claimed)
  729 {
  730         struct mac_lomac *mac_lomac;
  731 
  732         if (strcmp(MAC_LOMAC_LABEL_NAME, element_name) != 0)
  733                 return (0);
  734 
  735         (*claimed)++;
  736 
  737         mac_lomac = SLOT(label);
  738 
  739         return (mac_lomac_to_string(sb, mac_lomac));
  740 }
  741 
  742 static int
  743 mac_lomac_parse_element(struct mac_lomac_element *element, char *string)
  744 {
  745 
  746         if (strcmp(string, "high") == 0 ||
  747             strcmp(string, "hi") == 0) {
  748                 element->mle_type = MAC_LOMAC_TYPE_HIGH;
  749                 element->mle_grade = MAC_LOMAC_TYPE_UNDEF;
  750         } else if (strcmp(string, "low") == 0 ||
  751             strcmp(string, "lo") == 0) {
  752                 element->mle_type = MAC_LOMAC_TYPE_LOW;
  753                 element->mle_grade = MAC_LOMAC_TYPE_UNDEF;
  754         } else if (strcmp(string, "equal") == 0 ||
  755             strcmp(string, "eq") == 0) {
  756                 element->mle_type = MAC_LOMAC_TYPE_EQUAL;
  757                 element->mle_grade = MAC_LOMAC_TYPE_UNDEF;
  758         } else {
  759                 char *p0, *p1;
  760                 int d;
  761 
  762                 p0 = string;
  763                 d = strtol(p0, &p1, 10);
  764         
  765                 if (d < 0 || d > 65535)
  766                         return (EINVAL);
  767                 element->mle_type = MAC_LOMAC_TYPE_GRADE;
  768                 element->mle_grade = d;
  769 
  770                 if (p1 == p0 || *p1 != '\0')
  771                         return (EINVAL);
  772         }
  773 
  774         return (0);
  775 }
  776 
  777 /*
  778  * Note: destructively consumes the string, make a local copy before
  779  * calling if that's a problem.
  780  */
  781 static int
  782 mac_lomac_parse(struct mac_lomac *mac_lomac, char *string)
  783 {
  784         char *range, *rangeend, *rangehigh, *rangelow, *single, *auxsingle,
  785             *auxsingleend;
  786         int error;
  787 
  788         /* Do we have a range? */
  789         single = string;
  790         range = index(string, '(');
  791         if (range == single)
  792                 single = NULL;
  793         auxsingle = index(string, '[');
  794         if (auxsingle == single)
  795                 single = NULL;
  796         if (range != NULL && auxsingle != NULL)
  797                 return (EINVAL);
  798         rangelow = rangehigh = NULL;
  799         if (range != NULL) {
  800                 /* Nul terminate the end of the single string. */
  801                 *range = '\0';
  802                 range++;
  803                 rangelow = range;
  804                 rangehigh = index(rangelow, '-');
  805                 if (rangehigh == NULL)
  806                         return (EINVAL);
  807                 rangehigh++;
  808                 if (*rangelow == '\0' || *rangehigh == '\0')
  809                         return (EINVAL);
  810                 rangeend = index(rangehigh, ')');
  811                 if (rangeend == NULL)
  812                         return (EINVAL);
  813                 if (*(rangeend + 1) != '\0')
  814                         return (EINVAL);
  815                 /* Nul terminate the ends of the ranges. */
  816                 *(rangehigh - 1) = '\0';
  817                 *rangeend = '\0';
  818         }
  819         KASSERT((rangelow != NULL && rangehigh != NULL) ||
  820             (rangelow == NULL && rangehigh == NULL),
  821             ("mac_lomac_internalize_label: range mismatch"));
  822         if (auxsingle != NULL) {
  823                 /* Nul terminate the end of the single string. */
  824                 *auxsingle = '\0';
  825                 auxsingle++;
  826                 auxsingleend = index(auxsingle, ']');
  827                 if (auxsingleend == NULL)
  828                         return (EINVAL);
  829                 if (*(auxsingleend + 1) != '\0')
  830                         return (EINVAL);
  831                 /* Nul terminate the end of the auxsingle. */
  832                 *auxsingleend = '\0';
  833         }
  834 
  835         bzero(mac_lomac, sizeof(*mac_lomac));
  836         if (single != NULL) {
  837                 error = mac_lomac_parse_element(&mac_lomac->ml_single, single);
  838                 if (error)
  839                         return (error);
  840                 mac_lomac->ml_flags |= MAC_LOMAC_FLAG_SINGLE;
  841         }
  842 
  843         if (auxsingle != NULL) {
  844                 error = mac_lomac_parse_element(&mac_lomac->ml_auxsingle,
  845                     auxsingle);
  846                 if (error)
  847                         return (error);
  848                 mac_lomac->ml_flags |= MAC_LOMAC_FLAG_AUX;
  849         }
  850 
  851         if (rangelow != NULL) {
  852                 error = mac_lomac_parse_element(&mac_lomac->ml_rangelow,
  853                     rangelow);
  854                 if (error)
  855                         return (error);
  856                 error = mac_lomac_parse_element(&mac_lomac->ml_rangehigh,
  857                     rangehigh);
  858                 if (error)
  859                         return (error);
  860                 mac_lomac->ml_flags |= MAC_LOMAC_FLAG_RANGE;
  861         }
  862 
  863         error = mac_lomac_valid(mac_lomac);
  864         if (error)
  865                 return (error);
  866 
  867         return (0);
  868 }
  869 
  870 static int
  871 mac_lomac_internalize_label(struct label *label, char *element_name,
  872     char *element_data, int *claimed)
  873 {
  874         struct mac_lomac *mac_lomac, mac_lomac_temp;
  875         int error;
  876 
  877         if (strcmp(MAC_LOMAC_LABEL_NAME, element_name) != 0)
  878                 return (0);
  879 
  880         (*claimed)++;
  881 
  882         error = mac_lomac_parse(&mac_lomac_temp, element_data);
  883         if (error)
  884                 return (error);
  885 
  886         mac_lomac = SLOT(label);
  887         *mac_lomac = mac_lomac_temp;
  888 
  889         return (0);
  890 }
  891 
  892 static void
  893 mac_lomac_copy_label(struct label *src, struct label *dest)
  894 {
  895 
  896         *SLOT(dest) = *SLOT(src);
  897 }
  898 
  899 /*
  900  * Labeling event operations: file system objects, and things that look
  901  * a lot like file system objects.
  902  */
  903 static void
  904 mac_lomac_create_devfs_device(struct ucred *cred, struct mount *mp,
  905     struct cdev *dev, struct devfs_dirent *de, struct label *delabel)
  906 {
  907         struct mac_lomac *mac_lomac;
  908         int lomac_type;
  909 
  910         mac_lomac = SLOT(delabel);
  911         if (strcmp(dev->si_name, "null") == 0 ||
  912             strcmp(dev->si_name, "zero") == 0 ||
  913             strcmp(dev->si_name, "random") == 0 ||
  914             strncmp(dev->si_name, "fd/", strlen("fd/")) == 0 ||
  915             strncmp(dev->si_name, "ttyv", strlen("ttyv")) == 0)
  916                 lomac_type = MAC_LOMAC_TYPE_EQUAL;
  917         else if (ptys_equal &&
  918             (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 ||
  919             strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0))
  920                 lomac_type = MAC_LOMAC_TYPE_EQUAL;
  921         else
  922                 lomac_type = MAC_LOMAC_TYPE_HIGH;
  923         mac_lomac_set_single(mac_lomac, lomac_type, 0);
  924 }
  925 
  926 static void
  927 mac_lomac_create_devfs_directory(struct mount *mp, char *dirname,
  928     int dirnamelen, struct devfs_dirent *de, struct label *delabel)
  929 {
  930         struct mac_lomac *mac_lomac;
  931 
  932         mac_lomac = SLOT(delabel);
  933         mac_lomac_set_single(mac_lomac, MAC_LOMAC_TYPE_HIGH, 0);
  934 }
  935 
  936 static void
  937 mac_lomac_create_devfs_symlink(struct ucred *cred, struct mount *mp,
  938     struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de,
  939     struct label *delabel)
  940 {
  941         struct mac_lomac *source, *dest;
  942 
  943         source = SLOT(cred->cr_label);
  944         dest = SLOT(delabel);
  945 
  946         mac_lomac_copy_single(source, dest);
  947 }
  948 
  949 static void
  950 mac_lomac_create_mount(struct ucred *cred, struct mount *mp,
  951     struct label *mplabel)
  952 {
  953         struct mac_lomac *source, *dest;
  954 
  955         source = SLOT(cred->cr_label);
  956         dest = SLOT(mplabel);
  957         mac_lomac_copy_single(source, dest);
  958 }
  959 
  960 static void
  961 mac_lomac_relabel_vnode(struct ucred *cred, struct vnode *vp,
  962     struct label *vplabel, struct label *newlabel)
  963 {
  964         struct mac_lomac *source, *dest;
  965 
  966         source = SLOT(newlabel);
  967         dest = SLOT(vplabel);
  968 
  969         try_relabel(source, dest);
  970 }
  971 
  972 static void
  973 mac_lomac_update_devfs(struct mount *mp, struct devfs_dirent *de,
  974     struct label *delabel, struct vnode *vp, struct label *vplabel)
  975 {
  976         struct mac_lomac *source, *dest;
  977 
  978         source = SLOT(vplabel);
  979         dest = SLOT(delabel);
  980 
  981         mac_lomac_copy(source, dest);
  982 }
  983 
  984 static void
  985 mac_lomac_associate_vnode_devfs(struct mount *mp, struct label *mplabel,
  986     struct devfs_dirent *de, struct label *delabel, struct vnode *vp,
  987     struct label *vplabel)
  988 {
  989         struct mac_lomac *source, *dest;
  990 
  991         source = SLOT(delabel);
  992         dest = SLOT(vplabel);
  993 
  994         mac_lomac_copy_single(source, dest);
  995 }
  996 
  997 static int
  998 mac_lomac_associate_vnode_extattr(struct mount *mp, struct label *mplabel,
  999     struct vnode *vp, struct label *vplabel)
 1000 {
 1001         struct mac_lomac temp, *source, *dest;
 1002         int buflen, error;
 1003 
 1004         source = SLOT(mplabel);
 1005         dest = SLOT(vplabel);
 1006 
 1007         buflen = sizeof(temp);
 1008         bzero(&temp, buflen);
 1009 
 1010         error = vn_extattr_get(vp, IO_NODELOCKED, MAC_LOMAC_EXTATTR_NAMESPACE,
 1011             MAC_LOMAC_EXTATTR_NAME, &buflen, (char *)&temp, curthread);
 1012         if (error == ENOATTR || error == EOPNOTSUPP) {
 1013                 /* Fall back to the mntlabel. */
 1014                 mac_lomac_copy_single(source, dest);
 1015                 return (0);
 1016         } else if (error)
 1017                 return (error);
 1018 
 1019         if (buflen != sizeof(temp)) {
 1020                 if (buflen != sizeof(temp) - sizeof(temp.ml_auxsingle)) {
 1021                         printf("mac_lomac_associate_vnode_extattr: bad size %d\n",
 1022                             buflen);
 1023                         return (EPERM);
 1024                 }
 1025                 bzero(&temp.ml_auxsingle, sizeof(temp.ml_auxsingle));
 1026                 buflen = sizeof(temp);
 1027                 (void)vn_extattr_set(vp, IO_NODELOCKED,
 1028                     MAC_LOMAC_EXTATTR_NAMESPACE, MAC_LOMAC_EXTATTR_NAME,
 1029                     buflen, (char *)&temp, curthread);
 1030         }
 1031         if (mac_lomac_valid(&temp) != 0) {
 1032                 printf("mac_lomac_associate_vnode_extattr: invalid\n");
 1033                 return (EPERM);
 1034         }
 1035         if ((temp.ml_flags & MAC_LOMAC_FLAGS_BOTH) != MAC_LOMAC_FLAG_SINGLE) {
 1036                 printf("mac_lomac_associate_vnode_extattr: not single\n");
 1037                 return (EPERM);
 1038         }
 1039 
 1040         mac_lomac_copy_single(&temp, dest);
 1041         return (0);
 1042 }
 1043 
 1044 static void
 1045 mac_lomac_associate_vnode_singlelabel(struct mount *mp,
 1046     struct label *mplabel, struct vnode *vp, struct label *vplabel)
 1047 {
 1048         struct mac_lomac *source, *dest;
 1049 
 1050         source = SLOT(mplabel);
 1051         dest = SLOT(vplabel);
 1052 
 1053         mac_lomac_copy_single(source, dest);
 1054 }
 1055 
 1056 static int
 1057 mac_lomac_create_vnode_extattr(struct ucred *cred, struct mount *mp,
 1058     struct label *mplabel, struct vnode *dvp, struct label *dvplabel,
 1059     struct vnode *vp, struct label *vplabel, struct componentname *cnp)
 1060 {
 1061         struct mac_lomac *source, *dest, *dir, temp;
 1062         size_t buflen;
 1063         int error;
 1064 
 1065         buflen = sizeof(temp);
 1066         bzero(&temp, buflen);
 1067 
 1068         source = SLOT(cred->cr_label);
 1069         dest = SLOT(vplabel);
 1070         dir = SLOT(dvplabel);
 1071         if (dir->ml_flags & MAC_LOMAC_FLAG_AUX) {
 1072                 mac_lomac_copy_auxsingle(dir, &temp);
 1073                 mac_lomac_set_single(&temp, dir->ml_auxsingle.mle_type,
 1074                     dir->ml_auxsingle.mle_grade);
 1075         } else {
 1076                 mac_lomac_copy_single(source, &temp);
 1077         }
 1078 
 1079         error = vn_extattr_set(vp, IO_NODELOCKED, MAC_LOMAC_EXTATTR_NAMESPACE,
 1080             MAC_LOMAC_EXTATTR_NAME, buflen, (char *)&temp, curthread);
 1081         if (error == 0)
 1082                 mac_lomac_copy(&temp, dest);
 1083         return (error);
 1084 }
 1085 
 1086 static int
 1087 mac_lomac_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp,
 1088     struct label *vplabel, struct label *intlabel)
 1089 {
 1090         struct mac_lomac *source, temp;
 1091         size_t buflen;
 1092         int error;
 1093 
 1094         buflen = sizeof(temp);
 1095         bzero(&temp, buflen);
 1096 
 1097         source = SLOT(intlabel);
 1098         if ((source->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0)
 1099                 return (0);
 1100 
 1101         mac_lomac_copy_single(source, &temp);
 1102         error = vn_extattr_set(vp, IO_NODELOCKED, MAC_LOMAC_EXTATTR_NAMESPACE,
 1103             MAC_LOMAC_EXTATTR_NAME, buflen, (char *)&temp, curthread);
 1104         return (error);
 1105 }
 1106 
 1107 /*
 1108  * Labeling event operations: IPC object.
 1109  */
 1110 static void
 1111 mac_lomac_create_inpcb_from_socket(struct socket *so, struct label *solabel,
 1112     struct inpcb *inp, struct label *inplabel)
 1113 {
 1114         struct mac_lomac *source, *dest;
 1115 
 1116         source = SLOT(solabel);
 1117         dest = SLOT(inplabel);
 1118 
 1119         mac_lomac_copy_single(source, dest);
 1120 }
 1121 
 1122 static void
 1123 mac_lomac_create_mbuf_from_socket(struct socket *so, struct label *solabel,
 1124     struct mbuf *m, struct label *mlabel)
 1125 {
 1126         struct mac_lomac *source, *dest;
 1127 
 1128         source = SLOT(solabel);
 1129         dest = SLOT(mlabel);
 1130 
 1131         mac_lomac_copy_single(source, dest);
 1132 }
 1133 
 1134 static void
 1135 mac_lomac_create_socket(struct ucred *cred, struct socket *so,
 1136     struct label *solabel)
 1137 {
 1138         struct mac_lomac *source, *dest;
 1139 
 1140         source = SLOT(cred->cr_label);
 1141         dest = SLOT(solabel);
 1142 
 1143         mac_lomac_copy_single(source, dest);
 1144 }
 1145 
 1146 static void
 1147 mac_lomac_create_pipe(struct ucred *cred, struct pipepair *pp,
 1148     struct label *pplabel)
 1149 {
 1150         struct mac_lomac *source, *dest;
 1151 
 1152         source = SLOT(cred->cr_label);
 1153         dest = SLOT(pplabel);
 1154 
 1155         mac_lomac_copy_single(source, dest);
 1156 }
 1157 
 1158 static void
 1159 mac_lomac_create_socket_from_socket(struct socket *oldso,
 1160     struct label *oldsolabel, struct socket *newso, struct label *newsolabel)
 1161 {
 1162         struct mac_lomac *source, *dest;
 1163 
 1164         source = SLOT(oldsolabel);
 1165         dest = SLOT(newsolabel);
 1166 
 1167         mac_lomac_copy_single(source, dest);
 1168 }
 1169 
 1170 static void
 1171 mac_lomac_relabel_socket(struct ucred *cred, struct socket *so,
 1172     struct label *solabel, struct label *newlabel)
 1173 {
 1174         struct mac_lomac *source, *dest;
 1175 
 1176         source = SLOT(newlabel);
 1177         dest = SLOT(solabel);
 1178 
 1179         try_relabel(source, dest);
 1180 }
 1181 
 1182 static void
 1183 mac_lomac_relabel_pipe(struct ucred *cred, struct pipepair *pp,
 1184     struct label *pplabel, struct label *newlabel)
 1185 {
 1186         struct mac_lomac *source, *dest;
 1187 
 1188         source = SLOT(newlabel);
 1189         dest = SLOT(pplabel);
 1190 
 1191         try_relabel(source, dest);
 1192 }
 1193 
 1194 static void
 1195 mac_lomac_set_socket_peer_from_mbuf(struct mbuf *m, struct label *mlabel,
 1196     struct socket *so, struct label *sopeerlabel)
 1197 {
 1198         struct mac_lomac *source, *dest;
 1199 
 1200         source = SLOT(mlabel);
 1201         dest = SLOT(sopeerlabel);
 1202 
 1203         mac_lomac_copy_single(source, dest);
 1204 }
 1205 
 1206 /*
 1207  * Labeling event operations: network objects.
 1208  */
 1209 static void
 1210 mac_lomac_set_socket_peer_from_socket(struct socket *oldso,
 1211     struct label *oldsolabel, struct socket *newso,
 1212     struct label *newsopeerlabel)
 1213 {
 1214         struct mac_lomac *source, *dest;
 1215 
 1216         source = SLOT(oldsolabel);
 1217         dest = SLOT(newsopeerlabel);
 1218 
 1219         mac_lomac_copy_single(source, dest);
 1220 }
 1221 
 1222 static void
 1223 mac_lomac_create_bpfdesc(struct ucred *cred, struct bpf_d *d,
 1224     struct label *dlabel)
 1225 {
 1226         struct mac_lomac *source, *dest;
 1227 
 1228         source = SLOT(cred->cr_label);
 1229         dest = SLOT(dlabel);
 1230 
 1231         mac_lomac_copy_single(source, dest);
 1232 }
 1233 
 1234 static void
 1235 mac_lomac_create_ifnet(struct ifnet *ifp, struct label *ifplabel)
 1236 {
 1237         char tifname[IFNAMSIZ], *p, *q;
 1238         char tiflist[sizeof(trusted_interfaces)];
 1239         struct mac_lomac *dest;
 1240         int len, grade;
 1241 
 1242         dest = SLOT(ifplabel);
 1243 
 1244         if (ifp->if_type == IFT_LOOP) {
 1245                 grade = MAC_LOMAC_TYPE_EQUAL;
 1246                 goto set;
 1247         }
 1248 
 1249         if (trust_all_interfaces) {
 1250                 grade = MAC_LOMAC_TYPE_HIGH;
 1251                 goto set;
 1252         }
 1253 
 1254         grade = MAC_LOMAC_TYPE_LOW;
 1255 
 1256         if (trusted_interfaces[0] == '\0' ||
 1257             !strvalid(trusted_interfaces, sizeof(trusted_interfaces)))
 1258                 goto set;
 1259 
 1260         bzero(tiflist, sizeof(tiflist));
 1261         for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++)
 1262                 if(*p != ' ' && *p != '\t')
 1263                         *q = *p;
 1264 
 1265         for (p = q = tiflist;; p++) {
 1266                 if (*p == ',' || *p == '\0') {
 1267                         len = p - q;
 1268                         if (len < IFNAMSIZ) {
 1269                                 bzero(tifname, sizeof(tifname));
 1270                                 bcopy(q, tifname, len);
 1271                                 if (strcmp(tifname, ifp->if_xname) == 0) {
 1272                                         grade = MAC_LOMAC_TYPE_HIGH;
 1273                                         break;
 1274                                 }
 1275                         }
 1276                         else {
 1277                                 *p = '\0';
 1278                                 printf("MAC/LOMAC warning: interface name "
 1279                                     "\"%s\" is too long (must be < %d)\n",
 1280                                     q, IFNAMSIZ);
 1281                         }
 1282                         if (*p == '\0')
 1283                                 break;
 1284                         q = p + 1;
 1285                 }
 1286         }
 1287 set:
 1288         mac_lomac_set_single(dest, grade, 0);
 1289         mac_lomac_set_range(dest, grade, 0, grade, 0);
 1290 }
 1291 
 1292 static void
 1293 mac_lomac_create_ipq(struct mbuf *m, struct label *mlabel, struct ipq *ipq,
 1294     struct label *ipqlabel)
 1295 {
 1296         struct mac_lomac *source, *dest;
 1297 
 1298         source = SLOT(mlabel);
 1299         dest = SLOT(ipqlabel);
 1300 
 1301         mac_lomac_copy_single(source, dest);
 1302 }
 1303 
 1304 static void
 1305 mac_lomac_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel,
 1306     struct mbuf *m, struct label *mlabel)
 1307 {
 1308         struct mac_lomac *source, *dest;
 1309 
 1310         source = SLOT(ipqlabel);
 1311         dest = SLOT(mlabel);
 1312 
 1313         /* Just use the head, since we require them all to match. */
 1314         mac_lomac_copy_single(source, dest);
 1315 }
 1316 
 1317 static void
 1318 mac_lomac_create_fragment(struct mbuf *m, struct label *mlabel,
 1319     struct mbuf *frag, struct label *fraglabel)
 1320 {
 1321         struct mac_lomac *source, *dest;
 1322 
 1323         source = SLOT(mlabel);
 1324         dest = SLOT(fraglabel);
 1325 
 1326         mac_lomac_copy_single(source, dest);
 1327 }
 1328 
 1329 static void
 1330 mac_lomac_create_mbuf_from_inpcb(struct inpcb *inp, struct label *inplabel,
 1331     struct mbuf *m, struct label *mlabel)
 1332 {
 1333         struct mac_lomac *source, *dest;
 1334 
 1335         source = SLOT(inplabel);
 1336         dest = SLOT(mlabel);
 1337 
 1338         mac_lomac_copy_single(source, dest);
 1339 }
 1340 
 1341 static void
 1342 mac_lomac_create_mbuf_linklayer(struct ifnet *ifp, struct label *ifplabel,
 1343     struct mbuf *m, struct label *mlabel)
 1344 {
 1345         struct mac_lomac *dest;
 1346 
 1347         dest = SLOT(mlabel);
 1348 
 1349         mac_lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0);
 1350 }
 1351 
 1352 static void
 1353 mac_lomac_create_mbuf_from_bpfdesc(struct bpf_d *d, struct label *dlabel,
 1354     struct mbuf *m, struct label *mlabel)
 1355 {
 1356         struct mac_lomac *source, *dest;
 1357 
 1358         source = SLOT(dlabel);
 1359         dest = SLOT(mlabel);
 1360 
 1361         mac_lomac_copy_single(source, dest);
 1362 }
 1363 
 1364 static void
 1365 mac_lomac_create_mbuf_from_ifnet(struct ifnet *ifp, struct label *ifplabel,
 1366     struct mbuf *m, struct label *mlabel)
 1367 {
 1368         struct mac_lomac *source, *dest;
 1369 
 1370         source = SLOT(ifplabel);
 1371         dest = SLOT(mlabel);
 1372 
 1373         mac_lomac_copy_single(source, dest);
 1374 }
 1375 
 1376 static void
 1377 mac_lomac_create_mbuf_multicast_encap(struct mbuf *m, struct label *mlabel,
 1378     struct ifnet *ifp, struct label *ifplabel, struct mbuf *mnew,
 1379     struct label *mnewlabel)
 1380 {
 1381         struct mac_lomac *source, *dest;
 1382 
 1383         source = SLOT(mlabel);
 1384         dest = SLOT(mnewlabel);
 1385 
 1386         mac_lomac_copy_single(source, dest);
 1387 }
 1388 
 1389 static void
 1390 mac_lomac_create_mbuf_netlayer(struct mbuf *m, struct label *mlabel,
 1391     struct mbuf *mnew, struct label *mnewlabel)
 1392 {
 1393         struct mac_lomac *source, *dest;
 1394 
 1395         source = SLOT(mlabel);
 1396         dest = SLOT(mnewlabel);
 1397 
 1398         mac_lomac_copy_single(source, dest);
 1399 }
 1400 
 1401 static int
 1402 mac_lomac_fragment_match(struct mbuf *m, struct label *mlabel,
 1403     struct ipq *ipq, struct label *ipqlabel)
 1404 {
 1405         struct mac_lomac *a, *b;
 1406 
 1407         a = SLOT(ipqlabel);
 1408         b = SLOT(mlabel);
 1409 
 1410         return (mac_lomac_equal_single(a, b));
 1411 }
 1412 
 1413 static void
 1414 mac_lomac_relabel_ifnet(struct ucred *cred, struct ifnet *ifp,
 1415     struct label *ifplabel, struct label *newlabel)
 1416 {
 1417         struct mac_lomac *source, *dest;
 1418 
 1419         source = SLOT(newlabel);
 1420         dest = SLOT(ifplabel);
 1421 
 1422         try_relabel(source, dest);
 1423 }
 1424 
 1425 static void
 1426 mac_lomac_update_ipq(struct mbuf *m, struct label *mlabel, struct ipq *ipq,
 1427     struct label *ipqlabel)
 1428 {
 1429 
 1430         /* NOOP: we only accept matching labels, so no need to update */
 1431 }
 1432 
 1433 static void
 1434 mac_lomac_inpcb_sosetlabel(struct socket *so, struct label *solabel,
 1435     struct inpcb *inp, struct label *inplabel)
 1436 {
 1437         struct mac_lomac *source, *dest;
 1438 
 1439         source = SLOT(solabel);
 1440         dest = SLOT(inplabel);
 1441 
 1442         mac_lomac_copy_single(source, dest);
 1443 }
 1444 
 1445 static void
 1446 mac_lomac_init_syncache_from_inpcb(struct label *label, struct inpcb *inp)
 1447 {
 1448         struct mac_lomac *source, *dest;
 1449 
 1450         source = SLOT(inp->inp_label);
 1451         dest = SLOT(label);
 1452         mac_lomac_copy(source, dest);
 1453 }
 1454 
 1455 static void
 1456 mac_lomac_create_mbuf_from_syncache(struct label *sc_label, struct mbuf *m,
 1457     struct label *mlabel)
 1458 {
 1459         struct mac_lomac *source, *dest;
 1460 
 1461         source = SLOT(sc_label);
 1462         dest = SLOT(mlabel);
 1463         mac_lomac_copy(source, dest);
 1464 }
 1465 
 1466 static void
 1467 mac_lomac_create_mbuf_from_firewall(struct mbuf *m, struct label *mlabel)
 1468 {
 1469         struct mac_lomac *dest;
 1470 
 1471         dest = SLOT(mlabel);
 1472 
 1473         /* XXX: where is the label for the firewall really comming from? */
 1474         mac_lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0);
 1475 }
 1476 
 1477 /*
 1478  * Labeling event operations: processes.
 1479  */
 1480 static void
 1481 mac_lomac_execve_transition(struct ucred *old, struct ucred *new,
 1482     struct vnode *vp, struct label *vplabel, struct label *interpvnodelabel,
 1483     struct image_params *imgp, struct label *execlabel)
 1484 {
 1485         struct mac_lomac *source, *dest, *obj, *robj;
 1486 
 1487         source = SLOT(old->cr_label);
 1488         dest = SLOT(new->cr_label);
 1489         obj = SLOT(vplabel);
 1490         robj = interpvnodelabel != NULL ? SLOT(interpvnodelabel) : obj;
 1491 
 1492         mac_lomac_copy(source, dest);
 1493         /*
 1494          * If there's an auxiliary label on the real object, respect it
 1495          * and assume that this level should be assumed immediately if
 1496          * a higher level is currently in place.
 1497          */
 1498         if (robj->ml_flags & MAC_LOMAC_FLAG_AUX &&
 1499             !mac_lomac_dominate_element(&robj->ml_auxsingle, &dest->ml_single)
 1500             && mac_lomac_auxsingle_in_range(robj, dest))
 1501                 mac_lomac_set_single(dest, robj->ml_auxsingle.mle_type,
 1502                     robj->ml_auxsingle.mle_grade);
 1503         /*
 1504          * Restructuring to use the execve transitioning mechanism
 1505          * instead of the normal demotion mechanism here would be
 1506          * difficult, so just copy the label over and perform standard
 1507          * demotion.  This is also non-optimal because it will result
 1508          * in the intermediate label "new" being created and immediately
 1509          * recycled.
 1510          */
 1511         if (mac_lomac_enabled && revocation_enabled &&
 1512             !mac_lomac_dominate_single(obj, source))
 1513                 (void)maybe_demote(source, obj, "executing", "file", vp);
 1514 }
 1515 
 1516 static int
 1517 mac_lomac_execve_will_transition(struct ucred *old, struct vnode *vp,
 1518     struct label *vplabel, struct label *interpvnodelabel,
 1519     struct image_params *imgp, struct label *execlabel)
 1520 {
 1521         struct mac_lomac *subj, *obj, *robj;
 1522 
 1523         if (!mac_lomac_enabled || !revocation_enabled)
 1524                 return (0);
 1525 
 1526         subj = SLOT(old->cr_label);
 1527         obj = SLOT(vplabel);
 1528         robj = interpvnodelabel != NULL ? SLOT(interpvnodelabel) : obj;
 1529 
 1530         return ((robj->ml_flags & MAC_LOMAC_FLAG_AUX &&
 1531             !mac_lomac_dominate_element(&robj->ml_auxsingle, &subj->ml_single)
 1532             && mac_lomac_auxsingle_in_range(robj, subj)) ||
 1533             !mac_lomac_dominate_single(obj, subj));
 1534 }
 1535 
 1536 static void
 1537 mac_lomac_create_proc0(struct ucred *cred)
 1538 {
 1539         struct mac_lomac *dest;
 1540 
 1541         dest = SLOT(cred->cr_label);
 1542 
 1543         mac_lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0);
 1544         mac_lomac_set_range(dest, MAC_LOMAC_TYPE_LOW, 0, MAC_LOMAC_TYPE_HIGH,
 1545             0);
 1546 }
 1547 
 1548 static void
 1549 mac_lomac_create_proc1(struct ucred *cred)
 1550 {
 1551         struct mac_lomac *dest;
 1552 
 1553         dest = SLOT(cred->cr_label);
 1554 
 1555         mac_lomac_set_single(dest, MAC_LOMAC_TYPE_HIGH, 0);
 1556         mac_lomac_set_range(dest, MAC_LOMAC_TYPE_LOW, 0, MAC_LOMAC_TYPE_HIGH,
 1557             0);
 1558 }
 1559 
 1560 static void
 1561 mac_lomac_relabel_cred(struct ucred *cred, struct label *newlabel)
 1562 {
 1563         struct mac_lomac *source, *dest;
 1564 
 1565         source = SLOT(newlabel);
 1566         dest = SLOT(cred->cr_label);
 1567 
 1568         try_relabel(source, dest);
 1569 }
 1570 
 1571 /*
 1572  * Access control checks.
 1573  */
 1574 static int
 1575 mac_lomac_check_bpfdesc_receive(struct bpf_d *d, struct label *dlabel,
 1576     struct ifnet *ifp, struct label *ifplabel)
 1577 {
 1578         struct mac_lomac *a, *b;
 1579 
 1580         if (!mac_lomac_enabled)
 1581                 return (0);
 1582 
 1583         a = SLOT(dlabel);
 1584         b = SLOT(ifplabel);
 1585 
 1586         if (mac_lomac_equal_single(a, b))
 1587                 return (0);
 1588         return (EACCES);
 1589 }
 1590 
 1591 static int
 1592 mac_lomac_check_cred_relabel(struct ucred *cred, struct label *newlabel)
 1593 {
 1594         struct mac_lomac *subj, *new;
 1595         int error;
 1596 
 1597         subj = SLOT(cred->cr_label);
 1598         new = SLOT(newlabel);
 1599 
 1600         /*
 1601          * If there is a LOMAC label update for the credential, it may
 1602          * be an update of the single, range, or both.
 1603          */
 1604         error = lomac_atmostflags(new, MAC_LOMAC_FLAGS_BOTH);
 1605         if (error)
 1606                 return (error);
 1607 
 1608         /*
 1609          * If the LOMAC label is to be changed, authorize as appropriate.
 1610          */
 1611         if (new->ml_flags & MAC_LOMAC_FLAGS_BOTH) {
 1612                 /*
 1613                  * Fill in the missing parts from the previous label.
 1614                  */
 1615                 if ((new->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0)
 1616                         mac_lomac_copy_single(subj, new);
 1617                 if ((new->ml_flags & MAC_LOMAC_FLAG_RANGE) == 0)
 1618                         mac_lomac_copy_range(subj, new);
 1619 
 1620                 /*
 1621                  * To change the LOMAC range on a credential, the new
 1622                  * range label must be in the current range.
 1623                  */
 1624                 if (!mac_lomac_range_in_range(new, subj))
 1625                         return (EPERM);
 1626 
 1627                 /*
 1628                  * To change the LOMAC single label on a credential, the
 1629                  * new single label must be in the new range.  Implicitly
 1630                  * from the previous check, the new single is in the old
 1631                  * range.
 1632                  */
 1633                 if (!mac_lomac_single_in_range(new, new))
 1634                         return (EPERM);
 1635 
 1636                 /*
 1637                  * To have EQUAL in any component of the new credential
 1638                  * LOMAC label, the subject must already have EQUAL in
 1639                  * their label.
 1640                  */
 1641                 if (mac_lomac_contains_equal(new)) {
 1642                         error = mac_lomac_subject_privileged(subj);
 1643                         if (error)
 1644                                 return (error);
 1645                 }
 1646 
 1647                 /*
 1648                  * XXXMAC: Additional consistency tests regarding the
 1649                  * single and range of the new label might be performed
 1650                  * here.
 1651                  */
 1652         }
 1653 
 1654         return (0);
 1655 }
 1656 
 1657 static int
 1658 mac_lomac_check_cred_visible(struct ucred *cr1, struct ucred *cr2)
 1659 {
 1660         struct mac_lomac *subj, *obj;
 1661 
 1662         if (!mac_lomac_enabled)
 1663                 return (0);
 1664 
 1665         subj = SLOT(cr1->cr_label);
 1666         obj = SLOT(cr2->cr_label);
 1667 
 1668         /* XXX: range */
 1669         if (!mac_lomac_dominate_single(obj, subj))
 1670                 return (ESRCH);
 1671 
 1672         return (0);
 1673 }
 1674 
 1675 static int
 1676 mac_lomac_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifp,
 1677     struct label *ifplabel, struct label *newlabel)
 1678 {
 1679         struct mac_lomac *subj, *new;
 1680         int error;
 1681 
 1682         subj = SLOT(cred->cr_label);
 1683         new = SLOT(newlabel);
 1684 
 1685         /*
 1686          * If there is a LOMAC label update for the interface, it may
 1687          * be an update of the single, range, or both.
 1688          */
 1689         error = lomac_atmostflags(new, MAC_LOMAC_FLAGS_BOTH);
 1690         if (error)
 1691                 return (error);
 1692 
 1693         /*
 1694          * Relabling network interfaces requires LOMAC privilege.
 1695          */
 1696         error = mac_lomac_subject_privileged(subj);
 1697         if (error)
 1698                 return (error);
 1699 
 1700         /*
 1701          * If the LOMAC label is to be changed, authorize as appropriate.
 1702          */
 1703         if (new->ml_flags & MAC_LOMAC_FLAGS_BOTH) {
 1704                 /*
 1705                  * Fill in the missing parts from the previous label.
 1706                  */
 1707                 if ((new->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0)
 1708                         mac_lomac_copy_single(subj, new);
 1709                 if ((new->ml_flags & MAC_LOMAC_FLAG_RANGE) == 0)
 1710                         mac_lomac_copy_range(subj, new);
 1711 
 1712                 /*
 1713                  * Rely on the traditional superuser status for the LOMAC
 1714                  * interface relabel requirements.  XXXMAC: This will go
 1715                  * away.
 1716                  *
 1717                  * XXXRW: This is also redundant to a higher layer check.
 1718                  */
 1719                 error = priv_check_cred(cred, PRIV_NET_SETIFMAC, 0);
 1720                 if (error)
 1721                         return (EPERM);
 1722 
 1723                 /*
 1724                  * XXXMAC: Additional consistency tests regarding the single
 1725                  * and the range of the new label might be performed here.
 1726                  */
 1727         }
 1728 
 1729         return (0);
 1730 }
 1731 
 1732 static int
 1733 mac_lomac_check_ifnet_transmit(struct ifnet *ifp, struct label *ifplabel,
 1734     struct mbuf *m, struct label *mlabel)
 1735 {
 1736         struct mac_lomac *p, *i;
 1737 
 1738         if (!mac_lomac_enabled)
 1739                 return (0);
 1740 
 1741         p = SLOT(mlabel);
 1742         i = SLOT(ifplabel);
 1743 
 1744         return (mac_lomac_single_in_range(p, i) ? 0 : EACCES);
 1745 }
 1746 
 1747 static int
 1748 mac_lomac_check_inpcb_deliver(struct inpcb *inp, struct label *inplabel,
 1749     struct mbuf *m, struct label *mlabel)
 1750 {
 1751         struct mac_lomac *p, *i;
 1752 
 1753         if (!mac_lomac_enabled)
 1754                 return (0);
 1755 
 1756         p = SLOT(mlabel);
 1757         i = SLOT(inplabel);
 1758 
 1759         return (mac_lomac_equal_single(p, i) ? 0 : EACCES);
 1760 }
 1761 
 1762 static int
 1763 mac_lomac_check_kld_load(struct ucred *cred, struct vnode *vp,
 1764     struct label *vplabel)
 1765 {
 1766         struct mac_lomac *subj, *obj;
 1767 
 1768         if (!mac_lomac_enabled)
 1769                 return (0);
 1770 
 1771         subj = SLOT(cred->cr_label);
 1772         obj = SLOT(vplabel);
 1773 
 1774         if (mac_lomac_subject_privileged(subj))
 1775                 return (EPERM);
 1776 
 1777         if (!mac_lomac_high_single(obj))
 1778                 return (EACCES);
 1779 
 1780         return (0);
 1781 }
 1782 
 1783 static int
 1784 mac_lomac_check_pipe_ioctl(struct ucred *cred, struct pipepair *pp,
 1785     struct label *pplabel, unsigned long cmd, void /* caddr_t */ *data)
 1786 {
 1787 
 1788         if (!mac_lomac_enabled)
 1789                 return (0);
 1790 
 1791         /* XXX: This will be implemented soon... */
 1792 
 1793         return (0);
 1794 }
 1795 
 1796 static int
 1797 mac_lomac_check_pipe_read(struct ucred *cred, struct pipepair *pp,
 1798     struct label *pplabel)
 1799 {
 1800         struct mac_lomac *subj, *obj;
 1801 
 1802         if (!mac_lomac_enabled)
 1803                 return (0);
 1804 
 1805         subj = SLOT(cred->cr_label);
 1806         obj = SLOT(pplabel);
 1807 
 1808         if (!mac_lomac_dominate_single(obj, subj))
 1809                 return (maybe_demote(subj, obj, "reading", "pipe", NULL));
 1810 
 1811         return (0);
 1812 }
 1813 
 1814 static int
 1815 mac_lomac_check_pipe_relabel(struct ucred *cred, struct pipepair *pp,
 1816     struct label *pplabel, struct label *newlabel)
 1817 {
 1818         struct mac_lomac *subj, *obj, *new;
 1819         int error;
 1820 
 1821         new = SLOT(newlabel);
 1822         subj = SLOT(cred->cr_label);
 1823         obj = SLOT(pplabel);
 1824 
 1825         /*
 1826          * If there is a LOMAC label update for a pipe, it must be a
 1827          * single update.
 1828          */
 1829         error = lomac_atmostflags(new, MAC_LOMAC_FLAG_SINGLE);
 1830         if (error)
 1831                 return (error);
 1832 
 1833         /*
 1834          * To perform a relabel of a pipe (LOMAC label or not), LOMAC must
 1835          * authorize the relabel.
 1836          */
 1837         if (!mac_lomac_single_in_range(obj, subj))
 1838                 return (EPERM);
 1839 
 1840         /*
 1841          * If the LOMAC label is to be changed, authorize as appropriate.
 1842          */
 1843         if (new->ml_flags & MAC_LOMAC_FLAG_SINGLE) {
 1844                 /*
 1845                  * To change the LOMAC label on a pipe, the new pipe label
 1846                  * must be in the subject range.
 1847                  */
 1848                 if (!mac_lomac_single_in_range(new, subj))
 1849                         return (EPERM);
 1850 
 1851                 /*
 1852                  * To change the LOMAC label on a pipe to be EQUAL, the
 1853                  * subject must have appropriate privilege.
 1854                  */
 1855                 if (mac_lomac_contains_equal(new)) {
 1856                         error = mac_lomac_subject_privileged(subj);
 1857                         if (error)
 1858                                 return (error);
 1859                 }
 1860         }
 1861 
 1862         return (0);
 1863 }
 1864 
 1865 static int
 1866 mac_lomac_check_pipe_write(struct ucred *cred, struct pipepair *pp,
 1867     struct label *pplabel)
 1868 {
 1869         struct mac_lomac *subj, *obj;
 1870 
 1871         if (!mac_lomac_enabled)
 1872                 return (0);
 1873 
 1874         subj = SLOT(cred->cr_label);
 1875         obj = SLOT(pplabel);
 1876 
 1877         if (!mac_lomac_subject_dominate(subj, obj))
 1878                 return (EACCES);
 1879 
 1880         return (0);
 1881 }
 1882 
 1883 static int
 1884 mac_lomac_check_proc_debug(struct ucred *cred, struct proc *p)
 1885 {
 1886         struct mac_lomac *subj, *obj;
 1887 
 1888         if (!mac_lomac_enabled)
 1889                 return (0);
 1890 
 1891         subj = SLOT(cred->cr_label);
 1892         obj = SLOT(p->p_ucred->cr_label);
 1893 
 1894         /* XXX: range checks */
 1895         if (!mac_lomac_dominate_single(obj, subj))
 1896                 return (ESRCH);
 1897         if (!mac_lomac_subject_dominate(subj, obj))
 1898                 return (EACCES);
 1899 
 1900         return (0);
 1901 }
 1902 
 1903 static int
 1904 mac_lomac_check_proc_sched(struct ucred *cred, struct proc *p)
 1905 {
 1906         struct mac_lomac *subj, *obj;
 1907 
 1908         if (!mac_lomac_enabled)
 1909                 return (0);
 1910 
 1911         subj = SLOT(cred->cr_label);
 1912         obj = SLOT(p->p_ucred->cr_label);
 1913 
 1914         /* XXX: range checks */
 1915         if (!mac_lomac_dominate_single(obj, subj))
 1916                 return (ESRCH);
 1917         if (!mac_lomac_subject_dominate(subj, obj))
 1918                 return (EACCES);
 1919 
 1920         return (0);
 1921 }
 1922 
 1923 static int
 1924 mac_lomac_check_proc_signal(struct ucred *cred, struct proc *p, int signum)
 1925 {
 1926         struct mac_lomac *subj, *obj;
 1927 
 1928         if (!mac_lomac_enabled)
 1929                 return (0);
 1930 
 1931         subj = SLOT(cred->cr_label);
 1932         obj = SLOT(p->p_ucred->cr_label);
 1933 
 1934         /* XXX: range checks */
 1935         if (!mac_lomac_dominate_single(obj, subj))
 1936                 return (ESRCH);
 1937         if (!mac_lomac_subject_dominate(subj, obj))
 1938                 return (EACCES);
 1939 
 1940         return (0);
 1941 }
 1942 
 1943 static int
 1944 mac_lomac_check_socket_deliver(struct socket *so, struct label *solabel,
 1945     struct mbuf *m, struct label *mlabel)
 1946 {
 1947         struct mac_lomac *p, *s;
 1948 
 1949         if (!mac_lomac_enabled)
 1950                 return (0);
 1951 
 1952         p = SLOT(mlabel);
 1953         s = SLOT(solabel);
 1954 
 1955         return (mac_lomac_equal_single(p, s) ? 0 : EACCES);
 1956 }
 1957 
 1958 static int
 1959 mac_lomac_check_socket_relabel(struct ucred *cred, struct socket *so,
 1960     struct label *solabel, struct label *newlabel)
 1961 {
 1962         struct mac_lomac *subj, *obj, *new;
 1963         int error;
 1964 
 1965         new = SLOT(newlabel);
 1966         subj = SLOT(cred->cr_label);
 1967         obj = SLOT(solabel);
 1968 
 1969         /*
 1970          * If there is a LOMAC label update for the socket, it may be
 1971          * an update of single.
 1972          */
 1973         error = lomac_atmostflags(new, MAC_LOMAC_FLAG_SINGLE);
 1974         if (error)
 1975                 return (error);
 1976 
 1977         /*
 1978          * To relabel a socket, the old socket single must be in the subject
 1979          * range.
 1980          */
 1981         if (!mac_lomac_single_in_range(obj, subj))
 1982                 return (EPERM);
 1983 
 1984         /*
 1985          * If the LOMAC label is to be changed, authorize as appropriate.
 1986          */
 1987         if (new->ml_flags & MAC_LOMAC_FLAG_SINGLE) {
 1988                 /*
 1989                  * To relabel a socket, the new socket single must be in
 1990                  * the subject range.
 1991                  */
 1992                 if (!mac_lomac_single_in_range(new, subj))
 1993                         return (EPERM);
 1994 
 1995                 /*
 1996                  * To change the LOMAC label on the socket to contain EQUAL,
 1997                  * the subject must have appropriate privilege.
 1998                  */
 1999                 if (mac_lomac_contains_equal(new)) {
 2000                         error = mac_lomac_subject_privileged(subj);
 2001                         if (error)
 2002                                 return (error);
 2003                 }
 2004         }
 2005 
 2006         return (0);
 2007 }
 2008 
 2009 static int
 2010 mac_lomac_check_socket_visible(struct ucred *cred, struct socket *so,
 2011     struct label *solabel)
 2012 {
 2013         struct mac_lomac *subj, *obj;
 2014 
 2015         if (!mac_lomac_enabled)
 2016                 return (0);
 2017 
 2018         subj = SLOT(cred->cr_label);
 2019         obj = SLOT(solabel);
 2020 
 2021         if (!mac_lomac_dominate_single(obj, subj))
 2022                 return (ENOENT);
 2023 
 2024         return (0);
 2025 }
 2026 
 2027 /*
 2028  * Some system privileges are allowed regardless of integrity grade; others
 2029  * are allowed only when running with privilege with respect to the LOMAC 
 2030  * policy as they might otherwise allow bypassing of the integrity policy.
 2031  */
 2032 static int
 2033 mac_lomac_priv_check(struct ucred *cred, int priv)
 2034 {
 2035         struct mac_lomac *subj;
 2036         int error;
 2037 
 2038         if (!mac_lomac_enabled)
 2039                 return (0);
 2040 
 2041         /*
 2042          * Exempt only specific privileges from the LOMAC integrity policy.
 2043          */
 2044         switch (priv) {
 2045         case PRIV_KTRACE:
 2046         case PRIV_MSGBUF:
 2047 
 2048         /*
 2049          * Allow processes to manipulate basic process audit properties, and
 2050          * to submit audit records.
 2051          */
 2052         case PRIV_AUDIT_GETAUDIT:
 2053         case PRIV_AUDIT_SETAUDIT:
 2054         case PRIV_AUDIT_SUBMIT:
 2055 
 2056         /*
 2057          * Allow processes to manipulate their regular UNIX credentials.
 2058          */
 2059         case PRIV_CRED_SETUID:
 2060         case PRIV_CRED_SETEUID:
 2061         case PRIV_CRED_SETGID:
 2062         case PRIV_CRED_SETEGID:
 2063         case PRIV_CRED_SETGROUPS:
 2064         case PRIV_CRED_SETREUID:
 2065         case PRIV_CRED_SETREGID:
 2066         case PRIV_CRED_SETRESUID:
 2067         case PRIV_CRED_SETRESGID:
 2068 
 2069         /*
 2070          * Allow processes to perform system monitoring.
 2071          */
 2072         case PRIV_SEEOTHERGIDS:
 2073         case PRIV_SEEOTHERUIDS:
 2074                 break;
 2075 
 2076         /*
 2077          * Allow access to general process debugging facilities.  We
 2078          * separately control debugging based on MAC label.
 2079          */
 2080         case PRIV_DEBUG_DIFFCRED:
 2081         case PRIV_DEBUG_SUGID:
 2082         case PRIV_DEBUG_UNPRIV:
 2083 
 2084         /*
 2085          * Allow manipulating jails.
 2086          */
 2087         case PRIV_JAIL_ATTACH:
 2088 
 2089         /*
 2090          * Allow privilege with respect to the Partition policy, but not the
 2091          * Privs policy.
 2092          */
 2093         case PRIV_MAC_PARTITION:
 2094 
 2095         /*
 2096          * Allow privilege with respect to process resource limits and login
 2097          * context.
 2098          */
 2099         case PRIV_PROC_LIMIT:
 2100         case PRIV_PROC_SETLOGIN:
 2101         case PRIV_PROC_SETRLIMIT:
 2102 
 2103         /*
 2104          * Allow System V and POSIX IPC privileges.
 2105          */
 2106         case PRIV_IPC_READ:
 2107         case PRIV_IPC_WRITE:
 2108         case PRIV_IPC_ADMIN:
 2109         case PRIV_IPC_MSGSIZE:
 2110         case PRIV_MQ_ADMIN:
 2111 
 2112         /*
 2113          * Allow certain scheduler manipulations -- possibly this should be
 2114          * controlled by more fine-grained policy, as potentially low
 2115          * integrity processes can deny CPU to higher integrity ones.
 2116          */
 2117         case PRIV_SCHED_DIFFCRED:
 2118         case PRIV_SCHED_SETPRIORITY:
 2119         case PRIV_SCHED_RTPRIO:
 2120         case PRIV_SCHED_SETPOLICY:
 2121         case PRIV_SCHED_SET:
 2122         case PRIV_SCHED_SETPARAM:
 2123 
 2124         /*
 2125          * More IPC privileges.
 2126          */
 2127         case PRIV_SEM_WRITE:
 2128 
 2129         /*
 2130          * Allow signaling privileges subject to integrity policy.
 2131          */
 2132         case PRIV_SIGNAL_DIFFCRED:
 2133         case PRIV_SIGNAL_SUGID:
 2134 
 2135         /*
 2136          * Allow access to only limited sysctls from lower integrity levels;
 2137          * piggy-back on the Jail definition.
 2138          */
 2139         case PRIV_SYSCTL_WRITEJAIL:
 2140 
 2141         /*
 2142          * Allow TTY-based privileges, subject to general device access using
 2143          * labels on TTY device nodes, but not console privilege.
 2144          */
 2145         case PRIV_TTY_DRAINWAIT:
 2146         case PRIV_TTY_DTRWAIT:
 2147         case PRIV_TTY_EXCLUSIVE:
 2148         case PRIV_TTY_PRISON:
 2149         case PRIV_TTY_STI:
 2150         case PRIV_TTY_SETA:
 2151 
 2152         /*
 2153          * Grant most VFS privileges, as almost all are in practice bounded
 2154          * by more specific checks using labels.
 2155          */
 2156         case PRIV_VFS_READ:
 2157         case PRIV_VFS_WRITE:
 2158         case PRIV_VFS_ADMIN:
 2159         case PRIV_VFS_EXEC:
 2160         case PRIV_VFS_LOOKUP:
 2161         case PRIV_VFS_CHFLAGS_DEV:
 2162         case PRIV_VFS_CHOWN:
 2163         case PRIV_VFS_CHROOT:
 2164         case PRIV_VFS_RETAINSUGID:
 2165         case PRIV_VFS_EXCEEDQUOTA:
 2166         case PRIV_VFS_FCHROOT:
 2167         case PRIV_VFS_FHOPEN:
 2168         case PRIV_VFS_FHSTATFS:
 2169         case PRIV_VFS_GENERATION:
 2170         case PRIV_VFS_GETFH:
 2171         case PRIV_VFS_GETQUOTA:
 2172         case PRIV_VFS_LINK:
 2173         case PRIV_VFS_MOUNT:
 2174         case PRIV_VFS_MOUNT_OWNER:
 2175         case PRIV_VFS_MOUNT_PERM:
 2176         case PRIV_VFS_MOUNT_SUIDDIR:
 2177         case PRIV_VFS_MOUNT_NONUSER:
 2178         case PRIV_VFS_SETGID:
 2179         case PRIV_VFS_STICKYFILE:
 2180         case PRIV_VFS_SYSFLAGS:
 2181         case PRIV_VFS_UNMOUNT:
 2182 
 2183         /*
 2184          * Allow VM privileges; it would be nice if these were subject to
 2185          * resource limits.
 2186          */
 2187         case PRIV_VM_MADV_PROTECT:
 2188         case PRIV_VM_MLOCK:
 2189         case PRIV_VM_MUNLOCK:
 2190 
 2191         /*
 2192          * Allow some but not all network privileges.  In general, dont allow
 2193          * reconfiguring the network stack, just normal use.
 2194          */
 2195         case PRIV_NETATALK_RESERVEDPORT:
 2196         case PRIV_NETINET_RESERVEDPORT:
 2197         case PRIV_NETINET_RAW:
 2198         case PRIV_NETINET_REUSEPORT:
 2199         case PRIV_NETIPX_RESERVEDPORT:
 2200         case PRIV_NETIPX_RAW:
 2201                 break;
 2202 
 2203         /*
 2204          * All remaining system privileges are allow only if the process
 2205          * holds privilege with respect to the LOMAC policy.
 2206          */
 2207         default:
 2208                 subj = SLOT(cred->cr_label);
 2209                 error = mac_lomac_subject_privileged(subj);
 2210                 if (error)
 2211                         return (error);
 2212         }
 2213         return (0);
 2214 }
 2215 
 2216 
 2217 static int
 2218 mac_lomac_check_system_acct(struct ucred *cred, struct vnode *vp,
 2219     struct label *vplabel)
 2220 {
 2221         struct mac_lomac *subj, *obj;
 2222 
 2223         if (!mac_lomac_enabled)
 2224                 return (0);
 2225 
 2226         subj = SLOT(cred->cr_label);
 2227         obj = SLOT(vplabel);
 2228 
 2229         if (mac_lomac_subject_privileged(subj))
 2230                 return (EPERM);
 2231 
 2232         if (!mac_lomac_high_single(obj))
 2233                 return (EACCES);
 2234 
 2235         return (0);
 2236 }
 2237 
 2238 static int
 2239 mac_lomac_check_system_auditctl(struct ucred *cred, struct vnode *vp,
 2240     struct label *vplabel)
 2241 {
 2242         struct mac_lomac *subj, *obj;
 2243 
 2244         if (!mac_lomac_enabled)
 2245                 return (0);
 2246 
 2247         subj = SLOT(cred->cr_label);
 2248         obj = SLOT(vplabel);
 2249 
 2250         if (mac_lomac_subject_privileged(subj))
 2251                 return (EPERM);
 2252 
 2253         if (!mac_lomac_high_single(obj))
 2254                 return (EACCES);
 2255 
 2256         return (0);
 2257 }
 2258 
 2259 static int
 2260 mac_lomac_check_system_swapoff(struct ucred *cred, struct vnode *vp,
 2261     struct label *vplabel)
 2262 {
 2263         struct mac_lomac *subj;
 2264 
 2265         if (!mac_lomac_enabled)
 2266                 return (0);
 2267 
 2268         subj = SLOT(cred->cr_label);
 2269 
 2270         if (mac_lomac_subject_privileged(subj))
 2271                 return (EPERM);
 2272 
 2273         return (0);
 2274 }
 2275 
 2276 static int
 2277 mac_lomac_check_system_swapon(struct ucred *cred, struct vnode *vp,
 2278     struct label *vplabel)
 2279 {
 2280         struct mac_lomac *subj, *obj;
 2281 
 2282         if (!mac_lomac_enabled)
 2283                 return (0);
 2284 
 2285         subj = SLOT(cred->cr_label);
 2286         obj = SLOT(vplabel);
 2287 
 2288         if (mac_lomac_subject_privileged(subj))
 2289                 return (EPERM);
 2290 
 2291         if (!mac_lomac_high_single(obj))
 2292                 return (EACCES);
 2293 
 2294         return (0);
 2295 }
 2296 
 2297 static int
 2298 mac_lomac_check_system_sysctl(struct ucred *cred, struct sysctl_oid *oidp,
 2299     void *arg1, int arg2, struct sysctl_req *req)
 2300 {
 2301         struct mac_lomac *subj;
 2302 
 2303         if (!mac_lomac_enabled)
 2304                 return (0);
 2305 
 2306         subj = SLOT(cred->cr_label);
 2307 
 2308         /*
 2309          * Treat sysctl variables without CTLFLAG_ANYBODY flag as
 2310          * lomac/high, but also require privilege to change them.
 2311          */
 2312         if (req->newptr != NULL && (oidp->oid_kind & CTLFLAG_ANYBODY) == 0) {
 2313 #ifdef notdef
 2314                 if (!mac_lomac_subject_dominate_high(subj))
 2315                         return (EACCES);
 2316 #endif
 2317 
 2318                 if (mac_lomac_subject_privileged(subj))
 2319                         return (EPERM);
 2320         }
 2321 
 2322         return (0);
 2323 }
 2324 
 2325 static int
 2326 mac_lomac_check_vnode_create(struct ucred *cred, struct vnode *dvp,
 2327     struct label *dvplabel, struct componentname *cnp, struct vattr *vap)
 2328 {
 2329         struct mac_lomac *subj, *obj;
 2330 
 2331         if (!mac_lomac_enabled)
 2332                 return (0);
 2333 
 2334         subj = SLOT(cred->cr_label);
 2335         obj = SLOT(dvplabel);
 2336 
 2337         if (!mac_lomac_subject_dominate(subj, obj))
 2338                 return (EACCES);
 2339         if (obj->ml_flags & MAC_LOMAC_FLAG_AUX &&
 2340             !mac_lomac_dominate_element(&subj->ml_single, &obj->ml_auxsingle))
 2341                 return (EACCES);
 2342 
 2343         return (0);
 2344 }
 2345 
 2346 static int
 2347 mac_lomac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
 2348     struct label *vplabel, acl_type_t type)
 2349 {
 2350         struct mac_lomac *subj, *obj;
 2351 
 2352         if (!mac_lomac_enabled)
 2353                 return (0);
 2354 
 2355         subj = SLOT(cred->cr_label);
 2356         obj = SLOT(vplabel);
 2357 
 2358         if (!mac_lomac_subject_dominate(subj, obj))
 2359                 return (EACCES);
 2360 
 2361         return (0);
 2362 }
 2363 
 2364 static int
 2365 mac_lomac_check_vnode_link(struct ucred *cred, struct vnode *dvp,
 2366     struct label *dvplabel, struct vnode *vp, struct label *vplabel,
 2367     struct componentname *cnp)
 2368 {
 2369         struct mac_lomac *subj, *obj;
 2370 
 2371         if (!mac_lomac_enabled)
 2372                 return (0);
 2373 
 2374         subj = SLOT(cred->cr_label);
 2375         obj = SLOT(dvplabel);
 2376 
 2377         if (!mac_lomac_subject_dominate(subj, obj))
 2378                 return (EACCES);
 2379 
 2380         obj = SLOT(vplabel);
 2381 
 2382         if (!mac_lomac_subject_dominate(subj, obj))
 2383                 return (EACCES);
 2384 
 2385         return (0);
 2386 }
 2387 
 2388 static int
 2389 mac_lomac_check_vnode_mmap(struct ucred *cred, struct vnode *vp,
 2390     struct label *vplabel, int prot, int flags)
 2391 {
 2392         struct mac_lomac *subj, *obj;
 2393 
 2394         /*
 2395          * Rely on the use of open()-time protections to handle
 2396          * non-revocation cases.
 2397          */
 2398         if (!mac_lomac_enabled)
 2399                 return (0);
 2400 
 2401         subj = SLOT(cred->cr_label);
 2402         obj = SLOT(vplabel);
 2403 
 2404         if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) {
 2405                 if (!mac_lomac_subject_dominate(subj, obj))
 2406                         return (EACCES);
 2407         }
 2408         if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
 2409                 if (!mac_lomac_dominate_single(obj, subj))
 2410                         return (maybe_demote(subj, obj, "mapping", "file", vp));
 2411         }
 2412 
 2413         return (0);
 2414 }
 2415 
 2416 static void
 2417 mac_lomac_check_vnode_mmap_downgrade(struct ucred *cred, struct vnode *vp,
 2418     struct label *vplabel, /* XXX vm_prot_t */ int *prot)
 2419 {
 2420         struct mac_lomac *subj, *obj;
 2421 
 2422         /*
 2423          * Rely on the use of open()-time protections to handle
 2424          * non-revocation cases.
 2425          */
 2426         if (!mac_lomac_enabled || !revocation_enabled)
 2427                 return;
 2428 
 2429         subj = SLOT(cred->cr_label);
 2430         obj = SLOT(vplabel);
 2431 
 2432         if (!mac_lomac_subject_dominate(subj, obj))
 2433                 *prot &= ~VM_PROT_WRITE;
 2434 }
 2435 
 2436 static int
 2437 mac_lomac_check_vnode_open(struct ucred *cred, struct vnode *vp,
 2438     struct label *vplabel, int acc_mode)
 2439 {
 2440         struct mac_lomac *subj, *obj;
 2441 
 2442         if (!mac_lomac_enabled)
 2443                 return (0);
 2444 
 2445         subj = SLOT(cred->cr_label);
 2446         obj = SLOT(vplabel);
 2447 
 2448         /* XXX privilege override for admin? */
 2449         if (acc_mode & (VWRITE | VAPPEND | VADMIN)) {
 2450                 if (!mac_lomac_subject_dominate(subj, obj))
 2451                         return (EACCES);
 2452         }
 2453 
 2454         return (0);
 2455 }
 2456 
 2457 static int
 2458 mac_lomac_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
 2459     struct vnode *vp, struct label *vplabel)
 2460 {
 2461         struct mac_lomac *subj, *obj;
 2462 
 2463         if (!mac_lomac_enabled || !revocation_enabled)
 2464                 return (0);
 2465 
 2466         subj = SLOT(active_cred->cr_label);
 2467         obj = SLOT(vplabel);
 2468 
 2469         if (!mac_lomac_dominate_single(obj, subj))
 2470                 return (maybe_demote(subj, obj, "reading", "file", vp));
 2471 
 2472         return (0);
 2473 }
 2474 
 2475 static int
 2476 mac_lomac_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
 2477     struct label *vplabel, struct label *newlabel)
 2478 {
 2479         struct mac_lomac *old, *new, *subj;
 2480         int error;
 2481 
 2482         old = SLOT(vplabel);
 2483         new = SLOT(newlabel);
 2484         subj = SLOT(cred->cr_label);
 2485 
 2486         /*
 2487          * If there is a LOMAC label update for the vnode, it must be a
 2488          * single label, with an optional explicit auxiliary single.
 2489          */
 2490         error = lomac_atmostflags(new,
 2491             MAC_LOMAC_FLAG_SINGLE | MAC_LOMAC_FLAG_AUX);
 2492         if (error)
 2493                 return (error);
 2494 
 2495         /*
 2496          * To perform a relabel of the vnode (LOMAC label or not), LOMAC must
 2497          * authorize the relabel.
 2498          */
 2499         if (!mac_lomac_single_in_range(old, subj))
 2500                 return (EPERM);
 2501 
 2502         /*
 2503          * If the LOMAC label is to be changed, authorize as appropriate.
 2504          */
 2505         if (new->ml_flags & MAC_LOMAC_FLAG_SINGLE) {
 2506                 /*
 2507                  * To change the LOMAC label on a vnode, the new vnode label
 2508                  * must be in the subject range.
 2509                  */
 2510                 if (!mac_lomac_single_in_range(new, subj))
 2511                         return (EPERM);
 2512 
 2513                 /*
 2514                  * To change the LOMAC label on the vnode to be EQUAL,
 2515                  * the subject must have appropriate privilege.
 2516                  */
 2517                 if (mac_lomac_contains_equal(new)) {
 2518                         error = mac_lomac_subject_privileged(subj);
 2519                         if (error)
 2520                                 return (error);
 2521                 }
 2522         }
 2523         if (new->ml_flags & MAC_LOMAC_FLAG_AUX) {
 2524                 /*
 2525                  * Fill in the missing parts from the previous label.
 2526                  */
 2527                 if ((new->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0)
 2528                         mac_lomac_copy_single(subj, new);
 2529 
 2530                 /*
 2531                  * To change the auxiliary LOMAC label on a vnode, the new
 2532                  * vnode label must be in the subject range.
 2533                  */
 2534                 if (!mac_lomac_auxsingle_in_range(new, subj))
 2535                         return (EPERM);
 2536 
 2537                 /*
 2538                  * To change the auxiliary LOMAC label on the vnode to be
 2539                  * EQUAL, the subject must have appropriate privilege.
 2540                  */
 2541                 if (mac_lomac_contains_equal(new)) {
 2542                         error = mac_lomac_subject_privileged(subj);
 2543                         if (error)
 2544                                 return (error);
 2545                 }
 2546         }
 2547 
 2548         return (0);
 2549 }
 2550 
 2551 static int
 2552 mac_lomac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
 2553     struct label *dvplabel, struct vnode *vp, struct label *vplabel,
 2554     struct componentname *cnp)
 2555 {
 2556         struct mac_lomac *subj, *obj;
 2557 
 2558         if (!mac_lomac_enabled)
 2559                 return (0);
 2560 
 2561         subj = SLOT(cred->cr_label);
 2562         obj = SLOT(dvplabel);
 2563 
 2564         if (!mac_lomac_subject_dominate(subj, obj))
 2565                 return (EACCES);
 2566 
 2567         obj = SLOT(vplabel);
 2568 
 2569         if (!mac_lomac_subject_dominate(subj, obj))
 2570                 return (EACCES);
 2571 
 2572         return (0);
 2573 }
 2574 
 2575 static int
 2576 mac_lomac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
 2577     struct label *dvplabel, struct vnode *vp, struct label *vplabel,
 2578     int samedir, struct componentname *cnp)
 2579 {
 2580         struct mac_lomac *subj, *obj;
 2581 
 2582         if (!mac_lomac_enabled)
 2583                 return (0);
 2584 
 2585         subj = SLOT(cred->cr_label);
 2586         obj = SLOT(dvplabel);
 2587 
 2588         if (!mac_lomac_subject_dominate(subj, obj))
 2589                 return (EACCES);
 2590 
 2591         if (vp != NULL) {
 2592                 obj = SLOT(vplabel);
 2593 
 2594                 if (!mac_lomac_subject_dominate(subj, obj))
 2595                         return (EACCES);
 2596         }
 2597 
 2598         return (0);
 2599 }
 2600 
 2601 static int
 2602 mac_lomac_check_vnode_revoke(struct ucred *cred, struct vnode *vp,
 2603     struct label *vplabel)
 2604 {
 2605         struct mac_lomac *subj, *obj;
 2606 
 2607         if (!mac_lomac_enabled)
 2608                 return (0);
 2609 
 2610         subj = SLOT(cred->cr_label);
 2611         obj = SLOT(vplabel);
 2612 
 2613         if (!mac_lomac_subject_dominate(subj, obj))
 2614                 return (EACCES);
 2615 
 2616         return (0);
 2617 }
 2618 
 2619 static int
 2620 mac_lomac_check_vnode_setacl(struct ucred *cred, struct vnode *vp,
 2621     struct label *vplabel, acl_type_t type, struct acl *acl)
 2622 {
 2623         struct mac_lomac *subj, *obj;
 2624 
 2625         if (!mac_lomac_enabled)
 2626                 return (0);
 2627 
 2628         subj = SLOT(cred->cr_label);
 2629         obj = SLOT(vplabel);
 2630 
 2631         if (!mac_lomac_subject_dominate(subj, obj))
 2632                 return (EACCES);
 2633 
 2634         return (0);
 2635 }
 2636 
 2637 static int
 2638 mac_lomac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
 2639     struct label *vplabel, int attrnamespace, const char *name,
 2640     struct uio *uio)
 2641 {
 2642         struct mac_lomac *subj, *obj;
 2643 
 2644         if (!mac_lomac_enabled)
 2645                 return (0);
 2646 
 2647         subj = SLOT(cred->cr_label);
 2648         obj = SLOT(vplabel);
 2649 
 2650         if (!mac_lomac_subject_dominate(subj, obj))
 2651                 return (EACCES);
 2652 
 2653         /* XXX: protect the MAC EA in a special way? */
 2654 
 2655         return (0);
 2656 }
 2657 
 2658 static int
 2659 mac_lomac_check_vnode_setflags(struct ucred *cred, struct vnode *vp,
 2660     struct label *vplabel, u_long flags)
 2661 {
 2662         struct mac_lomac *subj, *obj;
 2663 
 2664         if (!mac_lomac_enabled)
 2665                 return (0);
 2666 
 2667         subj = SLOT(cred->cr_label);
 2668         obj = SLOT(vplabel);
 2669 
 2670         if (!mac_lomac_subject_dominate(subj, obj))
 2671                 return (EACCES);
 2672 
 2673         return (0);
 2674 }
 2675 
 2676 static int
 2677 mac_lomac_check_vnode_setmode(struct ucred *cred, struct vnode *vp,
 2678     struct label *vplabel, mode_t mode)
 2679 {
 2680         struct mac_lomac *subj, *obj;
 2681 
 2682         if (!mac_lomac_enabled)
 2683                 return (0);
 2684 
 2685         subj = SLOT(cred->cr_label);
 2686         obj = SLOT(vplabel);
 2687 
 2688         if (!mac_lomac_subject_dominate(subj, obj))
 2689                 return (EACCES);
 2690 
 2691         return (0);
 2692 }
 2693 
 2694 static int
 2695 mac_lomac_check_vnode_setowner(struct ucred *cred, struct vnode *vp,
 2696     struct label *vplabel, uid_t uid, gid_t gid)
 2697 {
 2698         struct mac_lomac *subj, *obj;
 2699 
 2700         if (!mac_lomac_enabled)
 2701                 return (0);
 2702 
 2703         subj = SLOT(cred->cr_label);
 2704         obj = SLOT(vplabel);
 2705 
 2706         if (!mac_lomac_subject_dominate(subj, obj))
 2707                 return (EACCES);
 2708 
 2709         return (0);
 2710 }
 2711 
 2712 static int
 2713 mac_lomac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
 2714     struct label *vplabel, struct timespec atime, struct timespec mtime)
 2715 {
 2716         struct mac_lomac *subj, *obj;
 2717 
 2718         if (!mac_lomac_enabled)
 2719                 return (0);
 2720 
 2721         subj = SLOT(cred->cr_label);
 2722         obj = SLOT(vplabel);
 2723 
 2724         if (!mac_lomac_subject_dominate(subj, obj))
 2725                 return (EACCES);
 2726 
 2727         return (0);
 2728 }
 2729 
 2730 static int
 2731 mac_lomac_check_vnode_unlink(struct ucred *cred, struct vnode *dvp,
 2732     struct label *dvplabel, struct vnode *vp, struct label *vplabel,
 2733     struct componentname *cnp)
 2734 {
 2735         struct mac_lomac *subj, *obj;
 2736 
 2737         if (!mac_lomac_enabled)
 2738                 return (0);
 2739 
 2740         subj = SLOT(cred->cr_label);
 2741         obj = SLOT(dvplabel);
 2742 
 2743         if (!mac_lomac_subject_dominate(subj, obj))
 2744                 return (EACCES);
 2745 
 2746         obj = SLOT(vplabel);
 2747 
 2748         if (!mac_lomac_subject_dominate(subj, obj))
 2749                 return (EACCES);
 2750 
 2751         return (0);
 2752 }
 2753 
 2754 static int
 2755 mac_lomac_check_vnode_write(struct ucred *active_cred,
 2756     struct ucred *file_cred, struct vnode *vp, struct label *vplabel)
 2757 {
 2758         struct mac_lomac *subj, *obj;
 2759 
 2760         if (!mac_lomac_enabled || !revocation_enabled)
 2761                 return (0);
 2762 
 2763         subj = SLOT(active_cred->cr_label);
 2764         obj = SLOT(vplabel);
 2765 
 2766         if (!mac_lomac_subject_dominate(subj, obj))
 2767                 return (EACCES);
 2768 
 2769         return (0);
 2770 }
 2771 
 2772 static void
 2773 mac_lomac_thread_userret(struct thread *td)
 2774 {
 2775         struct proc *p = td->td_proc;
 2776         struct mac_lomac_proc *subj = PSLOT(p->p_label);
 2777         struct ucred *newcred, *oldcred;
 2778         int dodrop;
 2779 
 2780         mtx_lock(&subj->mtx);
 2781         if (subj->mac_lomac.ml_flags & MAC_LOMAC_FLAG_UPDATE) {
 2782                 dodrop = 0;
 2783                 mtx_unlock(&subj->mtx);
 2784                 newcred = crget();
 2785                 /*
 2786                  * Prevent a lock order reversal in
 2787                  * mac_cred_mmapped_drop_perms; ideally, the other
 2788                  * user of subj->mtx wouldn't be holding Giant.
 2789                  */
 2790                 mtx_lock(&Giant);
 2791                 PROC_LOCK(p);
 2792                 mtx_lock(&subj->mtx);
 2793                 /*
 2794                  * Check if we lost the race while allocating the cred.
 2795                  */
 2796                 if ((subj->mac_lomac.ml_flags & MAC_LOMAC_FLAG_UPDATE) == 0) {
 2797                         crfree(newcred);
 2798                         goto out;
 2799                 }
 2800                 oldcred = p->p_ucred;
 2801                 crcopy(newcred, oldcred);
 2802                 crhold(newcred);
 2803                 mac_lomac_copy(&subj->mac_lomac, SLOT(newcred->cr_label));
 2804                 p->p_ucred = newcred;
 2805                 crfree(oldcred);
 2806                 dodrop = 1;
 2807         out:
 2808                 mtx_unlock(&subj->mtx);
 2809                 PROC_UNLOCK(p);
 2810                 if (dodrop)
 2811                         mac_cred_mmapped_drop_perms(curthread, newcred);
 2812                 mtx_unlock(&Giant);
 2813         } else {
 2814                 mtx_unlock(&subj->mtx);
 2815         }
 2816 }
 2817 
 2818 static struct mac_policy_ops mac_lomac_ops =
 2819 {
 2820         .mpo_init = mac_lomac_init,
 2821         .mpo_init_bpfdesc_label = mac_lomac_init_label,
 2822         .mpo_init_cred_label = mac_lomac_init_label,
 2823         .mpo_init_devfs_label = mac_lomac_init_label,
 2824         .mpo_init_ifnet_label = mac_lomac_init_label,
 2825         .mpo_init_syncache_label = mac_lomac_init_label_waitcheck,
 2826         .mpo_init_inpcb_label = mac_lomac_init_label_waitcheck,
 2827         .mpo_init_ipq_label = mac_lomac_init_label_waitcheck,
 2828         .mpo_init_mbuf_label = mac_lomac_init_label_waitcheck,
 2829         .mpo_init_mount_label = mac_lomac_init_label,
 2830         .mpo_init_pipe_label = mac_lomac_init_label,
 2831         .mpo_init_proc_label = mac_lomac_init_proc_label,
 2832         .mpo_init_socket_label = mac_lomac_init_label_waitcheck,
 2833         .mpo_init_socket_peer_label = mac_lomac_init_label_waitcheck,
 2834         .mpo_init_vnode_label = mac_lomac_init_label,
 2835         .mpo_init_syncache_from_inpcb = mac_lomac_init_syncache_from_inpcb,
 2836         .mpo_destroy_bpfdesc_label = mac_lomac_destroy_label,
 2837         .mpo_destroy_cred_label = mac_lomac_destroy_label,
 2838         .mpo_destroy_devfs_label = mac_lomac_destroy_label,
 2839         .mpo_destroy_ifnet_label = mac_lomac_destroy_label,
 2840         .mpo_destroy_inpcb_label = mac_lomac_destroy_label,
 2841         .mpo_destroy_ipq_label = mac_lomac_destroy_label,
 2842         .mpo_destroy_mbuf_label = mac_lomac_destroy_label,
 2843         .mpo_destroy_mount_label = mac_lomac_destroy_label,
 2844         .mpo_destroy_pipe_label = mac_lomac_destroy_label,
 2845         .mpo_destroy_proc_label = mac_lomac_destroy_proc_label,
 2846         .mpo_destroy_syncache_label = mac_lomac_destroy_label,
 2847         .mpo_destroy_socket_label = mac_lomac_destroy_label,
 2848         .mpo_destroy_socket_peer_label = mac_lomac_destroy_label,
 2849         .mpo_destroy_vnode_label = mac_lomac_destroy_label,
 2850         .mpo_copy_cred_label = mac_lomac_copy_label,
 2851         .mpo_copy_ifnet_label = mac_lomac_copy_label,
 2852         .mpo_copy_mbuf_label = mac_lomac_copy_label,
 2853         .mpo_copy_pipe_label = mac_lomac_copy_label,
 2854         .mpo_copy_socket_label = mac_lomac_copy_label,
 2855         .mpo_copy_vnode_label = mac_lomac_copy_label,
 2856         .mpo_externalize_cred_label = mac_lomac_externalize_label,
 2857         .mpo_externalize_ifnet_label = mac_lomac_externalize_label,
 2858         .mpo_externalize_pipe_label = mac_lomac_externalize_label,
 2859         .mpo_externalize_socket_label = mac_lomac_externalize_label,
 2860         .mpo_externalize_socket_peer_label = mac_lomac_externalize_label,
 2861         .mpo_externalize_vnode_label = mac_lomac_externalize_label,
 2862         .mpo_internalize_cred_label = mac_lomac_internalize_label,
 2863         .mpo_internalize_ifnet_label = mac_lomac_internalize_label,
 2864         .mpo_internalize_pipe_label = mac_lomac_internalize_label,
 2865         .mpo_internalize_socket_label = mac_lomac_internalize_label,
 2866         .mpo_internalize_vnode_label = mac_lomac_internalize_label,
 2867         .mpo_create_devfs_device = mac_lomac_create_devfs_device,
 2868         .mpo_create_devfs_directory = mac_lomac_create_devfs_directory,
 2869         .mpo_create_devfs_symlink = mac_lomac_create_devfs_symlink,
 2870         .mpo_create_mount = mac_lomac_create_mount,
 2871         .mpo_relabel_vnode = mac_lomac_relabel_vnode,
 2872         .mpo_update_devfs = mac_lomac_update_devfs,
 2873         .mpo_associate_vnode_devfs = mac_lomac_associate_vnode_devfs,
 2874         .mpo_associate_vnode_extattr = mac_lomac_associate_vnode_extattr,
 2875         .mpo_associate_vnode_singlelabel =
 2876             mac_lomac_associate_vnode_singlelabel,
 2877         .mpo_create_vnode_extattr = mac_lomac_create_vnode_extattr,
 2878         .mpo_setlabel_vnode_extattr = mac_lomac_setlabel_vnode_extattr,
 2879         .mpo_create_mbuf_from_socket = mac_lomac_create_mbuf_from_socket,
 2880         .mpo_create_mbuf_from_syncache = mac_lomac_create_mbuf_from_syncache,
 2881         .mpo_create_pipe = mac_lomac_create_pipe,
 2882         .mpo_create_socket = mac_lomac_create_socket,
 2883         .mpo_create_socket_from_socket = mac_lomac_create_socket_from_socket,
 2884         .mpo_relabel_pipe = mac_lomac_relabel_pipe,
 2885         .mpo_relabel_socket = mac_lomac_relabel_socket,
 2886         .mpo_set_socket_peer_from_mbuf = mac_lomac_set_socket_peer_from_mbuf,
 2887         .mpo_set_socket_peer_from_socket =
 2888             mac_lomac_set_socket_peer_from_socket,
 2889         .mpo_create_bpfdesc = mac_lomac_create_bpfdesc,
 2890         .mpo_create_datagram_from_ipq = mac_lomac_create_datagram_from_ipq,
 2891         .mpo_create_fragment = mac_lomac_create_fragment,
 2892         .mpo_create_ifnet = mac_lomac_create_ifnet,
 2893         .mpo_create_inpcb_from_socket = mac_lomac_create_inpcb_from_socket,
 2894         .mpo_create_ipq = mac_lomac_create_ipq,
 2895         .mpo_create_mbuf_from_inpcb = mac_lomac_create_mbuf_from_inpcb,
 2896         .mpo_create_mbuf_linklayer = mac_lomac_create_mbuf_linklayer,
 2897         .mpo_create_mbuf_from_bpfdesc = mac_lomac_create_mbuf_from_bpfdesc,
 2898         .mpo_create_mbuf_from_ifnet = mac_lomac_create_mbuf_from_ifnet,
 2899         .mpo_create_mbuf_multicast_encap =
 2900             mac_lomac_create_mbuf_multicast_encap,
 2901         .mpo_create_mbuf_netlayer = mac_lomac_create_mbuf_netlayer,
 2902         .mpo_fragment_match = mac_lomac_fragment_match,
 2903         .mpo_relabel_ifnet = mac_lomac_relabel_ifnet,
 2904         .mpo_update_ipq = mac_lomac_update_ipq,
 2905         .mpo_inpcb_sosetlabel = mac_lomac_inpcb_sosetlabel,
 2906         .mpo_execve_transition = mac_lomac_execve_transition,
 2907         .mpo_execve_will_transition = mac_lomac_execve_will_transition,
 2908         .mpo_create_proc0 = mac_lomac_create_proc0,
 2909         .mpo_create_proc1 = mac_lomac_create_proc1,
 2910         .mpo_relabel_cred = mac_lomac_relabel_cred,
 2911         .mpo_check_bpfdesc_receive = mac_lomac_check_bpfdesc_receive,
 2912         .mpo_check_cred_relabel = mac_lomac_check_cred_relabel,
 2913         .mpo_check_cred_visible = mac_lomac_check_cred_visible,
 2914         .mpo_check_ifnet_relabel = mac_lomac_check_ifnet_relabel,
 2915         .mpo_check_ifnet_transmit = mac_lomac_check_ifnet_transmit,
 2916         .mpo_check_inpcb_deliver = mac_lomac_check_inpcb_deliver,
 2917         .mpo_check_kld_load = mac_lomac_check_kld_load,
 2918         .mpo_check_pipe_ioctl = mac_lomac_check_pipe_ioctl,
 2919         .mpo_check_pipe_read = mac_lomac_check_pipe_read,
 2920         .mpo_check_pipe_relabel = mac_lomac_check_pipe_relabel,
 2921         .mpo_check_pipe_write = mac_lomac_check_pipe_write,
 2922         .mpo_check_proc_debug = mac_lomac_check_proc_debug,
 2923         .mpo_check_proc_sched = mac_lomac_check_proc_sched,
 2924         .mpo_check_proc_signal = mac_lomac_check_proc_signal,
 2925         .mpo_check_socket_deliver = mac_lomac_check_socket_deliver,
 2926         .mpo_check_socket_relabel = mac_lomac_check_socket_relabel,
 2927         .mpo_check_socket_visible = mac_lomac_check_socket_visible,
 2928         .mpo_check_system_acct = mac_lomac_check_system_acct,
 2929         .mpo_check_system_auditctl = mac_lomac_check_system_auditctl,
 2930         .mpo_check_system_swapoff = mac_lomac_check_system_swapoff,
 2931         .mpo_check_system_swapon = mac_lomac_check_system_swapon,
 2932         .mpo_check_system_sysctl = mac_lomac_check_system_sysctl,
 2933         .mpo_check_vnode_access = mac_lomac_check_vnode_open,
 2934         .mpo_check_vnode_create = mac_lomac_check_vnode_create,
 2935         .mpo_check_vnode_deleteacl = mac_lomac_check_vnode_deleteacl,
 2936         .mpo_check_vnode_link = mac_lomac_check_vnode_link,
 2937         .mpo_check_vnode_mmap = mac_lomac_check_vnode_mmap,
 2938         .mpo_check_vnode_mmap_downgrade = mac_lomac_check_vnode_mmap_downgrade,
 2939         .mpo_check_vnode_open = mac_lomac_check_vnode_open,
 2940         .mpo_check_vnode_read = mac_lomac_check_vnode_read,
 2941         .mpo_check_vnode_relabel = mac_lomac_check_vnode_relabel,
 2942         .mpo_check_vnode_rename_from = mac_lomac_check_vnode_rename_from,
 2943         .mpo_check_vnode_rename_to = mac_lomac_check_vnode_rename_to,
 2944         .mpo_check_vnode_revoke = mac_lomac_check_vnode_revoke,
 2945         .mpo_check_vnode_setacl = mac_lomac_check_vnode_setacl,
 2946         .mpo_check_vnode_setextattr = mac_lomac_check_vnode_setextattr,
 2947         .mpo_check_vnode_setflags = mac_lomac_check_vnode_setflags,
 2948         .mpo_check_vnode_setmode = mac_lomac_check_vnode_setmode,
 2949         .mpo_check_vnode_setowner = mac_lomac_check_vnode_setowner,
 2950         .mpo_check_vnode_setutimes = mac_lomac_check_vnode_setutimes,
 2951         .mpo_check_vnode_unlink = mac_lomac_check_vnode_unlink,
 2952         .mpo_check_vnode_write = mac_lomac_check_vnode_write,
 2953         .mpo_thread_userret = mac_lomac_thread_userret,
 2954         .mpo_create_mbuf_from_firewall = mac_lomac_create_mbuf_from_firewall,
 2955         .mpo_priv_check = mac_lomac_priv_check,
 2956 };
 2957 
 2958 MAC_POLICY_SET(&mac_lomac_ops, mac_lomac, "TrustedBSD MAC/LOMAC",
 2959     MPC_LOADTIME_FLAG_NOTLATE | MPC_LOADTIME_FLAG_LABELMBUFS,
 2960     &mac_lomac_slot);

Cache object: de8f68679b78473756184dfeb8186c62


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