xref: /freebsd/sys/security/mac_biba/mac_biba.c (revision b28624fde638caadd4a89f50c9b7e7da0f98c4d2)
1 /*-
2  * Copyright (c) 1999-2002, 2007 Robert N. M. Watson
3  * Copyright (c) 2001-2005 McAfee, 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 McAfee
9  * Research, the Security Research Division of McAfee, Inc. under
10  * DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA
11  * 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  *
40  * Biba fixed label mandatory integrity policy.
41  */
42 
43 #include <sys/param.h>
44 #include <sys/conf.h>
45 #include <sys/extattr.h>
46 #include <sys/kernel.h>
47 #include <sys/ksem.h>
48 #include <sys/malloc.h>
49 #include <sys/mman.h>
50 #include <sys/mount.h>
51 #include <sys/priv.h>
52 #include <sys/proc.h>
53 #include <sys/sbuf.h>
54 #include <sys/systm.h>
55 #include <sys/sysproto.h>
56 #include <sys/sysent.h>
57 #include <sys/systm.h>
58 #include <sys/vnode.h>
59 #include <sys/file.h>
60 #include <sys/socket.h>
61 #include <sys/socketvar.h>
62 #include <sys/pipe.h>
63 #include <sys/sx.h>
64 #include <sys/sysctl.h>
65 #include <sys/msg.h>
66 #include <sys/sem.h>
67 #include <sys/shm.h>
68 
69 #include <fs/devfs/devfs.h>
70 
71 #include <net/bpfdesc.h>
72 #include <net/if.h>
73 #include <net/if_types.h>
74 #include <net/if_var.h>
75 
76 #include <netinet/in.h>
77 #include <netinet/in_pcb.h>
78 #include <netinet/ip_var.h>
79 
80 #include <vm/uma.h>
81 #include <vm/vm.h>
82 
83 #include <security/mac/mac_policy.h>
84 #include <security/mac_biba/mac_biba.h>
85 
86 SYSCTL_DECL(_security_mac);
87 
88 SYSCTL_NODE(_security_mac, OID_AUTO, biba, CTLFLAG_RW, 0,
89     "TrustedBSD mac_biba policy controls");
90 
91 static int	mac_biba_label_size = sizeof(struct mac_biba);
92 SYSCTL_INT(_security_mac_biba, OID_AUTO, label_size, CTLFLAG_RD,
93     &mac_biba_label_size, 0, "Size of struct mac_biba");
94 
95 static int	mac_biba_enabled = 1;
96 SYSCTL_INT(_security_mac_biba, OID_AUTO, enabled, CTLFLAG_RW,
97     &mac_biba_enabled, 0, "Enforce MAC/Biba policy");
98 TUNABLE_INT("security.mac.biba.enabled", &mac_biba_enabled);
99 
100 static int	destroyed_not_inited;
101 SYSCTL_INT(_security_mac_biba, OID_AUTO, destroyed_not_inited, CTLFLAG_RD,
102     &destroyed_not_inited, 0, "Count of labels destroyed but not inited");
103 
104 static int	trust_all_interfaces = 0;
105 SYSCTL_INT(_security_mac_biba, OID_AUTO, trust_all_interfaces, CTLFLAG_RD,
106     &trust_all_interfaces, 0, "Consider all interfaces 'trusted' by MAC/Biba");
107 TUNABLE_INT("security.mac.biba.trust_all_interfaces", &trust_all_interfaces);
108 
109 static char	trusted_interfaces[128];
110 SYSCTL_STRING(_security_mac_biba, OID_AUTO, trusted_interfaces, CTLFLAG_RD,
111     trusted_interfaces, 0, "Interfaces considered 'trusted' by MAC/Biba");
112 TUNABLE_STR("security.mac.biba.trusted_interfaces", trusted_interfaces,
113     sizeof(trusted_interfaces));
114 
115 static int	max_compartments = MAC_BIBA_MAX_COMPARTMENTS;
116 SYSCTL_INT(_security_mac_biba, OID_AUTO, max_compartments, CTLFLAG_RD,
117     &max_compartments, 0, "Maximum supported compartments");
118 
119 static int	ptys_equal = 0;
120 SYSCTL_INT(_security_mac_biba, OID_AUTO, ptys_equal, CTLFLAG_RW,
121     &ptys_equal, 0, "Label pty devices as biba/equal on create");
122 TUNABLE_INT("security.mac.biba.ptys_equal", &ptys_equal);
123 
124 static int	interfaces_equal;
125 SYSCTL_INT(_security_mac_biba, OID_AUTO, interfaces_equal, CTLFLAG_RW,
126     &interfaces_equal, 0, "Label network interfaces as biba/equal on create");
127 TUNABLE_INT("security.mac.biba.interfaces_equal", &interfaces_equal);
128 
129 static int	revocation_enabled = 0;
130 SYSCTL_INT(_security_mac_biba, OID_AUTO, revocation_enabled, CTLFLAG_RW,
131     &revocation_enabled, 0, "Revoke access to objects on relabel");
132 TUNABLE_INT("security.mac.biba.revocation_enabled", &revocation_enabled);
133 
134 static int	mac_biba_slot;
135 #define	SLOT(l)	((struct mac_biba *)mac_label_get((l), mac_biba_slot))
136 #define	SLOT_SET(l, val) mac_label_set((l), mac_biba_slot, (uintptr_t)(val))
137 
138 static uma_zone_t	zone_biba;
139 
140 static __inline int
141 biba_bit_set_empty(u_char *set) {
142 	int i;
143 
144 	for (i = 0; i < MAC_BIBA_MAX_COMPARTMENTS >> 3; i++)
145 		if (set[i] != 0)
146 			return (0);
147 	return (1);
148 }
149 
150 static struct mac_biba *
151 biba_alloc(int flag)
152 {
153 
154 	return (uma_zalloc(zone_biba, flag | M_ZERO));
155 }
156 
157 static void
158 biba_free(struct mac_biba *mac_biba)
159 {
160 
161 	if (mac_biba != NULL)
162 		uma_zfree(zone_biba, mac_biba);
163 	else
164 		atomic_add_int(&destroyed_not_inited, 1);
165 }
166 
167 static int
168 biba_atmostflags(struct mac_biba *mac_biba, int flags)
169 {
170 
171 	if ((mac_biba->mb_flags & flags) != mac_biba->mb_flags)
172 		return (EINVAL);
173 	return (0);
174 }
175 
176 static int
177 mac_biba_dominate_element(struct mac_biba_element *a,
178     struct mac_biba_element *b)
179 {
180 	int bit;
181 
182 	switch (a->mbe_type) {
183 	case MAC_BIBA_TYPE_EQUAL:
184 	case MAC_BIBA_TYPE_HIGH:
185 		return (1);
186 
187 	case MAC_BIBA_TYPE_LOW:
188 		switch (b->mbe_type) {
189 		case MAC_BIBA_TYPE_GRADE:
190 		case MAC_BIBA_TYPE_HIGH:
191 			return (0);
192 
193 		case MAC_BIBA_TYPE_EQUAL:
194 		case MAC_BIBA_TYPE_LOW:
195 			return (1);
196 
197 		default:
198 			panic("mac_biba_dominate_element: b->mbe_type invalid");
199 		}
200 
201 	case MAC_BIBA_TYPE_GRADE:
202 		switch (b->mbe_type) {
203 		case MAC_BIBA_TYPE_EQUAL:
204 		case MAC_BIBA_TYPE_LOW:
205 			return (1);
206 
207 		case MAC_BIBA_TYPE_HIGH:
208 			return (0);
209 
210 		case MAC_BIBA_TYPE_GRADE:
211 			for (bit = 1; bit <= MAC_BIBA_MAX_COMPARTMENTS; bit++)
212 				if (!MAC_BIBA_BIT_TEST(bit,
213 				    a->mbe_compartments) &&
214 				    MAC_BIBA_BIT_TEST(bit, b->mbe_compartments))
215 					return (0);
216 			return (a->mbe_grade >= b->mbe_grade);
217 
218 		default:
219 			panic("mac_biba_dominate_element: b->mbe_type invalid");
220 		}
221 
222 	default:
223 		panic("mac_biba_dominate_element: a->mbe_type invalid");
224 	}
225 
226 	return (0);
227 }
228 
229 static int
230 mac_biba_subject_dominate_high(struct mac_biba *mac_biba)
231 {
232 	struct mac_biba_element *element;
233 
234 	KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
235 	    ("mac_biba_effective_in_range: mac_biba not effective"));
236 	element = &mac_biba->mb_effective;
237 
238 	return (element->mbe_type == MAC_BIBA_TYPE_EQUAL ||
239 	    element->mbe_type == MAC_BIBA_TYPE_HIGH);
240 }
241 
242 static int
243 mac_biba_range_in_range(struct mac_biba *rangea, struct mac_biba *rangeb)
244 {
245 
246 	return (mac_biba_dominate_element(&rangeb->mb_rangehigh,
247 	    &rangea->mb_rangehigh) &&
248 	    mac_biba_dominate_element(&rangea->mb_rangelow,
249 	    &rangeb->mb_rangelow));
250 }
251 
252 static int
253 mac_biba_effective_in_range(struct mac_biba *effective,
254     struct mac_biba *range)
255 {
256 
257 	KASSERT((effective->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
258 	    ("mac_biba_effective_in_range: a not effective"));
259 	KASSERT((range->mb_flags & MAC_BIBA_FLAG_RANGE) != 0,
260 	    ("mac_biba_effective_in_range: b not range"));
261 
262 	return (mac_biba_dominate_element(&range->mb_rangehigh,
263 	    &effective->mb_effective) &&
264 	    mac_biba_dominate_element(&effective->mb_effective,
265 	    &range->mb_rangelow));
266 
267 	return (1);
268 }
269 
270 static int
271 mac_biba_dominate_effective(struct mac_biba *a, struct mac_biba *b)
272 {
273 	KASSERT((a->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
274 	    ("mac_biba_dominate_effective: a not effective"));
275 	KASSERT((b->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
276 	    ("mac_biba_dominate_effective: b not effective"));
277 
278 	return (mac_biba_dominate_element(&a->mb_effective, &b->mb_effective));
279 }
280 
281 static int
282 mac_biba_equal_element(struct mac_biba_element *a, struct mac_biba_element *b)
283 {
284 
285 	if (a->mbe_type == MAC_BIBA_TYPE_EQUAL ||
286 	    b->mbe_type == MAC_BIBA_TYPE_EQUAL)
287 		return (1);
288 
289 	return (a->mbe_type == b->mbe_type && a->mbe_grade == b->mbe_grade);
290 }
291 
292 static int
293 mac_biba_equal_effective(struct mac_biba *a, struct mac_biba *b)
294 {
295 
296 	KASSERT((a->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
297 	    ("mac_biba_equal_effective: a not effective"));
298 	KASSERT((b->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
299 	    ("mac_biba_equal_effective: b not effective"));
300 
301 	return (mac_biba_equal_element(&a->mb_effective, &b->mb_effective));
302 }
303 
304 static int
305 mac_biba_contains_equal(struct mac_biba *mac_biba)
306 {
307 
308 	if (mac_biba->mb_flags & MAC_BIBA_FLAG_EFFECTIVE)
309 		if (mac_biba->mb_effective.mbe_type == MAC_BIBA_TYPE_EQUAL)
310 			return (1);
311 
312 	if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
313 		if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL)
314 			return (1);
315 		if (mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL)
316 			return (1);
317 	}
318 
319 	return (0);
320 }
321 
322 static int
323 mac_biba_subject_privileged(struct mac_biba *mac_biba)
324 {
325 
326 	KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAGS_BOTH) ==
327 	    MAC_BIBA_FLAGS_BOTH,
328 	    ("mac_biba_subject_privileged: subject doesn't have both labels"));
329 
330 	/* If the effective is EQUAL, it's ok. */
331 	if (mac_biba->mb_effective.mbe_type == MAC_BIBA_TYPE_EQUAL)
332 		return (0);
333 
334 	/* If either range endpoint is EQUAL, it's ok. */
335 	if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL ||
336 	    mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL)
337 		return (0);
338 
339 	/* If the range is low-high, it's ok. */
340 	if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_LOW &&
341 	    mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_HIGH)
342 		return (0);
343 
344 	/* It's not ok. */
345 	return (EPERM);
346 }
347 
348 static int
349 mac_biba_high_effective(struct mac_biba *mac_biba)
350 {
351 
352 	KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
353 	    ("mac_biba_equal_effective: mac_biba not effective"));
354 
355 	return (mac_biba->mb_effective.mbe_type == MAC_BIBA_TYPE_HIGH);
356 }
357 
358 static int
359 mac_biba_valid(struct mac_biba *mac_biba)
360 {
361 
362 	if (mac_biba->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
363 		switch (mac_biba->mb_effective.mbe_type) {
364 		case MAC_BIBA_TYPE_GRADE:
365 			break;
366 
367 		case MAC_BIBA_TYPE_EQUAL:
368 		case MAC_BIBA_TYPE_HIGH:
369 		case MAC_BIBA_TYPE_LOW:
370 			if (mac_biba->mb_effective.mbe_grade != 0 ||
371 			    !MAC_BIBA_BIT_SET_EMPTY(
372 			    mac_biba->mb_effective.mbe_compartments))
373 				return (EINVAL);
374 			break;
375 
376 		default:
377 			return (EINVAL);
378 		}
379 	} else {
380 		if (mac_biba->mb_effective.mbe_type != MAC_BIBA_TYPE_UNDEF)
381 			return (EINVAL);
382 	}
383 
384 	if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
385 		switch (mac_biba->mb_rangelow.mbe_type) {
386 		case MAC_BIBA_TYPE_GRADE:
387 			break;
388 
389 		case MAC_BIBA_TYPE_EQUAL:
390 		case MAC_BIBA_TYPE_HIGH:
391 		case MAC_BIBA_TYPE_LOW:
392 			if (mac_biba->mb_rangelow.mbe_grade != 0 ||
393 			    !MAC_BIBA_BIT_SET_EMPTY(
394 			    mac_biba->mb_rangelow.mbe_compartments))
395 				return (EINVAL);
396 			break;
397 
398 		default:
399 			return (EINVAL);
400 		}
401 
402 		switch (mac_biba->mb_rangehigh.mbe_type) {
403 		case MAC_BIBA_TYPE_GRADE:
404 			break;
405 
406 		case MAC_BIBA_TYPE_EQUAL:
407 		case MAC_BIBA_TYPE_HIGH:
408 		case MAC_BIBA_TYPE_LOW:
409 			if (mac_biba->mb_rangehigh.mbe_grade != 0 ||
410 			    !MAC_BIBA_BIT_SET_EMPTY(
411 			    mac_biba->mb_rangehigh.mbe_compartments))
412 				return (EINVAL);
413 			break;
414 
415 		default:
416 			return (EINVAL);
417 		}
418 		if (!mac_biba_dominate_element(&mac_biba->mb_rangehigh,
419 		    &mac_biba->mb_rangelow))
420 			return (EINVAL);
421 	} else {
422 		if (mac_biba->mb_rangelow.mbe_type != MAC_BIBA_TYPE_UNDEF ||
423 		    mac_biba->mb_rangehigh.mbe_type != MAC_BIBA_TYPE_UNDEF)
424 			return (EINVAL);
425 	}
426 
427 	return (0);
428 }
429 
430 static void
431 mac_biba_set_range(struct mac_biba *mac_biba, u_short typelow,
432     u_short gradelow, u_char *compartmentslow, u_short typehigh,
433     u_short gradehigh, u_char *compartmentshigh)
434 {
435 
436 	mac_biba->mb_rangelow.mbe_type = typelow;
437 	mac_biba->mb_rangelow.mbe_grade = gradelow;
438 	if (compartmentslow != NULL)
439 		memcpy(mac_biba->mb_rangelow.mbe_compartments,
440 		    compartmentslow,
441 		    sizeof(mac_biba->mb_rangelow.mbe_compartments));
442 	mac_biba->mb_rangehigh.mbe_type = typehigh;
443 	mac_biba->mb_rangehigh.mbe_grade = gradehigh;
444 	if (compartmentshigh != NULL)
445 		memcpy(mac_biba->mb_rangehigh.mbe_compartments,
446 		    compartmentshigh,
447 		    sizeof(mac_biba->mb_rangehigh.mbe_compartments));
448 	mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE;
449 }
450 
451 static void
452 mac_biba_set_effective(struct mac_biba *mac_biba, u_short type, u_short grade,
453     u_char *compartments)
454 {
455 
456 	mac_biba->mb_effective.mbe_type = type;
457 	mac_biba->mb_effective.mbe_grade = grade;
458 	if (compartments != NULL)
459 		memcpy(mac_biba->mb_effective.mbe_compartments, compartments,
460 		    sizeof(mac_biba->mb_effective.mbe_compartments));
461 	mac_biba->mb_flags |= MAC_BIBA_FLAG_EFFECTIVE;
462 }
463 
464 static void
465 mac_biba_copy_range(struct mac_biba *labelfrom, struct mac_biba *labelto)
466 {
467 
468 	KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_RANGE) != 0,
469 	    ("mac_biba_copy_range: labelfrom not range"));
470 
471 	labelto->mb_rangelow = labelfrom->mb_rangelow;
472 	labelto->mb_rangehigh = labelfrom->mb_rangehigh;
473 	labelto->mb_flags |= MAC_BIBA_FLAG_RANGE;
474 }
475 
476 static void
477 mac_biba_copy_effective(struct mac_biba *labelfrom, struct mac_biba *labelto)
478 {
479 
480 	KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
481 	    ("mac_biba_copy_effective: labelfrom not effective"));
482 
483 	labelto->mb_effective = labelfrom->mb_effective;
484 	labelto->mb_flags |= MAC_BIBA_FLAG_EFFECTIVE;
485 }
486 
487 static void
488 mac_biba_copy(struct mac_biba *source, struct mac_biba *dest)
489 {
490 
491 	if (source->mb_flags & MAC_BIBA_FLAG_EFFECTIVE)
492 		mac_biba_copy_effective(source, dest);
493 	if (source->mb_flags & MAC_BIBA_FLAG_RANGE)
494 		mac_biba_copy_range(source, dest);
495 }
496 
497 /*
498  * Policy module operations.
499  */
500 static void
501 mac_biba_init(struct mac_policy_conf *conf)
502 {
503 
504 	zone_biba = uma_zcreate("mac_biba", sizeof(struct mac_biba), NULL,
505 	    NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
506 }
507 
508 /*
509  * Label operations.
510  */
511 static void
512 mac_biba_init_label(struct label *label)
513 {
514 
515 	SLOT_SET(label, biba_alloc(M_WAITOK));
516 }
517 
518 static int
519 mac_biba_init_label_waitcheck(struct label *label, int flag)
520 {
521 
522 	SLOT_SET(label, biba_alloc(flag));
523 	if (SLOT(label) == NULL)
524 		return (ENOMEM);
525 
526 	return (0);
527 }
528 
529 static void
530 mac_biba_destroy_label(struct label *label)
531 {
532 
533 	biba_free(SLOT(label));
534 	SLOT_SET(label, NULL);
535 }
536 
537 /*
538  * mac_biba_element_to_string() accepts an sbuf and Biba element.  It
539  * converts the Biba element to a string and stores the result in the
540  * sbuf; if there isn't space in the sbuf, -1 is returned.
541  */
542 static int
543 mac_biba_element_to_string(struct sbuf *sb, struct mac_biba_element *element)
544 {
545 	int i, first;
546 
547 	switch (element->mbe_type) {
548 	case MAC_BIBA_TYPE_HIGH:
549 		return (sbuf_printf(sb, "high"));
550 
551 	case MAC_BIBA_TYPE_LOW:
552 		return (sbuf_printf(sb, "low"));
553 
554 	case MAC_BIBA_TYPE_EQUAL:
555 		return (sbuf_printf(sb, "equal"));
556 
557 	case MAC_BIBA_TYPE_GRADE:
558 		if (sbuf_printf(sb, "%d", element->mbe_grade) == -1)
559 			return (-1);
560 
561 		first = 1;
562 		for (i = 1; i <= MAC_BIBA_MAX_COMPARTMENTS; i++) {
563 			if (MAC_BIBA_BIT_TEST(i, element->mbe_compartments)) {
564 				if (first) {
565 					if (sbuf_putc(sb, ':') == -1)
566 						return (-1);
567 					if (sbuf_printf(sb, "%d", i) == -1)
568 						return (-1);
569 					first = 0;
570 				} else {
571 					if (sbuf_printf(sb, "+%d", i) == -1)
572 						return (-1);
573 				}
574 			}
575 		}
576 		return (0);
577 
578 	default:
579 		panic("mac_biba_element_to_string: invalid type (%d)",
580 		    element->mbe_type);
581 	}
582 }
583 
584 /*
585  * mac_biba_to_string() converts a Biba label to a string, and places
586  * the results in the passed sbuf.  It returns 0 on success, or EINVAL
587  * if there isn't room in the sbuf.  Note: the sbuf will be modified
588  * even in a failure case, so the caller may need to revert the sbuf
589  * by restoring the offset if that's undesired.
590  */
591 static int
592 mac_biba_to_string(struct sbuf *sb, struct mac_biba *mac_biba)
593 {
594 
595 	if (mac_biba->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
596 		if (mac_biba_element_to_string(sb, &mac_biba->mb_effective)
597 		    == -1)
598 			return (EINVAL);
599 	}
600 
601 	if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
602 		if (sbuf_putc(sb, '(') == -1)
603 			return (EINVAL);
604 
605 		if (mac_biba_element_to_string(sb, &mac_biba->mb_rangelow)
606 		    == -1)
607 			return (EINVAL);
608 
609 		if (sbuf_putc(sb, '-') == -1)
610 			return (EINVAL);
611 
612 		if (mac_biba_element_to_string(sb, &mac_biba->mb_rangehigh)
613 		    == -1)
614 			return (EINVAL);
615 
616 		if (sbuf_putc(sb, ')') == -1)
617 			return (EINVAL);
618 	}
619 
620 	return (0);
621 }
622 
623 static int
624 mac_biba_externalize_label(struct label *label, char *element_name,
625     struct sbuf *sb, int *claimed)
626 {
627 	struct mac_biba *mac_biba;
628 
629 	if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0)
630 		return (0);
631 
632 	(*claimed)++;
633 
634 	mac_biba = SLOT(label);
635 	return (mac_biba_to_string(sb, mac_biba));
636 }
637 
638 static int
639 mac_biba_parse_element(struct mac_biba_element *element, char *string)
640 {
641 	char *compartment, *end, *grade;
642 	int value;
643 
644 	if (strcmp(string, "high") == 0 ||
645 	    strcmp(string, "hi") == 0) {
646 		element->mbe_type = MAC_BIBA_TYPE_HIGH;
647 		element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
648 	} else if (strcmp(string, "low") == 0 ||
649 	    strcmp(string, "lo") == 0) {
650 		element->mbe_type = MAC_BIBA_TYPE_LOW;
651 		element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
652 	} else if (strcmp(string, "equal") == 0 ||
653 	    strcmp(string, "eq") == 0) {
654 		element->mbe_type = MAC_BIBA_TYPE_EQUAL;
655 		element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
656 	} else {
657 		element->mbe_type = MAC_BIBA_TYPE_GRADE;
658 
659 		/*
660 		 * Numeric grade piece of the element.
661 		 */
662 		grade = strsep(&string, ":");
663 		value = strtol(grade, &end, 10);
664 		if (end == grade || *end != '\0')
665 			return (EINVAL);
666 		if (value < 0 || value > 65535)
667 			return (EINVAL);
668 		element->mbe_grade = value;
669 
670 		/*
671 		 * Optional compartment piece of the element.  If none
672 		 * are included, we assume that the label has no
673 		 * compartments.
674 		 */
675 		if (string == NULL)
676 			return (0);
677 		if (*string == '\0')
678 			return (0);
679 
680 		while ((compartment = strsep(&string, "+")) != NULL) {
681 			value = strtol(compartment, &end, 10);
682 			if (compartment == end || *end != '\0')
683 				return (EINVAL);
684 			if (value < 1 || value > MAC_BIBA_MAX_COMPARTMENTS)
685 				return (EINVAL);
686 			MAC_BIBA_BIT_SET(value, element->mbe_compartments);
687 		}
688 	}
689 
690 	return (0);
691 }
692 
693 /*
694  * Note: destructively consumes the string, make a local copy before
695  * calling if that's a problem.
696  */
697 static int
698 mac_biba_parse(struct mac_biba *mac_biba, char *string)
699 {
700 	char *rangehigh, *rangelow, *effective;
701 	int error;
702 
703 	effective = strsep(&string, "(");
704 	if (*effective == '\0')
705 		effective = NULL;
706 
707 	if (string != NULL) {
708 		rangelow = strsep(&string, "-");
709 		if (string == NULL)
710 			return (EINVAL);
711 		rangehigh = strsep(&string, ")");
712 		if (string == NULL)
713 			return (EINVAL);
714 		if (*string != '\0')
715 			return (EINVAL);
716 	} else {
717 		rangelow = NULL;
718 		rangehigh = NULL;
719 	}
720 
721 	KASSERT((rangelow != NULL && rangehigh != NULL) ||
722 	    (rangelow == NULL && rangehigh == NULL),
723 	    ("mac_biba_parse: range mismatch"));
724 
725 	bzero(mac_biba, sizeof(*mac_biba));
726 	if (effective != NULL) {
727 		error = mac_biba_parse_element(&mac_biba->mb_effective, effective);
728 		if (error)
729 			return (error);
730 		mac_biba->mb_flags |= MAC_BIBA_FLAG_EFFECTIVE;
731 	}
732 
733 	if (rangelow != NULL) {
734 		error = mac_biba_parse_element(&mac_biba->mb_rangelow,
735 		    rangelow);
736 		if (error)
737 			return (error);
738 		error = mac_biba_parse_element(&mac_biba->mb_rangehigh,
739 		    rangehigh);
740 		if (error)
741 			return (error);
742 		mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE;
743 	}
744 
745 	error = mac_biba_valid(mac_biba);
746 	if (error)
747 		return (error);
748 
749 	return (0);
750 }
751 
752 static int
753 mac_biba_internalize_label(struct label *label, char *element_name,
754     char *element_data, int *claimed)
755 {
756 	struct mac_biba *mac_biba, mac_biba_temp;
757 	int error;
758 
759 	if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0)
760 		return (0);
761 
762 	(*claimed)++;
763 
764 	error = mac_biba_parse(&mac_biba_temp, element_data);
765 	if (error)
766 		return (error);
767 
768 	mac_biba = SLOT(label);
769 	*mac_biba = mac_biba_temp;
770 
771 	return (0);
772 }
773 
774 static void
775 mac_biba_copy_label(struct label *src, struct label *dest)
776 {
777 
778 	*SLOT(dest) = *SLOT(src);
779 }
780 
781 /*
782  * Labeling event operations: file system objects, and things that look
783  * a lot like file system objects.
784  */
785 static void
786 mac_biba_create_devfs_device(struct ucred *cred, struct mount *mp,
787     struct cdev *dev, struct devfs_dirent *de, struct label *delabel)
788 {
789 	struct mac_biba *mac_biba;
790 	int biba_type;
791 
792 	mac_biba = SLOT(delabel);
793 	if (strcmp(dev->si_name, "null") == 0 ||
794 	    strcmp(dev->si_name, "zero") == 0 ||
795 	    strcmp(dev->si_name, "random") == 0 ||
796 	    strncmp(dev->si_name, "fd/", strlen("fd/")) == 0)
797 		biba_type = MAC_BIBA_TYPE_EQUAL;
798 	else if (ptys_equal &&
799 	    (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 ||
800 	    strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0))
801 		biba_type = MAC_BIBA_TYPE_EQUAL;
802 	else
803 		biba_type = MAC_BIBA_TYPE_HIGH;
804 	mac_biba_set_effective(mac_biba, biba_type, 0, NULL);
805 }
806 
807 static void
808 mac_biba_create_devfs_directory(struct mount *mp, char *dirname,
809     int dirnamelen, struct devfs_dirent *de, struct label *delabel)
810 {
811 	struct mac_biba *mac_biba;
812 
813 	mac_biba = SLOT(delabel);
814 	mac_biba_set_effective(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
815 }
816 
817 static void
818 mac_biba_create_devfs_symlink(struct ucred *cred, struct mount *mp,
819     struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de,
820     struct label *delabel)
821 {
822 	struct mac_biba *source, *dest;
823 
824 	source = SLOT(cred->cr_label);
825 	dest = SLOT(delabel);
826 
827 	mac_biba_copy_effective(source, dest);
828 }
829 
830 static void
831 mac_biba_create_mount(struct ucred *cred, struct mount *mp,
832     struct label *mplabel)
833 {
834 	struct mac_biba *source, *dest;
835 
836 	source = SLOT(cred->cr_label);
837 	dest = SLOT(mplabel);
838 	mac_biba_copy_effective(source, dest);
839 }
840 
841 static void
842 mac_biba_relabel_vnode(struct ucred *cred, struct vnode *vp,
843     struct label *vplabel, struct label *newlabel)
844 {
845 	struct mac_biba *source, *dest;
846 
847 	source = SLOT(newlabel);
848 	dest = SLOT(vplabel);
849 
850 	mac_biba_copy(source, dest);
851 }
852 
853 static void
854 mac_biba_update_devfs(struct mount *mp, struct devfs_dirent *de,
855     struct label *delabel, struct vnode *vp, struct label *vplabel)
856 {
857 	struct mac_biba *source, *dest;
858 
859 	source = SLOT(vplabel);
860 	dest = SLOT(delabel);
861 
862 	mac_biba_copy(source, dest);
863 }
864 
865 static void
866 mac_biba_associate_vnode_devfs(struct mount *mp, struct label *mntlabel,
867     struct devfs_dirent *de, struct label *delabel, struct vnode *vp,
868     struct label *vplabel)
869 {
870 	struct mac_biba *source, *dest;
871 
872 	source = SLOT(delabel);
873 	dest = SLOT(vplabel);
874 
875 	mac_biba_copy_effective(source, dest);
876 }
877 
878 static int
879 mac_biba_associate_vnode_extattr(struct mount *mp, struct label *mplabel,
880     struct vnode *vp, struct label *vplabel)
881 {
882 	struct mac_biba temp, *source, *dest;
883 	int buflen, error;
884 
885 	source = SLOT(mplabel);
886 	dest = SLOT(vplabel);
887 
888 	buflen = sizeof(temp);
889 	bzero(&temp, buflen);
890 
891 	error = vn_extattr_get(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
892 	    MAC_BIBA_EXTATTR_NAME, &buflen, (char *) &temp, curthread);
893 	if (error == ENOATTR || error == EOPNOTSUPP) {
894 		/* Fall back to the mntlabel. */
895 		mac_biba_copy_effective(source, dest);
896 		return (0);
897 	} else if (error)
898 		return (error);
899 
900 	if (buflen != sizeof(temp)) {
901 		printf("mac_biba_associate_vnode_extattr: bad size %d\n",
902 		    buflen);
903 		return (EPERM);
904 	}
905 	if (mac_biba_valid(&temp) != 0) {
906 		printf("mac_biba_associate_vnode_extattr: invalid\n");
907 		return (EPERM);
908 	}
909 	if ((temp.mb_flags & MAC_BIBA_FLAGS_BOTH) != MAC_BIBA_FLAG_EFFECTIVE) {
910 		printf("mac_biba_associate_vnode_extattr: not effective\n");
911 		return (EPERM);
912 	}
913 
914 	mac_biba_copy_effective(&temp, dest);
915 	return (0);
916 }
917 
918 static void
919 mac_biba_associate_vnode_singlelabel(struct mount *mp,
920     struct label *mplabel, struct vnode *vp, struct label *vplabel)
921 {
922 	struct mac_biba *source, *dest;
923 
924 	source = SLOT(mplabel);
925 	dest = SLOT(vplabel);
926 
927 	mac_biba_copy_effective(source, dest);
928 }
929 
930 static int
931 mac_biba_create_vnode_extattr(struct ucred *cred, struct mount *mp,
932     struct label *mplabel, struct vnode *dvp, struct label *dvplabel,
933     struct vnode *vp, struct label *vplabel, struct componentname *cnp)
934 {
935 	struct mac_biba *source, *dest, temp;
936 	size_t buflen;
937 	int error;
938 
939 	buflen = sizeof(temp);
940 	bzero(&temp, buflen);
941 
942 	source = SLOT(cred->cr_label);
943 	dest = SLOT(vplabel);
944 	mac_biba_copy_effective(source, &temp);
945 
946 	error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
947 	    MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread);
948 	if (error == 0)
949 		mac_biba_copy_effective(source, dest);
950 	return (error);
951 }
952 
953 static int
954 mac_biba_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp,
955     struct label *vplabel, struct label *intlabel)
956 {
957 	struct mac_biba *source, temp;
958 	size_t buflen;
959 	int error;
960 
961 	buflen = sizeof(temp);
962 	bzero(&temp, buflen);
963 
964 	source = SLOT(intlabel);
965 	if ((source->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) == 0)
966 		return (0);
967 
968 	mac_biba_copy_effective(source, &temp);
969 
970 	error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
971 	    MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread);
972 	return (error);
973 }
974 
975 /*
976  * Labeling event operations: IPC object.
977  */
978 static void
979 mac_biba_create_inpcb_from_socket(struct socket *so, struct label *solabel,
980     struct inpcb *inp, struct label *inplabel)
981 {
982 	struct mac_biba *source, *dest;
983 
984 	source = SLOT(solabel);
985 	dest = SLOT(inplabel);
986 
987 	mac_biba_copy_effective(source, dest);
988 }
989 
990 static void
991 mac_biba_create_mbuf_from_socket(struct socket *so, struct label *solabel,
992     struct mbuf *m, struct label *mlabel)
993 {
994 	struct mac_biba *source, *dest;
995 
996 	source = SLOT(solabel);
997 	dest = SLOT(mlabel);
998 
999 	mac_biba_copy_effective(source, dest);
1000 }
1001 
1002 static void
1003 mac_biba_create_socket(struct ucred *cred, struct socket *so,
1004     struct label *solabel)
1005 {
1006 	struct mac_biba *source, *dest;
1007 
1008 	source = SLOT(cred->cr_label);
1009 	dest = SLOT(solabel);
1010 
1011 	mac_biba_copy_effective(source, dest);
1012 }
1013 
1014 static void
1015 mac_biba_create_pipe(struct ucred *cred, struct pipepair *pp,
1016     struct label *pplabel)
1017 {
1018 	struct mac_biba *source, *dest;
1019 
1020 	source = SLOT(cred->cr_label);
1021 	dest = SLOT(pplabel);
1022 
1023 	mac_biba_copy_effective(source, dest);
1024 }
1025 
1026 static void
1027 mac_biba_create_posix_sem(struct ucred *cred, struct ksem *ksemptr,
1028     struct label *ks_label)
1029 {
1030 	struct mac_biba *source, *dest;
1031 
1032 	source = SLOT(cred->cr_label);
1033 	dest = SLOT(ks_label);
1034 
1035 	mac_biba_copy_effective(source, dest);
1036 }
1037 
1038 static void
1039 mac_biba_create_socket_from_socket(struct socket *oldso,
1040     struct label *oldsolabel, struct socket *newso, struct label *newsolabel)
1041 {
1042 	struct mac_biba *source, *dest;
1043 
1044 	source = SLOT(oldsolabel);
1045 	dest = SLOT(newsolabel);
1046 
1047 	mac_biba_copy_effective(source, dest);
1048 }
1049 
1050 static void
1051 mac_biba_relabel_socket(struct ucred *cred, struct socket *so,
1052     struct label *solabel, struct label *newlabel)
1053 {
1054 	struct mac_biba *source, *dest;
1055 
1056 	source = SLOT(newlabel);
1057 	dest = SLOT(solabel);
1058 
1059 	mac_biba_copy(source, dest);
1060 }
1061 
1062 static void
1063 mac_biba_relabel_pipe(struct ucred *cred, struct pipepair *pp,
1064     struct label *pplabel, struct label *newlabel)
1065 {
1066 	struct mac_biba *source, *dest;
1067 
1068 	source = SLOT(newlabel);
1069 	dest = SLOT(pplabel);
1070 
1071 	mac_biba_copy(source, dest);
1072 }
1073 
1074 static void
1075 mac_biba_set_socket_peer_from_mbuf(struct mbuf *m, struct label *mlabel,
1076     struct socket *so, struct label *sopeerlabel)
1077 {
1078 	struct mac_biba *source, *dest;
1079 
1080 	source = SLOT(mlabel);
1081 	dest = SLOT(sopeerlabel);
1082 
1083 	mac_biba_copy_effective(source, dest);
1084 }
1085 
1086 /*
1087  * Labeling event operations: System V IPC objects.
1088  */
1089 static void
1090 mac_biba_create_sysv_msgmsg(struct ucred *cred, struct msqid_kernel *msqkptr,
1091     struct label *msqlabel, struct msg *msgptr, struct label *msglabel)
1092 {
1093 	struct mac_biba *source, *dest;
1094 
1095 	/* Ignore the msgq label */
1096 	source = SLOT(cred->cr_label);
1097 	dest = SLOT(msglabel);
1098 
1099 	mac_biba_copy_effective(source, dest);
1100 }
1101 
1102 static void
1103 mac_biba_create_sysv_msgqueue(struct ucred *cred,
1104     struct msqid_kernel *msqkptr, struct label *msqlabel)
1105 {
1106 	struct mac_biba *source, *dest;
1107 
1108 	source = SLOT(cred->cr_label);
1109 	dest = SLOT(msqlabel);
1110 
1111 	mac_biba_copy_effective(source, dest);
1112 }
1113 
1114 static void
1115 mac_biba_create_sysv_sem(struct ucred *cred, struct semid_kernel *semakptr,
1116     struct label *semalabel)
1117 {
1118 	struct mac_biba *source, *dest;
1119 
1120 	source = SLOT(cred->cr_label);
1121 	dest = SLOT(semalabel);
1122 
1123 	mac_biba_copy_effective(source, dest);
1124 }
1125 
1126 static void
1127 mac_biba_create_sysv_shm(struct ucred *cred, struct shmid_kernel *shmsegptr,
1128     struct label *shmlabel)
1129 {
1130 	struct mac_biba *source, *dest;
1131 
1132 	source = SLOT(cred->cr_label);
1133 	dest = SLOT(shmlabel);
1134 
1135 	mac_biba_copy_effective(source, dest);
1136 }
1137 
1138 /*
1139  * Labeling event operations: network objects.
1140  */
1141 static void
1142 mac_biba_set_socket_peer_from_socket(struct socket *oldso,
1143     struct label *oldsolabel, struct socket *newso,
1144     struct label *newsopeerlabel)
1145 {
1146 	struct mac_biba *source, *dest;
1147 
1148 	source = SLOT(oldsolabel);
1149 	dest = SLOT(newsopeerlabel);
1150 
1151 	mac_biba_copy_effective(source, dest);
1152 }
1153 
1154 static void
1155 mac_biba_create_bpfdesc(struct ucred *cred, struct bpf_d *d,
1156     struct label *dlabel)
1157 {
1158 	struct mac_biba *source, *dest;
1159 
1160 	source = SLOT(cred->cr_label);
1161 	dest = SLOT(dlabel);
1162 
1163 	mac_biba_copy_effective(source, dest);
1164 }
1165 
1166 static void
1167 mac_biba_create_ifnet(struct ifnet *ifp, struct label *ifplabel)
1168 {
1169 	char tifname[IFNAMSIZ], *p, *q;
1170 	char tiflist[sizeof(trusted_interfaces)];
1171 	struct mac_biba *dest;
1172 	int len, type;
1173 
1174 	dest = SLOT(ifplabel);
1175 
1176 	if (ifp->if_type == IFT_LOOP || interfaces_equal != 0) {
1177 		type = MAC_BIBA_TYPE_EQUAL;
1178 		goto set;
1179 	}
1180 
1181 	if (trust_all_interfaces) {
1182 		type = MAC_BIBA_TYPE_HIGH;
1183 		goto set;
1184 	}
1185 
1186 	type = MAC_BIBA_TYPE_LOW;
1187 
1188 	if (trusted_interfaces[0] == '\0' ||
1189 	    !strvalid(trusted_interfaces, sizeof(trusted_interfaces)))
1190 		goto set;
1191 
1192 	bzero(tiflist, sizeof(tiflist));
1193 	for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++)
1194 		if(*p != ' ' && *p != '\t')
1195 			*q = *p;
1196 
1197 	for (p = q = tiflist;; p++) {
1198 		if (*p == ',' || *p == '\0') {
1199 			len = p - q;
1200 			if (len < IFNAMSIZ) {
1201 				bzero(tifname, sizeof(tifname));
1202 				bcopy(q, tifname, len);
1203 				if (strcmp(tifname, ifp->if_xname) == 0) {
1204 					type = MAC_BIBA_TYPE_HIGH;
1205 					break;
1206 				}
1207 			} else {
1208 				*p = '\0';
1209 				printf("mac_biba warning: interface name "
1210 				    "\"%s\" is too long (must be < %d)\n",
1211 				    q, IFNAMSIZ);
1212 			}
1213 			if (*p == '\0')
1214 				break;
1215 			q = p + 1;
1216 		}
1217 	}
1218 set:
1219 	mac_biba_set_effective(dest, type, 0, NULL);
1220 	mac_biba_set_range(dest, type, 0, NULL, type, 0, NULL);
1221 }
1222 
1223 static void
1224 mac_biba_create_ipq(struct mbuf *m, struct label *mlabel, struct ipq *ipq,
1225     struct label *ipqlabel)
1226 {
1227 	struct mac_biba *source, *dest;
1228 
1229 	source = SLOT(mlabel);
1230 	dest = SLOT(ipqlabel);
1231 
1232 	mac_biba_copy_effective(source, dest);
1233 }
1234 
1235 static void
1236 mac_biba_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel,
1237     struct mbuf *m, struct label *mlabel)
1238 {
1239 	struct mac_biba *source, *dest;
1240 
1241 	source = SLOT(ipqlabel);
1242 	dest = SLOT(mlabel);
1243 
1244 	/* Just use the head, since we require them all to match. */
1245 	mac_biba_copy_effective(source, dest);
1246 }
1247 
1248 static void
1249 mac_biba_create_fragment(struct mbuf *m, struct label *mlabel,
1250     struct mbuf *frag, struct label *fraglabel)
1251 {
1252 	struct mac_biba *source, *dest;
1253 
1254 	source = SLOT(mlabel);
1255 	dest = SLOT(fraglabel);
1256 
1257 	mac_biba_copy_effective(source, dest);
1258 }
1259 
1260 static void
1261 mac_biba_create_mbuf_from_inpcb(struct inpcb *inp, struct label *inplabel,
1262     struct mbuf *m, struct label *mlabel)
1263 {
1264 	struct mac_biba *source, *dest;
1265 
1266 	source = SLOT(inplabel);
1267 	dest = SLOT(mlabel);
1268 
1269 	mac_biba_copy_effective(source, dest);
1270 }
1271 
1272 static void
1273 mac_biba_create_mbuf_linklayer(struct ifnet *ifp, struct label *ifplabel,
1274     struct mbuf *m, struct label *mlabel)
1275 {
1276 	struct mac_biba *dest;
1277 
1278 	dest = SLOT(mlabel);
1279 
1280 	mac_biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1281 }
1282 
1283 static void
1284 mac_biba_create_mbuf_from_bpfdesc(struct bpf_d *d, struct label *dlabel,
1285     struct mbuf *m, struct label *mlabel)
1286 {
1287 	struct mac_biba *source, *dest;
1288 
1289 	source = SLOT(dlabel);
1290 	dest = SLOT(mlabel);
1291 
1292 	mac_biba_copy_effective(source, dest);
1293 }
1294 
1295 static void
1296 mac_biba_create_mbuf_from_ifnet(struct ifnet *ifp, struct label *ifplabel,
1297     struct mbuf *m, struct label *mlabel)
1298 {
1299 	struct mac_biba *source, *dest;
1300 
1301 	source = SLOT(ifplabel);
1302 	dest = SLOT(mlabel);
1303 
1304 	mac_biba_copy_effective(source, dest);
1305 }
1306 
1307 static void
1308 mac_biba_create_mbuf_multicast_encap(struct mbuf *m, struct label *mlabel,
1309     struct ifnet *ifp, struct label *ifplabel, struct mbuf *mnew,
1310     struct label *mnewlabel)
1311 {
1312 	struct mac_biba *source, *dest;
1313 
1314 	source = SLOT(mlabel);
1315 	dest = SLOT(mnewlabel);
1316 
1317 	mac_biba_copy_effective(source, dest);
1318 }
1319 
1320 static void
1321 mac_biba_create_mbuf_netlayer(struct mbuf *m, struct label *mlabel,
1322     struct mbuf *newm, struct label *mnewlabel)
1323 {
1324 	struct mac_biba *source, *dest;
1325 
1326 	source = SLOT(mlabel);
1327 	dest = SLOT(mnewlabel);
1328 
1329 	mac_biba_copy_effective(source, dest);
1330 }
1331 
1332 static int
1333 mac_biba_fragment_match(struct mbuf *m, struct label *mlabel,
1334     struct ipq *ipq, struct label *ipqlabel)
1335 {
1336 	struct mac_biba *a, *b;
1337 
1338 	a = SLOT(ipqlabel);
1339 	b = SLOT(mlabel);
1340 
1341 	return (mac_biba_equal_effective(a, b));
1342 }
1343 
1344 static void
1345 mac_biba_relabel_ifnet(struct ucred *cred, struct ifnet *ifp,
1346     struct label *ifplabel, struct label *newlabel)
1347 {
1348 	struct mac_biba *source, *dest;
1349 
1350 	source = SLOT(newlabel);
1351 	dest = SLOT(ifplabel);
1352 
1353 	mac_biba_copy(source, dest);
1354 }
1355 
1356 static void
1357 mac_biba_update_ipq(struct mbuf *m, struct label *mlabel, struct ipq *ipq,
1358     struct label *ipqlabel)
1359 {
1360 
1361 	/* NOOP: we only accept matching labels, so no need to update */
1362 }
1363 
1364 static void
1365 mac_biba_inpcb_sosetlabel(struct socket *so, struct label *solabel,
1366     struct inpcb *inp, struct label *inplabel)
1367 {
1368 	struct mac_biba *source, *dest;
1369 
1370 	source = SLOT(solabel);
1371 	dest = SLOT(inplabel);
1372 
1373 	mac_biba_copy(source, dest);
1374 }
1375 
1376 static void
1377 mac_biba_create_mbuf_from_firewall(struct mbuf *m, struct label *label)
1378 {
1379 	struct mac_biba *dest;
1380 
1381 	dest = SLOT(label);
1382 
1383 	/* XXX: where is the label for the firewall really comming from? */
1384 	mac_biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1385 }
1386 
1387 /*
1388  * Labeling event operations: processes.
1389  */
1390 static void
1391 mac_biba_create_proc0(struct ucred *cred)
1392 {
1393 	struct mac_biba *dest;
1394 
1395 	dest = SLOT(cred->cr_label);
1396 
1397 	mac_biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1398 	mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL,
1399 	    MAC_BIBA_TYPE_HIGH, 0, NULL);
1400 }
1401 
1402 static void
1403 mac_biba_create_proc1(struct ucred *cred)
1404 {
1405 	struct mac_biba *dest;
1406 
1407 	dest = SLOT(cred->cr_label);
1408 
1409 	mac_biba_set_effective(dest, MAC_BIBA_TYPE_HIGH, 0, NULL);
1410 	mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL,
1411 	    MAC_BIBA_TYPE_HIGH, 0, NULL);
1412 }
1413 
1414 static void
1415 mac_biba_relabel_cred(struct ucred *cred, struct label *newlabel)
1416 {
1417 	struct mac_biba *source, *dest;
1418 
1419 	source = SLOT(newlabel);
1420 	dest = SLOT(cred->cr_label);
1421 
1422 	mac_biba_copy(source, dest);
1423 }
1424 
1425 /*
1426  * Label cleanup/flush operations
1427  */
1428 static void
1429 mac_biba_cleanup_sysv_msgmsg(struct label *msglabel)
1430 {
1431 
1432 	bzero(SLOT(msglabel), sizeof(struct mac_biba));
1433 }
1434 
1435 static void
1436 mac_biba_cleanup_sysv_msgqueue(struct label *msqlabel)
1437 {
1438 
1439 	bzero(SLOT(msqlabel), sizeof(struct mac_biba));
1440 }
1441 
1442 static void
1443 mac_biba_cleanup_sysv_sem(struct label *semalabel)
1444 {
1445 
1446 	bzero(SLOT(semalabel), sizeof(struct mac_biba));
1447 }
1448 
1449 static void
1450 mac_biba_cleanup_sysv_shm(struct label *shmlabel)
1451 {
1452 	bzero(SLOT(shmlabel), sizeof(struct mac_biba));
1453 }
1454 
1455 /*
1456  * Access control checks.
1457  */
1458 static int
1459 mac_biba_check_bpfdesc_receive(struct bpf_d *d, struct label *dlabel,
1460     struct ifnet *ifp, struct label *ifplabel)
1461 {
1462 	struct mac_biba *a, *b;
1463 
1464 	if (!mac_biba_enabled)
1465 		return (0);
1466 
1467 	a = SLOT(dlabel);
1468 	b = SLOT(ifplabel);
1469 
1470 	if (mac_biba_equal_effective(a, b))
1471 		return (0);
1472 	return (EACCES);
1473 }
1474 
1475 static int
1476 mac_biba_check_cred_relabel(struct ucred *cred, struct label *newlabel)
1477 {
1478 	struct mac_biba *subj, *new;
1479 	int error;
1480 
1481 	subj = SLOT(cred->cr_label);
1482 	new = SLOT(newlabel);
1483 
1484 	/*
1485 	 * If there is a Biba label update for the credential, it may
1486 	 * be an update of the effective, range, or both.
1487 	 */
1488 	error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
1489 	if (error)
1490 		return (error);
1491 
1492 	/*
1493 	 * If the Biba label is to be changed, authorize as appropriate.
1494 	 */
1495 	if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) {
1496 		/*
1497 		 * If the change request modifies both the Biba label
1498 		 * effective and range, check that the new effective will be
1499 		 * in the new range.
1500 		 */
1501 		if ((new->mb_flags & MAC_BIBA_FLAGS_BOTH) ==
1502 		    MAC_BIBA_FLAGS_BOTH &&
1503 		    !mac_biba_effective_in_range(new, new))
1504 			return (EINVAL);
1505 
1506 		/*
1507 		 * To change the Biba effective label on a credential, the
1508 		 * new effective label must be in the current range.
1509 		 */
1510 		if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE &&
1511 		    !mac_biba_effective_in_range(new, subj))
1512 			return (EPERM);
1513 
1514 		/*
1515 		 * To change the Biba range on a credential, the new
1516 		 * range label must be in the current range.
1517 		 */
1518 		if (new->mb_flags & MAC_BIBA_FLAG_RANGE &&
1519 		    !mac_biba_range_in_range(new, subj))
1520 			return (EPERM);
1521 
1522 		/*
1523 		 * To have EQUAL in any component of the new credential
1524 		 * Biba label, the subject must already have EQUAL in
1525 		 * their label.
1526 		 */
1527 		if (mac_biba_contains_equal(new)) {
1528 			error = mac_biba_subject_privileged(subj);
1529 			if (error)
1530 				return (error);
1531 		}
1532 	}
1533 
1534 	return (0);
1535 }
1536 
1537 static int
1538 mac_biba_check_cred_visible(struct ucred *u1, struct ucred *u2)
1539 {
1540 	struct mac_biba *subj, *obj;
1541 
1542 	if (!mac_biba_enabled)
1543 		return (0);
1544 
1545 	subj = SLOT(u1->cr_label);
1546 	obj = SLOT(u2->cr_label);
1547 
1548 	/* XXX: range */
1549 	if (!mac_biba_dominate_effective(obj, subj))
1550 		return (ESRCH);
1551 
1552 	return (0);
1553 }
1554 
1555 static int
1556 mac_biba_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifp,
1557     struct label *ifplabel, struct label *newlabel)
1558 {
1559 	struct mac_biba *subj, *new;
1560 	int error;
1561 
1562 	subj = SLOT(cred->cr_label);
1563 	new = SLOT(newlabel);
1564 
1565 	/*
1566 	 * If there is a Biba label update for the interface, it may
1567 	 * be an update of the effective, range, or both.
1568 	 */
1569 	error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
1570 	if (error)
1571 		return (error);
1572 
1573 	/*
1574 	 * Relabling network interfaces requires Biba privilege.
1575 	 */
1576 	error = mac_biba_subject_privileged(subj);
1577 	if (error)
1578 		return (error);
1579 
1580 	return (0);
1581 }
1582 
1583 static int
1584 mac_biba_check_ifnet_transmit(struct ifnet *ifp, struct label *ifplabel,
1585     struct mbuf *m, struct label *mlabel)
1586 {
1587 	struct mac_biba *p, *i;
1588 
1589 	if (!mac_biba_enabled)
1590 		return (0);
1591 
1592 	p = SLOT(mlabel);
1593 	i = SLOT(ifplabel);
1594 
1595 	return (mac_biba_effective_in_range(p, i) ? 0 : EACCES);
1596 }
1597 
1598 static int
1599 mac_biba_check_inpcb_deliver(struct inpcb *inp, struct label *inplabel,
1600     struct mbuf *m, struct label *mlabel)
1601 {
1602 	struct mac_biba *p, *i;
1603 
1604 	if (!mac_biba_enabled)
1605 		return (0);
1606 
1607 	p = SLOT(mlabel);
1608 	i = SLOT(inplabel);
1609 
1610 	return (mac_biba_equal_effective(p, i) ? 0 : EACCES);
1611 }
1612 
1613 static int
1614 mac_biba_check_sysv_msgrcv(struct ucred *cred, struct msg *msgptr,
1615     struct label *msglabel)
1616 {
1617 	struct mac_biba *subj, *obj;
1618 
1619 	if (!mac_biba_enabled)
1620 		return (0);
1621 
1622 	subj = SLOT(cred->cr_label);
1623 	obj = SLOT(msglabel);
1624 
1625 	if (!mac_biba_dominate_effective(obj, subj))
1626 		return (EACCES);
1627 
1628 	return (0);
1629 }
1630 
1631 static int
1632 mac_biba_check_sysv_msgrmid(struct ucred *cred, struct msg *msgptr,
1633     struct label *msglabel)
1634 {
1635 	struct mac_biba *subj, *obj;
1636 
1637 	if (!mac_biba_enabled)
1638 		return (0);
1639 
1640 	subj = SLOT(cred->cr_label);
1641 	obj = SLOT(msglabel);
1642 
1643 	if (!mac_biba_dominate_effective(subj, obj))
1644 		return (EACCES);
1645 
1646 	return (0);
1647 }
1648 
1649 static int
1650 mac_biba_check_sysv_msqget(struct ucred *cred, struct msqid_kernel *msqkptr,
1651     struct label *msqklabel)
1652 {
1653 	struct mac_biba *subj, *obj;
1654 
1655 	if (!mac_biba_enabled)
1656 		return (0);
1657 
1658 	subj = SLOT(cred->cr_label);
1659 	obj = SLOT(msqklabel);
1660 
1661 	if (!mac_biba_dominate_effective(obj, subj))
1662 		return (EACCES);
1663 
1664 	return (0);
1665 }
1666 
1667 static int
1668 mac_biba_check_sysv_msqsnd(struct ucred *cred, struct msqid_kernel *msqkptr,
1669     struct label *msqklabel)
1670 {
1671 	struct mac_biba *subj, *obj;
1672 
1673 	if (!mac_biba_enabled)
1674 		return (0);
1675 
1676 	subj = SLOT(cred->cr_label);
1677 	obj = SLOT(msqklabel);
1678 
1679 	if (!mac_biba_dominate_effective(subj, obj))
1680 		return (EACCES);
1681 
1682 	return (0);
1683 }
1684 
1685 static int
1686 mac_biba_check_sysv_msqrcv(struct ucred *cred, struct msqid_kernel *msqkptr,
1687     struct label *msqklabel)
1688 {
1689 	struct mac_biba *subj, *obj;
1690 
1691 	if (!mac_biba_enabled)
1692 		return (0);
1693 
1694 	subj = SLOT(cred->cr_label);
1695 	obj = SLOT(msqklabel);
1696 
1697 	if (!mac_biba_dominate_effective(obj, subj))
1698 		return (EACCES);
1699 
1700 	return (0);
1701 }
1702 
1703 
1704 static int
1705 mac_biba_check_sysv_msqctl(struct ucred *cred, struct msqid_kernel *msqkptr,
1706     struct label *msqklabel, int cmd)
1707 {
1708 	struct mac_biba *subj, *obj;
1709 
1710 	if (!mac_biba_enabled)
1711 		return (0);
1712 
1713 	subj = SLOT(cred->cr_label);
1714 	obj = SLOT(msqklabel);
1715 
1716 	switch(cmd) {
1717 	case IPC_RMID:
1718 	case IPC_SET:
1719 		if (!mac_biba_dominate_effective(subj, obj))
1720 			return (EACCES);
1721 		break;
1722 
1723 	case IPC_STAT:
1724 		if (!mac_biba_dominate_effective(obj, subj))
1725 			return (EACCES);
1726 		break;
1727 
1728 	default:
1729 		return (EACCES);
1730 	}
1731 
1732 	return (0);
1733 }
1734 
1735 static int
1736 mac_biba_check_sysv_semctl(struct ucred *cred, struct semid_kernel *semakptr,
1737     struct label *semaklabel, int cmd)
1738 {
1739 	struct mac_biba *subj, *obj;
1740 
1741 	if (!mac_biba_enabled)
1742 		return (0);
1743 
1744 	subj = SLOT(cred->cr_label);
1745 	obj = SLOT(semaklabel);
1746 
1747 	switch(cmd) {
1748 	case IPC_RMID:
1749 	case IPC_SET:
1750 	case SETVAL:
1751 	case SETALL:
1752 		if (!mac_biba_dominate_effective(subj, obj))
1753 			return (EACCES);
1754 		break;
1755 
1756 	case IPC_STAT:
1757 	case GETVAL:
1758 	case GETPID:
1759 	case GETNCNT:
1760 	case GETZCNT:
1761 	case GETALL:
1762 		if (!mac_biba_dominate_effective(obj, subj))
1763 			return (EACCES);
1764 		break;
1765 
1766 	default:
1767 		return (EACCES);
1768 	}
1769 
1770 	return (0);
1771 }
1772 
1773 static int
1774 mac_biba_check_sysv_semget(struct ucred *cred, struct semid_kernel *semakptr,
1775     struct label *semaklabel)
1776 {
1777 	struct mac_biba *subj, *obj;
1778 
1779 	if (!mac_biba_enabled)
1780 		return (0);
1781 
1782 	subj = SLOT(cred->cr_label);
1783 	obj = SLOT(semaklabel);
1784 
1785 	if (!mac_biba_dominate_effective(obj, subj))
1786 		return (EACCES);
1787 
1788 	return (0);
1789 }
1790 
1791 
1792 static int
1793 mac_biba_check_sysv_semop(struct ucred *cred, struct semid_kernel *semakptr,
1794     struct label *semaklabel, size_t accesstype)
1795 {
1796 	struct mac_biba *subj, *obj;
1797 
1798 	if (!mac_biba_enabled)
1799 		return (0);
1800 
1801 	subj = SLOT(cred->cr_label);
1802 	obj = SLOT(semaklabel);
1803 
1804 	if (accesstype & SEM_R)
1805 		if (!mac_biba_dominate_effective(obj, subj))
1806 			return (EACCES);
1807 
1808 	if (accesstype & SEM_A)
1809 		if (!mac_biba_dominate_effective(subj, obj))
1810 			return (EACCES);
1811 
1812 	return (0);
1813 }
1814 
1815 static int
1816 mac_biba_check_sysv_shmat(struct ucred *cred, struct shmid_kernel *shmsegptr,
1817     struct label *shmseglabel, int shmflg)
1818 {
1819 	struct mac_biba *subj, *obj;
1820 
1821 	if (!mac_biba_enabled)
1822 		return (0);
1823 
1824 	subj = SLOT(cred->cr_label);
1825 	obj = SLOT(shmseglabel);
1826 
1827 	if (!mac_biba_dominate_effective(obj, subj))
1828 		return (EACCES);
1829 	if ((shmflg & SHM_RDONLY) == 0) {
1830 		if (!mac_biba_dominate_effective(subj, obj))
1831 			return (EACCES);
1832 	}
1833 
1834 	return (0);
1835 }
1836 
1837 static int
1838 mac_biba_check_sysv_shmctl(struct ucred *cred, struct shmid_kernel *shmsegptr,
1839     struct label *shmseglabel, int cmd)
1840 {
1841 	struct mac_biba *subj, *obj;
1842 
1843 	if (!mac_biba_enabled)
1844 		return (0);
1845 
1846 	subj = SLOT(cred->cr_label);
1847 	obj = SLOT(shmseglabel);
1848 
1849 	switch(cmd) {
1850 	case IPC_RMID:
1851 	case IPC_SET:
1852 		if (!mac_biba_dominate_effective(subj, obj))
1853 			return (EACCES);
1854 		break;
1855 
1856 	case IPC_STAT:
1857 	case SHM_STAT:
1858 		if (!mac_biba_dominate_effective(obj, subj))
1859 			return (EACCES);
1860 		break;
1861 
1862 	default:
1863 		return (EACCES);
1864 	}
1865 
1866 	return (0);
1867 }
1868 
1869 static int
1870 mac_biba_check_sysv_shmget(struct ucred *cred, struct shmid_kernel *shmsegptr,
1871     struct label *shmseglabel, int shmflg)
1872 {
1873 	struct mac_biba *subj, *obj;
1874 
1875 	if (!mac_biba_enabled)
1876 		return (0);
1877 
1878 	subj = SLOT(cred->cr_label);
1879 	obj = SLOT(shmseglabel);
1880 
1881 	if (!mac_biba_dominate_effective(obj, subj))
1882 		return (EACCES);
1883 
1884 	return (0);
1885 }
1886 
1887 static int
1888 mac_biba_check_kld_load(struct ucred *cred, struct vnode *vp,
1889     struct label *vplabel)
1890 {
1891 	struct mac_biba *subj, *obj;
1892 	int error;
1893 
1894 	if (!mac_biba_enabled)
1895 		return (0);
1896 
1897 	subj = SLOT(cred->cr_label);
1898 
1899 	error = mac_biba_subject_privileged(subj);
1900 	if (error)
1901 		return (error);
1902 
1903 	obj = SLOT(vplabel);
1904 	if (!mac_biba_high_effective(obj))
1905 		return (EACCES);
1906 
1907 	return (0);
1908 }
1909 
1910 static int
1911 mac_biba_check_mount_stat(struct ucred *cred, struct mount *mp,
1912     struct label *mplabel)
1913 {
1914 	struct mac_biba *subj, *obj;
1915 
1916 	if (!mac_biba_enabled)
1917 		return (0);
1918 
1919 	subj = SLOT(cred->cr_label);
1920 	obj = SLOT(mplabel);
1921 
1922 	if (!mac_biba_dominate_effective(obj, subj))
1923 		return (EACCES);
1924 
1925 	return (0);
1926 }
1927 
1928 static int
1929 mac_biba_check_pipe_ioctl(struct ucred *cred, struct pipepair *pp,
1930     struct label *pplabel, unsigned long cmd, void /* caddr_t */ *data)
1931 {
1932 
1933 	if(!mac_biba_enabled)
1934 		return (0);
1935 
1936 	/* XXX: This will be implemented soon... */
1937 
1938 	return (0);
1939 }
1940 
1941 static int
1942 mac_biba_check_pipe_poll(struct ucred *cred, struct pipepair *pp,
1943     struct label *pplabel)
1944 {
1945 	struct mac_biba *subj, *obj;
1946 
1947 	if (!mac_biba_enabled)
1948 		return (0);
1949 
1950 	subj = SLOT(cred->cr_label);
1951 	obj = SLOT(pplabel);
1952 
1953 	if (!mac_biba_dominate_effective(obj, subj))
1954 		return (EACCES);
1955 
1956 	return (0);
1957 }
1958 
1959 static int
1960 mac_biba_check_pipe_read(struct ucred *cred, struct pipepair *pp,
1961     struct label *pplabel)
1962 {
1963 	struct mac_biba *subj, *obj;
1964 
1965 	if (!mac_biba_enabled)
1966 		return (0);
1967 
1968 	subj = SLOT(cred->cr_label);
1969 	obj = SLOT(pplabel);
1970 
1971 	if (!mac_biba_dominate_effective(obj, subj))
1972 		return (EACCES);
1973 
1974 	return (0);
1975 }
1976 
1977 static int
1978 mac_biba_check_pipe_relabel(struct ucred *cred, struct pipepair *pp,
1979     struct label *pplabel, struct label *newlabel)
1980 {
1981 	struct mac_biba *subj, *obj, *new;
1982 	int error;
1983 
1984 	new = SLOT(newlabel);
1985 	subj = SLOT(cred->cr_label);
1986 	obj = SLOT(pplabel);
1987 
1988 	/*
1989 	 * If there is a Biba label update for a pipe, it must be a
1990 	 * effective update.
1991 	 */
1992 	error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE);
1993 	if (error)
1994 		return (error);
1995 
1996 	/*
1997 	 * To perform a relabel of a pipe (Biba label or not), Biba must
1998 	 * authorize the relabel.
1999 	 */
2000 	if (!mac_biba_effective_in_range(obj, subj))
2001 		return (EPERM);
2002 
2003 	/*
2004 	 * If the Biba label is to be changed, authorize as appropriate.
2005 	 */
2006 	if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
2007 		/*
2008 		 * To change the Biba label on a pipe, the new pipe label
2009 		 * must be in the subject range.
2010 		 */
2011 		if (!mac_biba_effective_in_range(new, subj))
2012 			return (EPERM);
2013 
2014 		/*
2015 		 * To change the Biba label on a pipe to be EQUAL, the
2016 		 * subject must have appropriate privilege.
2017 		 */
2018 		if (mac_biba_contains_equal(new)) {
2019 			error = mac_biba_subject_privileged(subj);
2020 			if (error)
2021 				return (error);
2022 		}
2023 	}
2024 
2025 	return (0);
2026 }
2027 
2028 static int
2029 mac_biba_check_pipe_stat(struct ucred *cred, struct pipepair *pp,
2030     struct label *pplabel)
2031 {
2032 	struct mac_biba *subj, *obj;
2033 
2034 	if (!mac_biba_enabled)
2035 		return (0);
2036 
2037 	subj = SLOT(cred->cr_label);
2038 	obj = SLOT(pplabel);
2039 
2040 	if (!mac_biba_dominate_effective(obj, subj))
2041 		return (EACCES);
2042 
2043 	return (0);
2044 }
2045 
2046 static int
2047 mac_biba_check_pipe_write(struct ucred *cred, struct pipepair *pp,
2048     struct label *pplabel)
2049 {
2050 	struct mac_biba *subj, *obj;
2051 
2052 	if (!mac_biba_enabled)
2053 		return (0);
2054 
2055 	subj = SLOT(cred->cr_label);
2056 	obj = SLOT(pplabel);
2057 
2058 	if (!mac_biba_dominate_effective(subj, obj))
2059 		return (EACCES);
2060 
2061 	return (0);
2062 }
2063 
2064 static int
2065 mac_biba_check_posix_sem_write(struct ucred *cred, struct ksem *ksemptr,
2066     struct label *ks_label)
2067 {
2068 	struct mac_biba *subj, *obj;
2069 
2070 	if (!mac_biba_enabled)
2071 		return (0);
2072 
2073 	subj = SLOT(cred->cr_label);
2074 	obj = SLOT(ks_label);
2075 
2076 	if (!mac_biba_dominate_effective(subj, obj))
2077 		return (EACCES);
2078 
2079 	return (0);
2080 }
2081 
2082 static int
2083 mac_biba_check_posix_sem_rdonly(struct ucred *cred, struct ksem *ksemptr,
2084     struct label *ks_label)
2085 {
2086 	struct mac_biba *subj, *obj;
2087 
2088 	if (!mac_biba_enabled)
2089 		return (0);
2090 
2091 	subj = SLOT(cred->cr_label);
2092 	obj = SLOT(ks_label);
2093 
2094 	if (!mac_biba_dominate_effective(obj, subj))
2095 		return (EACCES);
2096 
2097 	return (0);
2098 }
2099 
2100 static int
2101 mac_biba_check_proc_debug(struct ucred *cred, struct proc *p)
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(p->p_ucred->cr_label);
2110 
2111 	/* XXX: range checks */
2112 	if (!mac_biba_dominate_effective(obj, subj))
2113 		return (ESRCH);
2114 	if (!mac_biba_dominate_effective(subj, obj))
2115 		return (EACCES);
2116 
2117 	return (0);
2118 }
2119 
2120 static int
2121 mac_biba_check_proc_sched(struct ucred *cred, struct proc *p)
2122 {
2123 	struct mac_biba *subj, *obj;
2124 
2125 	if (!mac_biba_enabled)
2126 		return (0);
2127 
2128 	subj = SLOT(cred->cr_label);
2129 	obj = SLOT(p->p_ucred->cr_label);
2130 
2131 	/* XXX: range checks */
2132 	if (!mac_biba_dominate_effective(obj, subj))
2133 		return (ESRCH);
2134 	if (!mac_biba_dominate_effective(subj, obj))
2135 		return (EACCES);
2136 
2137 	return (0);
2138 }
2139 
2140 static int
2141 mac_biba_check_proc_signal(struct ucred *cred, struct proc *p, int signum)
2142 {
2143 	struct mac_biba *subj, *obj;
2144 
2145 	if (!mac_biba_enabled)
2146 		return (0);
2147 
2148 	subj = SLOT(cred->cr_label);
2149 	obj = SLOT(p->p_ucred->cr_label);
2150 
2151 	/* XXX: range checks */
2152 	if (!mac_biba_dominate_effective(obj, subj))
2153 		return (ESRCH);
2154 	if (!mac_biba_dominate_effective(subj, obj))
2155 		return (EACCES);
2156 
2157 	return (0);
2158 }
2159 
2160 static int
2161 mac_biba_check_socket_deliver(struct socket *so, struct label *solabel,
2162     struct mbuf *m, struct label *mlabel)
2163 {
2164 	struct mac_biba *p, *s;
2165 
2166 	if (!mac_biba_enabled)
2167 		return (0);
2168 
2169 	p = SLOT(mlabel);
2170 	s = SLOT(solabel);
2171 
2172 	return (mac_biba_equal_effective(p, s) ? 0 : EACCES);
2173 }
2174 
2175 static int
2176 mac_biba_check_socket_relabel(struct ucred *cred, struct socket *so,
2177     struct label *solabel, struct label *newlabel)
2178 {
2179 	struct mac_biba *subj, *obj, *new;
2180 	int error;
2181 
2182 	new = SLOT(newlabel);
2183 	subj = SLOT(cred->cr_label);
2184 	obj = SLOT(solabel);
2185 
2186 	/*
2187 	 * If there is a Biba label update for the socket, it may be
2188 	 * an update of effective.
2189 	 */
2190 	error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE);
2191 	if (error)
2192 		return (error);
2193 
2194 	/*
2195 	 * To relabel a socket, the old socket effective must be in the subject
2196 	 * range.
2197 	 */
2198 	if (!mac_biba_effective_in_range(obj, subj))
2199 		return (EPERM);
2200 
2201 	/*
2202 	 * If the Biba label is to be changed, authorize as appropriate.
2203 	 */
2204 	if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
2205 		/*
2206 		 * To relabel a socket, the new socket effective must be in
2207 		 * the subject range.
2208 		 */
2209 		if (!mac_biba_effective_in_range(new, subj))
2210 			return (EPERM);
2211 
2212 		/*
2213 		 * To change the Biba label on the socket to contain EQUAL,
2214 		 * the subject must have appropriate privilege.
2215 		 */
2216 		if (mac_biba_contains_equal(new)) {
2217 			error = mac_biba_subject_privileged(subj);
2218 			if (error)
2219 				return (error);
2220 		}
2221 	}
2222 
2223 	return (0);
2224 }
2225 
2226 static int
2227 mac_biba_check_socket_visible(struct ucred *cred, struct socket *so,
2228     struct label *solabel)
2229 {
2230 	struct mac_biba *subj, *obj;
2231 
2232 	if (!mac_biba_enabled)
2233 		return (0);
2234 
2235 	subj = SLOT(cred->cr_label);
2236 	obj = SLOT(solabel);
2237 
2238 	if (!mac_biba_dominate_effective(obj, subj))
2239 		return (ENOENT);
2240 
2241 	return (0);
2242 }
2243 
2244 /*
2245  * Some system privileges are allowed regardless of integrity grade; others
2246  * are allowed only when running with privilege with respect to the Biba
2247  * policy as they might otherwise allow bypassing of the integrity policy.
2248  */
2249 static int
2250 mac_biba_priv_check(struct ucred *cred, int priv)
2251 {
2252 	struct mac_biba *subj;
2253 	int error;
2254 
2255 	if (!mac_biba_enabled)
2256 		return (0);
2257 
2258 	/*
2259 	 * Exempt only specific privileges from the Biba integrity policy.
2260 	 */
2261 	switch (priv) {
2262 	case PRIV_KTRACE:
2263 	case PRIV_MSGBUF:
2264 
2265 	/*
2266 	 * Allow processes to manipulate basic process audit properties, and
2267 	 * to submit audit records.
2268 	 */
2269 	case PRIV_AUDIT_GETAUDIT:
2270 	case PRIV_AUDIT_SETAUDIT:
2271 	case PRIV_AUDIT_SUBMIT:
2272 
2273 	/*
2274 	 * Allow processes to manipulate their regular UNIX credentials.
2275 	 */
2276 	case PRIV_CRED_SETUID:
2277 	case PRIV_CRED_SETEUID:
2278 	case PRIV_CRED_SETGID:
2279 	case PRIV_CRED_SETEGID:
2280 	case PRIV_CRED_SETGROUPS:
2281 	case PRIV_CRED_SETREUID:
2282 	case PRIV_CRED_SETREGID:
2283 	case PRIV_CRED_SETRESUID:
2284 	case PRIV_CRED_SETRESGID:
2285 
2286 	/*
2287 	 * Allow processes to perform system monitoring.
2288 	 */
2289 	case PRIV_SEEOTHERGIDS:
2290 	case PRIV_SEEOTHERUIDS:
2291 		break;
2292 
2293 	/*
2294 	 * Allow access to general process debugging facilities.  We
2295 	 * separately control debugging based on MAC label.
2296 	 */
2297 	case PRIV_DEBUG_DIFFCRED:
2298 	case PRIV_DEBUG_SUGID:
2299 	case PRIV_DEBUG_UNPRIV:
2300 
2301 	/*
2302 	 * Allow manipulating jails.
2303 	 */
2304 	case PRIV_JAIL_ATTACH:
2305 
2306 	/*
2307 	 * Allow privilege with respect to the Partition policy, but not the
2308 	 * Privs policy.
2309 	 */
2310 	case PRIV_MAC_PARTITION:
2311 
2312 	/*
2313 	 * Allow privilege with respect to process resource limits and login
2314 	 * context.
2315 	 */
2316 	case PRIV_PROC_LIMIT:
2317 	case PRIV_PROC_SETLOGIN:
2318 	case PRIV_PROC_SETRLIMIT:
2319 
2320 	/*
2321 	 * Allow System V and POSIX IPC privileges.
2322 	 */
2323 	case PRIV_IPC_READ:
2324 	case PRIV_IPC_WRITE:
2325 	case PRIV_IPC_ADMIN:
2326 	case PRIV_IPC_MSGSIZE:
2327 	case PRIV_MQ_ADMIN:
2328 
2329 	/*
2330 	 * Allow certain scheduler manipulations -- possibly this should be
2331 	 * controlled by more fine-grained policy, as potentially low
2332 	 * integrity processes can deny CPU to higher integrity ones.
2333 	 */
2334 	case PRIV_SCHED_DIFFCRED:
2335 	case PRIV_SCHED_SETPRIORITY:
2336 	case PRIV_SCHED_RTPRIO:
2337 	case PRIV_SCHED_SETPOLICY:
2338 	case PRIV_SCHED_SET:
2339 	case PRIV_SCHED_SETPARAM:
2340 
2341 	/*
2342 	 * More IPC privileges.
2343 	 */
2344 	case PRIV_SEM_WRITE:
2345 
2346 	/*
2347 	 * Allow signaling privileges subject to integrity policy.
2348 	 */
2349 	case PRIV_SIGNAL_DIFFCRED:
2350 	case PRIV_SIGNAL_SUGID:
2351 
2352 	/*
2353 	 * Allow access to only limited sysctls from lower integrity levels;
2354 	 * piggy-back on the Jail definition.
2355 	 */
2356 	case PRIV_SYSCTL_WRITEJAIL:
2357 
2358 	/*
2359 	 * Allow TTY-based privileges, subject to general device access using
2360 	 * labels on TTY device nodes, but not console privilege.
2361 	 */
2362 	case PRIV_TTY_DRAINWAIT:
2363 	case PRIV_TTY_DTRWAIT:
2364 	case PRIV_TTY_EXCLUSIVE:
2365 	case PRIV_TTY_PRISON:
2366 	case PRIV_TTY_STI:
2367 	case PRIV_TTY_SETA:
2368 
2369 	/*
2370 	 * Grant most VFS privileges, as almost all are in practice bounded
2371 	 * by more specific checks using labels.
2372 	 */
2373 	case PRIV_VFS_READ:
2374 	case PRIV_VFS_WRITE:
2375 	case PRIV_VFS_ADMIN:
2376 	case PRIV_VFS_EXEC:
2377 	case PRIV_VFS_LOOKUP:
2378 	case PRIV_VFS_CHFLAGS_DEV:
2379 	case PRIV_VFS_CHOWN:
2380 	case PRIV_VFS_CHROOT:
2381 	case PRIV_VFS_RETAINSUGID:
2382 	case PRIV_VFS_EXCEEDQUOTA:
2383 	case PRIV_VFS_FCHROOT:
2384 	case PRIV_VFS_FHOPEN:
2385 	case PRIV_VFS_FHSTATFS:
2386 	case PRIV_VFS_GENERATION:
2387 	case PRIV_VFS_GETFH:
2388 	case PRIV_VFS_GETQUOTA:
2389 	case PRIV_VFS_LINK:
2390 	case PRIV_VFS_MOUNT:
2391 	case PRIV_VFS_MOUNT_OWNER:
2392 	case PRIV_VFS_MOUNT_PERM:
2393 	case PRIV_VFS_MOUNT_SUIDDIR:
2394 	case PRIV_VFS_MOUNT_NONUSER:
2395 	case PRIV_VFS_SETGID:
2396 	case PRIV_VFS_STICKYFILE:
2397 	case PRIV_VFS_SYSFLAGS:
2398 	case PRIV_VFS_UNMOUNT:
2399 
2400 	/*
2401 	 * Allow VM privileges; it would be nice if these were subject to
2402 	 * resource limits.
2403 	 */
2404 	case PRIV_VM_MADV_PROTECT:
2405 	case PRIV_VM_MLOCK:
2406 	case PRIV_VM_MUNLOCK:
2407 
2408 	/*
2409 	 * Allow some but not all network privileges.  In general, dont allow
2410 	 * reconfiguring the network stack, just normal use.
2411 	 */
2412 	case PRIV_NETATALK_RESERVEDPORT:
2413 	case PRIV_NETINET_RESERVEDPORT:
2414 	case PRIV_NETINET_RAW:
2415 	case PRIV_NETINET_REUSEPORT:
2416 	case PRIV_NETIPX_RESERVEDPORT:
2417 	case PRIV_NETIPX_RAW:
2418 		break;
2419 
2420 	/*
2421 	 * All remaining system privileges are allow only if the process
2422 	 * holds privilege with respect to the Biba policy.
2423 	 */
2424 	default:
2425 		subj = SLOT(cred->cr_label);
2426 		error = mac_biba_subject_privileged(subj);
2427 		if (error)
2428 			return (error);
2429 	}
2430 	return (0);
2431 }
2432 
2433 static int
2434 mac_biba_check_system_acct(struct ucred *cred, struct vnode *vp,
2435     struct label *vplabel)
2436 {
2437 	struct mac_biba *subj, *obj;
2438 	int error;
2439 
2440 	if (!mac_biba_enabled)
2441 		return (0);
2442 
2443 	subj = SLOT(cred->cr_label);
2444 
2445 	error = mac_biba_subject_privileged(subj);
2446 	if (error)
2447 		return (error);
2448 
2449 	if (vplabel == NULL)
2450 		return (0);
2451 
2452 	obj = SLOT(vplabel);
2453 	if (!mac_biba_high_effective(obj))
2454 		return (EACCES);
2455 
2456 	return (0);
2457 }
2458 
2459 static int
2460 mac_biba_check_system_auditctl(struct ucred *cred, struct vnode *vp,
2461     struct label *vplabel)
2462 {
2463 	struct mac_biba *subj, *obj;
2464 	int error;
2465 
2466 	if (!mac_biba_enabled)
2467 		return (0);
2468 
2469 	subj = SLOT(cred->cr_label);
2470 
2471 	error = mac_biba_subject_privileged(subj);
2472 	if (error)
2473 		return (error);
2474 
2475 	if (vplabel == NULL)
2476 		return (0);
2477 
2478 	obj = SLOT(vplabel);
2479 	if (!mac_biba_high_effective(obj))
2480 		return (EACCES);
2481 
2482 	return (0);
2483 }
2484 
2485 static int
2486 mac_biba_check_system_auditon(struct ucred *cred, int cmd)
2487 {
2488 	struct mac_biba *subj;
2489 	int error;
2490 
2491 	if (!mac_biba_enabled)
2492 		return (0);
2493 
2494 	subj = SLOT(cred->cr_label);
2495 
2496 	error = mac_biba_subject_privileged(subj);
2497 	if (error)
2498 		return (error);
2499 
2500 	return (0);
2501 }
2502 
2503 static int
2504 mac_biba_check_system_swapon(struct ucred *cred, struct vnode *vp,
2505     struct label *vplabel)
2506 {
2507 	struct mac_biba *subj, *obj;
2508 	int error;
2509 
2510 	if (!mac_biba_enabled)
2511 		return (0);
2512 
2513 	subj = SLOT(cred->cr_label);
2514 	obj = SLOT(vplabel);
2515 
2516 	error = mac_biba_subject_privileged(subj);
2517 	if (error)
2518 		return (error);
2519 
2520 	if (!mac_biba_high_effective(obj))
2521 		return (EACCES);
2522 
2523 	return (0);
2524 }
2525 
2526 static int
2527 mac_biba_check_system_swapoff(struct ucred *cred, struct vnode *vp,
2528     struct label *label)
2529 {
2530 	struct mac_biba *subj;
2531 	int error;
2532 
2533 	if (!mac_biba_enabled)
2534 		return (0);
2535 
2536 	subj = SLOT(cred->cr_label);
2537 
2538 	error = mac_biba_subject_privileged(subj);
2539 	if (error)
2540 		return (error);
2541 
2542 	return (0);
2543 }
2544 
2545 static int
2546 mac_biba_check_system_sysctl(struct ucred *cred, struct sysctl_oid *oidp,
2547     void *arg1, int arg2, struct sysctl_req *req)
2548 {
2549 	struct mac_biba *subj;
2550 	int error;
2551 
2552 	if (!mac_biba_enabled)
2553 		return (0);
2554 
2555 	subj = SLOT(cred->cr_label);
2556 
2557 	/*
2558 	 * Treat sysctl variables without CTLFLAG_ANYBODY flag as
2559 	 * biba/high, but also require privilege to change them.
2560 	 */
2561 	if (req->newptr != NULL && (oidp->oid_kind & CTLFLAG_ANYBODY) == 0) {
2562 		if (!mac_biba_subject_dominate_high(subj))
2563 			return (EACCES);
2564 
2565 		error = mac_biba_subject_privileged(subj);
2566 		if (error)
2567 			return (error);
2568 	}
2569 
2570 	return (0);
2571 }
2572 
2573 static int
2574 mac_biba_check_vnode_chdir(struct ucred *cred, struct vnode *dvp,
2575     struct label *dvplabel)
2576 {
2577 	struct mac_biba *subj, *obj;
2578 
2579 	if (!mac_biba_enabled)
2580 		return (0);
2581 
2582 	subj = SLOT(cred->cr_label);
2583 	obj = SLOT(dvplabel);
2584 
2585 	if (!mac_biba_dominate_effective(obj, subj))
2586 		return (EACCES);
2587 
2588 	return (0);
2589 }
2590 
2591 static int
2592 mac_biba_check_vnode_chroot(struct ucred *cred, struct vnode *dvp,
2593     struct label *dvplabel)
2594 {
2595 	struct mac_biba *subj, *obj;
2596 
2597 	if (!mac_biba_enabled)
2598 		return (0);
2599 
2600 	subj = SLOT(cred->cr_label);
2601 	obj = SLOT(dvplabel);
2602 
2603 	if (!mac_biba_dominate_effective(obj, subj))
2604 		return (EACCES);
2605 
2606 	return (0);
2607 }
2608 
2609 static int
2610 mac_biba_check_vnode_create(struct ucred *cred, struct vnode *dvp,
2611     struct label *dvplabel, struct componentname *cnp, struct vattr *vap)
2612 {
2613 	struct mac_biba *subj, *obj;
2614 
2615 	if (!mac_biba_enabled)
2616 		return (0);
2617 
2618 	subj = SLOT(cred->cr_label);
2619 	obj = SLOT(dvplabel);
2620 
2621 	if (!mac_biba_dominate_effective(subj, obj))
2622 		return (EACCES);
2623 
2624 	return (0);
2625 }
2626 
2627 static int
2628 mac_biba_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
2629     struct label *vplabel, acl_type_t type)
2630 {
2631 	struct mac_biba *subj, *obj;
2632 
2633 	if (!mac_biba_enabled)
2634 		return (0);
2635 
2636 	subj = SLOT(cred->cr_label);
2637 	obj = SLOT(vplabel);
2638 
2639 	if (!mac_biba_dominate_effective(subj, obj))
2640 		return (EACCES);
2641 
2642 	return (0);
2643 }
2644 
2645 static int
2646 mac_biba_check_vnode_deleteextattr(struct ucred *cred, struct vnode *vp,
2647     struct label *vplabel, int attrnamespace, const char *name)
2648 {
2649 	struct mac_biba *subj, *obj;
2650 
2651 	if (!mac_biba_enabled)
2652 		return (0);
2653 
2654 	subj = SLOT(cred->cr_label);
2655 	obj = SLOT(vplabel);
2656 
2657 	if (!mac_biba_dominate_effective(subj, obj))
2658 		return (EACCES);
2659 
2660 	return (0);
2661 }
2662 
2663 static int
2664 mac_biba_check_vnode_exec(struct ucred *cred, struct vnode *vp,
2665     struct label *vplabel, struct image_params *imgp,
2666     struct label *execlabel)
2667 {
2668 	struct mac_biba *subj, *obj, *exec;
2669 	int error;
2670 
2671 	if (execlabel != NULL) {
2672 		/*
2673 		 * We currently don't permit labels to be changed at
2674 		 * exec-time as part of Biba, so disallow non-NULL
2675 		 * Biba label elements in the execlabel.
2676 		 */
2677 		exec = SLOT(execlabel);
2678 		error = biba_atmostflags(exec, 0);
2679 		if (error)
2680 			return (error);
2681 	}
2682 
2683 	if (!mac_biba_enabled)
2684 		return (0);
2685 
2686 	subj = SLOT(cred->cr_label);
2687 	obj = SLOT(vplabel);
2688 
2689 	if (!mac_biba_dominate_effective(obj, subj))
2690 		return (EACCES);
2691 
2692 	return (0);
2693 }
2694 
2695 static int
2696 mac_biba_check_vnode_getacl(struct ucred *cred, struct vnode *vp,
2697     struct label *vplabel, acl_type_t type)
2698 {
2699 	struct mac_biba *subj, *obj;
2700 
2701 	if (!mac_biba_enabled)
2702 		return (0);
2703 
2704 	subj = SLOT(cred->cr_label);
2705 	obj = SLOT(vplabel);
2706 
2707 	if (!mac_biba_dominate_effective(obj, subj))
2708 		return (EACCES);
2709 
2710 	return (0);
2711 }
2712 
2713 static int
2714 mac_biba_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
2715     struct label *vplabel, int attrnamespace, const char *name,
2716     struct uio *uio)
2717 {
2718 	struct mac_biba *subj, *obj;
2719 
2720 	if (!mac_biba_enabled)
2721 		return (0);
2722 
2723 	subj = SLOT(cred->cr_label);
2724 	obj = SLOT(vplabel);
2725 
2726 	if (!mac_biba_dominate_effective(obj, subj))
2727 		return (EACCES);
2728 
2729 	return (0);
2730 }
2731 
2732 static int
2733 mac_biba_check_vnode_link(struct ucred *cred, struct vnode *dvp,
2734     struct label *dvplabel, struct vnode *vp, struct label *vplabel,
2735     struct componentname *cnp)
2736 {
2737 	struct mac_biba *subj, *obj;
2738 
2739 	if (!mac_biba_enabled)
2740 		return (0);
2741 
2742 	subj = SLOT(cred->cr_label);
2743 	obj = SLOT(dvplabel);
2744 
2745 	if (!mac_biba_dominate_effective(subj, obj))
2746 		return (EACCES);
2747 
2748 	obj = SLOT(vplabel);
2749 
2750 	if (!mac_biba_dominate_effective(subj, obj))
2751 		return (EACCES);
2752 
2753 	return (0);
2754 }
2755 
2756 static int
2757 mac_biba_check_vnode_listextattr(struct ucred *cred, struct vnode *vp,
2758     struct label *vplabel, int attrnamespace)
2759 {
2760 	struct mac_biba *subj, *obj;
2761 
2762 	if (!mac_biba_enabled)
2763 		return (0);
2764 
2765 	subj = SLOT(cred->cr_label);
2766 	obj = SLOT(vplabel);
2767 
2768 	if (!mac_biba_dominate_effective(obj, subj))
2769 		return (EACCES);
2770 
2771 	return (0);
2772 }
2773 
2774 static int
2775 mac_biba_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
2776     struct label *dvplabel, struct componentname *cnp)
2777 {
2778 	struct mac_biba *subj, *obj;
2779 
2780 	if (!mac_biba_enabled)
2781 		return (0);
2782 
2783 	subj = SLOT(cred->cr_label);
2784 	obj = SLOT(dvplabel);
2785 
2786 	if (!mac_biba_dominate_effective(obj, subj))
2787 		return (EACCES);
2788 
2789 	return (0);
2790 }
2791 
2792 static int
2793 mac_biba_check_vnode_mmap(struct ucred *cred, struct vnode *vp,
2794     struct label *vplabel, int prot, int flags)
2795 {
2796 	struct mac_biba *subj, *obj;
2797 
2798 	/*
2799 	 * Rely on the use of open()-time protections to handle
2800 	 * non-revocation cases.
2801 	 */
2802 	if (!mac_biba_enabled || !revocation_enabled)
2803 		return (0);
2804 
2805 	subj = SLOT(cred->cr_label);
2806 	obj = SLOT(vplabel);
2807 
2808 	if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
2809 		if (!mac_biba_dominate_effective(obj, subj))
2810 			return (EACCES);
2811 	}
2812 	if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) {
2813 		if (!mac_biba_dominate_effective(subj, obj))
2814 			return (EACCES);
2815 	}
2816 
2817 	return (0);
2818 }
2819 
2820 static int
2821 mac_biba_check_vnode_open(struct ucred *cred, struct vnode *vp,
2822     struct label *vplabel, int acc_mode)
2823 {
2824 	struct mac_biba *subj, *obj;
2825 
2826 	if (!mac_biba_enabled)
2827 		return (0);
2828 
2829 	subj = SLOT(cred->cr_label);
2830 	obj = SLOT(vplabel);
2831 
2832 	/* XXX privilege override for admin? */
2833 	if (acc_mode & (VREAD | VEXEC | VSTAT)) {
2834 		if (!mac_biba_dominate_effective(obj, subj))
2835 			return (EACCES);
2836 	}
2837 	if (acc_mode & (VWRITE | VAPPEND | VADMIN)) {
2838 		if (!mac_biba_dominate_effective(subj, obj))
2839 			return (EACCES);
2840 	}
2841 
2842 	return (0);
2843 }
2844 
2845 static int
2846 mac_biba_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred,
2847     struct vnode *vp, struct label *vplabel)
2848 {
2849 	struct mac_biba *subj, *obj;
2850 
2851 	if (!mac_biba_enabled || !revocation_enabled)
2852 		return (0);
2853 
2854 	subj = SLOT(active_cred->cr_label);
2855 	obj = SLOT(vplabel);
2856 
2857 	if (!mac_biba_dominate_effective(obj, subj))
2858 		return (EACCES);
2859 
2860 	return (0);
2861 }
2862 
2863 static int
2864 mac_biba_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
2865     struct vnode *vp, struct label *vplabel)
2866 {
2867 	struct mac_biba *subj, *obj;
2868 
2869 	if (!mac_biba_enabled || !revocation_enabled)
2870 		return (0);
2871 
2872 	subj = SLOT(active_cred->cr_label);
2873 	obj = SLOT(vplabel);
2874 
2875 	if (!mac_biba_dominate_effective(obj, subj))
2876 		return (EACCES);
2877 
2878 	return (0);
2879 }
2880 
2881 static int
2882 mac_biba_check_vnode_readdir(struct ucred *cred, struct vnode *dvp,
2883     struct label *dvplabel)
2884 {
2885 	struct mac_biba *subj, *obj;
2886 
2887 	if (!mac_biba_enabled)
2888 		return (0);
2889 
2890 	subj = SLOT(cred->cr_label);
2891 	obj = SLOT(dvplabel);
2892 
2893 	if (!mac_biba_dominate_effective(obj, subj))
2894 		return (EACCES);
2895 
2896 	return (0);
2897 }
2898 
2899 static int
2900 mac_biba_check_vnode_readlink(struct ucred *cred, struct vnode *vp,
2901     struct label *vplabel)
2902 {
2903 	struct mac_biba *subj, *obj;
2904 
2905 	if (!mac_biba_enabled)
2906 		return (0);
2907 
2908 	subj = SLOT(cred->cr_label);
2909 	obj = SLOT(vplabel);
2910 
2911 	if (!mac_biba_dominate_effective(obj, subj))
2912 		return (EACCES);
2913 
2914 	return (0);
2915 }
2916 
2917 static int
2918 mac_biba_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
2919     struct label *vplabel, struct label *newlabel)
2920 {
2921 	struct mac_biba *old, *new, *subj;
2922 	int error;
2923 
2924 	old = SLOT(vplabel);
2925 	new = SLOT(newlabel);
2926 	subj = SLOT(cred->cr_label);
2927 
2928 	/*
2929 	 * If there is a Biba label update for the vnode, it must be a
2930 	 * effective label.
2931 	 */
2932 	error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE);
2933 	if (error)
2934 		return (error);
2935 
2936 	/*
2937 	 * To perform a relabel of the vnode (Biba label or not), Biba must
2938 	 * authorize the relabel.
2939 	 */
2940 	if (!mac_biba_effective_in_range(old, subj))
2941 		return (EPERM);
2942 
2943 	/*
2944 	 * If the Biba label is to be changed, authorize as appropriate.
2945 	 */
2946 	if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
2947 		/*
2948 		 * To change the Biba label on a vnode, the new vnode label
2949 		 * must be in the subject range.
2950 		 */
2951 		if (!mac_biba_effective_in_range(new, subj))
2952 			return (EPERM);
2953 
2954 		/*
2955 		 * To change the Biba label on the vnode to be EQUAL,
2956 		 * the subject must have appropriate privilege.
2957 		 */
2958 		if (mac_biba_contains_equal(new)) {
2959 			error = mac_biba_subject_privileged(subj);
2960 			if (error)
2961 				return (error);
2962 		}
2963 	}
2964 
2965 	return (0);
2966 }
2967 
2968 static int
2969 mac_biba_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
2970     struct label *dvplabel, struct vnode *vp, struct label *vplabel,
2971     struct componentname *cnp)
2972 {
2973 	struct mac_biba *subj, *obj;
2974 
2975 	if (!mac_biba_enabled)
2976 		return (0);
2977 
2978 	subj = SLOT(cred->cr_label);
2979 	obj = SLOT(dvplabel);
2980 
2981 	if (!mac_biba_dominate_effective(subj, obj))
2982 		return (EACCES);
2983 
2984 	obj = SLOT(vplabel);
2985 
2986 	if (!mac_biba_dominate_effective(subj, obj))
2987 		return (EACCES);
2988 
2989 	return (0);
2990 }
2991 
2992 static int
2993 mac_biba_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
2994     struct label *dvplabel, struct vnode *vp, struct label *vplabel,
2995     int samedir, struct componentname *cnp)
2996 {
2997 	struct mac_biba *subj, *obj;
2998 
2999 	if (!mac_biba_enabled)
3000 		return (0);
3001 
3002 	subj = SLOT(cred->cr_label);
3003 	obj = SLOT(dvplabel);
3004 
3005 	if (!mac_biba_dominate_effective(subj, obj))
3006 		return (EACCES);
3007 
3008 	if (vp != NULL) {
3009 		obj = SLOT(vplabel);
3010 
3011 		if (!mac_biba_dominate_effective(subj, obj))
3012 			return (EACCES);
3013 	}
3014 
3015 	return (0);
3016 }
3017 
3018 static int
3019 mac_biba_check_vnode_revoke(struct ucred *cred, struct vnode *vp,
3020     struct label *vplabel)
3021 {
3022 	struct mac_biba *subj, *obj;
3023 
3024 	if (!mac_biba_enabled)
3025 		return (0);
3026 
3027 	subj = SLOT(cred->cr_label);
3028 	obj = SLOT(vplabel);
3029 
3030 	if (!mac_biba_dominate_effective(subj, obj))
3031 		return (EACCES);
3032 
3033 	return (0);
3034 }
3035 
3036 static int
3037 mac_biba_check_vnode_setacl(struct ucred *cred, struct vnode *vp,
3038     struct label *vplabel, acl_type_t type, struct acl *acl)
3039 {
3040 	struct mac_biba *subj, *obj;
3041 
3042 	if (!mac_biba_enabled)
3043 		return (0);
3044 
3045 	subj = SLOT(cred->cr_label);
3046 	obj = SLOT(vplabel);
3047 
3048 	if (!mac_biba_dominate_effective(subj, obj))
3049 		return (EACCES);
3050 
3051 	return (0);
3052 }
3053 
3054 static int
3055 mac_biba_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
3056     struct label *vplabel, int attrnamespace, const char *name,
3057     struct uio *uio)
3058 {
3059 	struct mac_biba *subj, *obj;
3060 
3061 	if (!mac_biba_enabled)
3062 		return (0);
3063 
3064 	subj = SLOT(cred->cr_label);
3065 	obj = SLOT(vplabel);
3066 
3067 	if (!mac_biba_dominate_effective(subj, obj))
3068 		return (EACCES);
3069 
3070 	/* XXX: protect the MAC EA in a special way? */
3071 
3072 	return (0);
3073 }
3074 
3075 static int
3076 mac_biba_check_vnode_setflags(struct ucred *cred, struct vnode *vp,
3077     struct label *vplabel, u_long flags)
3078 {
3079 	struct mac_biba *subj, *obj;
3080 
3081 	if (!mac_biba_enabled)
3082 		return (0);
3083 
3084 	subj = SLOT(cred->cr_label);
3085 	obj = SLOT(vplabel);
3086 
3087 	if (!mac_biba_dominate_effective(subj, obj))
3088 		return (EACCES);
3089 
3090 	return (0);
3091 }
3092 
3093 static int
3094 mac_biba_check_vnode_setmode(struct ucred *cred, struct vnode *vp,
3095     struct label *vplabel, mode_t mode)
3096 {
3097 	struct mac_biba *subj, *obj;
3098 
3099 	if (!mac_biba_enabled)
3100 		return (0);
3101 
3102 	subj = SLOT(cred->cr_label);
3103 	obj = SLOT(vplabel);
3104 
3105 	if (!mac_biba_dominate_effective(subj, obj))
3106 		return (EACCES);
3107 
3108 	return (0);
3109 }
3110 
3111 static int
3112 mac_biba_check_vnode_setowner(struct ucred *cred, struct vnode *vp,
3113     struct label *vplabel, uid_t uid, gid_t gid)
3114 {
3115 	struct mac_biba *subj, *obj;
3116 
3117 	if (!mac_biba_enabled)
3118 		return (0);
3119 
3120 	subj = SLOT(cred->cr_label);
3121 	obj = SLOT(vplabel);
3122 
3123 	if (!mac_biba_dominate_effective(subj, obj))
3124 		return (EACCES);
3125 
3126 	return (0);
3127 }
3128 
3129 static int
3130 mac_biba_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
3131     struct label *vplabel, struct timespec atime, struct timespec mtime)
3132 {
3133 	struct mac_biba *subj, *obj;
3134 
3135 	if (!mac_biba_enabled)
3136 		return (0);
3137 
3138 	subj = SLOT(cred->cr_label);
3139 	obj = SLOT(vplabel);
3140 
3141 	if (!mac_biba_dominate_effective(subj, obj))
3142 		return (EACCES);
3143 
3144 	return (0);
3145 }
3146 
3147 static int
3148 mac_biba_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
3149     struct vnode *vp, struct label *vplabel)
3150 {
3151 	struct mac_biba *subj, *obj;
3152 
3153 	if (!mac_biba_enabled)
3154 		return (0);
3155 
3156 	subj = SLOT(active_cred->cr_label);
3157 	obj = SLOT(vplabel);
3158 
3159 	if (!mac_biba_dominate_effective(obj, subj))
3160 		return (EACCES);
3161 
3162 	return (0);
3163 }
3164 
3165 static int
3166 mac_biba_check_vnode_unlink(struct ucred *cred, struct vnode *dvp,
3167     struct label *dvplabel, struct vnode *vp, struct label *vplabel,
3168     struct componentname *cnp)
3169 {
3170 	struct mac_biba *subj, *obj;
3171 
3172 	if (!mac_biba_enabled)
3173 		return (0);
3174 
3175 	subj = SLOT(cred->cr_label);
3176 	obj = SLOT(dvplabel);
3177 
3178 	if (!mac_biba_dominate_effective(subj, obj))
3179 		return (EACCES);
3180 
3181 	obj = SLOT(vplabel);
3182 
3183 	if (!mac_biba_dominate_effective(subj, obj))
3184 		return (EACCES);
3185 
3186 	return (0);
3187 }
3188 
3189 static int
3190 mac_biba_check_vnode_write(struct ucred *active_cred,
3191     struct ucred *file_cred, struct vnode *vp, struct label *vplabel)
3192 {
3193 	struct mac_biba *subj, *obj;
3194 
3195 	if (!mac_biba_enabled || !revocation_enabled)
3196 		return (0);
3197 
3198 	subj = SLOT(active_cred->cr_label);
3199 	obj = SLOT(vplabel);
3200 
3201 	if (!mac_biba_dominate_effective(subj, obj))
3202 		return (EACCES);
3203 
3204 	return (0);
3205 }
3206 
3207 static void
3208 mac_biba_associate_nfsd_label(struct ucred *cred)
3209 {
3210 	struct mac_biba *label;
3211 
3212 	label = SLOT(cred->cr_label);
3213 	mac_biba_set_effective(label, MAC_BIBA_TYPE_LOW, 0, NULL);
3214 	mac_biba_set_range(label, MAC_BIBA_TYPE_LOW, 0, NULL,
3215 	    MAC_BIBA_TYPE_HIGH, 0, NULL);
3216 }
3217 
3218 static void
3219 mac_biba_init_syncache_from_inpcb(struct label *label, struct inpcb *inp)
3220 {
3221 	struct mac_biba *source, *dest;
3222 
3223 	source = SLOT(inp->inp_label);
3224 	dest = SLOT(label);
3225 	mac_biba_copy_effective(source, dest);
3226 }
3227 
3228 static void
3229 mac_biba_create_mbuf_from_syncache(struct label *sc_label, struct mbuf *m,
3230     struct label *mlabel)
3231 {
3232 	struct mac_biba *source, *dest;
3233 
3234 	source = SLOT(sc_label);
3235 	dest = SLOT(mlabel);
3236 	mac_biba_copy_effective(source, dest);
3237 }
3238 
3239 static struct mac_policy_ops mac_biba_ops =
3240 {
3241 	.mpo_init = mac_biba_init,
3242 	.mpo_init_bpfdesc_label = mac_biba_init_label,
3243 	.mpo_init_cred_label = mac_biba_init_label,
3244 	.mpo_init_devfs_label = mac_biba_init_label,
3245 	.mpo_init_ifnet_label = mac_biba_init_label,
3246 	.mpo_init_inpcb_label = mac_biba_init_label_waitcheck,
3247 	.mpo_init_syncache_label = mac_biba_init_label_waitcheck,
3248 	.mpo_init_sysv_msgmsg_label = mac_biba_init_label,
3249 	.mpo_init_sysv_msgqueue_label = mac_biba_init_label,
3250 	.mpo_init_sysv_sem_label = mac_biba_init_label,
3251 	.mpo_init_sysv_shm_label = mac_biba_init_label,
3252 	.mpo_init_ipq_label = mac_biba_init_label_waitcheck,
3253 	.mpo_init_mbuf_label = mac_biba_init_label_waitcheck,
3254 	.mpo_init_mount_label = mac_biba_init_label,
3255 	.mpo_init_pipe_label = mac_biba_init_label,
3256 	.mpo_init_posix_sem_label = mac_biba_init_label,
3257 	.mpo_init_socket_label = mac_biba_init_label_waitcheck,
3258 	.mpo_init_socket_peer_label = mac_biba_init_label_waitcheck,
3259 	.mpo_init_syncache_from_inpcb = mac_biba_init_syncache_from_inpcb,
3260 	.mpo_init_vnode_label = mac_biba_init_label,
3261 	.mpo_destroy_bpfdesc_label = mac_biba_destroy_label,
3262 	.mpo_destroy_cred_label = mac_biba_destroy_label,
3263 	.mpo_destroy_devfs_label = mac_biba_destroy_label,
3264 	.mpo_destroy_ifnet_label = mac_biba_destroy_label,
3265 	.mpo_destroy_inpcb_label = mac_biba_destroy_label,
3266 	.mpo_destroy_syncache_label = mac_biba_destroy_label,
3267 	.mpo_destroy_sysv_msgmsg_label = mac_biba_destroy_label,
3268 	.mpo_destroy_sysv_msgqueue_label = mac_biba_destroy_label,
3269 	.mpo_destroy_sysv_sem_label = mac_biba_destroy_label,
3270 	.mpo_destroy_sysv_shm_label = mac_biba_destroy_label,
3271 	.mpo_destroy_ipq_label = mac_biba_destroy_label,
3272 	.mpo_destroy_mbuf_label = mac_biba_destroy_label,
3273 	.mpo_destroy_mount_label = mac_biba_destroy_label,
3274 	.mpo_destroy_pipe_label = mac_biba_destroy_label,
3275 	.mpo_destroy_posix_sem_label = mac_biba_destroy_label,
3276 	.mpo_destroy_socket_label = mac_biba_destroy_label,
3277 	.mpo_destroy_socket_peer_label = mac_biba_destroy_label,
3278 	.mpo_destroy_vnode_label = mac_biba_destroy_label,
3279 	.mpo_copy_cred_label = mac_biba_copy_label,
3280 	.mpo_copy_ifnet_label = mac_biba_copy_label,
3281 	.mpo_copy_mbuf_label = mac_biba_copy_label,
3282 	.mpo_copy_pipe_label = mac_biba_copy_label,
3283 	.mpo_copy_socket_label = mac_biba_copy_label,
3284 	.mpo_copy_vnode_label = mac_biba_copy_label,
3285 	.mpo_externalize_cred_label = mac_biba_externalize_label,
3286 	.mpo_externalize_ifnet_label = mac_biba_externalize_label,
3287 	.mpo_externalize_pipe_label = mac_biba_externalize_label,
3288 	.mpo_externalize_socket_label = mac_biba_externalize_label,
3289 	.mpo_externalize_socket_peer_label = mac_biba_externalize_label,
3290 	.mpo_externalize_vnode_label = mac_biba_externalize_label,
3291 	.mpo_internalize_cred_label = mac_biba_internalize_label,
3292 	.mpo_internalize_ifnet_label = mac_biba_internalize_label,
3293 	.mpo_internalize_pipe_label = mac_biba_internalize_label,
3294 	.mpo_internalize_socket_label = mac_biba_internalize_label,
3295 	.mpo_internalize_vnode_label = mac_biba_internalize_label,
3296 	.mpo_create_devfs_device = mac_biba_create_devfs_device,
3297 	.mpo_create_devfs_directory = mac_biba_create_devfs_directory,
3298 	.mpo_create_devfs_symlink = mac_biba_create_devfs_symlink,
3299 	.mpo_create_mount = mac_biba_create_mount,
3300 	.mpo_relabel_vnode = mac_biba_relabel_vnode,
3301 	.mpo_update_devfs = mac_biba_update_devfs,
3302 	.mpo_associate_vnode_devfs = mac_biba_associate_vnode_devfs,
3303 	.mpo_associate_vnode_extattr = mac_biba_associate_vnode_extattr,
3304 	.mpo_associate_vnode_singlelabel = mac_biba_associate_vnode_singlelabel,
3305 	.mpo_create_vnode_extattr = mac_biba_create_vnode_extattr,
3306 	.mpo_setlabel_vnode_extattr = mac_biba_setlabel_vnode_extattr,
3307 	.mpo_create_mbuf_from_socket = mac_biba_create_mbuf_from_socket,
3308 	.mpo_create_mbuf_from_syncache = mac_biba_create_mbuf_from_syncache,
3309 	.mpo_create_pipe = mac_biba_create_pipe,
3310 	.mpo_create_posix_sem = mac_biba_create_posix_sem,
3311 	.mpo_create_socket = mac_biba_create_socket,
3312 	.mpo_create_socket_from_socket = mac_biba_create_socket_from_socket,
3313 	.mpo_relabel_pipe = mac_biba_relabel_pipe,
3314 	.mpo_relabel_socket = mac_biba_relabel_socket,
3315 	.mpo_set_socket_peer_from_mbuf = mac_biba_set_socket_peer_from_mbuf,
3316 	.mpo_set_socket_peer_from_socket = mac_biba_set_socket_peer_from_socket,
3317 	.mpo_create_bpfdesc = mac_biba_create_bpfdesc,
3318 	.mpo_create_datagram_from_ipq = mac_biba_create_datagram_from_ipq,
3319 	.mpo_create_fragment = mac_biba_create_fragment,
3320 	.mpo_create_ifnet = mac_biba_create_ifnet,
3321 	.mpo_create_inpcb_from_socket = mac_biba_create_inpcb_from_socket,
3322 	.mpo_create_sysv_msgmsg = mac_biba_create_sysv_msgmsg,
3323 	.mpo_create_sysv_msgqueue = mac_biba_create_sysv_msgqueue,
3324 	.mpo_create_sysv_sem = mac_biba_create_sysv_sem,
3325 	.mpo_create_sysv_shm = mac_biba_create_sysv_shm,
3326 	.mpo_create_ipq = mac_biba_create_ipq,
3327 	.mpo_create_mbuf_from_inpcb = mac_biba_create_mbuf_from_inpcb,
3328 	.mpo_create_mbuf_linklayer = mac_biba_create_mbuf_linklayer,
3329 	.mpo_create_mbuf_from_bpfdesc = mac_biba_create_mbuf_from_bpfdesc,
3330 	.mpo_create_mbuf_from_ifnet = mac_biba_create_mbuf_from_ifnet,
3331 	.mpo_create_mbuf_multicast_encap = mac_biba_create_mbuf_multicast_encap,
3332 	.mpo_create_mbuf_netlayer = mac_biba_create_mbuf_netlayer,
3333 	.mpo_fragment_match = mac_biba_fragment_match,
3334 	.mpo_relabel_ifnet = mac_biba_relabel_ifnet,
3335 	.mpo_update_ipq = mac_biba_update_ipq,
3336 	.mpo_inpcb_sosetlabel = mac_biba_inpcb_sosetlabel,
3337 	.mpo_create_proc0 = mac_biba_create_proc0,
3338 	.mpo_create_proc1 = mac_biba_create_proc1,
3339 	.mpo_relabel_cred = mac_biba_relabel_cred,
3340 	.mpo_cleanup_sysv_msgmsg = mac_biba_cleanup_sysv_msgmsg,
3341 	.mpo_cleanup_sysv_msgqueue = mac_biba_cleanup_sysv_msgqueue,
3342 	.mpo_cleanup_sysv_sem = mac_biba_cleanup_sysv_sem,
3343 	.mpo_cleanup_sysv_shm = mac_biba_cleanup_sysv_shm,
3344 	.mpo_check_bpfdesc_receive = mac_biba_check_bpfdesc_receive,
3345 	.mpo_check_cred_relabel = mac_biba_check_cred_relabel,
3346 	.mpo_check_cred_visible = mac_biba_check_cred_visible,
3347 	.mpo_check_ifnet_relabel = mac_biba_check_ifnet_relabel,
3348 	.mpo_check_ifnet_transmit = mac_biba_check_ifnet_transmit,
3349 	.mpo_check_inpcb_deliver = mac_biba_check_inpcb_deliver,
3350 	.mpo_check_sysv_msgrcv = mac_biba_check_sysv_msgrcv,
3351 	.mpo_check_sysv_msgrmid = mac_biba_check_sysv_msgrmid,
3352 	.mpo_check_sysv_msqget = mac_biba_check_sysv_msqget,
3353 	.mpo_check_sysv_msqsnd = mac_biba_check_sysv_msqsnd,
3354 	.mpo_check_sysv_msqrcv = mac_biba_check_sysv_msqrcv,
3355 	.mpo_check_sysv_msqctl = mac_biba_check_sysv_msqctl,
3356 	.mpo_check_sysv_semctl = mac_biba_check_sysv_semctl,
3357 	.mpo_check_sysv_semget = mac_biba_check_sysv_semget,
3358 	.mpo_check_sysv_semop = mac_biba_check_sysv_semop,
3359 	.mpo_check_sysv_shmat = mac_biba_check_sysv_shmat,
3360 	.mpo_check_sysv_shmctl = mac_biba_check_sysv_shmctl,
3361 	.mpo_check_sysv_shmget = mac_biba_check_sysv_shmget,
3362 	.mpo_check_kld_load = mac_biba_check_kld_load,
3363 	.mpo_check_mount_stat = mac_biba_check_mount_stat,
3364 	.mpo_check_pipe_ioctl = mac_biba_check_pipe_ioctl,
3365 	.mpo_check_pipe_poll = mac_biba_check_pipe_poll,
3366 	.mpo_check_pipe_read = mac_biba_check_pipe_read,
3367 	.mpo_check_pipe_relabel = mac_biba_check_pipe_relabel,
3368 	.mpo_check_pipe_stat = mac_biba_check_pipe_stat,
3369 	.mpo_check_pipe_write = mac_biba_check_pipe_write,
3370 	.mpo_check_posix_sem_destroy = mac_biba_check_posix_sem_write,
3371 	.mpo_check_posix_sem_getvalue = mac_biba_check_posix_sem_rdonly,
3372 	.mpo_check_posix_sem_open = mac_biba_check_posix_sem_write,
3373 	.mpo_check_posix_sem_post = mac_biba_check_posix_sem_write,
3374 	.mpo_check_posix_sem_unlink = mac_biba_check_posix_sem_write,
3375 	.mpo_check_posix_sem_wait = mac_biba_check_posix_sem_write,
3376 	.mpo_check_proc_debug = mac_biba_check_proc_debug,
3377 	.mpo_check_proc_sched = mac_biba_check_proc_sched,
3378 	.mpo_check_proc_signal = mac_biba_check_proc_signal,
3379 	.mpo_check_socket_deliver = mac_biba_check_socket_deliver,
3380 	.mpo_check_socket_relabel = mac_biba_check_socket_relabel,
3381 	.mpo_check_socket_visible = mac_biba_check_socket_visible,
3382 	.mpo_check_system_acct = mac_biba_check_system_acct,
3383 	.mpo_check_system_auditctl = mac_biba_check_system_auditctl,
3384 	.mpo_check_system_auditon = mac_biba_check_system_auditon,
3385 	.mpo_check_system_swapon = mac_biba_check_system_swapon,
3386 	.mpo_check_system_swapoff = mac_biba_check_system_swapoff,
3387 	.mpo_check_system_sysctl = mac_biba_check_system_sysctl,
3388 	.mpo_check_vnode_access = mac_biba_check_vnode_open,
3389 	.mpo_check_vnode_chdir = mac_biba_check_vnode_chdir,
3390 	.mpo_check_vnode_chroot = mac_biba_check_vnode_chroot,
3391 	.mpo_check_vnode_create = mac_biba_check_vnode_create,
3392 	.mpo_check_vnode_deleteacl = mac_biba_check_vnode_deleteacl,
3393 	.mpo_check_vnode_deleteextattr = mac_biba_check_vnode_deleteextattr,
3394 	.mpo_check_vnode_exec = mac_biba_check_vnode_exec,
3395 	.mpo_check_vnode_getacl = mac_biba_check_vnode_getacl,
3396 	.mpo_check_vnode_getextattr = mac_biba_check_vnode_getextattr,
3397 	.mpo_check_vnode_link = mac_biba_check_vnode_link,
3398 	.mpo_check_vnode_listextattr = mac_biba_check_vnode_listextattr,
3399 	.mpo_check_vnode_lookup = mac_biba_check_vnode_lookup,
3400 	.mpo_check_vnode_mmap = mac_biba_check_vnode_mmap,
3401 	.mpo_check_vnode_open = mac_biba_check_vnode_open,
3402 	.mpo_check_vnode_poll = mac_biba_check_vnode_poll,
3403 	.mpo_check_vnode_read = mac_biba_check_vnode_read,
3404 	.mpo_check_vnode_readdir = mac_biba_check_vnode_readdir,
3405 	.mpo_check_vnode_readlink = mac_biba_check_vnode_readlink,
3406 	.mpo_check_vnode_relabel = mac_biba_check_vnode_relabel,
3407 	.mpo_check_vnode_rename_from = mac_biba_check_vnode_rename_from,
3408 	.mpo_check_vnode_rename_to = mac_biba_check_vnode_rename_to,
3409 	.mpo_check_vnode_revoke = mac_biba_check_vnode_revoke,
3410 	.mpo_check_vnode_setacl = mac_biba_check_vnode_setacl,
3411 	.mpo_check_vnode_setextattr = mac_biba_check_vnode_setextattr,
3412 	.mpo_check_vnode_setflags = mac_biba_check_vnode_setflags,
3413 	.mpo_check_vnode_setmode = mac_biba_check_vnode_setmode,
3414 	.mpo_check_vnode_setowner = mac_biba_check_vnode_setowner,
3415 	.mpo_check_vnode_setutimes = mac_biba_check_vnode_setutimes,
3416 	.mpo_check_vnode_stat = mac_biba_check_vnode_stat,
3417 	.mpo_check_vnode_unlink = mac_biba_check_vnode_unlink,
3418 	.mpo_check_vnode_write = mac_biba_check_vnode_write,
3419 	.mpo_associate_nfsd_label = mac_biba_associate_nfsd_label,
3420 	.mpo_create_mbuf_from_firewall = mac_biba_create_mbuf_from_firewall,
3421 	.mpo_priv_check = mac_biba_priv_check,
3422 };
3423 
3424 MAC_POLICY_SET(&mac_biba_ops, mac_biba, "TrustedBSD MAC/Biba",
3425     MPC_LOADTIME_FLAG_NOTLATE | MPC_LOADTIME_FLAG_LABELMBUFS, &mac_biba_slot);
3426