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

Cache object: 9a012d6df961905e361cfe5a684c6873


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