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