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