xref: /freebsd/sys/security/mac_biba/mac_biba.c (revision 7660b554bc59a07be0431c17e0e33815818baa69)
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 	return (0);
1486 }
1487 
1488 static int
1489 mac_biba_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel,
1490     struct mbuf *m, struct label *mbuflabel)
1491 {
1492 	struct mac_biba *p, *i;
1493 
1494 	if (!mac_biba_enabled)
1495 		return (0);
1496 
1497 	p = SLOT(mbuflabel);
1498 	i = SLOT(ifnetlabel);
1499 
1500 	return (mac_biba_single_in_range(p, i) ? 0 : EACCES);
1501 }
1502 
1503 static int
1504 mac_biba_check_kld_load(struct ucred *cred, struct vnode *vp,
1505     struct label *label)
1506 {
1507 	struct mac_biba *subj, *obj;
1508 	int error;
1509 
1510 	if (!mac_biba_enabled)
1511 		return (0);
1512 
1513 	subj = SLOT(&cred->cr_label);
1514 
1515 	error = mac_biba_subject_privileged(subj);
1516 	if (error)
1517 		return (error);
1518 
1519 	obj = SLOT(label);
1520 	if (!mac_biba_high_single(obj))
1521 		return (EACCES);
1522 
1523 	return (0);
1524 }
1525 
1526 
1527 static int
1528 mac_biba_check_kld_unload(struct ucred *cred)
1529 {
1530 	struct mac_biba *subj;
1531 
1532 	if (!mac_biba_enabled)
1533 		return (0);
1534 
1535 	subj = SLOT(&cred->cr_label);
1536 
1537 	return (mac_biba_subject_privileged(subj));
1538 }
1539 
1540 static int
1541 mac_biba_check_mount_stat(struct ucred *cred, struct mount *mp,
1542     struct label *mntlabel)
1543 {
1544 	struct mac_biba *subj, *obj;
1545 
1546 	if (!mac_biba_enabled)
1547 		return (0);
1548 
1549 	subj = SLOT(&cred->cr_label);
1550 	obj = SLOT(mntlabel);
1551 
1552 	if (!mac_biba_dominate_single(obj, subj))
1553 		return (EACCES);
1554 
1555 	return (0);
1556 }
1557 
1558 static int
1559 mac_biba_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe,
1560     struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data)
1561 {
1562 
1563 	if(!mac_biba_enabled)
1564 		return (0);
1565 
1566 	/* XXX: This will be implemented soon... */
1567 
1568 	return (0);
1569 }
1570 
1571 static int
1572 mac_biba_check_pipe_poll(struct ucred *cred, struct pipe *pipe,
1573     struct label *pipelabel)
1574 {
1575 	struct mac_biba *subj, *obj;
1576 
1577 	if (!mac_biba_enabled)
1578 		return (0);
1579 
1580 	subj = SLOT(&cred->cr_label);
1581 	obj = SLOT((pipelabel));
1582 
1583 	if (!mac_biba_dominate_single(obj, subj))
1584 		return (EACCES);
1585 
1586 	return (0);
1587 }
1588 
1589 static int
1590 mac_biba_check_pipe_read(struct ucred *cred, struct pipe *pipe,
1591     struct label *pipelabel)
1592 {
1593 	struct mac_biba *subj, *obj;
1594 
1595 	if (!mac_biba_enabled)
1596 		return (0);
1597 
1598 	subj = SLOT(&cred->cr_label);
1599 	obj = SLOT((pipelabel));
1600 
1601 	if (!mac_biba_dominate_single(obj, subj))
1602 		return (EACCES);
1603 
1604 	return (0);
1605 }
1606 
1607 static int
1608 mac_biba_check_pipe_relabel(struct ucred *cred, struct pipe *pipe,
1609     struct label *pipelabel, struct label *newlabel)
1610 {
1611 	struct mac_biba *subj, *obj, *new;
1612 	int error;
1613 
1614 	new = SLOT(newlabel);
1615 	subj = SLOT(&cred->cr_label);
1616 	obj = SLOT(pipelabel);
1617 
1618 	/*
1619 	 * If there is a Biba label update for a pipe, it must be a
1620 	 * single update.
1621 	 */
1622 	error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE);
1623 	if (error)
1624 		return (error);
1625 
1626 	/*
1627 	 * To perform a relabel of a pipe (Biba label or not), Biba must
1628 	 * authorize the relabel.
1629 	 */
1630 	if (!mac_biba_single_in_range(obj, subj))
1631 		return (EPERM);
1632 
1633 	/*
1634 	 * If the Biba label is to be changed, authorize as appropriate.
1635 	 */
1636 	if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) {
1637 		/*
1638 		 * To change the Biba label on a pipe, the new pipe label
1639 		 * must be in the subject range.
1640 		 */
1641 		if (!mac_biba_single_in_range(new, subj))
1642 			return (EPERM);
1643 
1644 		/*
1645 		 * To change the Biba label on a pipe to be EQUAL, the
1646 		 * subject must have appropriate privilege.
1647 		 */
1648 		if (mac_biba_contains_equal(new)) {
1649 			error = mac_biba_subject_privileged(subj);
1650 			if (error)
1651 				return (error);
1652 		}
1653 	}
1654 
1655 	return (0);
1656 }
1657 
1658 static int
1659 mac_biba_check_pipe_stat(struct ucred *cred, struct pipe *pipe,
1660     struct label *pipelabel)
1661 {
1662 	struct mac_biba *subj, *obj;
1663 
1664 	if (!mac_biba_enabled)
1665 		return (0);
1666 
1667 	subj = SLOT(&cred->cr_label);
1668 	obj = SLOT((pipelabel));
1669 
1670 	if (!mac_biba_dominate_single(obj, subj))
1671 		return (EACCES);
1672 
1673 	return (0);
1674 }
1675 
1676 static int
1677 mac_biba_check_pipe_write(struct ucred *cred, struct pipe *pipe,
1678     struct label *pipelabel)
1679 {
1680 	struct mac_biba *subj, *obj;
1681 
1682 	if (!mac_biba_enabled)
1683 		return (0);
1684 
1685 	subj = SLOT(&cred->cr_label);
1686 	obj = SLOT((pipelabel));
1687 
1688 	if (!mac_biba_dominate_single(subj, obj))
1689 		return (EACCES);
1690 
1691 	return (0);
1692 }
1693 
1694 static int
1695 mac_biba_check_proc_debug(struct ucred *cred, struct proc *proc)
1696 {
1697 	struct mac_biba *subj, *obj;
1698 
1699 	if (!mac_biba_enabled)
1700 		return (0);
1701 
1702 	subj = SLOT(&cred->cr_label);
1703 	obj = SLOT(&proc->p_ucred->cr_label);
1704 
1705 	/* XXX: range checks */
1706 	if (!mac_biba_dominate_single(obj, subj))
1707 		return (ESRCH);
1708 	if (!mac_biba_dominate_single(subj, obj))
1709 		return (EACCES);
1710 
1711 	return (0);
1712 }
1713 
1714 static int
1715 mac_biba_check_proc_sched(struct ucred *cred, struct proc *proc)
1716 {
1717 	struct mac_biba *subj, *obj;
1718 
1719 	if (!mac_biba_enabled)
1720 		return (0);
1721 
1722 	subj = SLOT(&cred->cr_label);
1723 	obj = SLOT(&proc->p_ucred->cr_label);
1724 
1725 	/* XXX: range checks */
1726 	if (!mac_biba_dominate_single(obj, subj))
1727 		return (ESRCH);
1728 	if (!mac_biba_dominate_single(subj, obj))
1729 		return (EACCES);
1730 
1731 	return (0);
1732 }
1733 
1734 static int
1735 mac_biba_check_proc_signal(struct ucred *cred, struct proc *proc, int signum)
1736 {
1737 	struct mac_biba *subj, *obj;
1738 
1739 	if (!mac_biba_enabled)
1740 		return (0);
1741 
1742 	subj = SLOT(&cred->cr_label);
1743 	obj = SLOT(&proc->p_ucred->cr_label);
1744 
1745 	/* XXX: range checks */
1746 	if (!mac_biba_dominate_single(obj, subj))
1747 		return (ESRCH);
1748 	if (!mac_biba_dominate_single(subj, obj))
1749 		return (EACCES);
1750 
1751 	return (0);
1752 }
1753 
1754 static int
1755 mac_biba_check_socket_deliver(struct socket *so, struct label *socketlabel,
1756     struct mbuf *m, struct label *mbuflabel)
1757 {
1758 	struct mac_biba *p, *s;
1759 
1760 	if (!mac_biba_enabled)
1761 		return (0);
1762 
1763 	p = SLOT(mbuflabel);
1764 	s = SLOT(socketlabel);
1765 
1766 	return (mac_biba_equal_single(p, s) ? 0 : EACCES);
1767 }
1768 
1769 static int
1770 mac_biba_check_socket_relabel(struct ucred *cred, struct socket *so,
1771     struct label *socketlabel, struct label *newlabel)
1772 {
1773 	struct mac_biba *subj, *obj, *new;
1774 	int error;
1775 
1776 	new = SLOT(newlabel);
1777 	subj = SLOT(&cred->cr_label);
1778 	obj = SLOT(socketlabel);
1779 
1780 	/*
1781 	 * If there is a Biba label update for the socket, it may be
1782 	 * an update of single.
1783 	 */
1784 	error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE);
1785 	if (error)
1786 		return (error);
1787 
1788 	/*
1789 	 * To relabel a socket, the old socket single must be in the subject
1790 	 * range.
1791 	 */
1792 	if (!mac_biba_single_in_range(obj, subj))
1793 		return (EPERM);
1794 
1795 	/*
1796 	 * If the Biba label is to be changed, authorize as appropriate.
1797 	 */
1798 	if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) {
1799 		/*
1800 		 * To relabel a socket, the new socket single must be in
1801 		 * the subject range.
1802 		 */
1803 		if (!mac_biba_single_in_range(new, subj))
1804 			return (EPERM);
1805 
1806 		/*
1807 		 * To change the Biba label on the socket to contain EQUAL,
1808 		 * the subject must have appropriate privilege.
1809 		 */
1810 		if (mac_biba_contains_equal(new)) {
1811 			error = mac_biba_subject_privileged(subj);
1812 			if (error)
1813 				return (error);
1814 		}
1815 	}
1816 
1817 	return (0);
1818 }
1819 
1820 static int
1821 mac_biba_check_socket_visible(struct ucred *cred, struct socket *socket,
1822     struct label *socketlabel)
1823 {
1824 	struct mac_biba *subj, *obj;
1825 
1826 	if (!mac_biba_enabled)
1827 		return (0);
1828 
1829 	subj = SLOT(&cred->cr_label);
1830 	obj = SLOT(socketlabel);
1831 
1832 	if (!mac_biba_dominate_single(obj, subj))
1833 		return (ENOENT);
1834 
1835 	return (0);
1836 }
1837 
1838 static int
1839 mac_biba_check_sysarch_ioperm(struct ucred *cred)
1840 {
1841 	struct mac_biba *subj;
1842 	int error;
1843 
1844 	if (!mac_biba_enabled)
1845 		return (0);
1846 
1847 	subj = SLOT(&cred->cr_label);
1848 
1849 	error = mac_biba_subject_privileged(subj);
1850 	if (error)
1851 		return (error);
1852 
1853 	return (0);
1854 }
1855 
1856 static int
1857 mac_biba_check_system_acct(struct ucred *cred, struct vnode *vp,
1858     struct label *label)
1859 {
1860 	struct mac_biba *subj, *obj;
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 	if (label == NULL)
1873 		return (0);
1874 
1875 	obj = SLOT(label);
1876 	if (!mac_biba_high_single(obj))
1877 		return (EACCES);
1878 
1879 	return (0);
1880 }
1881 
1882 static int
1883 mac_biba_check_system_settime(struct ucred *cred)
1884 {
1885 	struct mac_biba *subj;
1886 	int error;
1887 
1888 	if (!mac_biba_enabled)
1889 		return (0);
1890 
1891 	subj = SLOT(&cred->cr_label);
1892 
1893 	error = mac_biba_subject_privileged(subj);
1894 	if (error)
1895 		return (error);
1896 
1897 	return (0);
1898 }
1899 
1900 static int
1901 mac_biba_check_system_swapon(struct ucred *cred, struct vnode *vp,
1902     struct label *label)
1903 {
1904 	struct mac_biba *subj, *obj;
1905 	int error;
1906 
1907 	if (!mac_biba_enabled)
1908 		return (0);
1909 
1910 	subj = SLOT(&cred->cr_label);
1911 	obj = SLOT(label);
1912 
1913 	error = mac_biba_subject_privileged(subj);
1914 	if (error)
1915 		return (error);
1916 
1917 	if (!mac_biba_high_single(obj))
1918 		return (EACCES);
1919 
1920 	return (0);
1921 }
1922 
1923 static int
1924 mac_biba_check_system_swapoff(struct ucred *cred, struct vnode *vp,
1925     struct label *label)
1926 {
1927 	struct mac_biba *subj, *obj;
1928 	int error;
1929 
1930 	if (!mac_biba_enabled)
1931 		return (0);
1932 
1933 	subj = SLOT(&cred->cr_label);
1934 	obj = SLOT(label);
1935 
1936 	error = mac_biba_subject_privileged(subj);
1937 	if (error)
1938 		return (error);
1939 
1940 	return (0);
1941 }
1942 
1943 static int
1944 mac_biba_check_system_sysctl(struct ucred *cred, int *name, u_int namelen,
1945     void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen)
1946 {
1947 	struct mac_biba *subj;
1948 	int error;
1949 
1950 	if (!mac_biba_enabled)
1951 		return (0);
1952 
1953 	subj = SLOT(&cred->cr_label);
1954 
1955 	/*
1956 	 * In general, treat sysctl variables as biba/high, but also
1957 	 * require privilege to change them, since they are a
1958 	 * communications channel between grades.  Exempt MIB
1959 	 * queries from this due to undocmented sysctl magic.
1960 	 * XXXMAC: This probably requires some more review.
1961 	 */
1962 	if (new != NULL) {
1963 		if (namelen > 0 && name[0] == 0)
1964 			return (0);
1965 
1966 		if (!mac_biba_subject_dominate_high(subj))
1967 			return (EACCES);
1968 
1969 		error = mac_biba_subject_privileged(subj);
1970 		if (error)
1971 			return (error);
1972 	}
1973 
1974 	return (0);
1975 }
1976 
1977 static int
1978 mac_biba_check_vnode_chdir(struct ucred *cred, struct vnode *dvp,
1979     struct label *dlabel)
1980 {
1981 	struct mac_biba *subj, *obj;
1982 
1983 	if (!mac_biba_enabled)
1984 		return (0);
1985 
1986 	subj = SLOT(&cred->cr_label);
1987 	obj = SLOT(dlabel);
1988 
1989 	if (!mac_biba_dominate_single(obj, subj))
1990 		return (EACCES);
1991 
1992 	return (0);
1993 }
1994 
1995 static int
1996 mac_biba_check_vnode_chroot(struct ucred *cred, struct vnode *dvp,
1997     struct label *dlabel)
1998 {
1999 	struct mac_biba *subj, *obj;
2000 
2001 	if (!mac_biba_enabled)
2002 		return (0);
2003 
2004 	subj = SLOT(&cred->cr_label);
2005 	obj = SLOT(dlabel);
2006 
2007 	if (!mac_biba_dominate_single(obj, subj))
2008 		return (EACCES);
2009 
2010 	return (0);
2011 }
2012 
2013 static int
2014 mac_biba_check_vnode_create(struct ucred *cred, struct vnode *dvp,
2015     struct label *dlabel, struct componentname *cnp, struct vattr *vap)
2016 {
2017 	struct mac_biba *subj, *obj;
2018 
2019 	if (!mac_biba_enabled)
2020 		return (0);
2021 
2022 	subj = SLOT(&cred->cr_label);
2023 	obj = SLOT(dlabel);
2024 
2025 	if (!mac_biba_dominate_single(subj, obj))
2026 		return (EACCES);
2027 
2028 	return (0);
2029 }
2030 
2031 static int
2032 mac_biba_check_vnode_delete(struct ucred *cred, struct vnode *dvp,
2033     struct label *dlabel, struct vnode *vp, struct label *label,
2034     struct componentname *cnp)
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 	obj = SLOT(label);
2048 
2049 	if (!mac_biba_dominate_single(subj, obj))
2050 		return (EACCES);
2051 
2052 	return (0);
2053 }
2054 
2055 static int
2056 mac_biba_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
2057     struct label *label, acl_type_t type)
2058 {
2059 	struct mac_biba *subj, *obj;
2060 
2061 	if (!mac_biba_enabled)
2062 		return (0);
2063 
2064 	subj = SLOT(&cred->cr_label);
2065 	obj = SLOT(label);
2066 
2067 	if (!mac_biba_dominate_single(subj, obj))
2068 		return (EACCES);
2069 
2070 	return (0);
2071 }
2072 
2073 static int
2074 mac_biba_check_vnode_deleteextattr(struct ucred *cred, struct vnode *vp,
2075     struct label *label, int attrnamespace, const char *name)
2076 {
2077 	struct mac_biba *subj, *obj;
2078 
2079 	if (!mac_biba_enabled)
2080 		return (0);
2081 
2082 	subj = SLOT(&cred->cr_label);
2083 	obj = SLOT(label);
2084 
2085 	if (!mac_biba_dominate_single(subj, obj))
2086 		return (EACCES);
2087 
2088 	return (0);
2089 }
2090 
2091 static int
2092 mac_biba_check_vnode_exec(struct ucred *cred, struct vnode *vp,
2093     struct label *label, struct image_params *imgp,
2094     struct label *execlabel)
2095 {
2096 	struct mac_biba *subj, *obj, *exec;
2097 	int error;
2098 
2099 	if (execlabel != NULL) {
2100 		/*
2101 		 * We currently don't permit labels to be changed at
2102 		 * exec-time as part of Biba, so disallow non-NULL
2103 		 * Biba label elements in the execlabel.
2104 		 */
2105 		exec = SLOT(execlabel);
2106 		error = biba_atmostflags(exec, 0);
2107 		if (error)
2108 			return (error);
2109 	}
2110 
2111 	if (!mac_biba_enabled)
2112 		return (0);
2113 
2114 	subj = SLOT(&cred->cr_label);
2115 	obj = SLOT(label);
2116 
2117 	if (!mac_biba_dominate_single(obj, subj))
2118 		return (EACCES);
2119 
2120 	return (0);
2121 }
2122 
2123 static int
2124 mac_biba_check_vnode_getacl(struct ucred *cred, struct vnode *vp,
2125     struct label *label, acl_type_t type)
2126 {
2127 	struct mac_biba *subj, *obj;
2128 
2129 	if (!mac_biba_enabled)
2130 		return (0);
2131 
2132 	subj = SLOT(&cred->cr_label);
2133 	obj = SLOT(label);
2134 
2135 	if (!mac_biba_dominate_single(obj, subj))
2136 		return (EACCES);
2137 
2138 	return (0);
2139 }
2140 
2141 static int
2142 mac_biba_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
2143     struct label *label, int attrnamespace, const char *name, struct uio *uio)
2144 {
2145 	struct mac_biba *subj, *obj;
2146 
2147 	if (!mac_biba_enabled)
2148 		return (0);
2149 
2150 	subj = SLOT(&cred->cr_label);
2151 	obj = SLOT(label);
2152 
2153 	if (!mac_biba_dominate_single(obj, subj))
2154 		return (EACCES);
2155 
2156 	return (0);
2157 }
2158 
2159 static int
2160 mac_biba_check_vnode_link(struct ucred *cred, struct vnode *dvp,
2161     struct label *dlabel, struct vnode *vp, struct label *label,
2162     struct componentname *cnp)
2163 {
2164 	struct mac_biba *subj, *obj;
2165 
2166 	if (!mac_biba_enabled)
2167 		return (0);
2168 
2169 	subj = SLOT(&cred->cr_label);
2170 	obj = SLOT(dlabel);
2171 
2172 	if (!mac_biba_dominate_single(subj, obj))
2173 		return (EACCES);
2174 
2175 	obj = SLOT(label);
2176 
2177 	if (!mac_biba_dominate_single(subj, obj))
2178 		return (EACCES);
2179 
2180 	return (0);
2181 }
2182 
2183 static int
2184 mac_biba_check_vnode_listextattr(struct ucred *cred, struct vnode *vp,
2185     struct label *label, int attrnamespace)
2186 {
2187 	struct mac_biba *subj, *obj;
2188 
2189 	if (!mac_biba_enabled)
2190 		return (0);
2191 
2192 	subj = SLOT(&cred->cr_label);
2193 	obj = SLOT(label);
2194 
2195 	if (!mac_biba_dominate_single(obj, subj))
2196 		return (EACCES);
2197 
2198 	return (0);
2199 }
2200 
2201 static int
2202 mac_biba_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
2203     struct label *dlabel, struct componentname *cnp)
2204 {
2205 	struct mac_biba *subj, *obj;
2206 
2207 	if (!mac_biba_enabled)
2208 		return (0);
2209 
2210 	subj = SLOT(&cred->cr_label);
2211 	obj = SLOT(dlabel);
2212 
2213 	if (!mac_biba_dominate_single(obj, subj))
2214 		return (EACCES);
2215 
2216 	return (0);
2217 }
2218 
2219 static int
2220 mac_biba_check_vnode_mmap(struct ucred *cred, struct vnode *vp,
2221     struct label *label, int prot)
2222 {
2223 	struct mac_biba *subj, *obj;
2224 
2225 	/*
2226 	 * Rely on the use of open()-time protections to handle
2227 	 * non-revocation cases.
2228 	 */
2229 	if (!mac_biba_enabled || !revocation_enabled)
2230 		return (0);
2231 
2232 	subj = SLOT(&cred->cr_label);
2233 	obj = SLOT(label);
2234 
2235 	if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
2236 		if (!mac_biba_dominate_single(obj, subj))
2237 			return (EACCES);
2238 	}
2239 	if (prot & VM_PROT_WRITE) {
2240 		if (!mac_biba_dominate_single(subj, obj))
2241 			return (EACCES);
2242 	}
2243 
2244 	return (0);
2245 }
2246 
2247 static int
2248 mac_biba_check_vnode_open(struct ucred *cred, struct vnode *vp,
2249     struct label *vnodelabel, int acc_mode)
2250 {
2251 	struct mac_biba *subj, *obj;
2252 
2253 	if (!mac_biba_enabled)
2254 		return (0);
2255 
2256 	subj = SLOT(&cred->cr_label);
2257 	obj = SLOT(vnodelabel);
2258 
2259 	/* XXX privilege override for admin? */
2260 	if (acc_mode & (VREAD | VEXEC | VSTAT)) {
2261 		if (!mac_biba_dominate_single(obj, subj))
2262 			return (EACCES);
2263 	}
2264 	if (acc_mode & (VWRITE | VAPPEND | VADMIN)) {
2265 		if (!mac_biba_dominate_single(subj, obj))
2266 			return (EACCES);
2267 	}
2268 
2269 	return (0);
2270 }
2271 
2272 static int
2273 mac_biba_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred,
2274     struct vnode *vp, struct label *label)
2275 {
2276 	struct mac_biba *subj, *obj;
2277 
2278 	if (!mac_biba_enabled || !revocation_enabled)
2279 		return (0);
2280 
2281 	subj = SLOT(&active_cred->cr_label);
2282 	obj = SLOT(label);
2283 
2284 	if (!mac_biba_dominate_single(obj, subj))
2285 		return (EACCES);
2286 
2287 	return (0);
2288 }
2289 
2290 static int
2291 mac_biba_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
2292     struct vnode *vp, struct label *label)
2293 {
2294 	struct mac_biba *subj, *obj;
2295 
2296 	if (!mac_biba_enabled || !revocation_enabled)
2297 		return (0);
2298 
2299 	subj = SLOT(&active_cred->cr_label);
2300 	obj = SLOT(label);
2301 
2302 	if (!mac_biba_dominate_single(obj, subj))
2303 		return (EACCES);
2304 
2305 	return (0);
2306 }
2307 
2308 static int
2309 mac_biba_check_vnode_readdir(struct ucred *cred, struct vnode *dvp,
2310     struct label *dlabel)
2311 {
2312 	struct mac_biba *subj, *obj;
2313 
2314 	if (!mac_biba_enabled)
2315 		return (0);
2316 
2317 	subj = SLOT(&cred->cr_label);
2318 	obj = SLOT(dlabel);
2319 
2320 	if (!mac_biba_dominate_single(obj, subj))
2321 		return (EACCES);
2322 
2323 	return (0);
2324 }
2325 
2326 static int
2327 mac_biba_check_vnode_readlink(struct ucred *cred, struct vnode *vp,
2328     struct label *label)
2329 {
2330 	struct mac_biba *subj, *obj;
2331 
2332 	if (!mac_biba_enabled)
2333 		return (0);
2334 
2335 	subj = SLOT(&cred->cr_label);
2336 	obj = SLOT(label);
2337 
2338 	if (!mac_biba_dominate_single(obj, subj))
2339 		return (EACCES);
2340 
2341 	return (0);
2342 }
2343 
2344 static int
2345 mac_biba_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
2346     struct label *vnodelabel, struct label *newlabel)
2347 {
2348 	struct mac_biba *old, *new, *subj;
2349 	int error;
2350 
2351 	old = SLOT(vnodelabel);
2352 	new = SLOT(newlabel);
2353 	subj = SLOT(&cred->cr_label);
2354 
2355 	/*
2356 	 * If there is a Biba label update for the vnode, it must be a
2357 	 * single label.
2358 	 */
2359 	error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE);
2360 	if (error)
2361 		return (error);
2362 
2363 	/*
2364 	 * To perform a relabel of the vnode (Biba label or not), Biba must
2365 	 * authorize the relabel.
2366 	 */
2367 	if (!mac_biba_single_in_range(old, subj))
2368 		return (EPERM);
2369 
2370 	/*
2371 	 * If the Biba label is to be changed, authorize as appropriate.
2372 	 */
2373 	if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) {
2374 		/*
2375 		 * To change the Biba label on a vnode, the new vnode label
2376 		 * must be in the subject range.
2377 		 */
2378 		if (!mac_biba_single_in_range(new, subj))
2379 			return (EPERM);
2380 
2381 		/*
2382 		 * To change the Biba label on the vnode to be EQUAL,
2383 		 * the subject must have appropriate privilege.
2384 		 */
2385 		if (mac_biba_contains_equal(new)) {
2386 			error = mac_biba_subject_privileged(subj);
2387 			if (error)
2388 				return (error);
2389 		}
2390 	}
2391 
2392 	return (0);
2393 }
2394 
2395 static int
2396 mac_biba_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
2397     struct label *dlabel, struct vnode *vp, struct label *label,
2398     struct componentname *cnp)
2399 {
2400 	struct mac_biba *subj, *obj;
2401 
2402 	if (!mac_biba_enabled)
2403 		return (0);
2404 
2405 	subj = SLOT(&cred->cr_label);
2406 	obj = SLOT(dlabel);
2407 
2408 	if (!mac_biba_dominate_single(subj, obj))
2409 		return (EACCES);
2410 
2411 	obj = SLOT(label);
2412 
2413 	if (!mac_biba_dominate_single(subj, obj))
2414 		return (EACCES);
2415 
2416 	return (0);
2417 }
2418 
2419 static int
2420 mac_biba_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
2421     struct label *dlabel, struct vnode *vp, struct label *label, int samedir,
2422     struct componentname *cnp)
2423 {
2424 	struct mac_biba *subj, *obj;
2425 
2426 	if (!mac_biba_enabled)
2427 		return (0);
2428 
2429 	subj = SLOT(&cred->cr_label);
2430 	obj = SLOT(dlabel);
2431 
2432 	if (!mac_biba_dominate_single(subj, obj))
2433 		return (EACCES);
2434 
2435 	if (vp != NULL) {
2436 		obj = SLOT(label);
2437 
2438 		if (!mac_biba_dominate_single(subj, obj))
2439 			return (EACCES);
2440 	}
2441 
2442 	return (0);
2443 }
2444 
2445 static int
2446 mac_biba_check_vnode_revoke(struct ucred *cred, struct vnode *vp,
2447     struct label *label)
2448 {
2449 	struct mac_biba *subj, *obj;
2450 
2451 	if (!mac_biba_enabled)
2452 		return (0);
2453 
2454 	subj = SLOT(&cred->cr_label);
2455 	obj = SLOT(label);
2456 
2457 	if (!mac_biba_dominate_single(subj, obj))
2458 		return (EACCES);
2459 
2460 	return (0);
2461 }
2462 
2463 static int
2464 mac_biba_check_vnode_setacl(struct ucred *cred, struct vnode *vp,
2465     struct label *label, acl_type_t type, struct acl *acl)
2466 {
2467 	struct mac_biba *subj, *obj;
2468 
2469 	if (!mac_biba_enabled)
2470 		return (0);
2471 
2472 	subj = SLOT(&cred->cr_label);
2473 	obj = SLOT(label);
2474 
2475 	if (!mac_biba_dominate_single(subj, obj))
2476 		return (EACCES);
2477 
2478 	return (0);
2479 }
2480 
2481 static int
2482 mac_biba_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
2483     struct label *vnodelabel, int attrnamespace, const char *name,
2484     struct uio *uio)
2485 {
2486 	struct mac_biba *subj, *obj;
2487 
2488 	if (!mac_biba_enabled)
2489 		return (0);
2490 
2491 	subj = SLOT(&cred->cr_label);
2492 	obj = SLOT(vnodelabel);
2493 
2494 	if (!mac_biba_dominate_single(subj, obj))
2495 		return (EACCES);
2496 
2497 	/* XXX: protect the MAC EA in a special way? */
2498 
2499 	return (0);
2500 }
2501 
2502 static int
2503 mac_biba_check_vnode_setflags(struct ucred *cred, struct vnode *vp,
2504     struct label *vnodelabel, u_long flags)
2505 {
2506 	struct mac_biba *subj, *obj;
2507 
2508 	if (!mac_biba_enabled)
2509 		return (0);
2510 
2511 	subj = SLOT(&cred->cr_label);
2512 	obj = SLOT(vnodelabel);
2513 
2514 	if (!mac_biba_dominate_single(subj, obj))
2515 		return (EACCES);
2516 
2517 	return (0);
2518 }
2519 
2520 static int
2521 mac_biba_check_vnode_setmode(struct ucred *cred, struct vnode *vp,
2522     struct label *vnodelabel, mode_t mode)
2523 {
2524 	struct mac_biba *subj, *obj;
2525 
2526 	if (!mac_biba_enabled)
2527 		return (0);
2528 
2529 	subj = SLOT(&cred->cr_label);
2530 	obj = SLOT(vnodelabel);
2531 
2532 	if (!mac_biba_dominate_single(subj, obj))
2533 		return (EACCES);
2534 
2535 	return (0);
2536 }
2537 
2538 static int
2539 mac_biba_check_vnode_setowner(struct ucred *cred, struct vnode *vp,
2540     struct label *vnodelabel, uid_t uid, gid_t gid)
2541 {
2542 	struct mac_biba *subj, *obj;
2543 
2544 	if (!mac_biba_enabled)
2545 		return (0);
2546 
2547 	subj = SLOT(&cred->cr_label);
2548 	obj = SLOT(vnodelabel);
2549 
2550 	if (!mac_biba_dominate_single(subj, obj))
2551 		return (EACCES);
2552 
2553 	return (0);
2554 }
2555 
2556 static int
2557 mac_biba_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
2558     struct label *vnodelabel, struct timespec atime, struct timespec mtime)
2559 {
2560 	struct mac_biba *subj, *obj;
2561 
2562 	if (!mac_biba_enabled)
2563 		return (0);
2564 
2565 	subj = SLOT(&cred->cr_label);
2566 	obj = SLOT(vnodelabel);
2567 
2568 	if (!mac_biba_dominate_single(subj, obj))
2569 		return (EACCES);
2570 
2571 	return (0);
2572 }
2573 
2574 static int
2575 mac_biba_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
2576     struct vnode *vp, struct label *vnodelabel)
2577 {
2578 	struct mac_biba *subj, *obj;
2579 
2580 	if (!mac_biba_enabled)
2581 		return (0);
2582 
2583 	subj = SLOT(&active_cred->cr_label);
2584 	obj = SLOT(vnodelabel);
2585 
2586 	if (!mac_biba_dominate_single(obj, subj))
2587 		return (EACCES);
2588 
2589 	return (0);
2590 }
2591 
2592 static int
2593 mac_biba_check_vnode_write(struct ucred *active_cred,
2594     struct ucred *file_cred, struct vnode *vp, struct label *label)
2595 {
2596 	struct mac_biba *subj, *obj;
2597 
2598 	if (!mac_biba_enabled || !revocation_enabled)
2599 		return (0);
2600 
2601 	subj = SLOT(&active_cred->cr_label);
2602 	obj = SLOT(label);
2603 
2604 	if (!mac_biba_dominate_single(subj, obj))
2605 		return (EACCES);
2606 
2607 	return (0);
2608 }
2609 
2610 static struct mac_policy_ops mac_biba_ops =
2611 {
2612 	.mpo_destroy = mac_biba_destroy,
2613 	.mpo_init = mac_biba_init,
2614 	.mpo_init_bpfdesc_label = mac_biba_init_label,
2615 	.mpo_init_cred_label = mac_biba_init_label,
2616 	.mpo_init_devfsdirent_label = mac_biba_init_label,
2617 	.mpo_init_ifnet_label = mac_biba_init_label,
2618 	.mpo_init_ipq_label = mac_biba_init_label_waitcheck,
2619 	.mpo_init_mbuf_label = mac_biba_init_label_waitcheck,
2620 	.mpo_init_mount_label = mac_biba_init_label,
2621 	.mpo_init_mount_fs_label = mac_biba_init_label,
2622 	.mpo_init_pipe_label = mac_biba_init_label,
2623 	.mpo_init_socket_label = mac_biba_init_label_waitcheck,
2624 	.mpo_init_socket_peer_label = mac_biba_init_label_waitcheck,
2625 	.mpo_init_vnode_label = mac_biba_init_label,
2626 	.mpo_destroy_bpfdesc_label = mac_biba_destroy_label,
2627 	.mpo_destroy_cred_label = mac_biba_destroy_label,
2628 	.mpo_destroy_devfsdirent_label = mac_biba_destroy_label,
2629 	.mpo_destroy_ifnet_label = mac_biba_destroy_label,
2630 	.mpo_destroy_ipq_label = mac_biba_destroy_label,
2631 	.mpo_destroy_mbuf_label = mac_biba_destroy_label,
2632 	.mpo_destroy_mount_label = mac_biba_destroy_label,
2633 	.mpo_destroy_mount_fs_label = mac_biba_destroy_label,
2634 	.mpo_destroy_pipe_label = mac_biba_destroy_label,
2635 	.mpo_destroy_socket_label = mac_biba_destroy_label,
2636 	.mpo_destroy_socket_peer_label = mac_biba_destroy_label,
2637 	.mpo_destroy_vnode_label = mac_biba_destroy_label,
2638 	.mpo_copy_mbuf_label = mac_biba_copy_label,
2639 	.mpo_copy_pipe_label = mac_biba_copy_label,
2640 	.mpo_copy_vnode_label = mac_biba_copy_label,
2641 	.mpo_externalize_cred_label = mac_biba_externalize_label,
2642 	.mpo_externalize_ifnet_label = mac_biba_externalize_label,
2643 	.mpo_externalize_pipe_label = mac_biba_externalize_label,
2644 	.mpo_externalize_socket_label = mac_biba_externalize_label,
2645 	.mpo_externalize_socket_peer_label = mac_biba_externalize_label,
2646 	.mpo_externalize_vnode_label = mac_biba_externalize_label,
2647 	.mpo_internalize_cred_label = mac_biba_internalize_label,
2648 	.mpo_internalize_ifnet_label = mac_biba_internalize_label,
2649 	.mpo_internalize_pipe_label = mac_biba_internalize_label,
2650 	.mpo_internalize_socket_label = mac_biba_internalize_label,
2651 	.mpo_internalize_vnode_label = mac_biba_internalize_label,
2652 	.mpo_create_devfs_device = mac_biba_create_devfs_device,
2653 	.mpo_create_devfs_directory = mac_biba_create_devfs_directory,
2654 	.mpo_create_devfs_symlink = mac_biba_create_devfs_symlink,
2655 	.mpo_create_mount = mac_biba_create_mount,
2656 	.mpo_create_root_mount = mac_biba_create_root_mount,
2657 	.mpo_relabel_vnode = mac_biba_relabel_vnode,
2658 	.mpo_update_devfsdirent = mac_biba_update_devfsdirent,
2659 	.mpo_associate_vnode_devfs = mac_biba_associate_vnode_devfs,
2660 	.mpo_associate_vnode_extattr = mac_biba_associate_vnode_extattr,
2661 	.mpo_associate_vnode_singlelabel = mac_biba_associate_vnode_singlelabel,
2662 	.mpo_create_vnode_extattr = mac_biba_create_vnode_extattr,
2663 	.mpo_setlabel_vnode_extattr = mac_biba_setlabel_vnode_extattr,
2664 	.mpo_create_mbuf_from_socket = mac_biba_create_mbuf_from_socket,
2665 	.mpo_create_pipe = mac_biba_create_pipe,
2666 	.mpo_create_socket = mac_biba_create_socket,
2667 	.mpo_create_socket_from_socket = mac_biba_create_socket_from_socket,
2668 	.mpo_relabel_pipe = mac_biba_relabel_pipe,
2669 	.mpo_relabel_socket = mac_biba_relabel_socket,
2670 	.mpo_set_socket_peer_from_mbuf = mac_biba_set_socket_peer_from_mbuf,
2671 	.mpo_set_socket_peer_from_socket = mac_biba_set_socket_peer_from_socket,
2672 	.mpo_create_bpfdesc = mac_biba_create_bpfdesc,
2673 	.mpo_create_datagram_from_ipq = mac_biba_create_datagram_from_ipq,
2674 	.mpo_create_fragment = mac_biba_create_fragment,
2675 	.mpo_create_ifnet = mac_biba_create_ifnet,
2676 	.mpo_create_ipq = mac_biba_create_ipq,
2677 	.mpo_create_mbuf_from_mbuf = mac_biba_create_mbuf_from_mbuf,
2678 	.mpo_create_mbuf_linklayer = mac_biba_create_mbuf_linklayer,
2679 	.mpo_create_mbuf_from_bpfdesc = mac_biba_create_mbuf_from_bpfdesc,
2680 	.mpo_create_mbuf_from_ifnet = mac_biba_create_mbuf_from_ifnet,
2681 	.mpo_create_mbuf_multicast_encap = mac_biba_create_mbuf_multicast_encap,
2682 	.mpo_create_mbuf_netlayer = mac_biba_create_mbuf_netlayer,
2683 	.mpo_fragment_match = mac_biba_fragment_match,
2684 	.mpo_relabel_ifnet = mac_biba_relabel_ifnet,
2685 	.mpo_update_ipq = mac_biba_update_ipq,
2686 	.mpo_create_cred = mac_biba_create_cred,
2687 	.mpo_create_proc0 = mac_biba_create_proc0,
2688 	.mpo_create_proc1 = mac_biba_create_proc1,
2689 	.mpo_relabel_cred = mac_biba_relabel_cred,
2690 	.mpo_check_bpfdesc_receive = mac_biba_check_bpfdesc_receive,
2691 	.mpo_check_cred_relabel = mac_biba_check_cred_relabel,
2692 	.mpo_check_cred_visible = mac_biba_check_cred_visible,
2693 	.mpo_check_ifnet_relabel = mac_biba_check_ifnet_relabel,
2694 	.mpo_check_ifnet_transmit = mac_biba_check_ifnet_transmit,
2695 	.mpo_check_kld_load = mac_biba_check_kld_load,
2696 	.mpo_check_kld_unload = mac_biba_check_kld_unload,
2697 	.mpo_check_mount_stat = mac_biba_check_mount_stat,
2698 	.mpo_check_pipe_ioctl = mac_biba_check_pipe_ioctl,
2699 	.mpo_check_pipe_poll = mac_biba_check_pipe_poll,
2700 	.mpo_check_pipe_read = mac_biba_check_pipe_read,
2701 	.mpo_check_pipe_relabel = mac_biba_check_pipe_relabel,
2702 	.mpo_check_pipe_stat = mac_biba_check_pipe_stat,
2703 	.mpo_check_pipe_write = mac_biba_check_pipe_write,
2704 	.mpo_check_proc_debug = mac_biba_check_proc_debug,
2705 	.mpo_check_proc_sched = mac_biba_check_proc_sched,
2706 	.mpo_check_proc_signal = mac_biba_check_proc_signal,
2707 	.mpo_check_socket_deliver = mac_biba_check_socket_deliver,
2708 	.mpo_check_socket_relabel = mac_biba_check_socket_relabel,
2709 	.mpo_check_socket_visible = mac_biba_check_socket_visible,
2710 	.mpo_check_sysarch_ioperm = mac_biba_check_sysarch_ioperm,
2711 	.mpo_check_system_acct = mac_biba_check_system_acct,
2712 	.mpo_check_system_settime = mac_biba_check_system_settime,
2713 	.mpo_check_system_swapon = mac_biba_check_system_swapon,
2714 	.mpo_check_system_swapoff = mac_biba_check_system_swapoff,
2715 	.mpo_check_system_sysctl = mac_biba_check_system_sysctl,
2716 	.mpo_check_vnode_access = mac_biba_check_vnode_open,
2717 	.mpo_check_vnode_chdir = mac_biba_check_vnode_chdir,
2718 	.mpo_check_vnode_chroot = mac_biba_check_vnode_chroot,
2719 	.mpo_check_vnode_create = mac_biba_check_vnode_create,
2720 	.mpo_check_vnode_delete = mac_biba_check_vnode_delete,
2721 	.mpo_check_vnode_deleteacl = mac_biba_check_vnode_deleteacl,
2722 	.mpo_check_vnode_deleteextattr = mac_biba_check_vnode_deleteextattr,
2723 	.mpo_check_vnode_exec = mac_biba_check_vnode_exec,
2724 	.mpo_check_vnode_getacl = mac_biba_check_vnode_getacl,
2725 	.mpo_check_vnode_getextattr = mac_biba_check_vnode_getextattr,
2726 	.mpo_check_vnode_link = mac_biba_check_vnode_link,
2727 	.mpo_check_vnode_listextattr = mac_biba_check_vnode_listextattr,
2728 	.mpo_check_vnode_lookup = mac_biba_check_vnode_lookup,
2729 	.mpo_check_vnode_mmap = mac_biba_check_vnode_mmap,
2730 	.mpo_check_vnode_mprotect = mac_biba_check_vnode_mmap,
2731 	.mpo_check_vnode_open = mac_biba_check_vnode_open,
2732 	.mpo_check_vnode_poll = mac_biba_check_vnode_poll,
2733 	.mpo_check_vnode_read = mac_biba_check_vnode_read,
2734 	.mpo_check_vnode_readdir = mac_biba_check_vnode_readdir,
2735 	.mpo_check_vnode_readlink = mac_biba_check_vnode_readlink,
2736 	.mpo_check_vnode_relabel = mac_biba_check_vnode_relabel,
2737 	.mpo_check_vnode_rename_from = mac_biba_check_vnode_rename_from,
2738 	.mpo_check_vnode_rename_to = mac_biba_check_vnode_rename_to,
2739 	.mpo_check_vnode_revoke = mac_biba_check_vnode_revoke,
2740 	.mpo_check_vnode_setacl = mac_biba_check_vnode_setacl,
2741 	.mpo_check_vnode_setextattr = mac_biba_check_vnode_setextattr,
2742 	.mpo_check_vnode_setflags = mac_biba_check_vnode_setflags,
2743 	.mpo_check_vnode_setmode = mac_biba_check_vnode_setmode,
2744 	.mpo_check_vnode_setowner = mac_biba_check_vnode_setowner,
2745 	.mpo_check_vnode_setutimes = mac_biba_check_vnode_setutimes,
2746 	.mpo_check_vnode_stat = mac_biba_check_vnode_stat,
2747 	.mpo_check_vnode_write = mac_biba_check_vnode_write,
2748 };
2749 
2750 MAC_POLICY_SET(&mac_biba_ops, mac_biba, "TrustedBSD MAC/Biba",
2751     MPC_LOADTIME_FLAG_NOTLATE | MPC_LOADTIME_FLAG_LABELMBUFS, &mac_biba_slot);
2752