mac_biba.c revision 153927
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 153927 2005-12-31 05:06:59Z 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
1384/*
1385 * Labeling event operations: processes.
1386 */
1387static void
1388mac_biba_create_proc0(struct ucred *cred)
1389{
1390	struct mac_biba *dest;
1391
1392	dest = SLOT(cred->cr_label);
1393
1394	mac_biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1395	mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL,
1396	    MAC_BIBA_TYPE_HIGH, 0, NULL);
1397}
1398
1399static void
1400mac_biba_create_proc1(struct ucred *cred)
1401{
1402	struct mac_biba *dest;
1403
1404	dest = SLOT(cred->cr_label);
1405
1406	mac_biba_set_effective(dest, MAC_BIBA_TYPE_HIGH, 0, NULL);
1407	mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL,
1408	    MAC_BIBA_TYPE_HIGH, 0, NULL);
1409}
1410
1411static void
1412mac_biba_relabel_cred(struct ucred *cred, struct label *newlabel)
1413{
1414	struct mac_biba *source, *dest;
1415
1416	source = SLOT(newlabel);
1417	dest = SLOT(cred->cr_label);
1418
1419	mac_biba_copy(source, dest);
1420}
1421
1422/*
1423 * Label cleanup/flush operations
1424 */
1425static void
1426mac_biba_cleanup_sysv_msgmsg(struct label *msglabel)
1427{
1428
1429	bzero(SLOT(msglabel), sizeof(struct mac_biba));
1430}
1431
1432static void
1433mac_biba_cleanup_sysv_msgqueue(struct label *msqlabel)
1434{
1435
1436	bzero(SLOT(msqlabel), sizeof(struct mac_biba));
1437}
1438
1439static void
1440mac_biba_cleanup_sysv_sem(struct label *semalabel)
1441{
1442
1443	bzero(SLOT(semalabel), sizeof(struct mac_biba));
1444}
1445
1446static void
1447mac_biba_cleanup_sysv_shm(struct label *shmlabel)
1448{
1449	bzero(SLOT(shmlabel), sizeof(struct mac_biba));
1450}
1451
1452/*
1453 * Access control checks.
1454 */
1455static int
1456mac_biba_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel,
1457    struct ifnet *ifnet, struct label *ifnetlabel)
1458{
1459	struct mac_biba *a, *b;
1460
1461	if (!mac_biba_enabled)
1462		return (0);
1463
1464	a = SLOT(bpflabel);
1465	b = SLOT(ifnetlabel);
1466
1467	if (mac_biba_equal_effective(a, b))
1468		return (0);
1469	return (EACCES);
1470}
1471
1472static int
1473mac_biba_check_cred_relabel(struct ucred *cred, struct label *newlabel)
1474{
1475	struct mac_biba *subj, *new;
1476	int error;
1477
1478	subj = SLOT(cred->cr_label);
1479	new = SLOT(newlabel);
1480
1481	/*
1482	 * If there is a Biba label update for the credential, it may
1483	 * be an update of the effective, range, or both.
1484	 */
1485	error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
1486	if (error)
1487		return (error);
1488
1489	/*
1490	 * If the Biba label is to be changed, authorize as appropriate.
1491	 */
1492	if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) {
1493		/*
1494		 * If the change request modifies both the Biba label
1495		 * effective and range, check that the new effective will be
1496		 * in the new range.
1497		 */
1498		if ((new->mb_flags & MAC_BIBA_FLAGS_BOTH) ==
1499		    MAC_BIBA_FLAGS_BOTH &&
1500		    !mac_biba_effective_in_range(new, new))
1501			return (EINVAL);
1502
1503		/*
1504		 * To change the Biba effective label on a credential, the
1505		 * new effective label must be in the current range.
1506		 */
1507		if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE &&
1508		    !mac_biba_effective_in_range(new, subj))
1509			return (EPERM);
1510
1511		/*
1512		 * To change the Biba range on a credential, the new
1513		 * range label must be in the current range.
1514		 */
1515		if (new->mb_flags & MAC_BIBA_FLAG_RANGE &&
1516		    !mac_biba_range_in_range(new, subj))
1517			return (EPERM);
1518
1519		/*
1520		 * To have EQUAL in any component of the new credential
1521		 * Biba label, the subject must already have EQUAL in
1522		 * their label.
1523		 */
1524		if (mac_biba_contains_equal(new)) {
1525			error = mac_biba_subject_privileged(subj);
1526			if (error)
1527				return (error);
1528		}
1529	}
1530
1531	return (0);
1532}
1533
1534static int
1535mac_biba_check_cred_visible(struct ucred *u1, struct ucred *u2)
1536{
1537	struct mac_biba *subj, *obj;
1538
1539	if (!mac_biba_enabled)
1540		return (0);
1541
1542	subj = SLOT(u1->cr_label);
1543	obj = SLOT(u2->cr_label);
1544
1545	/* XXX: range */
1546	if (!mac_biba_dominate_effective(obj, subj))
1547		return (ESRCH);
1548
1549	return (0);
1550}
1551
1552static int
1553mac_biba_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet,
1554    struct label *ifnetlabel, struct label *newlabel)
1555{
1556	struct mac_biba *subj, *new;
1557	int error;
1558
1559	subj = SLOT(cred->cr_label);
1560	new = SLOT(newlabel);
1561
1562	/*
1563	 * If there is a Biba label update for the interface, it may
1564	 * be an update of the effective, range, or both.
1565	 */
1566	error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
1567	if (error)
1568		return (error);
1569
1570	/*
1571	 * Relabling network interfaces requires Biba privilege.
1572	 */
1573	error = mac_biba_subject_privileged(subj);
1574	if (error)
1575		return (error);
1576
1577	return (0);
1578}
1579
1580static int
1581mac_biba_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel,
1582    struct mbuf *m, struct label *mbuflabel)
1583{
1584	struct mac_biba *p, *i;
1585
1586	if (!mac_biba_enabled)
1587		return (0);
1588
1589	p = SLOT(mbuflabel);
1590	i = SLOT(ifnetlabel);
1591
1592	return (mac_biba_effective_in_range(p, i) ? 0 : EACCES);
1593}
1594
1595static int
1596mac_biba_check_inpcb_deliver(struct inpcb *inp, struct label *inplabel,
1597    struct mbuf *m, struct label *mlabel)
1598{
1599	struct mac_biba *p, *i;
1600
1601	if (!mac_biba_enabled)
1602		return (0);
1603
1604	p = SLOT(mlabel);
1605	i = SLOT(inplabel);
1606
1607	return (mac_biba_equal_effective(p, i) ? 0 : EACCES);
1608}
1609
1610static int
1611mac_biba_check_sysv_msgrcv(struct ucred *cred, struct msg *msgptr,
1612    struct label *msglabel)
1613{
1614	struct mac_biba *subj, *obj;
1615
1616	if (!mac_biba_enabled)
1617		return (0);
1618
1619	subj = SLOT(cred->cr_label);
1620	obj = SLOT(msglabel);
1621
1622	if (!mac_biba_dominate_effective(obj, subj))
1623		return (EACCES);
1624
1625	return (0);
1626}
1627
1628static int
1629mac_biba_check_sysv_msgrmid(struct ucred *cred, struct msg *msgptr,
1630    struct label *msglabel)
1631{
1632	struct mac_biba *subj, *obj;
1633
1634	if (!mac_biba_enabled)
1635		return (0);
1636
1637	subj = SLOT(cred->cr_label);
1638	obj = SLOT(msglabel);
1639
1640	if (!mac_biba_dominate_effective(subj, obj))
1641		return (EACCES);
1642
1643	return (0);
1644}
1645
1646static int
1647mac_biba_check_sysv_msqget(struct ucred *cred, struct msqid_kernel *msqkptr,
1648    struct label *msqklabel)
1649{
1650	struct mac_biba *subj, *obj;
1651
1652	if (!mac_biba_enabled)
1653		return (0);
1654
1655	subj = SLOT(cred->cr_label);
1656	obj = SLOT(msqklabel);
1657
1658	if (!mac_biba_dominate_effective(obj, subj))
1659		return (EACCES);
1660
1661	return (0);
1662}
1663
1664static int
1665mac_biba_check_sysv_msqsnd(struct ucred *cred, struct msqid_kernel *msqkptr,
1666    struct label *msqklabel)
1667{
1668	struct mac_biba *subj, *obj;
1669
1670	if (!mac_biba_enabled)
1671		return (0);
1672
1673	subj = SLOT(cred->cr_label);
1674	obj = SLOT(msqklabel);
1675
1676	if (!mac_biba_dominate_effective(subj, obj))
1677		return (EACCES);
1678
1679	return (0);
1680}
1681
1682static int
1683mac_biba_check_sysv_msqrcv(struct ucred *cred, struct msqid_kernel *msqkptr,
1684    struct label *msqklabel)
1685{
1686	struct mac_biba *subj, *obj;
1687
1688	if (!mac_biba_enabled)
1689		return (0);
1690
1691	subj = SLOT(cred->cr_label);
1692	obj = SLOT(msqklabel);
1693
1694	if (!mac_biba_dominate_effective(obj, subj))
1695		return (EACCES);
1696
1697	return (0);
1698}
1699
1700
1701static int
1702mac_biba_check_sysv_msqctl(struct ucred *cred, struct msqid_kernel *msqkptr,
1703    struct label *msqklabel, int cmd)
1704{
1705	struct mac_biba *subj, *obj;
1706
1707	if (!mac_biba_enabled)
1708		return (0);
1709
1710	subj = SLOT(cred->cr_label);
1711	obj = SLOT(msqklabel);
1712
1713	switch(cmd) {
1714	case IPC_RMID:
1715	case IPC_SET:
1716		if (!mac_biba_dominate_effective(subj, obj))
1717			return (EACCES);
1718		break;
1719
1720	case IPC_STAT:
1721		if (!mac_biba_dominate_effective(obj, subj))
1722			return (EACCES);
1723		break;
1724
1725	default:
1726		return (EACCES);
1727	}
1728
1729	return (0);
1730}
1731
1732static int
1733mac_biba_check_sysv_semctl(struct ucred *cred, struct semid_kernel *semakptr,
1734    struct label *semaklabel, int cmd)
1735{
1736	struct mac_biba *subj, *obj;
1737
1738	if (!mac_biba_enabled)
1739		return (0);
1740
1741	subj = SLOT(cred->cr_label);
1742	obj = SLOT(semaklabel);
1743
1744	switch(cmd) {
1745	case IPC_RMID:
1746	case IPC_SET:
1747	case SETVAL:
1748	case SETALL:
1749		if (!mac_biba_dominate_effective(subj, obj))
1750			return (EACCES);
1751		break;
1752
1753	case IPC_STAT:
1754	case GETVAL:
1755	case GETPID:
1756	case GETNCNT:
1757	case GETZCNT:
1758	case GETALL:
1759		if (!mac_biba_dominate_effective(obj, subj))
1760			return (EACCES);
1761		break;
1762
1763	default:
1764		return (EACCES);
1765	}
1766
1767	return (0);
1768}
1769
1770
1771static int
1772mac_biba_check_sysv_semget(struct ucred *cred, struct semid_kernel *semakptr,
1773    struct label *semaklabel)
1774{
1775	struct mac_biba *subj, *obj;
1776
1777	if (!mac_biba_enabled)
1778		return (0);
1779
1780	subj = SLOT(cred->cr_label);
1781	obj = SLOT(semaklabel);
1782
1783	if (!mac_biba_dominate_effective(obj, subj))
1784		return (EACCES);
1785
1786	return (0);
1787}
1788
1789
1790static int
1791mac_biba_check_sysv_semop(struct ucred *cred, struct semid_kernel *semakptr,
1792    struct label *semaklabel, size_t accesstype)
1793{
1794	struct mac_biba *subj, *obj;
1795
1796	if (!mac_biba_enabled)
1797		return (0);
1798
1799	subj = SLOT(cred->cr_label);
1800	obj = SLOT(semaklabel);
1801
1802	if (accesstype & SEM_R)
1803		if (!mac_biba_dominate_effective(obj, subj))
1804			return (EACCES);
1805
1806	if (accesstype & SEM_A)
1807		if (!mac_biba_dominate_effective(subj, obj))
1808			return (EACCES);
1809
1810	return (0);
1811}
1812
1813static int
1814mac_biba_check_sysv_shmat(struct ucred *cred, struct shmid_kernel *shmsegptr,
1815    struct label *shmseglabel, int shmflg)
1816{
1817	struct mac_biba *subj, *obj;
1818
1819	if (!mac_biba_enabled)
1820		return (0);
1821
1822	subj = SLOT(cred->cr_label);
1823	obj = SLOT(shmseglabel);
1824
1825	if (!mac_biba_dominate_effective(obj, subj))
1826		return (EACCES);
1827	if ((shmflg & SHM_RDONLY) == 0) {
1828		if (!mac_biba_dominate_effective(subj, obj))
1829			return (EACCES);
1830	}
1831
1832	return (0);
1833}
1834
1835static int
1836mac_biba_check_sysv_shmctl(struct ucred *cred, struct shmid_kernel *shmsegptr,
1837    struct label *shmseglabel, int cmd)
1838{
1839	struct mac_biba *subj, *obj;
1840
1841	if (!mac_biba_enabled)
1842		return (0);
1843
1844	subj = SLOT(cred->cr_label);
1845	obj = SLOT(shmseglabel);
1846
1847	switch(cmd) {
1848	case IPC_RMID:
1849	case IPC_SET:
1850		if (!mac_biba_dominate_effective(subj, obj))
1851			return (EACCES);
1852		break;
1853
1854	case IPC_STAT:
1855	case SHM_STAT:
1856		if (!mac_biba_dominate_effective(obj, subj))
1857			return (EACCES);
1858		break;
1859
1860	default:
1861		return (EACCES);
1862	}
1863
1864	return (0);
1865}
1866
1867static int
1868mac_biba_check_sysv_shmget(struct ucred *cred, struct shmid_kernel *shmsegptr,
1869    struct label *shmseglabel, int shmflg)
1870{
1871	struct mac_biba *subj, *obj;
1872
1873	if (!mac_biba_enabled)
1874		return (0);
1875
1876	subj = SLOT(cred->cr_label);
1877	obj = SLOT(shmseglabel);
1878
1879	if (!mac_biba_dominate_effective(obj, subj))
1880		return (EACCES);
1881
1882	return (0);
1883}
1884
1885static int
1886mac_biba_check_kld_load(struct ucred *cred, struct vnode *vp,
1887    struct label *label)
1888{
1889	struct mac_biba *subj, *obj;
1890	int error;
1891
1892	if (!mac_biba_enabled)
1893		return (0);
1894
1895	subj = SLOT(cred->cr_label);
1896
1897	error = mac_biba_subject_privileged(subj);
1898	if (error)
1899		return (error);
1900
1901	obj = SLOT(label);
1902	if (!mac_biba_high_effective(obj))
1903		return (EACCES);
1904
1905	return (0);
1906}
1907
1908
1909static int
1910mac_biba_check_kld_unload(struct ucred *cred)
1911{
1912	struct mac_biba *subj;
1913
1914	if (!mac_biba_enabled)
1915		return (0);
1916
1917	subj = SLOT(cred->cr_label);
1918
1919	return (mac_biba_subject_privileged(subj));
1920}
1921
1922static int
1923mac_biba_check_mount_stat(struct ucred *cred, struct mount *mp,
1924    struct label *mntlabel)
1925{
1926	struct mac_biba *subj, *obj;
1927
1928	if (!mac_biba_enabled)
1929		return (0);
1930
1931	subj = SLOT(cred->cr_label);
1932	obj = SLOT(mntlabel);
1933
1934	if (!mac_biba_dominate_effective(obj, subj))
1935		return (EACCES);
1936
1937	return (0);
1938}
1939
1940static int
1941mac_biba_check_pipe_ioctl(struct ucred *cred, struct pipepair *pp,
1942    struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data)
1943{
1944
1945	if(!mac_biba_enabled)
1946		return (0);
1947
1948	/* XXX: This will be implemented soon... */
1949
1950	return (0);
1951}
1952
1953static int
1954mac_biba_check_pipe_poll(struct ucred *cred, struct pipepair *pp,
1955    struct label *pipelabel)
1956{
1957	struct mac_biba *subj, *obj;
1958
1959	if (!mac_biba_enabled)
1960		return (0);
1961
1962	subj = SLOT(cred->cr_label);
1963	obj = SLOT((pipelabel));
1964
1965	if (!mac_biba_dominate_effective(obj, subj))
1966		return (EACCES);
1967
1968	return (0);
1969}
1970
1971static int
1972mac_biba_check_pipe_read(struct ucred *cred, struct pipepair *pp,
1973    struct label *pipelabel)
1974{
1975	struct mac_biba *subj, *obj;
1976
1977	if (!mac_biba_enabled)
1978		return (0);
1979
1980	subj = SLOT(cred->cr_label);
1981	obj = SLOT((pipelabel));
1982
1983	if (!mac_biba_dominate_effective(obj, subj))
1984		return (EACCES);
1985
1986	return (0);
1987}
1988
1989static int
1990mac_biba_check_pipe_relabel(struct ucred *cred, struct pipepair *pp,
1991    struct label *pipelabel, struct label *newlabel)
1992{
1993	struct mac_biba *subj, *obj, *new;
1994	int error;
1995
1996	new = SLOT(newlabel);
1997	subj = SLOT(cred->cr_label);
1998	obj = SLOT(pipelabel);
1999
2000	/*
2001	 * If there is a Biba label update for a pipe, it must be a
2002	 * effective update.
2003	 */
2004	error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE);
2005	if (error)
2006		return (error);
2007
2008	/*
2009	 * To perform a relabel of a pipe (Biba label or not), Biba must
2010	 * authorize the relabel.
2011	 */
2012	if (!mac_biba_effective_in_range(obj, subj))
2013		return (EPERM);
2014
2015	/*
2016	 * If the Biba label is to be changed, authorize as appropriate.
2017	 */
2018	if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
2019		/*
2020		 * To change the Biba label on a pipe, the new pipe label
2021		 * must be in the subject range.
2022		 */
2023		if (!mac_biba_effective_in_range(new, subj))
2024			return (EPERM);
2025
2026		/*
2027		 * To change the Biba label on a pipe to be EQUAL, the
2028		 * subject must have appropriate privilege.
2029		 */
2030		if (mac_biba_contains_equal(new)) {
2031			error = mac_biba_subject_privileged(subj);
2032			if (error)
2033				return (error);
2034		}
2035	}
2036
2037	return (0);
2038}
2039
2040static int
2041mac_biba_check_pipe_stat(struct ucred *cred, struct pipepair *pp,
2042    struct label *pipelabel)
2043{
2044	struct mac_biba *subj, *obj;
2045
2046	if (!mac_biba_enabled)
2047		return (0);
2048
2049	subj = SLOT(cred->cr_label);
2050	obj = SLOT((pipelabel));
2051
2052	if (!mac_biba_dominate_effective(obj, subj))
2053		return (EACCES);
2054
2055	return (0);
2056}
2057
2058static int
2059mac_biba_check_pipe_write(struct ucred *cred, struct pipepair *pp,
2060    struct label *pipelabel)
2061{
2062	struct mac_biba *subj, *obj;
2063
2064	if (!mac_biba_enabled)
2065		return (0);
2066
2067	subj = SLOT(cred->cr_label);
2068	obj = SLOT((pipelabel));
2069
2070	if (!mac_biba_dominate_effective(subj, obj))
2071		return (EACCES);
2072
2073	return (0);
2074}
2075
2076static int
2077mac_biba_check_posix_sem_write(struct ucred *cred, struct ksem *ksemptr,
2078    struct label *ks_label)
2079{
2080	struct mac_biba *subj, *obj;
2081
2082	if (!mac_biba_enabled)
2083		return (0);
2084
2085	subj = SLOT(cred->cr_label);
2086	obj = SLOT(ks_label);
2087
2088	if (!mac_biba_dominate_effective(subj, obj))
2089		return (EACCES);
2090
2091	return (0);
2092}
2093
2094static int
2095mac_biba_check_posix_sem_rdonly(struct ucred *cred, struct ksem *ksemptr,
2096    struct label *ks_label)
2097{
2098	struct mac_biba *subj, *obj;
2099
2100	if (!mac_biba_enabled)
2101		return (0);
2102
2103	subj = SLOT(cred->cr_label);
2104	obj = SLOT(ks_label);
2105
2106	if (!mac_biba_dominate_effective(obj, subj))
2107		return (EACCES);
2108
2109	return (0);
2110}
2111
2112static int
2113mac_biba_check_proc_debug(struct ucred *cred, struct proc *proc)
2114{
2115	struct mac_biba *subj, *obj;
2116
2117	if (!mac_biba_enabled)
2118		return (0);
2119
2120	subj = SLOT(cred->cr_label);
2121	obj = SLOT(proc->p_ucred->cr_label);
2122
2123	/* XXX: range checks */
2124	if (!mac_biba_dominate_effective(obj, subj))
2125		return (ESRCH);
2126	if (!mac_biba_dominate_effective(subj, obj))
2127		return (EACCES);
2128
2129	return (0);
2130}
2131
2132static int
2133mac_biba_check_proc_sched(struct ucred *cred, struct proc *proc)
2134{
2135	struct mac_biba *subj, *obj;
2136
2137	if (!mac_biba_enabled)
2138		return (0);
2139
2140	subj = SLOT(cred->cr_label);
2141	obj = SLOT(proc->p_ucred->cr_label);
2142
2143	/* XXX: range checks */
2144	if (!mac_biba_dominate_effective(obj, subj))
2145		return (ESRCH);
2146	if (!mac_biba_dominate_effective(subj, obj))
2147		return (EACCES);
2148
2149	return (0);
2150}
2151
2152static int
2153mac_biba_check_proc_signal(struct ucred *cred, struct proc *proc, int signum)
2154{
2155	struct mac_biba *subj, *obj;
2156
2157	if (!mac_biba_enabled)
2158		return (0);
2159
2160	subj = SLOT(cred->cr_label);
2161	obj = SLOT(proc->p_ucred->cr_label);
2162
2163	/* XXX: range checks */
2164	if (!mac_biba_dominate_effective(obj, subj))
2165		return (ESRCH);
2166	if (!mac_biba_dominate_effective(subj, obj))
2167		return (EACCES);
2168
2169	return (0);
2170}
2171
2172static int
2173mac_biba_check_socket_deliver(struct socket *so, struct label *socketlabel,
2174    struct mbuf *m, struct label *mbuflabel)
2175{
2176	struct mac_biba *p, *s;
2177
2178	if (!mac_biba_enabled)
2179		return (0);
2180
2181	p = SLOT(mbuflabel);
2182	s = SLOT(socketlabel);
2183
2184	return (mac_biba_equal_effective(p, s) ? 0 : EACCES);
2185}
2186
2187static int
2188mac_biba_check_socket_relabel(struct ucred *cred, struct socket *so,
2189    struct label *socketlabel, struct label *newlabel)
2190{
2191	struct mac_biba *subj, *obj, *new;
2192	int error;
2193
2194	new = SLOT(newlabel);
2195	subj = SLOT(cred->cr_label);
2196	obj = SLOT(socketlabel);
2197
2198	/*
2199	 * If there is a Biba label update for the socket, it may be
2200	 * an update of effective.
2201	 */
2202	error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE);
2203	if (error)
2204		return (error);
2205
2206	/*
2207	 * To relabel a socket, the old socket effective must be in the subject
2208	 * range.
2209	 */
2210	if (!mac_biba_effective_in_range(obj, subj))
2211		return (EPERM);
2212
2213	/*
2214	 * If the Biba label is to be changed, authorize as appropriate.
2215	 */
2216	if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
2217		/*
2218		 * To relabel a socket, the new socket effective must be in
2219		 * the subject range.
2220		 */
2221		if (!mac_biba_effective_in_range(new, subj))
2222			return (EPERM);
2223
2224		/*
2225		 * To change the Biba label on the socket to contain EQUAL,
2226		 * the subject must have appropriate privilege.
2227		 */
2228		if (mac_biba_contains_equal(new)) {
2229			error = mac_biba_subject_privileged(subj);
2230			if (error)
2231				return (error);
2232		}
2233	}
2234
2235	return (0);
2236}
2237
2238static int
2239mac_biba_check_socket_visible(struct ucred *cred, struct socket *socket,
2240    struct label *socketlabel)
2241{
2242	struct mac_biba *subj, *obj;
2243
2244	if (!mac_biba_enabled)
2245		return (0);
2246
2247	subj = SLOT(cred->cr_label);
2248	obj = SLOT(socketlabel);
2249
2250	if (!mac_biba_dominate_effective(obj, subj))
2251		return (ENOENT);
2252
2253	return (0);
2254}
2255
2256static int
2257mac_biba_check_sysarch_ioperm(struct ucred *cred)
2258{
2259	struct mac_biba *subj;
2260	int error;
2261
2262	if (!mac_biba_enabled)
2263		return (0);
2264
2265	subj = SLOT(cred->cr_label);
2266
2267	error = mac_biba_subject_privileged(subj);
2268	if (error)
2269		return (error);
2270
2271	return (0);
2272}
2273
2274static int
2275mac_biba_check_system_acct(struct ucred *cred, struct vnode *vp,
2276    struct label *label)
2277{
2278	struct mac_biba *subj, *obj;
2279	int error;
2280
2281	if (!mac_biba_enabled)
2282		return (0);
2283
2284	subj = SLOT(cred->cr_label);
2285
2286	error = mac_biba_subject_privileged(subj);
2287	if (error)
2288		return (error);
2289
2290	if (label == NULL)
2291		return (0);
2292
2293	obj = SLOT(label);
2294	if (!mac_biba_high_effective(obj))
2295		return (EACCES);
2296
2297	return (0);
2298}
2299
2300static int
2301mac_biba_check_system_settime(struct ucred *cred)
2302{
2303	struct mac_biba *subj;
2304	int error;
2305
2306	if (!mac_biba_enabled)
2307		return (0);
2308
2309	subj = SLOT(cred->cr_label);
2310
2311	error = mac_biba_subject_privileged(subj);
2312	if (error)
2313		return (error);
2314
2315	return (0);
2316}
2317
2318static int
2319mac_biba_check_system_swapon(struct ucred *cred, struct vnode *vp,
2320    struct label *label)
2321{
2322	struct mac_biba *subj, *obj;
2323	int error;
2324
2325	if (!mac_biba_enabled)
2326		return (0);
2327
2328	subj = SLOT(cred->cr_label);
2329	obj = SLOT(label);
2330
2331	error = mac_biba_subject_privileged(subj);
2332	if (error)
2333		return (error);
2334
2335	if (!mac_biba_high_effective(obj))
2336		return (EACCES);
2337
2338	return (0);
2339}
2340
2341static int
2342mac_biba_check_system_swapoff(struct ucred *cred, struct vnode *vp,
2343    struct label *label)
2344{
2345	struct mac_biba *subj, *obj;
2346	int error;
2347
2348	if (!mac_biba_enabled)
2349		return (0);
2350
2351	subj = SLOT(cred->cr_label);
2352	obj = SLOT(label);
2353
2354	error = mac_biba_subject_privileged(subj);
2355	if (error)
2356		return (error);
2357
2358	return (0);
2359}
2360
2361static int
2362mac_biba_check_system_sysctl(struct ucred *cred, struct sysctl_oid *oidp,
2363    void *arg1, int arg2, struct sysctl_req *req)
2364{
2365	struct mac_biba *subj;
2366	int error;
2367
2368	if (!mac_biba_enabled)
2369		return (0);
2370
2371	subj = SLOT(cred->cr_label);
2372
2373	/*
2374	 * Treat sysctl variables without CTLFLAG_ANYBODY flag as
2375	 * biba/high, but also require privilege to change them.
2376	 */
2377	if (req->newptr != NULL && (oidp->oid_kind & CTLFLAG_ANYBODY) == 0) {
2378		if (!mac_biba_subject_dominate_high(subj))
2379			return (EACCES);
2380
2381		error = mac_biba_subject_privileged(subj);
2382		if (error)
2383			return (error);
2384	}
2385
2386	return (0);
2387}
2388
2389static int
2390mac_biba_check_vnode_chdir(struct ucred *cred, struct vnode *dvp,
2391    struct label *dlabel)
2392{
2393	struct mac_biba *subj, *obj;
2394
2395	if (!mac_biba_enabled)
2396		return (0);
2397
2398	subj = SLOT(cred->cr_label);
2399	obj = SLOT(dlabel);
2400
2401	if (!mac_biba_dominate_effective(obj, subj))
2402		return (EACCES);
2403
2404	return (0);
2405}
2406
2407static int
2408mac_biba_check_vnode_chroot(struct ucred *cred, struct vnode *dvp,
2409    struct label *dlabel)
2410{
2411	struct mac_biba *subj, *obj;
2412
2413	if (!mac_biba_enabled)
2414		return (0);
2415
2416	subj = SLOT(cred->cr_label);
2417	obj = SLOT(dlabel);
2418
2419	if (!mac_biba_dominate_effective(obj, subj))
2420		return (EACCES);
2421
2422	return (0);
2423}
2424
2425static int
2426mac_biba_check_vnode_create(struct ucred *cred, struct vnode *dvp,
2427    struct label *dlabel, struct componentname *cnp, struct vattr *vap)
2428{
2429	struct mac_biba *subj, *obj;
2430
2431	if (!mac_biba_enabled)
2432		return (0);
2433
2434	subj = SLOT(cred->cr_label);
2435	obj = SLOT(dlabel);
2436
2437	if (!mac_biba_dominate_effective(subj, obj))
2438		return (EACCES);
2439
2440	return (0);
2441}
2442
2443static int
2444mac_biba_check_vnode_delete(struct ucred *cred, struct vnode *dvp,
2445    struct label *dlabel, struct vnode *vp, struct label *label,
2446    struct componentname *cnp)
2447{
2448	struct mac_biba *subj, *obj;
2449
2450	if (!mac_biba_enabled)
2451		return (0);
2452
2453	subj = SLOT(cred->cr_label);
2454	obj = SLOT(dlabel);
2455
2456	if (!mac_biba_dominate_effective(subj, obj))
2457		return (EACCES);
2458
2459	obj = SLOT(label);
2460
2461	if (!mac_biba_dominate_effective(subj, obj))
2462		return (EACCES);
2463
2464	return (0);
2465}
2466
2467static int
2468mac_biba_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
2469    struct label *label, acl_type_t type)
2470{
2471	struct mac_biba *subj, *obj;
2472
2473	if (!mac_biba_enabled)
2474		return (0);
2475
2476	subj = SLOT(cred->cr_label);
2477	obj = SLOT(label);
2478
2479	if (!mac_biba_dominate_effective(subj, obj))
2480		return (EACCES);
2481
2482	return (0);
2483}
2484
2485static int
2486mac_biba_check_vnode_deleteextattr(struct ucred *cred, struct vnode *vp,
2487    struct label *label, int attrnamespace, const char *name)
2488{
2489	struct mac_biba *subj, *obj;
2490
2491	if (!mac_biba_enabled)
2492		return (0);
2493
2494	subj = SLOT(cred->cr_label);
2495	obj = SLOT(label);
2496
2497	if (!mac_biba_dominate_effective(subj, obj))
2498		return (EACCES);
2499
2500	return (0);
2501}
2502
2503static int
2504mac_biba_check_vnode_exec(struct ucred *cred, struct vnode *vp,
2505    struct label *label, struct image_params *imgp,
2506    struct label *execlabel)
2507{
2508	struct mac_biba *subj, *obj, *exec;
2509	int error;
2510
2511	if (execlabel != NULL) {
2512		/*
2513		 * We currently don't permit labels to be changed at
2514		 * exec-time as part of Biba, so disallow non-NULL
2515		 * Biba label elements in the execlabel.
2516		 */
2517		exec = SLOT(execlabel);
2518		error = biba_atmostflags(exec, 0);
2519		if (error)
2520			return (error);
2521	}
2522
2523	if (!mac_biba_enabled)
2524		return (0);
2525
2526	subj = SLOT(cred->cr_label);
2527	obj = SLOT(label);
2528
2529	if (!mac_biba_dominate_effective(obj, subj))
2530		return (EACCES);
2531
2532	return (0);
2533}
2534
2535static int
2536mac_biba_check_vnode_getacl(struct ucred *cred, struct vnode *vp,
2537    struct label *label, acl_type_t type)
2538{
2539	struct mac_biba *subj, *obj;
2540
2541	if (!mac_biba_enabled)
2542		return (0);
2543
2544	subj = SLOT(cred->cr_label);
2545	obj = SLOT(label);
2546
2547	if (!mac_biba_dominate_effective(obj, subj))
2548		return (EACCES);
2549
2550	return (0);
2551}
2552
2553static int
2554mac_biba_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
2555    struct label *label, int attrnamespace, const char *name, struct uio *uio)
2556{
2557	struct mac_biba *subj, *obj;
2558
2559	if (!mac_biba_enabled)
2560		return (0);
2561
2562	subj = SLOT(cred->cr_label);
2563	obj = SLOT(label);
2564
2565	if (!mac_biba_dominate_effective(obj, subj))
2566		return (EACCES);
2567
2568	return (0);
2569}
2570
2571static int
2572mac_biba_check_vnode_link(struct ucred *cred, struct vnode *dvp,
2573    struct label *dlabel, struct vnode *vp, struct label *label,
2574    struct componentname *cnp)
2575{
2576	struct mac_biba *subj, *obj;
2577
2578	if (!mac_biba_enabled)
2579		return (0);
2580
2581	subj = SLOT(cred->cr_label);
2582	obj = SLOT(dlabel);
2583
2584	if (!mac_biba_dominate_effective(subj, obj))
2585		return (EACCES);
2586
2587	obj = SLOT(label);
2588
2589	if (!mac_biba_dominate_effective(subj, obj))
2590		return (EACCES);
2591
2592	return (0);
2593}
2594
2595static int
2596mac_biba_check_vnode_listextattr(struct ucred *cred, struct vnode *vp,
2597    struct label *label, int attrnamespace)
2598{
2599	struct mac_biba *subj, *obj;
2600
2601	if (!mac_biba_enabled)
2602		return (0);
2603
2604	subj = SLOT(cred->cr_label);
2605	obj = SLOT(label);
2606
2607	if (!mac_biba_dominate_effective(obj, subj))
2608		return (EACCES);
2609
2610	return (0);
2611}
2612
2613static int
2614mac_biba_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
2615    struct label *dlabel, struct componentname *cnp)
2616{
2617	struct mac_biba *subj, *obj;
2618
2619	if (!mac_biba_enabled)
2620		return (0);
2621
2622	subj = SLOT(cred->cr_label);
2623	obj = SLOT(dlabel);
2624
2625	if (!mac_biba_dominate_effective(obj, subj))
2626		return (EACCES);
2627
2628	return (0);
2629}
2630
2631static int
2632mac_biba_check_vnode_mmap(struct ucred *cred, struct vnode *vp,
2633    struct label *label, int prot, int flags)
2634{
2635	struct mac_biba *subj, *obj;
2636
2637	/*
2638	 * Rely on the use of open()-time protections to handle
2639	 * non-revocation cases.
2640	 */
2641	if (!mac_biba_enabled || !revocation_enabled)
2642		return (0);
2643
2644	subj = SLOT(cred->cr_label);
2645	obj = SLOT(label);
2646
2647	if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
2648		if (!mac_biba_dominate_effective(obj, subj))
2649			return (EACCES);
2650	}
2651	if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) {
2652		if (!mac_biba_dominate_effective(subj, obj))
2653			return (EACCES);
2654	}
2655
2656	return (0);
2657}
2658
2659static int
2660mac_biba_check_vnode_open(struct ucred *cred, struct vnode *vp,
2661    struct label *vnodelabel, int acc_mode)
2662{
2663	struct mac_biba *subj, *obj;
2664
2665	if (!mac_biba_enabled)
2666		return (0);
2667
2668	subj = SLOT(cred->cr_label);
2669	obj = SLOT(vnodelabel);
2670
2671	/* XXX privilege override for admin? */
2672	if (acc_mode & (VREAD | VEXEC | VSTAT)) {
2673		if (!mac_biba_dominate_effective(obj, subj))
2674			return (EACCES);
2675	}
2676	if (acc_mode & (VWRITE | VAPPEND | VADMIN)) {
2677		if (!mac_biba_dominate_effective(subj, obj))
2678			return (EACCES);
2679	}
2680
2681	return (0);
2682}
2683
2684static int
2685mac_biba_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred,
2686    struct vnode *vp, struct label *label)
2687{
2688	struct mac_biba *subj, *obj;
2689
2690	if (!mac_biba_enabled || !revocation_enabled)
2691		return (0);
2692
2693	subj = SLOT(active_cred->cr_label);
2694	obj = SLOT(label);
2695
2696	if (!mac_biba_dominate_effective(obj, subj))
2697		return (EACCES);
2698
2699	return (0);
2700}
2701
2702static int
2703mac_biba_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
2704    struct vnode *vp, struct label *label)
2705{
2706	struct mac_biba *subj, *obj;
2707
2708	if (!mac_biba_enabled || !revocation_enabled)
2709		return (0);
2710
2711	subj = SLOT(active_cred->cr_label);
2712	obj = SLOT(label);
2713
2714	if (!mac_biba_dominate_effective(obj, subj))
2715		return (EACCES);
2716
2717	return (0);
2718}
2719
2720static int
2721mac_biba_check_vnode_readdir(struct ucred *cred, struct vnode *dvp,
2722    struct label *dlabel)
2723{
2724	struct mac_biba *subj, *obj;
2725
2726	if (!mac_biba_enabled)
2727		return (0);
2728
2729	subj = SLOT(cred->cr_label);
2730	obj = SLOT(dlabel);
2731
2732	if (!mac_biba_dominate_effective(obj, subj))
2733		return (EACCES);
2734
2735	return (0);
2736}
2737
2738static int
2739mac_biba_check_vnode_readlink(struct ucred *cred, struct vnode *vp,
2740    struct label *label)
2741{
2742	struct mac_biba *subj, *obj;
2743
2744	if (!mac_biba_enabled)
2745		return (0);
2746
2747	subj = SLOT(cred->cr_label);
2748	obj = SLOT(label);
2749
2750	if (!mac_biba_dominate_effective(obj, subj))
2751		return (EACCES);
2752
2753	return (0);
2754}
2755
2756static int
2757mac_biba_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
2758    struct label *vnodelabel, struct label *newlabel)
2759{
2760	struct mac_biba *old, *new, *subj;
2761	int error;
2762
2763	old = SLOT(vnodelabel);
2764	new = SLOT(newlabel);
2765	subj = SLOT(cred->cr_label);
2766
2767	/*
2768	 * If there is a Biba label update for the vnode, it must be a
2769	 * effective label.
2770	 */
2771	error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE);
2772	if (error)
2773		return (error);
2774
2775	/*
2776	 * To perform a relabel of the vnode (Biba label or not), Biba must
2777	 * authorize the relabel.
2778	 */
2779	if (!mac_biba_effective_in_range(old, subj))
2780		return (EPERM);
2781
2782	/*
2783	 * If the Biba label is to be changed, authorize as appropriate.
2784	 */
2785	if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
2786		/*
2787		 * To change the Biba label on a vnode, the new vnode label
2788		 * must be in the subject range.
2789		 */
2790		if (!mac_biba_effective_in_range(new, subj))
2791			return (EPERM);
2792
2793		/*
2794		 * To change the Biba label on the vnode to be EQUAL,
2795		 * the subject must have appropriate privilege.
2796		 */
2797		if (mac_biba_contains_equal(new)) {
2798			error = mac_biba_subject_privileged(subj);
2799			if (error)
2800				return (error);
2801		}
2802	}
2803
2804	return (0);
2805}
2806
2807static int
2808mac_biba_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
2809    struct label *dlabel, struct vnode *vp, struct label *label,
2810    struct componentname *cnp)
2811{
2812	struct mac_biba *subj, *obj;
2813
2814	if (!mac_biba_enabled)
2815		return (0);
2816
2817	subj = SLOT(cred->cr_label);
2818	obj = SLOT(dlabel);
2819
2820	if (!mac_biba_dominate_effective(subj, obj))
2821		return (EACCES);
2822
2823	obj = SLOT(label);
2824
2825	if (!mac_biba_dominate_effective(subj, obj))
2826		return (EACCES);
2827
2828	return (0);
2829}
2830
2831static int
2832mac_biba_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
2833    struct label *dlabel, struct vnode *vp, struct label *label, int samedir,
2834    struct componentname *cnp)
2835{
2836	struct mac_biba *subj, *obj;
2837
2838	if (!mac_biba_enabled)
2839		return (0);
2840
2841	subj = SLOT(cred->cr_label);
2842	obj = SLOT(dlabel);
2843
2844	if (!mac_biba_dominate_effective(subj, obj))
2845		return (EACCES);
2846
2847	if (vp != NULL) {
2848		obj = SLOT(label);
2849
2850		if (!mac_biba_dominate_effective(subj, obj))
2851			return (EACCES);
2852	}
2853
2854	return (0);
2855}
2856
2857static int
2858mac_biba_check_vnode_revoke(struct ucred *cred, struct vnode *vp,
2859    struct label *label)
2860{
2861	struct mac_biba *subj, *obj;
2862
2863	if (!mac_biba_enabled)
2864		return (0);
2865
2866	subj = SLOT(cred->cr_label);
2867	obj = SLOT(label);
2868
2869	if (!mac_biba_dominate_effective(subj, obj))
2870		return (EACCES);
2871
2872	return (0);
2873}
2874
2875static int
2876mac_biba_check_vnode_setacl(struct ucred *cred, struct vnode *vp,
2877    struct label *label, acl_type_t type, struct acl *acl)
2878{
2879	struct mac_biba *subj, *obj;
2880
2881	if (!mac_biba_enabled)
2882		return (0);
2883
2884	subj = SLOT(cred->cr_label);
2885	obj = SLOT(label);
2886
2887	if (!mac_biba_dominate_effective(subj, obj))
2888		return (EACCES);
2889
2890	return (0);
2891}
2892
2893static int
2894mac_biba_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
2895    struct label *vnodelabel, int attrnamespace, const char *name,
2896    struct uio *uio)
2897{
2898	struct mac_biba *subj, *obj;
2899
2900	if (!mac_biba_enabled)
2901		return (0);
2902
2903	subj = SLOT(cred->cr_label);
2904	obj = SLOT(vnodelabel);
2905
2906	if (!mac_biba_dominate_effective(subj, obj))
2907		return (EACCES);
2908
2909	/* XXX: protect the MAC EA in a special way? */
2910
2911	return (0);
2912}
2913
2914static int
2915mac_biba_check_vnode_setflags(struct ucred *cred, struct vnode *vp,
2916    struct label *vnodelabel, u_long flags)
2917{
2918	struct mac_biba *subj, *obj;
2919
2920	if (!mac_biba_enabled)
2921		return (0);
2922
2923	subj = SLOT(cred->cr_label);
2924	obj = SLOT(vnodelabel);
2925
2926	if (!mac_biba_dominate_effective(subj, obj))
2927		return (EACCES);
2928
2929	return (0);
2930}
2931
2932static int
2933mac_biba_check_vnode_setmode(struct ucred *cred, struct vnode *vp,
2934    struct label *vnodelabel, mode_t mode)
2935{
2936	struct mac_biba *subj, *obj;
2937
2938	if (!mac_biba_enabled)
2939		return (0);
2940
2941	subj = SLOT(cred->cr_label);
2942	obj = SLOT(vnodelabel);
2943
2944	if (!mac_biba_dominate_effective(subj, obj))
2945		return (EACCES);
2946
2947	return (0);
2948}
2949
2950static int
2951mac_biba_check_vnode_setowner(struct ucred *cred, struct vnode *vp,
2952    struct label *vnodelabel, uid_t uid, gid_t gid)
2953{
2954	struct mac_biba *subj, *obj;
2955
2956	if (!mac_biba_enabled)
2957		return (0);
2958
2959	subj = SLOT(cred->cr_label);
2960	obj = SLOT(vnodelabel);
2961
2962	if (!mac_biba_dominate_effective(subj, obj))
2963		return (EACCES);
2964
2965	return (0);
2966}
2967
2968static int
2969mac_biba_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
2970    struct label *vnodelabel, struct timespec atime, struct timespec mtime)
2971{
2972	struct mac_biba *subj, *obj;
2973
2974	if (!mac_biba_enabled)
2975		return (0);
2976
2977	subj = SLOT(cred->cr_label);
2978	obj = SLOT(vnodelabel);
2979
2980	if (!mac_biba_dominate_effective(subj, obj))
2981		return (EACCES);
2982
2983	return (0);
2984}
2985
2986static int
2987mac_biba_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
2988    struct vnode *vp, struct label *vnodelabel)
2989{
2990	struct mac_biba *subj, *obj;
2991
2992	if (!mac_biba_enabled)
2993		return (0);
2994
2995	subj = SLOT(active_cred->cr_label);
2996	obj = SLOT(vnodelabel);
2997
2998	if (!mac_biba_dominate_effective(obj, subj))
2999		return (EACCES);
3000
3001	return (0);
3002}
3003
3004static int
3005mac_biba_check_vnode_write(struct ucred *active_cred,
3006    struct ucred *file_cred, struct vnode *vp, struct label *label)
3007{
3008	struct mac_biba *subj, *obj;
3009
3010	if (!mac_biba_enabled || !revocation_enabled)
3011		return (0);
3012
3013	subj = SLOT(active_cred->cr_label);
3014	obj = SLOT(label);
3015
3016	if (!mac_biba_dominate_effective(subj, obj))
3017		return (EACCES);
3018
3019	return (0);
3020}
3021
3022static struct mac_policy_ops mac_biba_ops =
3023{
3024	.mpo_init = mac_biba_init,
3025	.mpo_init_bpfdesc_label = mac_biba_init_label,
3026	.mpo_init_cred_label = mac_biba_init_label,
3027	.mpo_init_devfsdirent_label = mac_biba_init_label,
3028	.mpo_init_ifnet_label = mac_biba_init_label,
3029	.mpo_init_inpcb_label = mac_biba_init_label_waitcheck,
3030	.mpo_init_sysv_msgmsg_label = mac_biba_init_label,
3031	.mpo_init_sysv_msgqueue_label = mac_biba_init_label,
3032	.mpo_init_sysv_sem_label = mac_biba_init_label,
3033	.mpo_init_sysv_shm_label = mac_biba_init_label,
3034	.mpo_init_ipq_label = mac_biba_init_label_waitcheck,
3035	.mpo_init_mbuf_label = mac_biba_init_label_waitcheck,
3036	.mpo_init_mount_label = mac_biba_init_label,
3037	.mpo_init_mount_fs_label = mac_biba_init_label,
3038	.mpo_init_pipe_label = mac_biba_init_label,
3039	.mpo_init_posix_sem_label = mac_biba_init_label,
3040	.mpo_init_socket_label = mac_biba_init_label_waitcheck,
3041	.mpo_init_socket_peer_label = mac_biba_init_label_waitcheck,
3042	.mpo_init_vnode_label = mac_biba_init_label,
3043	.mpo_destroy_bpfdesc_label = mac_biba_destroy_label,
3044	.mpo_destroy_cred_label = mac_biba_destroy_label,
3045	.mpo_destroy_devfsdirent_label = mac_biba_destroy_label,
3046	.mpo_destroy_ifnet_label = mac_biba_destroy_label,
3047	.mpo_destroy_inpcb_label = mac_biba_destroy_label,
3048	.mpo_destroy_sysv_msgmsg_label = mac_biba_destroy_label,
3049	.mpo_destroy_sysv_msgqueue_label = mac_biba_destroy_label,
3050	.mpo_destroy_sysv_sem_label = mac_biba_destroy_label,
3051	.mpo_destroy_sysv_shm_label = mac_biba_destroy_label,
3052	.mpo_destroy_ipq_label = mac_biba_destroy_label,
3053	.mpo_destroy_mbuf_label = mac_biba_destroy_label,
3054	.mpo_destroy_mount_label = mac_biba_destroy_label,
3055	.mpo_destroy_mount_fs_label = mac_biba_destroy_label,
3056	.mpo_destroy_pipe_label = mac_biba_destroy_label,
3057	.mpo_destroy_posix_sem_label = mac_biba_destroy_label,
3058	.mpo_destroy_socket_label = mac_biba_destroy_label,
3059	.mpo_destroy_socket_peer_label = mac_biba_destroy_label,
3060	.mpo_destroy_vnode_label = mac_biba_destroy_label,
3061	.mpo_copy_cred_label = mac_biba_copy_label,
3062	.mpo_copy_ifnet_label = mac_biba_copy_label,
3063	.mpo_copy_mbuf_label = mac_biba_copy_label,
3064	.mpo_copy_pipe_label = mac_biba_copy_label,
3065	.mpo_copy_socket_label = mac_biba_copy_label,
3066	.mpo_copy_vnode_label = mac_biba_copy_label,
3067	.mpo_externalize_cred_label = mac_biba_externalize_label,
3068	.mpo_externalize_ifnet_label = mac_biba_externalize_label,
3069	.mpo_externalize_pipe_label = mac_biba_externalize_label,
3070	.mpo_externalize_socket_label = mac_biba_externalize_label,
3071	.mpo_externalize_socket_peer_label = mac_biba_externalize_label,
3072	.mpo_externalize_vnode_label = mac_biba_externalize_label,
3073	.mpo_internalize_cred_label = mac_biba_internalize_label,
3074	.mpo_internalize_ifnet_label = mac_biba_internalize_label,
3075	.mpo_internalize_pipe_label = mac_biba_internalize_label,
3076	.mpo_internalize_socket_label = mac_biba_internalize_label,
3077	.mpo_internalize_vnode_label = mac_biba_internalize_label,
3078	.mpo_create_devfs_device = mac_biba_create_devfs_device,
3079	.mpo_create_devfs_directory = mac_biba_create_devfs_directory,
3080	.mpo_create_devfs_symlink = mac_biba_create_devfs_symlink,
3081	.mpo_create_mount = mac_biba_create_mount,
3082	.mpo_relabel_vnode = mac_biba_relabel_vnode,
3083	.mpo_update_devfsdirent = mac_biba_update_devfsdirent,
3084	.mpo_associate_vnode_devfs = mac_biba_associate_vnode_devfs,
3085	.mpo_associate_vnode_extattr = mac_biba_associate_vnode_extattr,
3086	.mpo_associate_vnode_singlelabel = mac_biba_associate_vnode_singlelabel,
3087	.mpo_create_vnode_extattr = mac_biba_create_vnode_extattr,
3088	.mpo_setlabel_vnode_extattr = mac_biba_setlabel_vnode_extattr,
3089	.mpo_create_mbuf_from_socket = mac_biba_create_mbuf_from_socket,
3090	.mpo_create_pipe = mac_biba_create_pipe,
3091	.mpo_create_posix_sem = mac_biba_create_posix_sem,
3092	.mpo_create_socket = mac_biba_create_socket,
3093	.mpo_create_socket_from_socket = mac_biba_create_socket_from_socket,
3094	.mpo_relabel_pipe = mac_biba_relabel_pipe,
3095	.mpo_relabel_socket = mac_biba_relabel_socket,
3096	.mpo_set_socket_peer_from_mbuf = mac_biba_set_socket_peer_from_mbuf,
3097	.mpo_set_socket_peer_from_socket = mac_biba_set_socket_peer_from_socket,
3098	.mpo_create_bpfdesc = mac_biba_create_bpfdesc,
3099	.mpo_create_datagram_from_ipq = mac_biba_create_datagram_from_ipq,
3100	.mpo_create_fragment = mac_biba_create_fragment,
3101	.mpo_create_ifnet = mac_biba_create_ifnet,
3102	.mpo_create_inpcb_from_socket = mac_biba_create_inpcb_from_socket,
3103	.mpo_create_sysv_msgmsg = mac_biba_create_sysv_msgmsg,
3104	.mpo_create_sysv_msgqueue = mac_biba_create_sysv_msgqueue,
3105	.mpo_create_sysv_sem = mac_biba_create_sysv_sem,
3106	.mpo_create_sysv_shm = mac_biba_create_sysv_shm,
3107	.mpo_create_ipq = mac_biba_create_ipq,
3108	.mpo_create_mbuf_from_inpcb = mac_biba_create_mbuf_from_inpcb,
3109	.mpo_create_mbuf_linklayer = mac_biba_create_mbuf_linklayer,
3110	.mpo_create_mbuf_from_bpfdesc = mac_biba_create_mbuf_from_bpfdesc,
3111	.mpo_create_mbuf_from_ifnet = mac_biba_create_mbuf_from_ifnet,
3112	.mpo_create_mbuf_multicast_encap = mac_biba_create_mbuf_multicast_encap,
3113	.mpo_create_mbuf_netlayer = mac_biba_create_mbuf_netlayer,
3114	.mpo_fragment_match = mac_biba_fragment_match,
3115	.mpo_relabel_ifnet = mac_biba_relabel_ifnet,
3116	.mpo_update_ipq = mac_biba_update_ipq,
3117	.mpo_inpcb_sosetlabel = mac_biba_inpcb_sosetlabel,
3118	.mpo_create_proc0 = mac_biba_create_proc0,
3119	.mpo_create_proc1 = mac_biba_create_proc1,
3120	.mpo_relabel_cred = mac_biba_relabel_cred,
3121	.mpo_cleanup_sysv_msgmsg = mac_biba_cleanup_sysv_msgmsg,
3122	.mpo_cleanup_sysv_msgqueue = mac_biba_cleanup_sysv_msgqueue,
3123	.mpo_cleanup_sysv_sem = mac_biba_cleanup_sysv_sem,
3124	.mpo_cleanup_sysv_shm = mac_biba_cleanup_sysv_shm,
3125	.mpo_check_bpfdesc_receive = mac_biba_check_bpfdesc_receive,
3126	.mpo_check_cred_relabel = mac_biba_check_cred_relabel,
3127	.mpo_check_cred_visible = mac_biba_check_cred_visible,
3128	.mpo_check_ifnet_relabel = mac_biba_check_ifnet_relabel,
3129	.mpo_check_ifnet_transmit = mac_biba_check_ifnet_transmit,
3130	.mpo_check_inpcb_deliver = mac_biba_check_inpcb_deliver,
3131	.mpo_check_sysv_msgrcv = mac_biba_check_sysv_msgrcv,
3132	.mpo_check_sysv_msgrmid = mac_biba_check_sysv_msgrmid,
3133	.mpo_check_sysv_msqget = mac_biba_check_sysv_msqget,
3134	.mpo_check_sysv_msqsnd = mac_biba_check_sysv_msqsnd,
3135	.mpo_check_sysv_msqrcv = mac_biba_check_sysv_msqrcv,
3136	.mpo_check_sysv_msqctl = mac_biba_check_sysv_msqctl,
3137	.mpo_check_sysv_semctl = mac_biba_check_sysv_semctl,
3138	.mpo_check_sysv_semget = mac_biba_check_sysv_semget,
3139	.mpo_check_sysv_semop = mac_biba_check_sysv_semop,
3140	.mpo_check_sysv_shmat = mac_biba_check_sysv_shmat,
3141	.mpo_check_sysv_shmctl = mac_biba_check_sysv_shmctl,
3142	.mpo_check_sysv_shmget = mac_biba_check_sysv_shmget,
3143	.mpo_check_kld_load = mac_biba_check_kld_load,
3144	.mpo_check_kld_unload = mac_biba_check_kld_unload,
3145	.mpo_check_mount_stat = mac_biba_check_mount_stat,
3146	.mpo_check_pipe_ioctl = mac_biba_check_pipe_ioctl,
3147	.mpo_check_pipe_poll = mac_biba_check_pipe_poll,
3148	.mpo_check_pipe_read = mac_biba_check_pipe_read,
3149	.mpo_check_pipe_relabel = mac_biba_check_pipe_relabel,
3150	.mpo_check_pipe_stat = mac_biba_check_pipe_stat,
3151	.mpo_check_pipe_write = mac_biba_check_pipe_write,
3152	.mpo_check_posix_sem_destroy = mac_biba_check_posix_sem_write,
3153	.mpo_check_posix_sem_getvalue = mac_biba_check_posix_sem_rdonly,
3154	.mpo_check_posix_sem_open = mac_biba_check_posix_sem_write,
3155	.mpo_check_posix_sem_post = mac_biba_check_posix_sem_write,
3156	.mpo_check_posix_sem_unlink = mac_biba_check_posix_sem_write,
3157	.mpo_check_posix_sem_wait = mac_biba_check_posix_sem_write,
3158	.mpo_check_proc_debug = mac_biba_check_proc_debug,
3159	.mpo_check_proc_sched = mac_biba_check_proc_sched,
3160	.mpo_check_proc_signal = mac_biba_check_proc_signal,
3161	.mpo_check_socket_deliver = mac_biba_check_socket_deliver,
3162	.mpo_check_socket_relabel = mac_biba_check_socket_relabel,
3163	.mpo_check_socket_visible = mac_biba_check_socket_visible,
3164	.mpo_check_sysarch_ioperm = mac_biba_check_sysarch_ioperm,
3165	.mpo_check_system_acct = mac_biba_check_system_acct,
3166	.mpo_check_system_settime = mac_biba_check_system_settime,
3167	.mpo_check_system_swapon = mac_biba_check_system_swapon,
3168	.mpo_check_system_swapoff = mac_biba_check_system_swapoff,
3169	.mpo_check_system_sysctl = mac_biba_check_system_sysctl,
3170	.mpo_check_vnode_access = mac_biba_check_vnode_open,
3171	.mpo_check_vnode_chdir = mac_biba_check_vnode_chdir,
3172	.mpo_check_vnode_chroot = mac_biba_check_vnode_chroot,
3173	.mpo_check_vnode_create = mac_biba_check_vnode_create,
3174	.mpo_check_vnode_delete = mac_biba_check_vnode_delete,
3175	.mpo_check_vnode_deleteacl = mac_biba_check_vnode_deleteacl,
3176	.mpo_check_vnode_deleteextattr = mac_biba_check_vnode_deleteextattr,
3177	.mpo_check_vnode_exec = mac_biba_check_vnode_exec,
3178	.mpo_check_vnode_getacl = mac_biba_check_vnode_getacl,
3179	.mpo_check_vnode_getextattr = mac_biba_check_vnode_getextattr,
3180	.mpo_check_vnode_link = mac_biba_check_vnode_link,
3181	.mpo_check_vnode_listextattr = mac_biba_check_vnode_listextattr,
3182	.mpo_check_vnode_lookup = mac_biba_check_vnode_lookup,
3183	.mpo_check_vnode_mmap = mac_biba_check_vnode_mmap,
3184	.mpo_check_vnode_open = mac_biba_check_vnode_open,
3185	.mpo_check_vnode_poll = mac_biba_check_vnode_poll,
3186	.mpo_check_vnode_read = mac_biba_check_vnode_read,
3187	.mpo_check_vnode_readdir = mac_biba_check_vnode_readdir,
3188	.mpo_check_vnode_readlink = mac_biba_check_vnode_readlink,
3189	.mpo_check_vnode_relabel = mac_biba_check_vnode_relabel,
3190	.mpo_check_vnode_rename_from = mac_biba_check_vnode_rename_from,
3191	.mpo_check_vnode_rename_to = mac_biba_check_vnode_rename_to,
3192	.mpo_check_vnode_revoke = mac_biba_check_vnode_revoke,
3193	.mpo_check_vnode_setacl = mac_biba_check_vnode_setacl,
3194	.mpo_check_vnode_setextattr = mac_biba_check_vnode_setextattr,
3195	.mpo_check_vnode_setflags = mac_biba_check_vnode_setflags,
3196	.mpo_check_vnode_setmode = mac_biba_check_vnode_setmode,
3197	.mpo_check_vnode_setowner = mac_biba_check_vnode_setowner,
3198	.mpo_check_vnode_setutimes = mac_biba_check_vnode_setutimes,
3199	.mpo_check_vnode_stat = mac_biba_check_vnode_stat,
3200	.mpo_check_vnode_write = mac_biba_check_vnode_write,
3201};
3202
3203MAC_POLICY_SET(&mac_biba_ops, mac_biba, "TrustedBSD MAC/Biba",
3204    MPC_LOADTIME_FLAG_NOTLATE | MPC_LOADTIME_FLAG_LABELMBUFS, &mac_biba_slot);
3205