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