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

Cache object: 1fecc17d125014cc86cb1844f2527525


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