]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/security/mac_biba/mac_biba.c
Add BSM record conversion for a number of syscalls:
[FreeBSD/FreeBSD.git] / sys / security / mac_biba / mac_biba.c
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
1979         /*
1980          * More IPC privileges.
1981          */
1982         case PRIV_SEM_WRITE:
1983
1984         /*
1985          * Allow signaling privileges subject to integrity policy.
1986          */
1987         case PRIV_SIGNAL_DIFFCRED:
1988         case PRIV_SIGNAL_SUGID:
1989
1990         /*
1991          * Allow access to only limited sysctls from lower integrity levels;
1992          * piggy-back on the Jail definition.
1993          */
1994         case PRIV_SYSCTL_WRITEJAIL:
1995
1996         /*
1997          * Allow TTY-based privileges, subject to general device access using
1998          * labels on TTY device nodes, but not console privilege.
1999          */
2000         case PRIV_TTY_DRAINWAIT:
2001         case PRIV_TTY_DTRWAIT:
2002         case PRIV_TTY_EXCLUSIVE:
2003         case PRIV_TTY_STI:
2004         case PRIV_TTY_SETA:
2005
2006         /*
2007          * Grant most VFS privileges, as almost all are in practice bounded
2008          * by more specific checks using labels.
2009          */
2010         case PRIV_VFS_READ:
2011         case PRIV_VFS_WRITE:
2012         case PRIV_VFS_ADMIN:
2013         case PRIV_VFS_EXEC:
2014         case PRIV_VFS_LOOKUP:
2015         case PRIV_VFS_CHFLAGS_DEV:
2016         case PRIV_VFS_CHOWN:
2017         case PRIV_VFS_CHROOT:
2018         case PRIV_VFS_RETAINSUGID:
2019         case PRIV_VFS_EXCEEDQUOTA:
2020         case PRIV_VFS_FCHROOT:
2021         case PRIV_VFS_FHOPEN:
2022         case PRIV_VFS_FHSTATFS:
2023         case PRIV_VFS_GENERATION:
2024         case PRIV_VFS_GETFH:
2025         case PRIV_VFS_GETQUOTA:
2026         case PRIV_VFS_LINK:
2027         case PRIV_VFS_MOUNT:
2028         case PRIV_VFS_MOUNT_OWNER:
2029         case PRIV_VFS_MOUNT_PERM:
2030         case PRIV_VFS_MOUNT_SUIDDIR:
2031         case PRIV_VFS_MOUNT_NONUSER:
2032         case PRIV_VFS_SETGID:
2033         case PRIV_VFS_STICKYFILE:
2034         case PRIV_VFS_SYSFLAGS:
2035         case PRIV_VFS_UNMOUNT:
2036
2037         /*
2038          * Allow VM privileges; it would be nice if these were subject to
2039          * resource limits.
2040          */
2041         case PRIV_VM_MADV_PROTECT:
2042         case PRIV_VM_MLOCK:
2043         case PRIV_VM_MUNLOCK:
2044         case PRIV_VM_SWAP_NOQUOTA:
2045         case PRIV_VM_SWAP_NORLIMIT:
2046
2047         /*
2048          * Allow some but not all network privileges.  In general, dont allow
2049          * reconfiguring the network stack, just normal use.
2050          */
2051         case PRIV_NETINET_RESERVEDPORT:
2052         case PRIV_NETINET_RAW:
2053         case PRIV_NETINET_REUSEPORT:
2054                 break;
2055
2056         /*
2057          * All remaining system privileges are allow only if the process
2058          * holds privilege with respect to the Biba policy.
2059          */
2060         default:
2061                 subj = SLOT(cred->cr_label);
2062                 error = biba_subject_privileged(subj);
2063                 if (error)
2064                         return (error);
2065         }
2066         return (0);
2067 }
2068
2069 static int
2070 biba_proc_check_debug(struct ucred *cred, struct proc *p)
2071 {
2072         struct mac_biba *subj, *obj;
2073
2074         if (!biba_enabled)
2075                 return (0);
2076
2077         subj = SLOT(cred->cr_label);
2078         obj = SLOT(p->p_ucred->cr_label);
2079
2080         /* XXX: range checks */
2081         if (!biba_dominate_effective(obj, subj))
2082                 return (ESRCH);
2083         if (!biba_dominate_effective(subj, obj))
2084                 return (EACCES);
2085
2086         return (0);
2087 }
2088
2089 static int
2090 biba_proc_check_sched(struct ucred *cred, struct proc *p)
2091 {
2092         struct mac_biba *subj, *obj;
2093
2094         if (!biba_enabled)
2095                 return (0);
2096
2097         subj = SLOT(cred->cr_label);
2098         obj = SLOT(p->p_ucred->cr_label);
2099
2100         /* XXX: range checks */
2101         if (!biba_dominate_effective(obj, subj))
2102                 return (ESRCH);
2103         if (!biba_dominate_effective(subj, obj))
2104                 return (EACCES);
2105
2106         return (0);
2107 }
2108
2109 static int
2110 biba_proc_check_signal(struct ucred *cred, struct proc *p, int signum)
2111 {
2112         struct mac_biba *subj, *obj;
2113
2114         if (!biba_enabled)
2115                 return (0);
2116
2117         subj = SLOT(cred->cr_label);
2118         obj = SLOT(p->p_ucred->cr_label);
2119
2120         /* XXX: range checks */
2121         if (!biba_dominate_effective(obj, subj))
2122                 return (ESRCH);
2123         if (!biba_dominate_effective(subj, obj))
2124                 return (EACCES);
2125
2126         return (0);
2127 }
2128
2129 static int
2130 biba_socket_check_deliver(struct socket *so, struct label *solabel,
2131     struct mbuf *m, struct label *mlabel)
2132 {
2133         struct mac_biba *p, *s;
2134         int error;
2135
2136         if (!biba_enabled)
2137                 return (0);
2138
2139         p = SLOT(mlabel);
2140         s = SLOT(solabel);
2141
2142         SOCK_LOCK(so);
2143         error = biba_equal_effective(p, s) ? 0 : EACCES;
2144         SOCK_UNLOCK(so);
2145         return (error);
2146 }
2147
2148 static int
2149 biba_socket_check_relabel(struct ucred *cred, struct socket *so,
2150     struct label *solabel, struct label *newlabel)
2151 {
2152         struct mac_biba *subj, *obj, *new;
2153         int error;
2154
2155         SOCK_LOCK_ASSERT(so);
2156
2157         new = SLOT(newlabel);
2158         subj = SLOT(cred->cr_label);
2159         obj = SLOT(solabel);
2160
2161         /*
2162          * If there is a Biba label update for the socket, it may be an
2163          * update of effective.
2164          */
2165         error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE);
2166         if (error)
2167                 return (error);
2168
2169         /*
2170          * To relabel a socket, the old socket effective must be in the
2171          * subject range.
2172          */
2173         if (!biba_effective_in_range(obj, subj))
2174                 return (EPERM);
2175
2176         /*
2177          * If the Biba label is to be changed, authorize as appropriate.
2178          */
2179         if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
2180                 /*
2181                  * To relabel a socket, the new socket effective must be in
2182                  * the subject range.
2183                  */
2184                 if (!biba_effective_in_range(new, subj))
2185                         return (EPERM);
2186
2187                 /*
2188                  * To change the Biba label on the socket to contain EQUAL,
2189                  * the subject must have appropriate privilege.
2190                  */
2191                 if (biba_contains_equal(new)) {
2192                         error = biba_subject_privileged(subj);
2193                         if (error)
2194                                 return (error);
2195                 }
2196         }
2197
2198         return (0);
2199 }
2200
2201 static int
2202 biba_socket_check_visible(struct ucred *cred, struct socket *so,
2203     struct label *solabel)
2204 {
2205         struct mac_biba *subj, *obj;
2206
2207         if (!biba_enabled)
2208                 return (0);
2209
2210         subj = SLOT(cred->cr_label);
2211         obj = SLOT(solabel);
2212
2213         SOCK_LOCK(so);
2214         if (!biba_dominate_effective(obj, subj)) {
2215                 SOCK_UNLOCK(so);
2216                 return (ENOENT);
2217         }
2218         SOCK_UNLOCK(so);
2219
2220         return (0);
2221 }
2222
2223 static void
2224 biba_socket_create(struct ucred *cred, struct socket *so,
2225     struct label *solabel)
2226 {
2227         struct mac_biba *source, *dest;
2228
2229         source = SLOT(cred->cr_label);
2230         dest = SLOT(solabel);
2231
2232         biba_copy_effective(source, dest);
2233 }
2234
2235 static void
2236 biba_socket_create_mbuf(struct socket *so, struct label *solabel,
2237     struct mbuf *m, struct label *mlabel)
2238 {
2239         struct mac_biba *source, *dest;
2240
2241         source = SLOT(solabel);
2242         dest = SLOT(mlabel);
2243
2244         SOCK_LOCK(so);
2245         biba_copy_effective(source, dest);
2246         SOCK_UNLOCK(so);
2247 }
2248
2249 static void
2250 biba_socket_newconn(struct socket *oldso, struct label *oldsolabel,
2251     struct socket *newso, struct label *newsolabel)
2252 {
2253         struct mac_biba source, *dest;
2254
2255         SOCK_LOCK(oldso);
2256         source = *SLOT(oldsolabel);
2257         SOCK_UNLOCK(oldso);
2258
2259         dest = SLOT(newsolabel);
2260
2261         SOCK_LOCK(newso);
2262         biba_copy_effective(&source, dest);
2263         SOCK_UNLOCK(newso);
2264 }
2265
2266 static void
2267 biba_socket_relabel(struct ucred *cred, struct socket *so,
2268     struct label *solabel, struct label *newlabel)
2269 {
2270         struct mac_biba *source, *dest;
2271
2272         SOCK_LOCK_ASSERT(so);
2273
2274         source = SLOT(newlabel);
2275         dest = SLOT(solabel);
2276
2277         biba_copy(source, dest);
2278 }
2279
2280 static void
2281 biba_socketpeer_set_from_mbuf(struct mbuf *m, struct label *mlabel,
2282     struct socket *so, struct label *sopeerlabel)
2283 {
2284         struct mac_biba *source, *dest;
2285
2286         source = SLOT(mlabel);
2287         dest = SLOT(sopeerlabel);
2288
2289         SOCK_LOCK(so);
2290         biba_copy_effective(source, dest);
2291         SOCK_UNLOCK(so);
2292 }
2293
2294 static void
2295 biba_socketpeer_set_from_socket(struct socket *oldso,
2296     struct label *oldsolabel, struct socket *newso,
2297     struct label *newsopeerlabel)
2298 {
2299         struct mac_biba source, *dest;
2300
2301         SOCK_LOCK(oldso);
2302         source = *SLOT(oldsolabel);
2303         SOCK_UNLOCK(oldso);
2304         dest = SLOT(newsopeerlabel);
2305
2306         SOCK_LOCK(newso);
2307         biba_copy_effective(&source, dest);
2308         SOCK_UNLOCK(newso);
2309 }
2310
2311 static void
2312 biba_syncache_create(struct label *label, struct inpcb *inp)
2313 {
2314         struct mac_biba *source, *dest;
2315
2316         source = SLOT(inp->inp_label);
2317         dest = SLOT(label);
2318         biba_copy_effective(source, dest);
2319 }
2320
2321 static void
2322 biba_syncache_create_mbuf(struct label *sc_label, struct mbuf *m,
2323     struct label *mlabel)
2324 {
2325         struct mac_biba *source, *dest;
2326
2327         source = SLOT(sc_label);
2328         dest = SLOT(mlabel);
2329         biba_copy_effective(source, dest);
2330 }
2331
2332 static int
2333 biba_system_check_acct(struct ucred *cred, struct vnode *vp,
2334     struct label *vplabel)
2335 {
2336         struct mac_biba *subj, *obj;
2337         int error;
2338
2339         if (!biba_enabled)
2340                 return (0);
2341
2342         subj = SLOT(cred->cr_label);
2343
2344         error = biba_subject_privileged(subj);
2345         if (error)
2346                 return (error);
2347
2348         if (vplabel == NULL)
2349                 return (0);
2350
2351         obj = SLOT(vplabel);
2352         if (!biba_high_effective(obj))
2353                 return (EACCES);
2354
2355         return (0);
2356 }
2357
2358 static int
2359 biba_system_check_auditctl(struct ucred *cred, struct vnode *vp,
2360     struct label *vplabel)
2361 {
2362         struct mac_biba *subj, *obj;
2363         int error;
2364
2365         if (!biba_enabled)
2366                 return (0);
2367
2368         subj = SLOT(cred->cr_label);
2369
2370         error = biba_subject_privileged(subj);
2371         if (error)
2372                 return (error);
2373
2374         if (vplabel == NULL)
2375                 return (0);
2376
2377         obj = SLOT(vplabel);
2378         if (!biba_high_effective(obj))
2379                 return (EACCES);
2380
2381         return (0);
2382 }
2383
2384 static int
2385 biba_system_check_auditon(struct ucred *cred, int cmd)
2386 {
2387         struct mac_biba *subj;
2388         int error;
2389
2390         if (!biba_enabled)
2391                 return (0);
2392
2393         subj = SLOT(cred->cr_label);
2394
2395         error = biba_subject_privileged(subj);
2396         if (error)
2397                 return (error);
2398
2399         return (0);
2400 }
2401
2402 static int
2403 biba_system_check_swapoff(struct ucred *cred, struct vnode *vp,
2404     struct label *label)
2405 {
2406         struct mac_biba *subj;
2407         int error;
2408
2409         if (!biba_enabled)
2410                 return (0);
2411
2412         subj = SLOT(cred->cr_label);
2413
2414         error = biba_subject_privileged(subj);
2415         if (error)
2416                 return (error);
2417
2418         return (0);
2419 }
2420
2421 static int
2422 biba_system_check_swapon(struct ucred *cred, struct vnode *vp,
2423     struct label *vplabel)
2424 {
2425         struct mac_biba *subj, *obj;
2426         int error;
2427
2428         if (!biba_enabled)
2429                 return (0);
2430
2431         subj = SLOT(cred->cr_label);
2432         obj = SLOT(vplabel);
2433
2434         error = biba_subject_privileged(subj);
2435         if (error)
2436                 return (error);
2437
2438         if (!biba_high_effective(obj))
2439                 return (EACCES);
2440
2441         return (0);
2442 }
2443
2444 static int
2445 biba_system_check_sysctl(struct ucred *cred, struct sysctl_oid *oidp,
2446     void *arg1, int arg2, struct sysctl_req *req)
2447 {
2448         struct mac_biba *subj;
2449         int error;
2450
2451         if (!biba_enabled)
2452                 return (0);
2453
2454         subj = SLOT(cred->cr_label);
2455
2456         /*
2457          * Treat sysctl variables without CTLFLAG_ANYBODY flag as biba/high,
2458          * but also require privilege to change them.
2459          */
2460         if (req->newptr != NULL && (oidp->oid_kind & CTLFLAG_ANYBODY) == 0) {
2461                 if (!biba_subject_dominate_high(subj))
2462                         return (EACCES);
2463
2464                 error = biba_subject_privileged(subj);
2465                 if (error)
2466                         return (error);
2467         }
2468
2469         return (0);
2470 }
2471
2472 static void
2473 biba_sysvmsg_cleanup(struct label *msglabel)
2474 {
2475
2476         bzero(SLOT(msglabel), sizeof(struct mac_biba));
2477 }
2478
2479 static void
2480 biba_sysvmsg_create(struct ucred *cred, struct msqid_kernel *msqkptr,
2481     struct label *msqlabel, struct msg *msgptr, struct label *msglabel)
2482 {
2483         struct mac_biba *source, *dest;
2484
2485         /* Ignore the msgq label */
2486         source = SLOT(cred->cr_label);
2487         dest = SLOT(msglabel);
2488
2489         biba_copy_effective(source, dest);
2490 }
2491
2492 static int
2493 biba_sysvmsq_check_msgrcv(struct ucred *cred, struct msg *msgptr,
2494     struct label *msglabel)
2495 {
2496         struct mac_biba *subj, *obj;
2497
2498         if (!biba_enabled)
2499                 return (0);
2500
2501         subj = SLOT(cred->cr_label);
2502         obj = SLOT(msglabel);
2503
2504         if (!biba_dominate_effective(obj, subj))
2505                 return (EACCES);
2506
2507         return (0);
2508 }
2509
2510 static int
2511 biba_sysvmsq_check_msgrmid(struct ucred *cred, struct msg *msgptr,
2512     struct label *msglabel)
2513 {
2514         struct mac_biba *subj, *obj;
2515
2516         if (!biba_enabled)
2517                 return (0);
2518
2519         subj = SLOT(cred->cr_label);
2520         obj = SLOT(msglabel);
2521
2522         if (!biba_dominate_effective(subj, obj))
2523                 return (EACCES);
2524
2525         return (0);
2526 }
2527
2528 static int
2529 biba_sysvmsq_check_msqget(struct ucred *cred, struct msqid_kernel *msqkptr,
2530     struct label *msqklabel)
2531 {
2532         struct mac_biba *subj, *obj;
2533
2534         if (!biba_enabled)
2535                 return (0);
2536
2537         subj = SLOT(cred->cr_label);
2538         obj = SLOT(msqklabel);
2539
2540         if (!biba_dominate_effective(obj, subj))
2541                 return (EACCES);
2542
2543         return (0);
2544 }
2545
2546 static int
2547 biba_sysvmsq_check_msqsnd(struct ucred *cred, struct msqid_kernel *msqkptr,
2548     struct label *msqklabel)
2549 {
2550         struct mac_biba *subj, *obj;
2551
2552         if (!biba_enabled)
2553                 return (0);
2554
2555         subj = SLOT(cred->cr_label);
2556         obj = SLOT(msqklabel);
2557
2558         if (!biba_dominate_effective(subj, obj))
2559                 return (EACCES);
2560
2561         return (0);
2562 }
2563
2564 static int
2565 biba_sysvmsq_check_msqrcv(struct ucred *cred, struct msqid_kernel *msqkptr,
2566     struct label *msqklabel)
2567 {
2568         struct mac_biba *subj, *obj;
2569
2570         if (!biba_enabled)
2571                 return (0);
2572
2573         subj = SLOT(cred->cr_label);
2574         obj = SLOT(msqklabel);
2575
2576         if (!biba_dominate_effective(obj, subj))
2577                 return (EACCES);
2578
2579         return (0);
2580 }
2581
2582 static int
2583 biba_sysvmsq_check_msqctl(struct ucred *cred, struct msqid_kernel *msqkptr,
2584     struct label *msqklabel, int cmd)
2585 {
2586         struct mac_biba *subj, *obj;
2587
2588         if (!biba_enabled)
2589                 return (0);
2590
2591         subj = SLOT(cred->cr_label);
2592         obj = SLOT(msqklabel);
2593
2594         switch(cmd) {
2595         case IPC_RMID:
2596         case IPC_SET:
2597                 if (!biba_dominate_effective(subj, obj))
2598                         return (EACCES);
2599                 break;
2600
2601         case IPC_STAT:
2602                 if (!biba_dominate_effective(obj, subj))
2603                         return (EACCES);
2604                 break;
2605
2606         default:
2607                 return (EACCES);
2608         }
2609
2610         return (0);
2611 }
2612
2613 static void
2614 biba_sysvmsq_cleanup(struct label *msqlabel)
2615 {
2616
2617         bzero(SLOT(msqlabel), sizeof(struct mac_biba));
2618 }
2619
2620 static void
2621 biba_sysvmsq_create(struct ucred *cred, struct msqid_kernel *msqkptr,
2622     struct label *msqlabel)
2623 {
2624         struct mac_biba *source, *dest;
2625
2626         source = SLOT(cred->cr_label);
2627         dest = SLOT(msqlabel);
2628
2629         biba_copy_effective(source, dest);
2630 }
2631
2632 static int
2633 biba_sysvsem_check_semctl(struct ucred *cred, struct semid_kernel *semakptr,
2634     struct label *semaklabel, int cmd)
2635 {
2636         struct mac_biba *subj, *obj;
2637
2638         if (!biba_enabled)
2639                 return (0);
2640
2641         subj = SLOT(cred->cr_label);
2642         obj = SLOT(semaklabel);
2643
2644         switch(cmd) {
2645         case IPC_RMID:
2646         case IPC_SET:
2647         case SETVAL:
2648         case SETALL:
2649                 if (!biba_dominate_effective(subj, obj))
2650                         return (EACCES);
2651                 break;
2652
2653         case IPC_STAT:
2654         case GETVAL:
2655         case GETPID:
2656         case GETNCNT:
2657         case GETZCNT:
2658         case GETALL:
2659                 if (!biba_dominate_effective(obj, subj))
2660                         return (EACCES);
2661                 break;
2662
2663         default:
2664                 return (EACCES);
2665         }
2666
2667         return (0);
2668 }
2669
2670 static int
2671 biba_sysvsem_check_semget(struct ucred *cred, struct semid_kernel *semakptr,
2672     struct label *semaklabel)
2673 {
2674         struct mac_biba *subj, *obj;
2675
2676         if (!biba_enabled)
2677                 return (0);
2678
2679         subj = SLOT(cred->cr_label);
2680         obj = SLOT(semaklabel);
2681
2682         if (!biba_dominate_effective(obj, subj))
2683                 return (EACCES);
2684
2685         return (0);
2686 }
2687
2688 static int
2689 biba_sysvsem_check_semop(struct ucred *cred, struct semid_kernel *semakptr,
2690     struct label *semaklabel, size_t accesstype)
2691 {
2692         struct mac_biba *subj, *obj;
2693
2694         if (!biba_enabled)
2695                 return (0);
2696
2697         subj = SLOT(cred->cr_label);
2698         obj = SLOT(semaklabel);
2699
2700         if (accesstype & SEM_R)
2701                 if (!biba_dominate_effective(obj, subj))
2702                         return (EACCES);
2703
2704         if (accesstype & SEM_A)
2705                 if (!biba_dominate_effective(subj, obj))
2706                         return (EACCES);
2707
2708         return (0);
2709 }
2710
2711 static void
2712 biba_sysvsem_cleanup(struct label *semalabel)
2713 {
2714
2715         bzero(SLOT(semalabel), sizeof(struct mac_biba));
2716 }
2717
2718 static void
2719 biba_sysvsem_create(struct ucred *cred, struct semid_kernel *semakptr,
2720     struct label *semalabel)
2721 {
2722         struct mac_biba *source, *dest;
2723
2724         source = SLOT(cred->cr_label);
2725         dest = SLOT(semalabel);
2726
2727         biba_copy_effective(source, dest);
2728 }
2729
2730 static int
2731 biba_sysvshm_check_shmat(struct ucred *cred, struct shmid_kernel *shmsegptr,
2732     struct label *shmseglabel, int shmflg)
2733 {
2734         struct mac_biba *subj, *obj;
2735
2736         if (!biba_enabled)
2737                 return (0);
2738
2739         subj = SLOT(cred->cr_label);
2740         obj = SLOT(shmseglabel);
2741
2742         if (!biba_dominate_effective(obj, subj))
2743                 return (EACCES);
2744         if ((shmflg & SHM_RDONLY) == 0) {
2745                 if (!biba_dominate_effective(subj, obj))
2746                         return (EACCES);
2747         }
2748         
2749         return (0);
2750 }
2751
2752 static int
2753 biba_sysvshm_check_shmctl(struct ucred *cred, struct shmid_kernel *shmsegptr,
2754     struct label *shmseglabel, int cmd)
2755 {
2756         struct mac_biba *subj, *obj;
2757
2758         if (!biba_enabled)
2759                 return (0);
2760
2761         subj = SLOT(cred->cr_label);
2762         obj = SLOT(shmseglabel);
2763
2764         switch(cmd) {
2765         case IPC_RMID:
2766         case IPC_SET:
2767                 if (!biba_dominate_effective(subj, obj))
2768                         return (EACCES);
2769                 break;
2770
2771         case IPC_STAT:
2772         case SHM_STAT:
2773                 if (!biba_dominate_effective(obj, subj))
2774                         return (EACCES);
2775                 break;
2776
2777         default:
2778                 return (EACCES);
2779         }
2780
2781         return (0);
2782 }
2783
2784 static int
2785 biba_sysvshm_check_shmget(struct ucred *cred, struct shmid_kernel *shmsegptr,
2786     struct label *shmseglabel, int shmflg)
2787 {
2788         struct mac_biba *subj, *obj;
2789
2790         if (!biba_enabled)
2791                 return (0);
2792
2793         subj = SLOT(cred->cr_label);
2794         obj = SLOT(shmseglabel);
2795
2796         if (!biba_dominate_effective(obj, subj))
2797                 return (EACCES);
2798
2799         return (0);
2800 }
2801
2802 static void
2803 biba_sysvshm_cleanup(struct label *shmlabel)
2804 {
2805
2806         bzero(SLOT(shmlabel), sizeof(struct mac_biba));
2807 }
2808
2809 static void
2810 biba_sysvshm_create(struct ucred *cred, struct shmid_kernel *shmsegptr,
2811     struct label *shmlabel)
2812 {
2813         struct mac_biba *source, *dest;
2814
2815         source = SLOT(cred->cr_label);
2816         dest = SLOT(shmlabel);
2817
2818         biba_copy_effective(source, dest);
2819 }
2820
2821 static int
2822 biba_vnode_associate_extattr(struct mount *mp, struct label *mplabel,
2823     struct vnode *vp, struct label *vplabel)
2824 {
2825         struct mac_biba mb_temp, *source, *dest;
2826         int buflen, error;
2827
2828         source = SLOT(mplabel);
2829         dest = SLOT(vplabel);
2830
2831         buflen = sizeof(mb_temp);
2832         bzero(&mb_temp, buflen);
2833
2834         error = vn_extattr_get(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
2835             MAC_BIBA_EXTATTR_NAME, &buflen, (char *) &mb_temp, curthread);
2836         if (error == ENOATTR || error == EOPNOTSUPP) {
2837                 /* Fall back to the mntlabel. */
2838                 biba_copy_effective(source, dest);
2839                 return (0);
2840         } else if (error)
2841                 return (error);
2842
2843         if (buflen != sizeof(mb_temp)) {
2844                 printf("biba_vnode_associate_extattr: bad size %d\n",
2845                     buflen);
2846                 return (EPERM);
2847         }
2848         if (biba_valid(&mb_temp) != 0) {
2849                 printf("biba_vnode_associate_extattr: invalid\n");
2850                 return (EPERM);
2851         }
2852         if ((mb_temp.mb_flags & MAC_BIBA_FLAGS_BOTH) !=
2853             MAC_BIBA_FLAG_EFFECTIVE) {
2854                 printf("biba_vnode_associate_extattr: not effective\n");
2855                 return (EPERM);
2856         }
2857
2858         biba_copy_effective(&mb_temp, dest);
2859         return (0);
2860 }
2861
2862 static void
2863 biba_vnode_associate_singlelabel(struct mount *mp, struct label *mplabel,
2864     struct vnode *vp, struct label *vplabel)
2865 {
2866         struct mac_biba *source, *dest;
2867
2868         source = SLOT(mplabel);
2869         dest = SLOT(vplabel);
2870
2871         biba_copy_effective(source, dest);
2872 }
2873
2874 static int
2875 biba_vnode_check_chdir(struct ucred *cred, struct vnode *dvp,
2876     struct label *dvplabel)
2877 {
2878         struct mac_biba *subj, *obj;
2879
2880         if (!biba_enabled)
2881                 return (0);
2882
2883         subj = SLOT(cred->cr_label);
2884         obj = SLOT(dvplabel);
2885
2886         if (!biba_dominate_effective(obj, subj))
2887                 return (EACCES);
2888
2889         return (0);
2890 }
2891
2892 static int
2893 biba_vnode_check_chroot(struct ucred *cred, struct vnode *dvp,
2894     struct label *dvplabel)
2895 {
2896         struct mac_biba *subj, *obj;
2897
2898         if (!biba_enabled)
2899                 return (0);
2900
2901         subj = SLOT(cred->cr_label);
2902         obj = SLOT(dvplabel);
2903
2904         if (!biba_dominate_effective(obj, subj))
2905                 return (EACCES);
2906
2907         return (0);
2908 }
2909
2910 static int
2911 biba_vnode_check_create(struct ucred *cred, struct vnode *dvp,
2912     struct label *dvplabel, struct componentname *cnp, struct vattr *vap)
2913 {
2914         struct mac_biba *subj, *obj;
2915
2916         if (!biba_enabled)
2917                 return (0);
2918
2919         subj = SLOT(cred->cr_label);
2920         obj = SLOT(dvplabel);
2921
2922         if (!biba_dominate_effective(subj, obj))
2923                 return (EACCES);
2924
2925         return (0);
2926 }
2927
2928 static int
2929 biba_vnode_check_deleteacl(struct ucred *cred, struct vnode *vp,
2930     struct label *vplabel, acl_type_t type)
2931 {
2932         struct mac_biba *subj, *obj;
2933
2934         if (!biba_enabled)
2935                 return (0);
2936
2937         subj = SLOT(cred->cr_label);
2938         obj = SLOT(vplabel);
2939
2940         if (!biba_dominate_effective(subj, obj))
2941                 return (EACCES);
2942
2943         return (0);
2944 }
2945
2946 static int
2947 biba_vnode_check_deleteextattr(struct ucred *cred, struct vnode *vp,
2948     struct label *vplabel, int attrnamespace, const char *name)
2949 {
2950         struct mac_biba *subj, *obj;
2951
2952         if (!biba_enabled)
2953                 return (0);
2954
2955         subj = SLOT(cred->cr_label);
2956         obj = SLOT(vplabel);
2957
2958         if (!biba_dominate_effective(subj, obj))
2959                 return (EACCES);
2960
2961         return (0);
2962 }
2963
2964 static int
2965 biba_vnode_check_exec(struct ucred *cred, struct vnode *vp,
2966     struct label *vplabel, struct image_params *imgp,
2967     struct label *execlabel)
2968 {
2969         struct mac_biba *subj, *obj, *exec;
2970         int error;
2971
2972         if (execlabel != NULL) {
2973                 /*
2974                  * We currently don't permit labels to be changed at
2975                  * exec-time as part of Biba, so disallow non-NULL Biba label
2976                  * elements in the execlabel.
2977                  */
2978                 exec = SLOT(execlabel);
2979                 error = biba_atmostflags(exec, 0);
2980                 if (error)
2981                         return (error);
2982         }
2983
2984         if (!biba_enabled)
2985                 return (0);
2986
2987         subj = SLOT(cred->cr_label);
2988         obj = SLOT(vplabel);
2989
2990         if (!biba_dominate_effective(obj, subj))
2991                 return (EACCES);
2992
2993         return (0);
2994 }
2995
2996 static int
2997 biba_vnode_check_getacl(struct ucred *cred, struct vnode *vp,
2998     struct label *vplabel, acl_type_t type)
2999 {
3000         struct mac_biba *subj, *obj;
3001
3002         if (!biba_enabled)
3003                 return (0);
3004
3005         subj = SLOT(cred->cr_label);
3006         obj = SLOT(vplabel);
3007
3008         if (!biba_dominate_effective(obj, subj))
3009                 return (EACCES);
3010
3011         return (0);
3012 }
3013
3014 static int
3015 biba_vnode_check_getextattr(struct ucred *cred, struct vnode *vp,
3016     struct label *vplabel, int attrnamespace, const char *name)
3017 {
3018         struct mac_biba *subj, *obj;
3019
3020         if (!biba_enabled)
3021                 return (0);
3022
3023         subj = SLOT(cred->cr_label);
3024         obj = SLOT(vplabel);
3025
3026         if (!biba_dominate_effective(obj, subj))
3027                 return (EACCES);
3028
3029         return (0);
3030 }
3031
3032 static int
3033 biba_vnode_check_link(struct ucred *cred, struct vnode *dvp,
3034     struct label *dvplabel, struct vnode *vp, struct label *vplabel,
3035     struct componentname *cnp)
3036 {
3037         struct mac_biba *subj, *obj;
3038
3039         if (!biba_enabled)
3040                 return (0);
3041
3042         subj = SLOT(cred->cr_label);
3043         obj = SLOT(dvplabel);
3044
3045         if (!biba_dominate_effective(subj, obj))
3046                 return (EACCES);
3047
3048         obj = SLOT(vplabel);
3049
3050         if (!biba_dominate_effective(subj, obj))
3051                 return (EACCES);
3052
3053         return (0);
3054 }
3055
3056 static int
3057 biba_vnode_check_listextattr(struct ucred *cred, struct vnode *vp,
3058     struct label *vplabel, int attrnamespace)
3059 {
3060         struct mac_biba *subj, *obj;
3061
3062         if (!biba_enabled)
3063                 return (0);
3064
3065         subj = SLOT(cred->cr_label);
3066         obj = SLOT(vplabel);
3067
3068         if (!biba_dominate_effective(obj, subj))
3069                 return (EACCES);
3070
3071         return (0);
3072 }
3073
3074 static int
3075 biba_vnode_check_lookup(struct ucred *cred, struct vnode *dvp,
3076     struct label *dvplabel, struct componentname *cnp)
3077 {
3078         struct mac_biba *subj, *obj;
3079
3080         if (!biba_enabled)
3081                 return (0);
3082
3083         subj = SLOT(cred->cr_label);
3084         obj = SLOT(dvplabel);
3085
3086         if (!biba_dominate_effective(obj, subj))
3087                 return (EACCES);
3088
3089         return (0);
3090 }
3091
3092 static int
3093 biba_vnode_check_mmap(struct ucred *cred, struct vnode *vp,
3094     struct label *vplabel, int prot, int flags)
3095 {
3096         struct mac_biba *subj, *obj;
3097
3098         /*
3099          * Rely on the use of open()-time protections to handle
3100          * non-revocation cases.
3101          */
3102         if (!biba_enabled || !revocation_enabled)
3103                 return (0);
3104
3105         subj = SLOT(cred->cr_label);
3106         obj = SLOT(vplabel);
3107
3108         if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
3109                 if (!biba_dominate_effective(obj, subj))
3110                         return (EACCES);
3111         }
3112         if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) {
3113                 if (!biba_dominate_effective(subj, obj))
3114                         return (EACCES);
3115         }
3116
3117         return (0);
3118 }
3119
3120 static int
3121 biba_vnode_check_open(struct ucred *cred, struct vnode *vp,
3122     struct label *vplabel, accmode_t accmode)
3123 {
3124         struct mac_biba *subj, *obj;
3125
3126         if (!biba_enabled)
3127                 return (0);
3128
3129         subj = SLOT(cred->cr_label);
3130         obj = SLOT(vplabel);
3131
3132         /* XXX privilege override for admin? */
3133         if (accmode & (VREAD | VEXEC | VSTAT_PERMS)) {
3134                 if (!biba_dominate_effective(obj, subj))
3135                         return (EACCES);
3136         }
3137         if (accmode & VMODIFY_PERMS) {
3138                 if (!biba_dominate_effective(subj, obj))
3139                         return (EACCES);
3140         }
3141
3142         return (0);
3143 }
3144
3145 static int
3146 biba_vnode_check_poll(struct ucred *active_cred, struct ucred *file_cred,
3147     struct vnode *vp, struct label *vplabel)
3148 {
3149         struct mac_biba *subj, *obj;
3150
3151         if (!biba_enabled || !revocation_enabled)
3152                 return (0);
3153
3154         subj = SLOT(active_cred->cr_label);
3155         obj = SLOT(vplabel);
3156
3157         if (!biba_dominate_effective(obj, subj))
3158                 return (EACCES);
3159
3160         return (0);
3161 }
3162
3163 static int
3164 biba_vnode_check_read(struct ucred *active_cred, struct ucred *file_cred,
3165     struct vnode *vp, struct label *vplabel)
3166 {
3167         struct mac_biba *subj, *obj;
3168
3169         if (!biba_enabled || !revocation_enabled)
3170                 return (0);
3171
3172         subj = SLOT(active_cred->cr_label);
3173         obj = SLOT(vplabel);
3174
3175         if (!biba_dominate_effective(obj, subj))
3176                 return (EACCES);
3177
3178         return (0);
3179 }
3180
3181 static int
3182 biba_vnode_check_readdir(struct ucred *cred, struct vnode *dvp,
3183     struct label *dvplabel)
3184 {
3185         struct mac_biba *subj, *obj;
3186
3187         if (!biba_enabled)
3188                 return (0);
3189
3190         subj = SLOT(cred->cr_label);
3191         obj = SLOT(dvplabel);
3192
3193         if (!biba_dominate_effective(obj, subj))
3194                 return (EACCES);
3195
3196         return (0);
3197 }
3198
3199 static int
3200 biba_vnode_check_readlink(struct ucred *cred, struct vnode *vp,
3201     struct label *vplabel)
3202 {
3203         struct mac_biba *subj, *obj;
3204
3205         if (!biba_enabled)
3206                 return (0);
3207
3208         subj = SLOT(cred->cr_label);
3209         obj = SLOT(vplabel);
3210
3211         if (!biba_dominate_effective(obj, subj))
3212                 return (EACCES);
3213
3214         return (0);
3215 }
3216
3217 static int
3218 biba_vnode_check_relabel(struct ucred *cred, struct vnode *vp,
3219     struct label *vplabel, struct label *newlabel)
3220 {
3221         struct mac_biba *old, *new, *subj;
3222         int error;
3223
3224         old = SLOT(vplabel);
3225         new = SLOT(newlabel);
3226         subj = SLOT(cred->cr_label);
3227
3228         /*
3229          * If there is a Biba label update for the vnode, it must be a
3230          * effective label.
3231          */
3232         error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE);
3233         if (error)
3234                 return (error);
3235
3236         /*
3237          * To perform a relabel of the vnode (Biba label or not), Biba must
3238          * authorize the relabel.
3239          */
3240         if (!biba_effective_in_range(old, subj))
3241                 return (EPERM);
3242
3243         /*
3244          * If the Biba label is to be changed, authorize as appropriate.
3245          */
3246         if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
3247                 /*
3248                  * To change the Biba label on a vnode, the new vnode label
3249                  * must be in the subject range.
3250                  */
3251                 if (!biba_effective_in_range(new, subj))
3252                         return (EPERM);
3253
3254                 /*
3255                  * To change the Biba label on the vnode to be EQUAL, the
3256                  * subject must have appropriate privilege.
3257                  */
3258                 if (biba_contains_equal(new)) {
3259                         error = biba_subject_privileged(subj);
3260                         if (error)
3261                                 return (error);
3262                 }
3263         }
3264
3265         return (0);
3266 }
3267
3268 static int
3269 biba_vnode_check_rename_from(struct ucred *cred, struct vnode *dvp,
3270     struct label *dvplabel, struct vnode *vp, struct label *vplabel,
3271     struct componentname *cnp)
3272 {
3273         struct mac_biba *subj, *obj;
3274
3275         if (!biba_enabled)
3276                 return (0);
3277
3278         subj = SLOT(cred->cr_label);
3279         obj = SLOT(dvplabel);
3280
3281         if (!biba_dominate_effective(subj, obj))
3282                 return (EACCES);
3283
3284         obj = SLOT(vplabel);
3285
3286         if (!biba_dominate_effective(subj, obj))
3287                 return (EACCES);
3288
3289         return (0);
3290 }
3291
3292 static int
3293 biba_vnode_check_rename_to(struct ucred *cred, struct vnode *dvp,
3294     struct label *dvplabel, struct vnode *vp, struct label *vplabel,
3295     int samedir, struct componentname *cnp)
3296 {
3297         struct mac_biba *subj, *obj;
3298
3299         if (!biba_enabled)
3300                 return (0);
3301
3302         subj = SLOT(cred->cr_label);
3303         obj = SLOT(dvplabel);
3304
3305         if (!biba_dominate_effective(subj, obj))
3306                 return (EACCES);
3307
3308         if (vp != NULL) {
3309                 obj = SLOT(vplabel);
3310
3311                 if (!biba_dominate_effective(subj, obj))
3312                         return (EACCES);
3313         }
3314
3315         return (0);
3316 }
3317
3318 static int
3319 biba_vnode_check_revoke(struct ucred *cred, struct vnode *vp,
3320     struct label *vplabel)
3321 {
3322         struct mac_biba *subj, *obj;
3323
3324         if (!biba_enabled)
3325                 return (0);
3326
3327         subj = SLOT(cred->cr_label);
3328         obj = SLOT(vplabel);
3329
3330         if (!biba_dominate_effective(subj, obj))
3331                 return (EACCES);
3332
3333         return (0);
3334 }
3335
3336 static int
3337 biba_vnode_check_setacl(struct ucred *cred, struct vnode *vp,
3338     struct label *vplabel, acl_type_t type, struct acl *acl)
3339 {
3340         struct mac_biba *subj, *obj;
3341
3342         if (!biba_enabled)
3343                 return (0);
3344
3345         subj = SLOT(cred->cr_label);
3346         obj = SLOT(vplabel);
3347
3348         if (!biba_dominate_effective(subj, obj))
3349                 return (EACCES);
3350
3351         return (0);
3352 }
3353
3354 static int
3355 biba_vnode_check_setextattr(struct ucred *cred, struct vnode *vp,
3356     struct label *vplabel, int attrnamespace, const char *name)
3357 {
3358         struct mac_biba *subj, *obj;
3359
3360         if (!biba_enabled)
3361                 return (0);
3362
3363         subj = SLOT(cred->cr_label);
3364         obj = SLOT(vplabel);
3365
3366         if (!biba_dominate_effective(subj, obj))
3367                 return (EACCES);
3368
3369         /* XXX: protect the MAC EA in a special way? */
3370
3371         return (0);
3372 }
3373
3374 static int
3375 biba_vnode_check_setflags(struct ucred *cred, struct vnode *vp,
3376     struct label *vplabel, u_long flags)
3377 {
3378         struct mac_biba *subj, *obj;
3379
3380         if (!biba_enabled)
3381                 return (0);
3382
3383         subj = SLOT(cred->cr_label);
3384         obj = SLOT(vplabel);
3385
3386         if (!biba_dominate_effective(subj, obj))
3387                 return (EACCES);
3388
3389         return (0);
3390 }
3391
3392 static int
3393 biba_vnode_check_setmode(struct ucred *cred, struct vnode *vp,
3394     struct label *vplabel, mode_t mode)
3395 {
3396         struct mac_biba *subj, *obj;
3397
3398         if (!biba_enabled)
3399                 return (0);
3400
3401         subj = SLOT(cred->cr_label);
3402         obj = SLOT(vplabel);
3403
3404         if (!biba_dominate_effective(subj, obj))
3405                 return (EACCES);
3406
3407         return (0);
3408 }
3409
3410 static int
3411 biba_vnode_check_setowner(struct ucred *cred, struct vnode *vp,
3412     struct label *vplabel, uid_t uid, gid_t gid)
3413 {
3414         struct mac_biba *subj, *obj;
3415
3416         if (!biba_enabled)
3417                 return (0);
3418
3419         subj = SLOT(cred->cr_label);
3420         obj = SLOT(vplabel);
3421
3422         if (!biba_dominate_effective(subj, obj))
3423                 return (EACCES);
3424
3425         return (0);
3426 }
3427
3428 static int
3429 biba_vnode_check_setutimes(struct ucred *cred, struct vnode *vp,
3430     struct label *vplabel, struct timespec atime, struct timespec mtime)
3431 {
3432         struct mac_biba *subj, *obj;
3433
3434         if (!biba_enabled)
3435                 return (0);
3436
3437         subj = SLOT(cred->cr_label);
3438         obj = SLOT(vplabel);
3439
3440         if (!biba_dominate_effective(subj, obj))
3441                 return (EACCES);
3442
3443         return (0);
3444 }
3445
3446 static int
3447 biba_vnode_check_stat(struct ucred *active_cred, struct ucred *file_cred,
3448     struct vnode *vp, struct label *vplabel)
3449 {
3450         struct mac_biba *subj, *obj;
3451
3452         if (!biba_enabled)
3453                 return (0);
3454
3455         subj = SLOT(active_cred->cr_label);
3456         obj = SLOT(vplabel);
3457
3458         if (!biba_dominate_effective(obj, subj))
3459                 return (EACCES);
3460
3461         return (0);
3462 }
3463
3464 static int
3465 biba_vnode_check_unlink(struct ucred *cred, struct vnode *dvp,
3466     struct label *dvplabel, struct vnode *vp, struct label *vplabel,
3467     struct componentname *cnp)
3468 {
3469         struct mac_biba *subj, *obj;
3470
3471         if (!biba_enabled)
3472                 return (0);
3473
3474         subj = SLOT(cred->cr_label);
3475         obj = SLOT(dvplabel);
3476
3477         if (!biba_dominate_effective(subj, obj))
3478                 return (EACCES);
3479
3480         obj = SLOT(vplabel);
3481
3482         if (!biba_dominate_effective(subj, obj))
3483                 return (EACCES);
3484
3485         return (0);
3486 }
3487
3488 static int
3489 biba_vnode_check_write(struct ucred *active_cred,
3490     struct ucred *file_cred, struct vnode *vp, struct label *vplabel)
3491 {
3492         struct mac_biba *subj, *obj;
3493
3494         if (!biba_enabled || !revocation_enabled)
3495                 return (0);
3496
3497         subj = SLOT(active_cred->cr_label);
3498         obj = SLOT(vplabel);
3499
3500         if (!biba_dominate_effective(subj, obj))
3501                 return (EACCES);
3502
3503         return (0);
3504 }
3505
3506 static int
3507 biba_vnode_create_extattr(struct ucred *cred, struct mount *mp,
3508     struct label *mplabel, struct vnode *dvp, struct label *dvplabel,
3509     struct vnode *vp, struct label *vplabel, struct componentname *cnp)
3510 {
3511         struct mac_biba *source, *dest, mb_temp;
3512         size_t buflen;
3513         int error;
3514
3515         buflen = sizeof(mb_temp);
3516         bzero(&mb_temp, buflen);
3517
3518         source = SLOT(cred->cr_label);
3519         dest = SLOT(vplabel);
3520         biba_copy_effective(source, &mb_temp);
3521
3522         error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
3523             MAC_BIBA_EXTATTR_NAME, buflen, (char *) &mb_temp, curthread);
3524         if (error == 0)
3525                 biba_copy_effective(source, dest);
3526         return (error);
3527 }
3528
3529 static void
3530 biba_vnode_relabel(struct ucred *cred, struct vnode *vp,
3531     struct label *vplabel, struct label *newlabel)
3532 {
3533         struct mac_biba *source, *dest;
3534
3535         source = SLOT(newlabel);
3536         dest = SLOT(vplabel);
3537
3538         biba_copy(source, dest);
3539 }
3540
3541 static int
3542 biba_vnode_setlabel_extattr(struct ucred *cred, struct vnode *vp,
3543     struct label *vplabel, struct label *intlabel)
3544 {
3545         struct mac_biba *source, mb_temp;
3546         size_t buflen;
3547         int error;
3548
3549         buflen = sizeof(mb_temp);
3550         bzero(&mb_temp, buflen);
3551
3552         source = SLOT(intlabel);
3553         if ((source->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) == 0)
3554                 return (0);
3555
3556         biba_copy_effective(source, &mb_temp);
3557
3558         error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
3559             MAC_BIBA_EXTATTR_NAME, buflen, (char *) &mb_temp, curthread);
3560         return (error);
3561 }
3562
3563 static struct mac_policy_ops mac_biba_ops =
3564 {
3565         .mpo_init = biba_init,
3566
3567         .mpo_bpfdesc_check_receive = biba_bpfdesc_check_receive,
3568         .mpo_bpfdesc_create = biba_bpfdesc_create,
3569         .mpo_bpfdesc_create_mbuf = biba_bpfdesc_create_mbuf,
3570         .mpo_bpfdesc_destroy_label = biba_destroy_label,
3571         .mpo_bpfdesc_init_label = biba_init_label,
3572
3573         .mpo_cred_associate_nfsd = biba_cred_associate_nfsd,
3574         .mpo_cred_check_relabel = biba_cred_check_relabel,
3575         .mpo_cred_check_visible = biba_cred_check_visible,
3576         .mpo_cred_copy_label = biba_copy_label,
3577         .mpo_cred_create_init = biba_cred_create_init,
3578         .mpo_cred_create_swapper = biba_cred_create_swapper,
3579         .mpo_cred_destroy_label = biba_destroy_label,
3580         .mpo_cred_externalize_label = biba_externalize_label,
3581         .mpo_cred_init_label = biba_init_label,
3582         .mpo_cred_internalize_label = biba_internalize_label,
3583         .mpo_cred_relabel = biba_cred_relabel,
3584
3585         .mpo_devfs_create_device = biba_devfs_create_device,
3586         .mpo_devfs_create_directory = biba_devfs_create_directory,
3587         .mpo_devfs_create_symlink = biba_devfs_create_symlink,
3588         .mpo_devfs_destroy_label = biba_destroy_label,
3589         .mpo_devfs_init_label = biba_init_label,
3590         .mpo_devfs_update = biba_devfs_update,
3591         .mpo_devfs_vnode_associate = biba_devfs_vnode_associate,
3592
3593         .mpo_ifnet_check_relabel = biba_ifnet_check_relabel,
3594         .mpo_ifnet_check_transmit = biba_ifnet_check_transmit,
3595         .mpo_ifnet_copy_label = biba_copy_label,
3596         .mpo_ifnet_create = biba_ifnet_create,
3597         .mpo_ifnet_create_mbuf = biba_ifnet_create_mbuf,
3598         .mpo_ifnet_destroy_label = biba_destroy_label,
3599         .mpo_ifnet_externalize_label = biba_externalize_label,
3600         .mpo_ifnet_init_label = biba_init_label,
3601         .mpo_ifnet_internalize_label = biba_internalize_label,
3602         .mpo_ifnet_relabel = biba_ifnet_relabel,
3603
3604         .mpo_inpcb_check_deliver = biba_inpcb_check_deliver,
3605         .mpo_inpcb_check_visible = biba_inpcb_check_visible,
3606         .mpo_inpcb_create = biba_inpcb_create,
3607         .mpo_inpcb_create_mbuf = biba_inpcb_create_mbuf,
3608         .mpo_inpcb_destroy_label = biba_destroy_label,
3609         .mpo_inpcb_init_label = biba_init_label_waitcheck,
3610         .mpo_inpcb_sosetlabel = biba_inpcb_sosetlabel,
3611
3612         .mpo_ip6q_create = biba_ip6q_create,
3613         .mpo_ip6q_destroy_label = biba_destroy_label,
3614         .mpo_ip6q_init_label = biba_init_label_waitcheck,
3615         .mpo_ip6q_match = biba_ip6q_match,
3616         .mpo_ip6q_reassemble = biba_ip6q_reassemble,
3617         .mpo_ip6q_update = biba_ip6q_update,
3618
3619         .mpo_ipq_create = biba_ipq_create,
3620         .mpo_ipq_destroy_label = biba_destroy_label,
3621         .mpo_ipq_init_label = biba_init_label_waitcheck,
3622         .mpo_ipq_match = biba_ipq_match,
3623         .mpo_ipq_reassemble = biba_ipq_reassemble,
3624         .mpo_ipq_update = biba_ipq_update,
3625
3626         .mpo_kld_check_load = biba_kld_check_load,
3627
3628         .mpo_mbuf_copy_label = biba_copy_label,
3629         .mpo_mbuf_destroy_label = biba_destroy_label,
3630         .mpo_mbuf_init_label = biba_init_label_waitcheck,
3631
3632         .mpo_mount_check_stat = biba_mount_check_stat,
3633         .mpo_mount_create = biba_mount_create,
3634         .mpo_mount_destroy_label = biba_destroy_label,
3635         .mpo_mount_init_label = biba_init_label,
3636
3637         .mpo_netinet_arp_send = biba_netinet_arp_send,
3638         .mpo_netinet_firewall_reply = biba_netinet_firewall_reply,
3639         .mpo_netinet_firewall_send = biba_netinet_firewall_send,
3640         .mpo_netinet_fragment = biba_netinet_fragment,
3641         .mpo_netinet_icmp_reply = biba_netinet_icmp_reply,
3642         .mpo_netinet_igmp_send = biba_netinet_igmp_send,
3643
3644         .mpo_netinet6_nd6_send = biba_netinet6_nd6_send,
3645
3646         .mpo_pipe_check_ioctl = biba_pipe_check_ioctl,
3647         .mpo_pipe_check_poll = biba_pipe_check_poll,
3648         .mpo_pipe_check_read = biba_pipe_check_read,
3649         .mpo_pipe_check_relabel = biba_pipe_check_relabel,
3650         .mpo_pipe_check_stat = biba_pipe_check_stat,
3651         .mpo_pipe_check_write = biba_pipe_check_write,
3652         .mpo_pipe_copy_label = biba_copy_label,
3653         .mpo_pipe_create = biba_pipe_create,
3654         .mpo_pipe_destroy_label = biba_destroy_label,
3655         .mpo_pipe_externalize_label = biba_externalize_label,
3656         .mpo_pipe_init_label = biba_init_label,
3657         .mpo_pipe_internalize_label = biba_internalize_label,
3658         .mpo_pipe_relabel = biba_pipe_relabel,
3659
3660         .mpo_posixsem_check_getvalue = biba_posixsem_check_rdonly,
3661         .mpo_posixsem_check_open = biba_posixsem_check_openunlink,
3662         .mpo_posixsem_check_post = biba_posixsem_check_write,
3663         .mpo_posixsem_check_setmode = biba_posixsem_check_setmode,
3664         .mpo_posixsem_check_setowner = biba_posixsem_check_setowner,
3665         .mpo_posixsem_check_stat = biba_posixsem_check_rdonly,
3666         .mpo_posixsem_check_unlink = biba_posixsem_check_openunlink,
3667         .mpo_posixsem_check_wait = biba_posixsem_check_write,
3668         .mpo_posixsem_create = biba_posixsem_create,
3669         .mpo_posixsem_destroy_label = biba_destroy_label,
3670         .mpo_posixsem_init_label = biba_init_label,
3671
3672         .mpo_posixshm_check_mmap = biba_posixshm_check_mmap,
3673         .mpo_posixshm_check_open = biba_posixshm_check_open,
3674         .mpo_posixshm_check_read = biba_posixshm_check_read,
3675         .mpo_posixshm_check_setmode = biba_posixshm_check_setmode,
3676         .mpo_posixshm_check_setowner = biba_posixshm_check_setowner,
3677         .mpo_posixshm_check_stat = biba_posixshm_check_stat,
3678         .mpo_posixshm_check_truncate = biba_posixshm_check_truncate,
3679         .mpo_posixshm_check_unlink = biba_posixshm_check_unlink,
3680         .mpo_posixshm_check_write = biba_posixshm_check_write,
3681         .mpo_posixshm_create = biba_posixshm_create,
3682         .mpo_posixshm_destroy_label = biba_destroy_label,
3683         .mpo_posixshm_init_label = biba_init_label,
3684
3685         .mpo_priv_check = biba_priv_check,
3686
3687         .mpo_proc_check_debug = biba_proc_check_debug,
3688         .mpo_proc_check_sched = biba_proc_check_sched,
3689         .mpo_proc_check_signal = biba_proc_check_signal,
3690
3691         .mpo_socket_check_deliver = biba_socket_check_deliver,
3692         .mpo_socket_check_relabel = biba_socket_check_relabel,
3693         .mpo_socket_check_visible = biba_socket_check_visible,
3694         .mpo_socket_copy_label = biba_copy_label,
3695         .mpo_socket_create = biba_socket_create,
3696         .mpo_socket_create_mbuf = biba_socket_create_mbuf,
3697         .mpo_socket_destroy_label = biba_destroy_label,
3698         .mpo_socket_externalize_label = biba_externalize_label,
3699         .mpo_socket_init_label = biba_init_label_waitcheck,
3700         .mpo_socket_internalize_label = biba_internalize_label,
3701         .mpo_socket_newconn = biba_socket_newconn,
3702         .mpo_socket_relabel = biba_socket_relabel,
3703
3704         .mpo_socketpeer_destroy_label = biba_destroy_label,
3705         .mpo_socketpeer_externalize_label = biba_externalize_label,
3706         .mpo_socketpeer_init_label = biba_init_label_waitcheck,
3707         .mpo_socketpeer_set_from_mbuf = biba_socketpeer_set_from_mbuf,
3708         .mpo_socketpeer_set_from_socket = biba_socketpeer_set_from_socket,
3709
3710         .mpo_syncache_create = biba_syncache_create,
3711         .mpo_syncache_create_mbuf = biba_syncache_create_mbuf,
3712         .mpo_syncache_destroy_label = biba_destroy_label,
3713         .mpo_syncache_init_label = biba_init_label_waitcheck,
3714
3715         .mpo_system_check_acct = biba_system_check_acct,
3716         .mpo_system_check_auditctl = biba_system_check_auditctl,
3717         .mpo_system_check_auditon = biba_system_check_auditon,
3718         .mpo_system_check_swapoff = biba_system_check_swapoff,
3719         .mpo_system_check_swapon = biba_system_check_swapon,
3720         .mpo_system_check_sysctl = biba_system_check_sysctl,
3721
3722         .mpo_sysvmsg_cleanup = biba_sysvmsg_cleanup,
3723         .mpo_sysvmsg_create = biba_sysvmsg_create,
3724         .mpo_sysvmsg_destroy_label = biba_destroy_label,
3725         .mpo_sysvmsg_init_label = biba_init_label,
3726
3727         .mpo_sysvmsq_check_msgrcv = biba_sysvmsq_check_msgrcv,
3728         .mpo_sysvmsq_check_msgrmid = biba_sysvmsq_check_msgrmid,
3729         .mpo_sysvmsq_check_msqget = biba_sysvmsq_check_msqget,
3730         .mpo_sysvmsq_check_msqsnd = biba_sysvmsq_check_msqsnd,
3731         .mpo_sysvmsq_check_msqrcv = biba_sysvmsq_check_msqrcv,
3732         .mpo_sysvmsq_check_msqctl = biba_sysvmsq_check_msqctl,
3733         .mpo_sysvmsq_cleanup = biba_sysvmsq_cleanup,
3734         .mpo_sysvmsq_create = biba_sysvmsq_create,
3735         .mpo_sysvmsq_destroy_label = biba_destroy_label,
3736         .mpo_sysvmsq_init_label = biba_init_label,
3737
3738         .mpo_sysvsem_check_semctl = biba_sysvsem_check_semctl,
3739         .mpo_sysvsem_check_semget = biba_sysvsem_check_semget,
3740         .mpo_sysvsem_check_semop = biba_sysvsem_check_semop,
3741         .mpo_sysvsem_cleanup = biba_sysvsem_cleanup,
3742         .mpo_sysvsem_create = biba_sysvsem_create,
3743         .mpo_sysvsem_destroy_label = biba_destroy_label,
3744         .mpo_sysvsem_init_label = biba_init_label,
3745
3746         .mpo_sysvshm_check_shmat = biba_sysvshm_check_shmat,
3747         .mpo_sysvshm_check_shmctl = biba_sysvshm_check_shmctl,
3748         .mpo_sysvshm_check_shmget = biba_sysvshm_check_shmget,
3749         .mpo_sysvshm_cleanup = biba_sysvshm_cleanup,
3750         .mpo_sysvshm_create = biba_sysvshm_create,
3751         .mpo_sysvshm_destroy_label = biba_destroy_label,
3752         .mpo_sysvshm_init_label = biba_init_label,
3753
3754         .mpo_vnode_associate_extattr = biba_vnode_associate_extattr,
3755         .mpo_vnode_associate_singlelabel = biba_vnode_associate_singlelabel,
3756         .mpo_vnode_check_access = biba_vnode_check_open,
3757         .mpo_vnode_check_chdir = biba_vnode_check_chdir,
3758         .mpo_vnode_check_chroot = biba_vnode_check_chroot,
3759         .mpo_vnode_check_create = biba_vnode_check_create,
3760         .mpo_vnode_check_deleteacl = biba_vnode_check_deleteacl,
3761         .mpo_vnode_check_deleteextattr = biba_vnode_check_deleteextattr,
3762         .mpo_vnode_check_exec = biba_vnode_check_exec,
3763         .mpo_vnode_check_getacl = biba_vnode_check_getacl,
3764         .mpo_vnode_check_getextattr = biba_vnode_check_getextattr,
3765         .mpo_vnode_check_link = biba_vnode_check_link,
3766         .mpo_vnode_check_listextattr = biba_vnode_check_listextattr,
3767         .mpo_vnode_check_lookup = biba_vnode_check_lookup,
3768         .mpo_vnode_check_mmap = biba_vnode_check_mmap,
3769         .mpo_vnode_check_open = biba_vnode_check_open,
3770         .mpo_vnode_check_poll = biba_vnode_check_poll,
3771         .mpo_vnode_check_read = biba_vnode_check_read,
3772         .mpo_vnode_check_readdir = biba_vnode_check_readdir,
3773         .mpo_vnode_check_readlink = biba_vnode_check_readlink,
3774         .mpo_vnode_check_relabel = biba_vnode_check_relabel,
3775         .mpo_vnode_check_rename_from = biba_vnode_check_rename_from,
3776         .mpo_vnode_check_rename_to = biba_vnode_check_rename_to,
3777         .mpo_vnode_check_revoke = biba_vnode_check_revoke,
3778         .mpo_vnode_check_setacl = biba_vnode_check_setacl,
3779         .mpo_vnode_check_setextattr = biba_vnode_check_setextattr,
3780         .mpo_vnode_check_setflags = biba_vnode_check_setflags,
3781         .mpo_vnode_check_setmode = biba_vnode_check_setmode,
3782         .mpo_vnode_check_setowner = biba_vnode_check_setowner,
3783         .mpo_vnode_check_setutimes = biba_vnode_check_setutimes,
3784         .mpo_vnode_check_stat = biba_vnode_check_stat,
3785         .mpo_vnode_check_unlink = biba_vnode_check_unlink,
3786         .mpo_vnode_check_write = biba_vnode_check_write,
3787         .mpo_vnode_create_extattr = biba_vnode_create_extattr,
3788         .mpo_vnode_copy_label = biba_copy_label,
3789         .mpo_vnode_destroy_label = biba_destroy_label,
3790         .mpo_vnode_externalize_label = biba_externalize_label,
3791         .mpo_vnode_init_label = biba_init_label,
3792         .mpo_vnode_internalize_label = biba_internalize_label,
3793         .mpo_vnode_relabel = biba_vnode_relabel,
3794         .mpo_vnode_setlabel_extattr = biba_vnode_setlabel_extattr,
3795 };
3796
3797 MAC_POLICY_SET(&mac_biba_ops, mac_biba, "TrustedBSD MAC/Biba",
3798     MPC_LOADTIME_FLAG_NOTLATE, &biba_slot);