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