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