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