The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/security/mac_lomac/mac_lomac.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 1999-2002, 2007-2009 Robert N. M. Watson
    3  * Copyright (c) 2001-2005 Networks Associates Technology, Inc.
    4  * Copyright (c) 2006 SPARTA, Inc.
    5  * All rights reserved.
    6  *
    7  * This software was developed by Robert Watson for the TrustedBSD Project.
    8  *
    9  * This software was developed for the FreeBSD Project in part by NAI Labs,
   10  * the Security Research Division of Network Associates, Inc. under
   11  * DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA
   12  * CHATS research program.
   13  *
   14  * This software was enhanced by SPARTA ISSO under SPAWAR contract
   15  * N66001-04-C-6019 ("SEFOS").
   16  *
   17  * Redistribution and use in source and binary forms, with or without
   18  * modification, are permitted provided that the following conditions
   19  * are met:
   20  * 1. Redistributions of source code must retain the above copyright
   21  *    notice, this list of conditions and the following disclaimer.
   22  * 2. Redistributions in binary form must reproduce the above copyright
   23  *    notice, this list of conditions and the following disclaimer in the
   24  *    documentation and/or other materials provided with the distribution.
   25  *
   26  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   27  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   28  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   29  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   30  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   31  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   32  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   35  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   36  * SUCH DAMAGE.
   37  *
   38  * $FreeBSD$
   39  */
   40 
   41 /*
   42  * Developed by the TrustedBSD Project.
   43  *
   44  * Low-watermark floating label mandatory integrity policy.
   45  */
   46 
   47 #include <sys/types.h>
   48 #include <sys/param.h>
   49 #include <sys/acl.h>
   50 #include <sys/conf.h>
   51 #include <sys/extattr.h>
   52 #include <sys/kernel.h>
   53 #include <sys/malloc.h>
   54 #include <sys/mman.h>
   55 #include <sys/mount.h>
   56 #include <sys/priv.h>
   57 #include <sys/proc.h>
   58 #include <sys/sbuf.h>
   59 #include <sys/systm.h>
   60 #include <sys/sysproto.h>
   61 #include <sys/sysent.h>
   62 #include <sys/systm.h>
   63 #include <sys/vnode.h>
   64 #include <sys/file.h>
   65 #include <sys/socket.h>
   66 #include <sys/socketvar.h>
   67 #include <sys/sx.h>
   68 #include <sys/pipe.h>
   69 #include <sys/sysctl.h>
   70 #include <sys/syslog.h>
   71 
   72 #include <fs/devfs/devfs.h>
   73 
   74 #include <net/bpfdesc.h>
   75 #include <net/if.h>
   76 #include <net/if_types.h>
   77 #include <net/if_var.h>
   78 
   79 #include <netinet/in.h>
   80 #include <netinet/in_pcb.h>
   81 #include <netinet/ip_var.h>
   82 
   83 #include <vm/vm.h>
   84 
   85 #include <security/mac/mac_policy.h>
   86 #include <security/mac/mac_framework.h>
   87 #include <security/mac_lomac/mac_lomac.h>
   88 
   89 struct mac_lomac_proc {
   90         struct mac_lomac mac_lomac;
   91         struct mtx mtx;
   92 };
   93 
   94 SYSCTL_DECL(_security_mac);
   95 
   96 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         int lomac_type;
 1036 
 1037         ml = SLOT(delabel);
 1038         if (strcmp(dev->si_name, "null") == 0 ||
 1039             strcmp(dev->si_name, "zero") == 0 ||
 1040             strcmp(dev->si_name, "random") == 0 ||
 1041             strncmp(dev->si_name, "fd/", strlen("fd/")) == 0 ||
 1042             strncmp(dev->si_name, "ttyv", strlen("ttyv")) == 0)
 1043                 lomac_type = MAC_LOMAC_TYPE_EQUAL;
 1044         else if (ptys_equal &&
 1045             (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 ||
 1046             strncmp(dev->si_name, "pts/", strlen("pts/")) == 0 ||
 1047             strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0))
 1048                 lomac_type = MAC_LOMAC_TYPE_EQUAL;
 1049         else
 1050                 lomac_type = MAC_LOMAC_TYPE_HIGH;
 1051         lomac_set_single(ml, lomac_type, 0);
 1052 }
 1053 
 1054 static void
 1055 lomac_devfs_create_directory(struct mount *mp, char *dirname, int dirnamelen,
 1056     struct devfs_dirent *de, struct label *delabel)
 1057 {
 1058         struct mac_lomac *ml;
 1059 
 1060         ml = SLOT(delabel);
 1061         lomac_set_single(ml, MAC_LOMAC_TYPE_HIGH, 0);
 1062 }
 1063 
 1064 static void
 1065 lomac_devfs_create_symlink(struct ucred *cred, struct mount *mp,
 1066     struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de,
 1067     struct label *delabel)
 1068 {
 1069         struct mac_lomac *source, *dest;
 1070 
 1071         source = SLOT(cred->cr_label);
 1072         dest = SLOT(delabel);
 1073 
 1074         lomac_copy_single(source, dest);
 1075 }
 1076 
 1077 static void
 1078 lomac_devfs_update(struct mount *mp, struct devfs_dirent *de,
 1079     struct label *delabel, struct vnode *vp, struct label *vplabel)
 1080 {
 1081         struct mac_lomac *source, *dest;
 1082 
 1083         source = SLOT(vplabel);
 1084         dest = SLOT(delabel);
 1085 
 1086         lomac_copy(source, dest);
 1087 }
 1088 
 1089 static void
 1090 lomac_devfs_vnode_associate(struct mount *mp, struct label *mplabel,
 1091     struct devfs_dirent *de, struct label *delabel, struct vnode *vp,
 1092     struct label *vplabel)
 1093 {
 1094         struct mac_lomac *source, *dest;
 1095 
 1096         source = SLOT(delabel);
 1097         dest = SLOT(vplabel);
 1098 
 1099         lomac_copy_single(source, dest);
 1100 }
 1101 
 1102 static int
 1103 lomac_ifnet_check_relabel(struct ucred *cred, struct ifnet *ifp,
 1104     struct label *ifplabel, struct label *newlabel)
 1105 {
 1106         struct mac_lomac *subj, *new;
 1107         int error;
 1108 
 1109         subj = SLOT(cred->cr_label);
 1110         new = SLOT(newlabel);
 1111 
 1112         /*
 1113          * If there is a LOMAC label update for the interface, it may be an
 1114          * update of the single, range, or both.
 1115          */
 1116         error = lomac_atmostflags(new, MAC_LOMAC_FLAGS_BOTH);
 1117         if (error)
 1118                 return (error);
 1119 
 1120         /*
 1121          * Relabling network interfaces requires LOMAC privilege.
 1122          */
 1123         error = lomac_subject_privileged(subj);
 1124         if (error)
 1125                 return (error);
 1126 
 1127         /*
 1128          * If the LOMAC label is to be changed, authorize as appropriate.
 1129          */
 1130         if (new->ml_flags & MAC_LOMAC_FLAGS_BOTH) {
 1131                 /*
 1132                  * Fill in the missing parts from the previous label.
 1133                  */
 1134                 if ((new->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0)
 1135                         lomac_copy_single(subj, new);
 1136                 if ((new->ml_flags & MAC_LOMAC_FLAG_RANGE) == 0)
 1137                         lomac_copy_range(subj, new);
 1138 
 1139                 /*
 1140                  * Rely on the traditional superuser status for the LOMAC
 1141                  * interface relabel requirements.  XXXMAC: This will go
 1142                  * away.
 1143                  *
 1144                  * XXXRW: This is also redundant to a higher layer check.
 1145                  */
 1146                 error = priv_check_cred(cred, PRIV_NET_SETIFMAC, 0);
 1147                 if (error)
 1148                         return (EPERM);
 1149 
 1150                 /*
 1151                  * XXXMAC: Additional consistency tests regarding the single
 1152                  * and the range of the new label might be performed here.
 1153                  */
 1154         }
 1155 
 1156         return (0);
 1157 }
 1158 
 1159 static int
 1160 lomac_ifnet_check_transmit(struct ifnet *ifp, struct label *ifplabel,
 1161     struct mbuf *m, struct label *mlabel)
 1162 {
 1163         struct mac_lomac *p, *i;
 1164 
 1165         if (!lomac_enabled)
 1166                 return (0);
 1167 
 1168         p = SLOT(mlabel);
 1169         i = SLOT(ifplabel);
 1170 
 1171         return (lomac_single_in_range(p, i) ? 0 : EACCES);
 1172 }
 1173 
 1174 static void
 1175 lomac_ifnet_create(struct ifnet *ifp, struct label *ifplabel)
 1176 {
 1177         char tifname[IFNAMSIZ], *p, *q;
 1178         char tiflist[sizeof(trusted_interfaces)];
 1179         struct mac_lomac *dest;
 1180         int len, grade;
 1181 
 1182         dest = SLOT(ifplabel);
 1183 
 1184         if (ifp->if_type == IFT_LOOP) {
 1185                 grade = MAC_LOMAC_TYPE_EQUAL;
 1186                 goto set;
 1187         }
 1188 
 1189         if (trust_all_interfaces) {
 1190                 grade = MAC_LOMAC_TYPE_HIGH;
 1191                 goto set;
 1192         }
 1193 
 1194         grade = MAC_LOMAC_TYPE_LOW;
 1195 
 1196         if (trusted_interfaces[0] == '\0' ||
 1197             !strvalid(trusted_interfaces, sizeof(trusted_interfaces)))
 1198                 goto set;
 1199 
 1200         bzero(tiflist, sizeof(tiflist));
 1201         for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++)
 1202                 if(*p != ' ' && *p != '\t')
 1203                         *q = *p;
 1204 
 1205         for (p = q = tiflist;; p++) {
 1206                 if (*p == ',' || *p == '\0') {
 1207                         len = p - q;
 1208                         if (len < IFNAMSIZ) {
 1209                                 bzero(tifname, sizeof(tifname));
 1210                                 bcopy(q, tifname, len);
 1211                                 if (strcmp(tifname, ifp->if_xname) == 0) {
 1212                                         grade = MAC_LOMAC_TYPE_HIGH;
 1213                                         break;
 1214                                 }
 1215                         }
 1216                         else {
 1217                                 *p = '\0';
 1218                                 printf("MAC/LOMAC warning: interface name "
 1219                                     "\"%s\" is too long (must be < %d)\n",
 1220                                     q, IFNAMSIZ);
 1221                         }
 1222                         if (*p == '\0')
 1223                                 break;
 1224                         q = p + 1;
 1225                 }
 1226         }
 1227 set:
 1228         lomac_set_single(dest, grade, 0);
 1229         lomac_set_range(dest, grade, 0, grade, 0);
 1230 }
 1231 
 1232 static void
 1233 lomac_ifnet_create_mbuf(struct ifnet *ifp, struct label *ifplabel,
 1234     struct mbuf *m, struct label *mlabel)
 1235 {
 1236         struct mac_lomac *source, *dest;
 1237 
 1238         source = SLOT(ifplabel);
 1239         dest = SLOT(mlabel);
 1240 
 1241         lomac_copy_single(source, dest);
 1242 }
 1243 
 1244 static void
 1245 lomac_ifnet_relabel(struct ucred *cred, struct ifnet *ifp,
 1246     struct label *ifplabel, struct label *newlabel)
 1247 {
 1248         struct mac_lomac *source, *dest;
 1249 
 1250         source = SLOT(newlabel);
 1251         dest = SLOT(ifplabel);
 1252 
 1253         try_relabel(source, dest);
 1254 }
 1255 
 1256 static int
 1257 lomac_inpcb_check_deliver(struct inpcb *inp, struct label *inplabel,
 1258     struct mbuf *m, struct label *mlabel)
 1259 {
 1260         struct mac_lomac *p, *i;
 1261 
 1262         if (!lomac_enabled)
 1263                 return (0);
 1264 
 1265         p = SLOT(mlabel);
 1266         i = SLOT(inplabel);
 1267 
 1268         return (lomac_equal_single(p, i) ? 0 : EACCES);
 1269 }
 1270 
 1271 static int
 1272 lomac_inpcb_check_visible(struct ucred *cred, struct inpcb *inp,
 1273     struct label *inplabel)
 1274 {
 1275         struct mac_lomac *subj, *obj;
 1276 
 1277         if (!lomac_enabled)
 1278                 return (0);
 1279 
 1280         subj = SLOT(cred->cr_label);
 1281         obj = SLOT(inplabel);
 1282 
 1283         if (!lomac_dominate_single(obj, subj))
 1284                 return (ENOENT);
 1285 
 1286         return (0);
 1287 }
 1288 
 1289 static void
 1290 lomac_inpcb_create(struct socket *so, struct label *solabel,
 1291     struct inpcb *inp, struct label *inplabel)
 1292 {
 1293         struct mac_lomac *source, *dest;
 1294 
 1295         source = SLOT(solabel);
 1296         dest = SLOT(inplabel);
 1297 
 1298         lomac_copy_single(source, dest);
 1299 }
 1300 
 1301 static void
 1302 lomac_inpcb_create_mbuf(struct inpcb *inp, struct label *inplabel,
 1303     struct mbuf *m, struct label *mlabel)
 1304 {
 1305         struct mac_lomac *source, *dest;
 1306 
 1307         source = SLOT(inplabel);
 1308         dest = SLOT(mlabel);
 1309 
 1310         lomac_copy_single(source, dest);
 1311 }
 1312 
 1313 static void
 1314 lomac_inpcb_sosetlabel(struct socket *so, struct label *solabel,
 1315     struct inpcb *inp, struct label *inplabel)
 1316 {
 1317         struct mac_lomac *source, *dest;
 1318 
 1319         SOCK_LOCK_ASSERT(so);
 1320 
 1321         source = SLOT(solabel);
 1322         dest = SLOT(inplabel);
 1323 
 1324         lomac_copy_single(source, dest);
 1325 }
 1326 
 1327 static void
 1328 lomac_ip6q_create(struct mbuf *m, struct label *mlabel, struct ip6q *q6,
 1329     struct label *q6label)
 1330 {
 1331         struct mac_lomac *source, *dest;
 1332 
 1333         source = SLOT(mlabel);
 1334         dest = SLOT(q6label);
 1335 
 1336         lomac_copy_single(source, dest);
 1337 }
 1338 
 1339 static int
 1340 lomac_ip6q_match(struct mbuf *m, struct label *mlabel, struct ip6q *q6,
 1341     struct label *q6label)
 1342 {
 1343         struct mac_lomac *a, *b;
 1344 
 1345         a = SLOT(q6label);
 1346         b = SLOT(mlabel);
 1347 
 1348         return (lomac_equal_single(a, b));
 1349 }
 1350 
 1351 static void
 1352 lomac_ip6q_reassemble(struct ip6q *q6, struct label *q6label, struct mbuf *m,
 1353     struct label *mlabel)
 1354 {
 1355         struct mac_lomac *source, *dest;
 1356 
 1357         source = SLOT(q6label);
 1358         dest = SLOT(mlabel);
 1359 
 1360         /* Just use the head, since we require them all to match. */
 1361         lomac_copy_single(source, dest);
 1362 }
 1363 
 1364 static void
 1365 lomac_ip6q_update(struct mbuf *m, struct label *mlabel, struct ip6q *q6,
 1366     struct label *q6label)
 1367 {
 1368 
 1369         /* NOOP: we only accept matching labels, so no need to update */
 1370 }
 1371 
 1372 static void
 1373 lomac_ipq_create(struct mbuf *m, struct label *mlabel, struct ipq *q,
 1374     struct label *qlabel)
 1375 {
 1376         struct mac_lomac *source, *dest;
 1377 
 1378         source = SLOT(mlabel);
 1379         dest = SLOT(qlabel);
 1380 
 1381         lomac_copy_single(source, dest);
 1382 }
 1383 
 1384 static int
 1385 lomac_ipq_match(struct mbuf *m, struct label *mlabel, struct ipq *q,
 1386     struct label *qlabel)
 1387 {
 1388         struct mac_lomac *a, *b;
 1389 
 1390         a = SLOT(qlabel);
 1391         b = SLOT(mlabel);
 1392 
 1393         return (lomac_equal_single(a, b));
 1394 }
 1395 
 1396 static void
 1397 lomac_ipq_reassemble(struct ipq *q, struct label *qlabel, struct mbuf *m,
 1398     struct label *mlabel)
 1399 {
 1400         struct mac_lomac *source, *dest;
 1401 
 1402         source = SLOT(qlabel);
 1403         dest = SLOT(mlabel);
 1404 
 1405         /* Just use the head, since we require them all to match. */
 1406         lomac_copy_single(source, dest);
 1407 }
 1408 
 1409 static void
 1410 lomac_ipq_update(struct mbuf *m, struct label *mlabel, struct ipq *q,
 1411     struct label *qlabel)
 1412 {
 1413 
 1414         /* NOOP: we only accept matching labels, so no need to update */
 1415 }
 1416 
 1417 static int
 1418 lomac_kld_check_load(struct ucred *cred, struct vnode *vp,
 1419     struct label *vplabel)
 1420 {
 1421         struct mac_lomac *subj, *obj;
 1422 
 1423         if (!lomac_enabled)
 1424                 return (0);
 1425 
 1426         subj = SLOT(cred->cr_label);
 1427         obj = SLOT(vplabel);
 1428 
 1429         if (lomac_subject_privileged(subj))
 1430                 return (EPERM);
 1431 
 1432         if (!lomac_high_single(obj))
 1433                 return (EACCES);
 1434 
 1435         return (0);
 1436 }
 1437 
 1438 static void
 1439 lomac_mount_create(struct ucred *cred, struct mount *mp,
 1440     struct label *mplabel)
 1441 {
 1442         struct mac_lomac *source, *dest;
 1443 
 1444         source = SLOT(cred->cr_label);
 1445         dest = SLOT(mplabel);
 1446         lomac_copy_single(source, dest);
 1447 }
 1448 
 1449 static void
 1450 lomac_netatalk_aarp_send(struct ifnet *ifp, struct label *ifplabel,
 1451     struct mbuf *m, struct label *mlabel)
 1452 {
 1453         struct mac_lomac *dest;
 1454 
 1455         dest = SLOT(mlabel);
 1456 
 1457         lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0);
 1458 }
 1459 
 1460 static void
 1461 lomac_netinet_arp_send(struct ifnet *ifp, struct label *ifplabel,
 1462     struct mbuf *m, struct label *mlabel)
 1463 {
 1464         struct mac_lomac *dest;
 1465 
 1466         dest = SLOT(mlabel);
 1467 
 1468         lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0);
 1469 }
 1470 
 1471 static void
 1472 lomac_netinet_firewall_reply(struct mbuf *mrecv, struct label *mrecvlabel,
 1473     struct mbuf *msend, struct label *msendlabel)
 1474 {
 1475         struct mac_lomac *source, *dest;
 1476 
 1477         source = SLOT(mrecvlabel);
 1478         dest = SLOT(msendlabel);
 1479 
 1480         lomac_copy_single(source, dest);
 1481 }
 1482 
 1483 static void
 1484 lomac_netinet_firewall_send(struct mbuf *m, struct label *mlabel)
 1485 {
 1486         struct mac_lomac *dest;
 1487 
 1488         dest = SLOT(mlabel);
 1489 
 1490         /* XXX: where is the label for the firewall really comming from? */
 1491         lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0);
 1492 }
 1493 
 1494 static void
 1495 lomac_netinet_fragment(struct mbuf *m, struct label *mlabel,
 1496     struct mbuf *frag, struct label *fraglabel)
 1497 {
 1498         struct mac_lomac *source, *dest;
 1499 
 1500         source = SLOT(mlabel);
 1501         dest = SLOT(fraglabel);
 1502 
 1503         lomac_copy_single(source, dest);
 1504 }
 1505 
 1506 static void
 1507 lomac_netinet_icmp_reply(struct mbuf *mrecv, struct label *mrecvlabel,
 1508     struct mbuf *msend, struct label *msendlabel)
 1509 {
 1510         struct mac_lomac *source, *dest;
 1511 
 1512         source = SLOT(mrecvlabel);
 1513         dest = SLOT(msendlabel);
 1514 
 1515         lomac_copy_single(source, dest);
 1516 }
 1517 
 1518 static void
 1519 lomac_netinet_igmp_send(struct ifnet *ifp, struct label *ifplabel,
 1520     struct mbuf *m, struct label *mlabel)
 1521 {
 1522         struct mac_lomac *dest;
 1523 
 1524         dest = SLOT(mlabel);
 1525 
 1526         lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0);
 1527 }
 1528 
 1529 static void
 1530 lomac_netinet6_nd6_send(struct ifnet *ifp, struct label *ifplabel,
 1531     struct mbuf *m, struct label *mlabel)
 1532 {
 1533         struct mac_lomac *dest;
 1534 
 1535         dest = SLOT(mlabel);
 1536 
 1537         lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0);
 1538 }
 1539 
 1540 static int
 1541 lomac_pipe_check_ioctl(struct ucred *cred, struct pipepair *pp,
 1542     struct label *pplabel, unsigned long cmd, void /* caddr_t */ *data)
 1543 {
 1544 
 1545         if (!lomac_enabled)
 1546                 return (0);
 1547 
 1548         /* XXX: This will be implemented soon... */
 1549 
 1550         return (0);
 1551 }
 1552 
 1553 static int
 1554 lomac_pipe_check_read(struct ucred *cred, struct pipepair *pp,
 1555     struct label *pplabel)
 1556 {
 1557         struct mac_lomac *subj, *obj;
 1558 
 1559         if (!lomac_enabled)
 1560                 return (0);
 1561 
 1562         subj = SLOT(cred->cr_label);
 1563         obj = SLOT(pplabel);
 1564 
 1565         if (!lomac_dominate_single(obj, subj))
 1566                 return (maybe_demote(subj, obj, "reading", "pipe", NULL));
 1567 
 1568         return (0);
 1569 }
 1570 
 1571 static int
 1572 lomac_pipe_check_relabel(struct ucred *cred, struct pipepair *pp,
 1573     struct label *pplabel, struct label *newlabel)
 1574 {
 1575         struct mac_lomac *subj, *obj, *new;
 1576         int error;
 1577 
 1578         new = SLOT(newlabel);
 1579         subj = SLOT(cred->cr_label);
 1580         obj = SLOT(pplabel);
 1581 
 1582         /*
 1583          * If there is a LOMAC label update for a pipe, it must be a single
 1584          * update.
 1585          */
 1586         error = lomac_atmostflags(new, MAC_LOMAC_FLAG_SINGLE);
 1587         if (error)
 1588                 return (error);
 1589 
 1590         /*
 1591          * To perform a relabel of a pipe (LOMAC label or not), LOMAC must
 1592          * authorize the relabel.
 1593          */
 1594         if (!lomac_single_in_range(obj, subj))
 1595                 return (EPERM);
 1596 
 1597         /*
 1598          * If the LOMAC label is to be changed, authorize as appropriate.
 1599          */
 1600         if (new->ml_flags & MAC_LOMAC_FLAG_SINGLE) {
 1601                 /*
 1602                  * To change the LOMAC label on a pipe, the new pipe label
 1603                  * must be in the subject range.
 1604                  */
 1605                 if (!lomac_single_in_range(new, subj))
 1606                         return (EPERM);
 1607 
 1608                 /*
 1609                  * To change the LOMAC label on a pipe to be EQUAL, the
 1610                  * subject must have appropriate privilege.
 1611                  */
 1612                 if (lomac_contains_equal(new)) {
 1613                         error = lomac_subject_privileged(subj);
 1614                         if (error)
 1615                                 return (error);
 1616                 }
 1617         }
 1618 
 1619         return (0);
 1620 }
 1621 
 1622 static int
 1623 lomac_pipe_check_write(struct ucred *cred, struct pipepair *pp,
 1624     struct label *pplabel)
 1625 {
 1626         struct mac_lomac *subj, *obj;
 1627 
 1628         if (!lomac_enabled)
 1629                 return (0);
 1630 
 1631         subj = SLOT(cred->cr_label);
 1632         obj = SLOT(pplabel);
 1633 
 1634         if (!lomac_subject_dominate(subj, obj))
 1635                 return (EACCES);
 1636 
 1637         return (0);
 1638 }
 1639 
 1640 static void
 1641 lomac_pipe_create(struct ucred *cred, struct pipepair *pp,
 1642     struct label *pplabel)
 1643 {
 1644         struct mac_lomac *source, *dest;
 1645 
 1646         source = SLOT(cred->cr_label);
 1647         dest = SLOT(pplabel);
 1648 
 1649         lomac_copy_single(source, dest);
 1650 }
 1651 
 1652 static void
 1653 lomac_pipe_relabel(struct ucred *cred, struct pipepair *pp,
 1654     struct label *pplabel, struct label *newlabel)
 1655 {
 1656         struct mac_lomac *source, *dest;
 1657 
 1658         source = SLOT(newlabel);
 1659         dest = SLOT(pplabel);
 1660 
 1661         try_relabel(source, dest);
 1662 }
 1663 
 1664 /*
 1665  * Some system privileges are allowed regardless of integrity grade; others
 1666  * are allowed only when running with privilege with respect to the LOMAC 
 1667  * policy as they might otherwise allow bypassing of the integrity policy.
 1668  */
 1669 static int
 1670 lomac_priv_check(struct ucred *cred, int priv)
 1671 {
 1672         struct mac_lomac *subj;
 1673         int error;
 1674 
 1675         if (!lomac_enabled)
 1676                 return (0);
 1677 
 1678         /*
 1679          * Exempt only specific privileges from the LOMAC integrity policy.
 1680          */
 1681         switch (priv) {
 1682         case PRIV_KTRACE:
 1683         case PRIV_MSGBUF:
 1684 
 1685         /*
 1686          * Allow processes to manipulate basic process audit properties, and
 1687          * to submit audit records.
 1688          */
 1689         case PRIV_AUDIT_GETAUDIT:
 1690         case PRIV_AUDIT_SETAUDIT:
 1691         case PRIV_AUDIT_SUBMIT:
 1692 
 1693         /*
 1694          * Allow processes to manipulate their regular UNIX credentials.
 1695          */
 1696         case PRIV_CRED_SETUID:
 1697         case PRIV_CRED_SETEUID:
 1698         case PRIV_CRED_SETGID:
 1699         case PRIV_CRED_SETEGID:
 1700         case PRIV_CRED_SETGROUPS:
 1701         case PRIV_CRED_SETREUID:
 1702         case PRIV_CRED_SETREGID:
 1703         case PRIV_CRED_SETRESUID:
 1704         case PRIV_CRED_SETRESGID:
 1705 
 1706         /*
 1707          * Allow processes to perform system monitoring.
 1708          */
 1709         case PRIV_SEEOTHERGIDS:
 1710         case PRIV_SEEOTHERUIDS:
 1711                 break;
 1712 
 1713         /*
 1714          * Allow access to general process debugging facilities.  We
 1715          * separately control debugging based on MAC label.
 1716          */
 1717         case PRIV_DEBUG_DIFFCRED:
 1718         case PRIV_DEBUG_SUGID:
 1719         case PRIV_DEBUG_UNPRIV:
 1720 
 1721         /*
 1722          * Allow manipulating jails.
 1723          */
 1724         case PRIV_JAIL_ATTACH:
 1725 
 1726         /*
 1727          * Allow privilege with respect to the Partition policy, but not the
 1728          * Privs policy.
 1729          */
 1730         case PRIV_MAC_PARTITION:
 1731 
 1732         /*
 1733          * Allow privilege with respect to process resource limits and login
 1734          * context.
 1735          */
 1736         case PRIV_PROC_LIMIT:
 1737         case PRIV_PROC_SETLOGIN:
 1738         case PRIV_PROC_SETRLIMIT:
 1739 
 1740         /*
 1741          * Allow System V and POSIX IPC privileges.
 1742          */
 1743         case PRIV_IPC_READ:
 1744         case PRIV_IPC_WRITE:
 1745         case PRIV_IPC_ADMIN:
 1746         case PRIV_IPC_MSGSIZE:
 1747         case PRIV_MQ_ADMIN:
 1748 
 1749         /*
 1750          * Allow certain scheduler manipulations -- possibly this should be
 1751          * controlled by more fine-grained policy, as potentially low
 1752          * integrity processes can deny CPU to higher integrity ones.
 1753          */
 1754         case PRIV_SCHED_DIFFCRED:
 1755         case PRIV_SCHED_SETPRIORITY:
 1756         case PRIV_SCHED_RTPRIO:
 1757         case PRIV_SCHED_SETPOLICY:
 1758         case PRIV_SCHED_SET:
 1759         case PRIV_SCHED_SETPARAM:
 1760 
 1761         /*
 1762          * More IPC privileges.
 1763          */
 1764         case PRIV_SEM_WRITE:
 1765 
 1766         /*
 1767          * Allow signaling privileges subject to integrity policy.
 1768          */
 1769         case PRIV_SIGNAL_DIFFCRED:
 1770         case PRIV_SIGNAL_SUGID:
 1771 
 1772         /*
 1773          * Allow access to only limited sysctls from lower integrity levels;
 1774          * piggy-back on the Jail definition.
 1775          */
 1776         case PRIV_SYSCTL_WRITEJAIL:
 1777 
 1778         /*
 1779          * Allow TTY-based privileges, subject to general device access using
 1780          * labels on TTY device nodes, but not console privilege.
 1781          */
 1782         case PRIV_TTY_DRAINWAIT:
 1783         case PRIV_TTY_DTRWAIT:
 1784         case PRIV_TTY_EXCLUSIVE:
 1785         case PRIV_TTY_STI:
 1786         case PRIV_TTY_SETA:
 1787 
 1788         /*
 1789          * Grant most VFS privileges, as almost all are in practice bounded
 1790          * by more specific checks using labels.
 1791          */
 1792         case PRIV_VFS_READ:
 1793         case PRIV_VFS_WRITE:
 1794         case PRIV_VFS_ADMIN:
 1795         case PRIV_VFS_EXEC:
 1796         case PRIV_VFS_LOOKUP:
 1797         case PRIV_VFS_CHFLAGS_DEV:
 1798         case PRIV_VFS_CHOWN:
 1799         case PRIV_VFS_CHROOT:
 1800         case PRIV_VFS_RETAINSUGID:
 1801         case PRIV_VFS_EXCEEDQUOTA:
 1802         case PRIV_VFS_FCHROOT:
 1803         case PRIV_VFS_FHOPEN:
 1804         case PRIV_VFS_FHSTATFS:
 1805         case PRIV_VFS_GENERATION:
 1806         case PRIV_VFS_GETFH:
 1807         case PRIV_VFS_GETQUOTA:
 1808         case PRIV_VFS_LINK:
 1809         case PRIV_VFS_MOUNT:
 1810         case PRIV_VFS_MOUNT_OWNER:
 1811         case PRIV_VFS_MOUNT_PERM:
 1812         case PRIV_VFS_MOUNT_SUIDDIR:
 1813         case PRIV_VFS_MOUNT_NONUSER:
 1814         case PRIV_VFS_SETGID:
 1815         case PRIV_VFS_STICKYFILE:
 1816         case PRIV_VFS_SYSFLAGS:
 1817         case PRIV_VFS_UNMOUNT:
 1818 
 1819         /*
 1820          * Allow VM privileges; it would be nice if these were subject to
 1821          * resource limits.
 1822          */
 1823         case PRIV_VM_MADV_PROTECT:
 1824         case PRIV_VM_MLOCK:
 1825         case PRIV_VM_MUNLOCK:
 1826         case PRIV_VM_SWAP_NOQUOTA:
 1827         case PRIV_VM_SWAP_NORLIMIT:
 1828 
 1829         /*
 1830          * Allow some but not all network privileges.  In general, dont allow
 1831          * reconfiguring the network stack, just normal use.
 1832          */
 1833         case PRIV_NETATALK_RESERVEDPORT:
 1834         case PRIV_NETINET_RESERVEDPORT:
 1835         case PRIV_NETINET_RAW:
 1836         case PRIV_NETINET_REUSEPORT:
 1837         case PRIV_NETIPX_RESERVEDPORT:
 1838         case PRIV_NETIPX_RAW:
 1839                 break;
 1840 
 1841         /*
 1842          * All remaining system privileges are allow only if the process
 1843          * holds privilege with respect to the LOMAC policy.
 1844          */
 1845         default:
 1846                 subj = SLOT(cred->cr_label);
 1847                 error = lomac_subject_privileged(subj);
 1848                 if (error)
 1849                         return (error);
 1850         }
 1851         return (0);
 1852 }
 1853 
 1854 static int
 1855 lomac_proc_check_debug(struct ucred *cred, struct proc *p)
 1856 {
 1857         struct mac_lomac *subj, *obj;
 1858 
 1859         if (!lomac_enabled)
 1860                 return (0);
 1861 
 1862         subj = SLOT(cred->cr_label);
 1863         obj = SLOT(p->p_ucred->cr_label);
 1864 
 1865         /* XXX: range checks */
 1866         if (!lomac_dominate_single(obj, subj))
 1867                 return (ESRCH);
 1868         if (!lomac_subject_dominate(subj, obj))
 1869                 return (EACCES);
 1870 
 1871         return (0);
 1872 }
 1873 
 1874 static int
 1875 lomac_proc_check_sched(struct ucred *cred, struct proc *p)
 1876 {
 1877         struct mac_lomac *subj, *obj;
 1878 
 1879         if (!lomac_enabled)
 1880                 return (0);
 1881 
 1882         subj = SLOT(cred->cr_label);
 1883         obj = SLOT(p->p_ucred->cr_label);
 1884 
 1885         /* XXX: range checks */
 1886         if (!lomac_dominate_single(obj, subj))
 1887                 return (ESRCH);
 1888         if (!lomac_subject_dominate(subj, obj))
 1889                 return (EACCES);
 1890 
 1891         return (0);
 1892 }
 1893 
 1894 static int
 1895 lomac_proc_check_signal(struct ucred *cred, struct proc *p, int signum)
 1896 {
 1897         struct mac_lomac *subj, *obj;
 1898 
 1899         if (!lomac_enabled)
 1900                 return (0);
 1901 
 1902         subj = SLOT(cred->cr_label);
 1903         obj = SLOT(p->p_ucred->cr_label);
 1904 
 1905         /* XXX: range checks */
 1906         if (!lomac_dominate_single(obj, subj))
 1907                 return (ESRCH);
 1908         if (!lomac_subject_dominate(subj, obj))
 1909                 return (EACCES);
 1910 
 1911         return (0);
 1912 }
 1913 
 1914 static void
 1915 lomac_proc_destroy_label(struct label *label)
 1916 {
 1917 
 1918         mtx_destroy(&PSLOT(label)->mtx);
 1919         free(PSLOT(label), M_LOMAC);
 1920         PSLOT_SET(label, NULL);
 1921 }
 1922 
 1923 static void
 1924 lomac_proc_init_label(struct label *label)
 1925 {
 1926 
 1927         PSLOT_SET(label, malloc(sizeof(struct mac_lomac_proc), M_LOMAC,
 1928             M_ZERO | M_WAITOK));
 1929         mtx_init(&PSLOT(label)->mtx, "MAC/Lomac proc lock", NULL, MTX_DEF);
 1930 }
 1931 
 1932 static int
 1933 lomac_socket_check_deliver(struct socket *so, struct label *solabel,
 1934     struct mbuf *m, struct label *mlabel)
 1935 {
 1936         struct mac_lomac *p, *s;
 1937         int error;
 1938 
 1939         if (!lomac_enabled)
 1940                 return (0);
 1941 
 1942         p = SLOT(mlabel);
 1943         s = SLOT(solabel);
 1944 
 1945         SOCK_LOCK(so);
 1946         error = lomac_equal_single(p, s) ? 0 : EACCES;
 1947         SOCK_UNLOCK(so);
 1948         return (error);
 1949 }
 1950 
 1951 static int
 1952 lomac_socket_check_relabel(struct ucred *cred, struct socket *so,
 1953     struct label *solabel, struct label *newlabel)
 1954 {
 1955         struct mac_lomac *subj, *obj, *new;
 1956         int error;
 1957 
 1958         SOCK_LOCK_ASSERT(so);
 1959 
 1960         new = SLOT(newlabel);
 1961         subj = SLOT(cred->cr_label);
 1962         obj = SLOT(solabel);
 1963 
 1964         /*
 1965          * If there is a LOMAC label update for the socket, it may be an
 1966          * update of single.
 1967          */
 1968         error = lomac_atmostflags(new, MAC_LOMAC_FLAG_SINGLE);
 1969         if (error)
 1970                 return (error);
 1971 
 1972         /*
 1973          * To relabel a socket, the old socket single must be in the subject
 1974          * range.
 1975          */
 1976         if (!lomac_single_in_range(obj, subj))
 1977                 return (EPERM);
 1978 
 1979         /*
 1980          * If the LOMAC label is to be changed, authorize as appropriate.
 1981          */
 1982         if (new->ml_flags & MAC_LOMAC_FLAG_SINGLE) {
 1983                 /*
 1984                  * To relabel a socket, the new socket single must be in the
 1985                  * subject range.
 1986                  */
 1987                 if (!lomac_single_in_range(new, subj))
 1988                         return (EPERM);
 1989 
 1990                 /*
 1991                  * To change the LOMAC label on the socket to contain EQUAL,
 1992                  * the subject must have appropriate privilege.
 1993                  */
 1994                 if (lomac_contains_equal(new)) {
 1995                         error = lomac_subject_privileged(subj);
 1996                         if (error)
 1997                                 return (error);
 1998                 }
 1999         }
 2000 
 2001         return (0);
 2002 }
 2003 
 2004 static int
 2005 lomac_socket_check_visible(struct ucred *cred, struct socket *so,
 2006     struct label *solabel)
 2007 {
 2008         struct mac_lomac *subj, *obj;
 2009 
 2010         if (!lomac_enabled)
 2011                 return (0);
 2012 
 2013         subj = SLOT(cred->cr_label);
 2014         obj = SLOT(solabel);
 2015 
 2016         SOCK_LOCK(so);
 2017         if (!lomac_dominate_single(obj, subj)) {
 2018                 SOCK_UNLOCK(so);
 2019                 return (ENOENT);
 2020         }
 2021         SOCK_UNLOCK(so);
 2022 
 2023         return (0);
 2024 }
 2025 
 2026 static void
 2027 lomac_socket_create(struct ucred *cred, struct socket *so,
 2028     struct label *solabel)
 2029 {
 2030         struct mac_lomac *source, *dest;
 2031 
 2032         source = SLOT(cred->cr_label);
 2033         dest = SLOT(solabel);
 2034 
 2035         lomac_copy_single(source, dest);
 2036 }
 2037 
 2038 static void
 2039 lomac_socket_create_mbuf(struct socket *so, struct label *solabel,
 2040     struct mbuf *m, struct label *mlabel)
 2041 {
 2042         struct mac_lomac *source, *dest;
 2043 
 2044         source = SLOT(solabel);
 2045         dest = SLOT(mlabel);
 2046 
 2047         SOCK_LOCK(so);
 2048         lomac_copy_single(source, dest);
 2049         SOCK_UNLOCK(so);
 2050 }
 2051 
 2052 static void
 2053 lomac_socket_newconn(struct socket *oldso, struct label *oldsolabel,
 2054     struct socket *newso, struct label *newsolabel)
 2055 {
 2056         struct mac_lomac source, *dest;
 2057 
 2058         SOCK_LOCK(oldso);
 2059         source = *SLOT(oldsolabel);
 2060         SOCK_UNLOCK(oldso);
 2061 
 2062         dest = SLOT(newsolabel);
 2063 
 2064         SOCK_LOCK(newso);
 2065         lomac_copy_single(&source, dest);
 2066         SOCK_UNLOCK(newso);
 2067 }
 2068 
 2069 static void
 2070 lomac_socket_relabel(struct ucred *cred, struct socket *so,
 2071     struct label *solabel, struct label *newlabel)
 2072 {
 2073         struct mac_lomac *source, *dest;
 2074 
 2075         SOCK_LOCK_ASSERT(so);
 2076 
 2077         source = SLOT(newlabel);
 2078         dest = SLOT(solabel);
 2079 
 2080         try_relabel(source, dest);
 2081 }
 2082 
 2083 static void
 2084 lomac_socketpeer_set_from_mbuf(struct mbuf *m, struct label *mlabel,
 2085     struct socket *so, struct label *sopeerlabel)
 2086 {
 2087         struct mac_lomac *source, *dest;
 2088 
 2089         source = SLOT(mlabel);
 2090         dest = SLOT(sopeerlabel);
 2091 
 2092         SOCK_LOCK(so);
 2093         lomac_copy_single(source, dest);
 2094         SOCK_UNLOCK(so);
 2095 }
 2096 
 2097 static void
 2098 lomac_socketpeer_set_from_socket(struct socket *oldso,
 2099     struct label *oldsolabel, struct socket *newso,
 2100     struct label *newsopeerlabel)
 2101 {
 2102         struct mac_lomac source, *dest;
 2103 
 2104         SOCK_LOCK(oldso);
 2105         source = *SLOT(oldsolabel);
 2106         SOCK_UNLOCK(oldso);
 2107 
 2108         dest = SLOT(newsopeerlabel);
 2109 
 2110         SOCK_LOCK(newso);
 2111         lomac_copy_single(&source, dest);
 2112         SOCK_UNLOCK(newso);
 2113 }
 2114 
 2115 static void
 2116 lomac_syncache_create(struct label *label, struct inpcb *inp)
 2117 {
 2118         struct mac_lomac *source, *dest;
 2119 
 2120         source = SLOT(inp->inp_label);
 2121         dest = SLOT(label);
 2122         lomac_copy(source, dest);
 2123 }
 2124 
 2125 static void
 2126 lomac_syncache_create_mbuf(struct label *sc_label, struct mbuf *m,
 2127     struct label *mlabel)
 2128 {
 2129         struct mac_lomac *source, *dest;
 2130 
 2131         source = SLOT(sc_label);
 2132         dest = SLOT(mlabel);
 2133         lomac_copy(source, dest);
 2134 }
 2135 
 2136 static int
 2137 lomac_system_check_acct(struct ucred *cred, struct vnode *vp,
 2138     struct label *vplabel)
 2139 {
 2140         struct mac_lomac *subj, *obj;
 2141 
 2142         if (!lomac_enabled)
 2143                 return (0);
 2144 
 2145         subj = SLOT(cred->cr_label);
 2146         obj = SLOT(vplabel);
 2147 
 2148         if (lomac_subject_privileged(subj))
 2149                 return (EPERM);
 2150 
 2151         if (!lomac_high_single(obj))
 2152                 return (EACCES);
 2153 
 2154         return (0);
 2155 }
 2156 
 2157 static int
 2158 lomac_system_check_auditctl(struct ucred *cred, struct vnode *vp,
 2159     struct label *vplabel)
 2160 {
 2161         struct mac_lomac *subj, *obj;
 2162 
 2163         if (!lomac_enabled)
 2164                 return (0);
 2165 
 2166         subj = SLOT(cred->cr_label);
 2167         obj = SLOT(vplabel);
 2168 
 2169         if (lomac_subject_privileged(subj))
 2170                 return (EPERM);
 2171 
 2172         if (!lomac_high_single(obj))
 2173                 return (EACCES);
 2174 
 2175         return (0);
 2176 }
 2177 
 2178 static int
 2179 lomac_system_check_swapoff(struct ucred *cred, struct vnode *vp,
 2180     struct label *vplabel)
 2181 {
 2182         struct mac_lomac *subj;
 2183 
 2184         if (!lomac_enabled)
 2185                 return (0);
 2186 
 2187         subj = SLOT(cred->cr_label);
 2188 
 2189         if (lomac_subject_privileged(subj))
 2190                 return (EPERM);
 2191 
 2192         return (0);
 2193 }
 2194 
 2195 static int
 2196 lomac_system_check_swapon(struct ucred *cred, struct vnode *vp,
 2197     struct label *vplabel)
 2198 {
 2199         struct mac_lomac *subj, *obj;
 2200 
 2201         if (!lomac_enabled)
 2202                 return (0);
 2203 
 2204         subj = SLOT(cred->cr_label);
 2205         obj = SLOT(vplabel);
 2206 
 2207         if (lomac_subject_privileged(subj))
 2208                 return (EPERM);
 2209 
 2210         if (!lomac_high_single(obj))
 2211                 return (EACCES);
 2212 
 2213         return (0);
 2214 }
 2215 
 2216 static int
 2217 lomac_system_check_sysctl(struct ucred *cred, struct sysctl_oid *oidp,
 2218     void *arg1, int arg2, struct sysctl_req *req)
 2219 {
 2220         struct mac_lomac *subj;
 2221 
 2222         if (!lomac_enabled)
 2223                 return (0);
 2224 
 2225         subj = SLOT(cred->cr_label);
 2226 
 2227         /*
 2228          * Treat sysctl variables without CTLFLAG_ANYBODY flag as lomac/high,
 2229          * but also require privilege to change them.
 2230          */
 2231         if (req->newptr != NULL && (oidp->oid_kind & CTLFLAG_ANYBODY) == 0) {
 2232 #ifdef notdef
 2233                 if (!lomac_subject_dominate_high(subj))
 2234                         return (EACCES);
 2235 #endif
 2236 
 2237                 if (lomac_subject_privileged(subj))
 2238                         return (EPERM);
 2239         }
 2240 
 2241         return (0);
 2242 }
 2243 
 2244 static void
 2245 lomac_thread_userret(struct thread *td)
 2246 {
 2247         struct proc *p = td->td_proc;
 2248         struct mac_lomac_proc *subj = PSLOT(p->p_label);
 2249         struct ucred *newcred, *oldcred;
 2250         int dodrop;
 2251 
 2252         mtx_lock(&subj->mtx);
 2253         if (subj->mac_lomac.ml_flags & MAC_LOMAC_FLAG_UPDATE) {
 2254                 dodrop = 0;
 2255                 mtx_unlock(&subj->mtx);
 2256                 newcred = crget();
 2257                 /*
 2258                  * Prevent a lock order reversal in mac_proc_vm_revoke;
 2259                  * ideally, the other user of subj->mtx wouldn't be holding
 2260                  * Giant.
 2261                  */
 2262                 mtx_lock(&Giant);
 2263                 PROC_LOCK(p);
 2264                 mtx_lock(&subj->mtx);
 2265                 /*
 2266                  * Check if we lost the race while allocating the cred.
 2267                  */
 2268                 if ((subj->mac_lomac.ml_flags & MAC_LOMAC_FLAG_UPDATE) == 0) {
 2269                         crfree(newcred);
 2270                         goto out;
 2271                 }
 2272                 oldcred = p->p_ucred;
 2273                 crcopy(newcred, oldcred);
 2274                 crhold(newcred);
 2275                 lomac_copy(&subj->mac_lomac, SLOT(newcred->cr_label));
 2276                 p->p_ucred = newcred;
 2277                 crfree(oldcred);
 2278                 dodrop = 1;
 2279         out:
 2280                 mtx_unlock(&subj->mtx);
 2281                 PROC_UNLOCK(p);
 2282                 if (dodrop)
 2283                         mac_proc_vm_revoke(curthread);
 2284                 mtx_unlock(&Giant);
 2285         } else {
 2286                 mtx_unlock(&subj->mtx);
 2287         }
 2288 }
 2289 
 2290 static int
 2291 lomac_vnode_associate_extattr(struct mount *mp, struct label *mplabel,
 2292     struct vnode *vp, struct label *vplabel)
 2293 {
 2294         struct mac_lomac ml_temp, *source, *dest;
 2295         int buflen, error;
 2296 
 2297         source = SLOT(mplabel);
 2298         dest = SLOT(vplabel);
 2299 
 2300         buflen = sizeof(ml_temp);
 2301         bzero(&ml_temp, buflen);
 2302 
 2303         error = vn_extattr_get(vp, IO_NODELOCKED, MAC_LOMAC_EXTATTR_NAMESPACE,
 2304             MAC_LOMAC_EXTATTR_NAME, &buflen, (char *)&ml_temp, curthread);
 2305         if (error == ENOATTR || error == EOPNOTSUPP) {
 2306                 /* Fall back to the mntlabel. */
 2307                 lomac_copy_single(source, dest);
 2308                 return (0);
 2309         } else if (error)
 2310                 return (error);
 2311 
 2312         if (buflen != sizeof(ml_temp)) {
 2313                 if (buflen != sizeof(ml_temp) - sizeof(ml_temp.ml_auxsingle)) {
 2314                         printf("lomac_vnode_associate_extattr: bad size %d\n",
 2315                             buflen);
 2316                         return (EPERM);
 2317                 }
 2318                 bzero(&ml_temp.ml_auxsingle, sizeof(ml_temp.ml_auxsingle));
 2319                 buflen = sizeof(ml_temp);
 2320                 (void)vn_extattr_set(vp, IO_NODELOCKED,
 2321                     MAC_LOMAC_EXTATTR_NAMESPACE, MAC_LOMAC_EXTATTR_NAME,
 2322                     buflen, (char *)&ml_temp, curthread);
 2323         }
 2324         if (lomac_valid(&ml_temp) != 0) {
 2325                 printf("lomac_vnode_associate_extattr: invalid\n");
 2326                 return (EPERM);
 2327         }
 2328         if ((ml_temp.ml_flags & MAC_LOMAC_FLAGS_BOTH) !=
 2329             MAC_LOMAC_FLAG_SINGLE) {
 2330                 printf("lomac_vnode_associate_extattr: not single\n");
 2331                 return (EPERM);
 2332         }
 2333 
 2334         lomac_copy_single(&ml_temp, dest);
 2335         return (0);
 2336 }
 2337 
 2338 static void
 2339 lomac_vnode_associate_singlelabel(struct mount *mp, struct label *mplabel,
 2340     struct vnode *vp, struct label *vplabel)
 2341 {
 2342         struct mac_lomac *source, *dest;
 2343 
 2344         source = SLOT(mplabel);
 2345         dest = SLOT(vplabel);
 2346 
 2347         lomac_copy_single(source, dest);
 2348 }
 2349 
 2350 static int
 2351 lomac_vnode_check_create(struct ucred *cred, struct vnode *dvp,
 2352     struct label *dvplabel, struct componentname *cnp, struct vattr *vap)
 2353 {
 2354         struct mac_lomac *subj, *obj;
 2355 
 2356         if (!lomac_enabled)
 2357                 return (0);
 2358 
 2359         subj = SLOT(cred->cr_label);
 2360         obj = SLOT(dvplabel);
 2361 
 2362         if (!lomac_subject_dominate(subj, obj))
 2363                 return (EACCES);
 2364         if (obj->ml_flags & MAC_LOMAC_FLAG_AUX &&
 2365             !lomac_dominate_element(&subj->ml_single, &obj->ml_auxsingle))
 2366                 return (EACCES);
 2367 
 2368         return (0);
 2369 }
 2370 
 2371 static int
 2372 lomac_vnode_check_deleteacl(struct ucred *cred, struct vnode *vp,
 2373     struct label *vplabel, acl_type_t type)
 2374 {
 2375         struct mac_lomac *subj, *obj;
 2376 
 2377         if (!lomac_enabled)
 2378                 return (0);
 2379 
 2380         subj = SLOT(cred->cr_label);
 2381         obj = SLOT(vplabel);
 2382 
 2383         if (!lomac_subject_dominate(subj, obj))
 2384                 return (EACCES);
 2385 
 2386         return (0);
 2387 }
 2388 
 2389 static int
 2390 lomac_vnode_check_link(struct ucred *cred, struct vnode *dvp,
 2391     struct label *dvplabel, struct vnode *vp, struct label *vplabel,
 2392     struct componentname *cnp)
 2393 {
 2394         struct mac_lomac *subj, *obj;
 2395 
 2396         if (!lomac_enabled)
 2397                 return (0);
 2398 
 2399         subj = SLOT(cred->cr_label);
 2400         obj = SLOT(dvplabel);
 2401 
 2402         if (!lomac_subject_dominate(subj, obj))
 2403                 return (EACCES);
 2404 
 2405         obj = SLOT(vplabel);
 2406 
 2407         if (!lomac_subject_dominate(subj, obj))
 2408                 return (EACCES);
 2409 
 2410         return (0);
 2411 }
 2412 
 2413 static int
 2414 lomac_vnode_check_mmap(struct ucred *cred, struct vnode *vp,
 2415     struct label *vplabel, int prot, int flags)
 2416 {
 2417         struct mac_lomac *subj, *obj;
 2418 
 2419         /*
 2420          * Rely on the use of open()-time protections to handle
 2421          * non-revocation cases.
 2422          */
 2423         if (!lomac_enabled)
 2424                 return (0);
 2425 
 2426         subj = SLOT(cred->cr_label);
 2427         obj = SLOT(vplabel);
 2428 
 2429         if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) {
 2430                 if (!lomac_subject_dominate(subj, obj))
 2431                         return (EACCES);
 2432         }
 2433         if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
 2434                 if (!lomac_dominate_single(obj, subj))
 2435                         return (maybe_demote(subj, obj, "mapping", "file", vp));
 2436         }
 2437 
 2438         return (0);
 2439 }
 2440 
 2441 static void
 2442 lomac_vnode_check_mmap_downgrade(struct ucred *cred, struct vnode *vp,
 2443     struct label *vplabel, /* XXX vm_prot_t */ int *prot)
 2444 {
 2445         struct mac_lomac *subj, *obj;
 2446 
 2447         /*
 2448          * Rely on the use of open()-time protections to handle
 2449          * non-revocation cases.
 2450          */
 2451         if (!lomac_enabled || !revocation_enabled)
 2452                 return;
 2453 
 2454         subj = SLOT(cred->cr_label);
 2455         obj = SLOT(vplabel);
 2456 
 2457         if (!lomac_subject_dominate(subj, obj))
 2458                 *prot &= ~VM_PROT_WRITE;
 2459 }
 2460 
 2461 static int
 2462 lomac_vnode_check_open(struct ucred *cred, struct vnode *vp,
 2463     struct label *vplabel, accmode_t accmode)
 2464 {
 2465         struct mac_lomac *subj, *obj;
 2466 
 2467         if (!lomac_enabled)
 2468                 return (0);
 2469 
 2470         subj = SLOT(cred->cr_label);
 2471         obj = SLOT(vplabel);
 2472 
 2473         /* XXX privilege override for admin? */
 2474         if (accmode & VMODIFY_PERMS) {
 2475                 if (!lomac_subject_dominate(subj, obj))
 2476                         return (EACCES);
 2477         }
 2478 
 2479         return (0);
 2480 }
 2481 
 2482 static int
 2483 lomac_vnode_check_read(struct ucred *active_cred, struct ucred *file_cred,
 2484     struct vnode *vp, struct label *vplabel)
 2485 {
 2486         struct mac_lomac *subj, *obj;
 2487 
 2488         if (!lomac_enabled || !revocation_enabled)
 2489                 return (0);
 2490 
 2491         subj = SLOT(active_cred->cr_label);
 2492         obj = SLOT(vplabel);
 2493 
 2494         if (!lomac_dominate_single(obj, subj))
 2495                 return (maybe_demote(subj, obj, "reading", "file", vp));
 2496 
 2497         return (0);
 2498 }
 2499 
 2500 static int
 2501 lomac_vnode_check_relabel(struct ucred *cred, struct vnode *vp,
 2502     struct label *vplabel, struct label *newlabel)
 2503 {
 2504         struct mac_lomac *old, *new, *subj;
 2505         int error;
 2506 
 2507         old = SLOT(vplabel);
 2508         new = SLOT(newlabel);
 2509         subj = SLOT(cred->cr_label);
 2510 
 2511         /*
 2512          * If there is a LOMAC label update for the vnode, it must be a
 2513          * single label, with an optional explicit auxiliary single.
 2514          */
 2515         error = lomac_atmostflags(new,
 2516             MAC_LOMAC_FLAG_SINGLE | MAC_LOMAC_FLAG_AUX);
 2517         if (error)
 2518                 return (error);
 2519 
 2520         /*
 2521          * To perform a relabel of the vnode (LOMAC label or not), LOMAC must
 2522          * authorize the relabel.
 2523          */
 2524         if (!lomac_single_in_range(old, subj))
 2525                 return (EPERM);
 2526 
 2527         /*
 2528          * If the LOMAC label is to be changed, authorize as appropriate.
 2529          */
 2530         if (new->ml_flags & MAC_LOMAC_FLAG_SINGLE) {
 2531                 /*
 2532                  * To change the LOMAC label on a vnode, the new vnode label
 2533                  * must be in the subject range.
 2534                  */
 2535                 if (!lomac_single_in_range(new, subj))
 2536                         return (EPERM);
 2537 
 2538                 /*
 2539                  * To change the LOMAC label on the vnode to be EQUAL, the
 2540                  * subject must have appropriate privilege.
 2541                  */
 2542                 if (lomac_contains_equal(new)) {
 2543                         error = lomac_subject_privileged(subj);
 2544                         if (error)
 2545                                 return (error);
 2546                 }
 2547         }
 2548         if (new->ml_flags & MAC_LOMAC_FLAG_AUX) {
 2549                 /*
 2550                  * Fill in the missing parts from the previous label.
 2551                  */
 2552                 if ((new->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0)
 2553                         lomac_copy_single(subj, new);
 2554 
 2555                 /*
 2556                  * To change the auxiliary LOMAC label on a vnode, the new
 2557                  * vnode label must be in the subject range.
 2558                  */
 2559                 if (!lomac_auxsingle_in_range(new, subj))
 2560                         return (EPERM);
 2561 
 2562                 /*
 2563                  * To change the auxiliary LOMAC label on the vnode to be
 2564                  * EQUAL, the subject must have appropriate privilege.
 2565                  */
 2566                 if (lomac_contains_equal(new)) {
 2567                         error = lomac_subject_privileged(subj);
 2568                         if (error)
 2569                                 return (error);
 2570                 }
 2571         }
 2572 
 2573         return (0);
 2574 }
 2575 
 2576 static int
 2577 lomac_vnode_check_rename_from(struct ucred *cred, struct vnode *dvp,
 2578     struct label *dvplabel, struct vnode *vp, struct label *vplabel,
 2579     struct componentname *cnp)
 2580 {
 2581         struct mac_lomac *subj, *obj;
 2582 
 2583         if (!lomac_enabled)
 2584                 return (0);
 2585 
 2586         subj = SLOT(cred->cr_label);
 2587         obj = SLOT(dvplabel);
 2588 
 2589         if (!lomac_subject_dominate(subj, obj))
 2590                 return (EACCES);
 2591 
 2592         obj = SLOT(vplabel);
 2593 
 2594         if (!lomac_subject_dominate(subj, obj))
 2595                 return (EACCES);
 2596 
 2597         return (0);
 2598 }
 2599 
 2600 static int
 2601 lomac_vnode_check_rename_to(struct ucred *cred, struct vnode *dvp,
 2602     struct label *dvplabel, struct vnode *vp, struct label *vplabel,
 2603     int samedir, struct componentname *cnp)
 2604 {
 2605         struct mac_lomac *subj, *obj;
 2606 
 2607         if (!lomac_enabled)
 2608                 return (0);
 2609 
 2610         subj = SLOT(cred->cr_label);
 2611         obj = SLOT(dvplabel);
 2612 
 2613         if (!lomac_subject_dominate(subj, obj))
 2614                 return (EACCES);
 2615 
 2616         if (vp != NULL) {
 2617                 obj = SLOT(vplabel);
 2618 
 2619                 if (!lomac_subject_dominate(subj, obj))
 2620                         return (EACCES);
 2621         }
 2622 
 2623         return (0);
 2624 }
 2625 
 2626 static int
 2627 lomac_vnode_check_revoke(struct ucred *cred, struct vnode *vp,
 2628     struct label *vplabel)
 2629 {
 2630         struct mac_lomac *subj, *obj;
 2631 
 2632         if (!lomac_enabled)
 2633                 return (0);
 2634 
 2635         subj = SLOT(cred->cr_label);
 2636         obj = SLOT(vplabel);
 2637 
 2638         if (!lomac_subject_dominate(subj, obj))
 2639                 return (EACCES);
 2640 
 2641         return (0);
 2642 }
 2643 
 2644 static int
 2645 lomac_vnode_check_setacl(struct ucred *cred, struct vnode *vp,
 2646     struct label *vplabel, acl_type_t type, struct acl *acl)
 2647 {
 2648         struct mac_lomac *subj, *obj;
 2649 
 2650         if (!lomac_enabled)
 2651                 return (0);
 2652 
 2653         subj = SLOT(cred->cr_label);
 2654         obj = SLOT(vplabel);
 2655 
 2656         if (!lomac_subject_dominate(subj, obj))
 2657                 return (EACCES);
 2658 
 2659         return (0);
 2660 }
 2661 
 2662 static int
 2663 lomac_vnode_check_setextattr(struct ucred *cred, struct vnode *vp,
 2664     struct label *vplabel, int attrnamespace, const char *name)
 2665 {
 2666         struct mac_lomac *subj, *obj;
 2667 
 2668         if (!lomac_enabled)
 2669                 return (0);
 2670 
 2671         subj = SLOT(cred->cr_label);
 2672         obj = SLOT(vplabel);
 2673 
 2674         if (!lomac_subject_dominate(subj, obj))
 2675                 return (EACCES);
 2676 
 2677         /* XXX: protect the MAC EA in a special way? */
 2678 
 2679         return (0);
 2680 }
 2681 
 2682 static int
 2683 lomac_vnode_check_setflags(struct ucred *cred, struct vnode *vp,
 2684     struct label *vplabel, u_long flags)
 2685 {
 2686         struct mac_lomac *subj, *obj;
 2687 
 2688         if (!lomac_enabled)
 2689                 return (0);
 2690 
 2691         subj = SLOT(cred->cr_label);
 2692         obj = SLOT(vplabel);
 2693 
 2694         if (!lomac_subject_dominate(subj, obj))
 2695                 return (EACCES);
 2696 
 2697         return (0);
 2698 }
 2699 
 2700 static int
 2701 lomac_vnode_check_setmode(struct ucred *cred, struct vnode *vp,
 2702     struct label *vplabel, mode_t mode)
 2703 {
 2704         struct mac_lomac *subj, *obj;
 2705 
 2706         if (!lomac_enabled)
 2707                 return (0);
 2708 
 2709         subj = SLOT(cred->cr_label);
 2710         obj = SLOT(vplabel);
 2711 
 2712         if (!lomac_subject_dominate(subj, obj))
 2713                 return (EACCES);
 2714 
 2715         return (0);
 2716 }
 2717 
 2718 static int
 2719 lomac_vnode_check_setowner(struct ucred *cred, struct vnode *vp,
 2720     struct label *vplabel, uid_t uid, gid_t gid)
 2721 {
 2722         struct mac_lomac *subj, *obj;
 2723 
 2724         if (!lomac_enabled)
 2725                 return (0);
 2726 
 2727         subj = SLOT(cred->cr_label);
 2728         obj = SLOT(vplabel);
 2729 
 2730         if (!lomac_subject_dominate(subj, obj))
 2731                 return (EACCES);
 2732 
 2733         return (0);
 2734 }
 2735 
 2736 static int
 2737 lomac_vnode_check_setutimes(struct ucred *cred, struct vnode *vp,
 2738     struct label *vplabel, struct timespec atime, struct timespec mtime)
 2739 {
 2740         struct mac_lomac *subj, *obj;
 2741 
 2742         if (!lomac_enabled)
 2743                 return (0);
 2744 
 2745         subj = SLOT(cred->cr_label);
 2746         obj = SLOT(vplabel);
 2747 
 2748         if (!lomac_subject_dominate(subj, obj))
 2749                 return (EACCES);
 2750 
 2751         return (0);
 2752 }
 2753 
 2754 static int
 2755 lomac_vnode_check_unlink(struct ucred *cred, struct vnode *dvp,
 2756     struct label *dvplabel, struct vnode *vp, struct label *vplabel,
 2757     struct componentname *cnp)
 2758 {
 2759         struct mac_lomac *subj, *obj;
 2760 
 2761         if (!lomac_enabled)
 2762                 return (0);
 2763 
 2764         subj = SLOT(cred->cr_label);
 2765         obj = SLOT(dvplabel);
 2766 
 2767         if (!lomac_subject_dominate(subj, obj))
 2768                 return (EACCES);
 2769 
 2770         obj = SLOT(vplabel);
 2771 
 2772         if (!lomac_subject_dominate(subj, obj))
 2773                 return (EACCES);
 2774 
 2775         return (0);
 2776 }
 2777 
 2778 static int
 2779 lomac_vnode_check_write(struct ucred *active_cred,
 2780     struct ucred *file_cred, struct vnode *vp, struct label *vplabel)
 2781 {
 2782         struct mac_lomac *subj, *obj;
 2783 
 2784         if (!lomac_enabled || !revocation_enabled)
 2785                 return (0);
 2786 
 2787         subj = SLOT(active_cred->cr_label);
 2788         obj = SLOT(vplabel);
 2789 
 2790         if (!lomac_subject_dominate(subj, obj))
 2791                 return (EACCES);
 2792 
 2793         return (0);
 2794 }
 2795 
 2796 static int
 2797 lomac_vnode_create_extattr(struct ucred *cred, struct mount *mp,
 2798     struct label *mplabel, struct vnode *dvp, struct label *dvplabel,
 2799     struct vnode *vp, struct label *vplabel, struct componentname *cnp)
 2800 {
 2801         struct mac_lomac *source, *dest, *dir, temp;
 2802         size_t buflen;
 2803         int error;
 2804 
 2805         buflen = sizeof(temp);
 2806         bzero(&temp, buflen);
 2807 
 2808         source = SLOT(cred->cr_label);
 2809         dest = SLOT(vplabel);
 2810         dir = SLOT(dvplabel);
 2811         if (dir->ml_flags & MAC_LOMAC_FLAG_AUX) {
 2812                 lomac_copy_auxsingle(dir, &temp);
 2813                 lomac_set_single(&temp, dir->ml_auxsingle.mle_type,
 2814                     dir->ml_auxsingle.mle_grade);
 2815         } else {
 2816                 lomac_copy_single(source, &temp);
 2817         }
 2818 
 2819         error = vn_extattr_set(vp, IO_NODELOCKED, MAC_LOMAC_EXTATTR_NAMESPACE,
 2820             MAC_LOMAC_EXTATTR_NAME, buflen, (char *)&temp, curthread);
 2821         if (error == 0)
 2822                 lomac_copy(&temp, dest);
 2823         return (error);
 2824 }
 2825 
 2826 static void
 2827 lomac_vnode_execve_transition(struct ucred *old, struct ucred *new,
 2828     struct vnode *vp, struct label *vplabel, struct label *interpvplabel,
 2829     struct image_params *imgp, struct label *execlabel)
 2830 {
 2831         struct mac_lomac *source, *dest, *obj, *robj;
 2832 
 2833         source = SLOT(old->cr_label);
 2834         dest = SLOT(new->cr_label);
 2835         obj = SLOT(vplabel);
 2836         robj = interpvplabel != NULL ? SLOT(interpvplabel) : obj;
 2837 
 2838         lomac_copy(source, dest);
 2839         /*
 2840          * If there's an auxiliary label on the real object, respect it and
 2841          * assume that this level should be assumed immediately if a higher
 2842          * level is currently in place.
 2843          */
 2844         if (robj->ml_flags & MAC_LOMAC_FLAG_AUX &&
 2845             !lomac_dominate_element(&robj->ml_auxsingle, &dest->ml_single)
 2846             && lomac_auxsingle_in_range(robj, dest))
 2847                 lomac_set_single(dest, robj->ml_auxsingle.mle_type,
 2848                     robj->ml_auxsingle.mle_grade);
 2849         /*
 2850          * Restructuring to use the execve transitioning mechanism instead of
 2851          * the normal demotion mechanism here would be difficult, so just
 2852          * copy the label over and perform standard demotion.  This is also
 2853          * non-optimal because it will result in the intermediate label "new"
 2854          * being created and immediately recycled.
 2855          */
 2856         if (lomac_enabled && revocation_enabled &&
 2857             !lomac_dominate_single(obj, source))
 2858                 (void)maybe_demote(source, obj, "executing", "file", vp);
 2859 }
 2860 
 2861 static int
 2862 lomac_vnode_execve_will_transition(struct ucred *old, struct vnode *vp,
 2863     struct label *vplabel, struct label *interpvplabel,
 2864     struct image_params *imgp, struct label *execlabel)
 2865 {
 2866         struct mac_lomac *subj, *obj, *robj;
 2867 
 2868         if (!lomac_enabled || !revocation_enabled)
 2869                 return (0);
 2870 
 2871         subj = SLOT(old->cr_label);
 2872         obj = SLOT(vplabel);
 2873         robj = interpvplabel != NULL ? SLOT(interpvplabel) : obj;
 2874 
 2875         return ((robj->ml_flags & MAC_LOMAC_FLAG_AUX &&
 2876             !lomac_dominate_element(&robj->ml_auxsingle, &subj->ml_single)
 2877             && lomac_auxsingle_in_range(robj, subj)) ||
 2878             !lomac_dominate_single(obj, subj));
 2879 }
 2880 
 2881 static void
 2882 lomac_vnode_relabel(struct ucred *cred, struct vnode *vp,
 2883     struct label *vplabel, struct label *newlabel)
 2884 {
 2885         struct mac_lomac *source, *dest;
 2886 
 2887         source = SLOT(newlabel);
 2888         dest = SLOT(vplabel);
 2889 
 2890         try_relabel(source, dest);
 2891 }
 2892 
 2893 static int
 2894 lomac_vnode_setlabel_extattr(struct ucred *cred, struct vnode *vp,
 2895     struct label *vplabel, struct label *intlabel)
 2896 {
 2897         struct mac_lomac *source, temp;
 2898         size_t buflen;
 2899         int error;
 2900 
 2901         buflen = sizeof(temp);
 2902         bzero(&temp, buflen);
 2903 
 2904         source = SLOT(intlabel);
 2905         if ((source->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0)
 2906                 return (0);
 2907 
 2908         lomac_copy_single(source, &temp);
 2909         error = vn_extattr_set(vp, IO_NODELOCKED, MAC_LOMAC_EXTATTR_NAMESPACE,
 2910             MAC_LOMAC_EXTATTR_NAME, buflen, (char *)&temp, curthread);
 2911         return (error);
 2912 }
 2913 
 2914 static struct mac_policy_ops lomac_ops =
 2915 {
 2916         .mpo_init = lomac_init,
 2917 
 2918         .mpo_bpfdesc_check_receive = lomac_bpfdesc_check_receive,
 2919         .mpo_bpfdesc_create = lomac_bpfdesc_create,
 2920         .mpo_bpfdesc_create_mbuf = lomac_bpfdesc_create_mbuf,
 2921         .mpo_bpfdesc_destroy_label = lomac_destroy_label,
 2922         .mpo_bpfdesc_init_label = lomac_init_label,
 2923 
 2924         .mpo_cred_check_relabel = lomac_cred_check_relabel,
 2925         .mpo_cred_check_visible = lomac_cred_check_visible,
 2926         .mpo_cred_copy_label = lomac_copy_label,
 2927         .mpo_cred_create_swapper = lomac_cred_create_swapper,
 2928         .mpo_cred_create_init = lomac_cred_create_init,
 2929         .mpo_cred_destroy_label = lomac_destroy_label,
 2930         .mpo_cred_externalize_label = lomac_externalize_label,
 2931         .mpo_cred_init_label = lomac_init_label,
 2932         .mpo_cred_internalize_label = lomac_internalize_label,
 2933         .mpo_cred_relabel = lomac_cred_relabel,
 2934 
 2935         .mpo_devfs_create_device = lomac_devfs_create_device,
 2936         .mpo_devfs_create_directory = lomac_devfs_create_directory,
 2937         .mpo_devfs_create_symlink = lomac_devfs_create_symlink,
 2938         .mpo_devfs_destroy_label = lomac_destroy_label,
 2939         .mpo_devfs_init_label = lomac_init_label,
 2940         .mpo_devfs_update = lomac_devfs_update,
 2941         .mpo_devfs_vnode_associate = lomac_devfs_vnode_associate,
 2942 
 2943         .mpo_ifnet_check_relabel = lomac_ifnet_check_relabel,
 2944         .mpo_ifnet_check_transmit = lomac_ifnet_check_transmit,
 2945         .mpo_ifnet_copy_label = lomac_copy_label,
 2946         .mpo_ifnet_create = lomac_ifnet_create,
 2947         .mpo_ifnet_create_mbuf = lomac_ifnet_create_mbuf,
 2948         .mpo_ifnet_destroy_label = lomac_destroy_label,
 2949         .mpo_ifnet_externalize_label = lomac_externalize_label,
 2950         .mpo_ifnet_init_label = lomac_init_label,
 2951         .mpo_ifnet_internalize_label = lomac_internalize_label,
 2952         .mpo_ifnet_relabel = lomac_ifnet_relabel,
 2953 
 2954         .mpo_syncache_create = lomac_syncache_create,
 2955         .mpo_syncache_destroy_label = lomac_destroy_label,
 2956         .mpo_syncache_init_label = lomac_init_label_waitcheck,
 2957 
 2958         .mpo_inpcb_check_deliver = lomac_inpcb_check_deliver,
 2959         .mpo_inpcb_check_visible = lomac_inpcb_check_visible,
 2960         .mpo_inpcb_create = lomac_inpcb_create,
 2961         .mpo_inpcb_create_mbuf = lomac_inpcb_create_mbuf,
 2962         .mpo_inpcb_destroy_label = lomac_destroy_label,
 2963         .mpo_inpcb_init_label = lomac_init_label_waitcheck,
 2964         .mpo_inpcb_sosetlabel = lomac_inpcb_sosetlabel,
 2965 
 2966         .mpo_ip6q_create = lomac_ip6q_create,
 2967         .mpo_ip6q_destroy_label = lomac_destroy_label,
 2968         .mpo_ip6q_init_label = lomac_init_label_waitcheck,
 2969         .mpo_ip6q_match = lomac_ip6q_match,
 2970         .mpo_ip6q_reassemble = lomac_ip6q_reassemble,
 2971         .mpo_ip6q_update = lomac_ip6q_update,
 2972 
 2973         .mpo_ipq_create = lomac_ipq_create,
 2974         .mpo_ipq_destroy_label = lomac_destroy_label,
 2975         .mpo_ipq_init_label = lomac_init_label_waitcheck,
 2976         .mpo_ipq_match = lomac_ipq_match,
 2977         .mpo_ipq_reassemble = lomac_ipq_reassemble,
 2978         .mpo_ipq_update = lomac_ipq_update,
 2979 
 2980         .mpo_kld_check_load = lomac_kld_check_load,
 2981 
 2982         .mpo_mbuf_copy_label = lomac_copy_label,
 2983         .mpo_mbuf_destroy_label = lomac_destroy_label,
 2984         .mpo_mbuf_init_label = lomac_init_label_waitcheck,
 2985 
 2986         .mpo_mount_create = lomac_mount_create,
 2987         .mpo_mount_destroy_label = lomac_destroy_label,
 2988         .mpo_mount_init_label = lomac_init_label,
 2989 
 2990         .mpo_netatalk_aarp_send = lomac_netatalk_aarp_send,
 2991 
 2992         .mpo_netinet_arp_send = lomac_netinet_arp_send,
 2993         .mpo_netinet_firewall_reply = lomac_netinet_firewall_reply,
 2994         .mpo_netinet_firewall_send = lomac_netinet_firewall_send,
 2995         .mpo_netinet_fragment = lomac_netinet_fragment,
 2996         .mpo_netinet_icmp_reply = lomac_netinet_icmp_reply,
 2997         .mpo_netinet_igmp_send = lomac_netinet_igmp_send,
 2998 
 2999         .mpo_netinet6_nd6_send = lomac_netinet6_nd6_send,
 3000 
 3001         .mpo_pipe_check_ioctl = lomac_pipe_check_ioctl,
 3002         .mpo_pipe_check_read = lomac_pipe_check_read,
 3003         .mpo_pipe_check_relabel = lomac_pipe_check_relabel,
 3004         .mpo_pipe_check_write = lomac_pipe_check_write,
 3005         .mpo_pipe_copy_label = lomac_copy_label,
 3006         .mpo_pipe_create = lomac_pipe_create,
 3007         .mpo_pipe_destroy_label = lomac_destroy_label,
 3008         .mpo_pipe_externalize_label = lomac_externalize_label,
 3009         .mpo_pipe_init_label = lomac_init_label,
 3010         .mpo_pipe_internalize_label = lomac_internalize_label,
 3011         .mpo_pipe_relabel = lomac_pipe_relabel,
 3012 
 3013         .mpo_priv_check = lomac_priv_check,
 3014 
 3015         .mpo_proc_check_debug = lomac_proc_check_debug,
 3016         .mpo_proc_check_sched = lomac_proc_check_sched,
 3017         .mpo_proc_check_signal = lomac_proc_check_signal,
 3018         .mpo_proc_destroy_label = lomac_proc_destroy_label,
 3019         .mpo_proc_init_label = lomac_proc_init_label,
 3020 
 3021         .mpo_socket_check_deliver = lomac_socket_check_deliver,
 3022         .mpo_socket_check_relabel = lomac_socket_check_relabel,
 3023         .mpo_socket_check_visible = lomac_socket_check_visible,
 3024         .mpo_socket_copy_label = lomac_copy_label,
 3025         .mpo_socket_create = lomac_socket_create,
 3026         .mpo_socket_create_mbuf = lomac_socket_create_mbuf,
 3027         .mpo_socket_destroy_label = lomac_destroy_label,
 3028         .mpo_socket_externalize_label = lomac_externalize_label,
 3029         .mpo_socket_init_label = lomac_init_label_waitcheck,
 3030         .mpo_socket_internalize_label = lomac_internalize_label,
 3031         .mpo_socket_newconn = lomac_socket_newconn,
 3032         .mpo_socket_relabel = lomac_socket_relabel,
 3033 
 3034         .mpo_socketpeer_destroy_label = lomac_destroy_label,
 3035         .mpo_socketpeer_externalize_label = lomac_externalize_label,
 3036         .mpo_socketpeer_init_label = lomac_init_label_waitcheck,
 3037         .mpo_socketpeer_set_from_mbuf = lomac_socketpeer_set_from_mbuf,
 3038         .mpo_socketpeer_set_from_socket = lomac_socketpeer_set_from_socket,
 3039 
 3040         .mpo_syncache_create_mbuf = lomac_syncache_create_mbuf,
 3041 
 3042         .mpo_system_check_acct = lomac_system_check_acct,
 3043         .mpo_system_check_auditctl = lomac_system_check_auditctl,
 3044         .mpo_system_check_swapoff = lomac_system_check_swapoff,
 3045         .mpo_system_check_swapon = lomac_system_check_swapon,
 3046         .mpo_system_check_sysctl = lomac_system_check_sysctl,
 3047 
 3048         .mpo_thread_userret = lomac_thread_userret,
 3049 
 3050         .mpo_vnode_associate_extattr = lomac_vnode_associate_extattr,
 3051         .mpo_vnode_associate_singlelabel = lomac_vnode_associate_singlelabel,
 3052         .mpo_vnode_check_access = lomac_vnode_check_open,
 3053         .mpo_vnode_check_create = lomac_vnode_check_create,
 3054         .mpo_vnode_check_deleteacl = lomac_vnode_check_deleteacl,
 3055         .mpo_vnode_check_link = lomac_vnode_check_link,
 3056         .mpo_vnode_check_mmap = lomac_vnode_check_mmap,
 3057         .mpo_vnode_check_mmap_downgrade = lomac_vnode_check_mmap_downgrade,
 3058         .mpo_vnode_check_open = lomac_vnode_check_open,
 3059         .mpo_vnode_check_read = lomac_vnode_check_read,
 3060         .mpo_vnode_check_relabel = lomac_vnode_check_relabel,
 3061         .mpo_vnode_check_rename_from = lomac_vnode_check_rename_from,
 3062         .mpo_vnode_check_rename_to = lomac_vnode_check_rename_to,
 3063         .mpo_vnode_check_revoke = lomac_vnode_check_revoke,
 3064         .mpo_vnode_check_setacl = lomac_vnode_check_setacl,
 3065         .mpo_vnode_check_setextattr = lomac_vnode_check_setextattr,
 3066         .mpo_vnode_check_setflags = lomac_vnode_check_setflags,
 3067         .mpo_vnode_check_setmode = lomac_vnode_check_setmode,
 3068         .mpo_vnode_check_setowner = lomac_vnode_check_setowner,
 3069         .mpo_vnode_check_setutimes = lomac_vnode_check_setutimes,
 3070         .mpo_vnode_check_unlink = lomac_vnode_check_unlink,
 3071         .mpo_vnode_check_write = lomac_vnode_check_write,
 3072         .mpo_vnode_copy_label = lomac_copy_label,
 3073         .mpo_vnode_create_extattr = lomac_vnode_create_extattr,
 3074         .mpo_vnode_destroy_label = lomac_destroy_label,
 3075         .mpo_vnode_execve_transition = lomac_vnode_execve_transition,
 3076         .mpo_vnode_execve_will_transition = lomac_vnode_execve_will_transition,
 3077         .mpo_vnode_externalize_label = lomac_externalize_label,
 3078         .mpo_vnode_init_label = lomac_init_label,
 3079         .mpo_vnode_internalize_label = lomac_internalize_label,
 3080         .mpo_vnode_relabel = lomac_vnode_relabel,
 3081         .mpo_vnode_setlabel_extattr = lomac_vnode_setlabel_extattr,
 3082 };
 3083 
 3084 MAC_POLICY_SET(&lomac_ops, mac_lomac, "TrustedBSD MAC/LOMAC",
 3085     MPC_LOADTIME_FLAG_NOTLATE, &lomac_slot);

Cache object: a4c4d8b9daffc93b6c246175eeaf26a4


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