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