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