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

Cache object: 8a18f8c7c9b77822842f511668654da9


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