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