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

Cache object: 89654b8302592390af92a1de5839c4a4


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