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