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