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