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

Cache object: b96db58ee4338a7b28cc4dbcc8ef0e6a


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