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