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