xref: /freebsd/sys/security/mac_biba/mac_biba.c (revision e0c27215058b5786c78fcfb3963eebe61a989511)
1 /*-
2  * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson
3  * Copyright (c) 2001, 2002, 2003 Networks Associates Technology, Inc.
4  * All rights reserved.
5  *
6  * This software was developed by Robert Watson for the TrustedBSD Project.
7  *
8  * This software was developed for the FreeBSD Project in part by Network
9  * Associates Laboratories, the Security Research Division of Network
10  * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"),
11  * as part of the DARPA CHATS research program.
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions
15  * are met:
16  * 1. Redistributions of source code must retain the above copyright
17  *    notice, this list of conditions and the following disclaimer.
18  * 2. Redistributions in binary form must reproduce the above copyright
19  *    notice, this list of conditions and the following disclaimer in the
20  *    documentation and/or other materials provided with the distribution.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  *
34  * $FreeBSD$
35  */
36 
37 /*
38  * Developed by the TrustedBSD Project.
39  * Biba fixed label mandatory integrity policy.
40  */
41 
42 #include <sys/types.h>
43 #include <sys/param.h>
44 #include <sys/acl.h>
45 #include <sys/conf.h>
46 #include <sys/extattr.h>
47 #include <sys/kernel.h>
48 #include <sys/mac.h>
49 #include <sys/malloc.h>
50 #include <sys/mount.h>
51 #include <sys/proc.h>
52 #include <sys/sbuf.h>
53 #include <sys/systm.h>
54 #include <sys/sysproto.h>
55 #include <sys/sysent.h>
56 #include <sys/systm.h>
57 #include <sys/vnode.h>
58 #include <sys/file.h>
59 #include <sys/socket.h>
60 #include <sys/socketvar.h>
61 #include <sys/pipe.h>
62 #include <sys/sysctl.h>
63 
64 #include <fs/devfs/devfs.h>
65 
66 #include <net/bpfdesc.h>
67 #include <net/if.h>
68 #include <net/if_types.h>
69 #include <net/if_var.h>
70 
71 #include <netinet/in.h>
72 #include <netinet/ip_var.h>
73 
74 #include <vm/vm.h>
75 
76 #include <sys/mac_policy.h>
77 
78 #include <security/mac_biba/mac_biba.h>
79 
80 SYSCTL_DECL(_security_mac);
81 
82 SYSCTL_NODE(_security_mac, OID_AUTO, biba, CTLFLAG_RW, 0,
83     "TrustedBSD mac_biba policy controls");
84 
85 static int	mac_biba_label_size = sizeof(struct mac_biba);
86 SYSCTL_INT(_security_mac_biba, OID_AUTO, label_size, CTLFLAG_RD,
87     &mac_biba_label_size, 0, "Size of struct mac_biba");
88 
89 static int	mac_biba_enabled = 1;
90 SYSCTL_INT(_security_mac_biba, OID_AUTO, enabled, CTLFLAG_RW,
91     &mac_biba_enabled, 0, "Enforce MAC/Biba policy");
92 TUNABLE_INT("security.mac.biba.enabled", &mac_biba_enabled);
93 
94 static int	destroyed_not_inited;
95 SYSCTL_INT(_security_mac_biba, OID_AUTO, destroyed_not_inited, CTLFLAG_RD,
96     &destroyed_not_inited, 0, "Count of labels destroyed but not inited");
97 
98 static int	trust_all_interfaces = 0;
99 SYSCTL_INT(_security_mac_biba, OID_AUTO, trust_all_interfaces, CTLFLAG_RD,
100     &trust_all_interfaces, 0, "Consider all interfaces 'trusted' by MAC/Biba");
101 TUNABLE_INT("security.mac.biba.trust_all_interfaces", &trust_all_interfaces);
102 
103 static char	trusted_interfaces[128];
104 SYSCTL_STRING(_security_mac_biba, OID_AUTO, trusted_interfaces, CTLFLAG_RD,
105     trusted_interfaces, 0, "Interfaces considered 'trusted' by MAC/Biba");
106 TUNABLE_STR("security.mac.biba.trusted_interfaces", trusted_interfaces,
107     sizeof(trusted_interfaces));
108 
109 static int	max_compartments = MAC_BIBA_MAX_COMPARTMENTS;
110 SYSCTL_INT(_security_mac_biba, OID_AUTO, max_compartments, CTLFLAG_RD,
111     &max_compartments, 0, "Maximum supported compartments");
112 
113 static int	ptys_equal = 0;
114 SYSCTL_INT(_security_mac_biba, OID_AUTO, ptys_equal, CTLFLAG_RW,
115     &ptys_equal, 0, "Label pty devices as biba/equal on create");
116 TUNABLE_INT("security.mac.biba.ptys_equal", &ptys_equal);
117 
118 static int	revocation_enabled = 0;
119 SYSCTL_INT(_security_mac_biba, OID_AUTO, revocation_enabled, CTLFLAG_RW,
120     &revocation_enabled, 0, "Revoke access to objects on relabel");
121 TUNABLE_INT("security.mac.biba.revocation_enabled", &revocation_enabled);
122 
123 static int	mac_biba_slot;
124 #define	SLOT(l)	((struct mac_biba *)LABEL_TO_SLOT((l), mac_biba_slot).l_ptr)
125 
126 MALLOC_DEFINE(M_MACBIBA, "biba label", "MAC/Biba labels");
127 
128 static __inline int
129 biba_bit_set_empty(u_char *set) {
130 	int i;
131 
132 	for (i = 0; i < MAC_BIBA_MAX_COMPARTMENTS >> 3; i++)
133 		if (set[i] != 0)
134 			return (0);
135 	return (1);
136 }
137 
138 static struct mac_biba *
139 biba_alloc(int flag)
140 {
141 	struct mac_biba *mac_biba;
142 
143 	mac_biba = malloc(sizeof(struct mac_biba), M_MACBIBA, M_ZERO | flag);
144 
145 	return (mac_biba);
146 }
147 
148 static void
149 biba_free(struct mac_biba *mac_biba)
150 {
151 
152 	if (mac_biba != NULL)
153 		free(mac_biba, M_MACBIBA);
154 	else
155 		atomic_add_int(&destroyed_not_inited, 1);
156 }
157 
158 static int
159 biba_atmostflags(struct mac_biba *mac_biba, int flags)
160 {
161 
162 	if ((mac_biba->mb_flags & flags) != mac_biba->mb_flags)
163 		return (EINVAL);
164 	return (0);
165 }
166 
167 static int
168 mac_biba_dominate_element(struct mac_biba_element *a,
169     struct mac_biba_element *b)
170 {
171 	int bit;
172 
173 	switch (a->mbe_type) {
174 	case MAC_BIBA_TYPE_EQUAL:
175 	case MAC_BIBA_TYPE_HIGH:
176 		return (1);
177 
178 	case MAC_BIBA_TYPE_LOW:
179 		switch (b->mbe_type) {
180 		case MAC_BIBA_TYPE_GRADE:
181 		case MAC_BIBA_TYPE_HIGH:
182 			return (0);
183 
184 		case MAC_BIBA_TYPE_EQUAL:
185 		case MAC_BIBA_TYPE_LOW:
186 			return (1);
187 
188 		default:
189 			panic("mac_biba_dominate_element: b->mbe_type invalid");
190 		}
191 
192 	case MAC_BIBA_TYPE_GRADE:
193 		switch (b->mbe_type) {
194 		case MAC_BIBA_TYPE_EQUAL:
195 		case MAC_BIBA_TYPE_LOW:
196 			return (1);
197 
198 		case MAC_BIBA_TYPE_HIGH:
199 			return (0);
200 
201 		case MAC_BIBA_TYPE_GRADE:
202 			for (bit = 1; bit <= MAC_BIBA_MAX_COMPARTMENTS; bit++)
203 				if (!MAC_BIBA_BIT_TEST(bit,
204 				    a->mbe_compartments) &&
205 				    MAC_BIBA_BIT_TEST(bit, b->mbe_compartments))
206 					return (0);
207 			return (a->mbe_grade >= b->mbe_grade);
208 
209 		default:
210 			panic("mac_biba_dominate_element: b->mbe_type invalid");
211 		}
212 
213 	default:
214 		panic("mac_biba_dominate_element: a->mbe_type invalid");
215 	}
216 
217 	return (0);
218 }
219 
220 static int
221 mac_biba_subject_dominate_high(struct mac_biba *mac_biba)
222 {
223 	struct mac_biba_element *element;
224 
225 	KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
226 	    ("mac_biba_single_in_range: mac_biba not single"));
227 	element = &mac_biba->mb_single;
228 
229 	return (element->mbe_type == MAC_BIBA_TYPE_EQUAL ||
230 	    element->mbe_type == MAC_BIBA_TYPE_HIGH);
231 }
232 
233 static int
234 mac_biba_range_in_range(struct mac_biba *rangea, struct mac_biba *rangeb)
235 {
236 
237 	return (mac_biba_dominate_element(&rangeb->mb_rangehigh,
238 	    &rangea->mb_rangehigh) &&
239 	    mac_biba_dominate_element(&rangea->mb_rangelow,
240 	    &rangeb->mb_rangelow));
241 }
242 
243 static int
244 mac_biba_single_in_range(struct mac_biba *single, struct mac_biba *range)
245 {
246 
247 	KASSERT((single->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
248 	    ("mac_biba_single_in_range: a not single"));
249 	KASSERT((range->mb_flags & MAC_BIBA_FLAG_RANGE) != 0,
250 	    ("mac_biba_single_in_range: b not range"));
251 
252 	return (mac_biba_dominate_element(&range->mb_rangehigh,
253 	    &single->mb_single) &&
254 	    mac_biba_dominate_element(&single->mb_single,
255 	    &range->mb_rangelow));
256 
257 	return (1);
258 }
259 
260 static int
261 mac_biba_dominate_single(struct mac_biba *a, struct mac_biba *b)
262 {
263 	KASSERT((a->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
264 	    ("mac_biba_dominate_single: a not single"));
265 	KASSERT((b->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
266 	    ("mac_biba_dominate_single: b not single"));
267 
268 	return (mac_biba_dominate_element(&a->mb_single, &b->mb_single));
269 }
270 
271 static int
272 mac_biba_equal_element(struct mac_biba_element *a, struct mac_biba_element *b)
273 {
274 
275 	if (a->mbe_type == MAC_BIBA_TYPE_EQUAL ||
276 	    b->mbe_type == MAC_BIBA_TYPE_EQUAL)
277 		return (1);
278 
279 	return (a->mbe_type == b->mbe_type && a->mbe_grade == b->mbe_grade);
280 }
281 
282 static int
283 mac_biba_equal_single(struct mac_biba *a, struct mac_biba *b)
284 {
285 
286 	KASSERT((a->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
287 	    ("mac_biba_equal_single: a not single"));
288 	KASSERT((b->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
289 	    ("mac_biba_equal_single: b not single"));
290 
291 	return (mac_biba_equal_element(&a->mb_single, &b->mb_single));
292 }
293 
294 static int
295 mac_biba_contains_equal(struct mac_biba *mac_biba)
296 {
297 
298 	if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE)
299 		if (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_EQUAL)
300 			return (1);
301 
302 	if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
303 		if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL)
304 			return (1);
305 		if (mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL)
306 			return (1);
307 	}
308 
309 	return (0);
310 }
311 
312 static int
313 mac_biba_subject_privileged(struct mac_biba *mac_biba)
314 {
315 
316 	KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAGS_BOTH) ==
317 	    MAC_BIBA_FLAGS_BOTH,
318 	    ("mac_biba_subject_privileged: subject doesn't have both labels"));
319 
320 	/* If the single is EQUAL, it's ok. */
321 	if (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_EQUAL)
322 		return (0);
323 
324 	/* If either range endpoint is EQUAL, it's ok. */
325 	if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL ||
326 	    mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL)
327 		return (0);
328 
329 	/* If the range is low-high, it's ok. */
330 	if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_LOW &&
331 	    mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_HIGH)
332 		return (0);
333 
334 	/* It's not ok. */
335 	return (EPERM);
336 }
337 
338 static int
339 mac_biba_high_single(struct mac_biba *mac_biba)
340 {
341 
342 	KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
343 	    ("mac_biba_equal_single: mac_biba not single"));
344 
345 	return (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_HIGH);
346 }
347 
348 static int
349 mac_biba_valid(struct mac_biba *mac_biba)
350 {
351 
352 	if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) {
353 		switch (mac_biba->mb_single.mbe_type) {
354 		case MAC_BIBA_TYPE_GRADE:
355 			break;
356 
357 		case MAC_BIBA_TYPE_EQUAL:
358 		case MAC_BIBA_TYPE_HIGH:
359 		case MAC_BIBA_TYPE_LOW:
360 			if (mac_biba->mb_single.mbe_grade != 0 ||
361 			    !MAC_BIBA_BIT_SET_EMPTY(
362 			    mac_biba->mb_single.mbe_compartments))
363 				return (EINVAL);
364 			break;
365 
366 		default:
367 			return (EINVAL);
368 		}
369 	} else {
370 		if (mac_biba->mb_single.mbe_type != MAC_BIBA_TYPE_UNDEF)
371 			return (EINVAL);
372 	}
373 
374 	if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
375 		switch (mac_biba->mb_rangelow.mbe_type) {
376 		case MAC_BIBA_TYPE_GRADE:
377 			break;
378 
379 		case MAC_BIBA_TYPE_EQUAL:
380 		case MAC_BIBA_TYPE_HIGH:
381 		case MAC_BIBA_TYPE_LOW:
382 			if (mac_biba->mb_rangelow.mbe_grade != 0 ||
383 			    !MAC_BIBA_BIT_SET_EMPTY(
384 			    mac_biba->mb_rangelow.mbe_compartments))
385 				return (EINVAL);
386 			break;
387 
388 		default:
389 			return (EINVAL);
390 		}
391 
392 		switch (mac_biba->mb_rangehigh.mbe_type) {
393 		case MAC_BIBA_TYPE_GRADE:
394 			break;
395 
396 		case MAC_BIBA_TYPE_EQUAL:
397 		case MAC_BIBA_TYPE_HIGH:
398 		case MAC_BIBA_TYPE_LOW:
399 			if (mac_biba->mb_rangehigh.mbe_grade != 0 ||
400 			    !MAC_BIBA_BIT_SET_EMPTY(
401 			    mac_biba->mb_rangehigh.mbe_compartments))
402 				return (EINVAL);
403 			break;
404 
405 		default:
406 			return (EINVAL);
407 		}
408 		if (!mac_biba_dominate_element(&mac_biba->mb_rangehigh,
409 		    &mac_biba->mb_rangelow))
410 			return (EINVAL);
411 	} else {
412 		if (mac_biba->mb_rangelow.mbe_type != MAC_BIBA_TYPE_UNDEF ||
413 		    mac_biba->mb_rangehigh.mbe_type != MAC_BIBA_TYPE_UNDEF)
414 			return (EINVAL);
415 	}
416 
417 	return (0);
418 }
419 
420 static void
421 mac_biba_set_range(struct mac_biba *mac_biba, u_short typelow,
422     u_short gradelow, u_char *compartmentslow, u_short typehigh,
423     u_short gradehigh, u_char *compartmentshigh)
424 {
425 
426 	mac_biba->mb_rangelow.mbe_type = typelow;
427 	mac_biba->mb_rangelow.mbe_grade = gradelow;
428 	if (compartmentslow != NULL)
429 		memcpy(mac_biba->mb_rangelow.mbe_compartments,
430 		    compartmentslow,
431 		    sizeof(mac_biba->mb_rangelow.mbe_compartments));
432 	mac_biba->mb_rangehigh.mbe_type = typehigh;
433 	mac_biba->mb_rangehigh.mbe_grade = gradehigh;
434 	if (compartmentshigh != NULL)
435 		memcpy(mac_biba->mb_rangehigh.mbe_compartments,
436 		    compartmentshigh,
437 		    sizeof(mac_biba->mb_rangehigh.mbe_compartments));
438 	mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE;
439 }
440 
441 static void
442 mac_biba_set_single(struct mac_biba *mac_biba, u_short type, u_short grade,
443     u_char *compartments)
444 {
445 
446 	mac_biba->mb_single.mbe_type = type;
447 	mac_biba->mb_single.mbe_grade = grade;
448 	if (compartments != NULL)
449 		memcpy(mac_biba->mb_single.mbe_compartments, compartments,
450 		    sizeof(mac_biba->mb_single.mbe_compartments));
451 	mac_biba->mb_flags |= MAC_BIBA_FLAG_SINGLE;
452 }
453 
454 static void
455 mac_biba_copy_range(struct mac_biba *labelfrom, struct mac_biba *labelto)
456 {
457 
458 	KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_RANGE) != 0,
459 	    ("mac_biba_copy_range: labelfrom not range"));
460 
461 	labelto->mb_rangelow = labelfrom->mb_rangelow;
462 	labelto->mb_rangehigh = labelfrom->mb_rangehigh;
463 	labelto->mb_flags |= MAC_BIBA_FLAG_RANGE;
464 }
465 
466 static void
467 mac_biba_copy_single(struct mac_biba *labelfrom, struct mac_biba *labelto)
468 {
469 
470 	KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
471 	    ("mac_biba_copy_single: labelfrom not single"));
472 
473 	labelto->mb_single = labelfrom->mb_single;
474 	labelto->mb_flags |= MAC_BIBA_FLAG_SINGLE;
475 }
476 
477 static void
478 mac_biba_copy(struct mac_biba *source, struct mac_biba *dest)
479 {
480 
481 	if (source->mb_flags & MAC_BIBA_FLAG_SINGLE)
482 		mac_biba_copy_single(source, dest);
483 	if (source->mb_flags & MAC_BIBA_FLAG_RANGE)
484 		mac_biba_copy_range(source, dest);
485 }
486 
487 /*
488  * Policy module operations.
489  */
490 static void
491 mac_biba_destroy(struct mac_policy_conf *conf)
492 {
493 
494 }
495 
496 static void
497 mac_biba_init(struct mac_policy_conf *conf)
498 {
499 
500 }
501 
502 /*
503  * Label operations.
504  */
505 static void
506 mac_biba_init_label(struct label *label)
507 {
508 
509 	SLOT(label) = biba_alloc(M_WAITOK);
510 }
511 
512 static int
513 mac_biba_init_label_waitcheck(struct label *label, int flag)
514 {
515 
516 	SLOT(label) = biba_alloc(flag);
517 	if (SLOT(label) == NULL)
518 		return (ENOMEM);
519 
520 	return (0);
521 }
522 
523 static void
524 mac_biba_destroy_label(struct label *label)
525 {
526 
527 	biba_free(SLOT(label));
528 	SLOT(label) = NULL;
529 }
530 
531 /*
532  * mac_biba_element_to_string() accepts an sbuf and Biba element.  It
533  * converts the Biba element to a string and stores the result in the
534  * sbuf; if there isn't space in the sbuf, -1 is returned.
535  */
536 static int
537 mac_biba_element_to_string(struct sbuf *sb, struct mac_biba_element *element)
538 {
539 	int i, first;
540 
541 	switch (element->mbe_type) {
542 	case MAC_BIBA_TYPE_HIGH:
543 		return (sbuf_printf(sb, "high"));
544 
545 	case MAC_BIBA_TYPE_LOW:
546 		return (sbuf_printf(sb, "low"));
547 
548 	case MAC_BIBA_TYPE_EQUAL:
549 		return (sbuf_printf(sb, "equal"));
550 
551 	case MAC_BIBA_TYPE_GRADE:
552 		if (sbuf_printf(sb, "%d", element->mbe_grade) == -1)
553 			return (-1);
554 
555 		first = 1;
556 		for (i = 1; i <= MAC_BIBA_MAX_COMPARTMENTS; i++) {
557 			if (MAC_BIBA_BIT_TEST(i, element->mbe_compartments)) {
558 				if (first) {
559 					if (sbuf_putc(sb, ':') == -1)
560 						return (-1);
561 					if (sbuf_printf(sb, "%d", i) == -1)
562 						return (-1);
563 					first = 0;
564 				} else {
565 					if (sbuf_printf(sb, "+%d", i) == -1)
566 						return (-1);
567 				}
568 			}
569 		}
570 		return (0);
571 
572 	default:
573 		panic("mac_biba_element_to_string: invalid type (%d)",
574 		    element->mbe_type);
575 	}
576 }
577 
578 /*
579  * mac_biba_to_string() converts a Biba label to a string, and places
580  * the results in the passed sbuf.  It returns 0 on success, or EINVAL
581  * if there isn't room in the sbuf.  Note: the sbuf will be modified
582  * even in a failure case, so the caller may need to revert the sbuf
583  * by restoring the offset if that's undesired.
584  */
585 static int
586 mac_biba_to_string(struct sbuf *sb, struct mac_biba *mac_biba)
587 {
588 
589 	if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) {
590 		if (mac_biba_element_to_string(sb, &mac_biba->mb_single)
591 		    == -1)
592 			return (EINVAL);
593 	}
594 
595 	if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
596 		if (sbuf_putc(sb, '(') == -1)
597 			return (EINVAL);
598 
599 		if (mac_biba_element_to_string(sb, &mac_biba->mb_rangelow)
600 		    == -1)
601 			return (EINVAL);
602 
603 		if (sbuf_putc(sb, '-') == -1)
604 			return (EINVAL);
605 
606 		if (mac_biba_element_to_string(sb, &mac_biba->mb_rangehigh)
607 		    == -1)
608 			return (EINVAL);
609 
610 		if (sbuf_putc(sb, ')') == -1)
611 			return (EINVAL);
612 	}
613 
614 	return (0);
615 }
616 
617 static int
618 mac_biba_externalize_label(struct label *label, char *element_name,
619     struct sbuf *sb, int *claimed)
620 {
621 	struct mac_biba *mac_biba;
622 
623 	if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0)
624 		return (0);
625 
626 	(*claimed)++;
627 
628 	mac_biba = SLOT(label);
629 	return (mac_biba_to_string(sb, mac_biba));
630 }
631 
632 static int
633 mac_biba_parse_element(struct mac_biba_element *element, char *string)
634 {
635 	char *compartment, *end, *grade;
636 	int value;
637 
638 	if (strcmp(string, "high") == 0 ||
639 	    strcmp(string, "hi") == 0) {
640 		element->mbe_type = MAC_BIBA_TYPE_HIGH;
641 		element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
642 	} else if (strcmp(string, "low") == 0 ||
643 	    strcmp(string, "lo") == 0) {
644 		element->mbe_type = MAC_BIBA_TYPE_LOW;
645 		element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
646 	} else if (strcmp(string, "equal") == 0 ||
647 	    strcmp(string, "eq") == 0) {
648 		element->mbe_type = MAC_BIBA_TYPE_EQUAL;
649 		element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
650 	} else {
651 		element->mbe_type = MAC_BIBA_TYPE_GRADE;
652 
653 		/*
654 		 * Numeric grade piece of the element.
655 		 */
656 		grade = strsep(&string, ":");
657 		value = strtol(grade, &end, 10);
658 		if (end == grade || *end != '\0')
659 			return (EINVAL);
660 		if (value < 0 || value > 65535)
661 			return (EINVAL);
662 		element->mbe_grade = value;
663 
664 		/*
665 		 * Optional compartment piece of the element.  If none
666 		 * are included, we assume that the label has no
667 		 * compartments.
668 		 */
669 		if (string == NULL)
670 			return (0);
671 		if (*string == '\0')
672 			return (0);
673 
674 		while ((compartment = strsep(&string, "+")) != NULL) {
675 			value = strtol(compartment, &end, 10);
676 			if (compartment == end || *end != '\0')
677 				return (EINVAL);
678 			if (value < 1 || value > MAC_BIBA_MAX_COMPARTMENTS)
679 				return (EINVAL);
680 			MAC_BIBA_BIT_SET(value, element->mbe_compartments);
681 		}
682 	}
683 
684 	return (0);
685 }
686 
687 /*
688  * Note: destructively consumes the string, make a local copy before
689  * calling if that's a problem.
690  */
691 static int
692 mac_biba_parse(struct mac_biba *mac_biba, char *string)
693 {
694 	char *rangehigh, *rangelow, *single;
695 	int error;
696 
697 	single = strsep(&string, "(");
698 	if (*single == '\0')
699 		single = NULL;
700 
701 	if (string != NULL) {
702 		rangelow = strsep(&string, "-");
703 		if (string == NULL)
704 			return (EINVAL);
705 		rangehigh = strsep(&string, ")");
706 		if (string == NULL)
707 			return (EINVAL);
708 		if (*string != '\0')
709 			return (EINVAL);
710 	} else {
711 		rangelow = NULL;
712 		rangehigh = NULL;
713 	}
714 
715 	KASSERT((rangelow != NULL && rangehigh != NULL) ||
716 	    (rangelow == NULL && rangehigh == NULL),
717 	    ("mac_biba_parse: range mismatch"));
718 
719 	bzero(mac_biba, sizeof(*mac_biba));
720 	if (single != NULL) {
721 		error = mac_biba_parse_element(&mac_biba->mb_single, single);
722 		if (error)
723 			return (error);
724 		mac_biba->mb_flags |= MAC_BIBA_FLAG_SINGLE;
725 	}
726 
727 	if (rangelow != NULL) {
728 		error = mac_biba_parse_element(&mac_biba->mb_rangelow,
729 		    rangelow);
730 		if (error)
731 			return (error);
732 		error = mac_biba_parse_element(&mac_biba->mb_rangehigh,
733 		    rangehigh);
734 		if (error)
735 			return (error);
736 		mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE;
737 	}
738 
739 	error = mac_biba_valid(mac_biba);
740 	if (error)
741 		return (error);
742 
743 	return (0);
744 }
745 
746 static int
747 mac_biba_internalize_label(struct label *label, char *element_name,
748     char *element_data, int *claimed)
749 {
750 	struct mac_biba *mac_biba, mac_biba_temp;
751 	int error;
752 
753 	if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0)
754 		return (0);
755 
756 	(*claimed)++;
757 
758 	error = mac_biba_parse(&mac_biba_temp, element_data);
759 	if (error)
760 		return (error);
761 
762 	mac_biba = SLOT(label);
763 	*mac_biba = mac_biba_temp;
764 
765 	return (0);
766 }
767 
768 static void
769 mac_biba_copy_label(struct label *src, struct label *dest)
770 {
771 
772 	*SLOT(dest) = *SLOT(src);
773 }
774 
775 /*
776  * Labeling event operations: file system objects, and things that look
777  * a lot like file system objects.
778  */
779 static void
780 mac_biba_create_devfs_device(struct mount *mp, dev_t dev,
781     struct devfs_dirent *devfs_dirent, struct label *label)
782 {
783 	struct mac_biba *mac_biba;
784 	int biba_type;
785 
786 	mac_biba = SLOT(label);
787 	if (strcmp(dev->si_name, "null") == 0 ||
788 	    strcmp(dev->si_name, "zero") == 0 ||
789 	    strcmp(dev->si_name, "random") == 0 ||
790 	    strncmp(dev->si_name, "fd/", strlen("fd/")) == 0)
791 		biba_type = MAC_BIBA_TYPE_EQUAL;
792 	else if (ptys_equal &&
793 	    (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 ||
794 	    strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0))
795 		biba_type = MAC_BIBA_TYPE_EQUAL;
796 	else
797 		biba_type = MAC_BIBA_TYPE_HIGH;
798 	mac_biba_set_single(mac_biba, biba_type, 0, NULL);
799 }
800 
801 static void
802 mac_biba_create_devfs_directory(struct mount *mp, char *dirname,
803     int dirnamelen, struct devfs_dirent *devfs_dirent, struct label *label)
804 {
805 	struct mac_biba *mac_biba;
806 
807 	mac_biba = SLOT(label);
808 	mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
809 }
810 
811 static void
812 mac_biba_create_devfs_symlink(struct ucred *cred, struct mount *mp,
813     struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de,
814     struct label *delabel)
815 {
816 	struct mac_biba *source, *dest;
817 
818 	source = SLOT(&cred->cr_label);
819 	dest = SLOT(delabel);
820 
821 	mac_biba_copy_single(source, dest);
822 }
823 
824 static void
825 mac_biba_create_mount(struct ucred *cred, struct mount *mp,
826     struct label *mntlabel, struct label *fslabel)
827 {
828 	struct mac_biba *source, *dest;
829 
830 	source = SLOT(&cred->cr_label);
831 	dest = SLOT(mntlabel);
832 	mac_biba_copy_single(source, dest);
833 	dest = SLOT(fslabel);
834 	mac_biba_copy_single(source, dest);
835 }
836 
837 static void
838 mac_biba_create_root_mount(struct ucred *cred, struct mount *mp,
839     struct label *mntlabel, struct label *fslabel)
840 {
841 	struct mac_biba *mac_biba;
842 
843 	/* Always mount root as high integrity. */
844 	mac_biba = SLOT(fslabel);
845 	mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
846 	mac_biba = SLOT(mntlabel);
847 	mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
848 }
849 
850 static void
851 mac_biba_relabel_vnode(struct ucred *cred, struct vnode *vp,
852     struct label *vnodelabel, struct label *label)
853 {
854 	struct mac_biba *source, *dest;
855 
856 	source = SLOT(label);
857 	dest = SLOT(vnodelabel);
858 
859 	mac_biba_copy(source, dest);
860 }
861 
862 static void
863 mac_biba_update_devfsdirent(struct mount *mp,
864     struct devfs_dirent *devfs_dirent, struct label *direntlabel,
865     struct vnode *vp, struct label *vnodelabel)
866 {
867 	struct mac_biba *source, *dest;
868 
869 	source = SLOT(vnodelabel);
870 	dest = SLOT(direntlabel);
871 
872 	mac_biba_copy(source, dest);
873 }
874 
875 static void
876 mac_biba_associate_vnode_devfs(struct mount *mp, struct label *fslabel,
877     struct devfs_dirent *de, struct label *delabel, struct vnode *vp,
878     struct label *vlabel)
879 {
880 	struct mac_biba *source, *dest;
881 
882 	source = SLOT(delabel);
883 	dest = SLOT(vlabel);
884 
885 	mac_biba_copy_single(source, dest);
886 }
887 
888 static int
889 mac_biba_associate_vnode_extattr(struct mount *mp, struct label *fslabel,
890     struct vnode *vp, struct label *vlabel)
891 {
892 	struct mac_biba temp, *source, *dest;
893 	int buflen, error;
894 
895 	source = SLOT(fslabel);
896 	dest = SLOT(vlabel);
897 
898 	buflen = sizeof(temp);
899 	bzero(&temp, buflen);
900 
901 	error = vn_extattr_get(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
902 	    MAC_BIBA_EXTATTR_NAME, &buflen, (char *) &temp, curthread);
903 	if (error == ENOATTR || error == EOPNOTSUPP) {
904 		/* Fall back to the fslabel. */
905 		mac_biba_copy_single(source, dest);
906 		return (0);
907 	} else if (error)
908 		return (error);
909 
910 	if (buflen != sizeof(temp)) {
911 		printf("mac_biba_associate_vnode_extattr: bad size %d\n",
912 		    buflen);
913 		return (EPERM);
914 	}
915 	if (mac_biba_valid(&temp) != 0) {
916 		printf("mac_biba_associate_vnode_extattr: invalid\n");
917 		return (EPERM);
918 	}
919 	if ((temp.mb_flags & MAC_BIBA_FLAGS_BOTH) != MAC_BIBA_FLAG_SINGLE) {
920 		printf("mac_biba_associate_vnode_extattr: not single\n");
921 		return (EPERM);
922 	}
923 
924 	mac_biba_copy_single(&temp, dest);
925 	return (0);
926 }
927 
928 static void
929 mac_biba_associate_vnode_singlelabel(struct mount *mp,
930     struct label *fslabel, struct vnode *vp, struct label *vlabel)
931 {
932 	struct mac_biba *source, *dest;
933 
934 	source = SLOT(fslabel);
935 	dest = SLOT(vlabel);
936 
937 	mac_biba_copy_single(source, dest);
938 }
939 
940 static int
941 mac_biba_create_vnode_extattr(struct ucred *cred, struct mount *mp,
942     struct label *fslabel, struct vnode *dvp, struct label *dlabel,
943     struct vnode *vp, struct label *vlabel, struct componentname *cnp)
944 {
945 	struct mac_biba *source, *dest, temp;
946 	size_t buflen;
947 	int error;
948 
949 	buflen = sizeof(temp);
950 	bzero(&temp, buflen);
951 
952 	source = SLOT(&cred->cr_label);
953 	dest = SLOT(vlabel);
954 	mac_biba_copy_single(source, &temp);
955 
956 	error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
957 	    MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread);
958 	if (error == 0)
959 		mac_biba_copy_single(source, dest);
960 	return (error);
961 }
962 
963 static int
964 mac_biba_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp,
965     struct label *vlabel, struct label *intlabel)
966 {
967 	struct mac_biba *source, temp;
968 	size_t buflen;
969 	int error;
970 
971 	buflen = sizeof(temp);
972 	bzero(&temp, buflen);
973 
974 	source = SLOT(intlabel);
975 	if ((source->mb_flags & MAC_BIBA_FLAG_SINGLE) == 0)
976 		return (0);
977 
978 	mac_biba_copy_single(source, &temp);
979 
980 	error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
981 	    MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread);
982 	return (error);
983 }
984 
985 /*
986  * Labeling event operations: IPC object.
987  */
988 static void
989 mac_biba_create_mbuf_from_socket(struct socket *so, struct label *socketlabel,
990     struct mbuf *m, struct label *mbuflabel)
991 {
992 	struct mac_biba *source, *dest;
993 
994 	source = SLOT(socketlabel);
995 	dest = SLOT(mbuflabel);
996 
997 	mac_biba_copy_single(source, dest);
998 }
999 
1000 static void
1001 mac_biba_create_socket(struct ucred *cred, struct socket *socket,
1002     struct label *socketlabel)
1003 {
1004 	struct mac_biba *source, *dest;
1005 
1006 	source = SLOT(&cred->cr_label);
1007 	dest = SLOT(socketlabel);
1008 
1009 	mac_biba_copy_single(source, dest);
1010 }
1011 
1012 static void
1013 mac_biba_create_pipe(struct ucred *cred, struct pipe *pipe,
1014     struct label *pipelabel)
1015 {
1016 	struct mac_biba *source, *dest;
1017 
1018 	source = SLOT(&cred->cr_label);
1019 	dest = SLOT(pipelabel);
1020 
1021 	mac_biba_copy_single(source, dest);
1022 }
1023 
1024 static void
1025 mac_biba_create_socket_from_socket(struct socket *oldsocket,
1026     struct label *oldsocketlabel, struct socket *newsocket,
1027     struct label *newsocketlabel)
1028 {
1029 	struct mac_biba *source, *dest;
1030 
1031 	source = SLOT(oldsocketlabel);
1032 	dest = SLOT(newsocketlabel);
1033 
1034 	mac_biba_copy_single(source, dest);
1035 }
1036 
1037 static void
1038 mac_biba_relabel_socket(struct ucred *cred, struct socket *socket,
1039     struct label *socketlabel, struct label *newlabel)
1040 {
1041 	struct mac_biba *source, *dest;
1042 
1043 	source = SLOT(newlabel);
1044 	dest = SLOT(socketlabel);
1045 
1046 	mac_biba_copy(source, dest);
1047 }
1048 
1049 static void
1050 mac_biba_relabel_pipe(struct ucred *cred, struct pipe *pipe,
1051     struct label *pipelabel, struct label *newlabel)
1052 {
1053 	struct mac_biba *source, *dest;
1054 
1055 	source = SLOT(newlabel);
1056 	dest = SLOT(pipelabel);
1057 
1058 	mac_biba_copy(source, dest);
1059 }
1060 
1061 static void
1062 mac_biba_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel,
1063     struct socket *socket, struct label *socketpeerlabel)
1064 {
1065 	struct mac_biba *source, *dest;
1066 
1067 	source = SLOT(mbuflabel);
1068 	dest = SLOT(socketpeerlabel);
1069 
1070 	mac_biba_copy_single(source, dest);
1071 }
1072 
1073 /*
1074  * Labeling event operations: network objects.
1075  */
1076 static void
1077 mac_biba_set_socket_peer_from_socket(struct socket *oldsocket,
1078     struct label *oldsocketlabel, struct socket *newsocket,
1079     struct label *newsocketpeerlabel)
1080 {
1081 	struct mac_biba *source, *dest;
1082 
1083 	source = SLOT(oldsocketlabel);
1084 	dest = SLOT(newsocketpeerlabel);
1085 
1086 	mac_biba_copy_single(source, dest);
1087 }
1088 
1089 static void
1090 mac_biba_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d,
1091     struct label *bpflabel)
1092 {
1093 	struct mac_biba *source, *dest;
1094 
1095 	source = SLOT(&cred->cr_label);
1096 	dest = SLOT(bpflabel);
1097 
1098 	mac_biba_copy_single(source, dest);
1099 }
1100 
1101 static void
1102 mac_biba_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel)
1103 {
1104 	char tifname[IFNAMSIZ], ifname[IFNAMSIZ], *p, *q;
1105 	char tiflist[sizeof(trusted_interfaces)];
1106 	struct mac_biba *dest;
1107 	int len, type;
1108 
1109 	dest = SLOT(ifnetlabel);
1110 
1111 	if (ifnet->if_type == IFT_LOOP) {
1112 		type = MAC_BIBA_TYPE_EQUAL;
1113 		goto set;
1114 	}
1115 
1116 	if (trust_all_interfaces) {
1117 		type = MAC_BIBA_TYPE_HIGH;
1118 		goto set;
1119 	}
1120 
1121 	type = MAC_BIBA_TYPE_LOW;
1122 
1123 	if (trusted_interfaces[0] == '\0' ||
1124 	    !strvalid(trusted_interfaces, sizeof(trusted_interfaces)))
1125 		goto set;
1126 
1127 	bzero(tiflist, sizeof(tiflist));
1128 	for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++)
1129 		if(*p != ' ' && *p != '\t')
1130 			*q = *p;
1131 
1132 	snprintf(ifname, IFNAMSIZ, "%s%d", ifnet->if_name, ifnet->if_unit);
1133 
1134 	for (p = q = tiflist;; p++) {
1135 		if (*p == ',' || *p == '\0') {
1136 			len = p - q;
1137 			if (len < IFNAMSIZ) {
1138 				bzero(tifname, sizeof(tifname));
1139 				bcopy(q, tifname, len);
1140 				if (strcmp(tifname, ifname) == 0) {
1141 					type = MAC_BIBA_TYPE_HIGH;
1142 					break;
1143 				}
1144 			} else {
1145 				*p = '\0';
1146 				printf("mac_biba warning: interface name "
1147 				    "\"%s\" is too long (must be < %d)\n",
1148 				    q, IFNAMSIZ);
1149 			}
1150 			if (*p == '\0')
1151 				break;
1152 			q = p + 1;
1153 		}
1154 	}
1155 set:
1156 	mac_biba_set_single(dest, type, 0, NULL);
1157 	mac_biba_set_range(dest, type, 0, NULL, type, 0, NULL);
1158 }
1159 
1160 static void
1161 mac_biba_create_ipq(struct mbuf *fragment, struct label *fragmentlabel,
1162     struct ipq *ipq, struct label *ipqlabel)
1163 {
1164 	struct mac_biba *source, *dest;
1165 
1166 	source = SLOT(fragmentlabel);
1167 	dest = SLOT(ipqlabel);
1168 
1169 	mac_biba_copy_single(source, dest);
1170 }
1171 
1172 static void
1173 mac_biba_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel,
1174     struct mbuf *datagram, struct label *datagramlabel)
1175 {
1176 	struct mac_biba *source, *dest;
1177 
1178 	source = SLOT(ipqlabel);
1179 	dest = SLOT(datagramlabel);
1180 
1181 	/* Just use the head, since we require them all to match. */
1182 	mac_biba_copy_single(source, dest);
1183 }
1184 
1185 static void
1186 mac_biba_create_fragment(struct mbuf *datagram, struct label *datagramlabel,
1187     struct mbuf *fragment, struct label *fragmentlabel)
1188 {
1189 	struct mac_biba *source, *dest;
1190 
1191 	source = SLOT(datagramlabel);
1192 	dest = SLOT(fragmentlabel);
1193 
1194 	mac_biba_copy_single(source, dest);
1195 }
1196 
1197 static void
1198 mac_biba_create_mbuf_from_mbuf(struct mbuf *oldmbuf,
1199     struct label *oldmbuflabel, struct mbuf *newmbuf,
1200     struct label *newmbuflabel)
1201 {
1202 	struct mac_biba *source, *dest;
1203 
1204 	source = SLOT(oldmbuflabel);
1205 	dest = SLOT(newmbuflabel);
1206 
1207 	/*
1208 	 * Because the source mbuf may not yet have been "created",
1209 	 * just initialized, we do a conditional copy.  Since we don't
1210 	 * allow mbufs to have ranges, do a KASSERT to make sure that
1211 	 * doesn't happen.
1212 	 */
1213 	KASSERT((source->mb_flags & MAC_BIBA_FLAG_RANGE) == 0,
1214 	    ("mac_biba_create_mbuf_from_mbuf: source mbuf has range"));
1215 	mac_biba_copy(source, dest);
1216 }
1217 
1218 static void
1219 mac_biba_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel,
1220     struct mbuf *mbuf, struct label *mbuflabel)
1221 {
1222 	struct mac_biba *dest;
1223 
1224 	dest = SLOT(mbuflabel);
1225 
1226 	mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1227 }
1228 
1229 static void
1230 mac_biba_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel,
1231     struct mbuf *mbuf, struct label *mbuflabel)
1232 {
1233 	struct mac_biba *source, *dest;
1234 
1235 	source = SLOT(bpflabel);
1236 	dest = SLOT(mbuflabel);
1237 
1238 	mac_biba_copy_single(source, dest);
1239 }
1240 
1241 static void
1242 mac_biba_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel,
1243     struct mbuf *m, struct label *mbuflabel)
1244 {
1245 	struct mac_biba *source, *dest;
1246 
1247 	source = SLOT(ifnetlabel);
1248 	dest = SLOT(mbuflabel);
1249 
1250 	mac_biba_copy_single(source, dest);
1251 }
1252 
1253 static void
1254 mac_biba_create_mbuf_multicast_encap(struct mbuf *oldmbuf,
1255     struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel,
1256     struct mbuf *newmbuf, struct label *newmbuflabel)
1257 {
1258 	struct mac_biba *source, *dest;
1259 
1260 	source = SLOT(oldmbuflabel);
1261 	dest = SLOT(newmbuflabel);
1262 
1263 	mac_biba_copy_single(source, dest);
1264 }
1265 
1266 static void
1267 mac_biba_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel,
1268     struct mbuf *newmbuf, struct label *newmbuflabel)
1269 {
1270 	struct mac_biba *source, *dest;
1271 
1272 	source = SLOT(oldmbuflabel);
1273 	dest = SLOT(newmbuflabel);
1274 
1275 	mac_biba_copy_single(source, dest);
1276 }
1277 
1278 static int
1279 mac_biba_fragment_match(struct mbuf *fragment, struct label *fragmentlabel,
1280     struct ipq *ipq, struct label *ipqlabel)
1281 {
1282 	struct mac_biba *a, *b;
1283 
1284 	a = SLOT(ipqlabel);
1285 	b = SLOT(fragmentlabel);
1286 
1287 	return (mac_biba_equal_single(a, b));
1288 }
1289 
1290 static void
1291 mac_biba_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet,
1292     struct label *ifnetlabel, struct label *newlabel)
1293 {
1294 	struct mac_biba *source, *dest;
1295 
1296 	source = SLOT(newlabel);
1297 	dest = SLOT(ifnetlabel);
1298 
1299 	mac_biba_copy(source, dest);
1300 }
1301 
1302 static void
1303 mac_biba_update_ipq(struct mbuf *fragment, struct label *fragmentlabel,
1304     struct ipq *ipq, struct label *ipqlabel)
1305 {
1306 
1307 	/* NOOP: we only accept matching labels, so no need to update */
1308 }
1309 
1310 /*
1311  * Labeling event operations: processes.
1312  */
1313 static void
1314 mac_biba_create_cred(struct ucred *cred_parent, struct ucred *cred_child)
1315 {
1316 	struct mac_biba *source, *dest;
1317 
1318 	source = SLOT(&cred_parent->cr_label);
1319 	dest = SLOT(&cred_child->cr_label);
1320 
1321 	mac_biba_copy_single(source, dest);
1322 	mac_biba_copy_range(source, dest);
1323 }
1324 
1325 static void
1326 mac_biba_create_proc0(struct ucred *cred)
1327 {
1328 	struct mac_biba *dest;
1329 
1330 	dest = SLOT(&cred->cr_label);
1331 
1332 	mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1333 	mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL,
1334 	    MAC_BIBA_TYPE_HIGH, 0, NULL);
1335 }
1336 
1337 static void
1338 mac_biba_create_proc1(struct ucred *cred)
1339 {
1340 	struct mac_biba *dest;
1341 
1342 	dest = SLOT(&cred->cr_label);
1343 
1344 	mac_biba_set_single(dest, MAC_BIBA_TYPE_HIGH, 0, NULL);
1345 	mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL,
1346 	    MAC_BIBA_TYPE_HIGH, 0, NULL);
1347 }
1348 
1349 static void
1350 mac_biba_relabel_cred(struct ucred *cred, struct label *newlabel)
1351 {
1352 	struct mac_biba *source, *dest;
1353 
1354 	source = SLOT(newlabel);
1355 	dest = SLOT(&cred->cr_label);
1356 
1357 	mac_biba_copy(source, dest);
1358 }
1359 
1360 /*
1361  * Access control checks.
1362  */
1363 static int
1364 mac_biba_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel,
1365     struct ifnet *ifnet, struct label *ifnetlabel)
1366 {
1367 	struct mac_biba *a, *b;
1368 
1369 	if (!mac_biba_enabled)
1370 		return (0);
1371 
1372 	a = SLOT(bpflabel);
1373 	b = SLOT(ifnetlabel);
1374 
1375 	if (mac_biba_equal_single(a, b))
1376 		return (0);
1377 	return (EACCES);
1378 }
1379 
1380 static int
1381 mac_biba_check_cred_relabel(struct ucred *cred, struct label *newlabel)
1382 {
1383 	struct mac_biba *subj, *new;
1384 	int error;
1385 
1386 	subj = SLOT(&cred->cr_label);
1387 	new = SLOT(newlabel);
1388 
1389 	/*
1390 	 * If there is a Biba label update for the credential, it may
1391 	 * be an update of the single, range, or both.
1392 	 */
1393 	error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
1394 	if (error)
1395 		return (error);
1396 
1397 	/*
1398 	 * If the Biba label is to be changed, authorize as appropriate.
1399 	 */
1400 	if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) {
1401 		/*
1402 		 * If the change request modifies both the Biba label
1403 		 * single and range, check that the new single will be
1404 		 * in the new range.
1405 		 */
1406 		if ((new->mb_flags & MAC_BIBA_FLAGS_BOTH) ==
1407 		    MAC_BIBA_FLAGS_BOTH &&
1408 		    !mac_biba_single_in_range(new, new))
1409 			return (EINVAL);
1410 
1411 		/*
1412 		 * To change the Biba single label on a credential, the
1413 		 * new single label must be in the current range.
1414 		 */
1415 		if (new->mb_flags & MAC_BIBA_FLAG_SINGLE &&
1416 		    !mac_biba_single_in_range(new, subj))
1417 			return (EPERM);
1418 
1419 		/*
1420 		 * To change the Biba range on a credential, the new
1421 		 * range label must be in the current range.
1422 		 */
1423 		if (new->mb_flags & MAC_BIBA_FLAG_RANGE &&
1424 		    !mac_biba_range_in_range(new, subj))
1425 			return (EPERM);
1426 
1427 		/*
1428 		 * To have EQUAL in any component of the new credential
1429 		 * Biba label, the subject must already have EQUAL in
1430 		 * their label.
1431 		 */
1432 		if (mac_biba_contains_equal(new)) {
1433 			error = mac_biba_subject_privileged(subj);
1434 			if (error)
1435 				return (error);
1436 		}
1437 	}
1438 
1439 	return (0);
1440 }
1441 
1442 static int
1443 mac_biba_check_cred_visible(struct ucred *u1, struct ucred *u2)
1444 {
1445 	struct mac_biba *subj, *obj;
1446 
1447 	if (!mac_biba_enabled)
1448 		return (0);
1449 
1450 	subj = SLOT(&u1->cr_label);
1451 	obj = SLOT(&u2->cr_label);
1452 
1453 	/* XXX: range */
1454 	if (!mac_biba_dominate_single(obj, subj))
1455 		return (ESRCH);
1456 
1457 	return (0);
1458 }
1459 
1460 static int
1461 mac_biba_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet,
1462     struct label *ifnetlabel, struct label *newlabel)
1463 {
1464 	struct mac_biba *subj, *new;
1465 	int error;
1466 
1467 	subj = SLOT(&cred->cr_label);
1468 	new = SLOT(newlabel);
1469 
1470 	/*
1471 	 * If there is a Biba label update for the interface, it may
1472 	 * be an update of the single, range, or both.
1473 	 */
1474 	error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
1475 	if (error)
1476 		return (error);
1477 
1478 	/*
1479 	 * Relabling network interfaces requires Biba privilege.
1480 	 */
1481 	error = mac_biba_subject_privileged(subj);
1482 	if (error)
1483 		return (error);
1484 
1485 	/*
1486 	 * If the Biba label is to be changed, authorize as appropriate.
1487 	 */
1488 	if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) {
1489 		/*
1490 		 * Rely on the traditional superuser status for the Biba
1491 		 * interface relabel requirements.  XXXMAC: This will go
1492 		 * away.
1493 		 */
1494 		error = suser_cred(cred, 0);
1495 		if (error)
1496 			return (EPERM);
1497 
1498 		/*
1499 		 * XXXMAC: Additional consistency tests regarding the single
1500 		 * and the range of the new label might be performed here.
1501 		 */
1502 	}
1503 
1504 	return (0);
1505 }
1506 
1507 static int
1508 mac_biba_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel,
1509     struct mbuf *m, struct label *mbuflabel)
1510 {
1511 	struct mac_biba *p, *i;
1512 
1513 	if (!mac_biba_enabled)
1514 		return (0);
1515 
1516 	p = SLOT(mbuflabel);
1517 	i = SLOT(ifnetlabel);
1518 
1519 	return (mac_biba_single_in_range(p, i) ? 0 : EACCES);
1520 }
1521 
1522 static int
1523 mac_biba_check_kld_load(struct ucred *cred, struct vnode *vp,
1524     struct label *label)
1525 {
1526 	struct mac_biba *subj, *obj;
1527 	int error;
1528 
1529 	if (!mac_biba_enabled)
1530 		return (0);
1531 
1532 	subj = SLOT(&cred->cr_label);
1533 
1534 	error = mac_biba_subject_privileged(subj);
1535 	if (error)
1536 		return (error);
1537 
1538 	obj = SLOT(label);
1539 	if (!mac_biba_high_single(obj))
1540 		return (EACCES);
1541 
1542 	return (0);
1543 }
1544 
1545 
1546 static int
1547 mac_biba_check_kld_unload(struct ucred *cred)
1548 {
1549 	struct mac_biba *subj;
1550 
1551 	if (!mac_biba_enabled)
1552 		return (0);
1553 
1554 	subj = SLOT(&cred->cr_label);
1555 
1556 	return (mac_biba_subject_privileged(subj));
1557 }
1558 
1559 static int
1560 mac_biba_check_mount_stat(struct ucred *cred, struct mount *mp,
1561     struct label *mntlabel)
1562 {
1563 	struct mac_biba *subj, *obj;
1564 
1565 	if (!mac_biba_enabled)
1566 		return (0);
1567 
1568 	subj = SLOT(&cred->cr_label);
1569 	obj = SLOT(mntlabel);
1570 
1571 	if (!mac_biba_dominate_single(obj, subj))
1572 		return (EACCES);
1573 
1574 	return (0);
1575 }
1576 
1577 static int
1578 mac_biba_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe,
1579     struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data)
1580 {
1581 
1582 	if(!mac_biba_enabled)
1583 		return (0);
1584 
1585 	/* XXX: This will be implemented soon... */
1586 
1587 	return (0);
1588 }
1589 
1590 static int
1591 mac_biba_check_pipe_poll(struct ucred *cred, struct pipe *pipe,
1592     struct label *pipelabel)
1593 {
1594 	struct mac_biba *subj, *obj;
1595 
1596 	if (!mac_biba_enabled)
1597 		return (0);
1598 
1599 	subj = SLOT(&cred->cr_label);
1600 	obj = SLOT((pipelabel));
1601 
1602 	if (!mac_biba_dominate_single(obj, subj))
1603 		return (EACCES);
1604 
1605 	return (0);
1606 }
1607 
1608 static int
1609 mac_biba_check_pipe_read(struct ucred *cred, struct pipe *pipe,
1610     struct label *pipelabel)
1611 {
1612 	struct mac_biba *subj, *obj;
1613 
1614 	if (!mac_biba_enabled)
1615 		return (0);
1616 
1617 	subj = SLOT(&cred->cr_label);
1618 	obj = SLOT((pipelabel));
1619 
1620 	if (!mac_biba_dominate_single(obj, subj))
1621 		return (EACCES);
1622 
1623 	return (0);
1624 }
1625 
1626 static int
1627 mac_biba_check_pipe_relabel(struct ucred *cred, struct pipe *pipe,
1628     struct label *pipelabel, struct label *newlabel)
1629 {
1630 	struct mac_biba *subj, *obj, *new;
1631 	int error;
1632 
1633 	new = SLOT(newlabel);
1634 	subj = SLOT(&cred->cr_label);
1635 	obj = SLOT(pipelabel);
1636 
1637 	/*
1638 	 * If there is a Biba label update for a pipe, it must be a
1639 	 * single update.
1640 	 */
1641 	error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE);
1642 	if (error)
1643 		return (error);
1644 
1645 	/*
1646 	 * To perform a relabel of a pipe (Biba label or not), Biba must
1647 	 * authorize the relabel.
1648 	 */
1649 	if (!mac_biba_single_in_range(obj, subj))
1650 		return (EPERM);
1651 
1652 	/*
1653 	 * If the Biba label is to be changed, authorize as appropriate.
1654 	 */
1655 	if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) {
1656 		/*
1657 		 * To change the Biba label on a pipe, the new pipe label
1658 		 * must be in the subject range.
1659 		 */
1660 		if (!mac_biba_single_in_range(new, subj))
1661 			return (EPERM);
1662 
1663 		/*
1664 		 * To change the Biba label on a pipe to be EQUAL, the
1665 		 * subject must have appropriate privilege.
1666 		 */
1667 		if (mac_biba_contains_equal(new)) {
1668 			error = mac_biba_subject_privileged(subj);
1669 			if (error)
1670 				return (error);
1671 		}
1672 	}
1673 
1674 	return (0);
1675 }
1676 
1677 static int
1678 mac_biba_check_pipe_stat(struct ucred *cred, struct pipe *pipe,
1679     struct label *pipelabel)
1680 {
1681 	struct mac_biba *subj, *obj;
1682 
1683 	if (!mac_biba_enabled)
1684 		return (0);
1685 
1686 	subj = SLOT(&cred->cr_label);
1687 	obj = SLOT((pipelabel));
1688 
1689 	if (!mac_biba_dominate_single(obj, subj))
1690 		return (EACCES);
1691 
1692 	return (0);
1693 }
1694 
1695 static int
1696 mac_biba_check_pipe_write(struct ucred *cred, struct pipe *pipe,
1697     struct label *pipelabel)
1698 {
1699 	struct mac_biba *subj, *obj;
1700 
1701 	if (!mac_biba_enabled)
1702 		return (0);
1703 
1704 	subj = SLOT(&cred->cr_label);
1705 	obj = SLOT((pipelabel));
1706 
1707 	if (!mac_biba_dominate_single(subj, obj))
1708 		return (EACCES);
1709 
1710 	return (0);
1711 }
1712 
1713 static int
1714 mac_biba_check_proc_debug(struct ucred *cred, struct proc *proc)
1715 {
1716 	struct mac_biba *subj, *obj;
1717 
1718 	if (!mac_biba_enabled)
1719 		return (0);
1720 
1721 	subj = SLOT(&cred->cr_label);
1722 	obj = SLOT(&proc->p_ucred->cr_label);
1723 
1724 	/* XXX: range checks */
1725 	if (!mac_biba_dominate_single(obj, subj))
1726 		return (ESRCH);
1727 	if (!mac_biba_dominate_single(subj, obj))
1728 		return (EACCES);
1729 
1730 	return (0);
1731 }
1732 
1733 static int
1734 mac_biba_check_proc_sched(struct ucred *cred, struct proc *proc)
1735 {
1736 	struct mac_biba *subj, *obj;
1737 
1738 	if (!mac_biba_enabled)
1739 		return (0);
1740 
1741 	subj = SLOT(&cred->cr_label);
1742 	obj = SLOT(&proc->p_ucred->cr_label);
1743 
1744 	/* XXX: range checks */
1745 	if (!mac_biba_dominate_single(obj, subj))
1746 		return (ESRCH);
1747 	if (!mac_biba_dominate_single(subj, obj))
1748 		return (EACCES);
1749 
1750 	return (0);
1751 }
1752 
1753 static int
1754 mac_biba_check_proc_signal(struct ucred *cred, struct proc *proc, int signum)
1755 {
1756 	struct mac_biba *subj, *obj;
1757 
1758 	if (!mac_biba_enabled)
1759 		return (0);
1760 
1761 	subj = SLOT(&cred->cr_label);
1762 	obj = SLOT(&proc->p_ucred->cr_label);
1763 
1764 	/* XXX: range checks */
1765 	if (!mac_biba_dominate_single(obj, subj))
1766 		return (ESRCH);
1767 	if (!mac_biba_dominate_single(subj, obj))
1768 		return (EACCES);
1769 
1770 	return (0);
1771 }
1772 
1773 static int
1774 mac_biba_check_socket_deliver(struct socket *so, struct label *socketlabel,
1775     struct mbuf *m, struct label *mbuflabel)
1776 {
1777 	struct mac_biba *p, *s;
1778 
1779 	if (!mac_biba_enabled)
1780 		return (0);
1781 
1782 	p = SLOT(mbuflabel);
1783 	s = SLOT(socketlabel);
1784 
1785 	return (mac_biba_equal_single(p, s) ? 0 : EACCES);
1786 }
1787 
1788 static int
1789 mac_biba_check_socket_relabel(struct ucred *cred, struct socket *so,
1790     struct label *socketlabel, struct label *newlabel)
1791 {
1792 	struct mac_biba *subj, *obj, *new;
1793 	int error;
1794 
1795 	new = SLOT(newlabel);
1796 	subj = SLOT(&cred->cr_label);
1797 	obj = SLOT(socketlabel);
1798 
1799 	/*
1800 	 * If there is a Biba label update for the socket, it may be
1801 	 * an update of single.
1802 	 */
1803 	error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE);
1804 	if (error)
1805 		return (error);
1806 
1807 	/*
1808 	 * To relabel a socket, the old socket single must be in the subject
1809 	 * range.
1810 	 */
1811 	if (!mac_biba_single_in_range(obj, subj))
1812 		return (EPERM);
1813 
1814 	/*
1815 	 * If the Biba label is to be changed, authorize as appropriate.
1816 	 */
1817 	if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) {
1818 		/*
1819 		 * To relabel a socket, the new socket single must be in
1820 		 * the subject range.
1821 		 */
1822 		if (!mac_biba_single_in_range(new, subj))
1823 			return (EPERM);
1824 
1825 		/*
1826 		 * To change the Biba label on the socket to contain EQUAL,
1827 		 * the subject must have appropriate privilege.
1828 		 */
1829 		if (mac_biba_contains_equal(new)) {
1830 			error = mac_biba_subject_privileged(subj);
1831 			if (error)
1832 				return (error);
1833 		}
1834 	}
1835 
1836 	return (0);
1837 }
1838 
1839 static int
1840 mac_biba_check_socket_visible(struct ucred *cred, struct socket *socket,
1841     struct label *socketlabel)
1842 {
1843 	struct mac_biba *subj, *obj;
1844 
1845 	if (!mac_biba_enabled)
1846 		return (0);
1847 
1848 	subj = SLOT(&cred->cr_label);
1849 	obj = SLOT(socketlabel);
1850 
1851 	if (!mac_biba_dominate_single(obj, subj))
1852 		return (ENOENT);
1853 
1854 	return (0);
1855 }
1856 
1857 static int
1858 mac_biba_check_sysarch_ioperm(struct ucred *cred)
1859 {
1860 	struct mac_biba *subj;
1861 	int error;
1862 
1863 	if (!mac_biba_enabled)
1864 		return (0);
1865 
1866 	subj = SLOT(&cred->cr_label);
1867 
1868 	error = mac_biba_subject_privileged(subj);
1869 	if (error)
1870 		return (error);
1871 
1872 	return (0);
1873 }
1874 
1875 static int
1876 mac_biba_check_system_acct(struct ucred *cred, struct vnode *vp,
1877     struct label *label)
1878 {
1879 	struct mac_biba *subj, *obj;
1880 	int error;
1881 
1882 	if (!mac_biba_enabled)
1883 		return (0);
1884 
1885 	subj = SLOT(&cred->cr_label);
1886 
1887 	error = mac_biba_subject_privileged(subj);
1888 	if (error)
1889 		return (error);
1890 
1891 	if (label == NULL)
1892 		return (0);
1893 
1894 	obj = SLOT(label);
1895 	if (!mac_biba_high_single(obj))
1896 		return (EACCES);
1897 
1898 	return (0);
1899 }
1900 
1901 static int
1902 mac_biba_check_system_settime(struct ucred *cred)
1903 {
1904 	struct mac_biba *subj;
1905 	int error;
1906 
1907 	if (!mac_biba_enabled)
1908 		return (0);
1909 
1910 	subj = SLOT(&cred->cr_label);
1911 
1912 	error = mac_biba_subject_privileged(subj);
1913 	if (error)
1914 		return (error);
1915 
1916 	return (0);
1917 }
1918 
1919 static int
1920 mac_biba_check_system_swapon(struct ucred *cred, struct vnode *vp,
1921     struct label *label)
1922 {
1923 	struct mac_biba *subj, *obj;
1924 	int error;
1925 
1926 	if (!mac_biba_enabled)
1927 		return (0);
1928 
1929 	subj = SLOT(&cred->cr_label);
1930 	obj = SLOT(label);
1931 
1932 	error = mac_biba_subject_privileged(subj);
1933 	if (error)
1934 		return (error);
1935 
1936 	if (!mac_biba_high_single(obj))
1937 		return (EACCES);
1938 
1939 	return (0);
1940 }
1941 
1942 static int
1943 mac_biba_check_system_swapoff(struct ucred *cred, struct vnode *vp,
1944     struct label *label)
1945 {
1946 	struct mac_biba *subj, *obj;
1947 	int error;
1948 
1949 	if (!mac_biba_enabled)
1950 		return (0);
1951 
1952 	subj = SLOT(&cred->cr_label);
1953 	obj = SLOT(label);
1954 
1955 	error = mac_biba_subject_privileged(subj);
1956 	if (error)
1957 		return (error);
1958 
1959 	return (0);
1960 }
1961 
1962 static int
1963 mac_biba_check_system_sysctl(struct ucred *cred, int *name, u_int namelen,
1964     void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen)
1965 {
1966 	struct mac_biba *subj;
1967 	int error;
1968 
1969 	if (!mac_biba_enabled)
1970 		return (0);
1971 
1972 	subj = SLOT(&cred->cr_label);
1973 
1974 	/*
1975 	 * In general, treat sysctl variables as biba/high, but also
1976 	 * require privilege to change them, since they are a
1977 	 * communications channel between grades.  Exempt MIB
1978 	 * queries from this due to undocmented sysctl magic.
1979 	 * XXXMAC: This probably requires some more review.
1980 	 */
1981 	if (new != NULL) {
1982 		if (namelen > 0 && name[0] == 0)
1983 			return (0);
1984 
1985 		if (!mac_biba_subject_dominate_high(subj))
1986 			return (EACCES);
1987 
1988 		error = mac_biba_subject_privileged(subj);
1989 		if (error)
1990 			return (error);
1991 	}
1992 
1993 	return (0);
1994 }
1995 
1996 static int
1997 mac_biba_check_vnode_chdir(struct ucred *cred, struct vnode *dvp,
1998     struct label *dlabel)
1999 {
2000 	struct mac_biba *subj, *obj;
2001 
2002 	if (!mac_biba_enabled)
2003 		return (0);
2004 
2005 	subj = SLOT(&cred->cr_label);
2006 	obj = SLOT(dlabel);
2007 
2008 	if (!mac_biba_dominate_single(obj, subj))
2009 		return (EACCES);
2010 
2011 	return (0);
2012 }
2013 
2014 static int
2015 mac_biba_check_vnode_chroot(struct ucred *cred, struct vnode *dvp,
2016     struct label *dlabel)
2017 {
2018 	struct mac_biba *subj, *obj;
2019 
2020 	if (!mac_biba_enabled)
2021 		return (0);
2022 
2023 	subj = SLOT(&cred->cr_label);
2024 	obj = SLOT(dlabel);
2025 
2026 	if (!mac_biba_dominate_single(obj, subj))
2027 		return (EACCES);
2028 
2029 	return (0);
2030 }
2031 
2032 static int
2033 mac_biba_check_vnode_create(struct ucred *cred, struct vnode *dvp,
2034     struct label *dlabel, struct componentname *cnp, struct vattr *vap)
2035 {
2036 	struct mac_biba *subj, *obj;
2037 
2038 	if (!mac_biba_enabled)
2039 		return (0);
2040 
2041 	subj = SLOT(&cred->cr_label);
2042 	obj = SLOT(dlabel);
2043 
2044 	if (!mac_biba_dominate_single(subj, obj))
2045 		return (EACCES);
2046 
2047 	return (0);
2048 }
2049 
2050 static int
2051 mac_biba_check_vnode_delete(struct ucred *cred, struct vnode *dvp,
2052     struct label *dlabel, struct vnode *vp, struct label *label,
2053     struct componentname *cnp)
2054 {
2055 	struct mac_biba *subj, *obj;
2056 
2057 	if (!mac_biba_enabled)
2058 		return (0);
2059 
2060 	subj = SLOT(&cred->cr_label);
2061 	obj = SLOT(dlabel);
2062 
2063 	if (!mac_biba_dominate_single(subj, obj))
2064 		return (EACCES);
2065 
2066 	obj = SLOT(label);
2067 
2068 	if (!mac_biba_dominate_single(subj, obj))
2069 		return (EACCES);
2070 
2071 	return (0);
2072 }
2073 
2074 static int
2075 mac_biba_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
2076     struct label *label, acl_type_t type)
2077 {
2078 	struct mac_biba *subj, *obj;
2079 
2080 	if (!mac_biba_enabled)
2081 		return (0);
2082 
2083 	subj = SLOT(&cred->cr_label);
2084 	obj = SLOT(label);
2085 
2086 	if (!mac_biba_dominate_single(subj, obj))
2087 		return (EACCES);
2088 
2089 	return (0);
2090 }
2091 
2092 static int
2093 mac_biba_check_vnode_exec(struct ucred *cred, struct vnode *vp,
2094     struct label *label, struct image_params *imgp,
2095     struct label *execlabel)
2096 {
2097 	struct mac_biba *subj, *obj, *exec;
2098 	int error;
2099 
2100 	if (execlabel != NULL) {
2101 		/*
2102 		 * We currently don't permit labels to be changed at
2103 		 * exec-time as part of Biba, so disallow non-NULL
2104 		 * Biba label elements in the execlabel.
2105 		 */
2106 		exec = SLOT(execlabel);
2107 		error = biba_atmostflags(exec, 0);
2108 		if (error)
2109 			return (error);
2110 	}
2111 
2112 	if (!mac_biba_enabled)
2113 		return (0);
2114 
2115 	subj = SLOT(&cred->cr_label);
2116 	obj = SLOT(label);
2117 
2118 	if (!mac_biba_dominate_single(obj, subj))
2119 		return (EACCES);
2120 
2121 	return (0);
2122 }
2123 
2124 static int
2125 mac_biba_check_vnode_getacl(struct ucred *cred, struct vnode *vp,
2126     struct label *label, acl_type_t type)
2127 {
2128 	struct mac_biba *subj, *obj;
2129 
2130 	if (!mac_biba_enabled)
2131 		return (0);
2132 
2133 	subj = SLOT(&cred->cr_label);
2134 	obj = SLOT(label);
2135 
2136 	if (!mac_biba_dominate_single(obj, subj))
2137 		return (EACCES);
2138 
2139 	return (0);
2140 }
2141 
2142 static int
2143 mac_biba_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
2144     struct label *label, int attrnamespace, const char *name, struct uio *uio)
2145 {
2146 	struct mac_biba *subj, *obj;
2147 
2148 	if (!mac_biba_enabled)
2149 		return (0);
2150 
2151 	subj = SLOT(&cred->cr_label);
2152 	obj = SLOT(label);
2153 
2154 	if (!mac_biba_dominate_single(obj, subj))
2155 		return (EACCES);
2156 
2157 	return (0);
2158 }
2159 
2160 static int
2161 mac_biba_check_vnode_link(struct ucred *cred, struct vnode *dvp,
2162     struct label *dlabel, struct vnode *vp, struct label *label,
2163     struct componentname *cnp)
2164 {
2165 	struct mac_biba *subj, *obj;
2166 
2167 	if (!mac_biba_enabled)
2168 		return (0);
2169 
2170 	subj = SLOT(&cred->cr_label);
2171 	obj = SLOT(dlabel);
2172 
2173 	if (!mac_biba_dominate_single(subj, obj))
2174 		return (EACCES);
2175 
2176 	obj = SLOT(label);
2177 
2178 	if (!mac_biba_dominate_single(subj, obj))
2179 		return (EACCES);
2180 
2181 	return (0);
2182 }
2183 
2184 static int
2185 mac_biba_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
2186     struct label *dlabel, struct componentname *cnp)
2187 {
2188 	struct mac_biba *subj, *obj;
2189 
2190 	if (!mac_biba_enabled)
2191 		return (0);
2192 
2193 	subj = SLOT(&cred->cr_label);
2194 	obj = SLOT(dlabel);
2195 
2196 	if (!mac_biba_dominate_single(obj, subj))
2197 		return (EACCES);
2198 
2199 	return (0);
2200 }
2201 
2202 static int
2203 mac_biba_check_vnode_mmap(struct ucred *cred, struct vnode *vp,
2204     struct label *label, int prot)
2205 {
2206 	struct mac_biba *subj, *obj;
2207 
2208 	/*
2209 	 * Rely on the use of open()-time protections to handle
2210 	 * non-revocation cases.
2211 	 */
2212 	if (!mac_biba_enabled || !revocation_enabled)
2213 		return (0);
2214 
2215 	subj = SLOT(&cred->cr_label);
2216 	obj = SLOT(label);
2217 
2218 	if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
2219 		if (!mac_biba_dominate_single(obj, subj))
2220 			return (EACCES);
2221 	}
2222 	if (prot & VM_PROT_WRITE) {
2223 		if (!mac_biba_dominate_single(subj, obj))
2224 			return (EACCES);
2225 	}
2226 
2227 	return (0);
2228 }
2229 
2230 static int
2231 mac_biba_check_vnode_open(struct ucred *cred, struct vnode *vp,
2232     struct label *vnodelabel, int acc_mode)
2233 {
2234 	struct mac_biba *subj, *obj;
2235 
2236 	if (!mac_biba_enabled)
2237 		return (0);
2238 
2239 	subj = SLOT(&cred->cr_label);
2240 	obj = SLOT(vnodelabel);
2241 
2242 	/* XXX privilege override for admin? */
2243 	if (acc_mode & (VREAD | VEXEC | VSTAT)) {
2244 		if (!mac_biba_dominate_single(obj, subj))
2245 			return (EACCES);
2246 	}
2247 	if (acc_mode & (VWRITE | VAPPEND | VADMIN)) {
2248 		if (!mac_biba_dominate_single(subj, obj))
2249 			return (EACCES);
2250 	}
2251 
2252 	return (0);
2253 }
2254 
2255 static int
2256 mac_biba_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred,
2257     struct vnode *vp, struct label *label)
2258 {
2259 	struct mac_biba *subj, *obj;
2260 
2261 	if (!mac_biba_enabled || !revocation_enabled)
2262 		return (0);
2263 
2264 	subj = SLOT(&active_cred->cr_label);
2265 	obj = SLOT(label);
2266 
2267 	if (!mac_biba_dominate_single(obj, subj))
2268 		return (EACCES);
2269 
2270 	return (0);
2271 }
2272 
2273 static int
2274 mac_biba_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
2275     struct vnode *vp, struct label *label)
2276 {
2277 	struct mac_biba *subj, *obj;
2278 
2279 	if (!mac_biba_enabled || !revocation_enabled)
2280 		return (0);
2281 
2282 	subj = SLOT(&active_cred->cr_label);
2283 	obj = SLOT(label);
2284 
2285 	if (!mac_biba_dominate_single(obj, subj))
2286 		return (EACCES);
2287 
2288 	return (0);
2289 }
2290 
2291 static int
2292 mac_biba_check_vnode_readdir(struct ucred *cred, struct vnode *dvp,
2293     struct label *dlabel)
2294 {
2295 	struct mac_biba *subj, *obj;
2296 
2297 	if (!mac_biba_enabled)
2298 		return (0);
2299 
2300 	subj = SLOT(&cred->cr_label);
2301 	obj = SLOT(dlabel);
2302 
2303 	if (!mac_biba_dominate_single(obj, subj))
2304 		return (EACCES);
2305 
2306 	return (0);
2307 }
2308 
2309 static int
2310 mac_biba_check_vnode_readlink(struct ucred *cred, struct vnode *vp,
2311     struct label *label)
2312 {
2313 	struct mac_biba *subj, *obj;
2314 
2315 	if (!mac_biba_enabled)
2316 		return (0);
2317 
2318 	subj = SLOT(&cred->cr_label);
2319 	obj = SLOT(label);
2320 
2321 	if (!mac_biba_dominate_single(obj, subj))
2322 		return (EACCES);
2323 
2324 	return (0);
2325 }
2326 
2327 static int
2328 mac_biba_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
2329     struct label *vnodelabel, struct label *newlabel)
2330 {
2331 	struct mac_biba *old, *new, *subj;
2332 	int error;
2333 
2334 	old = SLOT(vnodelabel);
2335 	new = SLOT(newlabel);
2336 	subj = SLOT(&cred->cr_label);
2337 
2338 	/*
2339 	 * If there is a Biba label update for the vnode, it must be a
2340 	 * single label.
2341 	 */
2342 	error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE);
2343 	if (error)
2344 		return (error);
2345 
2346 	/*
2347 	 * To perform a relabel of the vnode (Biba label or not), Biba must
2348 	 * authorize the relabel.
2349 	 */
2350 	if (!mac_biba_single_in_range(old, subj))
2351 		return (EPERM);
2352 
2353 	/*
2354 	 * If the Biba label is to be changed, authorize as appropriate.
2355 	 */
2356 	if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) {
2357 		/*
2358 		 * To change the Biba label on a vnode, the new vnode label
2359 		 * must be in the subject range.
2360 		 */
2361 		if (!mac_biba_single_in_range(new, subj))
2362 			return (EPERM);
2363 
2364 		/*
2365 		 * To change the Biba label on the vnode to be EQUAL,
2366 		 * the subject must have appropriate privilege.
2367 		 */
2368 		if (mac_biba_contains_equal(new)) {
2369 			error = mac_biba_subject_privileged(subj);
2370 			if (error)
2371 				return (error);
2372 		}
2373 	}
2374 
2375 	return (0);
2376 }
2377 
2378 static int
2379 mac_biba_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
2380     struct label *dlabel, struct vnode *vp, struct label *label,
2381     struct componentname *cnp)
2382 {
2383 	struct mac_biba *subj, *obj;
2384 
2385 	if (!mac_biba_enabled)
2386 		return (0);
2387 
2388 	subj = SLOT(&cred->cr_label);
2389 	obj = SLOT(dlabel);
2390 
2391 	if (!mac_biba_dominate_single(subj, obj))
2392 		return (EACCES);
2393 
2394 	obj = SLOT(label);
2395 
2396 	if (!mac_biba_dominate_single(subj, obj))
2397 		return (EACCES);
2398 
2399 	return (0);
2400 }
2401 
2402 static int
2403 mac_biba_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
2404     struct label *dlabel, struct vnode *vp, struct label *label, int samedir,
2405     struct componentname *cnp)
2406 {
2407 	struct mac_biba *subj, *obj;
2408 
2409 	if (!mac_biba_enabled)
2410 		return (0);
2411 
2412 	subj = SLOT(&cred->cr_label);
2413 	obj = SLOT(dlabel);
2414 
2415 	if (!mac_biba_dominate_single(subj, obj))
2416 		return (EACCES);
2417 
2418 	if (vp != NULL) {
2419 		obj = SLOT(label);
2420 
2421 		if (!mac_biba_dominate_single(subj, obj))
2422 			return (EACCES);
2423 	}
2424 
2425 	return (0);
2426 }
2427 
2428 static int
2429 mac_biba_check_vnode_revoke(struct ucred *cred, struct vnode *vp,
2430     struct label *label)
2431 {
2432 	struct mac_biba *subj, *obj;
2433 
2434 	if (!mac_biba_enabled)
2435 		return (0);
2436 
2437 	subj = SLOT(&cred->cr_label);
2438 	obj = SLOT(label);
2439 
2440 	if (!mac_biba_dominate_single(subj, obj))
2441 		return (EACCES);
2442 
2443 	return (0);
2444 }
2445 
2446 static int
2447 mac_biba_check_vnode_setacl(struct ucred *cred, struct vnode *vp,
2448     struct label *label, acl_type_t type, struct acl *acl)
2449 {
2450 	struct mac_biba *subj, *obj;
2451 
2452 	if (!mac_biba_enabled)
2453 		return (0);
2454 
2455 	subj = SLOT(&cred->cr_label);
2456 	obj = SLOT(label);
2457 
2458 	if (!mac_biba_dominate_single(subj, obj))
2459 		return (EACCES);
2460 
2461 	return (0);
2462 }
2463 
2464 static int
2465 mac_biba_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
2466     struct label *vnodelabel, int attrnamespace, const char *name,
2467     struct uio *uio)
2468 {
2469 	struct mac_biba *subj, *obj;
2470 
2471 	if (!mac_biba_enabled)
2472 		return (0);
2473 
2474 	subj = SLOT(&cred->cr_label);
2475 	obj = SLOT(vnodelabel);
2476 
2477 	if (!mac_biba_dominate_single(subj, obj))
2478 		return (EACCES);
2479 
2480 	/* XXX: protect the MAC EA in a special way? */
2481 
2482 	return (0);
2483 }
2484 
2485 static int
2486 mac_biba_check_vnode_setflags(struct ucred *cred, struct vnode *vp,
2487     struct label *vnodelabel, u_long flags)
2488 {
2489 	struct mac_biba *subj, *obj;
2490 
2491 	if (!mac_biba_enabled)
2492 		return (0);
2493 
2494 	subj = SLOT(&cred->cr_label);
2495 	obj = SLOT(vnodelabel);
2496 
2497 	if (!mac_biba_dominate_single(subj, obj))
2498 		return (EACCES);
2499 
2500 	return (0);
2501 }
2502 
2503 static int
2504 mac_biba_check_vnode_setmode(struct ucred *cred, struct vnode *vp,
2505     struct label *vnodelabel, mode_t mode)
2506 {
2507 	struct mac_biba *subj, *obj;
2508 
2509 	if (!mac_biba_enabled)
2510 		return (0);
2511 
2512 	subj = SLOT(&cred->cr_label);
2513 	obj = SLOT(vnodelabel);
2514 
2515 	if (!mac_biba_dominate_single(subj, obj))
2516 		return (EACCES);
2517 
2518 	return (0);
2519 }
2520 
2521 static int
2522 mac_biba_check_vnode_setowner(struct ucred *cred, struct vnode *vp,
2523     struct label *vnodelabel, uid_t uid, gid_t gid)
2524 {
2525 	struct mac_biba *subj, *obj;
2526 
2527 	if (!mac_biba_enabled)
2528 		return (0);
2529 
2530 	subj = SLOT(&cred->cr_label);
2531 	obj = SLOT(vnodelabel);
2532 
2533 	if (!mac_biba_dominate_single(subj, obj))
2534 		return (EACCES);
2535 
2536 	return (0);
2537 }
2538 
2539 static int
2540 mac_biba_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
2541     struct label *vnodelabel, struct timespec atime, struct timespec mtime)
2542 {
2543 	struct mac_biba *subj, *obj;
2544 
2545 	if (!mac_biba_enabled)
2546 		return (0);
2547 
2548 	subj = SLOT(&cred->cr_label);
2549 	obj = SLOT(vnodelabel);
2550 
2551 	if (!mac_biba_dominate_single(subj, obj))
2552 		return (EACCES);
2553 
2554 	return (0);
2555 }
2556 
2557 static int
2558 mac_biba_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
2559     struct vnode *vp, struct label *vnodelabel)
2560 {
2561 	struct mac_biba *subj, *obj;
2562 
2563 	if (!mac_biba_enabled)
2564 		return (0);
2565 
2566 	subj = SLOT(&active_cred->cr_label);
2567 	obj = SLOT(vnodelabel);
2568 
2569 	if (!mac_biba_dominate_single(obj, subj))
2570 		return (EACCES);
2571 
2572 	return (0);
2573 }
2574 
2575 static int
2576 mac_biba_check_vnode_write(struct ucred *active_cred,
2577     struct ucred *file_cred, struct vnode *vp, struct label *label)
2578 {
2579 	struct mac_biba *subj, *obj;
2580 
2581 	if (!mac_biba_enabled || !revocation_enabled)
2582 		return (0);
2583 
2584 	subj = SLOT(&active_cred->cr_label);
2585 	obj = SLOT(label);
2586 
2587 	if (!mac_biba_dominate_single(subj, obj))
2588 		return (EACCES);
2589 
2590 	return (0);
2591 }
2592 
2593 static struct mac_policy_ops mac_biba_ops =
2594 {
2595 	.mpo_destroy = mac_biba_destroy,
2596 	.mpo_init = mac_biba_init,
2597 	.mpo_init_bpfdesc_label = mac_biba_init_label,
2598 	.mpo_init_cred_label = mac_biba_init_label,
2599 	.mpo_init_devfsdirent_label = mac_biba_init_label,
2600 	.mpo_init_ifnet_label = mac_biba_init_label,
2601 	.mpo_init_ipq_label = mac_biba_init_label_waitcheck,
2602 	.mpo_init_mbuf_label = mac_biba_init_label_waitcheck,
2603 	.mpo_init_mount_label = mac_biba_init_label,
2604 	.mpo_init_mount_fs_label = mac_biba_init_label,
2605 	.mpo_init_pipe_label = mac_biba_init_label,
2606 	.mpo_init_socket_label = mac_biba_init_label_waitcheck,
2607 	.mpo_init_socket_peer_label = mac_biba_init_label_waitcheck,
2608 	.mpo_init_vnode_label = mac_biba_init_label,
2609 	.mpo_destroy_bpfdesc_label = mac_biba_destroy_label,
2610 	.mpo_destroy_cred_label = mac_biba_destroy_label,
2611 	.mpo_destroy_devfsdirent_label = mac_biba_destroy_label,
2612 	.mpo_destroy_ifnet_label = mac_biba_destroy_label,
2613 	.mpo_destroy_ipq_label = mac_biba_destroy_label,
2614 	.mpo_destroy_mbuf_label = mac_biba_destroy_label,
2615 	.mpo_destroy_mount_label = mac_biba_destroy_label,
2616 	.mpo_destroy_mount_fs_label = mac_biba_destroy_label,
2617 	.mpo_destroy_pipe_label = mac_biba_destroy_label,
2618 	.mpo_destroy_socket_label = mac_biba_destroy_label,
2619 	.mpo_destroy_socket_peer_label = mac_biba_destroy_label,
2620 	.mpo_destroy_vnode_label = mac_biba_destroy_label,
2621 	.mpo_copy_mbuf_label = mac_biba_copy_label,
2622 	.mpo_copy_pipe_label = mac_biba_copy_label,
2623 	.mpo_copy_vnode_label = mac_biba_copy_label,
2624 	.mpo_externalize_cred_label = mac_biba_externalize_label,
2625 	.mpo_externalize_ifnet_label = mac_biba_externalize_label,
2626 	.mpo_externalize_pipe_label = mac_biba_externalize_label,
2627 	.mpo_externalize_socket_label = mac_biba_externalize_label,
2628 	.mpo_externalize_socket_peer_label = mac_biba_externalize_label,
2629 	.mpo_externalize_vnode_label = mac_biba_externalize_label,
2630 	.mpo_internalize_cred_label = mac_biba_internalize_label,
2631 	.mpo_internalize_ifnet_label = mac_biba_internalize_label,
2632 	.mpo_internalize_pipe_label = mac_biba_internalize_label,
2633 	.mpo_internalize_socket_label = mac_biba_internalize_label,
2634 	.mpo_internalize_vnode_label = mac_biba_internalize_label,
2635 	.mpo_create_devfs_device = mac_biba_create_devfs_device,
2636 	.mpo_create_devfs_directory = mac_biba_create_devfs_directory,
2637 	.mpo_create_devfs_symlink = mac_biba_create_devfs_symlink,
2638 	.mpo_create_mount = mac_biba_create_mount,
2639 	.mpo_create_root_mount = mac_biba_create_root_mount,
2640 	.mpo_relabel_vnode = mac_biba_relabel_vnode,
2641 	.mpo_update_devfsdirent = mac_biba_update_devfsdirent,
2642 	.mpo_associate_vnode_devfs = mac_biba_associate_vnode_devfs,
2643 	.mpo_associate_vnode_extattr = mac_biba_associate_vnode_extattr,
2644 	.mpo_associate_vnode_singlelabel = mac_biba_associate_vnode_singlelabel,
2645 	.mpo_create_vnode_extattr = mac_biba_create_vnode_extattr,
2646 	.mpo_setlabel_vnode_extattr = mac_biba_setlabel_vnode_extattr,
2647 	.mpo_create_mbuf_from_socket = mac_biba_create_mbuf_from_socket,
2648 	.mpo_create_pipe = mac_biba_create_pipe,
2649 	.mpo_create_socket = mac_biba_create_socket,
2650 	.mpo_create_socket_from_socket = mac_biba_create_socket_from_socket,
2651 	.mpo_relabel_pipe = mac_biba_relabel_pipe,
2652 	.mpo_relabel_socket = mac_biba_relabel_socket,
2653 	.mpo_set_socket_peer_from_mbuf = mac_biba_set_socket_peer_from_mbuf,
2654 	.mpo_set_socket_peer_from_socket = mac_biba_set_socket_peer_from_socket,
2655 	.mpo_create_bpfdesc = mac_biba_create_bpfdesc,
2656 	.mpo_create_datagram_from_ipq = mac_biba_create_datagram_from_ipq,
2657 	.mpo_create_fragment = mac_biba_create_fragment,
2658 	.mpo_create_ifnet = mac_biba_create_ifnet,
2659 	.mpo_create_ipq = mac_biba_create_ipq,
2660 	.mpo_create_mbuf_from_mbuf = mac_biba_create_mbuf_from_mbuf,
2661 	.mpo_create_mbuf_linklayer = mac_biba_create_mbuf_linklayer,
2662 	.mpo_create_mbuf_from_bpfdesc = mac_biba_create_mbuf_from_bpfdesc,
2663 	.mpo_create_mbuf_from_ifnet = mac_biba_create_mbuf_from_ifnet,
2664 	.mpo_create_mbuf_multicast_encap = mac_biba_create_mbuf_multicast_encap,
2665 	.mpo_create_mbuf_netlayer = mac_biba_create_mbuf_netlayer,
2666 	.mpo_fragment_match = mac_biba_fragment_match,
2667 	.mpo_relabel_ifnet = mac_biba_relabel_ifnet,
2668 	.mpo_update_ipq = mac_biba_update_ipq,
2669 	.mpo_create_cred = mac_biba_create_cred,
2670 	.mpo_create_proc0 = mac_biba_create_proc0,
2671 	.mpo_create_proc1 = mac_biba_create_proc1,
2672 	.mpo_relabel_cred = mac_biba_relabel_cred,
2673 	.mpo_check_bpfdesc_receive = mac_biba_check_bpfdesc_receive,
2674 	.mpo_check_cred_relabel = mac_biba_check_cred_relabel,
2675 	.mpo_check_cred_visible = mac_biba_check_cred_visible,
2676 	.mpo_check_ifnet_relabel = mac_biba_check_ifnet_relabel,
2677 	.mpo_check_ifnet_transmit = mac_biba_check_ifnet_transmit,
2678 	.mpo_check_kld_load = mac_biba_check_kld_load,
2679 	.mpo_check_kld_unload = mac_biba_check_kld_unload,
2680 	.mpo_check_mount_stat = mac_biba_check_mount_stat,
2681 	.mpo_check_pipe_ioctl = mac_biba_check_pipe_ioctl,
2682 	.mpo_check_pipe_poll = mac_biba_check_pipe_poll,
2683 	.mpo_check_pipe_read = mac_biba_check_pipe_read,
2684 	.mpo_check_pipe_relabel = mac_biba_check_pipe_relabel,
2685 	.mpo_check_pipe_stat = mac_biba_check_pipe_stat,
2686 	.mpo_check_pipe_write = mac_biba_check_pipe_write,
2687 	.mpo_check_proc_debug = mac_biba_check_proc_debug,
2688 	.mpo_check_proc_sched = mac_biba_check_proc_sched,
2689 	.mpo_check_proc_signal = mac_biba_check_proc_signal,
2690 	.mpo_check_socket_deliver = mac_biba_check_socket_deliver,
2691 	.mpo_check_socket_relabel = mac_biba_check_socket_relabel,
2692 	.mpo_check_socket_visible = mac_biba_check_socket_visible,
2693 	.mpo_check_sysarch_ioperm = mac_biba_check_sysarch_ioperm,
2694 	.mpo_check_system_acct = mac_biba_check_system_acct,
2695 	.mpo_check_system_settime = mac_biba_check_system_settime,
2696 	.mpo_check_system_swapon = mac_biba_check_system_swapon,
2697 	.mpo_check_system_swapoff = mac_biba_check_system_swapoff,
2698 	.mpo_check_system_sysctl = mac_biba_check_system_sysctl,
2699 	.mpo_check_vnode_access = mac_biba_check_vnode_open,
2700 	.mpo_check_vnode_chdir = mac_biba_check_vnode_chdir,
2701 	.mpo_check_vnode_chroot = mac_biba_check_vnode_chroot,
2702 	.mpo_check_vnode_create = mac_biba_check_vnode_create,
2703 	.mpo_check_vnode_delete = mac_biba_check_vnode_delete,
2704 	.mpo_check_vnode_deleteacl = mac_biba_check_vnode_deleteacl,
2705 	.mpo_check_vnode_exec = mac_biba_check_vnode_exec,
2706 	.mpo_check_vnode_getacl = mac_biba_check_vnode_getacl,
2707 	.mpo_check_vnode_getextattr = mac_biba_check_vnode_getextattr,
2708 	.mpo_check_vnode_link = mac_biba_check_vnode_link,
2709 	.mpo_check_vnode_lookup = mac_biba_check_vnode_lookup,
2710 	.mpo_check_vnode_mmap = mac_biba_check_vnode_mmap,
2711 	.mpo_check_vnode_mprotect = mac_biba_check_vnode_mmap,
2712 	.mpo_check_vnode_open = mac_biba_check_vnode_open,
2713 	.mpo_check_vnode_poll = mac_biba_check_vnode_poll,
2714 	.mpo_check_vnode_read = mac_biba_check_vnode_read,
2715 	.mpo_check_vnode_readdir = mac_biba_check_vnode_readdir,
2716 	.mpo_check_vnode_readlink = mac_biba_check_vnode_readlink,
2717 	.mpo_check_vnode_relabel = mac_biba_check_vnode_relabel,
2718 	.mpo_check_vnode_rename_from = mac_biba_check_vnode_rename_from,
2719 	.mpo_check_vnode_rename_to = mac_biba_check_vnode_rename_to,
2720 	.mpo_check_vnode_revoke = mac_biba_check_vnode_revoke,
2721 	.mpo_check_vnode_setacl = mac_biba_check_vnode_setacl,
2722 	.mpo_check_vnode_setextattr = mac_biba_check_vnode_setextattr,
2723 	.mpo_check_vnode_setflags = mac_biba_check_vnode_setflags,
2724 	.mpo_check_vnode_setmode = mac_biba_check_vnode_setmode,
2725 	.mpo_check_vnode_setowner = mac_biba_check_vnode_setowner,
2726 	.mpo_check_vnode_setutimes = mac_biba_check_vnode_setutimes,
2727 	.mpo_check_vnode_stat = mac_biba_check_vnode_stat,
2728 	.mpo_check_vnode_write = mac_biba_check_vnode_write,
2729 };
2730 
2731 MAC_POLICY_SET(&mac_biba_ops, mac_biba, "TrustedBSD MAC/Biba",
2732     MPC_LOADTIME_FLAG_NOTLATE | MPC_LOADTIME_FLAG_LABELMBUFS, &mac_biba_slot);
2733