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