mac_biba.c revision 105722
1/*-
2 * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson
3 * Copyright (c) 2001, 2002 Networks Associates Technology, 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 NAI Labs,
9 * the Security Research Division of Network Associates, 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 * 3. The names of the authors may not be used to endorse or promote
22 *    products derived from this software without specific prior written
23 *    permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 *
37 * $FreeBSD: head/sys/security/mac_biba/mac_biba.c 105722 2002-10-22 17:02:42Z rwatson $
38 */
39
40/*
41 * Developed by the TrustedBSD Project.
42 * Biba fixed label mandatory integrity policy.
43 */
44
45#include <sys/types.h>
46#include <sys/param.h>
47#include <sys/acl.h>
48#include <sys/conf.h>
49#include <sys/kernel.h>
50#include <sys/mac.h>
51#include <sys/malloc.h>
52#include <sys/mount.h>
53#include <sys/proc.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
65#include <fs/devfs/devfs.h>
66
67#include <net/bpfdesc.h>
68#include <net/if.h>
69#include <net/if_types.h>
70#include <net/if_var.h>
71
72#include <netinet/in.h>
73#include <netinet/ip_var.h>
74
75#include <vm/vm.h>
76
77#include <sys/mac_policy.h>
78
79#include <security/mac_biba/mac_biba.h>
80
81SYSCTL_DECL(_security_mac);
82
83SYSCTL_NODE(_security_mac, OID_AUTO, biba, CTLFLAG_RW, 0,
84    "TrustedBSD mac_biba policy controls");
85
86static int	mac_biba_enabled = 0;
87SYSCTL_INT(_security_mac_biba, OID_AUTO, enabled, CTLFLAG_RW,
88    &mac_biba_enabled, 0, "Enforce MAC/Biba policy");
89TUNABLE_INT("security.mac.biba.enabled", &mac_biba_enabled);
90
91static int	destroyed_not_inited;
92SYSCTL_INT(_security_mac_biba, OID_AUTO, destroyed_not_inited, CTLFLAG_RD,
93    &destroyed_not_inited, 0, "Count of labels destroyed but not inited");
94
95static int	trust_all_interfaces = 0;
96SYSCTL_INT(_security_mac_biba, OID_AUTO, trust_all_interfaces, CTLFLAG_RD,
97    &trust_all_interfaces, 0, "Consider all interfaces 'trusted' by MAC/Biba");
98TUNABLE_INT("security.mac.biba.trust_all_interfaces", &trust_all_interfaces);
99
100static char	trusted_interfaces[128];
101SYSCTL_STRING(_security_mac_biba, OID_AUTO, trusted_interfaces, CTLFLAG_RD,
102    trusted_interfaces, 0, "Interfaces considered 'trusted' by MAC/Biba");
103TUNABLE_STR("security.mac.biba.trusted_interfaces", trusted_interfaces,
104    sizeof(trusted_interfaces));
105
106static int	max_compartments = MAC_BIBA_MAX_COMPARTMENTS;
107SYSCTL_INT(_security_mac_biba, OID_AUTO, max_compartments, CTLFLAG_RD,
108    &max_compartments, 0, "Maximum supported compartments");
109
110static int	ptys_equal = 0;
111SYSCTL_INT(_security_mac_biba, OID_AUTO, ptys_equal, CTLFLAG_RW,
112    &ptys_equal, 0, "Label pty devices as biba/equal on create");
113TUNABLE_INT("security.mac.biba.ptys_equal", &ptys_equal);
114
115static int	revocation_enabled = 0;
116SYSCTL_INT(_security_mac_biba, OID_AUTO, revocation_enabled, CTLFLAG_RW,
117    &revocation_enabled, 0, "Revoke access to objects on relabel");
118TUNABLE_INT("security.mac.biba.revocation_enabled", &revocation_enabled);
119
120static int	mac_biba_slot;
121#define	SLOT(l)	((struct mac_biba *)LABEL_TO_SLOT((l), mac_biba_slot).l_ptr)
122
123MALLOC_DEFINE(M_MACBIBA, "biba label", "MAC/Biba labels");
124
125static __inline int
126biba_bit_set_empty(u_char *set) {
127	int i;
128
129	for (i = 0; i < MAC_BIBA_MAX_COMPARTMENTS >> 3; i++)
130		if (set[i] != 0)
131			return (0);
132	return (1);
133}
134
135static struct mac_biba *
136biba_alloc(int flag)
137{
138	struct mac_biba *mac_biba;
139
140	mac_biba = malloc(sizeof(struct mac_biba), M_MACBIBA, M_ZERO | flag);
141
142	return (mac_biba);
143}
144
145static void
146biba_free(struct mac_biba *mac_biba)
147{
148
149	if (mac_biba != NULL)
150		free(mac_biba, M_MACBIBA);
151	else
152		atomic_add_int(&destroyed_not_inited, 1);
153}
154
155static int
156biba_atmostflags(struct mac_biba *mac_biba, int flags)
157{
158
159	if ((mac_biba->mb_flags & flags) != mac_biba->mb_flags)
160		return (EINVAL);
161	return (0);
162}
163
164static int
165mac_biba_dominate_element(struct mac_biba_element *a,
166    struct mac_biba_element *b)
167{
168	int bit;
169
170	switch(a->mbe_type) {
171	case MAC_BIBA_TYPE_EQUAL:
172	case MAC_BIBA_TYPE_HIGH:
173		return (1);
174
175	case MAC_BIBA_TYPE_LOW:
176		switch (b->mbe_type) {
177		case MAC_BIBA_TYPE_GRADE:
178		case MAC_BIBA_TYPE_HIGH:
179			return (0);
180
181		case MAC_BIBA_TYPE_EQUAL:
182		case MAC_BIBA_TYPE_LOW:
183			return (1);
184
185		default:
186			panic("mac_biba_dominate_element: b->mbe_type invalid");
187		}
188
189	case MAC_BIBA_TYPE_GRADE:
190		switch (b->mbe_type) {
191		case MAC_BIBA_TYPE_EQUAL:
192		case MAC_BIBA_TYPE_LOW:
193			return (1);
194
195		case MAC_BIBA_TYPE_HIGH:
196			return (0);
197
198		case MAC_BIBA_TYPE_GRADE:
199			for (bit = 1; bit <= MAC_BIBA_MAX_COMPARTMENTS; bit++)
200				if (!MAC_BIBA_BIT_TEST(bit,
201				    a->mbe_compartments) &&
202				    MAC_BIBA_BIT_TEST(bit, b->mbe_compartments))
203					return (0);
204			return (a->mbe_grade >= b->mbe_grade);
205
206		default:
207			panic("mac_biba_dominate_element: b->mbe_type invalid");
208		}
209
210	default:
211		panic("mac_biba_dominate_element: a->mbe_type invalid");
212	}
213
214	return (0);
215}
216
217static int
218mac_biba_range_in_range(struct mac_biba *rangea, struct mac_biba *rangeb)
219{
220
221	return (mac_biba_dominate_element(&rangeb->mb_rangehigh,
222	    &rangea->mb_rangehigh) &&
223	    mac_biba_dominate_element(&rangea->mb_rangelow,
224	    &rangeb->mb_rangelow));
225}
226
227static int
228mac_biba_single_in_range(struct mac_biba *single, struct mac_biba *range)
229{
230
231	KASSERT((single->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
232	    ("mac_biba_single_in_range: a not single"));
233	KASSERT((range->mb_flags & MAC_BIBA_FLAG_RANGE) != 0,
234	    ("mac_biba_single_in_range: b not range"));
235
236	return (mac_biba_dominate_element(&range->mb_rangehigh,
237	    &single->mb_single) &&
238	    mac_biba_dominate_element(&single->mb_single,
239	    &range->mb_rangelow));
240
241	return (1);
242}
243
244static int
245mac_biba_dominate_single(struct mac_biba *a, struct mac_biba *b)
246{
247	KASSERT((a->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
248	    ("mac_biba_dominate_single: a not single"));
249	KASSERT((b->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
250	    ("mac_biba_dominate_single: b not single"));
251
252	return (mac_biba_dominate_element(&a->mb_single, &b->mb_single));
253}
254
255static int
256mac_biba_equal_element(struct mac_biba_element *a, struct mac_biba_element *b)
257{
258
259	if (a->mbe_type == MAC_BIBA_TYPE_EQUAL ||
260	    b->mbe_type == MAC_BIBA_TYPE_EQUAL)
261		return (1);
262
263	return (a->mbe_type == b->mbe_type && a->mbe_grade == b->mbe_grade);
264}
265
266static int
267mac_biba_equal_single(struct mac_biba *a, struct mac_biba *b)
268{
269
270	KASSERT((a->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
271	    ("mac_biba_equal_single: a not single"));
272	KASSERT((b->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
273	    ("mac_biba_equal_single: b not single"));
274
275	return (mac_biba_equal_element(&a->mb_single, &b->mb_single));
276}
277
278static int
279mac_biba_contains_equal(struct mac_biba *mac_biba)
280{
281
282	if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE)
283		if (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_EQUAL)
284			return (1);
285
286	if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
287		if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL)
288			return (1);
289		if (mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL)
290			return (1);
291	}
292
293	return (0);
294}
295
296static int
297mac_biba_subject_equal_ok(struct mac_biba *mac_biba)
298{
299
300	KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAGS_BOTH) ==
301	    MAC_BIBA_FLAGS_BOTH,
302	    ("mac_biba_subject_equal_ok: subject doesn't have both labels"));
303
304	/* If the single is EQUAL, it's ok. */
305	if (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_EQUAL)
306		return (0);
307
308	/* If either range endpoint is EQUAL, it's ok. */
309	if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL ||
310	    mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL)
311		return (0);
312
313	/* If the range is low-high, it's ok. */
314	if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_LOW &&
315	    mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_HIGH)
316		return (0);
317
318	/* It's not ok. */
319	return (EPERM);
320}
321
322static int
323mac_biba_valid(struct mac_biba *mac_biba)
324{
325
326	if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) {
327		switch (mac_biba->mb_single.mbe_type) {
328		case MAC_BIBA_TYPE_GRADE:
329			break;
330
331		case MAC_BIBA_TYPE_EQUAL:
332		case MAC_BIBA_TYPE_HIGH:
333		case MAC_BIBA_TYPE_LOW:
334			if (mac_biba->mb_single.mbe_grade != 0 ||
335			    !MAC_BIBA_BIT_SET_EMPTY(
336			    mac_biba->mb_single.mbe_compartments))
337				return (EINVAL);
338			break;
339
340		default:
341			return (EINVAL);
342		}
343	} else {
344		if (mac_biba->mb_single.mbe_type != MAC_BIBA_TYPE_UNDEF)
345			return (EINVAL);
346	}
347
348	if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
349		switch (mac_biba->mb_rangelow.mbe_type) {
350		case MAC_BIBA_TYPE_GRADE:
351			break;
352
353		case MAC_BIBA_TYPE_EQUAL:
354		case MAC_BIBA_TYPE_HIGH:
355		case MAC_BIBA_TYPE_LOW:
356			if (mac_biba->mb_rangelow.mbe_grade != 0 ||
357			    !MAC_BIBA_BIT_SET_EMPTY(
358			    mac_biba->mb_rangelow.mbe_compartments))
359				return (EINVAL);
360			break;
361
362		default:
363			return (EINVAL);
364		}
365
366		switch (mac_biba->mb_rangehigh.mbe_type) {
367		case MAC_BIBA_TYPE_GRADE:
368			break;
369
370		case MAC_BIBA_TYPE_EQUAL:
371		case MAC_BIBA_TYPE_HIGH:
372		case MAC_BIBA_TYPE_LOW:
373			if (mac_biba->mb_rangehigh.mbe_grade != 0 ||
374			    !MAC_BIBA_BIT_SET_EMPTY(
375			    mac_biba->mb_rangehigh.mbe_compartments))
376				return (EINVAL);
377			break;
378
379		default:
380			return (EINVAL);
381		}
382		if (!mac_biba_dominate_element(&mac_biba->mb_rangehigh,
383		    &mac_biba->mb_rangelow))
384			return (EINVAL);
385	} else {
386		if (mac_biba->mb_rangelow.mbe_type != MAC_BIBA_TYPE_UNDEF ||
387		    mac_biba->mb_rangehigh.mbe_type != MAC_BIBA_TYPE_UNDEF)
388			return (EINVAL);
389	}
390
391	return (0);
392}
393
394static void
395mac_biba_set_range(struct mac_biba *mac_biba, u_short typelow,
396    u_short gradelow, u_char *compartmentslow, u_short typehigh,
397    u_short gradehigh, u_char *compartmentshigh)
398{
399
400	mac_biba->mb_rangelow.mbe_type = typelow;
401	mac_biba->mb_rangelow.mbe_grade = gradelow;
402	if (compartmentslow != NULL)
403		memcpy(mac_biba->mb_rangelow.mbe_compartments,
404		    compartmentslow,
405		    sizeof(mac_biba->mb_rangelow.mbe_compartments));
406	mac_biba->mb_rangehigh.mbe_type = typehigh;
407	mac_biba->mb_rangehigh.mbe_grade = gradehigh;
408	if (compartmentshigh != NULL)
409		memcpy(mac_biba->mb_rangehigh.mbe_compartments,
410		    compartmentshigh,
411		    sizeof(mac_biba->mb_rangehigh.mbe_compartments));
412	mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE;
413}
414
415static void
416mac_biba_set_single(struct mac_biba *mac_biba, u_short type, u_short grade,
417    u_char *compartments)
418{
419
420	mac_biba->mb_single.mbe_type = type;
421	mac_biba->mb_single.mbe_grade = grade;
422	if (compartments != NULL)
423		memcpy(mac_biba->mb_single.mbe_compartments, compartments,
424		    sizeof(mac_biba->mb_single.mbe_compartments));
425	mac_biba->mb_flags |= MAC_BIBA_FLAG_SINGLE;
426}
427
428static void
429mac_biba_copy_range(struct mac_biba *labelfrom, struct mac_biba *labelto)
430{
431
432	KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_RANGE) != 0,
433	    ("mac_biba_copy_range: labelfrom not range"));
434
435	labelto->mb_rangelow = labelfrom->mb_rangelow;
436	labelto->mb_rangehigh = labelfrom->mb_rangehigh;
437	labelto->mb_flags |= MAC_BIBA_FLAG_RANGE;
438}
439
440static void
441mac_biba_copy_single(struct mac_biba *labelfrom, struct mac_biba *labelto)
442{
443
444	KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
445	    ("mac_biba_copy_single: labelfrom not single"));
446
447	labelto->mb_single = labelfrom->mb_single;
448	labelto->mb_flags |= MAC_BIBA_FLAG_SINGLE;
449}
450
451static void
452mac_biba_copy(struct mac_biba *source, struct mac_biba *dest)
453{
454
455	if (source->mb_flags & MAC_BIBA_FLAG_SINGLE)
456		mac_biba_copy_single(source, dest);
457	if (source->mb_flags & MAC_BIBA_FLAG_RANGE)
458		mac_biba_copy_range(source, dest);
459}
460
461/*
462 * Policy module operations.
463 */
464static void
465mac_biba_destroy(struct mac_policy_conf *conf)
466{
467
468}
469
470static void
471mac_biba_init(struct mac_policy_conf *conf)
472{
473
474}
475
476/*
477 * Label operations.
478 */
479static void
480mac_biba_init_label(struct label *label)
481{
482
483	SLOT(label) = biba_alloc(M_WAITOK);
484}
485
486static int
487mac_biba_init_label_waitcheck(struct label *label, int flag)
488{
489
490	SLOT(label) = biba_alloc(flag);
491	if (SLOT(label) == NULL)
492		return (ENOMEM);
493
494	return (0);
495}
496
497static void
498mac_biba_destroy_label(struct label *label)
499{
500
501	biba_free(SLOT(label));
502	SLOT(label) = NULL;
503}
504
505/*
506 * mac_biba_element_to_string() is basically an snprintf wrapper with
507 * the same properties as snprintf().  It returns the length it would
508 * have added to the string in the event the string is too short.
509 */
510static size_t
511mac_biba_element_to_string(char *string, size_t size,
512    struct mac_biba_element *element)
513{
514	int pos, bit = 1;
515
516	switch (element->mbe_type) {
517	case MAC_BIBA_TYPE_HIGH:
518		return (snprintf(string, size, "high"));
519
520	case MAC_BIBA_TYPE_LOW:
521		return (snprintf(string, size, "low"));
522
523	case MAC_BIBA_TYPE_EQUAL:
524		return (snprintf(string, size, "equal"));
525
526	case MAC_BIBA_TYPE_GRADE:
527		pos = snprintf(string, size, "%d:", element->mbe_grade);
528		for (bit = 1; bit <= MAC_BIBA_MAX_COMPARTMENTS; bit++) {
529			if (MAC_BIBA_BIT_TEST(bit, element->mbe_compartments))
530				pos += snprintf(string + pos, size - pos,
531				    "%d+", bit);
532		}
533		if (string[pos - 1] == '+' || string[pos - 1] == ':')
534			string[--pos] = NULL;
535		return (pos);
536
537	default:
538		panic("mac_biba_element_to_string: invalid type (%d)",
539		    element->mbe_type);
540	}
541}
542
543static int
544mac_biba_to_string(char *string, size_t size, size_t *caller_len,
545    struct mac_biba *mac_biba)
546{
547	size_t left, len;
548	char *curptr;
549
550	bzero(string, size);
551	curptr = string;
552	left = size;
553
554	if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) {
555		len = mac_biba_element_to_string(curptr, left,
556		    &mac_biba->mb_single);
557		if (len >= left)
558			return (EINVAL);
559		left -= len;
560		curptr += len;
561	}
562
563	if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
564		len = snprintf(curptr, left, "(");
565		if (len >= left)
566			return (EINVAL);
567		left -= len;
568		curptr += len;
569
570		len = mac_biba_element_to_string(curptr, left,
571		    &mac_biba->mb_rangelow);
572		if (len >= left)
573			return (EINVAL);
574		left -= len;
575		curptr += len;
576
577		len = snprintf(curptr, left, "-");
578		if (len >= left)
579			return (EINVAL);
580		left -= len;
581		curptr += len;
582
583		len = mac_biba_element_to_string(curptr, left,
584		    &mac_biba->mb_rangehigh);
585		if (len >= left)
586			return (EINVAL);
587		left -= len;
588		curptr += len;
589
590		len = snprintf(curptr, left, ")");
591		if (len >= left)
592			return (EINVAL);
593		left -= len;
594		curptr += len;
595	}
596
597	*caller_len = strlen(string);
598	return (0);
599}
600
601static int
602mac_biba_externalize_label(struct label *label, char *element_name,
603    char *element_data, size_t size, size_t *len, int *claimed)
604{
605	struct mac_biba *mac_biba;
606	int error;
607
608	if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0)
609		return (0);
610
611	(*claimed)++;
612
613	mac_biba = SLOT(label);
614	error = mac_biba_to_string(element_data, size, len, mac_biba);
615	if (error)
616		return (error);
617
618	*len = strlen(element_data);
619	return (0);
620}
621
622static int
623mac_biba_externalize_vnode_oldmac(struct label *label, struct oldmac *extmac)
624{
625	struct mac_biba *mac_biba;
626
627	mac_biba = SLOT(label);
628
629	if (mac_biba == NULL) {
630		printf("mac_biba_externalize_vnode_oldmac: NULL pointer\n");
631		return (0);
632	}
633
634	extmac->m_biba = *mac_biba;
635
636	return (0);
637}
638
639static int
640mac_biba_parse_element(struct mac_biba_element *element, char *string)
641{
642
643	if (strcmp(string, "high") == 0 ||
644	    strcmp(string, "hi") == 0) {
645		element->mbe_type = MAC_BIBA_TYPE_HIGH;
646		element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
647	} else if (strcmp(string, "low") == 0 ||
648	    strcmp(string, "lo") == 0) {
649		element->mbe_type = MAC_BIBA_TYPE_LOW;
650		element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
651	} else if (strcmp(string, "equal") == 0 ||
652	    strcmp(string, "eq") == 0) {
653		element->mbe_type = MAC_BIBA_TYPE_EQUAL;
654		element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
655	} else {
656		char *p0, *p1;
657		int d;
658
659		p0 = string;
660		d = strtol(p0, &p1, 10);
661
662		if (d < 0 || d > 65535)
663			return (EINVAL);
664		element->mbe_type = MAC_BIBA_TYPE_GRADE;
665		element->mbe_grade = d;
666
667		if (*p1 != ':')  {
668			if (p1 == p0 || *p1 != '\0')
669				return (EINVAL);
670			else
671				return (0);
672		}
673		else
674			if (*(p1 + 1) == '\0')
675				return (0);
676
677		while ((p0 = ++p1)) {
678			d = strtol(p0, &p1, 10);
679			if (d < 1 || d > MAC_BIBA_MAX_COMPARTMENTS)
680				return (EINVAL);
681
682			MAC_BIBA_BIT_SET(d, element->mbe_compartments);
683
684			if (*p1 == '\0')
685				break;
686			if (p1 == p0 || *p1 != '+')
687				return (EINVAL);
688		}
689	}
690
691	return (0);
692}
693
694/*
695 * Note: destructively consumes the string, make a local copy before
696 * calling if that's a problem.
697 */
698static int
699mac_biba_parse(struct mac_biba *mac_biba, char *string)
700{
701	char *range, *rangeend, *rangehigh, *rangelow, *single;
702	int error;
703
704	/* Do we have a range? */
705	single = string;
706	range = index(string, '(');
707	if (range == single)
708		single = NULL;
709	rangelow = rangehigh = NULL;
710	if (range != NULL) {
711		/* Nul terminate the end of the single string. */
712		*range = '\0';
713		range++;
714		rangelow = range;
715		rangehigh = index(rangelow, '-');
716		if (rangehigh == NULL)
717			return (EINVAL);
718		rangehigh++;
719		if (*rangelow == '\0' || *rangehigh == '\0')
720			return (EINVAL);
721		rangeend = index(rangehigh, ')');
722		if (rangeend == NULL)
723			return (EINVAL);
724		if (*(rangeend + 1) != '\0')
725			return (EINVAL);
726		/* Nul terminate the ends of the ranges. */
727		*(rangehigh - 1) = '\0';
728		*rangeend = '\0';
729	}
730	KASSERT((rangelow != NULL && rangehigh != NULL) ||
731	    (rangelow == NULL && rangehigh == NULL),
732	    ("mac_biba_internalize_label: range mismatch"));
733
734	bzero(mac_biba, sizeof(*mac_biba));
735	if (single != NULL) {
736		error = mac_biba_parse_element(&mac_biba->mb_single, single);
737		if (error)
738			return (error);
739		mac_biba->mb_flags |= MAC_BIBA_FLAG_SINGLE;
740	}
741
742	if (rangelow != NULL) {
743		error = mac_biba_parse_element(&mac_biba->mb_rangelow,
744		    rangelow);
745		if (error)
746			return (error);
747		error = mac_biba_parse_element(&mac_biba->mb_rangehigh,
748		    rangehigh);
749		if (error)
750			return (error);
751		mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE;
752	}
753
754	error = mac_biba_valid(mac_biba);
755	if (error)
756		return (error);
757
758	return (0);
759}
760
761static int
762mac_biba_internalize_label(struct label *label, char *element_name,
763    char *element_data, int *claimed)
764{
765	struct mac_biba *mac_biba, mac_biba_temp;
766	int error;
767
768	if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0)
769		return (0);
770
771	(*claimed)++;
772
773	error = mac_biba_parse(&mac_biba_temp, element_data);
774	if (error)
775		return (error);
776
777	mac_biba = SLOT(label);
778	*mac_biba = mac_biba_temp;
779
780	return (0);
781}
782
783static void
784mac_biba_copy_label(struct label *src, struct label *dest)
785{
786
787	*SLOT(dest) = *SLOT(src);
788}
789
790/*
791 * Labeling event operations: file system objects, and things that look
792 * a lot like file system objects.
793 */
794static void
795mac_biba_create_devfs_device(dev_t dev, struct devfs_dirent *devfs_dirent,
796    struct label *label)
797{
798	struct mac_biba *mac_biba;
799	int biba_type;
800
801	mac_biba = SLOT(label);
802	if (strcmp(dev->si_name, "null") == 0 ||
803	    strcmp(dev->si_name, "zero") == 0 ||
804	    strcmp(dev->si_name, "random") == 0 ||
805	    strncmp(dev->si_name, "fd/", strlen("fd/")) == 0)
806		biba_type = MAC_BIBA_TYPE_EQUAL;
807	else if (ptys_equal &&
808	    (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 ||
809	    strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0))
810		biba_type = MAC_BIBA_TYPE_EQUAL;
811	else
812		biba_type = MAC_BIBA_TYPE_HIGH;
813	mac_biba_set_single(mac_biba, biba_type, 0, NULL);
814}
815
816static void
817mac_biba_create_devfs_directory(char *dirname, int dirnamelen,
818    struct devfs_dirent *devfs_dirent, struct label *label)
819{
820	struct mac_biba *mac_biba;
821
822	mac_biba = SLOT(label);
823	mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
824}
825
826static void
827mac_biba_create_devfs_symlink(struct ucred *cred, struct devfs_dirent *dd,
828    struct label *ddlabel, struct devfs_dirent *de, struct label *delabel)
829{
830	struct mac_biba *source, *dest;
831
832	source = SLOT(&cred->cr_label);
833	dest = SLOT(delabel);
834
835	mac_biba_copy_single(source, dest);
836}
837
838static void
839mac_biba_create_devfs_vnode(struct devfs_dirent *devfs_dirent,
840    struct label *direntlabel, struct vnode *vp, struct label *vnodelabel)
841{
842	struct mac_biba *source, *dest;
843
844	source = SLOT(direntlabel);
845	dest = SLOT(vnodelabel);
846	mac_biba_copy_single(source, dest);
847}
848
849static void
850mac_biba_create_vnode(struct ucred *cred, struct vnode *parent,
851    struct label *parentlabel, struct vnode *child, struct label *childlabel)
852{
853	struct mac_biba *source, *dest;
854
855	source = SLOT(&cred->cr_label);
856	dest = SLOT(childlabel);
857
858	mac_biba_copy_single(source, dest);
859}
860
861static void
862mac_biba_create_mount(struct ucred *cred, struct mount *mp,
863    struct label *mntlabel, struct label *fslabel)
864{
865	struct mac_biba *source, *dest;
866
867	source = SLOT(&cred->cr_label);
868	dest = SLOT(mntlabel);
869	mac_biba_copy_single(source, dest);
870	dest = SLOT(fslabel);
871	mac_biba_copy_single(source, dest);
872}
873
874static void
875mac_biba_create_root_mount(struct ucred *cred, struct mount *mp,
876    struct label *mntlabel, struct label *fslabel)
877{
878	struct mac_biba *mac_biba;
879
880	/* Always mount root as high integrity. */
881	mac_biba = SLOT(fslabel);
882	mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
883	mac_biba = SLOT(mntlabel);
884	mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
885}
886
887static void
888mac_biba_relabel_vnode(struct ucred *cred, struct vnode *vp,
889    struct label *vnodelabel, struct label *label)
890{
891	struct mac_biba *source, *dest;
892
893	source = SLOT(label);
894	dest = SLOT(vnodelabel);
895
896	mac_biba_copy(source, dest);
897}
898
899static void
900mac_biba_update_devfsdirent(struct devfs_dirent *devfs_dirent,
901    struct label *direntlabel, struct vnode *vp, struct label *vnodelabel)
902{
903	struct mac_biba *source, *dest;
904
905	source = SLOT(vnodelabel);
906	dest = SLOT(direntlabel);
907
908	mac_biba_copy(source, dest);
909}
910
911static void
912mac_biba_update_procfsvnode(struct vnode *vp, struct label *vnodelabel,
913    struct ucred *cred)
914{
915	struct mac_biba *source, *dest;
916
917	source = SLOT(&cred->cr_label);
918	dest = SLOT(vnodelabel);
919
920	/*
921	 * Only copy the single, not the range, since vnodes only have
922	 * a single.
923	 */
924	mac_biba_copy_single(source, dest);
925}
926
927static int
928mac_biba_update_vnode_from_externalized(struct vnode *vp,
929    struct label *vnodelabel, struct oldmac *extmac)
930{
931	struct mac_biba *source, *dest;
932	int error;
933
934	source = &extmac->m_biba;
935	dest = SLOT(vnodelabel);
936
937	error = mac_biba_valid(source);
938	if (error)
939		return (error);
940
941	if ((source->mb_flags & MAC_BIBA_FLAGS_BOTH) != MAC_BIBA_FLAG_SINGLE)
942		return (EINVAL);
943
944	mac_biba_copy_single(source, dest);
945
946	return (0);
947}
948
949static void
950mac_biba_update_vnode_from_mount(struct vnode *vp, struct label *vnodelabel,
951    struct mount *mp, struct label *fslabel)
952{
953	struct mac_biba *source, *dest;
954
955	source = SLOT(fslabel);
956	dest = SLOT(vnodelabel);
957
958	mac_biba_copy_single(source, dest);
959}
960
961/*
962 * Labeling event operations: IPC object.
963 */
964static void
965mac_biba_create_mbuf_from_socket(struct socket *so, struct label *socketlabel,
966    struct mbuf *m, struct label *mbuflabel)
967{
968	struct mac_biba *source, *dest;
969
970	source = SLOT(socketlabel);
971	dest = SLOT(mbuflabel);
972
973	mac_biba_copy_single(source, dest);
974}
975
976static void
977mac_biba_create_socket(struct ucred *cred, struct socket *socket,
978    struct label *socketlabel)
979{
980	struct mac_biba *source, *dest;
981
982	source = SLOT(&cred->cr_label);
983	dest = SLOT(socketlabel);
984
985	mac_biba_copy_single(source, dest);
986}
987
988static void
989mac_biba_create_pipe(struct ucred *cred, struct pipe *pipe,
990    struct label *pipelabel)
991{
992	struct mac_biba *source, *dest;
993
994	source = SLOT(&cred->cr_label);
995	dest = SLOT(pipelabel);
996
997	mac_biba_copy_single(source, dest);
998}
999
1000static void
1001mac_biba_create_socket_from_socket(struct socket *oldsocket,
1002    struct label *oldsocketlabel, struct socket *newsocket,
1003    struct label *newsocketlabel)
1004{
1005	struct mac_biba *source, *dest;
1006
1007	source = SLOT(oldsocketlabel);
1008	dest = SLOT(newsocketlabel);
1009
1010	mac_biba_copy_single(source, dest);
1011}
1012
1013static void
1014mac_biba_relabel_socket(struct ucred *cred, struct socket *socket,
1015    struct label *socketlabel, struct label *newlabel)
1016{
1017	struct mac_biba *source, *dest;
1018
1019	source = SLOT(newlabel);
1020	dest = SLOT(socketlabel);
1021
1022	mac_biba_copy(source, dest);
1023}
1024
1025static void
1026mac_biba_relabel_pipe(struct ucred *cred, struct pipe *pipe,
1027    struct label *pipelabel, struct label *newlabel)
1028{
1029	struct mac_biba *source, *dest;
1030
1031	source = SLOT(newlabel);
1032	dest = SLOT(pipelabel);
1033
1034	mac_biba_copy(source, dest);
1035}
1036
1037static void
1038mac_biba_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel,
1039    struct socket *socket, struct label *socketpeerlabel)
1040{
1041	struct mac_biba *source, *dest;
1042
1043	source = SLOT(mbuflabel);
1044	dest = SLOT(socketpeerlabel);
1045
1046	mac_biba_copy_single(source, dest);
1047}
1048
1049/*
1050 * Labeling event operations: network objects.
1051 */
1052static void
1053mac_biba_set_socket_peer_from_socket(struct socket *oldsocket,
1054    struct label *oldsocketlabel, struct socket *newsocket,
1055    struct label *newsocketpeerlabel)
1056{
1057	struct mac_biba *source, *dest;
1058
1059	source = SLOT(oldsocketlabel);
1060	dest = SLOT(newsocketpeerlabel);
1061
1062	mac_biba_copy_single(source, dest);
1063}
1064
1065static void
1066mac_biba_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d,
1067    struct label *bpflabel)
1068{
1069	struct mac_biba *source, *dest;
1070
1071	source = SLOT(&cred->cr_label);
1072	dest = SLOT(bpflabel);
1073
1074	mac_biba_copy_single(source, dest);
1075}
1076
1077static void
1078mac_biba_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel)
1079{
1080	char tifname[IFNAMSIZ], ifname[IFNAMSIZ], *p, *q;
1081	char tiflist[sizeof(trusted_interfaces)];
1082	struct mac_biba *dest;
1083	int len, grade;
1084
1085	dest = SLOT(ifnetlabel);
1086
1087	if (ifnet->if_type == IFT_LOOP) {
1088		grade = MAC_BIBA_TYPE_EQUAL;
1089		goto set;
1090	}
1091
1092	if (trust_all_interfaces) {
1093		grade = MAC_BIBA_TYPE_HIGH;
1094		goto set;
1095	}
1096
1097	grade = MAC_BIBA_TYPE_LOW;
1098
1099	if (trusted_interfaces[0] == '\0' ||
1100	    !strvalid(trusted_interfaces, sizeof(trusted_interfaces)))
1101		goto set;
1102
1103	for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++)
1104		if(*p != ' ' && *p != '\t')
1105			*q = *p;
1106
1107	snprintf(ifname, IFNAMSIZ, "%s%d", ifnet->if_name, ifnet->if_unit);
1108
1109	for (p = q = tiflist;; p++) {
1110		if (*p == ',' || *p == '\0') {
1111			len = p - q;
1112			if (len < IFNAMSIZ) {
1113				bzero(tifname, sizeof(tifname));
1114				bcopy(q, tifname, len);
1115				if (strcmp(tifname, ifname) == 0) {
1116					grade = MAC_BIBA_TYPE_HIGH;
1117					break;
1118				}
1119			}
1120			if (*p == '\0')
1121				break;
1122			q = p + 1;
1123		}
1124	}
1125set:
1126	mac_biba_set_single(dest, grade, 0, NULL);
1127	mac_biba_set_range(dest, grade, 0, NULL, grade, 0, NULL);
1128}
1129
1130static void
1131mac_biba_create_ipq(struct mbuf *fragment, struct label *fragmentlabel,
1132    struct ipq *ipq, struct label *ipqlabel)
1133{
1134	struct mac_biba *source, *dest;
1135
1136	source = SLOT(fragmentlabel);
1137	dest = SLOT(ipqlabel);
1138
1139	mac_biba_copy_single(source, dest);
1140}
1141
1142static void
1143mac_biba_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel,
1144    struct mbuf *datagram, struct label *datagramlabel)
1145{
1146	struct mac_biba *source, *dest;
1147
1148	source = SLOT(ipqlabel);
1149	dest = SLOT(datagramlabel);
1150
1151	/* Just use the head, since we require them all to match. */
1152	mac_biba_copy_single(source, dest);
1153}
1154
1155static void
1156mac_biba_create_fragment(struct mbuf *datagram, struct label *datagramlabel,
1157    struct mbuf *fragment, struct label *fragmentlabel)
1158{
1159	struct mac_biba *source, *dest;
1160
1161	source = SLOT(datagramlabel);
1162	dest = SLOT(fragmentlabel);
1163
1164	mac_biba_copy_single(source, dest);
1165}
1166
1167static void
1168mac_biba_create_mbuf_from_mbuf(struct mbuf *oldmbuf,
1169    struct label *oldmbuflabel, struct mbuf *newmbuf,
1170    struct label *newmbuflabel)
1171{
1172	struct mac_biba *source, *dest;
1173
1174	source = SLOT(oldmbuflabel);
1175	dest = SLOT(newmbuflabel);
1176
1177	/*
1178	 * Because the source mbuf may not yet have been "created",
1179	 * just initialized, we do a conditional copy.  Since we don't
1180	 * allow mbufs to have ranges, do a KASSERT to make sure that
1181	 * doesn't happen.
1182	 */
1183	KASSERT((source->mb_flags & MAC_BIBA_FLAG_RANGE) == 0,
1184	    ("mac_biba_create_mbuf_from_mbuf: source mbuf has range"));
1185	mac_biba_copy(source, dest);
1186}
1187
1188static void
1189mac_biba_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel,
1190    struct mbuf *mbuf, struct label *mbuflabel)
1191{
1192	struct mac_biba *dest;
1193
1194	dest = SLOT(mbuflabel);
1195
1196	mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1197}
1198
1199static void
1200mac_biba_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel,
1201    struct mbuf *mbuf, struct label *mbuflabel)
1202{
1203	struct mac_biba *source, *dest;
1204
1205	source = SLOT(bpflabel);
1206	dest = SLOT(mbuflabel);
1207
1208	mac_biba_copy_single(source, dest);
1209}
1210
1211static void
1212mac_biba_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel,
1213    struct mbuf *m, struct label *mbuflabel)
1214{
1215	struct mac_biba *source, *dest;
1216
1217	source = SLOT(ifnetlabel);
1218	dest = SLOT(mbuflabel);
1219
1220	mac_biba_copy_single(source, dest);
1221}
1222
1223static void
1224mac_biba_create_mbuf_multicast_encap(struct mbuf *oldmbuf,
1225    struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel,
1226    struct mbuf *newmbuf, struct label *newmbuflabel)
1227{
1228	struct mac_biba *source, *dest;
1229
1230	source = SLOT(oldmbuflabel);
1231	dest = SLOT(newmbuflabel);
1232
1233	mac_biba_copy_single(source, dest);
1234}
1235
1236static void
1237mac_biba_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel,
1238    struct mbuf *newmbuf, struct label *newmbuflabel)
1239{
1240	struct mac_biba *source, *dest;
1241
1242	source = SLOT(oldmbuflabel);
1243	dest = SLOT(newmbuflabel);
1244
1245	mac_biba_copy_single(source, dest);
1246}
1247
1248static int
1249mac_biba_fragment_match(struct mbuf *fragment, struct label *fragmentlabel,
1250    struct ipq *ipq, struct label *ipqlabel)
1251{
1252	struct mac_biba *a, *b;
1253
1254	a = SLOT(ipqlabel);
1255	b = SLOT(fragmentlabel);
1256
1257	return (mac_biba_equal_single(a, b));
1258}
1259
1260static void
1261mac_biba_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet,
1262    struct label *ifnetlabel, struct label *newlabel)
1263{
1264	struct mac_biba *source, *dest;
1265
1266	source = SLOT(newlabel);
1267	dest = SLOT(ifnetlabel);
1268
1269	mac_biba_copy(source, dest);
1270}
1271
1272static void
1273mac_biba_update_ipq(struct mbuf *fragment, struct label *fragmentlabel,
1274    struct ipq *ipq, struct label *ipqlabel)
1275{
1276
1277	/* NOOP: we only accept matching labels, so no need to update */
1278}
1279
1280/*
1281 * Labeling event operations: processes.
1282 */
1283static void
1284mac_biba_create_cred(struct ucred *cred_parent, struct ucred *cred_child)
1285{
1286	struct mac_biba *source, *dest;
1287
1288	source = SLOT(&cred_parent->cr_label);
1289	dest = SLOT(&cred_child->cr_label);
1290
1291	mac_biba_copy_single(source, dest);
1292	mac_biba_copy_range(source, dest);
1293}
1294
1295static void
1296mac_biba_execve_transition(struct ucred *old, struct ucred *new,
1297    struct vnode *vp, struct mac *vnodelabel)
1298{
1299	struct mac_biba *source, *dest;
1300
1301	source = SLOT(&old->cr_label);
1302	dest = SLOT(&new->cr_label);
1303
1304	mac_biba_copy_single(source, dest);
1305	mac_biba_copy_range(source, dest);
1306}
1307
1308static int
1309mac_biba_execve_will_transition(struct ucred *old, struct vnode *vp,
1310    struct mac *vnodelabel)
1311{
1312
1313	return (0);
1314}
1315
1316static void
1317mac_biba_create_proc0(struct ucred *cred)
1318{
1319	struct mac_biba *dest;
1320
1321	dest = SLOT(&cred->cr_label);
1322
1323	mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1324	mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL,
1325	    MAC_BIBA_TYPE_HIGH, 0, NULL);
1326}
1327
1328static void
1329mac_biba_create_proc1(struct ucred *cred)
1330{
1331	struct mac_biba *dest;
1332
1333	dest = SLOT(&cred->cr_label);
1334
1335	mac_biba_set_single(dest, MAC_BIBA_TYPE_HIGH, 0, NULL);
1336	mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL,
1337	    MAC_BIBA_TYPE_HIGH, 0, NULL);
1338}
1339
1340static void
1341mac_biba_relabel_cred(struct ucred *cred, struct label *newlabel)
1342{
1343	struct mac_biba *source, *dest;
1344
1345	source = SLOT(newlabel);
1346	dest = SLOT(&cred->cr_label);
1347
1348	mac_biba_copy(source, dest);
1349}
1350
1351/*
1352 * Access control checks.
1353 */
1354static int
1355mac_biba_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel,
1356    struct ifnet *ifnet, struct label *ifnetlabel)
1357{
1358	struct mac_biba *a, *b;
1359
1360	if (!mac_biba_enabled)
1361		return (0);
1362
1363	a = SLOT(bpflabel);
1364	b = SLOT(ifnetlabel);
1365
1366	if (mac_biba_equal_single(a, b))
1367		return (0);
1368	return (EACCES);
1369}
1370
1371static int
1372mac_biba_check_cred_relabel(struct ucred *cred, struct label *newlabel)
1373{
1374	struct mac_biba *subj, *new;
1375	int error;
1376
1377	subj = SLOT(&cred->cr_label);
1378	new = SLOT(newlabel);
1379
1380	/*
1381	 * If there is a Biba label update for the credential, it may
1382	 * be an update of the single, range, or both.
1383	 */
1384	error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
1385	if (error)
1386		return (error);
1387
1388	/*
1389	 * If the Biba label is to be changed, authorize as appropriate.
1390	 */
1391	if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) {
1392		/*
1393		 * To change the Biba single label on a credential, the
1394		 * new single label must be in the current range.
1395		 */
1396		if (new->mb_flags & MAC_BIBA_FLAG_SINGLE &&
1397		    !mac_biba_single_in_range(new, subj))
1398			return (EPERM);
1399
1400		/*
1401		 * To change the Biba range on a credential, the new
1402		 * range label must be in the current range.
1403		 */
1404		if (new->mb_flags & MAC_BIBA_FLAG_RANGE &&
1405		    !mac_biba_range_in_range(new, subj))
1406			return (EPERM);
1407
1408		/*
1409		 * To have EQUAL in any component of the new credential
1410		 * Biba label, the subject must already have EQUAL in
1411		 * their label.
1412		 */
1413		if (mac_biba_contains_equal(new)) {
1414			error = mac_biba_subject_equal_ok(subj);
1415			if (error)
1416				return (error);
1417		}
1418
1419		/*
1420		 * XXXMAC: Additional consistency tests regarding the
1421		 * single and range of the new label might be performed
1422		 * here.
1423		 */
1424	}
1425
1426	return (0);
1427}
1428
1429static int
1430mac_biba_check_cred_visible(struct ucred *u1, struct ucred *u2)
1431{
1432	struct mac_biba *subj, *obj;
1433
1434	if (!mac_biba_enabled)
1435		return (0);
1436
1437	subj = SLOT(&u1->cr_label);
1438	obj = SLOT(&u2->cr_label);
1439
1440	/* XXX: range */
1441	if (!mac_biba_dominate_single(obj, subj))
1442		return (ESRCH);
1443
1444	return (0);
1445}
1446
1447static int
1448mac_biba_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet,
1449    struct label *ifnetlabel, struct label *newlabel)
1450{
1451	struct mac_biba *subj, *new;
1452	int error;
1453
1454	subj = SLOT(&cred->cr_label);
1455	new = SLOT(newlabel);
1456
1457	/*
1458	 * If there is a Biba label update for the interface, it may
1459	 * be an update of the single, range, or both.
1460	 */
1461	error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
1462	if (error)
1463		return (error);
1464
1465	/*
1466	 * If the Biba label is to be changed, authorize as appropriate.
1467	 */
1468	if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) {
1469		/*
1470		 * Rely on the traditional superuser status for the Biba
1471		 * interface relabel requirements.  XXXMAC: This will go
1472		 * away.
1473		 */
1474		error = suser_cred(cred, 0);
1475		if (error)
1476			return (EPERM);
1477
1478		/*
1479		 * XXXMAC: Additional consistency tests regarding the single
1480		 * and the range of the new label might be performed here.
1481		 */
1482	}
1483
1484	return (0);
1485}
1486
1487static int
1488mac_biba_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel,
1489    struct mbuf *m, struct label *mbuflabel)
1490{
1491	struct mac_biba *p, *i;
1492
1493	if (!mac_biba_enabled)
1494		return (0);
1495
1496	p = SLOT(mbuflabel);
1497	i = SLOT(ifnetlabel);
1498
1499	return (mac_biba_single_in_range(p, i) ? 0 : EACCES);
1500}
1501
1502static int
1503mac_biba_check_mount_stat(struct ucred *cred, struct mount *mp,
1504    struct label *mntlabel)
1505{
1506	struct mac_biba *subj, *obj;
1507
1508	if (!mac_biba_enabled)
1509		return (0);
1510
1511	subj = SLOT(&cred->cr_label);
1512	obj = SLOT(mntlabel);
1513
1514	if (!mac_biba_dominate_single(obj, subj))
1515		return (EACCES);
1516
1517	return (0);
1518}
1519
1520static int
1521mac_biba_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe,
1522    struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data)
1523{
1524
1525	if(!mac_biba_enabled)
1526		return (0);
1527
1528	/* XXX: This will be implemented soon... */
1529
1530	return (0);
1531}
1532
1533static int
1534mac_biba_check_pipe_poll(struct ucred *cred, struct pipe *pipe,
1535    struct label *pipelabel)
1536{
1537	struct mac_biba *subj, *obj;
1538
1539	if (!mac_biba_enabled)
1540		return (0);
1541
1542	subj = SLOT(&cred->cr_label);
1543	obj = SLOT((pipelabel));
1544
1545	if (!mac_biba_dominate_single(obj, subj))
1546		return (EACCES);
1547
1548	return (0);
1549}
1550
1551static int
1552mac_biba_check_pipe_read(struct ucred *cred, struct pipe *pipe,
1553    struct label *pipelabel)
1554{
1555	struct mac_biba *subj, *obj;
1556
1557	if (!mac_biba_enabled)
1558		return (0);
1559
1560	subj = SLOT(&cred->cr_label);
1561	obj = SLOT((pipelabel));
1562
1563	if (!mac_biba_dominate_single(obj, subj))
1564		return (EACCES);
1565
1566	return (0);
1567}
1568
1569static int
1570mac_biba_check_pipe_relabel(struct ucred *cred, struct pipe *pipe,
1571    struct label *pipelabel, struct label *newlabel)
1572{
1573	struct mac_biba *subj, *obj, *new;
1574	int error;
1575
1576	new = SLOT(newlabel);
1577	subj = SLOT(&cred->cr_label);
1578	obj = SLOT(pipelabel);
1579
1580	/*
1581	 * If there is a Biba label update for a pipe, it must be a
1582	 * single update.
1583	 */
1584	error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE);
1585	if (error)
1586		return (error);
1587
1588	/*
1589	 * To perform a relabel of a pipe (Biba label or not), Biba must
1590	 * authorize the relabel.
1591	 */
1592	if (!mac_biba_single_in_range(obj, subj))
1593		return (EPERM);
1594
1595	/*
1596	 * If the Biba label is to be changed, authorize as appropriate.
1597	 */
1598	if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) {
1599		/*
1600		 * To change the Biba label on a pipe, the new pipe label
1601		 * must be in the subject range.
1602		 */
1603		if (!mac_biba_single_in_range(new, subj))
1604			return (EPERM);
1605
1606		/*
1607		 * To change the Biba label on a pipe to be EQUAL, the
1608		 * subject must have appropriate privilege.
1609		 */
1610		if (mac_biba_contains_equal(new)) {
1611			error = mac_biba_subject_equal_ok(subj);
1612			if (error)
1613				return (error);
1614		}
1615	}
1616
1617	return (0);
1618}
1619
1620static int
1621mac_biba_check_pipe_stat(struct ucred *cred, struct pipe *pipe,
1622    struct label *pipelabel)
1623{
1624	struct mac_biba *subj, *obj;
1625
1626	if (!mac_biba_enabled)
1627		return (0);
1628
1629	subj = SLOT(&cred->cr_label);
1630	obj = SLOT((pipelabel));
1631
1632	if (!mac_biba_dominate_single(obj, subj))
1633		return (EACCES);
1634
1635	return (0);
1636}
1637
1638static int
1639mac_biba_check_pipe_write(struct ucred *cred, struct pipe *pipe,
1640    struct label *pipelabel)
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((pipelabel));
1649
1650	if (!mac_biba_dominate_single(subj, obj))
1651		return (EACCES);
1652
1653	return (0);
1654}
1655
1656static int
1657mac_biba_check_proc_debug(struct ucred *cred, struct proc *proc)
1658{
1659	struct mac_biba *subj, *obj;
1660
1661	if (!mac_biba_enabled)
1662		return (0);
1663
1664	subj = SLOT(&cred->cr_label);
1665	obj = SLOT(&proc->p_ucred->cr_label);
1666
1667	/* XXX: range checks */
1668	if (!mac_biba_dominate_single(obj, subj))
1669		return (ESRCH);
1670	if (!mac_biba_dominate_single(subj, obj))
1671		return (EACCES);
1672
1673	return (0);
1674}
1675
1676static int
1677mac_biba_check_proc_sched(struct ucred *cred, struct proc *proc)
1678{
1679	struct mac_biba *subj, *obj;
1680
1681	if (!mac_biba_enabled)
1682		return (0);
1683
1684	subj = SLOT(&cred->cr_label);
1685	obj = SLOT(&proc->p_ucred->cr_label);
1686
1687	/* XXX: range checks */
1688	if (!mac_biba_dominate_single(obj, subj))
1689		return (ESRCH);
1690	if (!mac_biba_dominate_single(subj, obj))
1691		return (EACCES);
1692
1693	return (0);
1694}
1695
1696static int
1697mac_biba_check_proc_signal(struct ucred *cred, struct proc *proc, int signum)
1698{
1699	struct mac_biba *subj, *obj;
1700
1701	if (!mac_biba_enabled)
1702		return (0);
1703
1704	subj = SLOT(&cred->cr_label);
1705	obj = SLOT(&proc->p_ucred->cr_label);
1706
1707	/* XXX: range checks */
1708	if (!mac_biba_dominate_single(obj, subj))
1709		return (ESRCH);
1710	if (!mac_biba_dominate_single(subj, obj))
1711		return (EACCES);
1712
1713	return (0);
1714}
1715
1716static int
1717mac_biba_check_socket_deliver(struct socket *so, struct label *socketlabel,
1718    struct mbuf *m, struct label *mbuflabel)
1719{
1720	struct mac_biba *p, *s;
1721
1722	if (!mac_biba_enabled)
1723		return (0);
1724
1725	p = SLOT(mbuflabel);
1726	s = SLOT(socketlabel);
1727
1728	return (mac_biba_equal_single(p, s) ? 0 : EACCES);
1729}
1730
1731static int
1732mac_biba_check_socket_relabel(struct ucred *cred, struct socket *socket,
1733    struct label *socketlabel, struct label *newlabel)
1734{
1735	struct mac_biba *subj, *obj, *new;
1736	int error;
1737
1738	new = SLOT(newlabel);
1739	subj = SLOT(&cred->cr_label);
1740	obj = SLOT(socketlabel);
1741
1742	/*
1743	 * If there is a Biba label update for the socket, it may be
1744	 * an update of single.
1745	 */
1746	error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE);
1747	if (error)
1748		return (error);
1749
1750	/*
1751	 * To relabel a socket, the old socket single must be in the subject
1752	 * range.
1753	 */
1754	if (!mac_biba_single_in_range(obj, subj))
1755		return (EPERM);
1756
1757	/*
1758	 * If the Biba label is to be changed, authorize as appropriate.
1759	 */
1760	if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) {
1761		/*
1762		 * To relabel a socket, the new socket single must be in
1763		 * the subject range.
1764		 */
1765		if (!mac_biba_single_in_range(new, subj))
1766			return (EPERM);
1767
1768		/*
1769		 * To change the Biba label on the socket to contain EQUAL,
1770		 * the subject must have appropriate privilege.
1771		 */
1772		if (mac_biba_contains_equal(new)) {
1773			error = mac_biba_subject_equal_ok(subj);
1774			if (error)
1775				return (error);
1776		}
1777	}
1778
1779	return (0);
1780}
1781
1782static int
1783mac_biba_check_socket_visible(struct ucred *cred, struct socket *socket,
1784    struct label *socketlabel)
1785{
1786	struct mac_biba *subj, *obj;
1787
1788	if (!mac_biba_enabled)
1789		return (0);
1790
1791	subj = SLOT(&cred->cr_label);
1792	obj = SLOT(socketlabel);
1793
1794	if (!mac_biba_dominate_single(obj, subj))
1795		return (ENOENT);
1796
1797	return (0);
1798}
1799
1800static int
1801mac_biba_check_vnode_chdir(struct ucred *cred, struct vnode *dvp,
1802    struct label *dlabel)
1803{
1804	struct mac_biba *subj, *obj;
1805
1806	if (!mac_biba_enabled)
1807		return (0);
1808
1809	subj = SLOT(&cred->cr_label);
1810	obj = SLOT(dlabel);
1811
1812	if (!mac_biba_dominate_single(obj, subj))
1813		return (EACCES);
1814
1815	return (0);
1816}
1817
1818static int
1819mac_biba_check_vnode_chroot(struct ucred *cred, struct vnode *dvp,
1820    struct label *dlabel)
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(dlabel);
1829
1830	if (!mac_biba_dominate_single(obj, subj))
1831		return (EACCES);
1832
1833	return (0);
1834}
1835
1836static int
1837mac_biba_check_vnode_create(struct ucred *cred, struct vnode *dvp,
1838    struct label *dlabel, struct componentname *cnp, struct vattr *vap)
1839{
1840	struct mac_biba *subj, *obj;
1841
1842	if (!mac_biba_enabled)
1843		return (0);
1844
1845	subj = SLOT(&cred->cr_label);
1846	obj = SLOT(dlabel);
1847
1848	if (!mac_biba_dominate_single(subj, obj))
1849		return (EACCES);
1850
1851	return (0);
1852}
1853
1854static int
1855mac_biba_check_vnode_delete(struct ucred *cred, struct vnode *dvp,
1856    struct label *dlabel, struct vnode *vp, struct label *label,
1857    struct componentname *cnp)
1858{
1859	struct mac_biba *subj, *obj;
1860
1861	if (!mac_biba_enabled)
1862		return (0);
1863
1864	subj = SLOT(&cred->cr_label);
1865	obj = SLOT(dlabel);
1866
1867	if (!mac_biba_dominate_single(subj, obj))
1868		return (EACCES);
1869
1870	obj = SLOT(label);
1871
1872	if (!mac_biba_dominate_single(subj, obj))
1873		return (EACCES);
1874
1875	return (0);
1876}
1877
1878static int
1879mac_biba_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
1880    struct label *label, acl_type_t type)
1881{
1882	struct mac_biba *subj, *obj;
1883
1884	if (!mac_biba_enabled)
1885		return (0);
1886
1887	subj = SLOT(&cred->cr_label);
1888	obj = SLOT(label);
1889
1890	if (!mac_biba_dominate_single(subj, obj))
1891		return (EACCES);
1892
1893	return (0);
1894}
1895
1896static int
1897mac_biba_check_vnode_exec(struct ucred *cred, struct vnode *vp,
1898    struct label *label)
1899{
1900	struct mac_biba *subj, *obj;
1901
1902	if (!mac_biba_enabled)
1903		return (0);
1904
1905	subj = SLOT(&cred->cr_label);
1906	obj = SLOT(label);
1907
1908	if (!mac_biba_dominate_single(obj, subj))
1909		return (EACCES);
1910
1911	return (0);
1912}
1913
1914static int
1915mac_biba_check_vnode_getacl(struct ucred *cred, struct vnode *vp,
1916    struct label *label, acl_type_t type)
1917{
1918	struct mac_biba *subj, *obj;
1919
1920	if (!mac_biba_enabled)
1921		return (0);
1922
1923	subj = SLOT(&cred->cr_label);
1924	obj = SLOT(label);
1925
1926	if (!mac_biba_dominate_single(obj, subj))
1927		return (EACCES);
1928
1929	return (0);
1930}
1931
1932static int
1933mac_biba_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
1934    struct label *label, int attrnamespace, const char *name, struct uio *uio)
1935{
1936	struct mac_biba *subj, *obj;
1937
1938	if (!mac_biba_enabled)
1939		return (0);
1940
1941	subj = SLOT(&cred->cr_label);
1942	obj = SLOT(label);
1943
1944	if (!mac_biba_dominate_single(obj, subj))
1945		return (EACCES);
1946
1947	return (0);
1948}
1949
1950static int
1951mac_biba_check_vnode_link(struct ucred *cred, struct vnode *dvp,
1952    struct label *dlabel, struct vnode *vp, struct label *label,
1953    struct componentname *cnp)
1954{
1955	struct mac_biba *subj, *obj;
1956
1957	if (!mac_biba_enabled)
1958		return (0);
1959
1960	subj = SLOT(&cred->cr_label);
1961	obj = SLOT(dlabel);
1962
1963	if (!mac_biba_dominate_single(subj, obj))
1964		return (EACCES);
1965
1966	obj = SLOT(label);
1967
1968	if (!mac_biba_dominate_single(subj, obj))
1969		return (EACCES);
1970
1971	return (0);
1972}
1973
1974static int
1975mac_biba_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
1976    struct label *dlabel, struct componentname *cnp)
1977{
1978	struct mac_biba *subj, *obj;
1979
1980	if (!mac_biba_enabled)
1981		return (0);
1982
1983	subj = SLOT(&cred->cr_label);
1984	obj = SLOT(dlabel);
1985
1986	if (!mac_biba_dominate_single(obj, subj))
1987		return (EACCES);
1988
1989	return (0);
1990}
1991
1992static int
1993mac_biba_check_vnode_mmap(struct ucred *cred, struct vnode *vp,
1994    struct label *label, int prot)
1995{
1996	struct mac_biba *subj, *obj;
1997
1998	/*
1999	 * Rely on the use of open()-time protections to handle
2000	 * non-revocation cases.
2001	 */
2002	if (!mac_biba_enabled || !revocation_enabled)
2003		return (0);
2004
2005	subj = SLOT(&cred->cr_label);
2006	obj = SLOT(label);
2007
2008	if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
2009		if (!mac_biba_dominate_single(obj, subj))
2010			return (EACCES);
2011	}
2012	if (prot & VM_PROT_WRITE) {
2013		if (!mac_biba_dominate_single(subj, obj))
2014			return (EACCES);
2015	}
2016
2017	return (0);
2018}
2019
2020static int
2021mac_biba_check_vnode_open(struct ucred *cred, struct vnode *vp,
2022    struct label *vnodelabel, mode_t acc_mode)
2023{
2024	struct mac_biba *subj, *obj;
2025
2026	if (!mac_biba_enabled)
2027		return (0);
2028
2029	subj = SLOT(&cred->cr_label);
2030	obj = SLOT(vnodelabel);
2031
2032	/* XXX privilege override for admin? */
2033	if (acc_mode & (VREAD | VEXEC | VSTAT)) {
2034		if (!mac_biba_dominate_single(obj, subj))
2035			return (EACCES);
2036	}
2037	if (acc_mode & (VWRITE | VAPPEND | VADMIN)) {
2038		if (!mac_biba_dominate_single(subj, obj))
2039			return (EACCES);
2040	}
2041
2042	return (0);
2043}
2044
2045static int
2046mac_biba_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred,
2047    struct vnode *vp, struct label *label)
2048{
2049	struct mac_biba *subj, *obj;
2050
2051	if (!mac_biba_enabled || !revocation_enabled)
2052		return (0);
2053
2054	subj = SLOT(&active_cred->cr_label);
2055	obj = SLOT(label);
2056
2057	if (!mac_biba_dominate_single(obj, subj))
2058		return (EACCES);
2059
2060	return (0);
2061}
2062
2063static int
2064mac_biba_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
2065    struct vnode *vp, struct label *label)
2066{
2067	struct mac_biba *subj, *obj;
2068
2069	if (!mac_biba_enabled || !revocation_enabled)
2070		return (0);
2071
2072	subj = SLOT(&active_cred->cr_label);
2073	obj = SLOT(label);
2074
2075	if (!mac_biba_dominate_single(obj, subj))
2076		return (EACCES);
2077
2078	return (0);
2079}
2080
2081static int
2082mac_biba_check_vnode_readdir(struct ucred *cred, struct vnode *dvp,
2083    struct label *dlabel)
2084{
2085	struct mac_biba *subj, *obj;
2086
2087	if (!mac_biba_enabled)
2088		return (0);
2089
2090	subj = SLOT(&cred->cr_label);
2091	obj = SLOT(dlabel);
2092
2093	if (!mac_biba_dominate_single(obj, subj))
2094		return (EACCES);
2095
2096	return (0);
2097}
2098
2099static int
2100mac_biba_check_vnode_readlink(struct ucred *cred, struct vnode *vp,
2101    struct label *label)
2102{
2103	struct mac_biba *subj, *obj;
2104
2105	if (!mac_biba_enabled)
2106		return (0);
2107
2108	subj = SLOT(&cred->cr_label);
2109	obj = SLOT(label);
2110
2111	if (!mac_biba_dominate_single(obj, subj))
2112		return (EACCES);
2113
2114	return (0);
2115}
2116
2117static int
2118mac_biba_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
2119    struct label *vnodelabel, struct label *newlabel)
2120{
2121	struct mac_biba *old, *new, *subj;
2122	int error;
2123
2124	old = SLOT(vnodelabel);
2125	new = SLOT(newlabel);
2126	subj = SLOT(&cred->cr_label);
2127
2128	/*
2129	 * If there is a Biba label update for the vnode, it must be a
2130	 * single label.
2131	 */
2132	error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE);
2133	if (error)
2134		return (error);
2135
2136	/*
2137	 * To perform a relabel of the vnode (Biba label or not), Biba must
2138	 * authorize the relabel.
2139	 */
2140	if (!mac_biba_single_in_range(old, subj))
2141		return (EPERM);
2142
2143	/*
2144	 * If the Biba label is to be changed, authorize as appropriate.
2145	 */
2146	if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) {
2147		/*
2148		 * To change the Biba label on a vnode, the new vnode label
2149		 * must be in the subject range.
2150		 */
2151		if (!mac_biba_single_in_range(new, subj))
2152			return (EPERM);
2153
2154		/*
2155		 * To change the Biba label on the vnode to be EQUAL,
2156		 * the subject must have appropriate privilege.
2157		 */
2158		if (mac_biba_contains_equal(new)) {
2159			error = mac_biba_subject_equal_ok(subj);
2160			if (error)
2161				return (error);
2162		}
2163	}
2164
2165	return (0);
2166}
2167
2168static int
2169mac_biba_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
2170    struct label *dlabel, struct vnode *vp, struct label *label,
2171    struct componentname *cnp)
2172{
2173	struct mac_biba *subj, *obj;
2174
2175	if (!mac_biba_enabled)
2176		return (0);
2177
2178	subj = SLOT(&cred->cr_label);
2179	obj = SLOT(dlabel);
2180
2181	if (!mac_biba_dominate_single(subj, obj))
2182		return (EACCES);
2183
2184	obj = SLOT(label);
2185
2186	if (!mac_biba_dominate_single(subj, obj))
2187		return (EACCES);
2188
2189	return (0);
2190}
2191
2192static int
2193mac_biba_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
2194    struct label *dlabel, struct vnode *vp, struct label *label, int samedir,
2195    struct componentname *cnp)
2196{
2197	struct mac_biba *subj, *obj;
2198
2199	if (!mac_biba_enabled)
2200		return (0);
2201
2202	subj = SLOT(&cred->cr_label);
2203	obj = SLOT(dlabel);
2204
2205	if (!mac_biba_dominate_single(subj, obj))
2206		return (EACCES);
2207
2208	if (vp != NULL) {
2209		obj = SLOT(label);
2210
2211		if (!mac_biba_dominate_single(subj, obj))
2212			return (EACCES);
2213	}
2214
2215	return (0);
2216}
2217
2218static int
2219mac_biba_check_vnode_revoke(struct ucred *cred, struct vnode *vp,
2220    struct label *label)
2221{
2222	struct mac_biba *subj, *obj;
2223
2224	if (!mac_biba_enabled)
2225		return (0);
2226
2227	subj = SLOT(&cred->cr_label);
2228	obj = SLOT(label);
2229
2230	if (!mac_biba_dominate_single(subj, obj))
2231		return (EACCES);
2232
2233	return (0);
2234}
2235
2236static int
2237mac_biba_check_vnode_setacl(struct ucred *cred, struct vnode *vp,
2238    struct label *label, acl_type_t type, struct acl *acl)
2239{
2240	struct mac_biba *subj, *obj;
2241
2242	if (!mac_biba_enabled)
2243		return (0);
2244
2245	subj = SLOT(&cred->cr_label);
2246	obj = SLOT(label);
2247
2248	if (!mac_biba_dominate_single(subj, obj))
2249		return (EACCES);
2250
2251	return (0);
2252}
2253
2254static int
2255mac_biba_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
2256    struct label *vnodelabel, int attrnamespace, const char *name,
2257    struct uio *uio)
2258{
2259	struct mac_biba *subj, *obj;
2260
2261	if (!mac_biba_enabled)
2262		return (0);
2263
2264	subj = SLOT(&cred->cr_label);
2265	obj = SLOT(vnodelabel);
2266
2267	if (!mac_biba_dominate_single(subj, obj))
2268		return (EACCES);
2269
2270	/* XXX: protect the MAC EA in a special way? */
2271
2272	return (0);
2273}
2274
2275static int
2276mac_biba_check_vnode_setflags(struct ucred *cred, struct vnode *vp,
2277    struct label *vnodelabel, u_long flags)
2278{
2279	struct mac_biba *subj, *obj;
2280
2281	if (!mac_biba_enabled)
2282		return (0);
2283
2284	subj = SLOT(&cred->cr_label);
2285	obj = SLOT(vnodelabel);
2286
2287	if (!mac_biba_dominate_single(subj, obj))
2288		return (EACCES);
2289
2290	return (0);
2291}
2292
2293static int
2294mac_biba_check_vnode_setmode(struct ucred *cred, struct vnode *vp,
2295    struct label *vnodelabel, mode_t mode)
2296{
2297	struct mac_biba *subj, *obj;
2298
2299	if (!mac_biba_enabled)
2300		return (0);
2301
2302	subj = SLOT(&cred->cr_label);
2303	obj = SLOT(vnodelabel);
2304
2305	if (!mac_biba_dominate_single(subj, obj))
2306		return (EACCES);
2307
2308	return (0);
2309}
2310
2311static int
2312mac_biba_check_vnode_setowner(struct ucred *cred, struct vnode *vp,
2313    struct label *vnodelabel, uid_t uid, gid_t gid)
2314{
2315	struct mac_biba *subj, *obj;
2316
2317	if (!mac_biba_enabled)
2318		return (0);
2319
2320	subj = SLOT(&cred->cr_label);
2321	obj = SLOT(vnodelabel);
2322
2323	if (!mac_biba_dominate_single(subj, obj))
2324		return (EACCES);
2325
2326	return (0);
2327}
2328
2329static int
2330mac_biba_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
2331    struct label *vnodelabel, struct timespec atime, struct timespec mtime)
2332{
2333	struct mac_biba *subj, *obj;
2334
2335	if (!mac_biba_enabled)
2336		return (0);
2337
2338	subj = SLOT(&cred->cr_label);
2339	obj = SLOT(vnodelabel);
2340
2341	if (!mac_biba_dominate_single(subj, obj))
2342		return (EACCES);
2343
2344	return (0);
2345}
2346
2347static int
2348mac_biba_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
2349    struct vnode *vp, struct label *vnodelabel)
2350{
2351	struct mac_biba *subj, *obj;
2352
2353	if (!mac_biba_enabled)
2354		return (0);
2355
2356	subj = SLOT(&active_cred->cr_label);
2357	obj = SLOT(vnodelabel);
2358
2359	if (!mac_biba_dominate_single(obj, subj))
2360		return (EACCES);
2361
2362	return (0);
2363}
2364
2365static int
2366mac_biba_check_vnode_write(struct ucred *active_cred,
2367    struct ucred *file_cred, struct vnode *vp, struct label *label)
2368{
2369	struct mac_biba *subj, *obj;
2370
2371	if (!mac_biba_enabled || !revocation_enabled)
2372		return (0);
2373
2374	subj = SLOT(&active_cred->cr_label);
2375	obj = SLOT(label);
2376
2377	if (!mac_biba_dominate_single(subj, obj))
2378		return (EACCES);
2379
2380	return (0);
2381}
2382
2383static struct mac_policy_op_entry mac_biba_ops[] =
2384{
2385	{ MAC_DESTROY,
2386	    (macop_t)mac_biba_destroy },
2387	{ MAC_INIT,
2388	    (macop_t)mac_biba_init },
2389	{ MAC_INIT_BPFDESC_LABEL,
2390	    (macop_t)mac_biba_init_label },
2391	{ MAC_INIT_CRED_LABEL,
2392	    (macop_t)mac_biba_init_label },
2393	{ MAC_INIT_DEVFSDIRENT_LABEL,
2394	    (macop_t)mac_biba_init_label },
2395	{ MAC_INIT_IFNET_LABEL,
2396	    (macop_t)mac_biba_init_label },
2397	{ MAC_INIT_IPQ_LABEL,
2398	    (macop_t)mac_biba_init_label },
2399	{ MAC_INIT_MBUF_LABEL,
2400	    (macop_t)mac_biba_init_label_waitcheck },
2401	{ MAC_INIT_MOUNT_LABEL,
2402	    (macop_t)mac_biba_init_label },
2403	{ MAC_INIT_MOUNT_FS_LABEL,
2404	    (macop_t)mac_biba_init_label },
2405	{ MAC_INIT_PIPE_LABEL,
2406	    (macop_t)mac_biba_init_label },
2407	{ MAC_INIT_SOCKET_LABEL,
2408	    (macop_t)mac_biba_init_label_waitcheck },
2409	{ MAC_INIT_SOCKET_PEER_LABEL,
2410	    (macop_t)mac_biba_init_label_waitcheck },
2411	{ MAC_INIT_VNODE_LABEL,
2412	    (macop_t)mac_biba_init_label },
2413	{ MAC_DESTROY_BPFDESC_LABEL,
2414	    (macop_t)mac_biba_destroy_label },
2415	{ MAC_DESTROY_CRED_LABEL,
2416	    (macop_t)mac_biba_destroy_label },
2417	{ MAC_DESTROY_DEVFSDIRENT_LABEL,
2418	    (macop_t)mac_biba_destroy_label },
2419	{ MAC_DESTROY_IFNET_LABEL,
2420	    (macop_t)mac_biba_destroy_label },
2421	{ MAC_DESTROY_IPQ_LABEL,
2422	    (macop_t)mac_biba_destroy_label },
2423	{ MAC_DESTROY_MBUF_LABEL,
2424	    (macop_t)mac_biba_destroy_label },
2425	{ MAC_DESTROY_MOUNT_LABEL,
2426	    (macop_t)mac_biba_destroy_label },
2427	{ MAC_DESTROY_MOUNT_FS_LABEL,
2428	    (macop_t)mac_biba_destroy_label },
2429	{ MAC_DESTROY_PIPE_LABEL,
2430	    (macop_t)mac_biba_destroy_label },
2431	{ MAC_DESTROY_SOCKET_LABEL,
2432	    (macop_t)mac_biba_destroy_label },
2433	{ MAC_DESTROY_SOCKET_PEER_LABEL,
2434	    (macop_t)mac_biba_destroy_label },
2435	{ MAC_DESTROY_VNODE_LABEL,
2436	    (macop_t)mac_biba_destroy_label },
2437	{ MAC_COPY_PIPE_LABEL,
2438	    (macop_t)mac_biba_copy_label },
2439	{ MAC_COPY_VNODE_LABEL,
2440	    (macop_t)mac_biba_copy_label },
2441	{ MAC_EXTERNALIZE_CRED_LABEL,
2442	    (macop_t)mac_biba_externalize_label },
2443	{ MAC_EXTERNALIZE_IFNET_LABEL,
2444	    (macop_t)mac_biba_externalize_label },
2445	{ MAC_EXTERNALIZE_PIPE_LABEL,
2446	    (macop_t)mac_biba_externalize_label },
2447	{ MAC_EXTERNALIZE_SOCKET_LABEL,
2448	    (macop_t)mac_biba_externalize_label },
2449	{ MAC_EXTERNALIZE_SOCKET_PEER_LABEL,
2450	    (macop_t)mac_biba_externalize_label },
2451	{ MAC_EXTERNALIZE_VNODE_LABEL,
2452	    (macop_t)mac_biba_externalize_label },
2453	{ MAC_EXTERNALIZE_VNODE_OLDMAC,
2454	    (macop_t)mac_biba_externalize_vnode_oldmac },
2455	{ MAC_INTERNALIZE_CRED_LABEL,
2456	    (macop_t)mac_biba_internalize_label },
2457	{ MAC_INTERNALIZE_IFNET_LABEL,
2458	    (macop_t)mac_biba_internalize_label },
2459	{ MAC_INTERNALIZE_PIPE_LABEL,
2460	    (macop_t)mac_biba_internalize_label },
2461	{ MAC_INTERNALIZE_SOCKET_LABEL,
2462	    (macop_t)mac_biba_internalize_label },
2463	{ MAC_INTERNALIZE_VNODE_LABEL,
2464	    (macop_t)mac_biba_internalize_label },
2465	{ MAC_CREATE_DEVFS_DEVICE,
2466	    (macop_t)mac_biba_create_devfs_device },
2467	{ MAC_CREATE_DEVFS_DIRECTORY,
2468	    (macop_t)mac_biba_create_devfs_directory },
2469	{ MAC_CREATE_DEVFS_SYMLINK,
2470	    (macop_t)mac_biba_create_devfs_symlink },
2471	{ MAC_CREATE_DEVFS_VNODE,
2472	    (macop_t)mac_biba_create_devfs_vnode },
2473	{ MAC_CREATE_VNODE,
2474	    (macop_t)mac_biba_create_vnode },
2475	{ MAC_CREATE_MOUNT,
2476	    (macop_t)mac_biba_create_mount },
2477	{ MAC_CREATE_ROOT_MOUNT,
2478	    (macop_t)mac_biba_create_root_mount },
2479	{ MAC_RELABEL_VNODE,
2480	    (macop_t)mac_biba_relabel_vnode },
2481	{ MAC_UPDATE_DEVFSDIRENT,
2482	    (macop_t)mac_biba_update_devfsdirent },
2483	{ MAC_UPDATE_PROCFSVNODE,
2484	    (macop_t)mac_biba_update_procfsvnode },
2485	{ MAC_UPDATE_VNODE_FROM_EXTERNALIZED,
2486	    (macop_t)mac_biba_update_vnode_from_externalized },
2487	{ MAC_UPDATE_VNODE_FROM_MOUNT,
2488	    (macop_t)mac_biba_update_vnode_from_mount },
2489	{ MAC_CREATE_MBUF_FROM_SOCKET,
2490	    (macop_t)mac_biba_create_mbuf_from_socket },
2491	{ MAC_CREATE_PIPE,
2492	    (macop_t)mac_biba_create_pipe },
2493	{ MAC_CREATE_SOCKET,
2494	    (macop_t)mac_biba_create_socket },
2495	{ MAC_CREATE_SOCKET_FROM_SOCKET,
2496	    (macop_t)mac_biba_create_socket_from_socket },
2497	{ MAC_RELABEL_PIPE,
2498	    (macop_t)mac_biba_relabel_pipe },
2499	{ MAC_RELABEL_SOCKET,
2500	    (macop_t)mac_biba_relabel_socket },
2501	{ MAC_SET_SOCKET_PEER_FROM_MBUF,
2502	    (macop_t)mac_biba_set_socket_peer_from_mbuf },
2503	{ MAC_SET_SOCKET_PEER_FROM_SOCKET,
2504	    (macop_t)mac_biba_set_socket_peer_from_socket },
2505	{ MAC_CREATE_BPFDESC,
2506	    (macop_t)mac_biba_create_bpfdesc },
2507	{ MAC_CREATE_DATAGRAM_FROM_IPQ,
2508	    (macop_t)mac_biba_create_datagram_from_ipq },
2509	{ MAC_CREATE_FRAGMENT,
2510	    (macop_t)mac_biba_create_fragment },
2511	{ MAC_CREATE_IFNET,
2512	    (macop_t)mac_biba_create_ifnet },
2513	{ MAC_CREATE_IPQ,
2514	    (macop_t)mac_biba_create_ipq },
2515	{ MAC_CREATE_MBUF_FROM_MBUF,
2516	    (macop_t)mac_biba_create_mbuf_from_mbuf },
2517	{ MAC_CREATE_MBUF_LINKLAYER,
2518	    (macop_t)mac_biba_create_mbuf_linklayer },
2519	{ MAC_CREATE_MBUF_FROM_BPFDESC,
2520	    (macop_t)mac_biba_create_mbuf_from_bpfdesc },
2521	{ MAC_CREATE_MBUF_FROM_IFNET,
2522	    (macop_t)mac_biba_create_mbuf_from_ifnet },
2523	{ MAC_CREATE_MBUF_MULTICAST_ENCAP,
2524	    (macop_t)mac_biba_create_mbuf_multicast_encap },
2525	{ MAC_CREATE_MBUF_NETLAYER,
2526	    (macop_t)mac_biba_create_mbuf_netlayer },
2527	{ MAC_FRAGMENT_MATCH,
2528	    (macop_t)mac_biba_fragment_match },
2529	{ MAC_RELABEL_IFNET,
2530	    (macop_t)mac_biba_relabel_ifnet },
2531	{ MAC_UPDATE_IPQ,
2532	    (macop_t)mac_biba_update_ipq },
2533	{ MAC_CREATE_CRED,
2534	    (macop_t)mac_biba_create_cred },
2535	{ MAC_EXECVE_TRANSITION,
2536	    (macop_t)mac_biba_execve_transition },
2537	{ MAC_EXECVE_WILL_TRANSITION,
2538	    (macop_t)mac_biba_execve_will_transition },
2539	{ MAC_CREATE_PROC0,
2540	    (macop_t)mac_biba_create_proc0 },
2541	{ MAC_CREATE_PROC1,
2542	    (macop_t)mac_biba_create_proc1 },
2543	{ MAC_RELABEL_CRED,
2544	    (macop_t)mac_biba_relabel_cred },
2545	{ MAC_CHECK_BPFDESC_RECEIVE,
2546	    (macop_t)mac_biba_check_bpfdesc_receive },
2547	{ MAC_CHECK_CRED_RELABEL,
2548	    (macop_t)mac_biba_check_cred_relabel },
2549	{ MAC_CHECK_CRED_VISIBLE,
2550	    (macop_t)mac_biba_check_cred_visible },
2551	{ MAC_CHECK_IFNET_RELABEL,
2552	    (macop_t)mac_biba_check_ifnet_relabel },
2553	{ MAC_CHECK_IFNET_TRANSMIT,
2554	    (macop_t)mac_biba_check_ifnet_transmit },
2555	{ MAC_CHECK_MOUNT_STAT,
2556	    (macop_t)mac_biba_check_mount_stat },
2557	{ MAC_CHECK_PIPE_IOCTL,
2558	    (macop_t)mac_biba_check_pipe_ioctl },
2559	{ MAC_CHECK_PIPE_POLL,
2560	    (macop_t)mac_biba_check_pipe_poll },
2561	{ MAC_CHECK_PIPE_READ,
2562	    (macop_t)mac_biba_check_pipe_read },
2563	{ MAC_CHECK_PIPE_RELABEL,
2564	    (macop_t)mac_biba_check_pipe_relabel },
2565	{ MAC_CHECK_PIPE_STAT,
2566	    (macop_t)mac_biba_check_pipe_stat },
2567	{ MAC_CHECK_PIPE_WRITE,
2568	    (macop_t)mac_biba_check_pipe_write },
2569	{ MAC_CHECK_PROC_DEBUG,
2570	    (macop_t)mac_biba_check_proc_debug },
2571	{ MAC_CHECK_PROC_SCHED,
2572	    (macop_t)mac_biba_check_proc_sched },
2573	{ MAC_CHECK_PROC_SIGNAL,
2574	    (macop_t)mac_biba_check_proc_signal },
2575	{ MAC_CHECK_SOCKET_DELIVER,
2576	    (macop_t)mac_biba_check_socket_deliver },
2577	{ MAC_CHECK_SOCKET_RELABEL,
2578	    (macop_t)mac_biba_check_socket_relabel },
2579	{ MAC_CHECK_SOCKET_VISIBLE,
2580	    (macop_t)mac_biba_check_socket_visible },
2581	{ MAC_CHECK_VNODE_ACCESS,
2582	    (macop_t)mac_biba_check_vnode_open },
2583	{ MAC_CHECK_VNODE_CHDIR,
2584	    (macop_t)mac_biba_check_vnode_chdir },
2585	{ MAC_CHECK_VNODE_CHROOT,
2586	    (macop_t)mac_biba_check_vnode_chroot },
2587	{ MAC_CHECK_VNODE_CREATE,
2588	    (macop_t)mac_biba_check_vnode_create },
2589	{ MAC_CHECK_VNODE_DELETE,
2590	    (macop_t)mac_biba_check_vnode_delete },
2591	{ MAC_CHECK_VNODE_DELETEACL,
2592	    (macop_t)mac_biba_check_vnode_deleteacl },
2593	{ MAC_CHECK_VNODE_EXEC,
2594	    (macop_t)mac_biba_check_vnode_exec },
2595	{ MAC_CHECK_VNODE_GETACL,
2596	    (macop_t)mac_biba_check_vnode_getacl },
2597	{ MAC_CHECK_VNODE_GETEXTATTR,
2598	    (macop_t)mac_biba_check_vnode_getextattr },
2599	{ MAC_CHECK_VNODE_LINK,
2600	    (macop_t)mac_biba_check_vnode_link },
2601	{ MAC_CHECK_VNODE_LOOKUP,
2602	    (macop_t)mac_biba_check_vnode_lookup },
2603	{ MAC_CHECK_VNODE_MMAP,
2604	    (macop_t)mac_biba_check_vnode_mmap },
2605	{ MAC_CHECK_VNODE_MPROTECT,
2606	    (macop_t)mac_biba_check_vnode_mmap },
2607	{ MAC_CHECK_VNODE_OPEN,
2608	    (macop_t)mac_biba_check_vnode_open },
2609	{ MAC_CHECK_VNODE_POLL,
2610	    (macop_t)mac_biba_check_vnode_poll },
2611	{ MAC_CHECK_VNODE_READ,
2612	    (macop_t)mac_biba_check_vnode_read },
2613	{ MAC_CHECK_VNODE_READDIR,
2614	    (macop_t)mac_biba_check_vnode_readdir },
2615	{ MAC_CHECK_VNODE_READLINK,
2616	    (macop_t)mac_biba_check_vnode_readlink },
2617	{ MAC_CHECK_VNODE_RELABEL,
2618	    (macop_t)mac_biba_check_vnode_relabel },
2619	{ MAC_CHECK_VNODE_RENAME_FROM,
2620	    (macop_t)mac_biba_check_vnode_rename_from },
2621	{ MAC_CHECK_VNODE_RENAME_TO,
2622	    (macop_t)mac_biba_check_vnode_rename_to },
2623	{ MAC_CHECK_VNODE_REVOKE,
2624	    (macop_t)mac_biba_check_vnode_revoke },
2625	{ MAC_CHECK_VNODE_SETACL,
2626	    (macop_t)mac_biba_check_vnode_setacl },
2627	{ MAC_CHECK_VNODE_SETEXTATTR,
2628	    (macop_t)mac_biba_check_vnode_setextattr },
2629	{ MAC_CHECK_VNODE_SETFLAGS,
2630	    (macop_t)mac_biba_check_vnode_setflags },
2631	{ MAC_CHECK_VNODE_SETMODE,
2632	    (macop_t)mac_biba_check_vnode_setmode },
2633	{ MAC_CHECK_VNODE_SETOWNER,
2634	    (macop_t)mac_biba_check_vnode_setowner },
2635	{ MAC_CHECK_VNODE_SETUTIMES,
2636	    (macop_t)mac_biba_check_vnode_setutimes },
2637	{ MAC_CHECK_VNODE_STAT,
2638	    (macop_t)mac_biba_check_vnode_stat },
2639	{ MAC_CHECK_VNODE_WRITE,
2640	    (macop_t)mac_biba_check_vnode_write },
2641	{ MAC_OP_LAST, NULL }
2642};
2643
2644MAC_POLICY_SET(mac_biba_ops, trustedbsd_mac_biba, "TrustedBSD MAC/Biba",
2645    MPC_LOADTIME_FLAG_NOTLATE, &mac_biba_slot);
2646