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