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