mac_biba.c revision 150324
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 150324 2005-09-19 13:59:57Z 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_relabel_vnode(struct ucred *cred, struct vnode *vp,
842    struct label *vnodelabel, struct label *label)
843{
844	struct mac_biba *source, *dest;
845
846	source = SLOT(label);
847	dest = SLOT(vnodelabel);
848
849	mac_biba_copy(source, dest);
850}
851
852static void
853mac_biba_update_devfsdirent(struct mount *mp,
854    struct devfs_dirent *devfs_dirent, struct label *direntlabel,
855    struct vnode *vp, struct label *vnodelabel)
856{
857	struct mac_biba *source, *dest;
858
859	source = SLOT(vnodelabel);
860	dest = SLOT(direntlabel);
861
862	mac_biba_copy(source, dest);
863}
864
865static void
866mac_biba_associate_vnode_devfs(struct mount *mp, struct label *fslabel,
867    struct devfs_dirent *de, struct label *delabel, struct vnode *vp,
868    struct label *vlabel)
869{
870	struct mac_biba *source, *dest;
871
872	source = SLOT(delabel);
873	dest = SLOT(vlabel);
874
875	mac_biba_copy_effective(source, dest);
876}
877
878static int
879mac_biba_associate_vnode_extattr(struct mount *mp, struct label *fslabel,
880    struct vnode *vp, struct label *vlabel)
881{
882	struct mac_biba temp, *source, *dest;
883	int buflen, error;
884
885	source = SLOT(fslabel);
886	dest = SLOT(vlabel);
887
888	buflen = sizeof(temp);
889	bzero(&temp, buflen);
890
891	error = vn_extattr_get(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
892	    MAC_BIBA_EXTATTR_NAME, &buflen, (char *) &temp, curthread);
893	if (error == ENOATTR || error == EOPNOTSUPP) {
894		/* Fall back to the fslabel. */
895		mac_biba_copy_effective(source, dest);
896		return (0);
897	} else if (error)
898		return (error);
899
900	if (buflen != sizeof(temp)) {
901		printf("mac_biba_associate_vnode_extattr: bad size %d\n",
902		    buflen);
903		return (EPERM);
904	}
905	if (mac_biba_valid(&temp) != 0) {
906		printf("mac_biba_associate_vnode_extattr: invalid\n");
907		return (EPERM);
908	}
909	if ((temp.mb_flags & MAC_BIBA_FLAGS_BOTH) != MAC_BIBA_FLAG_EFFECTIVE) {
910		printf("mac_biba_associate_vnode_extattr: not effective\n");
911		return (EPERM);
912	}
913
914	mac_biba_copy_effective(&temp, dest);
915	return (0);
916}
917
918static void
919mac_biba_associate_vnode_singlelabel(struct mount *mp,
920    struct label *fslabel, struct vnode *vp, struct label *vlabel)
921{
922	struct mac_biba *source, *dest;
923
924	source = SLOT(fslabel);
925	dest = SLOT(vlabel);
926
927	mac_biba_copy_effective(source, dest);
928}
929
930static int
931mac_biba_create_vnode_extattr(struct ucred *cred, struct mount *mp,
932    struct label *fslabel, struct vnode *dvp, struct label *dlabel,
933    struct vnode *vp, struct label *vlabel, struct componentname *cnp)
934{
935	struct mac_biba *source, *dest, temp;
936	size_t buflen;
937	int error;
938
939	buflen = sizeof(temp);
940	bzero(&temp, buflen);
941
942	source = SLOT(cred->cr_label);
943	dest = SLOT(vlabel);
944	mac_biba_copy_effective(source, &temp);
945
946	error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
947	    MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread);
948	if (error == 0)
949		mac_biba_copy_effective(source, dest);
950	return (error);
951}
952
953static int
954mac_biba_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp,
955    struct label *vlabel, struct label *intlabel)
956{
957	struct mac_biba *source, temp;
958	size_t buflen;
959	int error;
960
961	buflen = sizeof(temp);
962	bzero(&temp, buflen);
963
964	source = SLOT(intlabel);
965	if ((source->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) == 0)
966		return (0);
967
968	mac_biba_copy_effective(source, &temp);
969
970	error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
971	    MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread);
972	return (error);
973}
974
975/*
976 * Labeling event operations: IPC object.
977 */
978static void
979mac_biba_create_inpcb_from_socket(struct socket *so, struct label *solabel,
980    struct inpcb *inp, struct label *inplabel)
981{
982	struct mac_biba *source, *dest;
983
984	source = SLOT(solabel);
985	dest = SLOT(inplabel);
986
987	mac_biba_copy_effective(source, dest);
988}
989
990static void
991mac_biba_create_mbuf_from_socket(struct socket *so, struct label *socketlabel,
992    struct mbuf *m, struct label *mbuflabel)
993{
994	struct mac_biba *source, *dest;
995
996	source = SLOT(socketlabel);
997	dest = SLOT(mbuflabel);
998
999	mac_biba_copy_effective(source, dest);
1000}
1001
1002static void
1003mac_biba_create_socket(struct ucred *cred, struct socket *socket,
1004    struct label *socketlabel)
1005{
1006	struct mac_biba *source, *dest;
1007
1008	source = SLOT(cred->cr_label);
1009	dest = SLOT(socketlabel);
1010
1011	mac_biba_copy_effective(source, dest);
1012}
1013
1014static void
1015mac_biba_create_pipe(struct ucred *cred, struct pipepair *pp,
1016    struct label *pipelabel)
1017{
1018	struct mac_biba *source, *dest;
1019
1020	source = SLOT(cred->cr_label);
1021	dest = SLOT(pipelabel);
1022
1023	mac_biba_copy_effective(source, dest);
1024}
1025
1026static void
1027mac_biba_create_posix_sem(struct ucred *cred, struct ksem *ksemptr,
1028    struct label *ks_label)
1029{
1030	struct mac_biba *source, *dest;
1031
1032	source = SLOT(cred->cr_label);
1033	dest = SLOT(ks_label);
1034
1035	mac_biba_copy_effective(source, dest);
1036}
1037
1038static void
1039mac_biba_create_socket_from_socket(struct socket *oldsocket,
1040    struct label *oldsocketlabel, struct socket *newsocket,
1041    struct label *newsocketlabel)
1042{
1043	struct mac_biba *source, *dest;
1044
1045	source = SLOT(oldsocketlabel);
1046	dest = SLOT(newsocketlabel);
1047
1048	mac_biba_copy_effective(source, dest);
1049}
1050
1051static void
1052mac_biba_relabel_socket(struct ucred *cred, struct socket *socket,
1053    struct label *socketlabel, struct label *newlabel)
1054{
1055	struct mac_biba *source, *dest;
1056
1057	source = SLOT(newlabel);
1058	dest = SLOT(socketlabel);
1059
1060	mac_biba_copy(source, dest);
1061}
1062
1063static void
1064mac_biba_relabel_pipe(struct ucred *cred, struct pipepair *pp,
1065    struct label *pipelabel, struct label *newlabel)
1066{
1067	struct mac_biba *source, *dest;
1068
1069	source = SLOT(newlabel);
1070	dest = SLOT(pipelabel);
1071
1072	mac_biba_copy(source, dest);
1073}
1074
1075static void
1076mac_biba_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel,
1077    struct socket *socket, struct label *socketpeerlabel)
1078{
1079	struct mac_biba *source, *dest;
1080
1081	source = SLOT(mbuflabel);
1082	dest = SLOT(socketpeerlabel);
1083
1084	mac_biba_copy_effective(source, dest);
1085}
1086
1087/*
1088 * Labeling event operations: System V IPC objects.
1089 */
1090
1091static void
1092mac_biba_create_sysv_msgmsg(struct ucred *cred, struct msqid_kernel *msqkptr,
1093    struct label *msqlabel, struct msg *msgptr, struct label *msglabel)
1094{
1095	struct mac_biba *source, *dest;
1096
1097	/* Ignore the msgq label */
1098	source = SLOT(cred->cr_label);
1099	dest = SLOT(msglabel);
1100
1101	mac_biba_copy_effective(source, dest);
1102}
1103
1104static void
1105mac_biba_create_sysv_msgqueue(struct ucred *cred,
1106    struct msqid_kernel *msqkptr, struct label *msqlabel)
1107{
1108	struct mac_biba *source, *dest;
1109
1110	source = SLOT(cred->cr_label);
1111	dest = SLOT(msqlabel);
1112
1113	mac_biba_copy_effective(source, dest);
1114}
1115
1116static void
1117mac_biba_create_sysv_sem(struct ucred *cred, struct semid_kernel *semakptr,
1118    struct label *semalabel)
1119{
1120	struct mac_biba *source, *dest;
1121
1122	source = SLOT(cred->cr_label);
1123	dest = SLOT(semalabel);
1124
1125	mac_biba_copy_effective(source, dest);
1126}
1127
1128static void
1129mac_biba_create_sysv_shm(struct ucred *cred, struct shmid_kernel *shmsegptr,
1130    struct label *shmlabel)
1131{
1132	struct mac_biba *source, *dest;
1133
1134	source = SLOT(cred->cr_label);
1135	dest = SLOT(shmlabel);
1136
1137	mac_biba_copy_effective(source, dest);
1138}
1139
1140/*
1141 * Labeling event operations: network objects.
1142 */
1143static void
1144mac_biba_set_socket_peer_from_socket(struct socket *oldsocket,
1145    struct label *oldsocketlabel, struct socket *newsocket,
1146    struct label *newsocketpeerlabel)
1147{
1148	struct mac_biba *source, *dest;
1149
1150	source = SLOT(oldsocketlabel);
1151	dest = SLOT(newsocketpeerlabel);
1152
1153	mac_biba_copy_effective(source, dest);
1154}
1155
1156static void
1157mac_biba_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d,
1158    struct label *bpflabel)
1159{
1160	struct mac_biba *source, *dest;
1161
1162	source = SLOT(cred->cr_label);
1163	dest = SLOT(bpflabel);
1164
1165	mac_biba_copy_effective(source, dest);
1166}
1167
1168static void
1169mac_biba_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel)
1170{
1171	char tifname[IFNAMSIZ], *p, *q;
1172	char tiflist[sizeof(trusted_interfaces)];
1173	struct mac_biba *dest;
1174	int len, type;
1175
1176	dest = SLOT(ifnetlabel);
1177
1178	if (ifnet->if_type == IFT_LOOP) {
1179		type = MAC_BIBA_TYPE_EQUAL;
1180		goto set;
1181	}
1182
1183	if (trust_all_interfaces) {
1184		type = MAC_BIBA_TYPE_HIGH;
1185		goto set;
1186	}
1187
1188	type = MAC_BIBA_TYPE_LOW;
1189
1190	if (trusted_interfaces[0] == '\0' ||
1191	    !strvalid(trusted_interfaces, sizeof(trusted_interfaces)))
1192		goto set;
1193
1194	bzero(tiflist, sizeof(tiflist));
1195	for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++)
1196		if(*p != ' ' && *p != '\t')
1197			*q = *p;
1198
1199	for (p = q = tiflist;; p++) {
1200		if (*p == ',' || *p == '\0') {
1201			len = p - q;
1202			if (len < IFNAMSIZ) {
1203				bzero(tifname, sizeof(tifname));
1204				bcopy(q, tifname, len);
1205				if (strcmp(tifname, ifnet->if_xname) == 0) {
1206					type = MAC_BIBA_TYPE_HIGH;
1207					break;
1208				}
1209			} else {
1210				*p = '\0';
1211				printf("mac_biba warning: interface name "
1212				    "\"%s\" is too long (must be < %d)\n",
1213				    q, IFNAMSIZ);
1214			}
1215			if (*p == '\0')
1216				break;
1217			q = p + 1;
1218		}
1219	}
1220set:
1221	mac_biba_set_effective(dest, type, 0, NULL);
1222	mac_biba_set_range(dest, type, 0, NULL, type, 0, NULL);
1223}
1224
1225static void
1226mac_biba_create_ipq(struct mbuf *fragment, struct label *fragmentlabel,
1227    struct ipq *ipq, struct label *ipqlabel)
1228{
1229	struct mac_biba *source, *dest;
1230
1231	source = SLOT(fragmentlabel);
1232	dest = SLOT(ipqlabel);
1233
1234	mac_biba_copy_effective(source, dest);
1235}
1236
1237static void
1238mac_biba_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel,
1239    struct mbuf *datagram, struct label *datagramlabel)
1240{
1241	struct mac_biba *source, *dest;
1242
1243	source = SLOT(ipqlabel);
1244	dest = SLOT(datagramlabel);
1245
1246	/* Just use the head, since we require them all to match. */
1247	mac_biba_copy_effective(source, dest);
1248}
1249
1250static void
1251mac_biba_create_fragment(struct mbuf *datagram, struct label *datagramlabel,
1252    struct mbuf *fragment, struct label *fragmentlabel)
1253{
1254	struct mac_biba *source, *dest;
1255
1256	source = SLOT(datagramlabel);
1257	dest = SLOT(fragmentlabel);
1258
1259	mac_biba_copy_effective(source, dest);
1260}
1261
1262static void
1263mac_biba_create_mbuf_from_inpcb(struct inpcb *inp, struct label *inplabel,
1264    struct mbuf *m, struct label *mlabel)
1265{
1266	struct mac_biba *source, *dest;
1267
1268	source = SLOT(inplabel);
1269	dest = SLOT(mlabel);
1270
1271	mac_biba_copy_effective(source, dest);
1272}
1273
1274static void
1275mac_biba_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel,
1276    struct mbuf *mbuf, struct label *mbuflabel)
1277{
1278	struct mac_biba *dest;
1279
1280	dest = SLOT(mbuflabel);
1281
1282	mac_biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1283}
1284
1285static void
1286mac_biba_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel,
1287    struct mbuf *mbuf, struct label *mbuflabel)
1288{
1289	struct mac_biba *source, *dest;
1290
1291	source = SLOT(bpflabel);
1292	dest = SLOT(mbuflabel);
1293
1294	mac_biba_copy_effective(source, dest);
1295}
1296
1297static void
1298mac_biba_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel,
1299    struct mbuf *m, struct label *mbuflabel)
1300{
1301	struct mac_biba *source, *dest;
1302
1303	source = SLOT(ifnetlabel);
1304	dest = SLOT(mbuflabel);
1305
1306	mac_biba_copy_effective(source, dest);
1307}
1308
1309static void
1310mac_biba_create_mbuf_multicast_encap(struct mbuf *oldmbuf,
1311    struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel,
1312    struct mbuf *newmbuf, struct label *newmbuflabel)
1313{
1314	struct mac_biba *source, *dest;
1315
1316	source = SLOT(oldmbuflabel);
1317	dest = SLOT(newmbuflabel);
1318
1319	mac_biba_copy_effective(source, dest);
1320}
1321
1322static void
1323mac_biba_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel,
1324    struct mbuf *newmbuf, struct label *newmbuflabel)
1325{
1326	struct mac_biba *source, *dest;
1327
1328	source = SLOT(oldmbuflabel);
1329	dest = SLOT(newmbuflabel);
1330
1331	mac_biba_copy_effective(source, dest);
1332}
1333
1334static int
1335mac_biba_fragment_match(struct mbuf *fragment, struct label *fragmentlabel,
1336    struct ipq *ipq, struct label *ipqlabel)
1337{
1338	struct mac_biba *a, *b;
1339
1340	a = SLOT(ipqlabel);
1341	b = SLOT(fragmentlabel);
1342
1343	return (mac_biba_equal_effective(a, b));
1344}
1345
1346static void
1347mac_biba_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet,
1348    struct label *ifnetlabel, struct label *newlabel)
1349{
1350	struct mac_biba *source, *dest;
1351
1352	source = SLOT(newlabel);
1353	dest = SLOT(ifnetlabel);
1354
1355	mac_biba_copy(source, dest);
1356}
1357
1358static void
1359mac_biba_update_ipq(struct mbuf *fragment, struct label *fragmentlabel,
1360    struct ipq *ipq, struct label *ipqlabel)
1361{
1362
1363	/* NOOP: we only accept matching labels, so no need to update */
1364}
1365
1366static void
1367mac_biba_inpcb_sosetlabel(struct socket *so, struct label *solabel,
1368    struct inpcb *inp, struct label *inplabel)
1369{
1370	struct mac_biba *source, *dest;
1371
1372	source = SLOT(solabel);
1373	dest = SLOT(inplabel);
1374
1375	mac_biba_copy(source, dest);
1376}
1377
1378/*
1379 * Labeling event operations: processes.
1380 */
1381static void
1382mac_biba_create_proc0(struct ucred *cred)
1383{
1384	struct mac_biba *dest;
1385
1386	dest = SLOT(cred->cr_label);
1387
1388	mac_biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1389	mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL,
1390	    MAC_BIBA_TYPE_HIGH, 0, NULL);
1391}
1392
1393static void
1394mac_biba_create_proc1(struct ucred *cred)
1395{
1396	struct mac_biba *dest;
1397
1398	dest = SLOT(cred->cr_label);
1399
1400	mac_biba_set_effective(dest, MAC_BIBA_TYPE_HIGH, 0, NULL);
1401	mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL,
1402	    MAC_BIBA_TYPE_HIGH, 0, NULL);
1403}
1404
1405static void
1406mac_biba_relabel_cred(struct ucred *cred, struct label *newlabel)
1407{
1408	struct mac_biba *source, *dest;
1409
1410	source = SLOT(newlabel);
1411	dest = SLOT(cred->cr_label);
1412
1413	mac_biba_copy(source, dest);
1414}
1415
1416/*
1417 * Label cleanup/flush operations
1418 */
1419static void
1420mac_biba_cleanup_sysv_msgmsg(struct label *msglabel)
1421{
1422
1423	bzero(SLOT(msglabel), sizeof(struct mac_biba));
1424}
1425
1426static void
1427mac_biba_cleanup_sysv_msgqueue(struct label *msqlabel)
1428{
1429
1430	bzero(SLOT(msqlabel), sizeof(struct mac_biba));
1431}
1432
1433static void
1434mac_biba_cleanup_sysv_sem(struct label *semalabel)
1435{
1436
1437	bzero(SLOT(semalabel), sizeof(struct mac_biba));
1438}
1439
1440static void
1441mac_biba_cleanup_sysv_shm(struct label *shmlabel)
1442{
1443	bzero(SLOT(shmlabel), sizeof(struct mac_biba));
1444}
1445
1446/*
1447 * Access control checks.
1448 */
1449static int
1450mac_biba_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel,
1451    struct ifnet *ifnet, struct label *ifnetlabel)
1452{
1453	struct mac_biba *a, *b;
1454
1455	if (!mac_biba_enabled)
1456		return (0);
1457
1458	a = SLOT(bpflabel);
1459	b = SLOT(ifnetlabel);
1460
1461	if (mac_biba_equal_effective(a, b))
1462		return (0);
1463	return (EACCES);
1464}
1465
1466static int
1467mac_biba_check_cred_relabel(struct ucred *cred, struct label *newlabel)
1468{
1469	struct mac_biba *subj, *new;
1470	int error;
1471
1472	subj = SLOT(cred->cr_label);
1473	new = SLOT(newlabel);
1474
1475	/*
1476	 * If there is a Biba label update for the credential, it may
1477	 * be an update of the effective, range, or both.
1478	 */
1479	error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
1480	if (error)
1481		return (error);
1482
1483	/*
1484	 * If the Biba label is to be changed, authorize as appropriate.
1485	 */
1486	if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) {
1487		/*
1488		 * If the change request modifies both the Biba label
1489		 * effective and range, check that the new effective will be
1490		 * in the new range.
1491		 */
1492		if ((new->mb_flags & MAC_BIBA_FLAGS_BOTH) ==
1493		    MAC_BIBA_FLAGS_BOTH &&
1494		    !mac_biba_effective_in_range(new, new))
1495			return (EINVAL);
1496
1497		/*
1498		 * To change the Biba effective label on a credential, the
1499		 * new effective label must be in the current range.
1500		 */
1501		if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE &&
1502		    !mac_biba_effective_in_range(new, subj))
1503			return (EPERM);
1504
1505		/*
1506		 * To change the Biba range on a credential, the new
1507		 * range label must be in the current range.
1508		 */
1509		if (new->mb_flags & MAC_BIBA_FLAG_RANGE &&
1510		    !mac_biba_range_in_range(new, subj))
1511			return (EPERM);
1512
1513		/*
1514		 * To have EQUAL in any component of the new credential
1515		 * Biba label, the subject must already have EQUAL in
1516		 * their label.
1517		 */
1518		if (mac_biba_contains_equal(new)) {
1519			error = mac_biba_subject_privileged(subj);
1520			if (error)
1521				return (error);
1522		}
1523	}
1524
1525	return (0);
1526}
1527
1528static int
1529mac_biba_check_cred_visible(struct ucred *u1, struct ucred *u2)
1530{
1531	struct mac_biba *subj, *obj;
1532
1533	if (!mac_biba_enabled)
1534		return (0);
1535
1536	subj = SLOT(u1->cr_label);
1537	obj = SLOT(u2->cr_label);
1538
1539	/* XXX: range */
1540	if (!mac_biba_dominate_effective(obj, subj))
1541		return (ESRCH);
1542
1543	return (0);
1544}
1545
1546static int
1547mac_biba_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet,
1548    struct label *ifnetlabel, struct label *newlabel)
1549{
1550	struct mac_biba *subj, *new;
1551	int error;
1552
1553	subj = SLOT(cred->cr_label);
1554	new = SLOT(newlabel);
1555
1556	/*
1557	 * If there is a Biba label update for the interface, it may
1558	 * be an update of the effective, range, or both.
1559	 */
1560	error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
1561	if (error)
1562		return (error);
1563
1564	/*
1565	 * Relabling network interfaces requires Biba privilege.
1566	 */
1567	error = mac_biba_subject_privileged(subj);
1568	if (error)
1569		return (error);
1570
1571	return (0);
1572}
1573
1574static int
1575mac_biba_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel,
1576    struct mbuf *m, struct label *mbuflabel)
1577{
1578	struct mac_biba *p, *i;
1579
1580	if (!mac_biba_enabled)
1581		return (0);
1582
1583	p = SLOT(mbuflabel);
1584	i = SLOT(ifnetlabel);
1585
1586	return (mac_biba_effective_in_range(p, i) ? 0 : EACCES);
1587}
1588
1589static int
1590mac_biba_check_inpcb_deliver(struct inpcb *inp, struct label *inplabel,
1591    struct mbuf *m, struct label *mlabel)
1592{
1593	struct mac_biba *p, *i;
1594
1595	if (!mac_biba_enabled)
1596		return (0);
1597
1598	p = SLOT(mlabel);
1599	i = SLOT(inplabel);
1600
1601	return (mac_biba_equal_effective(p, i) ? 0 : EACCES);
1602}
1603
1604static int
1605mac_biba_check_sysv_msgrcv(struct ucred *cred, struct msg *msgptr,
1606    struct label *msglabel)
1607{
1608	struct mac_biba *subj, *obj;
1609
1610	if (!mac_biba_enabled)
1611		return (0);
1612
1613	subj = SLOT(cred->cr_label);
1614	obj = SLOT(msglabel);
1615
1616	if (!mac_biba_dominate_effective(obj, subj))
1617		return (EACCES);
1618
1619	return (0);
1620}
1621
1622static int
1623mac_biba_check_sysv_msgrmid(struct ucred *cred, struct msg *msgptr,
1624    struct label *msglabel)
1625{
1626	struct mac_biba *subj, *obj;
1627
1628	if (!mac_biba_enabled)
1629		return (0);
1630
1631	subj = SLOT(cred->cr_label);
1632	obj = SLOT(msglabel);
1633
1634	if (!mac_biba_dominate_effective(subj, obj))
1635		return (EACCES);
1636
1637	return (0);
1638}
1639
1640static int
1641mac_biba_check_sysv_msqget(struct ucred *cred, struct msqid_kernel *msqkptr,
1642    struct label *msqklabel)
1643{
1644	struct mac_biba *subj, *obj;
1645
1646	if (!mac_biba_enabled)
1647		return (0);
1648
1649	subj = SLOT(cred->cr_label);
1650	obj = SLOT(msqklabel);
1651
1652	if (!mac_biba_dominate_effective(obj, subj))
1653		return (EACCES);
1654
1655	return (0);
1656}
1657
1658static int
1659mac_biba_check_sysv_msqsnd(struct ucred *cred, struct msqid_kernel *msqkptr,
1660    struct label *msqklabel)
1661{
1662	struct mac_biba *subj, *obj;
1663
1664	if (!mac_biba_enabled)
1665		return (0);
1666
1667	subj = SLOT(cred->cr_label);
1668	obj = SLOT(msqklabel);
1669
1670	if (!mac_biba_dominate_effective(subj, obj))
1671		return (EACCES);
1672
1673	return (0);
1674}
1675
1676static int
1677mac_biba_check_sysv_msqrcv(struct ucred *cred, struct msqid_kernel *msqkptr,
1678    struct label *msqklabel)
1679{
1680	struct mac_biba *subj, *obj;
1681
1682	if (!mac_biba_enabled)
1683		return (0);
1684
1685	subj = SLOT(cred->cr_label);
1686	obj = SLOT(msqklabel);
1687
1688	if (!mac_biba_dominate_effective(obj, subj))
1689		return (EACCES);
1690
1691	return (0);
1692}
1693
1694
1695static int
1696mac_biba_check_sysv_msqctl(struct ucred *cred, struct msqid_kernel *msqkptr,
1697    struct label *msqklabel, int cmd)
1698{
1699	struct mac_biba *subj, *obj;
1700
1701	if (!mac_biba_enabled)
1702		return (0);
1703
1704	subj = SLOT(cred->cr_label);
1705	obj = SLOT(msqklabel);
1706
1707	switch(cmd) {
1708	case IPC_RMID:
1709	case IPC_SET:
1710		if (!mac_biba_dominate_effective(subj, obj))
1711			return (EACCES);
1712		break;
1713
1714	case IPC_STAT:
1715		if (!mac_biba_dominate_effective(obj, subj))
1716			return (EACCES);
1717		break;
1718
1719	default:
1720		return (EACCES);
1721	}
1722
1723	return (0);
1724}
1725
1726static int
1727mac_biba_check_sysv_semctl(struct ucred *cred, struct semid_kernel *semakptr,
1728    struct label *semaklabel, int cmd)
1729{
1730	struct mac_biba *subj, *obj;
1731
1732	if (!mac_biba_enabled)
1733		return (0);
1734
1735	subj = SLOT(cred->cr_label);
1736	obj = SLOT(semaklabel);
1737
1738	switch(cmd) {
1739	case IPC_RMID:
1740	case IPC_SET:
1741	case SETVAL:
1742	case SETALL:
1743		if (!mac_biba_dominate_effective(subj, obj))
1744			return (EACCES);
1745		break;
1746
1747	case IPC_STAT:
1748	case GETVAL:
1749	case GETPID:
1750	case GETNCNT:
1751	case GETZCNT:
1752	case GETALL:
1753		if (!mac_biba_dominate_effective(obj, subj))
1754			return (EACCES);
1755		break;
1756
1757	default:
1758		return (EACCES);
1759	}
1760
1761	return (0);
1762}
1763
1764
1765static int
1766mac_biba_check_sysv_semget(struct ucred *cred, struct semid_kernel *semakptr,
1767    struct label *semaklabel)
1768{
1769	struct mac_biba *subj, *obj;
1770
1771	if (!mac_biba_enabled)
1772		return (0);
1773
1774	subj = SLOT(cred->cr_label);
1775	obj = SLOT(semaklabel);
1776
1777	if (!mac_biba_dominate_effective(obj, subj))
1778		return (EACCES);
1779
1780	return (0);
1781}
1782
1783
1784static int
1785mac_biba_check_sysv_semop(struct ucred *cred, struct semid_kernel *semakptr,
1786    struct label *semaklabel, size_t accesstype)
1787{
1788	struct mac_biba *subj, *obj;
1789
1790	if (!mac_biba_enabled)
1791		return (0);
1792
1793	subj = SLOT(cred->cr_label);
1794	obj = SLOT(semaklabel);
1795
1796	if (accesstype & SEM_R)
1797		if (!mac_biba_dominate_effective(obj, subj))
1798			return (EACCES);
1799
1800	if (accesstype & SEM_A)
1801		if (!mac_biba_dominate_effective(subj, obj))
1802			return (EACCES);
1803
1804	return (0);
1805}
1806
1807static int
1808mac_biba_check_sysv_shmat(struct ucred *cred, struct shmid_kernel *shmsegptr,
1809    struct label *shmseglabel, int shmflg)
1810{
1811	struct mac_biba *subj, *obj;
1812
1813	if (!mac_biba_enabled)
1814		return (0);
1815
1816	subj = SLOT(cred->cr_label);
1817	obj = SLOT(shmseglabel);
1818
1819	if (!mac_biba_dominate_effective(obj, subj))
1820		return (EACCES);
1821	if ((shmflg & SHM_RDONLY) == 0) {
1822		if (!mac_biba_dominate_effective(subj, obj))
1823			return (EACCES);
1824	}
1825
1826	return (0);
1827}
1828
1829static int
1830mac_biba_check_sysv_shmctl(struct ucred *cred, struct shmid_kernel *shmsegptr,
1831    struct label *shmseglabel, int cmd)
1832{
1833	struct mac_biba *subj, *obj;
1834
1835	if (!mac_biba_enabled)
1836		return (0);
1837
1838	subj = SLOT(cred->cr_label);
1839	obj = SLOT(shmseglabel);
1840
1841	switch(cmd) {
1842	case IPC_RMID:
1843	case IPC_SET:
1844		if (!mac_biba_dominate_effective(subj, obj))
1845			return (EACCES);
1846		break;
1847
1848	case IPC_STAT:
1849	case SHM_STAT:
1850		if (!mac_biba_dominate_effective(obj, subj))
1851			return (EACCES);
1852		break;
1853
1854	default:
1855		return (EACCES);
1856	}
1857
1858	return (0);
1859}
1860
1861static int
1862mac_biba_check_sysv_shmget(struct ucred *cred, struct shmid_kernel *shmsegptr,
1863    struct label *shmseglabel, int shmflg)
1864{
1865	struct mac_biba *subj, *obj;
1866
1867	if (!mac_biba_enabled)
1868		return (0);
1869
1870	subj = SLOT(cred->cr_label);
1871	obj = SLOT(shmseglabel);
1872
1873	if (!mac_biba_dominate_effective(obj, subj))
1874		return (EACCES);
1875
1876	return (0);
1877}
1878
1879static int
1880mac_biba_check_kld_load(struct ucred *cred, struct vnode *vp,
1881    struct label *label)
1882{
1883	struct mac_biba *subj, *obj;
1884	int error;
1885
1886	if (!mac_biba_enabled)
1887		return (0);
1888
1889	subj = SLOT(cred->cr_label);
1890
1891	error = mac_biba_subject_privileged(subj);
1892	if (error)
1893		return (error);
1894
1895	obj = SLOT(label);
1896	if (!mac_biba_high_effective(obj))
1897		return (EACCES);
1898
1899	return (0);
1900}
1901
1902
1903static int
1904mac_biba_check_kld_unload(struct ucred *cred)
1905{
1906	struct mac_biba *subj;
1907
1908	if (!mac_biba_enabled)
1909		return (0);
1910
1911	subj = SLOT(cred->cr_label);
1912
1913	return (mac_biba_subject_privileged(subj));
1914}
1915
1916static int
1917mac_biba_check_mount_stat(struct ucred *cred, struct mount *mp,
1918    struct label *mntlabel)
1919{
1920	struct mac_biba *subj, *obj;
1921
1922	if (!mac_biba_enabled)
1923		return (0);
1924
1925	subj = SLOT(cred->cr_label);
1926	obj = SLOT(mntlabel);
1927
1928	if (!mac_biba_dominate_effective(obj, subj))
1929		return (EACCES);
1930
1931	return (0);
1932}
1933
1934static int
1935mac_biba_check_pipe_ioctl(struct ucred *cred, struct pipepair *pp,
1936    struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data)
1937{
1938
1939	if(!mac_biba_enabled)
1940		return (0);
1941
1942	/* XXX: This will be implemented soon... */
1943
1944	return (0);
1945}
1946
1947static int
1948mac_biba_check_pipe_poll(struct ucred *cred, struct pipepair *pp,
1949    struct label *pipelabel)
1950{
1951	struct mac_biba *subj, *obj;
1952
1953	if (!mac_biba_enabled)
1954		return (0);
1955
1956	subj = SLOT(cred->cr_label);
1957	obj = SLOT((pipelabel));
1958
1959	if (!mac_biba_dominate_effective(obj, subj))
1960		return (EACCES);
1961
1962	return (0);
1963}
1964
1965static int
1966mac_biba_check_pipe_read(struct ucred *cred, struct pipepair *pp,
1967    struct label *pipelabel)
1968{
1969	struct mac_biba *subj, *obj;
1970
1971	if (!mac_biba_enabled)
1972		return (0);
1973
1974	subj = SLOT(cred->cr_label);
1975	obj = SLOT((pipelabel));
1976
1977	if (!mac_biba_dominate_effective(obj, subj))
1978		return (EACCES);
1979
1980	return (0);
1981}
1982
1983static int
1984mac_biba_check_pipe_relabel(struct ucred *cred, struct pipepair *pp,
1985    struct label *pipelabel, struct label *newlabel)
1986{
1987	struct mac_biba *subj, *obj, *new;
1988	int error;
1989
1990	new = SLOT(newlabel);
1991	subj = SLOT(cred->cr_label);
1992	obj = SLOT(pipelabel);
1993
1994	/*
1995	 * If there is a Biba label update for a pipe, it must be a
1996	 * effective update.
1997	 */
1998	error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE);
1999	if (error)
2000		return (error);
2001
2002	/*
2003	 * To perform a relabel of a pipe (Biba label or not), Biba must
2004	 * authorize the relabel.
2005	 */
2006	if (!mac_biba_effective_in_range(obj, subj))
2007		return (EPERM);
2008
2009	/*
2010	 * If the Biba label is to be changed, authorize as appropriate.
2011	 */
2012	if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
2013		/*
2014		 * To change the Biba label on a pipe, the new pipe label
2015		 * must be in the subject range.
2016		 */
2017		if (!mac_biba_effective_in_range(new, subj))
2018			return (EPERM);
2019
2020		/*
2021		 * To change the Biba label on a pipe to be EQUAL, the
2022		 * subject must have appropriate privilege.
2023		 */
2024		if (mac_biba_contains_equal(new)) {
2025			error = mac_biba_subject_privileged(subj);
2026			if (error)
2027				return (error);
2028		}
2029	}
2030
2031	return (0);
2032}
2033
2034static int
2035mac_biba_check_pipe_stat(struct ucred *cred, struct pipepair *pp,
2036    struct label *pipelabel)
2037{
2038	struct mac_biba *subj, *obj;
2039
2040	if (!mac_biba_enabled)
2041		return (0);
2042
2043	subj = SLOT(cred->cr_label);
2044	obj = SLOT((pipelabel));
2045
2046	if (!mac_biba_dominate_effective(obj, subj))
2047		return (EACCES);
2048
2049	return (0);
2050}
2051
2052static int
2053mac_biba_check_pipe_write(struct ucred *cred, struct pipepair *pp,
2054    struct label *pipelabel)
2055{
2056	struct mac_biba *subj, *obj;
2057
2058	if (!mac_biba_enabled)
2059		return (0);
2060
2061	subj = SLOT(cred->cr_label);
2062	obj = SLOT((pipelabel));
2063
2064	if (!mac_biba_dominate_effective(subj, obj))
2065		return (EACCES);
2066
2067	return (0);
2068}
2069
2070static int
2071mac_biba_check_posix_sem_write(struct ucred *cred, struct ksem *ksemptr,
2072    struct label *ks_label)
2073{
2074	struct mac_biba *subj, *obj;
2075
2076	if (!mac_biba_enabled)
2077		return (0);
2078
2079	subj = SLOT(cred->cr_label);
2080	obj = SLOT(ks_label);
2081
2082	if (!mac_biba_dominate_effective(subj, obj))
2083		return (EACCES);
2084
2085	return (0);
2086}
2087
2088static int
2089mac_biba_check_posix_sem_rdonly(struct ucred *cred, struct ksem *ksemptr,
2090    struct label *ks_label)
2091{
2092	struct mac_biba *subj, *obj;
2093
2094	if (!mac_biba_enabled)
2095		return (0);
2096
2097	subj = SLOT(cred->cr_label);
2098	obj = SLOT(ks_label);
2099
2100	if (!mac_biba_dominate_effective(obj, subj))
2101		return (EACCES);
2102
2103	return (0);
2104}
2105
2106static int
2107mac_biba_check_proc_debug(struct ucred *cred, struct proc *proc)
2108{
2109	struct mac_biba *subj, *obj;
2110
2111	if (!mac_biba_enabled)
2112		return (0);
2113
2114	subj = SLOT(cred->cr_label);
2115	obj = SLOT(proc->p_ucred->cr_label);
2116
2117	/* XXX: range checks */
2118	if (!mac_biba_dominate_effective(obj, subj))
2119		return (ESRCH);
2120	if (!mac_biba_dominate_effective(subj, obj))
2121		return (EACCES);
2122
2123	return (0);
2124}
2125
2126static int
2127mac_biba_check_proc_sched(struct ucred *cred, struct proc *proc)
2128{
2129	struct mac_biba *subj, *obj;
2130
2131	if (!mac_biba_enabled)
2132		return (0);
2133
2134	subj = SLOT(cred->cr_label);
2135	obj = SLOT(proc->p_ucred->cr_label);
2136
2137	/* XXX: range checks */
2138	if (!mac_biba_dominate_effective(obj, subj))
2139		return (ESRCH);
2140	if (!mac_biba_dominate_effective(subj, obj))
2141		return (EACCES);
2142
2143	return (0);
2144}
2145
2146static int
2147mac_biba_check_proc_signal(struct ucred *cred, struct proc *proc, int signum)
2148{
2149	struct mac_biba *subj, *obj;
2150
2151	if (!mac_biba_enabled)
2152		return (0);
2153
2154	subj = SLOT(cred->cr_label);
2155	obj = SLOT(proc->p_ucred->cr_label);
2156
2157	/* XXX: range checks */
2158	if (!mac_biba_dominate_effective(obj, subj))
2159		return (ESRCH);
2160	if (!mac_biba_dominate_effective(subj, obj))
2161		return (EACCES);
2162
2163	return (0);
2164}
2165
2166static int
2167mac_biba_check_socket_deliver(struct socket *so, struct label *socketlabel,
2168    struct mbuf *m, struct label *mbuflabel)
2169{
2170	struct mac_biba *p, *s;
2171
2172	if (!mac_biba_enabled)
2173		return (0);
2174
2175	p = SLOT(mbuflabel);
2176	s = SLOT(socketlabel);
2177
2178	return (mac_biba_equal_effective(p, s) ? 0 : EACCES);
2179}
2180
2181static int
2182mac_biba_check_socket_relabel(struct ucred *cred, struct socket *so,
2183    struct label *socketlabel, struct label *newlabel)
2184{
2185	struct mac_biba *subj, *obj, *new;
2186	int error;
2187
2188	new = SLOT(newlabel);
2189	subj = SLOT(cred->cr_label);
2190	obj = SLOT(socketlabel);
2191
2192	/*
2193	 * If there is a Biba label update for the socket, it may be
2194	 * an update of effective.
2195	 */
2196	error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE);
2197	if (error)
2198		return (error);
2199
2200	/*
2201	 * To relabel a socket, the old socket effective must be in the subject
2202	 * range.
2203	 */
2204	if (!mac_biba_effective_in_range(obj, subj))
2205		return (EPERM);
2206
2207	/*
2208	 * If the Biba label is to be changed, authorize as appropriate.
2209	 */
2210	if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
2211		/*
2212		 * To relabel a socket, the new socket effective must be in
2213		 * the subject range.
2214		 */
2215		if (!mac_biba_effective_in_range(new, subj))
2216			return (EPERM);
2217
2218		/*
2219		 * To change the Biba label on the socket to contain EQUAL,
2220		 * the subject must have appropriate privilege.
2221		 */
2222		if (mac_biba_contains_equal(new)) {
2223			error = mac_biba_subject_privileged(subj);
2224			if (error)
2225				return (error);
2226		}
2227	}
2228
2229	return (0);
2230}
2231
2232static int
2233mac_biba_check_socket_visible(struct ucred *cred, struct socket *socket,
2234    struct label *socketlabel)
2235{
2236	struct mac_biba *subj, *obj;
2237
2238	if (!mac_biba_enabled)
2239		return (0);
2240
2241	subj = SLOT(cred->cr_label);
2242	obj = SLOT(socketlabel);
2243
2244	if (!mac_biba_dominate_effective(obj, subj))
2245		return (ENOENT);
2246
2247	return (0);
2248}
2249
2250static int
2251mac_biba_check_sysarch_ioperm(struct ucred *cred)
2252{
2253	struct mac_biba *subj;
2254	int error;
2255
2256	if (!mac_biba_enabled)
2257		return (0);
2258
2259	subj = SLOT(cred->cr_label);
2260
2261	error = mac_biba_subject_privileged(subj);
2262	if (error)
2263		return (error);
2264
2265	return (0);
2266}
2267
2268static int
2269mac_biba_check_system_acct(struct ucred *cred, struct vnode *vp,
2270    struct label *label)
2271{
2272	struct mac_biba *subj, *obj;
2273	int error;
2274
2275	if (!mac_biba_enabled)
2276		return (0);
2277
2278	subj = SLOT(cred->cr_label);
2279
2280	error = mac_biba_subject_privileged(subj);
2281	if (error)
2282		return (error);
2283
2284	if (label == NULL)
2285		return (0);
2286
2287	obj = SLOT(label);
2288	if (!mac_biba_high_effective(obj))
2289		return (EACCES);
2290
2291	return (0);
2292}
2293
2294static int
2295mac_biba_check_system_settime(struct ucred *cred)
2296{
2297	struct mac_biba *subj;
2298	int error;
2299
2300	if (!mac_biba_enabled)
2301		return (0);
2302
2303	subj = SLOT(cred->cr_label);
2304
2305	error = mac_biba_subject_privileged(subj);
2306	if (error)
2307		return (error);
2308
2309	return (0);
2310}
2311
2312static int
2313mac_biba_check_system_swapon(struct ucred *cred, struct vnode *vp,
2314    struct label *label)
2315{
2316	struct mac_biba *subj, *obj;
2317	int error;
2318
2319	if (!mac_biba_enabled)
2320		return (0);
2321
2322	subj = SLOT(cred->cr_label);
2323	obj = SLOT(label);
2324
2325	error = mac_biba_subject_privileged(subj);
2326	if (error)
2327		return (error);
2328
2329	if (!mac_biba_high_effective(obj))
2330		return (EACCES);
2331
2332	return (0);
2333}
2334
2335static int
2336mac_biba_check_system_swapoff(struct ucred *cred, struct vnode *vp,
2337    struct label *label)
2338{
2339	struct mac_biba *subj, *obj;
2340	int error;
2341
2342	if (!mac_biba_enabled)
2343		return (0);
2344
2345	subj = SLOT(cred->cr_label);
2346	obj = SLOT(label);
2347
2348	error = mac_biba_subject_privileged(subj);
2349	if (error)
2350		return (error);
2351
2352	return (0);
2353}
2354
2355static int
2356mac_biba_check_system_sysctl(struct ucred *cred, struct sysctl_oid *oidp,
2357    void *arg1, int arg2, struct sysctl_req *req)
2358{
2359	struct mac_biba *subj;
2360	int error;
2361
2362	if (!mac_biba_enabled)
2363		return (0);
2364
2365	subj = SLOT(cred->cr_label);
2366
2367	/*
2368	 * Treat sysctl variables without CTLFLAG_ANYBODY flag as
2369	 * biba/high, but also require privilege to change them.
2370	 */
2371	if (req->newptr != NULL && (oidp->oid_kind & CTLFLAG_ANYBODY) == 0) {
2372		if (!mac_biba_subject_dominate_high(subj))
2373			return (EACCES);
2374
2375		error = mac_biba_subject_privileged(subj);
2376		if (error)
2377			return (error);
2378	}
2379
2380	return (0);
2381}
2382
2383static int
2384mac_biba_check_vnode_chdir(struct ucred *cred, struct vnode *dvp,
2385    struct label *dlabel)
2386{
2387	struct mac_biba *subj, *obj;
2388
2389	if (!mac_biba_enabled)
2390		return (0);
2391
2392	subj = SLOT(cred->cr_label);
2393	obj = SLOT(dlabel);
2394
2395	if (!mac_biba_dominate_effective(obj, subj))
2396		return (EACCES);
2397
2398	return (0);
2399}
2400
2401static int
2402mac_biba_check_vnode_chroot(struct ucred *cred, struct vnode *dvp,
2403    struct label *dlabel)
2404{
2405	struct mac_biba *subj, *obj;
2406
2407	if (!mac_biba_enabled)
2408		return (0);
2409
2410	subj = SLOT(cred->cr_label);
2411	obj = SLOT(dlabel);
2412
2413	if (!mac_biba_dominate_effective(obj, subj))
2414		return (EACCES);
2415
2416	return (0);
2417}
2418
2419static int
2420mac_biba_check_vnode_create(struct ucred *cred, struct vnode *dvp,
2421    struct label *dlabel, struct componentname *cnp, struct vattr *vap)
2422{
2423	struct mac_biba *subj, *obj;
2424
2425	if (!mac_biba_enabled)
2426		return (0);
2427
2428	subj = SLOT(cred->cr_label);
2429	obj = SLOT(dlabel);
2430
2431	if (!mac_biba_dominate_effective(subj, obj))
2432		return (EACCES);
2433
2434	return (0);
2435}
2436
2437static int
2438mac_biba_check_vnode_delete(struct ucred *cred, struct vnode *dvp,
2439    struct label *dlabel, struct vnode *vp, struct label *label,
2440    struct componentname *cnp)
2441{
2442	struct mac_biba *subj, *obj;
2443
2444	if (!mac_biba_enabled)
2445		return (0);
2446
2447	subj = SLOT(cred->cr_label);
2448	obj = SLOT(dlabel);
2449
2450	if (!mac_biba_dominate_effective(subj, obj))
2451		return (EACCES);
2452
2453	obj = SLOT(label);
2454
2455	if (!mac_biba_dominate_effective(subj, obj))
2456		return (EACCES);
2457
2458	return (0);
2459}
2460
2461static int
2462mac_biba_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
2463    struct label *label, acl_type_t type)
2464{
2465	struct mac_biba *subj, *obj;
2466
2467	if (!mac_biba_enabled)
2468		return (0);
2469
2470	subj = SLOT(cred->cr_label);
2471	obj = SLOT(label);
2472
2473	if (!mac_biba_dominate_effective(subj, obj))
2474		return (EACCES);
2475
2476	return (0);
2477}
2478
2479static int
2480mac_biba_check_vnode_deleteextattr(struct ucred *cred, struct vnode *vp,
2481    struct label *label, int attrnamespace, const char *name)
2482{
2483	struct mac_biba *subj, *obj;
2484
2485	if (!mac_biba_enabled)
2486		return (0);
2487
2488	subj = SLOT(cred->cr_label);
2489	obj = SLOT(label);
2490
2491	if (!mac_biba_dominate_effective(subj, obj))
2492		return (EACCES);
2493
2494	return (0);
2495}
2496
2497static int
2498mac_biba_check_vnode_exec(struct ucred *cred, struct vnode *vp,
2499    struct label *label, struct image_params *imgp,
2500    struct label *execlabel)
2501{
2502	struct mac_biba *subj, *obj, *exec;
2503	int error;
2504
2505	if (execlabel != NULL) {
2506		/*
2507		 * We currently don't permit labels to be changed at
2508		 * exec-time as part of Biba, so disallow non-NULL
2509		 * Biba label elements in the execlabel.
2510		 */
2511		exec = SLOT(execlabel);
2512		error = biba_atmostflags(exec, 0);
2513		if (error)
2514			return (error);
2515	}
2516
2517	if (!mac_biba_enabled)
2518		return (0);
2519
2520	subj = SLOT(cred->cr_label);
2521	obj = SLOT(label);
2522
2523	if (!mac_biba_dominate_effective(obj, subj))
2524		return (EACCES);
2525
2526	return (0);
2527}
2528
2529static int
2530mac_biba_check_vnode_getacl(struct ucred *cred, struct vnode *vp,
2531    struct label *label, acl_type_t type)
2532{
2533	struct mac_biba *subj, *obj;
2534
2535	if (!mac_biba_enabled)
2536		return (0);
2537
2538	subj = SLOT(cred->cr_label);
2539	obj = SLOT(label);
2540
2541	if (!mac_biba_dominate_effective(obj, subj))
2542		return (EACCES);
2543
2544	return (0);
2545}
2546
2547static int
2548mac_biba_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
2549    struct label *label, int attrnamespace, const char *name, struct uio *uio)
2550{
2551	struct mac_biba *subj, *obj;
2552
2553	if (!mac_biba_enabled)
2554		return (0);
2555
2556	subj = SLOT(cred->cr_label);
2557	obj = SLOT(label);
2558
2559	if (!mac_biba_dominate_effective(obj, subj))
2560		return (EACCES);
2561
2562	return (0);
2563}
2564
2565static int
2566mac_biba_check_vnode_link(struct ucred *cred, struct vnode *dvp,
2567    struct label *dlabel, struct vnode *vp, struct label *label,
2568    struct componentname *cnp)
2569{
2570	struct mac_biba *subj, *obj;
2571
2572	if (!mac_biba_enabled)
2573		return (0);
2574
2575	subj = SLOT(cred->cr_label);
2576	obj = SLOT(dlabel);
2577
2578	if (!mac_biba_dominate_effective(subj, obj))
2579		return (EACCES);
2580
2581	obj = SLOT(label);
2582
2583	if (!mac_biba_dominate_effective(subj, obj))
2584		return (EACCES);
2585
2586	return (0);
2587}
2588
2589static int
2590mac_biba_check_vnode_listextattr(struct ucred *cred, struct vnode *vp,
2591    struct label *label, int attrnamespace)
2592{
2593	struct mac_biba *subj, *obj;
2594
2595	if (!mac_biba_enabled)
2596		return (0);
2597
2598	subj = SLOT(cred->cr_label);
2599	obj = SLOT(label);
2600
2601	if (!mac_biba_dominate_effective(obj, subj))
2602		return (EACCES);
2603
2604	return (0);
2605}
2606
2607static int
2608mac_biba_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
2609    struct label *dlabel, struct componentname *cnp)
2610{
2611	struct mac_biba *subj, *obj;
2612
2613	if (!mac_biba_enabled)
2614		return (0);
2615
2616	subj = SLOT(cred->cr_label);
2617	obj = SLOT(dlabel);
2618
2619	if (!mac_biba_dominate_effective(obj, subj))
2620		return (EACCES);
2621
2622	return (0);
2623}
2624
2625static int
2626mac_biba_check_vnode_mmap(struct ucred *cred, struct vnode *vp,
2627    struct label *label, int prot, int flags)
2628{
2629	struct mac_biba *subj, *obj;
2630
2631	/*
2632	 * Rely on the use of open()-time protections to handle
2633	 * non-revocation cases.
2634	 */
2635	if (!mac_biba_enabled || !revocation_enabled)
2636		return (0);
2637
2638	subj = SLOT(cred->cr_label);
2639	obj = SLOT(label);
2640
2641	if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
2642		if (!mac_biba_dominate_effective(obj, subj))
2643			return (EACCES);
2644	}
2645	if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) {
2646		if (!mac_biba_dominate_effective(subj, obj))
2647			return (EACCES);
2648	}
2649
2650	return (0);
2651}
2652
2653static int
2654mac_biba_check_vnode_open(struct ucred *cred, struct vnode *vp,
2655    struct label *vnodelabel, int acc_mode)
2656{
2657	struct mac_biba *subj, *obj;
2658
2659	if (!mac_biba_enabled)
2660		return (0);
2661
2662	subj = SLOT(cred->cr_label);
2663	obj = SLOT(vnodelabel);
2664
2665	/* XXX privilege override for admin? */
2666	if (acc_mode & (VREAD | VEXEC | VSTAT)) {
2667		if (!mac_biba_dominate_effective(obj, subj))
2668			return (EACCES);
2669	}
2670	if (acc_mode & (VWRITE | VAPPEND | VADMIN)) {
2671		if (!mac_biba_dominate_effective(subj, obj))
2672			return (EACCES);
2673	}
2674
2675	return (0);
2676}
2677
2678static int
2679mac_biba_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred,
2680    struct vnode *vp, struct label *label)
2681{
2682	struct mac_biba *subj, *obj;
2683
2684	if (!mac_biba_enabled || !revocation_enabled)
2685		return (0);
2686
2687	subj = SLOT(active_cred->cr_label);
2688	obj = SLOT(label);
2689
2690	if (!mac_biba_dominate_effective(obj, subj))
2691		return (EACCES);
2692
2693	return (0);
2694}
2695
2696static int
2697mac_biba_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
2698    struct vnode *vp, struct label *label)
2699{
2700	struct mac_biba *subj, *obj;
2701
2702	if (!mac_biba_enabled || !revocation_enabled)
2703		return (0);
2704
2705	subj = SLOT(active_cred->cr_label);
2706	obj = SLOT(label);
2707
2708	if (!mac_biba_dominate_effective(obj, subj))
2709		return (EACCES);
2710
2711	return (0);
2712}
2713
2714static int
2715mac_biba_check_vnode_readdir(struct ucred *cred, struct vnode *dvp,
2716    struct label *dlabel)
2717{
2718	struct mac_biba *subj, *obj;
2719
2720	if (!mac_biba_enabled)
2721		return (0);
2722
2723	subj = SLOT(cred->cr_label);
2724	obj = SLOT(dlabel);
2725
2726	if (!mac_biba_dominate_effective(obj, subj))
2727		return (EACCES);
2728
2729	return (0);
2730}
2731
2732static int
2733mac_biba_check_vnode_readlink(struct ucred *cred, struct vnode *vp,
2734    struct label *label)
2735{
2736	struct mac_biba *subj, *obj;
2737
2738	if (!mac_biba_enabled)
2739		return (0);
2740
2741	subj = SLOT(cred->cr_label);
2742	obj = SLOT(label);
2743
2744	if (!mac_biba_dominate_effective(obj, subj))
2745		return (EACCES);
2746
2747	return (0);
2748}
2749
2750static int
2751mac_biba_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
2752    struct label *vnodelabel, struct label *newlabel)
2753{
2754	struct mac_biba *old, *new, *subj;
2755	int error;
2756
2757	old = SLOT(vnodelabel);
2758	new = SLOT(newlabel);
2759	subj = SLOT(cred->cr_label);
2760
2761	/*
2762	 * If there is a Biba label update for the vnode, it must be a
2763	 * effective label.
2764	 */
2765	error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE);
2766	if (error)
2767		return (error);
2768
2769	/*
2770	 * To perform a relabel of the vnode (Biba label or not), Biba must
2771	 * authorize the relabel.
2772	 */
2773	if (!mac_biba_effective_in_range(old, subj))
2774		return (EPERM);
2775
2776	/*
2777	 * If the Biba label is to be changed, authorize as appropriate.
2778	 */
2779	if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
2780		/*
2781		 * To change the Biba label on a vnode, the new vnode label
2782		 * must be in the subject range.
2783		 */
2784		if (!mac_biba_effective_in_range(new, subj))
2785			return (EPERM);
2786
2787		/*
2788		 * To change the Biba label on the vnode to be EQUAL,
2789		 * the subject must have appropriate privilege.
2790		 */
2791		if (mac_biba_contains_equal(new)) {
2792			error = mac_biba_subject_privileged(subj);
2793			if (error)
2794				return (error);
2795		}
2796	}
2797
2798	return (0);
2799}
2800
2801static int
2802mac_biba_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
2803    struct label *dlabel, struct vnode *vp, struct label *label,
2804    struct componentname *cnp)
2805{
2806	struct mac_biba *subj, *obj;
2807
2808	if (!mac_biba_enabled)
2809		return (0);
2810
2811	subj = SLOT(cred->cr_label);
2812	obj = SLOT(dlabel);
2813
2814	if (!mac_biba_dominate_effective(subj, obj))
2815		return (EACCES);
2816
2817	obj = SLOT(label);
2818
2819	if (!mac_biba_dominate_effective(subj, obj))
2820		return (EACCES);
2821
2822	return (0);
2823}
2824
2825static int
2826mac_biba_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
2827    struct label *dlabel, struct vnode *vp, struct label *label, int samedir,
2828    struct componentname *cnp)
2829{
2830	struct mac_biba *subj, *obj;
2831
2832	if (!mac_biba_enabled)
2833		return (0);
2834
2835	subj = SLOT(cred->cr_label);
2836	obj = SLOT(dlabel);
2837
2838	if (!mac_biba_dominate_effective(subj, obj))
2839		return (EACCES);
2840
2841	if (vp != NULL) {
2842		obj = SLOT(label);
2843
2844		if (!mac_biba_dominate_effective(subj, obj))
2845			return (EACCES);
2846	}
2847
2848	return (0);
2849}
2850
2851static int
2852mac_biba_check_vnode_revoke(struct ucred *cred, struct vnode *vp,
2853    struct label *label)
2854{
2855	struct mac_biba *subj, *obj;
2856
2857	if (!mac_biba_enabled)
2858		return (0);
2859
2860	subj = SLOT(cred->cr_label);
2861	obj = SLOT(label);
2862
2863	if (!mac_biba_dominate_effective(subj, obj))
2864		return (EACCES);
2865
2866	return (0);
2867}
2868
2869static int
2870mac_biba_check_vnode_setacl(struct ucred *cred, struct vnode *vp,
2871    struct label *label, acl_type_t type, struct acl *acl)
2872{
2873	struct mac_biba *subj, *obj;
2874
2875	if (!mac_biba_enabled)
2876		return (0);
2877
2878	subj = SLOT(cred->cr_label);
2879	obj = SLOT(label);
2880
2881	if (!mac_biba_dominate_effective(subj, obj))
2882		return (EACCES);
2883
2884	return (0);
2885}
2886
2887static int
2888mac_biba_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
2889    struct label *vnodelabel, int attrnamespace, const char *name,
2890    struct uio *uio)
2891{
2892	struct mac_biba *subj, *obj;
2893
2894	if (!mac_biba_enabled)
2895		return (0);
2896
2897	subj = SLOT(cred->cr_label);
2898	obj = SLOT(vnodelabel);
2899
2900	if (!mac_biba_dominate_effective(subj, obj))
2901		return (EACCES);
2902
2903	/* XXX: protect the MAC EA in a special way? */
2904
2905	return (0);
2906}
2907
2908static int
2909mac_biba_check_vnode_setflags(struct ucred *cred, struct vnode *vp,
2910    struct label *vnodelabel, u_long flags)
2911{
2912	struct mac_biba *subj, *obj;
2913
2914	if (!mac_biba_enabled)
2915		return (0);
2916
2917	subj = SLOT(cred->cr_label);
2918	obj = SLOT(vnodelabel);
2919
2920	if (!mac_biba_dominate_effective(subj, obj))
2921		return (EACCES);
2922
2923	return (0);
2924}
2925
2926static int
2927mac_biba_check_vnode_setmode(struct ucred *cred, struct vnode *vp,
2928    struct label *vnodelabel, mode_t mode)
2929{
2930	struct mac_biba *subj, *obj;
2931
2932	if (!mac_biba_enabled)
2933		return (0);
2934
2935	subj = SLOT(cred->cr_label);
2936	obj = SLOT(vnodelabel);
2937
2938	if (!mac_biba_dominate_effective(subj, obj))
2939		return (EACCES);
2940
2941	return (0);
2942}
2943
2944static int
2945mac_biba_check_vnode_setowner(struct ucred *cred, struct vnode *vp,
2946    struct label *vnodelabel, uid_t uid, gid_t gid)
2947{
2948	struct mac_biba *subj, *obj;
2949
2950	if (!mac_biba_enabled)
2951		return (0);
2952
2953	subj = SLOT(cred->cr_label);
2954	obj = SLOT(vnodelabel);
2955
2956	if (!mac_biba_dominate_effective(subj, obj))
2957		return (EACCES);
2958
2959	return (0);
2960}
2961
2962static int
2963mac_biba_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
2964    struct label *vnodelabel, struct timespec atime, struct timespec mtime)
2965{
2966	struct mac_biba *subj, *obj;
2967
2968	if (!mac_biba_enabled)
2969		return (0);
2970
2971	subj = SLOT(cred->cr_label);
2972	obj = SLOT(vnodelabel);
2973
2974	if (!mac_biba_dominate_effective(subj, obj))
2975		return (EACCES);
2976
2977	return (0);
2978}
2979
2980static int
2981mac_biba_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
2982    struct vnode *vp, struct label *vnodelabel)
2983{
2984	struct mac_biba *subj, *obj;
2985
2986	if (!mac_biba_enabled)
2987		return (0);
2988
2989	subj = SLOT(active_cred->cr_label);
2990	obj = SLOT(vnodelabel);
2991
2992	if (!mac_biba_dominate_effective(obj, subj))
2993		return (EACCES);
2994
2995	return (0);
2996}
2997
2998static int
2999mac_biba_check_vnode_write(struct ucred *active_cred,
3000    struct ucred *file_cred, struct vnode *vp, struct label *label)
3001{
3002	struct mac_biba *subj, *obj;
3003
3004	if (!mac_biba_enabled || !revocation_enabled)
3005		return (0);
3006
3007	subj = SLOT(active_cred->cr_label);
3008	obj = SLOT(label);
3009
3010	if (!mac_biba_dominate_effective(subj, obj))
3011		return (EACCES);
3012
3013	return (0);
3014}
3015
3016static struct mac_policy_ops mac_biba_ops =
3017{
3018	.mpo_init = mac_biba_init,
3019	.mpo_init_bpfdesc_label = mac_biba_init_label,
3020	.mpo_init_cred_label = mac_biba_init_label,
3021	.mpo_init_devfsdirent_label = mac_biba_init_label,
3022	.mpo_init_ifnet_label = mac_biba_init_label,
3023	.mpo_init_inpcb_label = mac_biba_init_label_waitcheck,
3024	.mpo_init_sysv_msgmsg_label = mac_biba_init_label,
3025	.mpo_init_sysv_msgqueue_label = mac_biba_init_label,
3026	.mpo_init_sysv_sem_label = mac_biba_init_label,
3027	.mpo_init_sysv_shm_label = mac_biba_init_label,
3028	.mpo_init_ipq_label = mac_biba_init_label_waitcheck,
3029	.mpo_init_mbuf_label = mac_biba_init_label_waitcheck,
3030	.mpo_init_mount_label = mac_biba_init_label,
3031	.mpo_init_mount_fs_label = mac_biba_init_label,
3032	.mpo_init_pipe_label = mac_biba_init_label,
3033	.mpo_init_posix_sem_label = mac_biba_init_label,
3034	.mpo_init_socket_label = mac_biba_init_label_waitcheck,
3035	.mpo_init_socket_peer_label = mac_biba_init_label_waitcheck,
3036	.mpo_init_vnode_label = mac_biba_init_label,
3037	.mpo_destroy_bpfdesc_label = mac_biba_destroy_label,
3038	.mpo_destroy_cred_label = mac_biba_destroy_label,
3039	.mpo_destroy_devfsdirent_label = mac_biba_destroy_label,
3040	.mpo_destroy_ifnet_label = mac_biba_destroy_label,
3041	.mpo_destroy_inpcb_label = mac_biba_destroy_label,
3042	.mpo_destroy_sysv_msgmsg_label = mac_biba_destroy_label,
3043	.mpo_destroy_sysv_msgqueue_label = mac_biba_destroy_label,
3044	.mpo_destroy_sysv_sem_label = mac_biba_destroy_label,
3045	.mpo_destroy_sysv_shm_label = mac_biba_destroy_label,
3046	.mpo_destroy_ipq_label = mac_biba_destroy_label,
3047	.mpo_destroy_mbuf_label = mac_biba_destroy_label,
3048	.mpo_destroy_mount_label = mac_biba_destroy_label,
3049	.mpo_destroy_mount_fs_label = mac_biba_destroy_label,
3050	.mpo_destroy_pipe_label = mac_biba_destroy_label,
3051	.mpo_destroy_posix_sem_label = mac_biba_destroy_label,
3052	.mpo_destroy_socket_label = mac_biba_destroy_label,
3053	.mpo_destroy_socket_peer_label = mac_biba_destroy_label,
3054	.mpo_destroy_vnode_label = mac_biba_destroy_label,
3055	.mpo_copy_cred_label = mac_biba_copy_label,
3056	.mpo_copy_ifnet_label = mac_biba_copy_label,
3057	.mpo_copy_mbuf_label = mac_biba_copy_label,
3058	.mpo_copy_pipe_label = mac_biba_copy_label,
3059	.mpo_copy_socket_label = mac_biba_copy_label,
3060	.mpo_copy_vnode_label = mac_biba_copy_label,
3061	.mpo_externalize_cred_label = mac_biba_externalize_label,
3062	.mpo_externalize_ifnet_label = mac_biba_externalize_label,
3063	.mpo_externalize_pipe_label = mac_biba_externalize_label,
3064	.mpo_externalize_socket_label = mac_biba_externalize_label,
3065	.mpo_externalize_socket_peer_label = mac_biba_externalize_label,
3066	.mpo_externalize_vnode_label = mac_biba_externalize_label,
3067	.mpo_internalize_cred_label = mac_biba_internalize_label,
3068	.mpo_internalize_ifnet_label = mac_biba_internalize_label,
3069	.mpo_internalize_pipe_label = mac_biba_internalize_label,
3070	.mpo_internalize_socket_label = mac_biba_internalize_label,
3071	.mpo_internalize_vnode_label = mac_biba_internalize_label,
3072	.mpo_create_devfs_device = mac_biba_create_devfs_device,
3073	.mpo_create_devfs_directory = mac_biba_create_devfs_directory,
3074	.mpo_create_devfs_symlink = mac_biba_create_devfs_symlink,
3075	.mpo_create_mount = mac_biba_create_mount,
3076	.mpo_relabel_vnode = mac_biba_relabel_vnode,
3077	.mpo_update_devfsdirent = mac_biba_update_devfsdirent,
3078	.mpo_associate_vnode_devfs = mac_biba_associate_vnode_devfs,
3079	.mpo_associate_vnode_extattr = mac_biba_associate_vnode_extattr,
3080	.mpo_associate_vnode_singlelabel = mac_biba_associate_vnode_singlelabel,
3081	.mpo_create_vnode_extattr = mac_biba_create_vnode_extattr,
3082	.mpo_setlabel_vnode_extattr = mac_biba_setlabel_vnode_extattr,
3083	.mpo_create_mbuf_from_socket = mac_biba_create_mbuf_from_socket,
3084	.mpo_create_pipe = mac_biba_create_pipe,
3085	.mpo_create_posix_sem = mac_biba_create_posix_sem,
3086	.mpo_create_socket = mac_biba_create_socket,
3087	.mpo_create_socket_from_socket = mac_biba_create_socket_from_socket,
3088	.mpo_relabel_pipe = mac_biba_relabel_pipe,
3089	.mpo_relabel_socket = mac_biba_relabel_socket,
3090	.mpo_set_socket_peer_from_mbuf = mac_biba_set_socket_peer_from_mbuf,
3091	.mpo_set_socket_peer_from_socket = mac_biba_set_socket_peer_from_socket,
3092	.mpo_create_bpfdesc = mac_biba_create_bpfdesc,
3093	.mpo_create_datagram_from_ipq = mac_biba_create_datagram_from_ipq,
3094	.mpo_create_fragment = mac_biba_create_fragment,
3095	.mpo_create_ifnet = mac_biba_create_ifnet,
3096	.mpo_create_inpcb_from_socket = mac_biba_create_inpcb_from_socket,
3097	.mpo_create_sysv_msgmsg = mac_biba_create_sysv_msgmsg,
3098	.mpo_create_sysv_msgqueue = mac_biba_create_sysv_msgqueue,
3099	.mpo_create_sysv_sem = mac_biba_create_sysv_sem,
3100	.mpo_create_sysv_shm = mac_biba_create_sysv_shm,
3101	.mpo_create_ipq = mac_biba_create_ipq,
3102	.mpo_create_mbuf_from_inpcb = mac_biba_create_mbuf_from_inpcb,
3103	.mpo_create_mbuf_linklayer = mac_biba_create_mbuf_linklayer,
3104	.mpo_create_mbuf_from_bpfdesc = mac_biba_create_mbuf_from_bpfdesc,
3105	.mpo_create_mbuf_from_ifnet = mac_biba_create_mbuf_from_ifnet,
3106	.mpo_create_mbuf_multicast_encap = mac_biba_create_mbuf_multicast_encap,
3107	.mpo_create_mbuf_netlayer = mac_biba_create_mbuf_netlayer,
3108	.mpo_fragment_match = mac_biba_fragment_match,
3109	.mpo_relabel_ifnet = mac_biba_relabel_ifnet,
3110	.mpo_update_ipq = mac_biba_update_ipq,
3111	.mpo_inpcb_sosetlabel = mac_biba_inpcb_sosetlabel,
3112	.mpo_create_proc0 = mac_biba_create_proc0,
3113	.mpo_create_proc1 = mac_biba_create_proc1,
3114	.mpo_relabel_cred = mac_biba_relabel_cred,
3115	.mpo_cleanup_sysv_msgmsg = mac_biba_cleanup_sysv_msgmsg,
3116	.mpo_cleanup_sysv_msgqueue = mac_biba_cleanup_sysv_msgqueue,
3117	.mpo_cleanup_sysv_sem = mac_biba_cleanup_sysv_sem,
3118	.mpo_cleanup_sysv_shm = mac_biba_cleanup_sysv_shm,
3119	.mpo_check_bpfdesc_receive = mac_biba_check_bpfdesc_receive,
3120	.mpo_check_cred_relabel = mac_biba_check_cred_relabel,
3121	.mpo_check_cred_visible = mac_biba_check_cred_visible,
3122	.mpo_check_ifnet_relabel = mac_biba_check_ifnet_relabel,
3123	.mpo_check_ifnet_transmit = mac_biba_check_ifnet_transmit,
3124	.mpo_check_inpcb_deliver = mac_biba_check_inpcb_deliver,
3125	.mpo_check_sysv_msgrcv = mac_biba_check_sysv_msgrcv,
3126	.mpo_check_sysv_msgrmid = mac_biba_check_sysv_msgrmid,
3127	.mpo_check_sysv_msqget = mac_biba_check_sysv_msqget,
3128	.mpo_check_sysv_msqsnd = mac_biba_check_sysv_msqsnd,
3129	.mpo_check_sysv_msqrcv = mac_biba_check_sysv_msqrcv,
3130	.mpo_check_sysv_msqctl = mac_biba_check_sysv_msqctl,
3131	.mpo_check_sysv_semctl = mac_biba_check_sysv_semctl,
3132	.mpo_check_sysv_semget = mac_biba_check_sysv_semget,
3133	.mpo_check_sysv_semop = mac_biba_check_sysv_semop,
3134	.mpo_check_sysv_shmat = mac_biba_check_sysv_shmat,
3135	.mpo_check_sysv_shmctl = mac_biba_check_sysv_shmctl,
3136	.mpo_check_sysv_shmget = mac_biba_check_sysv_shmget,
3137	.mpo_check_kld_load = mac_biba_check_kld_load,
3138	.mpo_check_kld_unload = mac_biba_check_kld_unload,
3139	.mpo_check_mount_stat = mac_biba_check_mount_stat,
3140	.mpo_check_pipe_ioctl = mac_biba_check_pipe_ioctl,
3141	.mpo_check_pipe_poll = mac_biba_check_pipe_poll,
3142	.mpo_check_pipe_read = mac_biba_check_pipe_read,
3143	.mpo_check_pipe_relabel = mac_biba_check_pipe_relabel,
3144	.mpo_check_pipe_stat = mac_biba_check_pipe_stat,
3145	.mpo_check_pipe_write = mac_biba_check_pipe_write,
3146	.mpo_check_posix_sem_destroy = mac_biba_check_posix_sem_write,
3147	.mpo_check_posix_sem_getvalue = mac_biba_check_posix_sem_rdonly,
3148	.mpo_check_posix_sem_open = mac_biba_check_posix_sem_write,
3149	.mpo_check_posix_sem_post = mac_biba_check_posix_sem_write,
3150	.mpo_check_posix_sem_unlink = mac_biba_check_posix_sem_write,
3151	.mpo_check_posix_sem_wait = mac_biba_check_posix_sem_write,
3152	.mpo_check_proc_debug = mac_biba_check_proc_debug,
3153	.mpo_check_proc_sched = mac_biba_check_proc_sched,
3154	.mpo_check_proc_signal = mac_biba_check_proc_signal,
3155	.mpo_check_socket_deliver = mac_biba_check_socket_deliver,
3156	.mpo_check_socket_relabel = mac_biba_check_socket_relabel,
3157	.mpo_check_socket_visible = mac_biba_check_socket_visible,
3158	.mpo_check_sysarch_ioperm = mac_biba_check_sysarch_ioperm,
3159	.mpo_check_system_acct = mac_biba_check_system_acct,
3160	.mpo_check_system_settime = mac_biba_check_system_settime,
3161	.mpo_check_system_swapon = mac_biba_check_system_swapon,
3162	.mpo_check_system_swapoff = mac_biba_check_system_swapoff,
3163	.mpo_check_system_sysctl = mac_biba_check_system_sysctl,
3164	.mpo_check_vnode_access = mac_biba_check_vnode_open,
3165	.mpo_check_vnode_chdir = mac_biba_check_vnode_chdir,
3166	.mpo_check_vnode_chroot = mac_biba_check_vnode_chroot,
3167	.mpo_check_vnode_create = mac_biba_check_vnode_create,
3168	.mpo_check_vnode_delete = mac_biba_check_vnode_delete,
3169	.mpo_check_vnode_deleteacl = mac_biba_check_vnode_deleteacl,
3170	.mpo_check_vnode_deleteextattr = mac_biba_check_vnode_deleteextattr,
3171	.mpo_check_vnode_exec = mac_biba_check_vnode_exec,
3172	.mpo_check_vnode_getacl = mac_biba_check_vnode_getacl,
3173	.mpo_check_vnode_getextattr = mac_biba_check_vnode_getextattr,
3174	.mpo_check_vnode_link = mac_biba_check_vnode_link,
3175	.mpo_check_vnode_listextattr = mac_biba_check_vnode_listextattr,
3176	.mpo_check_vnode_lookup = mac_biba_check_vnode_lookup,
3177	.mpo_check_vnode_mmap = mac_biba_check_vnode_mmap,
3178	.mpo_check_vnode_open = mac_biba_check_vnode_open,
3179	.mpo_check_vnode_poll = mac_biba_check_vnode_poll,
3180	.mpo_check_vnode_read = mac_biba_check_vnode_read,
3181	.mpo_check_vnode_readdir = mac_biba_check_vnode_readdir,
3182	.mpo_check_vnode_readlink = mac_biba_check_vnode_readlink,
3183	.mpo_check_vnode_relabel = mac_biba_check_vnode_relabel,
3184	.mpo_check_vnode_rename_from = mac_biba_check_vnode_rename_from,
3185	.mpo_check_vnode_rename_to = mac_biba_check_vnode_rename_to,
3186	.mpo_check_vnode_revoke = mac_biba_check_vnode_revoke,
3187	.mpo_check_vnode_setacl = mac_biba_check_vnode_setacl,
3188	.mpo_check_vnode_setextattr = mac_biba_check_vnode_setextattr,
3189	.mpo_check_vnode_setflags = mac_biba_check_vnode_setflags,
3190	.mpo_check_vnode_setmode = mac_biba_check_vnode_setmode,
3191	.mpo_check_vnode_setowner = mac_biba_check_vnode_setowner,
3192	.mpo_check_vnode_setutimes = mac_biba_check_vnode_setutimes,
3193	.mpo_check_vnode_stat = mac_biba_check_vnode_stat,
3194	.mpo_check_vnode_write = mac_biba_check_vnode_write,
3195};
3196
3197MAC_POLICY_SET(&mac_biba_ops, mac_biba, "TrustedBSD MAC/Biba",
3198    MPC_LOADTIME_FLAG_NOTLATE | MPC_LOADTIME_FLAG_LABELMBUFS, &mac_biba_slot);
3199