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


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

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

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

    1 /*-
    2  * Copyright (c) 1999-2002, 2007-2011 Robert N. M. Watson
    3  * Copyright (c) 2001-2005 McAfee, Inc.
    4  * Copyright (c) 2006 SPARTA, Inc.
    5  * All rights reserved.
    6  *
    7  * This software was developed by Robert Watson for the TrustedBSD Project.
    8  *
    9  * This software was developed for the FreeBSD Project in part by McAfee
   10  * Research, the Security Research Division of McAfee, Inc. under
   11  * DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA
   12  * CHATS research program.
   13  *
   14  * This software was enhanced by SPARTA ISSO under SPAWAR contract
   15  * N66001-04-C-6019 ("SEFOS").
   16  *
   17  * This software was developed at the University of Cambridge Computer
   18  * Laboratory with support from a grant from Google, Inc.
   19  *
   20  * Redistribution and use in source and binary forms, with or without
   21  * modification, are permitted provided that the following conditions
   22  * are met:
   23  * 1. Redistributions of source code must retain the above copyright
   24  *    notice, this list of conditions and the following disclaimer.
   25  * 2. Redistributions in binary form must reproduce the above copyright
   26  *    notice, this list of conditions and the following disclaimer in the
   27  *    documentation and/or other materials provided with the distribution.
   28  *
   29  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   30  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   31  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   32  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   33  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   34  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   35  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   36  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   37  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   38  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   39  * SUCH DAMAGE.
   40  *
   41  * $FreeBSD$
   42  */
   43 
   44 /*
   45  * Developed by the TrustedBSD Project.
   46  *
   47  * Biba fixed label mandatory integrity policy.
   48  */
   49 
   50 #include <sys/param.h>
   51 #include <sys/conf.h>
   52 #include <sys/extattr.h>
   53 #include <sys/kernel.h>
   54 #include <sys/ksem.h>
   55 #include <sys/malloc.h>
   56 #include <sys/mman.h>
   57 #include <sys/mount.h>
   58 #include <sys/priv.h>
   59 #include <sys/proc.h>
   60 #include <sys/sbuf.h>
   61 #include <sys/systm.h>
   62 #include <sys/sysproto.h>
   63 #include <sys/sysent.h>
   64 #include <sys/systm.h>
   65 #include <sys/vnode.h>
   66 #include <sys/file.h>
   67 #include <sys/socket.h>
   68 #include <sys/socketvar.h>
   69 #include <sys/pipe.h>
   70 #include <sys/sx.h>
   71 #include <sys/sysctl.h>
   72 #include <sys/msg.h>
   73 #include <sys/sem.h>
   74 #include <sys/shm.h>
   75 
   76 #include <fs/devfs/devfs.h>
   77 
   78 #include <net/bpfdesc.h>
   79 #include <net/if.h>
   80 #include <net/if_types.h>
   81 #include <net/if_var.h>
   82 
   83 #include <netinet/in.h>
   84 #include <netinet/in_pcb.h>
   85 #include <netinet/ip_var.h>
   86 
   87 #include <vm/uma.h>
   88 #include <vm/vm.h>
   89 
   90 #include <security/mac/mac_policy.h>
   91 #include <security/mac_biba/mac_biba.h>
   92 
   93 SYSCTL_DECL(_security_mac);
   94 
   95 static SYSCTL_NODE(_security_mac, OID_AUTO, biba,
   96     CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
   97     "TrustedBSD mac_biba policy controls");
   98 
   99 static int      biba_label_size = sizeof(struct mac_biba);
  100 SYSCTL_INT(_security_mac_biba, OID_AUTO, label_size, CTLFLAG_RD,
  101     &biba_label_size, 0, "Size of struct mac_biba");
  102 
  103 static int      biba_enabled = 1;
  104 SYSCTL_INT(_security_mac_biba, OID_AUTO, enabled, CTLFLAG_RWTUN, &biba_enabled,
  105     0, "Enforce MAC/Biba policy");
  106 
  107 static int      destroyed_not_inited;
  108 SYSCTL_INT(_security_mac_biba, OID_AUTO, destroyed_not_inited, CTLFLAG_RD,
  109     &destroyed_not_inited, 0, "Count of labels destroyed but not inited");
  110 
  111 static int      trust_all_interfaces = 0;
  112 SYSCTL_INT(_security_mac_biba, OID_AUTO, trust_all_interfaces, CTLFLAG_RDTUN,
  113     &trust_all_interfaces, 0, "Consider all interfaces 'trusted' by MAC/Biba");
  114 
  115 static char     trusted_interfaces[128];
  116 SYSCTL_STRING(_security_mac_biba, OID_AUTO, trusted_interfaces, CTLFLAG_RDTUN,
  117     trusted_interfaces, 0, "Interfaces considered 'trusted' by MAC/Biba");
  118 
  119 static int      max_compartments = MAC_BIBA_MAX_COMPARTMENTS;
  120 SYSCTL_INT(_security_mac_biba, OID_AUTO, max_compartments, CTLFLAG_RD,
  121     &max_compartments, 0, "Maximum supported compartments");
  122 
  123 static int      ptys_equal = 0;
  124 SYSCTL_INT(_security_mac_biba, OID_AUTO, ptys_equal, CTLFLAG_RWTUN, &ptys_equal,
  125     0, "Label pty devices as biba/equal on create");
  126 
  127 static int      interfaces_equal = 1;
  128 SYSCTL_INT(_security_mac_biba, OID_AUTO, interfaces_equal, CTLFLAG_RWTUN,
  129     &interfaces_equal, 0, "Label network interfaces as biba/equal on create");
  130 
  131 static int      revocation_enabled = 0;
  132 SYSCTL_INT(_security_mac_biba, OID_AUTO, revocation_enabled, CTLFLAG_RWTUN,
  133     &revocation_enabled, 0, "Revoke access to objects on relabel");
  134 
  135 static int      biba_slot;
  136 #define SLOT(l) ((struct mac_biba *)mac_label_get((l), biba_slot))
  137 #define SLOT_SET(l, val) mac_label_set((l), biba_slot, (uintptr_t)(val))
  138 
  139 static uma_zone_t       zone_biba;
  140 
  141 static __inline int
  142 biba_bit_set_empty(u_char *set) {
  143         int i;
  144 
  145         for (i = 0; i < MAC_BIBA_MAX_COMPARTMENTS >> 3; i++)
  146                 if (set[i] != 0)
  147                         return (0);
  148         return (1);
  149 }
  150 
  151 static struct mac_biba *
  152 biba_alloc(int flag)
  153 {
  154 
  155         return (uma_zalloc(zone_biba, flag | M_ZERO));
  156 }
  157 
  158 static void
  159 biba_free(struct mac_biba *mb)
  160 {
  161 
  162         if (mb != NULL)
  163                 uma_zfree(zone_biba, mb);
  164         else
  165                 atomic_add_int(&destroyed_not_inited, 1);
  166 }
  167 
  168 static int
  169 biba_atmostflags(struct mac_biba *mb, int flags)
  170 {
  171 
  172         if ((mb->mb_flags & flags) != mb->mb_flags)
  173                 return (EINVAL);
  174         return (0);
  175 }
  176 
  177 static int
  178 biba_dominate_element(struct mac_biba_element *a, struct mac_biba_element *b)
  179 {
  180         int bit;
  181 
  182         switch (a->mbe_type) {
  183         case MAC_BIBA_TYPE_EQUAL:
  184         case MAC_BIBA_TYPE_HIGH:
  185                 return (1);
  186 
  187         case MAC_BIBA_TYPE_LOW:
  188                 switch (b->mbe_type) {
  189                 case MAC_BIBA_TYPE_GRADE:
  190                 case MAC_BIBA_TYPE_HIGH:
  191                         return (0);
  192 
  193                 case MAC_BIBA_TYPE_EQUAL:
  194                 case MAC_BIBA_TYPE_LOW:
  195                         return (1);
  196 
  197                 default:
  198                         panic("biba_dominate_element: b->mbe_type invalid");
  199                 }
  200 
  201         case MAC_BIBA_TYPE_GRADE:
  202                 switch (b->mbe_type) {
  203                 case MAC_BIBA_TYPE_EQUAL:
  204                 case MAC_BIBA_TYPE_LOW:
  205                         return (1);
  206 
  207                 case MAC_BIBA_TYPE_HIGH:
  208                         return (0);
  209 
  210                 case MAC_BIBA_TYPE_GRADE:
  211                         for (bit = 1; bit <= MAC_BIBA_MAX_COMPARTMENTS; bit++)
  212                                 if (!MAC_BIBA_BIT_TEST(bit,
  213                                     a->mbe_compartments) &&
  214                                     MAC_BIBA_BIT_TEST(bit, b->mbe_compartments))
  215                                         return (0);
  216                         return (a->mbe_grade >= b->mbe_grade);
  217 
  218                 default:
  219                         panic("biba_dominate_element: b->mbe_type invalid");
  220                 }
  221 
  222         default:
  223                 panic("biba_dominate_element: a->mbe_type invalid");
  224         }
  225 
  226         return (0);
  227 }
  228 
  229 static int
  230 biba_subject_dominate_high(struct mac_biba *mb)
  231 {
  232         struct mac_biba_element *element;
  233 
  234         KASSERT((mb->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
  235             ("biba_effective_in_range: mb not effective"));
  236         element = &mb->mb_effective;
  237 
  238         return (element->mbe_type == MAC_BIBA_TYPE_EQUAL ||
  239             element->mbe_type == MAC_BIBA_TYPE_HIGH);
  240 }
  241 
  242 static int
  243 biba_range_in_range(struct mac_biba *rangea, struct mac_biba *rangeb)
  244 {
  245 
  246         return (biba_dominate_element(&rangeb->mb_rangehigh,
  247             &rangea->mb_rangehigh) &&
  248             biba_dominate_element(&rangea->mb_rangelow,
  249             &rangeb->mb_rangelow));
  250 }
  251 
  252 static int
  253 biba_effective_in_range(struct mac_biba *effective, struct mac_biba *range)
  254 {
  255 
  256         KASSERT((effective->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
  257             ("biba_effective_in_range: a not effective"));
  258         KASSERT((range->mb_flags & MAC_BIBA_FLAG_RANGE) != 0,
  259             ("biba_effective_in_range: b not range"));
  260 
  261         return (biba_dominate_element(&range->mb_rangehigh,
  262             &effective->mb_effective) &&
  263             biba_dominate_element(&effective->mb_effective,
  264             &range->mb_rangelow));
  265 
  266         return (1);
  267 }
  268 
  269 static int
  270 biba_dominate_effective(struct mac_biba *a, struct mac_biba *b)
  271 {
  272         KASSERT((a->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
  273             ("biba_dominate_effective: a not effective"));
  274         KASSERT((b->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
  275             ("biba_dominate_effective: b not effective"));
  276 
  277         return (biba_dominate_element(&a->mb_effective, &b->mb_effective));
  278 }
  279 
  280 static int
  281 biba_equal_element(struct mac_biba_element *a, struct mac_biba_element *b)
  282 {
  283 
  284         if (a->mbe_type == MAC_BIBA_TYPE_EQUAL ||
  285             b->mbe_type == MAC_BIBA_TYPE_EQUAL)
  286                 return (1);
  287 
  288         return (a->mbe_type == b->mbe_type && a->mbe_grade == b->mbe_grade);
  289 }
  290 
  291 static int
  292 biba_equal_effective(struct mac_biba *a, struct mac_biba *b)
  293 {
  294 
  295         KASSERT((a->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
  296             ("biba_equal_effective: a not effective"));
  297         KASSERT((b->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
  298             ("biba_equal_effective: b not effective"));
  299 
  300         return (biba_equal_element(&a->mb_effective, &b->mb_effective));
  301 }
  302 
  303 static int
  304 biba_contains_equal(struct mac_biba *mb)
  305 {
  306 
  307         if (mb->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
  308                 if (mb->mb_effective.mbe_type == MAC_BIBA_TYPE_EQUAL)
  309                         return (1);
  310         }
  311 
  312         if (mb->mb_flags & MAC_BIBA_FLAG_RANGE) {
  313                 if (mb->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL)
  314                         return (1);
  315                 if (mb->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL)
  316                         return (1);
  317         }
  318 
  319         return (0);
  320 }
  321 
  322 static int
  323 biba_subject_privileged(struct mac_biba *mb)
  324 {
  325 
  326         KASSERT((mb->mb_flags & MAC_BIBA_FLAGS_BOTH) == MAC_BIBA_FLAGS_BOTH,
  327             ("biba_subject_privileged: subject doesn't have both labels"));
  328 
  329         /* If the effective is EQUAL, it's ok. */
  330         if (mb->mb_effective.mbe_type == MAC_BIBA_TYPE_EQUAL)
  331                 return (0);
  332 
  333         /* If either range endpoint is EQUAL, it's ok. */
  334         if (mb->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL ||
  335             mb->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL)
  336                 return (0);
  337 
  338         /* If the range is low-high, it's ok. */
  339         if (mb->mb_rangelow.mbe_type == MAC_BIBA_TYPE_LOW &&
  340             mb->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_HIGH)
  341                 return (0);
  342 
  343         /* It's not ok. */
  344         return (EPERM);
  345 }
  346 
  347 static int
  348 biba_high_effective(struct mac_biba *mb)
  349 {
  350 
  351         KASSERT((mb->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
  352             ("biba_equal_effective: mb not effective"));
  353 
  354         return (mb->mb_effective.mbe_type == MAC_BIBA_TYPE_HIGH);
  355 }
  356 
  357 static int
  358 biba_valid(struct mac_biba *mb)
  359 {
  360 
  361         if (mb->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
  362                 switch (mb->mb_effective.mbe_type) {
  363                 case MAC_BIBA_TYPE_GRADE:
  364                         break;
  365 
  366                 case MAC_BIBA_TYPE_EQUAL:
  367                 case MAC_BIBA_TYPE_HIGH:
  368                 case MAC_BIBA_TYPE_LOW:
  369                         if (mb->mb_effective.mbe_grade != 0 ||
  370                             !MAC_BIBA_BIT_SET_EMPTY(
  371                             mb->mb_effective.mbe_compartments))
  372                                 return (EINVAL);
  373                         break;
  374 
  375                 default:
  376                         return (EINVAL);
  377                 }
  378         } else {
  379                 if (mb->mb_effective.mbe_type != MAC_BIBA_TYPE_UNDEF)
  380                         return (EINVAL);
  381         }
  382 
  383         if (mb->mb_flags & MAC_BIBA_FLAG_RANGE) {
  384                 switch (mb->mb_rangelow.mbe_type) {
  385                 case MAC_BIBA_TYPE_GRADE:
  386                         break;
  387 
  388                 case MAC_BIBA_TYPE_EQUAL:
  389                 case MAC_BIBA_TYPE_HIGH:
  390                 case MAC_BIBA_TYPE_LOW:
  391                         if (mb->mb_rangelow.mbe_grade != 0 ||
  392                             !MAC_BIBA_BIT_SET_EMPTY(
  393                             mb->mb_rangelow.mbe_compartments))
  394                                 return (EINVAL);
  395                         break;
  396 
  397                 default:
  398                         return (EINVAL);
  399                 }
  400 
  401                 switch (mb->mb_rangehigh.mbe_type) {
  402                 case MAC_BIBA_TYPE_GRADE:
  403                         break;
  404 
  405                 case MAC_BIBA_TYPE_EQUAL:
  406                 case MAC_BIBA_TYPE_HIGH:
  407                 case MAC_BIBA_TYPE_LOW:
  408                         if (mb->mb_rangehigh.mbe_grade != 0 ||
  409                             !MAC_BIBA_BIT_SET_EMPTY(
  410                             mb->mb_rangehigh.mbe_compartments))
  411                                 return (EINVAL);
  412                         break;
  413 
  414                 default:
  415                         return (EINVAL);
  416                 }
  417                 if (!biba_dominate_element(&mb->mb_rangehigh,
  418                     &mb->mb_rangelow))
  419                         return (EINVAL);
  420         } else {
  421                 if (mb->mb_rangelow.mbe_type != MAC_BIBA_TYPE_UNDEF ||
  422                     mb->mb_rangehigh.mbe_type != MAC_BIBA_TYPE_UNDEF)
  423                         return (EINVAL);
  424         }
  425 
  426         return (0);
  427 }
  428 
  429 static void
  430 biba_set_range(struct mac_biba *mb, u_short typelow, u_short gradelow,
  431     u_char *compartmentslow, u_short typehigh, u_short gradehigh,
  432     u_char *compartmentshigh)
  433 {
  434 
  435         mb->mb_rangelow.mbe_type = typelow;
  436         mb->mb_rangelow.mbe_grade = gradelow;
  437         if (compartmentslow != NULL)
  438                 memcpy(mb->mb_rangelow.mbe_compartments, compartmentslow,
  439                     sizeof(mb->mb_rangelow.mbe_compartments));
  440         mb->mb_rangehigh.mbe_type = typehigh;
  441         mb->mb_rangehigh.mbe_grade = gradehigh;
  442         if (compartmentshigh != NULL)
  443                 memcpy(mb->mb_rangehigh.mbe_compartments, compartmentshigh,
  444                     sizeof(mb->mb_rangehigh.mbe_compartments));
  445         mb->mb_flags |= MAC_BIBA_FLAG_RANGE;
  446 }
  447 
  448 static void
  449 biba_set_effective(struct mac_biba *mb, u_short type, u_short grade,
  450     u_char *compartments)
  451 {
  452 
  453         mb->mb_effective.mbe_type = type;
  454         mb->mb_effective.mbe_grade = grade;
  455         if (compartments != NULL)
  456                 memcpy(mb->mb_effective.mbe_compartments, compartments,
  457                     sizeof(mb->mb_effective.mbe_compartments));
  458         mb->mb_flags |= MAC_BIBA_FLAG_EFFECTIVE;
  459 }
  460 
  461 static void
  462 biba_copy_range(struct mac_biba *labelfrom, struct mac_biba *labelto)
  463 {
  464 
  465         KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_RANGE) != 0,
  466             ("biba_copy_range: labelfrom not range"));
  467 
  468         labelto->mb_rangelow = labelfrom->mb_rangelow;
  469         labelto->mb_rangehigh = labelfrom->mb_rangehigh;
  470         labelto->mb_flags |= MAC_BIBA_FLAG_RANGE;
  471 }
  472 
  473 static void
  474 biba_copy_effective(struct mac_biba *labelfrom, struct mac_biba *labelto)
  475 {
  476 
  477         KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
  478             ("biba_copy_effective: labelfrom not effective"));
  479 
  480         labelto->mb_effective = labelfrom->mb_effective;
  481         labelto->mb_flags |= MAC_BIBA_FLAG_EFFECTIVE;
  482 }
  483 
  484 static void
  485 biba_copy(struct mac_biba *source, struct mac_biba *dest)
  486 {
  487 
  488         if (source->mb_flags & MAC_BIBA_FLAG_EFFECTIVE)
  489                 biba_copy_effective(source, dest);
  490         if (source->mb_flags & MAC_BIBA_FLAG_RANGE)
  491                 biba_copy_range(source, dest);
  492 }
  493 
  494 /*
  495  * Policy module operations.
  496  */
  497 static void
  498 biba_init(struct mac_policy_conf *conf)
  499 {
  500 
  501         zone_biba = uma_zcreate("mac_biba", sizeof(struct mac_biba), NULL,
  502             NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
  503 }
  504 
  505 /*
  506  * Label operations.
  507  */
  508 static void
  509 biba_init_label(struct label *label)
  510 {
  511 
  512         SLOT_SET(label, biba_alloc(M_WAITOK));
  513 }
  514 
  515 static int
  516 biba_init_label_waitcheck(struct label *label, int flag)
  517 {
  518 
  519         SLOT_SET(label, biba_alloc(flag));
  520         if (SLOT(label) == NULL)
  521                 return (ENOMEM);
  522 
  523         return (0);
  524 }
  525 
  526 static void
  527 biba_destroy_label(struct label *label)
  528 {
  529 
  530         biba_free(SLOT(label));
  531         SLOT_SET(label, NULL);
  532 }
  533 
  534 /*
  535  * biba_element_to_string() accepts an sbuf and Biba element.  It converts
  536  * the Biba element to a string and stores the result in the sbuf; if there
  537  * isn't space in the sbuf, -1 is returned.
  538  */
  539 static int
  540 biba_element_to_string(struct sbuf *sb, struct mac_biba_element *element)
  541 {
  542         int i, first;
  543 
  544         switch (element->mbe_type) {
  545         case MAC_BIBA_TYPE_HIGH:
  546                 return (sbuf_printf(sb, "high"));
  547 
  548         case MAC_BIBA_TYPE_LOW:
  549                 return (sbuf_printf(sb, "low"));
  550 
  551         case MAC_BIBA_TYPE_EQUAL:
  552                 return (sbuf_printf(sb, "equal"));
  553 
  554         case MAC_BIBA_TYPE_GRADE:
  555                 if (sbuf_printf(sb, "%d", element->mbe_grade) == -1)
  556                         return (-1);
  557 
  558                 first = 1;
  559                 for (i = 1; i <= MAC_BIBA_MAX_COMPARTMENTS; i++) {
  560                         if (MAC_BIBA_BIT_TEST(i, element->mbe_compartments)) {
  561                                 if (first) {
  562                                         if (sbuf_putc(sb, ':') == -1)
  563                                                 return (-1);
  564                                         if (sbuf_printf(sb, "%d", i) == -1)
  565                                                 return (-1);
  566                                         first = 0;
  567                                 } else {
  568                                         if (sbuf_printf(sb, "+%d", i) == -1)
  569                                                 return (-1);
  570                                 }
  571                         }
  572                 }
  573                 return (0);
  574 
  575         default:
  576                 panic("biba_element_to_string: invalid type (%d)",
  577                     element->mbe_type);
  578         }
  579 }
  580 
  581 /*
  582  * biba_to_string() converts a Biba label to a string, and places the results
  583  * in the passed sbuf.  It returns 0 on success, or EINVAL if there isn't
  584  * room in the sbuf.  Note: the sbuf will be modified even in a failure case,
  585  * so the caller may need to revert the sbuf by restoring the offset if
  586  * that's undesired.
  587  */
  588 static int
  589 biba_to_string(struct sbuf *sb, struct mac_biba *mb)
  590 {
  591 
  592         if (mb->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
  593                 if (biba_element_to_string(sb, &mb->mb_effective) == -1)
  594                         return (EINVAL);
  595         }
  596 
  597         if (mb->mb_flags & MAC_BIBA_FLAG_RANGE) {
  598                 if (sbuf_putc(sb, '(') == -1)
  599                         return (EINVAL);
  600 
  601                 if (biba_element_to_string(sb, &mb->mb_rangelow) == -1)
  602                         return (EINVAL);
  603 
  604                 if (sbuf_putc(sb, '-') == -1)
  605                         return (EINVAL);
  606 
  607                 if (biba_element_to_string(sb, &mb->mb_rangehigh) == -1)
  608                         return (EINVAL);
  609 
  610                 if (sbuf_putc(sb, ')') == -1)
  611                         return (EINVAL);
  612         }
  613 
  614         return (0);
  615 }
  616 
  617 static int
  618 biba_externalize_label(struct label *label, char *element_name,
  619     struct sbuf *sb, int *claimed)
  620 {
  621         struct mac_biba *mb;
  622 
  623         if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0)
  624                 return (0);
  625 
  626         (*claimed)++;
  627 
  628         mb = SLOT(label);
  629         return (biba_to_string(sb, mb));
  630 }
  631 
  632 static int
  633 biba_parse_element(struct mac_biba_element *element, char *string)
  634 {
  635         char *compartment, *end, *grade;
  636         int value;
  637 
  638         if (strcmp(string, "high") == 0 || strcmp(string, "hi") == 0) {
  639                 element->mbe_type = MAC_BIBA_TYPE_HIGH;
  640                 element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
  641         } else if (strcmp(string, "low") == 0 || strcmp(string, "lo") == 0) {
  642                 element->mbe_type = MAC_BIBA_TYPE_LOW;
  643                 element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
  644         } else if (strcmp(string, "equal") == 0 ||
  645             strcmp(string, "eq") == 0) {
  646                 element->mbe_type = MAC_BIBA_TYPE_EQUAL;
  647                 element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
  648         } else {
  649                 element->mbe_type = MAC_BIBA_TYPE_GRADE;
  650 
  651                 /*
  652                  * Numeric grade piece of the element.
  653                  */
  654                 grade = strsep(&string, ":");
  655                 value = strtol(grade, &end, 10);
  656                 if (end == grade || *end != '\0')
  657                         return (EINVAL);
  658                 if (value < 0 || value > 65535)
  659                         return (EINVAL);
  660                 element->mbe_grade = value;
  661 
  662                 /*
  663                  * Optional compartment piece of the element.  If none are
  664                  * included, we assume that the label has no compartments.
  665                  */
  666                 if (string == NULL)
  667                         return (0);
  668                 if (*string == '\0')
  669                         return (0);
  670 
  671                 while ((compartment = strsep(&string, "+")) != NULL) {
  672                         value = strtol(compartment, &end, 10);
  673                         if (compartment == end || *end != '\0')
  674                                 return (EINVAL);
  675                         if (value < 1 || value > MAC_BIBA_MAX_COMPARTMENTS)
  676                                 return (EINVAL);
  677                         MAC_BIBA_BIT_SET(value, element->mbe_compartments);
  678                 }
  679         }
  680 
  681         return (0);
  682 }
  683 
  684 /*
  685  * Note: destructively consumes the string, make a local copy before calling
  686  * if that's a problem.
  687  */
  688 static int
  689 biba_parse(struct mac_biba *mb, char *string)
  690 {
  691         char *rangehigh, *rangelow, *effective;
  692         int error;
  693 
  694         effective = strsep(&string, "(");
  695         if (*effective == '\0')
  696                 effective = NULL;
  697 
  698         if (string != NULL) {
  699                 rangelow = strsep(&string, "-");
  700                 if (string == NULL)
  701                         return (EINVAL);
  702                 rangehigh = strsep(&string, ")");
  703                 if (string == NULL)
  704                         return (EINVAL);
  705                 if (*string != '\0')
  706                         return (EINVAL);
  707         } else {
  708                 rangelow = NULL;
  709                 rangehigh = NULL;
  710         }
  711 
  712         KASSERT((rangelow != NULL && rangehigh != NULL) ||
  713             (rangelow == NULL && rangehigh == NULL),
  714             ("biba_parse: range mismatch"));
  715 
  716         bzero(mb, sizeof(*mb));
  717         if (effective != NULL) {
  718                 error = biba_parse_element(&mb->mb_effective, effective);
  719                 if (error)
  720                         return (error);
  721                 mb->mb_flags |= MAC_BIBA_FLAG_EFFECTIVE;
  722         }
  723 
  724         if (rangelow != NULL) {
  725                 error = biba_parse_element(&mb->mb_rangelow, rangelow);
  726                 if (error)
  727                         return (error);
  728                 error = biba_parse_element(&mb->mb_rangehigh, rangehigh);
  729                 if (error)
  730                         return (error);
  731                 mb->mb_flags |= MAC_BIBA_FLAG_RANGE;
  732         }
  733 
  734         error = biba_valid(mb);
  735         if (error)
  736                 return (error);
  737 
  738         return (0);
  739 }
  740 
  741 static int
  742 biba_internalize_label(struct label *label, char *element_name,
  743     char *element_data, int *claimed)
  744 {
  745         struct mac_biba *mb, mb_temp;
  746         int error;
  747 
  748         if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0)
  749                 return (0);
  750 
  751         (*claimed)++;
  752 
  753         error = biba_parse(&mb_temp, element_data);
  754         if (error)
  755                 return (error);
  756 
  757         mb = SLOT(label);
  758         *mb = mb_temp;
  759 
  760         return (0);
  761 }
  762 
  763 static void
  764 biba_copy_label(struct label *src, struct label *dest)
  765 {
  766 
  767         *SLOT(dest) = *SLOT(src);
  768 }
  769 
  770 /*
  771  * Object-specific entry point implementations are sorted alphabetically by
  772  * object type name and then by operation.
  773  */
  774 static int
  775 biba_bpfdesc_check_receive(struct bpf_d *d, struct label *dlabel,
  776     struct ifnet *ifp, struct label *ifplabel)
  777 {
  778         struct mac_biba *a, *b;
  779 
  780         if (!biba_enabled)
  781                 return (0);
  782 
  783         a = SLOT(dlabel);
  784         b = SLOT(ifplabel);
  785 
  786         if (biba_equal_effective(a, b))
  787                 return (0);
  788         return (EACCES);
  789 }
  790 
  791 static void
  792 biba_bpfdesc_create(struct ucred *cred, struct bpf_d *d,
  793     struct label *dlabel)
  794 {
  795         struct mac_biba *source, *dest;
  796 
  797         source = SLOT(cred->cr_label);
  798         dest = SLOT(dlabel);
  799 
  800         biba_copy_effective(source, dest);
  801 }
  802 
  803 static void
  804 biba_bpfdesc_create_mbuf(struct bpf_d *d, struct label *dlabel,
  805     struct mbuf *m, struct label *mlabel)
  806 {
  807         struct mac_biba *source, *dest;
  808 
  809         source = SLOT(dlabel);
  810         dest = SLOT(mlabel);
  811 
  812         biba_copy_effective(source, dest);
  813 }
  814 
  815 static void
  816 biba_cred_associate_nfsd(struct ucred *cred)
  817 {
  818         struct mac_biba *label;
  819 
  820         label = SLOT(cred->cr_label);
  821         biba_set_effective(label, MAC_BIBA_TYPE_LOW, 0, NULL);
  822         biba_set_range(label, MAC_BIBA_TYPE_LOW, 0, NULL, MAC_BIBA_TYPE_HIGH,
  823             0, NULL);
  824 }
  825 
  826 static int
  827 biba_cred_check_relabel(struct ucred *cred, struct label *newlabel)
  828 {
  829         struct mac_biba *subj, *new;
  830         int error;
  831 
  832         subj = SLOT(cred->cr_label);
  833         new = SLOT(newlabel);
  834 
  835         /*
  836          * If there is a Biba label update for the credential, it may
  837          * be an update of the effective, range, or both.
  838          */
  839         error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
  840         if (error)
  841                 return (error);
  842 
  843         /*
  844          * If the Biba label is to be changed, authorize as appropriate.
  845          */
  846         if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) {
  847                 /*
  848                  * If the change request modifies both the Biba label
  849                  * effective and range, check that the new effective will be
  850                  * in the new range.
  851                  */
  852                 if ((new->mb_flags & MAC_BIBA_FLAGS_BOTH) ==
  853                     MAC_BIBA_FLAGS_BOTH &&
  854                     !biba_effective_in_range(new, new))
  855                         return (EINVAL);
  856 
  857                 /*
  858                  * To change the Biba effective label on a credential, the
  859                  * new effective label must be in the current range.
  860                  */
  861                 if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE &&
  862                     !biba_effective_in_range(new, subj))
  863                         return (EPERM);
  864 
  865                 /*
  866                  * To change the Biba range on a credential, the new range
  867                  * label must be in the current range.
  868                  */
  869                 if (new->mb_flags & MAC_BIBA_FLAG_RANGE &&
  870                     !biba_range_in_range(new, subj))
  871                         return (EPERM);
  872 
  873                 /*
  874                  * To have EQUAL in any component of the new credential Biba
  875                  * label, the subject must already have EQUAL in their label.
  876                  */
  877                 if (biba_contains_equal(new)) {
  878                         error = biba_subject_privileged(subj);
  879                         if (error)
  880                                 return (error);
  881                 }
  882         }
  883 
  884         return (0);
  885 }
  886 
  887 static int
  888 biba_cred_check_visible(struct ucred *u1, struct ucred *u2)
  889 {
  890         struct mac_biba *subj, *obj;
  891 
  892         if (!biba_enabled)
  893                 return (0);
  894 
  895         subj = SLOT(u1->cr_label);
  896         obj = SLOT(u2->cr_label);
  897 
  898         /* XXX: range */
  899         if (!biba_dominate_effective(obj, subj))
  900                 return (ESRCH);
  901 
  902         return (0);
  903 }
  904 
  905 static void
  906 biba_cred_create_init(struct ucred *cred)
  907 {
  908         struct mac_biba *dest;
  909 
  910         dest = SLOT(cred->cr_label);
  911 
  912         biba_set_effective(dest, MAC_BIBA_TYPE_HIGH, 0, NULL);
  913         biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL, MAC_BIBA_TYPE_HIGH,
  914             0, NULL);
  915 }
  916 
  917 static void
  918 biba_cred_create_swapper(struct ucred *cred)
  919 {
  920         struct mac_biba *dest;
  921 
  922         dest = SLOT(cred->cr_label);
  923 
  924         biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
  925         biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL, MAC_BIBA_TYPE_HIGH,
  926             0, NULL);
  927 }
  928 
  929 static void
  930 biba_cred_relabel(struct ucred *cred, struct label *newlabel)
  931 {
  932         struct mac_biba *source, *dest;
  933 
  934         source = SLOT(newlabel);
  935         dest = SLOT(cred->cr_label);
  936 
  937         biba_copy(source, dest);
  938 }
  939 
  940 static void
  941 biba_devfs_create_device(struct ucred *cred, struct mount *mp,
  942     struct cdev *dev, struct devfs_dirent *de, struct label *delabel)
  943 {
  944         struct mac_biba *mb;
  945         const char *dn;
  946         int biba_type;
  947 
  948         mb = SLOT(delabel);
  949         dn = devtoname(dev);
  950         if (strcmp(dn, "null") == 0 ||
  951             strcmp(dn, "zero") == 0 ||
  952             strcmp(dn, "random") == 0 ||
  953             strncmp(dn, "fd/", strlen("fd/")) == 0)
  954                 biba_type = MAC_BIBA_TYPE_EQUAL;
  955         else if (ptys_equal &&
  956             (strncmp(dn, "ttyp", strlen("ttyp")) == 0 ||
  957             strncmp(dn, "pts/", strlen("pts/")) == 0 ||
  958             strncmp(dn, "ptyp", strlen("ptyp")) == 0))
  959                 biba_type = MAC_BIBA_TYPE_EQUAL;
  960         else
  961                 biba_type = MAC_BIBA_TYPE_HIGH;
  962         biba_set_effective(mb, biba_type, 0, NULL);
  963 }
  964 
  965 static void
  966 biba_devfs_create_directory(struct mount *mp, char *dirname, int dirnamelen,
  967     struct devfs_dirent *de, struct label *delabel)
  968 {
  969         struct mac_biba *mb;
  970 
  971         mb = SLOT(delabel);
  972 
  973         biba_set_effective(mb, MAC_BIBA_TYPE_HIGH, 0, NULL);
  974 }
  975 
  976 static void
  977 biba_devfs_create_symlink(struct ucred *cred, struct mount *mp,
  978     struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de,
  979     struct label *delabel)
  980 {
  981         struct mac_biba *source, *dest;
  982 
  983         source = SLOT(cred->cr_label);
  984         dest = SLOT(delabel);
  985 
  986         biba_copy_effective(source, dest);
  987 }
  988 
  989 static void
  990 biba_devfs_update(struct mount *mp, struct devfs_dirent *de,
  991     struct label *delabel, struct vnode *vp, struct label *vplabel)
  992 {
  993         struct mac_biba *source, *dest;
  994 
  995         source = SLOT(vplabel);
  996         dest = SLOT(delabel);
  997 
  998         biba_copy(source, dest);
  999 }
 1000 
 1001 static void
 1002 biba_devfs_vnode_associate(struct mount *mp, struct label *mntlabel,
 1003     struct devfs_dirent *de, struct label *delabel, struct vnode *vp,
 1004     struct label *vplabel)
 1005 {
 1006         struct mac_biba *source, *dest;
 1007 
 1008         source = SLOT(delabel);
 1009         dest = SLOT(vplabel);
 1010 
 1011         biba_copy_effective(source, dest);
 1012 }
 1013 
 1014 static int
 1015 biba_ifnet_check_relabel(struct ucred *cred, struct ifnet *ifp,
 1016     struct label *ifplabel, struct label *newlabel)
 1017 {
 1018         struct mac_biba *subj, *new;
 1019         int error;
 1020 
 1021         subj = SLOT(cred->cr_label);
 1022         new = SLOT(newlabel);
 1023 
 1024         /*
 1025          * If there is a Biba label update for the interface, it may be an
 1026          * update of the effective, range, or both.
 1027          */
 1028         error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
 1029         if (error)
 1030                 return (error);
 1031 
 1032         /*
 1033          * Relabling network interfaces requires Biba privilege.
 1034          */
 1035         error = biba_subject_privileged(subj);
 1036         if (error)
 1037                 return (error);
 1038 
 1039         return (0);
 1040 }
 1041 
 1042 static int
 1043 biba_ifnet_check_transmit(struct ifnet *ifp, struct label *ifplabel,
 1044     struct mbuf *m, struct label *mlabel)
 1045 {
 1046         struct mac_biba *p, *i;
 1047 
 1048         if (!biba_enabled)
 1049                 return (0);
 1050 
 1051         p = SLOT(mlabel);
 1052         i = SLOT(ifplabel);
 1053 
 1054         return (biba_effective_in_range(p, i) ? 0 : EACCES);
 1055 }
 1056 
 1057 static void
 1058 biba_ifnet_create(struct ifnet *ifp, struct label *ifplabel)
 1059 {
 1060         char tifname[IFNAMSIZ], *p, *q;
 1061         char tiflist[sizeof(trusted_interfaces)];
 1062         struct mac_biba *dest;
 1063         int len, type;
 1064 
 1065         dest = SLOT(ifplabel);
 1066 
 1067         if (ifp->if_type == IFT_LOOP || interfaces_equal != 0) {
 1068                 type = MAC_BIBA_TYPE_EQUAL;
 1069                 goto set;
 1070         }
 1071 
 1072         if (trust_all_interfaces) {
 1073                 type = MAC_BIBA_TYPE_HIGH;
 1074                 goto set;
 1075         }
 1076 
 1077         type = MAC_BIBA_TYPE_LOW;
 1078 
 1079         if (trusted_interfaces[0] == '\0' ||
 1080             !strvalid(trusted_interfaces, sizeof(trusted_interfaces)))
 1081                 goto set;
 1082 
 1083         bzero(tiflist, sizeof(tiflist));
 1084         for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++)
 1085                 if(*p != ' ' && *p != '\t')
 1086                         *q = *p;
 1087 
 1088         for (p = q = tiflist;; p++) {
 1089                 if (*p == ',' || *p == '\0') {
 1090                         len = p - q;
 1091                         if (len < IFNAMSIZ) {
 1092                                 bzero(tifname, sizeof(tifname));
 1093                                 bcopy(q, tifname, len);
 1094                                 if (strcmp(tifname, ifp->if_xname) == 0) {
 1095                                         type = MAC_BIBA_TYPE_HIGH;
 1096                                         break;
 1097                                 }
 1098                         } else {
 1099                                 *p = '\0';
 1100                                 printf("mac_biba warning: interface name "
 1101                                     "\"%s\" is too long (must be < %d)\n",
 1102                                     q, IFNAMSIZ);
 1103                         }
 1104                         if (*p == '\0')
 1105                                 break;
 1106                         q = p + 1;
 1107                 }
 1108         }
 1109 set:
 1110         biba_set_effective(dest, type, 0, NULL);
 1111         biba_set_range(dest, type, 0, NULL, type, 0, NULL);
 1112 }
 1113 
 1114 static void
 1115 biba_ifnet_create_mbuf(struct ifnet *ifp, struct label *ifplabel,
 1116     struct mbuf *m, struct label *mlabel)
 1117 {
 1118         struct mac_biba *source, *dest;
 1119 
 1120         source = SLOT(ifplabel);
 1121         dest = SLOT(mlabel);
 1122 
 1123         biba_copy_effective(source, dest);
 1124 }
 1125 
 1126 static void
 1127 biba_ifnet_relabel(struct ucred *cred, struct ifnet *ifp,
 1128     struct label *ifplabel, struct label *newlabel)
 1129 {
 1130         struct mac_biba *source, *dest;
 1131 
 1132         source = SLOT(newlabel);
 1133         dest = SLOT(ifplabel);
 1134 
 1135         biba_copy(source, dest);
 1136 }
 1137 
 1138 static int
 1139 biba_inpcb_check_deliver(struct inpcb *inp, struct label *inplabel,
 1140     struct mbuf *m, struct label *mlabel)
 1141 {
 1142         struct mac_biba *p, *i;
 1143 
 1144         if (!biba_enabled)
 1145                 return (0);
 1146 
 1147         p = SLOT(mlabel);
 1148         i = SLOT(inplabel);
 1149 
 1150         return (biba_equal_effective(p, i) ? 0 : EACCES);
 1151 }
 1152 
 1153 static int
 1154 biba_inpcb_check_visible(struct ucred *cred, struct inpcb *inp,
 1155     struct label *inplabel)
 1156 {
 1157         struct mac_biba *subj, *obj;
 1158 
 1159         if (!biba_enabled)
 1160                 return (0);
 1161 
 1162         subj = SLOT(cred->cr_label);
 1163         obj = SLOT(inplabel);
 1164 
 1165         if (!biba_dominate_effective(obj, subj))
 1166                 return (ENOENT);
 1167 
 1168         return (0);
 1169 }
 1170 
 1171 static void
 1172 biba_inpcb_create(struct socket *so, struct label *solabel,
 1173     struct inpcb *inp, struct label *inplabel)
 1174 {
 1175         struct mac_biba *source, *dest;
 1176 
 1177         source = SLOT(solabel);
 1178         dest = SLOT(inplabel);
 1179 
 1180         SOCK_LOCK(so);
 1181         biba_copy_effective(source, dest);
 1182         SOCK_UNLOCK(so);
 1183 }
 1184 
 1185 static void
 1186 biba_inpcb_create_mbuf(struct inpcb *inp, struct label *inplabel,
 1187     struct mbuf *m, struct label *mlabel)
 1188 {
 1189         struct mac_biba *source, *dest;
 1190 
 1191         source = SLOT(inplabel);
 1192         dest = SLOT(mlabel);
 1193 
 1194         biba_copy_effective(source, dest);
 1195 }
 1196 
 1197 static void
 1198 biba_inpcb_sosetlabel(struct socket *so, struct label *solabel,
 1199     struct inpcb *inp, struct label *inplabel)
 1200 {
 1201         struct mac_biba *source, *dest;
 1202 
 1203         SOCK_LOCK_ASSERT(so);
 1204 
 1205         source = SLOT(solabel);
 1206         dest = SLOT(inplabel);
 1207 
 1208         biba_copy(source, dest);
 1209 }
 1210 
 1211 static void
 1212 biba_ip6q_create(struct mbuf *m, struct label *mlabel, struct ip6q *q6,
 1213     struct label *q6label)
 1214 {
 1215         struct mac_biba *source, *dest;
 1216 
 1217         source = SLOT(mlabel);
 1218         dest = SLOT(q6label);
 1219 
 1220         biba_copy_effective(source, dest);
 1221 }
 1222 
 1223 static int
 1224 biba_ip6q_match(struct mbuf *m, struct label *mlabel, struct ip6q *q6,
 1225     struct label *q6label)
 1226 {
 1227         struct mac_biba *a, *b;
 1228 
 1229         a = SLOT(q6label);
 1230         b = SLOT(mlabel);
 1231 
 1232         return (biba_equal_effective(a, b));
 1233 }
 1234 
 1235 static void
 1236 biba_ip6q_reassemble(struct ip6q *q6, struct label *q6label, struct mbuf *m,
 1237     struct label *mlabel)
 1238 {
 1239         struct mac_biba *source, *dest;
 1240 
 1241         source = SLOT(q6label);
 1242         dest = SLOT(mlabel);
 1243 
 1244         /* Just use the head, since we require them all to match. */
 1245         biba_copy_effective(source, dest);
 1246 }
 1247 
 1248 static void
 1249 biba_ip6q_update(struct mbuf *m, struct label *mlabel, struct ip6q *q6,
 1250     struct label *q6label)
 1251 {
 1252 
 1253         /* NOOP: we only accept matching labels, so no need to update */
 1254 }
 1255 
 1256 static void
 1257 biba_ipq_create(struct mbuf *m, struct label *mlabel, struct ipq *q,
 1258     struct label *qlabel)
 1259 {
 1260         struct mac_biba *source, *dest;
 1261 
 1262         source = SLOT(mlabel);
 1263         dest = SLOT(qlabel);
 1264 
 1265         biba_copy_effective(source, dest);
 1266 }
 1267 
 1268 static int
 1269 biba_ipq_match(struct mbuf *m, struct label *mlabel, struct ipq *q,
 1270     struct label *qlabel)
 1271 {
 1272         struct mac_biba *a, *b;
 1273 
 1274         a = SLOT(qlabel);
 1275         b = SLOT(mlabel);
 1276 
 1277         return (biba_equal_effective(a, b));
 1278 }
 1279 
 1280 static void
 1281 biba_ipq_reassemble(struct ipq *q, struct label *qlabel, struct mbuf *m,
 1282     struct label *mlabel)
 1283 {
 1284         struct mac_biba *source, *dest;
 1285 
 1286         source = SLOT(qlabel);
 1287         dest = SLOT(mlabel);
 1288 
 1289         /* Just use the head, since we require them all to match. */
 1290         biba_copy_effective(source, dest);
 1291 }
 1292 
 1293 static void
 1294 biba_ipq_update(struct mbuf *m, struct label *mlabel, struct ipq *q,
 1295     struct label *qlabel)
 1296 {
 1297 
 1298         /* NOOP: we only accept matching labels, so no need to update */
 1299 }
 1300 
 1301 static int
 1302 biba_kld_check_load(struct ucred *cred, struct vnode *vp,
 1303     struct label *vplabel)
 1304 {
 1305         struct mac_biba *subj, *obj;
 1306         int error;
 1307 
 1308         if (!biba_enabled)
 1309                 return (0);
 1310 
 1311         subj = SLOT(cred->cr_label);
 1312 
 1313         error = biba_subject_privileged(subj);
 1314         if (error)
 1315                 return (error);
 1316 
 1317         obj = SLOT(vplabel);
 1318         if (!biba_high_effective(obj))
 1319                 return (EACCES);
 1320 
 1321         return (0);
 1322 }
 1323 
 1324 static int
 1325 biba_mount_check_stat(struct ucred *cred, struct mount *mp,
 1326     struct label *mplabel)
 1327 {
 1328         struct mac_biba *subj, *obj;
 1329 
 1330         if (!biba_enabled)
 1331                 return (0);
 1332 
 1333         subj = SLOT(cred->cr_label);
 1334         obj = SLOT(mplabel);
 1335 
 1336         if (!biba_dominate_effective(obj, subj))
 1337                 return (EACCES);
 1338 
 1339         return (0);
 1340 }
 1341 
 1342 static void
 1343 biba_mount_create(struct ucred *cred, struct mount *mp,
 1344     struct label *mplabel)
 1345 {
 1346         struct mac_biba *source, *dest;
 1347 
 1348         source = SLOT(cred->cr_label);
 1349         dest = SLOT(mplabel);
 1350 
 1351         biba_copy_effective(source, dest);
 1352 }
 1353 
 1354 static void
 1355 biba_netinet_arp_send(struct ifnet *ifp, struct label *ifplabel,
 1356     struct mbuf *m, struct label *mlabel)
 1357 {
 1358         struct mac_biba *dest;
 1359 
 1360         dest = SLOT(mlabel);
 1361 
 1362         biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
 1363 }
 1364 
 1365 static void
 1366 biba_netinet_firewall_reply(struct mbuf *mrecv, struct label *mrecvlabel,
 1367     struct mbuf *msend, struct label *msendlabel)
 1368 {
 1369         struct mac_biba *source, *dest;
 1370 
 1371         source = SLOT(mrecvlabel);
 1372         dest = SLOT(msendlabel);
 1373 
 1374         biba_copy_effective(source, dest);
 1375 }
 1376 
 1377 static void
 1378 biba_netinet_firewall_send(struct mbuf *m, struct label *mlabel)
 1379 {
 1380         struct mac_biba *dest;
 1381 
 1382         dest = SLOT(mlabel);
 1383 
 1384         /* XXX: where is the label for the firewall really coming from? */
 1385         biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
 1386 }
 1387 
 1388 static void
 1389 biba_netinet_fragment(struct mbuf *m, struct label *mlabel,
 1390     struct mbuf *frag, struct label *fraglabel)
 1391 {
 1392         struct mac_biba *source, *dest;
 1393 
 1394         source = SLOT(mlabel);
 1395         dest = SLOT(fraglabel);
 1396 
 1397         biba_copy_effective(source, dest);
 1398 }
 1399 
 1400 static void
 1401 biba_netinet_icmp_reply(struct mbuf *mrecv, struct label *mrecvlabel,
 1402     struct mbuf *msend, struct label *msendlabel)
 1403 {
 1404         struct mac_biba *source, *dest;
 1405 
 1406         source = SLOT(mrecvlabel);
 1407         dest = SLOT(msendlabel);
 1408 
 1409         biba_copy_effective(source, dest);
 1410 }
 1411 
 1412 static void
 1413 biba_netinet_igmp_send(struct ifnet *ifp, struct label *ifplabel,
 1414     struct mbuf *m, struct label *mlabel)
 1415 {
 1416         struct mac_biba *dest;
 1417 
 1418         dest = SLOT(mlabel);
 1419 
 1420         biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
 1421 }
 1422 
 1423 static void
 1424 biba_netinet6_nd6_send(struct ifnet *ifp, struct label *ifplabel,
 1425     struct mbuf *m, struct label *mlabel)
 1426 {
 1427         struct mac_biba *dest;
 1428 
 1429         dest = SLOT(mlabel);
 1430 
 1431         biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
 1432 }
 1433 
 1434 static int
 1435 biba_pipe_check_ioctl(struct ucred *cred, struct pipepair *pp,
 1436     struct label *pplabel, unsigned long cmd, void /* caddr_t */ *data)
 1437 {
 1438 
 1439         if(!biba_enabled)
 1440                 return (0);
 1441 
 1442         /* XXX: This will be implemented soon... */
 1443 
 1444         return (0);
 1445 }
 1446 
 1447 static int
 1448 biba_pipe_check_poll(struct ucred *cred, struct pipepair *pp,
 1449     struct label *pplabel)
 1450 {
 1451         struct mac_biba *subj, *obj;
 1452 
 1453         if (!biba_enabled)
 1454                 return (0);
 1455 
 1456         subj = SLOT(cred->cr_label);
 1457         obj = SLOT(pplabel);
 1458 
 1459         if (!biba_dominate_effective(obj, subj))
 1460                 return (EACCES);
 1461 
 1462         return (0);
 1463 }
 1464 
 1465 static int
 1466 biba_pipe_check_read(struct ucred *cred, struct pipepair *pp,
 1467     struct label *pplabel)
 1468 {
 1469         struct mac_biba *subj, *obj;
 1470 
 1471         if (!biba_enabled)
 1472                 return (0);
 1473 
 1474         subj = SLOT(cred->cr_label);
 1475         obj = SLOT(pplabel);
 1476 
 1477         if (!biba_dominate_effective(obj, subj))
 1478                 return (EACCES);
 1479 
 1480         return (0);
 1481 }
 1482 
 1483 static int
 1484 biba_pipe_check_relabel(struct ucred *cred, struct pipepair *pp,
 1485     struct label *pplabel, struct label *newlabel)
 1486 {
 1487         struct mac_biba *subj, *obj, *new;
 1488         int error;
 1489 
 1490         new = SLOT(newlabel);
 1491         subj = SLOT(cred->cr_label);
 1492         obj = SLOT(pplabel);
 1493 
 1494         /*
 1495          * If there is a Biba label update for a pipe, it must be a effective
 1496          * update.
 1497          */
 1498         error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE);
 1499         if (error)
 1500                 return (error);
 1501 
 1502         /*
 1503          * To perform a relabel of a pipe (Biba label or not), Biba must
 1504          * authorize the relabel.
 1505          */
 1506         if (!biba_effective_in_range(obj, subj))
 1507                 return (EPERM);
 1508 
 1509         /*
 1510          * If the Biba label is to be changed, authorize as appropriate.
 1511          */
 1512         if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
 1513                 /*
 1514                  * To change the Biba label on a pipe, the new pipe label
 1515                  * must be in the subject range.
 1516                  */
 1517                 if (!biba_effective_in_range(new, subj))
 1518                         return (EPERM);
 1519 
 1520                 /*
 1521                  * To change the Biba label on a pipe to be EQUAL, the
 1522                  * subject must have appropriate privilege.
 1523                  */
 1524                 if (biba_contains_equal(new)) {
 1525                         error = biba_subject_privileged(subj);
 1526                         if (error)
 1527                                 return (error);
 1528                 }
 1529         }
 1530 
 1531         return (0);
 1532 }
 1533 
 1534 static int
 1535 biba_pipe_check_stat(struct ucred *cred, struct pipepair *pp,
 1536     struct label *pplabel)
 1537 {
 1538         struct mac_biba *subj, *obj;
 1539 
 1540         if (!biba_enabled)
 1541                 return (0);
 1542 
 1543         subj = SLOT(cred->cr_label);
 1544         obj = SLOT(pplabel);
 1545 
 1546         if (!biba_dominate_effective(obj, subj))
 1547                 return (EACCES);
 1548 
 1549         return (0);
 1550 }
 1551 
 1552 static int
 1553 biba_pipe_check_write(struct ucred *cred, struct pipepair *pp,
 1554     struct label *pplabel)
 1555 {
 1556         struct mac_biba *subj, *obj;
 1557 
 1558         if (!biba_enabled)
 1559                 return (0);
 1560 
 1561         subj = SLOT(cred->cr_label);
 1562         obj = SLOT(pplabel);
 1563 
 1564         if (!biba_dominate_effective(subj, obj))
 1565                 return (EACCES);
 1566 
 1567         return (0);
 1568 }
 1569 
 1570 static void
 1571 biba_pipe_create(struct ucred *cred, struct pipepair *pp,
 1572     struct label *pplabel)
 1573 {
 1574         struct mac_biba *source, *dest;
 1575 
 1576         source = SLOT(cred->cr_label);
 1577         dest = SLOT(pplabel);
 1578 
 1579         biba_copy_effective(source, dest);
 1580 }
 1581 
 1582 static void
 1583 biba_pipe_relabel(struct ucred *cred, struct pipepair *pp,
 1584     struct label *pplabel, struct label *newlabel)
 1585 {
 1586         struct mac_biba *source, *dest;
 1587 
 1588         source = SLOT(newlabel);
 1589         dest = SLOT(pplabel);
 1590 
 1591         biba_copy(source, dest);
 1592 }
 1593 
 1594 static int
 1595 biba_posixsem_check_openunlink(struct ucred *cred, struct ksem *ks,
 1596     struct label *kslabel)
 1597 {
 1598         struct mac_biba *subj, *obj;
 1599 
 1600         if (!biba_enabled)
 1601                 return (0);
 1602 
 1603         subj = SLOT(cred->cr_label);
 1604         obj = SLOT(kslabel);
 1605 
 1606         if (!biba_dominate_effective(subj, obj))
 1607                 return (EACCES);
 1608 
 1609         return (0);
 1610 }
 1611 
 1612 static int
 1613 biba_posixsem_check_setmode(struct ucred *cred, struct ksem *ks,
 1614     struct label *kslabel, mode_t mode)
 1615 {
 1616         struct mac_biba *subj, *obj;
 1617 
 1618         if (!biba_enabled)
 1619                 return (0);
 1620 
 1621         subj = SLOT(cred->cr_label);
 1622         obj = SLOT(kslabel);
 1623 
 1624         if (!biba_dominate_effective(subj, obj))
 1625                 return (EACCES);
 1626 
 1627         return (0);
 1628 }
 1629 
 1630 static int
 1631 biba_posixsem_check_setowner(struct ucred *cred, struct ksem *ks,
 1632     struct label *kslabel, uid_t uid, gid_t gid)
 1633 {
 1634         struct mac_biba *subj, *obj;
 1635 
 1636         if (!biba_enabled)
 1637                 return (0);
 1638 
 1639         subj = SLOT(cred->cr_label);
 1640         obj = SLOT(kslabel);
 1641 
 1642         if (!biba_dominate_effective(subj, obj))
 1643                 return (EACCES);
 1644 
 1645         return (0);
 1646 }
 1647 
 1648 static int
 1649 biba_posixsem_check_write(struct ucred *active_cred, struct ucred *file_cred,
 1650     struct ksem *ks, struct label *kslabel)
 1651 {
 1652         struct mac_biba *subj, *obj;
 1653 
 1654         if (!biba_enabled)
 1655                 return (0);
 1656 
 1657         subj = SLOT(active_cred->cr_label);
 1658         obj = SLOT(kslabel);
 1659 
 1660         if (!biba_dominate_effective(subj, obj))
 1661                 return (EACCES);
 1662 
 1663         return (0);
 1664 }
 1665 
 1666 static int
 1667 biba_posixsem_check_rdonly(struct ucred *active_cred, struct ucred *file_cred,
 1668     struct ksem *ks, struct label *kslabel)
 1669 {
 1670         struct mac_biba *subj, *obj;
 1671 
 1672         if (!biba_enabled)
 1673                 return (0);
 1674 
 1675         subj = SLOT(active_cred->cr_label);
 1676         obj = SLOT(kslabel);
 1677 
 1678         if (!biba_dominate_effective(obj, subj))
 1679                 return (EACCES);
 1680 
 1681         return (0);
 1682 }
 1683 
 1684 static void
 1685 biba_posixsem_create(struct ucred *cred, struct ksem *ks,
 1686     struct label *kslabel)
 1687 {
 1688         struct mac_biba *source, *dest;
 1689 
 1690         source = SLOT(cred->cr_label);
 1691         dest = SLOT(kslabel);
 1692 
 1693         biba_copy_effective(source, dest);
 1694 }
 1695 
 1696 static int
 1697 biba_posixshm_check_mmap(struct ucred *cred, struct shmfd *shmfd,
 1698     struct label *shmlabel, int prot, int flags)
 1699 {
 1700         struct mac_biba *subj, *obj;
 1701 
 1702         if (!biba_enabled || !revocation_enabled)
 1703                 return (0);
 1704 
 1705         subj = SLOT(cred->cr_label);
 1706         obj = SLOT(shmlabel);
 1707 
 1708         if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
 1709                 if (!biba_dominate_effective(obj, subj))
 1710                         return (EACCES);
 1711         }
 1712         if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) {
 1713                 if (!biba_dominate_effective(subj, obj))
 1714                         return (EACCES);
 1715         }
 1716 
 1717         return (0);
 1718 }
 1719 
 1720 static int
 1721 biba_posixshm_check_open(struct ucred *cred, struct shmfd *shmfd,
 1722     struct label *shmlabel, accmode_t accmode)
 1723 {
 1724         struct mac_biba *subj, *obj;
 1725 
 1726         if (!biba_enabled)
 1727                 return (0);
 1728 
 1729         subj = SLOT(cred->cr_label);
 1730         obj = SLOT(shmlabel);
 1731 
 1732         if (accmode & (VREAD | VEXEC | VSTAT_PERMS)) {
 1733                 if (!biba_dominate_effective(obj, subj))
 1734                         return (EACCES);
 1735         }
 1736         if (accmode & VMODIFY_PERMS) {
 1737                 if (!biba_dominate_effective(subj, obj))
 1738                         return (EACCES);
 1739         }
 1740 
 1741         return (0);
 1742 }
 1743 
 1744 static int
 1745 biba_posixshm_check_read(struct ucred *active_cred, struct ucred *file_cred,
 1746     struct shmfd *vp, struct label *shmlabel)
 1747 {
 1748         struct mac_biba *subj, *obj;
 1749 
 1750         if (!biba_enabled || !revocation_enabled)
 1751                 return (0);
 1752 
 1753         subj = SLOT(active_cred->cr_label);
 1754         obj = SLOT(shmlabel);
 1755 
 1756         if (!biba_dominate_effective(obj, subj))
 1757                 return (EACCES);
 1758 
 1759         return (0);
 1760 }
 1761 
 1762 static int
 1763 biba_posixshm_check_setmode(struct ucred *cred, struct shmfd *shmfd,
 1764     struct label *shmlabel, mode_t mode)
 1765 {
 1766         struct mac_biba *subj, *obj;
 1767 
 1768         if (!biba_enabled)
 1769                 return (0);
 1770 
 1771         subj = SLOT(cred->cr_label);
 1772         obj = SLOT(shmlabel);
 1773 
 1774         if (!biba_dominate_effective(subj, obj))
 1775                 return (EACCES);
 1776 
 1777         return (0);
 1778 }
 1779 
 1780 static int
 1781 biba_posixshm_check_setowner(struct ucred *cred, struct shmfd *shmfd,
 1782     struct label *shmlabel, uid_t uid, gid_t gid)
 1783 {
 1784         struct mac_biba *subj, *obj;
 1785 
 1786         if (!biba_enabled)
 1787                 return (0);
 1788 
 1789         subj = SLOT(cred->cr_label);
 1790         obj = SLOT(shmlabel);
 1791 
 1792         if (!biba_dominate_effective(subj, obj))
 1793                 return (EACCES);
 1794 
 1795         return (0);
 1796 }
 1797 
 1798 static int
 1799 biba_posixshm_check_stat(struct ucred *active_cred, struct ucred *file_cred,
 1800     struct shmfd *shmfd, struct label *shmlabel)
 1801 {
 1802         struct mac_biba *subj, *obj;
 1803 
 1804         if (!biba_enabled)
 1805                 return (0);
 1806 
 1807         subj = SLOT(active_cred->cr_label);
 1808         obj = SLOT(shmlabel);
 1809 
 1810         if (!biba_dominate_effective(obj, subj))
 1811                 return (EACCES);
 1812 
 1813         return (0);
 1814 }
 1815 
 1816 static int
 1817 biba_posixshm_check_truncate(struct ucred *active_cred,
 1818     struct ucred *file_cred, struct shmfd *shmfd, struct label *shmlabel)
 1819 {
 1820         struct mac_biba *subj, *obj;
 1821 
 1822         if (!biba_enabled)
 1823                 return (0);
 1824 
 1825         subj = SLOT(active_cred->cr_label);
 1826         obj = SLOT(shmlabel);
 1827 
 1828         if (!biba_dominate_effective(subj, obj))
 1829                 return (EACCES);
 1830 
 1831         return (0);
 1832 }
 1833 
 1834 static int
 1835 biba_posixshm_check_unlink(struct ucred *cred, struct shmfd *shmfd,
 1836     struct label *shmlabel)
 1837 {
 1838         struct mac_biba *subj, *obj;
 1839 
 1840         if (!biba_enabled)
 1841                 return (0);
 1842 
 1843         subj = SLOT(cred->cr_label);
 1844         obj = SLOT(shmlabel);
 1845 
 1846         if (!biba_dominate_effective(subj, obj))
 1847                 return (EACCES);
 1848     
 1849         return (0);
 1850 }
 1851 
 1852 static int
 1853 biba_posixshm_check_write(struct ucred *active_cred, struct ucred *file_cred,
 1854     struct shmfd *vp, struct label *shmlabel)
 1855 {
 1856         struct mac_biba *subj, *obj;
 1857 
 1858         if (!biba_enabled || !revocation_enabled)
 1859                 return (0);
 1860 
 1861         subj = SLOT(active_cred->cr_label);
 1862         obj = SLOT(shmlabel);
 1863 
 1864         if (!biba_dominate_effective(obj, subj))
 1865                 return (EACCES);
 1866 
 1867         return (0);
 1868 }
 1869 
 1870 static void
 1871 biba_posixshm_create(struct ucred *cred, struct shmfd *shmfd,
 1872     struct label *shmlabel)
 1873 {
 1874         struct mac_biba *source, *dest;
 1875 
 1876         source = SLOT(cred->cr_label);
 1877         dest = SLOT(shmlabel);
 1878 
 1879         biba_copy_effective(source, dest);
 1880 }
 1881 
 1882 /*
 1883  * Some system privileges are allowed regardless of integrity grade; others
 1884  * are allowed only when running with privilege with respect to the Biba
 1885  * policy as they might otherwise allow bypassing of the integrity policy.
 1886  */
 1887 static int
 1888 biba_priv_check(struct ucred *cred, int priv)
 1889 {
 1890         struct mac_biba *subj;
 1891         int error;
 1892 
 1893         if (!biba_enabled)
 1894                 return (0);
 1895 
 1896         /*
 1897          * Exempt only specific privileges from the Biba integrity policy.
 1898          */
 1899         switch (priv) {
 1900         case PRIV_KTRACE:
 1901         case PRIV_MSGBUF:
 1902 
 1903         /*
 1904          * Allow processes to manipulate basic process audit properties, and
 1905          * to submit audit records.
 1906          */
 1907         case PRIV_AUDIT_GETAUDIT:
 1908         case PRIV_AUDIT_SETAUDIT:
 1909         case PRIV_AUDIT_SUBMIT:
 1910 
 1911         /*
 1912          * Allow processes to manipulate their regular UNIX credentials.
 1913          */
 1914         case PRIV_CRED_SETUID:
 1915         case PRIV_CRED_SETEUID:
 1916         case PRIV_CRED_SETGID:
 1917         case PRIV_CRED_SETEGID:
 1918         case PRIV_CRED_SETGROUPS:
 1919         case PRIV_CRED_SETREUID:
 1920         case PRIV_CRED_SETREGID:
 1921         case PRIV_CRED_SETRESUID:
 1922         case PRIV_CRED_SETRESGID:
 1923 
 1924         /*
 1925          * Allow processes to perform system monitoring.
 1926          */
 1927         case PRIV_SEEOTHERGIDS:
 1928         case PRIV_SEEOTHERUIDS:
 1929                 break;
 1930 
 1931         /*
 1932          * Allow access to general process debugging facilities.  We
 1933          * separately control debugging based on MAC label.
 1934          */
 1935         case PRIV_DEBUG_DIFFCRED:
 1936         case PRIV_DEBUG_SUGID:
 1937         case PRIV_DEBUG_UNPRIV:
 1938 
 1939         /*
 1940          * Allow manipulating jails.
 1941          */
 1942         case PRIV_JAIL_ATTACH:
 1943 
 1944         /*
 1945          * Allow privilege with respect to the Partition policy, but not the
 1946          * Privs policy.
 1947          */
 1948         case PRIV_MAC_PARTITION:
 1949 
 1950         /*
 1951          * Allow privilege with respect to process resource limits and login
 1952          * context.
 1953          */
 1954         case PRIV_PROC_LIMIT:
 1955         case PRIV_PROC_SETLOGIN:
 1956         case PRIV_PROC_SETRLIMIT:
 1957 
 1958         /*
 1959          * Allow System V and POSIX IPC privileges.
 1960          */
 1961         case PRIV_IPC_READ:
 1962         case PRIV_IPC_WRITE:
 1963         case PRIV_IPC_ADMIN:
 1964         case PRIV_IPC_MSGSIZE:
 1965         case PRIV_MQ_ADMIN:
 1966 
 1967         /*
 1968          * Allow certain scheduler manipulations -- possibly this should be
 1969          * controlled by more fine-grained policy, as potentially low
 1970          * integrity processes can deny CPU to higher integrity ones.
 1971          */
 1972         case PRIV_SCHED_DIFFCRED:
 1973         case PRIV_SCHED_SETPRIORITY:
 1974         case PRIV_SCHED_RTPRIO:
 1975         case PRIV_SCHED_SETPOLICY:
 1976         case PRIV_SCHED_SET:
 1977         case PRIV_SCHED_SETPARAM:
 1978         case PRIV_SCHED_IDPRIO:
 1979 
 1980         /*
 1981          * More IPC privileges.
 1982          */
 1983         case PRIV_SEM_WRITE:
 1984 
 1985         /*
 1986          * Allow signaling privileges subject to integrity policy.
 1987          */
 1988         case PRIV_SIGNAL_DIFFCRED:
 1989         case PRIV_SIGNAL_SUGID:
 1990 
 1991         /*
 1992          * Allow access to only limited sysctls from lower integrity levels;
 1993          * piggy-back on the Jail definition.
 1994          */
 1995         case PRIV_SYSCTL_WRITEJAIL:
 1996 
 1997         /*
 1998          * Allow TTY-based privileges, subject to general device access using
 1999          * labels on TTY device nodes, but not console privilege.
 2000          */
 2001         case PRIV_TTY_DRAINWAIT:
 2002         case PRIV_TTY_DTRWAIT:
 2003         case PRIV_TTY_EXCLUSIVE:
 2004         case PRIV_TTY_STI:
 2005         case PRIV_TTY_SETA:
 2006 
 2007         /*
 2008          * Grant most VFS privileges, as almost all are in practice bounded
 2009          * by more specific checks using labels.
 2010          */
 2011         case PRIV_VFS_READ:
 2012         case PRIV_VFS_WRITE:
 2013         case PRIV_VFS_ADMIN:
 2014         case PRIV_VFS_EXEC:
 2015         case PRIV_VFS_LOOKUP:
 2016         case PRIV_VFS_CHFLAGS_DEV:
 2017         case PRIV_VFS_CHOWN:
 2018         case PRIV_VFS_CHROOT:
 2019         case PRIV_VFS_RETAINSUGID:
 2020         case PRIV_VFS_EXCEEDQUOTA:
 2021         case PRIV_VFS_FCHROOT:
 2022         case PRIV_VFS_FHOPEN:
 2023         case PRIV_VFS_FHSTATFS:
 2024         case PRIV_VFS_GENERATION:
 2025         case PRIV_VFS_GETFH:
 2026         case PRIV_VFS_GETQUOTA:
 2027         case PRIV_VFS_LINK:
 2028         case PRIV_VFS_MOUNT:
 2029         case PRIV_VFS_MOUNT_OWNER:
 2030         case PRIV_VFS_MOUNT_PERM:
 2031         case PRIV_VFS_MOUNT_SUIDDIR:
 2032         case PRIV_VFS_MOUNT_NONUSER:
 2033         case PRIV_VFS_SETGID:
 2034         case PRIV_VFS_STICKYFILE:
 2035         case PRIV_VFS_SYSFLAGS:
 2036         case PRIV_VFS_UNMOUNT:
 2037 
 2038         /*
 2039          * Allow VM privileges; it would be nice if these were subject to
 2040          * resource limits.
 2041          */
 2042         case PRIV_VM_MADV_PROTECT:
 2043         case PRIV_VM_MLOCK:
 2044         case PRIV_VM_MUNLOCK:
 2045         case PRIV_VM_SWAP_NOQUOTA:
 2046         case PRIV_VM_SWAP_NORLIMIT:
 2047 
 2048         /*
 2049          * Allow some but not all network privileges.  In general, dont allow
 2050          * reconfiguring the network stack, just normal use.
 2051          */
 2052         case PRIV_NETINET_RESERVEDPORT:
 2053         case PRIV_NETINET_RAW:
 2054         case PRIV_NETINET_REUSEPORT:
 2055                 break;
 2056 
 2057         /*
 2058          * All remaining system privileges are allow only if the process
 2059          * holds privilege with respect to the Biba policy.
 2060          */
 2061         default:
 2062                 subj = SLOT(cred->cr_label);
 2063                 error = biba_subject_privileged(subj);
 2064                 if (error)
 2065                         return (error);
 2066         }
 2067         return (0);
 2068 }
 2069 
 2070 static int
 2071 biba_proc_check_debug(struct ucred *cred, struct proc *p)
 2072 {
 2073         struct mac_biba *subj, *obj;
 2074 
 2075         if (!biba_enabled)
 2076                 return (0);
 2077 
 2078         subj = SLOT(cred->cr_label);
 2079         obj = SLOT(p->p_ucred->cr_label);
 2080 
 2081         /* XXX: range checks */
 2082         if (!biba_dominate_effective(obj, subj))
 2083                 return (ESRCH);
 2084         if (!biba_dominate_effective(subj, obj))
 2085                 return (EACCES);
 2086 
 2087         return (0);
 2088 }
 2089 
 2090 static int
 2091 biba_proc_check_sched(struct ucred *cred, struct proc *p)
 2092 {
 2093         struct mac_biba *subj, *obj;
 2094 
 2095         if (!biba_enabled)
 2096                 return (0);
 2097 
 2098         subj = SLOT(cred->cr_label);
 2099         obj = SLOT(p->p_ucred->cr_label);
 2100 
 2101         /* XXX: range checks */
 2102         if (!biba_dominate_effective(obj, subj))
 2103                 return (ESRCH);
 2104         if (!biba_dominate_effective(subj, obj))
 2105                 return (EACCES);
 2106 
 2107         return (0);
 2108 }
 2109 
 2110 static int
 2111 biba_proc_check_signal(struct ucred *cred, struct proc *p, int signum)
 2112 {
 2113         struct mac_biba *subj, *obj;
 2114 
 2115         if (!biba_enabled)
 2116                 return (0);
 2117 
 2118         subj = SLOT(cred->cr_label);
 2119         obj = SLOT(p->p_ucred->cr_label);
 2120 
 2121         /* XXX: range checks */
 2122         if (!biba_dominate_effective(obj, subj))
 2123                 return (ESRCH);
 2124         if (!biba_dominate_effective(subj, obj))
 2125                 return (EACCES);
 2126 
 2127         return (0);
 2128 }
 2129 
 2130 static int
 2131 biba_socket_check_deliver(struct socket *so, struct label *solabel,
 2132     struct mbuf *m, struct label *mlabel)
 2133 {
 2134         struct mac_biba *p, *s;
 2135         int error;
 2136 
 2137         if (!biba_enabled)
 2138                 return (0);
 2139 
 2140         p = SLOT(mlabel);
 2141         s = SLOT(solabel);
 2142 
 2143         SOCK_LOCK(so);
 2144         error = biba_equal_effective(p, s) ? 0 : EACCES;
 2145         SOCK_UNLOCK(so);
 2146         return (error);
 2147 }
 2148 
 2149 static int
 2150 biba_socket_check_relabel(struct ucred *cred, struct socket *so,
 2151     struct label *solabel, struct label *newlabel)
 2152 {
 2153         struct mac_biba *subj, *obj, *new;
 2154         int error;
 2155 
 2156         SOCK_LOCK_ASSERT(so);
 2157 
 2158         new = SLOT(newlabel);
 2159         subj = SLOT(cred->cr_label);
 2160         obj = SLOT(solabel);
 2161 
 2162         /*
 2163          * If there is a Biba label update for the socket, it may be an
 2164          * update of effective.
 2165          */
 2166         error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE);
 2167         if (error)
 2168                 return (error);
 2169 
 2170         /*
 2171          * To relabel a socket, the old socket effective must be in the
 2172          * subject range.
 2173          */
 2174         if (!biba_effective_in_range(obj, subj))
 2175                 return (EPERM);
 2176 
 2177         /*
 2178          * If the Biba label is to be changed, authorize as appropriate.
 2179          */
 2180         if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
 2181                 /*
 2182                  * To relabel a socket, the new socket effective must be in
 2183                  * the subject range.
 2184                  */
 2185                 if (!biba_effective_in_range(new, subj))
 2186                         return (EPERM);
 2187 
 2188                 /*
 2189                  * To change the Biba label on the socket to contain EQUAL,
 2190                  * the subject must have appropriate privilege.
 2191                  */
 2192                 if (biba_contains_equal(new)) {
 2193                         error = biba_subject_privileged(subj);
 2194                         if (error)
 2195                                 return (error);
 2196                 }
 2197         }
 2198 
 2199         return (0);
 2200 }
 2201 
 2202 static int
 2203 biba_socket_check_visible(struct ucred *cred, struct socket *so,
 2204     struct label *solabel)
 2205 {
 2206         struct mac_biba *subj, *obj;
 2207 
 2208         if (!biba_enabled)
 2209                 return (0);
 2210 
 2211         subj = SLOT(cred->cr_label);
 2212         obj = SLOT(solabel);
 2213 
 2214         SOCK_LOCK(so);
 2215         if (!biba_dominate_effective(obj, subj)) {
 2216                 SOCK_UNLOCK(so);
 2217                 return (ENOENT);
 2218         }
 2219         SOCK_UNLOCK(so);
 2220 
 2221         return (0);
 2222 }
 2223 
 2224 static void
 2225 biba_socket_create(struct ucred *cred, struct socket *so,
 2226     struct label *solabel)
 2227 {
 2228         struct mac_biba *source, *dest;
 2229 
 2230         source = SLOT(cred->cr_label);
 2231         dest = SLOT(solabel);
 2232 
 2233         biba_copy_effective(source, dest);
 2234 }
 2235 
 2236 static void
 2237 biba_socket_create_mbuf(struct socket *so, struct label *solabel,
 2238     struct mbuf *m, struct label *mlabel)
 2239 {
 2240         struct mac_biba *source, *dest;
 2241 
 2242         source = SLOT(solabel);
 2243         dest = SLOT(mlabel);
 2244 
 2245         SOCK_LOCK(so);
 2246         biba_copy_effective(source, dest);
 2247         SOCK_UNLOCK(so);
 2248 }
 2249 
 2250 static void
 2251 biba_socket_newconn(struct socket *oldso, struct label *oldsolabel,
 2252     struct socket *newso, struct label *newsolabel)
 2253 {
 2254         struct mac_biba source, *dest;
 2255 
 2256         SOCK_LOCK(oldso);
 2257         source = *SLOT(oldsolabel);
 2258         SOCK_UNLOCK(oldso);
 2259 
 2260         dest = SLOT(newsolabel);
 2261 
 2262         SOCK_LOCK(newso);
 2263         biba_copy_effective(&source, dest);
 2264         SOCK_UNLOCK(newso);
 2265 }
 2266 
 2267 static void
 2268 biba_socket_relabel(struct ucred *cred, struct socket *so,
 2269     struct label *solabel, struct label *newlabel)
 2270 {
 2271         struct mac_biba *source, *dest;
 2272 
 2273         SOCK_LOCK_ASSERT(so);
 2274 
 2275         source = SLOT(newlabel);
 2276         dest = SLOT(solabel);
 2277 
 2278         biba_copy(source, dest);
 2279 }
 2280 
 2281 static void
 2282 biba_socketpeer_set_from_mbuf(struct mbuf *m, struct label *mlabel,
 2283     struct socket *so, struct label *sopeerlabel)
 2284 {
 2285         struct mac_biba *source, *dest;
 2286 
 2287         source = SLOT(mlabel);
 2288         dest = SLOT(sopeerlabel);
 2289 
 2290         SOCK_LOCK(so);
 2291         biba_copy_effective(source, dest);
 2292         SOCK_UNLOCK(so);
 2293 }
 2294 
 2295 static void
 2296 biba_socketpeer_set_from_socket(struct socket *oldso,
 2297     struct label *oldsolabel, struct socket *newso,
 2298     struct label *newsopeerlabel)
 2299 {
 2300         struct mac_biba source, *dest;
 2301 
 2302         SOCK_LOCK(oldso);
 2303         source = *SLOT(oldsolabel);
 2304         SOCK_UNLOCK(oldso);
 2305         dest = SLOT(newsopeerlabel);
 2306 
 2307         SOCK_LOCK(newso);
 2308         biba_copy_effective(&source, dest);
 2309         SOCK_UNLOCK(newso);
 2310 }
 2311 
 2312 static void
 2313 biba_syncache_create(struct label *label, struct inpcb *inp)
 2314 {
 2315         struct mac_biba *source, *dest;
 2316 
 2317         source = SLOT(inp->inp_label);
 2318         dest = SLOT(label);
 2319         biba_copy_effective(source, dest);
 2320 }
 2321 
 2322 static void
 2323 biba_syncache_create_mbuf(struct label *sc_label, struct mbuf *m,
 2324     struct label *mlabel)
 2325 {
 2326         struct mac_biba *source, *dest;
 2327 
 2328         source = SLOT(sc_label);
 2329         dest = SLOT(mlabel);
 2330         biba_copy_effective(source, dest);
 2331 }
 2332 
 2333 static int
 2334 biba_system_check_acct(struct ucred *cred, struct vnode *vp,
 2335     struct label *vplabel)
 2336 {
 2337         struct mac_biba *subj, *obj;
 2338         int error;
 2339 
 2340         if (!biba_enabled)
 2341                 return (0);
 2342 
 2343         subj = SLOT(cred->cr_label);
 2344 
 2345         error = biba_subject_privileged(subj);
 2346         if (error)
 2347                 return (error);
 2348 
 2349         if (vplabel == NULL)
 2350                 return (0);
 2351 
 2352         obj = SLOT(vplabel);
 2353         if (!biba_high_effective(obj))
 2354                 return (EACCES);
 2355 
 2356         return (0);
 2357 }
 2358 
 2359 static int
 2360 biba_system_check_auditctl(struct ucred *cred, struct vnode *vp,
 2361     struct label *vplabel)
 2362 {
 2363         struct mac_biba *subj, *obj;
 2364         int error;
 2365 
 2366         if (!biba_enabled)
 2367                 return (0);
 2368 
 2369         subj = SLOT(cred->cr_label);
 2370 
 2371         error = biba_subject_privileged(subj);
 2372         if (error)
 2373                 return (error);
 2374 
 2375         if (vplabel == NULL)
 2376                 return (0);
 2377 
 2378         obj = SLOT(vplabel);
 2379         if (!biba_high_effective(obj))
 2380                 return (EACCES);
 2381 
 2382         return (0);
 2383 }
 2384 
 2385 static int
 2386 biba_system_check_auditon(struct ucred *cred, int cmd)
 2387 {
 2388         struct mac_biba *subj;
 2389         int error;
 2390 
 2391         if (!biba_enabled)
 2392                 return (0);
 2393 
 2394         subj = SLOT(cred->cr_label);
 2395 
 2396         error = biba_subject_privileged(subj);
 2397         if (error)
 2398                 return (error);
 2399 
 2400         return (0);
 2401 }
 2402 
 2403 static int
 2404 biba_system_check_swapoff(struct ucred *cred, struct vnode *vp,
 2405     struct label *label)
 2406 {
 2407         struct mac_biba *subj;
 2408         int error;
 2409 
 2410         if (!biba_enabled)
 2411                 return (0);
 2412 
 2413         subj = SLOT(cred->cr_label);
 2414 
 2415         error = biba_subject_privileged(subj);
 2416         if (error)
 2417                 return (error);
 2418 
 2419         return (0);
 2420 }
 2421 
 2422 static int
 2423 biba_system_check_swapon(struct ucred *cred, struct vnode *vp,
 2424     struct label *vplabel)
 2425 {
 2426         struct mac_biba *subj, *obj;
 2427         int error;
 2428 
 2429         if (!biba_enabled)
 2430                 return (0);
 2431 
 2432         subj = SLOT(cred->cr_label);
 2433         obj = SLOT(vplabel);
 2434 
 2435         error = biba_subject_privileged(subj);
 2436         if (error)
 2437                 return (error);
 2438 
 2439         if (!biba_high_effective(obj))
 2440                 return (EACCES);
 2441 
 2442         return (0);
 2443 }
 2444 
 2445 static int
 2446 biba_system_check_sysctl(struct ucred *cred, struct sysctl_oid *oidp,
 2447     void *arg1, int arg2, struct sysctl_req *req)
 2448 {
 2449         struct mac_biba *subj;
 2450         int error;
 2451 
 2452         if (!biba_enabled)
 2453                 return (0);
 2454 
 2455         subj = SLOT(cred->cr_label);
 2456 
 2457         /*
 2458          * Treat sysctl variables without CTLFLAG_ANYBODY flag as biba/high,
 2459          * but also require privilege to change them.
 2460          */
 2461         if (req->newptr != NULL && (oidp->oid_kind & CTLFLAG_ANYBODY) == 0) {
 2462                 if (!biba_subject_dominate_high(subj))
 2463                         return (EACCES);
 2464 
 2465                 error = biba_subject_privileged(subj);
 2466                 if (error)
 2467                         return (error);
 2468         }
 2469 
 2470         return (0);
 2471 }
 2472 
 2473 static void
 2474 biba_sysvmsg_cleanup(struct label *msglabel)
 2475 {
 2476 
 2477         bzero(SLOT(msglabel), sizeof(struct mac_biba));
 2478 }
 2479 
 2480 static void
 2481 biba_sysvmsg_create(struct ucred *cred, struct msqid_kernel *msqkptr,
 2482     struct label *msqlabel, struct msg *msgptr, struct label *msglabel)
 2483 {
 2484         struct mac_biba *source, *dest;
 2485 
 2486         /* Ignore the msgq label */
 2487         source = SLOT(cred->cr_label);
 2488         dest = SLOT(msglabel);
 2489 
 2490         biba_copy_effective(source, dest);
 2491 }
 2492 
 2493 static int
 2494 biba_sysvmsq_check_msgrcv(struct ucred *cred, struct msg *msgptr,
 2495     struct label *msglabel)
 2496 {
 2497         struct mac_biba *subj, *obj;
 2498 
 2499         if (!biba_enabled)
 2500                 return (0);
 2501 
 2502         subj = SLOT(cred->cr_label);
 2503         obj = SLOT(msglabel);
 2504 
 2505         if (!biba_dominate_effective(obj, subj))
 2506                 return (EACCES);
 2507 
 2508         return (0);
 2509 }
 2510 
 2511 static int
 2512 biba_sysvmsq_check_msgrmid(struct ucred *cred, struct msg *msgptr,
 2513     struct label *msglabel)
 2514 {
 2515         struct mac_biba *subj, *obj;
 2516 
 2517         if (!biba_enabled)
 2518                 return (0);
 2519 
 2520         subj = SLOT(cred->cr_label);
 2521         obj = SLOT(msglabel);
 2522 
 2523         if (!biba_dominate_effective(subj, obj))
 2524                 return (EACCES);
 2525 
 2526         return (0);
 2527 }
 2528 
 2529 static int
 2530 biba_sysvmsq_check_msqget(struct ucred *cred, struct msqid_kernel *msqkptr,
 2531     struct label *msqklabel)
 2532 {
 2533         struct mac_biba *subj, *obj;
 2534 
 2535         if (!biba_enabled)
 2536                 return (0);
 2537 
 2538         subj = SLOT(cred->cr_label);
 2539         obj = SLOT(msqklabel);
 2540 
 2541         if (!biba_dominate_effective(obj, subj))
 2542                 return (EACCES);
 2543 
 2544         return (0);
 2545 }
 2546 
 2547 static int
 2548 biba_sysvmsq_check_msqsnd(struct ucred *cred, struct msqid_kernel *msqkptr,
 2549     struct label *msqklabel)
 2550 {
 2551         struct mac_biba *subj, *obj;
 2552 
 2553         if (!biba_enabled)
 2554                 return (0);
 2555 
 2556         subj = SLOT(cred->cr_label);
 2557         obj = SLOT(msqklabel);
 2558 
 2559         if (!biba_dominate_effective(subj, obj))
 2560                 return (EACCES);
 2561 
 2562         return (0);
 2563 }
 2564 
 2565 static int
 2566 biba_sysvmsq_check_msqrcv(struct ucred *cred, struct msqid_kernel *msqkptr,
 2567     struct label *msqklabel)
 2568 {
 2569         struct mac_biba *subj, *obj;
 2570 
 2571         if (!biba_enabled)
 2572                 return (0);
 2573 
 2574         subj = SLOT(cred->cr_label);
 2575         obj = SLOT(msqklabel);
 2576 
 2577         if (!biba_dominate_effective(obj, subj))
 2578                 return (EACCES);
 2579 
 2580         return (0);
 2581 }
 2582 
 2583 static int
 2584 biba_sysvmsq_check_msqctl(struct ucred *cred, struct msqid_kernel *msqkptr,
 2585     struct label *msqklabel, int cmd)
 2586 {
 2587         struct mac_biba *subj, *obj;
 2588 
 2589         if (!biba_enabled)
 2590                 return (0);
 2591 
 2592         subj = SLOT(cred->cr_label);
 2593         obj = SLOT(msqklabel);
 2594 
 2595         switch(cmd) {
 2596         case IPC_RMID:
 2597         case IPC_SET:
 2598                 if (!biba_dominate_effective(subj, obj))
 2599                         return (EACCES);
 2600                 break;
 2601 
 2602         case IPC_STAT:
 2603                 if (!biba_dominate_effective(obj, subj))
 2604                         return (EACCES);
 2605                 break;
 2606 
 2607         default:
 2608                 return (EACCES);
 2609         }
 2610 
 2611         return (0);
 2612 }
 2613 
 2614 static void
 2615 biba_sysvmsq_cleanup(struct label *msqlabel)
 2616 {
 2617 
 2618         bzero(SLOT(msqlabel), sizeof(struct mac_biba));
 2619 }
 2620 
 2621 static void
 2622 biba_sysvmsq_create(struct ucred *cred, struct msqid_kernel *msqkptr,
 2623     struct label *msqlabel)
 2624 {
 2625         struct mac_biba *source, *dest;
 2626 
 2627         source = SLOT(cred->cr_label);
 2628         dest = SLOT(msqlabel);
 2629 
 2630         biba_copy_effective(source, dest);
 2631 }
 2632 
 2633 static int
 2634 biba_sysvsem_check_semctl(struct ucred *cred, struct semid_kernel *semakptr,
 2635     struct label *semaklabel, int cmd)
 2636 {
 2637         struct mac_biba *subj, *obj;
 2638 
 2639         if (!biba_enabled)
 2640                 return (0);
 2641 
 2642         subj = SLOT(cred->cr_label);
 2643         obj = SLOT(semaklabel);
 2644 
 2645         switch(cmd) {
 2646         case IPC_RMID:
 2647         case IPC_SET:
 2648         case SETVAL:
 2649         case SETALL:
 2650                 if (!biba_dominate_effective(subj, obj))
 2651                         return (EACCES);
 2652                 break;
 2653 
 2654         case IPC_STAT:
 2655         case GETVAL:
 2656         case GETPID:
 2657         case GETNCNT:
 2658         case GETZCNT:
 2659         case GETALL:
 2660                 if (!biba_dominate_effective(obj, subj))
 2661                         return (EACCES);
 2662                 break;
 2663 
 2664         default:
 2665                 return (EACCES);
 2666         }
 2667 
 2668         return (0);
 2669 }
 2670 
 2671 static int
 2672 biba_sysvsem_check_semget(struct ucred *cred, struct semid_kernel *semakptr,
 2673     struct label *semaklabel)
 2674 {
 2675         struct mac_biba *subj, *obj;
 2676 
 2677         if (!biba_enabled)
 2678                 return (0);
 2679 
 2680         subj = SLOT(cred->cr_label);
 2681         obj = SLOT(semaklabel);
 2682 
 2683         if (!biba_dominate_effective(obj, subj))
 2684                 return (EACCES);
 2685 
 2686         return (0);
 2687 }
 2688 
 2689 static int
 2690 biba_sysvsem_check_semop(struct ucred *cred, struct semid_kernel *semakptr,
 2691     struct label *semaklabel, size_t accesstype)
 2692 {
 2693         struct mac_biba *subj, *obj;
 2694 
 2695         if (!biba_enabled)
 2696                 return (0);
 2697 
 2698         subj = SLOT(cred->cr_label);
 2699         obj = SLOT(semaklabel);
 2700 
 2701         if (accesstype & SEM_R)
 2702                 if (!biba_dominate_effective(obj, subj))
 2703                         return (EACCES);
 2704 
 2705         if (accesstype & SEM_A)
 2706                 if (!biba_dominate_effective(subj, obj))
 2707                         return (EACCES);
 2708 
 2709         return (0);
 2710 }
 2711 
 2712 static void
 2713 biba_sysvsem_cleanup(struct label *semalabel)
 2714 {
 2715 
 2716         bzero(SLOT(semalabel), sizeof(struct mac_biba));
 2717 }
 2718 
 2719 static void
 2720 biba_sysvsem_create(struct ucred *cred, struct semid_kernel *semakptr,
 2721     struct label *semalabel)
 2722 {
 2723         struct mac_biba *source, *dest;
 2724 
 2725         source = SLOT(cred->cr_label);
 2726         dest = SLOT(semalabel);
 2727 
 2728         biba_copy_effective(source, dest);
 2729 }
 2730 
 2731 static int
 2732 biba_sysvshm_check_shmat(struct ucred *cred, struct shmid_kernel *shmsegptr,
 2733     struct label *shmseglabel, int shmflg)
 2734 {
 2735         struct mac_biba *subj, *obj;
 2736 
 2737         if (!biba_enabled)
 2738                 return (0);
 2739 
 2740         subj = SLOT(cred->cr_label);
 2741         obj = SLOT(shmseglabel);
 2742 
 2743         if (!biba_dominate_effective(obj, subj))
 2744                 return (EACCES);
 2745         if ((shmflg & SHM_RDONLY) == 0) {
 2746                 if (!biba_dominate_effective(subj, obj))
 2747                         return (EACCES);
 2748         }
 2749 
 2750         return (0);
 2751 }
 2752 
 2753 static int
 2754 biba_sysvshm_check_shmctl(struct ucred *cred, struct shmid_kernel *shmsegptr,
 2755     struct label *shmseglabel, int cmd)
 2756 {
 2757         struct mac_biba *subj, *obj;
 2758 
 2759         if (!biba_enabled)
 2760                 return (0);
 2761 
 2762         subj = SLOT(cred->cr_label);
 2763         obj = SLOT(shmseglabel);
 2764 
 2765         switch(cmd) {
 2766         case IPC_RMID:
 2767         case IPC_SET:
 2768                 if (!biba_dominate_effective(subj, obj))
 2769                         return (EACCES);
 2770                 break;
 2771 
 2772         case IPC_STAT:
 2773         case SHM_STAT:
 2774                 if (!biba_dominate_effective(obj, subj))
 2775                         return (EACCES);
 2776                 break;
 2777 
 2778         default:
 2779                 return (EACCES);
 2780         }
 2781 
 2782         return (0);
 2783 }
 2784 
 2785 static int
 2786 biba_sysvshm_check_shmget(struct ucred *cred, struct shmid_kernel *shmsegptr,
 2787     struct label *shmseglabel, int shmflg)
 2788 {
 2789         struct mac_biba *subj, *obj;
 2790 
 2791         if (!biba_enabled)
 2792                 return (0);
 2793 
 2794         subj = SLOT(cred->cr_label);
 2795         obj = SLOT(shmseglabel);
 2796 
 2797         if (!biba_dominate_effective(obj, subj))
 2798                 return (EACCES);
 2799 
 2800         return (0);
 2801 }
 2802 
 2803 static void
 2804 biba_sysvshm_cleanup(struct label *shmlabel)
 2805 {
 2806 
 2807         bzero(SLOT(shmlabel), sizeof(struct mac_biba));
 2808 }
 2809 
 2810 static void
 2811 biba_sysvshm_create(struct ucred *cred, struct shmid_kernel *shmsegptr,
 2812     struct label *shmlabel)
 2813 {
 2814         struct mac_biba *source, *dest;
 2815 
 2816         source = SLOT(cred->cr_label);
 2817         dest = SLOT(shmlabel);
 2818 
 2819         biba_copy_effective(source, dest);
 2820 }
 2821 
 2822 static int
 2823 biba_vnode_associate_extattr(struct mount *mp, struct label *mplabel,
 2824     struct vnode *vp, struct label *vplabel)
 2825 {
 2826         struct mac_biba mb_temp, *source, *dest;
 2827         int buflen, error;
 2828 
 2829         source = SLOT(mplabel);
 2830         dest = SLOT(vplabel);
 2831 
 2832         buflen = sizeof(mb_temp);
 2833         bzero(&mb_temp, buflen);
 2834 
 2835         error = vn_extattr_get(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
 2836             MAC_BIBA_EXTATTR_NAME, &buflen, (char *) &mb_temp, curthread);
 2837         if (error == ENOATTR || error == EOPNOTSUPP) {
 2838                 /* Fall back to the mntlabel. */
 2839                 biba_copy_effective(source, dest);
 2840                 return (0);
 2841         } else if (error)
 2842                 return (error);
 2843 
 2844         if (buflen != sizeof(mb_temp)) {
 2845                 printf("biba_vnode_associate_extattr: bad size %d\n",
 2846                     buflen);
 2847                 return (EPERM);
 2848         }
 2849         if (biba_valid(&mb_temp) != 0) {
 2850                 printf("biba_vnode_associate_extattr: invalid\n");
 2851                 return (EPERM);
 2852         }
 2853         if ((mb_temp.mb_flags & MAC_BIBA_FLAGS_BOTH) !=
 2854             MAC_BIBA_FLAG_EFFECTIVE) {
 2855                 printf("biba_vnode_associate_extattr: not effective\n");
 2856                 return (EPERM);
 2857         }
 2858 
 2859         biba_copy_effective(&mb_temp, dest);
 2860         return (0);
 2861 }
 2862 
 2863 static void
 2864 biba_vnode_associate_singlelabel(struct mount *mp, struct label *mplabel,
 2865     struct vnode *vp, struct label *vplabel)
 2866 {
 2867         struct mac_biba *source, *dest;
 2868 
 2869         source = SLOT(mplabel);
 2870         dest = SLOT(vplabel);
 2871 
 2872         biba_copy_effective(source, dest);
 2873 }
 2874 
 2875 static int
 2876 biba_vnode_check_chdir(struct ucred *cred, struct vnode *dvp,
 2877     struct label *dvplabel)
 2878 {
 2879         struct mac_biba *subj, *obj;
 2880 
 2881         if (!biba_enabled)
 2882                 return (0);
 2883 
 2884         subj = SLOT(cred->cr_label);
 2885         obj = SLOT(dvplabel);
 2886 
 2887         if (!biba_dominate_effective(obj, subj))
 2888                 return (EACCES);
 2889 
 2890         return (0);
 2891 }
 2892 
 2893 static int
 2894 biba_vnode_check_chroot(struct ucred *cred, struct vnode *dvp,
 2895     struct label *dvplabel)
 2896 {
 2897         struct mac_biba *subj, *obj;
 2898 
 2899         if (!biba_enabled)
 2900                 return (0);
 2901 
 2902         subj = SLOT(cred->cr_label);
 2903         obj = SLOT(dvplabel);
 2904 
 2905         if (!biba_dominate_effective(obj, subj))
 2906                 return (EACCES);
 2907 
 2908         return (0);
 2909 }
 2910 
 2911 static int
 2912 biba_vnode_check_create(struct ucred *cred, struct vnode *dvp,
 2913     struct label *dvplabel, struct componentname *cnp, struct vattr *vap)
 2914 {
 2915         struct mac_biba *subj, *obj;
 2916 
 2917         if (!biba_enabled)
 2918                 return (0);
 2919 
 2920         subj = SLOT(cred->cr_label);
 2921         obj = SLOT(dvplabel);
 2922 
 2923         if (!biba_dominate_effective(subj, obj))
 2924                 return (EACCES);
 2925 
 2926         return (0);
 2927 }
 2928 
 2929 static int
 2930 biba_vnode_check_deleteacl(struct ucred *cred, struct vnode *vp,
 2931     struct label *vplabel, acl_type_t type)
 2932 {
 2933         struct mac_biba *subj, *obj;
 2934 
 2935         if (!biba_enabled)
 2936                 return (0);
 2937 
 2938         subj = SLOT(cred->cr_label);
 2939         obj = SLOT(vplabel);
 2940 
 2941         if (!biba_dominate_effective(subj, obj))
 2942                 return (EACCES);
 2943 
 2944         return (0);
 2945 }
 2946 
 2947 static int
 2948 biba_vnode_check_deleteextattr(struct ucred *cred, struct vnode *vp,
 2949     struct label *vplabel, int attrnamespace, const char *name)
 2950 {
 2951         struct mac_biba *subj, *obj;
 2952 
 2953         if (!biba_enabled)
 2954                 return (0);
 2955 
 2956         subj = SLOT(cred->cr_label);
 2957         obj = SLOT(vplabel);
 2958 
 2959         if (!biba_dominate_effective(subj, obj))
 2960                 return (EACCES);
 2961 
 2962         return (0);
 2963 }
 2964 
 2965 static int
 2966 biba_vnode_check_exec(struct ucred *cred, struct vnode *vp,
 2967     struct label *vplabel, struct image_params *imgp,
 2968     struct label *execlabel)
 2969 {
 2970         struct mac_biba *subj, *obj, *exec;
 2971         int error;
 2972 
 2973         if (execlabel != NULL) {
 2974                 /*
 2975                  * We currently don't permit labels to be changed at
 2976                  * exec-time as part of Biba, so disallow non-NULL Biba label
 2977                  * elements in the execlabel.
 2978                  */
 2979                 exec = SLOT(execlabel);
 2980                 error = biba_atmostflags(exec, 0);
 2981                 if (error)
 2982                         return (error);
 2983         }
 2984 
 2985         if (!biba_enabled)
 2986                 return (0);
 2987 
 2988         subj = SLOT(cred->cr_label);
 2989         obj = SLOT(vplabel);
 2990 
 2991         if (!biba_dominate_effective(obj, subj))
 2992                 return (EACCES);
 2993 
 2994         return (0);
 2995 }
 2996 
 2997 static int
 2998 biba_vnode_check_getacl(struct ucred *cred, struct vnode *vp,
 2999     struct label *vplabel, acl_type_t type)
 3000 {
 3001         struct mac_biba *subj, *obj;
 3002 
 3003         if (!biba_enabled)
 3004                 return (0);
 3005 
 3006         subj = SLOT(cred->cr_label);
 3007         obj = SLOT(vplabel);
 3008 
 3009         if (!biba_dominate_effective(obj, subj))
 3010                 return (EACCES);
 3011 
 3012         return (0);
 3013 }
 3014 
 3015 static int
 3016 biba_vnode_check_getextattr(struct ucred *cred, struct vnode *vp,
 3017     struct label *vplabel, int attrnamespace, const char *name)
 3018 {
 3019         struct mac_biba *subj, *obj;
 3020 
 3021         if (!biba_enabled)
 3022                 return (0);
 3023 
 3024         subj = SLOT(cred->cr_label);
 3025         obj = SLOT(vplabel);
 3026 
 3027         if (!biba_dominate_effective(obj, subj))
 3028                 return (EACCES);
 3029 
 3030         return (0);
 3031 }
 3032 
 3033 static int
 3034 biba_vnode_check_link(struct ucred *cred, struct vnode *dvp,
 3035     struct label *dvplabel, struct vnode *vp, struct label *vplabel,
 3036     struct componentname *cnp)
 3037 {
 3038         struct mac_biba *subj, *obj;
 3039 
 3040         if (!biba_enabled)
 3041                 return (0);
 3042 
 3043         subj = SLOT(cred->cr_label);
 3044         obj = SLOT(dvplabel);
 3045 
 3046         if (!biba_dominate_effective(subj, obj))
 3047                 return (EACCES);
 3048 
 3049         obj = SLOT(vplabel);
 3050 
 3051         if (!biba_dominate_effective(subj, obj))
 3052                 return (EACCES);
 3053 
 3054         return (0);
 3055 }
 3056 
 3057 static int
 3058 biba_vnode_check_listextattr(struct ucred *cred, struct vnode *vp,
 3059     struct label *vplabel, int attrnamespace)
 3060 {
 3061         struct mac_biba *subj, *obj;
 3062 
 3063         if (!biba_enabled)
 3064                 return (0);
 3065 
 3066         subj = SLOT(cred->cr_label);
 3067         obj = SLOT(vplabel);
 3068 
 3069         if (!biba_dominate_effective(obj, subj))
 3070                 return (EACCES);
 3071 
 3072         return (0);
 3073 }
 3074 
 3075 static int
 3076 biba_vnode_check_lookup(struct ucred *cred, struct vnode *dvp,
 3077     struct label *dvplabel, struct componentname *cnp)
 3078 {
 3079         struct mac_biba *subj, *obj;
 3080 
 3081         if (!biba_enabled)
 3082                 return (0);
 3083 
 3084         subj = SLOT(cred->cr_label);
 3085         obj = SLOT(dvplabel);
 3086 
 3087         if (!biba_dominate_effective(obj, subj))
 3088                 return (EACCES);
 3089 
 3090         return (0);
 3091 }
 3092 
 3093 static int
 3094 biba_vnode_check_mmap(struct ucred *cred, struct vnode *vp,
 3095     struct label *vplabel, int prot, int flags)
 3096 {
 3097         struct mac_biba *subj, *obj;
 3098 
 3099         /*
 3100          * Rely on the use of open()-time protections to handle
 3101          * non-revocation cases.
 3102          */
 3103         if (!biba_enabled || !revocation_enabled)
 3104                 return (0);
 3105 
 3106         subj = SLOT(cred->cr_label);
 3107         obj = SLOT(vplabel);
 3108 
 3109         if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
 3110                 if (!biba_dominate_effective(obj, subj))
 3111                         return (EACCES);
 3112         }
 3113         if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) {
 3114                 if (!biba_dominate_effective(subj, obj))
 3115                         return (EACCES);
 3116         }
 3117 
 3118         return (0);
 3119 }
 3120 
 3121 static int
 3122 biba_vnode_check_open(struct ucred *cred, struct vnode *vp,
 3123     struct label *vplabel, accmode_t accmode)
 3124 {
 3125         struct mac_biba *subj, *obj;
 3126 
 3127         if (!biba_enabled)
 3128                 return (0);
 3129 
 3130         subj = SLOT(cred->cr_label);
 3131         obj = SLOT(vplabel);
 3132 
 3133         /* XXX privilege override for admin? */
 3134         if (accmode & (VREAD | VEXEC | VSTAT_PERMS)) {
 3135                 if (!biba_dominate_effective(obj, subj))
 3136                         return (EACCES);
 3137         }
 3138         if (accmode & VMODIFY_PERMS) {
 3139                 if (!biba_dominate_effective(subj, obj))
 3140                         return (EACCES);
 3141         }
 3142 
 3143         return (0);
 3144 }
 3145 
 3146 static int
 3147 biba_vnode_check_poll(struct ucred *active_cred, struct ucred *file_cred,
 3148     struct vnode *vp, struct label *vplabel)
 3149 {
 3150         struct mac_biba *subj, *obj;
 3151 
 3152         if (!biba_enabled || !revocation_enabled)
 3153                 return (0);
 3154 
 3155         subj = SLOT(active_cred->cr_label);
 3156         obj = SLOT(vplabel);
 3157 
 3158         if (!biba_dominate_effective(obj, subj))
 3159                 return (EACCES);
 3160 
 3161         return (0);
 3162 }
 3163 
 3164 static int
 3165 biba_vnode_check_read(struct ucred *active_cred, struct ucred *file_cred,
 3166     struct vnode *vp, struct label *vplabel)
 3167 {
 3168         struct mac_biba *subj, *obj;
 3169 
 3170         if (!biba_enabled || !revocation_enabled)
 3171                 return (0);
 3172 
 3173         subj = SLOT(active_cred->cr_label);
 3174         obj = SLOT(vplabel);
 3175 
 3176         if (!biba_dominate_effective(obj, subj))
 3177                 return (EACCES);
 3178 
 3179         return (0);
 3180 }
 3181 
 3182 static int
 3183 biba_vnode_check_readdir(struct ucred *cred, struct vnode *dvp,
 3184     struct label *dvplabel)
 3185 {
 3186         struct mac_biba *subj, *obj;
 3187 
 3188         if (!biba_enabled)
 3189                 return (0);
 3190 
 3191         subj = SLOT(cred->cr_label);
 3192         obj = SLOT(dvplabel);
 3193 
 3194         if (!biba_dominate_effective(obj, subj))
 3195                 return (EACCES);
 3196 
 3197         return (0);
 3198 }
 3199 
 3200 static int
 3201 biba_vnode_check_readlink(struct ucred *cred, struct vnode *vp,
 3202     struct label *vplabel)
 3203 {
 3204         struct mac_biba *subj, *obj;
 3205 
 3206         if (!biba_enabled)
 3207                 return (0);
 3208 
 3209         subj = SLOT(cred->cr_label);
 3210         obj = SLOT(vplabel);
 3211 
 3212         if (!biba_dominate_effective(obj, subj))
 3213                 return (EACCES);
 3214 
 3215         return (0);
 3216 }
 3217 
 3218 static int
 3219 biba_vnode_check_relabel(struct ucred *cred, struct vnode *vp,
 3220     struct label *vplabel, struct label *newlabel)
 3221 {
 3222         struct mac_biba *old, *new, *subj;
 3223         int error;
 3224 
 3225         old = SLOT(vplabel);
 3226         new = SLOT(newlabel);
 3227         subj = SLOT(cred->cr_label);
 3228 
 3229         /*
 3230          * If there is a Biba label update for the vnode, it must be a
 3231          * effective label.
 3232          */
 3233         error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE);
 3234         if (error)
 3235                 return (error);
 3236 
 3237         /*
 3238          * To perform a relabel of the vnode (Biba label or not), Biba must
 3239          * authorize the relabel.
 3240          */
 3241         if (!biba_effective_in_range(old, subj))
 3242                 return (EPERM);
 3243 
 3244         /*
 3245          * If the Biba label is to be changed, authorize as appropriate.
 3246          */
 3247         if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
 3248                 /*
 3249                  * To change the Biba label on a vnode, the new vnode label
 3250                  * must be in the subject range.
 3251                  */
 3252                 if (!biba_effective_in_range(new, subj))
 3253                         return (EPERM);
 3254 
 3255                 /*
 3256                  * To change the Biba label on the vnode to be EQUAL, the
 3257                  * subject must have appropriate privilege.
 3258                  */
 3259                 if (biba_contains_equal(new)) {
 3260                         error = biba_subject_privileged(subj);
 3261                         if (error)
 3262                                 return (error);
 3263                 }
 3264         }
 3265 
 3266         return (0);
 3267 }
 3268 
 3269 static int
 3270 biba_vnode_check_rename_from(struct ucred *cred, struct vnode *dvp,
 3271     struct label *dvplabel, struct vnode *vp, struct label *vplabel,
 3272     struct componentname *cnp)
 3273 {
 3274         struct mac_biba *subj, *obj;
 3275 
 3276         if (!biba_enabled)
 3277                 return (0);
 3278 
 3279         subj = SLOT(cred->cr_label);
 3280         obj = SLOT(dvplabel);
 3281 
 3282         if (!biba_dominate_effective(subj, obj))
 3283                 return (EACCES);
 3284 
 3285         obj = SLOT(vplabel);
 3286 
 3287         if (!biba_dominate_effective(subj, obj))
 3288                 return (EACCES);
 3289 
 3290         return (0);
 3291 }
 3292 
 3293 static int
 3294 biba_vnode_check_rename_to(struct ucred *cred, struct vnode *dvp,
 3295     struct label *dvplabel, struct vnode *vp, struct label *vplabel,
 3296     int samedir, struct componentname *cnp)
 3297 {
 3298         struct mac_biba *subj, *obj;
 3299 
 3300         if (!biba_enabled)
 3301                 return (0);
 3302 
 3303         subj = SLOT(cred->cr_label);
 3304         obj = SLOT(dvplabel);
 3305 
 3306         if (!biba_dominate_effective(subj, obj))
 3307                 return (EACCES);
 3308 
 3309         if (vp != NULL) {
 3310                 obj = SLOT(vplabel);
 3311 
 3312                 if (!biba_dominate_effective(subj, obj))
 3313                         return (EACCES);
 3314         }
 3315 
 3316         return (0);
 3317 }
 3318 
 3319 static int
 3320 biba_vnode_check_revoke(struct ucred *cred, struct vnode *vp,
 3321     struct label *vplabel)
 3322 {
 3323         struct mac_biba *subj, *obj;
 3324 
 3325         if (!biba_enabled)
 3326                 return (0);
 3327 
 3328         subj = SLOT(cred->cr_label);
 3329         obj = SLOT(vplabel);
 3330 
 3331         if (!biba_dominate_effective(subj, obj))
 3332                 return (EACCES);
 3333 
 3334         return (0);
 3335 }
 3336 
 3337 static int
 3338 biba_vnode_check_setacl(struct ucred *cred, struct vnode *vp,
 3339     struct label *vplabel, acl_type_t type, struct acl *acl)
 3340 {
 3341         struct mac_biba *subj, *obj;
 3342 
 3343         if (!biba_enabled)
 3344                 return (0);
 3345 
 3346         subj = SLOT(cred->cr_label);
 3347         obj = SLOT(vplabel);
 3348 
 3349         if (!biba_dominate_effective(subj, obj))
 3350                 return (EACCES);
 3351 
 3352         return (0);
 3353 }
 3354 
 3355 static int
 3356 biba_vnode_check_setextattr(struct ucred *cred, struct vnode *vp,
 3357     struct label *vplabel, int attrnamespace, const char *name)
 3358 {
 3359         struct mac_biba *subj, *obj;
 3360 
 3361         if (!biba_enabled)
 3362                 return (0);
 3363 
 3364         subj = SLOT(cred->cr_label);
 3365         obj = SLOT(vplabel);
 3366 
 3367         if (!biba_dominate_effective(subj, obj))
 3368                 return (EACCES);
 3369 
 3370         /* XXX: protect the MAC EA in a special way? */
 3371 
 3372         return (0);
 3373 }
 3374 
 3375 static int
 3376 biba_vnode_check_setflags(struct ucred *cred, struct vnode *vp,
 3377     struct label *vplabel, u_long flags)
 3378 {
 3379         struct mac_biba *subj, *obj;
 3380 
 3381         if (!biba_enabled)
 3382                 return (0);
 3383 
 3384         subj = SLOT(cred->cr_label);
 3385         obj = SLOT(vplabel);
 3386 
 3387         if (!biba_dominate_effective(subj, obj))
 3388                 return (EACCES);
 3389 
 3390         return (0);
 3391 }
 3392 
 3393 static int
 3394 biba_vnode_check_setmode(struct ucred *cred, struct vnode *vp,
 3395     struct label *vplabel, mode_t mode)
 3396 {
 3397         struct mac_biba *subj, *obj;
 3398 
 3399         if (!biba_enabled)
 3400                 return (0);
 3401 
 3402         subj = SLOT(cred->cr_label);
 3403         obj = SLOT(vplabel);
 3404 
 3405         if (!biba_dominate_effective(subj, obj))
 3406                 return (EACCES);
 3407 
 3408         return (0);
 3409 }
 3410 
 3411 static int
 3412 biba_vnode_check_setowner(struct ucred *cred, struct vnode *vp,
 3413     struct label *vplabel, uid_t uid, gid_t gid)
 3414 {
 3415         struct mac_biba *subj, *obj;
 3416 
 3417         if (!biba_enabled)
 3418                 return (0);
 3419 
 3420         subj = SLOT(cred->cr_label);
 3421         obj = SLOT(vplabel);
 3422 
 3423         if (!biba_dominate_effective(subj, obj))
 3424                 return (EACCES);
 3425 
 3426         return (0);
 3427 }
 3428 
 3429 static int
 3430 biba_vnode_check_setutimes(struct ucred *cred, struct vnode *vp,
 3431     struct label *vplabel, struct timespec atime, struct timespec mtime)
 3432 {
 3433         struct mac_biba *subj, *obj;
 3434 
 3435         if (!biba_enabled)
 3436                 return (0);
 3437 
 3438         subj = SLOT(cred->cr_label);
 3439         obj = SLOT(vplabel);
 3440 
 3441         if (!biba_dominate_effective(subj, obj))
 3442                 return (EACCES);
 3443 
 3444         return (0);
 3445 }
 3446 
 3447 static int
 3448 biba_vnode_check_stat(struct ucred *active_cred, struct ucred *file_cred,
 3449     struct vnode *vp, struct label *vplabel)
 3450 {
 3451         struct mac_biba *subj, *obj;
 3452 
 3453         if (!biba_enabled)
 3454                 return (0);
 3455 
 3456         subj = SLOT(active_cred->cr_label);
 3457         obj = SLOT(vplabel);
 3458 
 3459         if (!biba_dominate_effective(obj, subj))
 3460                 return (EACCES);
 3461 
 3462         return (0);
 3463 }
 3464 
 3465 static int
 3466 biba_vnode_check_unlink(struct ucred *cred, struct vnode *dvp,
 3467     struct label *dvplabel, struct vnode *vp, struct label *vplabel,
 3468     struct componentname *cnp)
 3469 {
 3470         struct mac_biba *subj, *obj;
 3471 
 3472         if (!biba_enabled)
 3473                 return (0);
 3474 
 3475         subj = SLOT(cred->cr_label);
 3476         obj = SLOT(dvplabel);
 3477 
 3478         if (!biba_dominate_effective(subj, obj))
 3479                 return (EACCES);
 3480 
 3481         obj = SLOT(vplabel);
 3482 
 3483         if (!biba_dominate_effective(subj, obj))
 3484                 return (EACCES);
 3485 
 3486         return (0);
 3487 }
 3488 
 3489 static int
 3490 biba_vnode_check_write(struct ucred *active_cred,
 3491     struct ucred *file_cred, struct vnode *vp, struct label *vplabel)
 3492 {
 3493         struct mac_biba *subj, *obj;
 3494 
 3495         if (!biba_enabled || !revocation_enabled)
 3496                 return (0);
 3497 
 3498         subj = SLOT(active_cred->cr_label);
 3499         obj = SLOT(vplabel);
 3500 
 3501         if (!biba_dominate_effective(subj, obj))
 3502                 return (EACCES);
 3503 
 3504         return (0);
 3505 }
 3506 
 3507 static int
 3508 biba_vnode_create_extattr(struct ucred *cred, struct mount *mp,
 3509     struct label *mplabel, struct vnode *dvp, struct label *dvplabel,
 3510     struct vnode *vp, struct label *vplabel, struct componentname *cnp)
 3511 {
 3512         struct mac_biba *source, *dest, mb_temp;
 3513         size_t buflen;
 3514         int error;
 3515 
 3516         buflen = sizeof(mb_temp);
 3517         bzero(&mb_temp, buflen);
 3518 
 3519         source = SLOT(cred->cr_label);
 3520         dest = SLOT(vplabel);
 3521         biba_copy_effective(source, &mb_temp);
 3522 
 3523         error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
 3524             MAC_BIBA_EXTATTR_NAME, buflen, (char *) &mb_temp, curthread);
 3525         if (error == 0)
 3526                 biba_copy_effective(source, dest);
 3527         return (error);
 3528 }
 3529 
 3530 static void
 3531 biba_vnode_relabel(struct ucred *cred, struct vnode *vp,
 3532     struct label *vplabel, struct label *newlabel)
 3533 {
 3534         struct mac_biba *source, *dest;
 3535 
 3536         source = SLOT(newlabel);
 3537         dest = SLOT(vplabel);
 3538 
 3539         biba_copy(source, dest);
 3540 }
 3541 
 3542 static int
 3543 biba_vnode_setlabel_extattr(struct ucred *cred, struct vnode *vp,
 3544     struct label *vplabel, struct label *intlabel)
 3545 {
 3546         struct mac_biba *source, mb_temp;
 3547         size_t buflen;
 3548         int error;
 3549 
 3550         buflen = sizeof(mb_temp);
 3551         bzero(&mb_temp, buflen);
 3552 
 3553         source = SLOT(intlabel);
 3554         if ((source->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) == 0)
 3555                 return (0);
 3556 
 3557         biba_copy_effective(source, &mb_temp);
 3558 
 3559         error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
 3560             MAC_BIBA_EXTATTR_NAME, buflen, (char *) &mb_temp, curthread);
 3561         return (error);
 3562 }
 3563 
 3564 static struct mac_policy_ops mac_biba_ops =
 3565 {
 3566         .mpo_init = biba_init,
 3567 
 3568         .mpo_bpfdesc_check_receive = biba_bpfdesc_check_receive,
 3569         .mpo_bpfdesc_create = biba_bpfdesc_create,
 3570         .mpo_bpfdesc_create_mbuf = biba_bpfdesc_create_mbuf,
 3571         .mpo_bpfdesc_destroy_label = biba_destroy_label,
 3572         .mpo_bpfdesc_init_label = biba_init_label,
 3573 
 3574         .mpo_cred_associate_nfsd = biba_cred_associate_nfsd,
 3575         .mpo_cred_check_relabel = biba_cred_check_relabel,
 3576         .mpo_cred_check_visible = biba_cred_check_visible,
 3577         .mpo_cred_copy_label = biba_copy_label,
 3578         .mpo_cred_create_init = biba_cred_create_init,
 3579         .mpo_cred_create_swapper = biba_cred_create_swapper,
 3580         .mpo_cred_destroy_label = biba_destroy_label,
 3581         .mpo_cred_externalize_label = biba_externalize_label,
 3582         .mpo_cred_init_label = biba_init_label,
 3583         .mpo_cred_internalize_label = biba_internalize_label,
 3584         .mpo_cred_relabel = biba_cred_relabel,
 3585 
 3586         .mpo_devfs_create_device = biba_devfs_create_device,
 3587         .mpo_devfs_create_directory = biba_devfs_create_directory,
 3588         .mpo_devfs_create_symlink = biba_devfs_create_symlink,
 3589         .mpo_devfs_destroy_label = biba_destroy_label,
 3590         .mpo_devfs_init_label = biba_init_label,
 3591         .mpo_devfs_update = biba_devfs_update,
 3592         .mpo_devfs_vnode_associate = biba_devfs_vnode_associate,
 3593 
 3594         .mpo_ifnet_check_relabel = biba_ifnet_check_relabel,
 3595         .mpo_ifnet_check_transmit = biba_ifnet_check_transmit,
 3596         .mpo_ifnet_copy_label = biba_copy_label,
 3597         .mpo_ifnet_create = biba_ifnet_create,
 3598         .mpo_ifnet_create_mbuf = biba_ifnet_create_mbuf,
 3599         .mpo_ifnet_destroy_label = biba_destroy_label,
 3600         .mpo_ifnet_externalize_label = biba_externalize_label,
 3601         .mpo_ifnet_init_label = biba_init_label,
 3602         .mpo_ifnet_internalize_label = biba_internalize_label,
 3603         .mpo_ifnet_relabel = biba_ifnet_relabel,
 3604 
 3605         .mpo_inpcb_check_deliver = biba_inpcb_check_deliver,
 3606         .mpo_inpcb_check_visible = biba_inpcb_check_visible,
 3607         .mpo_inpcb_create = biba_inpcb_create,
 3608         .mpo_inpcb_create_mbuf = biba_inpcb_create_mbuf,
 3609         .mpo_inpcb_destroy_label = biba_destroy_label,
 3610         .mpo_inpcb_init_label = biba_init_label_waitcheck,
 3611         .mpo_inpcb_sosetlabel = biba_inpcb_sosetlabel,
 3612 
 3613         .mpo_ip6q_create = biba_ip6q_create,
 3614         .mpo_ip6q_destroy_label = biba_destroy_label,
 3615         .mpo_ip6q_init_label = biba_init_label_waitcheck,
 3616         .mpo_ip6q_match = biba_ip6q_match,
 3617         .mpo_ip6q_reassemble = biba_ip6q_reassemble,
 3618         .mpo_ip6q_update = biba_ip6q_update,
 3619 
 3620         .mpo_ipq_create = biba_ipq_create,
 3621         .mpo_ipq_destroy_label = biba_destroy_label,
 3622         .mpo_ipq_init_label = biba_init_label_waitcheck,
 3623         .mpo_ipq_match = biba_ipq_match,
 3624         .mpo_ipq_reassemble = biba_ipq_reassemble,
 3625         .mpo_ipq_update = biba_ipq_update,
 3626 
 3627         .mpo_kld_check_load = biba_kld_check_load,
 3628 
 3629         .mpo_mbuf_copy_label = biba_copy_label,
 3630         .mpo_mbuf_destroy_label = biba_destroy_label,
 3631         .mpo_mbuf_init_label = biba_init_label_waitcheck,
 3632 
 3633         .mpo_mount_check_stat = biba_mount_check_stat,
 3634         .mpo_mount_create = biba_mount_create,
 3635         .mpo_mount_destroy_label = biba_destroy_label,
 3636         .mpo_mount_init_label = biba_init_label,
 3637 
 3638         .mpo_netinet_arp_send = biba_netinet_arp_send,
 3639         .mpo_netinet_firewall_reply = biba_netinet_firewall_reply,
 3640         .mpo_netinet_firewall_send = biba_netinet_firewall_send,
 3641         .mpo_netinet_fragment = biba_netinet_fragment,
 3642         .mpo_netinet_icmp_reply = biba_netinet_icmp_reply,
 3643         .mpo_netinet_igmp_send = biba_netinet_igmp_send,
 3644 
 3645         .mpo_netinet6_nd6_send = biba_netinet6_nd6_send,
 3646 
 3647         .mpo_pipe_check_ioctl = biba_pipe_check_ioctl,
 3648         .mpo_pipe_check_poll = biba_pipe_check_poll,
 3649         .mpo_pipe_check_read = biba_pipe_check_read,
 3650         .mpo_pipe_check_relabel = biba_pipe_check_relabel,
 3651         .mpo_pipe_check_stat = biba_pipe_check_stat,
 3652         .mpo_pipe_check_write = biba_pipe_check_write,
 3653         .mpo_pipe_copy_label = biba_copy_label,
 3654         .mpo_pipe_create = biba_pipe_create,
 3655         .mpo_pipe_destroy_label = biba_destroy_label,
 3656         .mpo_pipe_externalize_label = biba_externalize_label,
 3657         .mpo_pipe_init_label = biba_init_label,
 3658         .mpo_pipe_internalize_label = biba_internalize_label,
 3659         .mpo_pipe_relabel = biba_pipe_relabel,
 3660 
 3661         .mpo_posixsem_check_getvalue = biba_posixsem_check_rdonly,
 3662         .mpo_posixsem_check_open = biba_posixsem_check_openunlink,
 3663         .mpo_posixsem_check_post = biba_posixsem_check_write,
 3664         .mpo_posixsem_check_setmode = biba_posixsem_check_setmode,
 3665         .mpo_posixsem_check_setowner = biba_posixsem_check_setowner,
 3666         .mpo_posixsem_check_stat = biba_posixsem_check_rdonly,
 3667         .mpo_posixsem_check_unlink = biba_posixsem_check_openunlink,
 3668         .mpo_posixsem_check_wait = biba_posixsem_check_write,
 3669         .mpo_posixsem_create = biba_posixsem_create,
 3670         .mpo_posixsem_destroy_label = biba_destroy_label,
 3671         .mpo_posixsem_init_label = biba_init_label,
 3672 
 3673         .mpo_posixshm_check_mmap = biba_posixshm_check_mmap,
 3674         .mpo_posixshm_check_open = biba_posixshm_check_open,
 3675         .mpo_posixshm_check_read = biba_posixshm_check_read,
 3676         .mpo_posixshm_check_setmode = biba_posixshm_check_setmode,
 3677         .mpo_posixshm_check_setowner = biba_posixshm_check_setowner,
 3678         .mpo_posixshm_check_stat = biba_posixshm_check_stat,
 3679         .mpo_posixshm_check_truncate = biba_posixshm_check_truncate,
 3680         .mpo_posixshm_check_unlink = biba_posixshm_check_unlink,
 3681         .mpo_posixshm_check_write = biba_posixshm_check_write,
 3682         .mpo_posixshm_create = biba_posixshm_create,
 3683         .mpo_posixshm_destroy_label = biba_destroy_label,
 3684         .mpo_posixshm_init_label = biba_init_label,
 3685 
 3686         .mpo_priv_check = biba_priv_check,
 3687 
 3688         .mpo_proc_check_debug = biba_proc_check_debug,
 3689         .mpo_proc_check_sched = biba_proc_check_sched,
 3690         .mpo_proc_check_signal = biba_proc_check_signal,
 3691 
 3692         .mpo_socket_check_deliver = biba_socket_check_deliver,
 3693         .mpo_socket_check_relabel = biba_socket_check_relabel,
 3694         .mpo_socket_check_visible = biba_socket_check_visible,
 3695         .mpo_socket_copy_label = biba_copy_label,
 3696         .mpo_socket_create = biba_socket_create,
 3697         .mpo_socket_create_mbuf = biba_socket_create_mbuf,
 3698         .mpo_socket_destroy_label = biba_destroy_label,
 3699         .mpo_socket_externalize_label = biba_externalize_label,
 3700         .mpo_socket_init_label = biba_init_label_waitcheck,
 3701         .mpo_socket_internalize_label = biba_internalize_label,
 3702         .mpo_socket_newconn = biba_socket_newconn,
 3703         .mpo_socket_relabel = biba_socket_relabel,
 3704 
 3705         .mpo_socketpeer_destroy_label = biba_destroy_label,
 3706         .mpo_socketpeer_externalize_label = biba_externalize_label,
 3707         .mpo_socketpeer_init_label = biba_init_label_waitcheck,
 3708         .mpo_socketpeer_set_from_mbuf = biba_socketpeer_set_from_mbuf,
 3709         .mpo_socketpeer_set_from_socket = biba_socketpeer_set_from_socket,
 3710 
 3711         .mpo_syncache_create = biba_syncache_create,
 3712         .mpo_syncache_create_mbuf = biba_syncache_create_mbuf,
 3713         .mpo_syncache_destroy_label = biba_destroy_label,
 3714         .mpo_syncache_init_label = biba_init_label_waitcheck,
 3715 
 3716         .mpo_system_check_acct = biba_system_check_acct,
 3717         .mpo_system_check_auditctl = biba_system_check_auditctl,
 3718         .mpo_system_check_auditon = biba_system_check_auditon,
 3719         .mpo_system_check_swapoff = biba_system_check_swapoff,
 3720         .mpo_system_check_swapon = biba_system_check_swapon,
 3721         .mpo_system_check_sysctl = biba_system_check_sysctl,
 3722 
 3723         .mpo_sysvmsg_cleanup = biba_sysvmsg_cleanup,
 3724         .mpo_sysvmsg_create = biba_sysvmsg_create,
 3725         .mpo_sysvmsg_destroy_label = biba_destroy_label,
 3726         .mpo_sysvmsg_init_label = biba_init_label,
 3727 
 3728         .mpo_sysvmsq_check_msgrcv = biba_sysvmsq_check_msgrcv,
 3729         .mpo_sysvmsq_check_msgrmid = biba_sysvmsq_check_msgrmid,
 3730         .mpo_sysvmsq_check_msqget = biba_sysvmsq_check_msqget,
 3731         .mpo_sysvmsq_check_msqsnd = biba_sysvmsq_check_msqsnd,
 3732         .mpo_sysvmsq_check_msqrcv = biba_sysvmsq_check_msqrcv,
 3733         .mpo_sysvmsq_check_msqctl = biba_sysvmsq_check_msqctl,
 3734         .mpo_sysvmsq_cleanup = biba_sysvmsq_cleanup,
 3735         .mpo_sysvmsq_create = biba_sysvmsq_create,
 3736         .mpo_sysvmsq_destroy_label = biba_destroy_label,
 3737         .mpo_sysvmsq_init_label = biba_init_label,
 3738 
 3739         .mpo_sysvsem_check_semctl = biba_sysvsem_check_semctl,
 3740         .mpo_sysvsem_check_semget = biba_sysvsem_check_semget,
 3741         .mpo_sysvsem_check_semop = biba_sysvsem_check_semop,
 3742         .mpo_sysvsem_cleanup = biba_sysvsem_cleanup,
 3743         .mpo_sysvsem_create = biba_sysvsem_create,
 3744         .mpo_sysvsem_destroy_label = biba_destroy_label,
 3745         .mpo_sysvsem_init_label = biba_init_label,
 3746 
 3747         .mpo_sysvshm_check_shmat = biba_sysvshm_check_shmat,
 3748         .mpo_sysvshm_check_shmctl = biba_sysvshm_check_shmctl,
 3749         .mpo_sysvshm_check_shmget = biba_sysvshm_check_shmget,
 3750         .mpo_sysvshm_cleanup = biba_sysvshm_cleanup,
 3751         .mpo_sysvshm_create = biba_sysvshm_create,
 3752         .mpo_sysvshm_destroy_label = biba_destroy_label,
 3753         .mpo_sysvshm_init_label = biba_init_label,
 3754 
 3755         .mpo_vnode_associate_extattr = biba_vnode_associate_extattr,
 3756         .mpo_vnode_associate_singlelabel = biba_vnode_associate_singlelabel,
 3757         .mpo_vnode_check_access = biba_vnode_check_open,
 3758         .mpo_vnode_check_chdir = biba_vnode_check_chdir,
 3759         .mpo_vnode_check_chroot = biba_vnode_check_chroot,
 3760         .mpo_vnode_check_create = biba_vnode_check_create,
 3761         .mpo_vnode_check_deleteacl = biba_vnode_check_deleteacl,
 3762         .mpo_vnode_check_deleteextattr = biba_vnode_check_deleteextattr,
 3763         .mpo_vnode_check_exec = biba_vnode_check_exec,
 3764         .mpo_vnode_check_getacl = biba_vnode_check_getacl,
 3765         .mpo_vnode_check_getextattr = biba_vnode_check_getextattr,
 3766         .mpo_vnode_check_link = biba_vnode_check_link,
 3767         .mpo_vnode_check_listextattr = biba_vnode_check_listextattr,
 3768         .mpo_vnode_check_lookup = biba_vnode_check_lookup,
 3769         .mpo_vnode_check_mmap = biba_vnode_check_mmap,
 3770         .mpo_vnode_check_open = biba_vnode_check_open,
 3771         .mpo_vnode_check_poll = biba_vnode_check_poll,
 3772         .mpo_vnode_check_read = biba_vnode_check_read,
 3773         .mpo_vnode_check_readdir = biba_vnode_check_readdir,
 3774         .mpo_vnode_check_readlink = biba_vnode_check_readlink,
 3775         .mpo_vnode_check_relabel = biba_vnode_check_relabel,
 3776         .mpo_vnode_check_rename_from = biba_vnode_check_rename_from,
 3777         .mpo_vnode_check_rename_to = biba_vnode_check_rename_to,
 3778         .mpo_vnode_check_revoke = biba_vnode_check_revoke,
 3779         .mpo_vnode_check_setacl = biba_vnode_check_setacl,
 3780         .mpo_vnode_check_setextattr = biba_vnode_check_setextattr,
 3781         .mpo_vnode_check_setflags = biba_vnode_check_setflags,
 3782         .mpo_vnode_check_setmode = biba_vnode_check_setmode,
 3783         .mpo_vnode_check_setowner = biba_vnode_check_setowner,
 3784         .mpo_vnode_check_setutimes = biba_vnode_check_setutimes,
 3785         .mpo_vnode_check_stat = biba_vnode_check_stat,
 3786         .mpo_vnode_check_unlink = biba_vnode_check_unlink,
 3787         .mpo_vnode_check_write = biba_vnode_check_write,
 3788         .mpo_vnode_create_extattr = biba_vnode_create_extattr,
 3789         .mpo_vnode_copy_label = biba_copy_label,
 3790         .mpo_vnode_destroy_label = biba_destroy_label,
 3791         .mpo_vnode_externalize_label = biba_externalize_label,
 3792         .mpo_vnode_init_label = biba_init_label,
 3793         .mpo_vnode_internalize_label = biba_internalize_label,
 3794         .mpo_vnode_relabel = biba_vnode_relabel,
 3795         .mpo_vnode_setlabel_extattr = biba_vnode_setlabel_extattr,
 3796 };
 3797 
 3798 MAC_POLICY_SET(&mac_biba_ops, mac_biba, "TrustedBSD MAC/Biba",
 3799     MPC_LOADTIME_FLAG_NOTLATE, &biba_slot);

Cache object: 141502915bacc952fce4585a069b40ff


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