[ 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  -  FREEBSD8  -  FREEBSD7  -  FREEBSD72  -  FREEBSD71  -  FREEBSD70  -  FREEBSD6  -  FREEBSD64  -  FREEBSD63  -  FREEBSD62  -  FREEBSD61  -  FREEBSD60  -  FREEBSD5  -  FREEBSD55  -  FREEBSD54  -  FREEBSD53  -  FREEBSD52  -  FREEBSD51  -  FREEBSD50  -  FREEBSD4  -  FREEBSD3  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  OPENSOLARIS  -  minix-3-1-1  -  FREEBSD-LIBC  -  FREEBSD7-LIBC  -  FREEBSD6-LIBC  -  GLIBC27 
SearchContext: -  none  -  excerpts  -  bigexcerpts 

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

Cache object: 89654b8302592390af92a1de5839c4a4


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


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.