mac_biba.c revision 105696
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 105696 2002-10-22 14:31:34Z 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	subj = SLOT(&cred->cr_label);
1789	obj = SLOT(socketlabel);
1790
1791	if (!mac_biba_dominate_single(obj, subj))
1792		return (ENOENT);
1793
1794	return (0);
1795}
1796
1797static int
1798mac_biba_check_vnode_chdir(struct ucred *cred, struct vnode *dvp,
1799    struct label *dlabel)
1800{
1801	struct mac_biba *subj, *obj;
1802
1803	if (!mac_biba_enabled)
1804		return (0);
1805
1806	subj = SLOT(&cred->cr_label);
1807	obj = SLOT(dlabel);
1808
1809	if (!mac_biba_dominate_single(obj, subj))
1810		return (EACCES);
1811
1812	return (0);
1813}
1814
1815static int
1816mac_biba_check_vnode_chroot(struct ucred *cred, struct vnode *dvp,
1817    struct label *dlabel)
1818{
1819	struct mac_biba *subj, *obj;
1820
1821	if (!mac_biba_enabled)
1822		return (0);
1823
1824	subj = SLOT(&cred->cr_label);
1825	obj = SLOT(dlabel);
1826
1827	if (!mac_biba_dominate_single(obj, subj))
1828		return (EACCES);
1829
1830	return (0);
1831}
1832
1833static int
1834mac_biba_check_vnode_create(struct ucred *cred, struct vnode *dvp,
1835    struct label *dlabel, struct componentname *cnp, struct vattr *vap)
1836{
1837	struct mac_biba *subj, *obj;
1838
1839	if (!mac_biba_enabled)
1840		return (0);
1841
1842	subj = SLOT(&cred->cr_label);
1843	obj = SLOT(dlabel);
1844
1845	if (!mac_biba_dominate_single(subj, obj))
1846		return (EACCES);
1847
1848	return (0);
1849}
1850
1851static int
1852mac_biba_check_vnode_delete(struct ucred *cred, struct vnode *dvp,
1853    struct label *dlabel, struct vnode *vp, struct label *label,
1854    struct componentname *cnp)
1855{
1856	struct mac_biba *subj, *obj;
1857
1858	if (!mac_biba_enabled)
1859		return (0);
1860
1861	subj = SLOT(&cred->cr_label);
1862	obj = SLOT(dlabel);
1863
1864	if (!mac_biba_dominate_single(subj, obj))
1865		return (EACCES);
1866
1867	obj = SLOT(label);
1868
1869	if (!mac_biba_dominate_single(subj, obj))
1870		return (EACCES);
1871
1872	return (0);
1873}
1874
1875static int
1876mac_biba_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
1877    struct label *label, acl_type_t type)
1878{
1879	struct mac_biba *subj, *obj;
1880
1881	if (!mac_biba_enabled)
1882		return (0);
1883
1884	subj = SLOT(&cred->cr_label);
1885	obj = SLOT(label);
1886
1887	if (!mac_biba_dominate_single(subj, obj))
1888		return (EACCES);
1889
1890	return (0);
1891}
1892
1893static int
1894mac_biba_check_vnode_exec(struct ucred *cred, struct vnode *vp,
1895    struct label *label)
1896{
1897	struct mac_biba *subj, *obj;
1898
1899	if (!mac_biba_enabled)
1900		return (0);
1901
1902	subj = SLOT(&cred->cr_label);
1903	obj = SLOT(label);
1904
1905	if (!mac_biba_dominate_single(obj, subj))
1906		return (EACCES);
1907
1908	return (0);
1909}
1910
1911static int
1912mac_biba_check_vnode_getacl(struct ucred *cred, struct vnode *vp,
1913    struct label *label, acl_type_t type)
1914{
1915	struct mac_biba *subj, *obj;
1916
1917	if (!mac_biba_enabled)
1918		return (0);
1919
1920	subj = SLOT(&cred->cr_label);
1921	obj = SLOT(label);
1922
1923	if (!mac_biba_dominate_single(obj, subj))
1924		return (EACCES);
1925
1926	return (0);
1927}
1928
1929static int
1930mac_biba_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
1931    struct label *label, int attrnamespace, const char *name, struct uio *uio)
1932{
1933	struct mac_biba *subj, *obj;
1934
1935	if (!mac_biba_enabled)
1936		return (0);
1937
1938	subj = SLOT(&cred->cr_label);
1939	obj = SLOT(label);
1940
1941	if (!mac_biba_dominate_single(obj, subj))
1942		return (EACCES);
1943
1944	return (0);
1945}
1946
1947static int
1948mac_biba_check_vnode_link(struct ucred *cred, struct vnode *dvp,
1949    struct label *dlabel, struct vnode *vp, struct label *label,
1950    struct componentname *cnp)
1951{
1952	struct mac_biba *subj, *obj;
1953
1954	if (!mac_biba_enabled)
1955		return (0);
1956
1957	subj = SLOT(&cred->cr_label);
1958	obj = SLOT(dlabel);
1959
1960	if (!mac_biba_dominate_single(subj, obj))
1961		return (EACCES);
1962
1963	obj = SLOT(label);
1964
1965	if (!mac_biba_dominate_single(subj, obj))
1966		return (EACCES);
1967
1968	return (0);
1969}
1970
1971static int
1972mac_biba_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
1973    struct label *dlabel, struct componentname *cnp)
1974{
1975	struct mac_biba *subj, *obj;
1976
1977	if (!mac_biba_enabled)
1978		return (0);
1979
1980	subj = SLOT(&cred->cr_label);
1981	obj = SLOT(dlabel);
1982
1983	if (!mac_biba_dominate_single(obj, subj))
1984		return (EACCES);
1985
1986	return (0);
1987}
1988
1989static int
1990mac_biba_check_vnode_mmap(struct ucred *cred, struct vnode *vp,
1991    struct label *label, int prot)
1992{
1993	struct mac_biba *subj, *obj;
1994
1995	/*
1996	 * Rely on the use of open()-time protections to handle
1997	 * non-revocation cases.
1998	 */
1999	if (!mac_biba_enabled || !revocation_enabled)
2000		return (0);
2001
2002	subj = SLOT(&cred->cr_label);
2003	obj = SLOT(label);
2004
2005	if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
2006		if (!mac_biba_dominate_single(obj, subj))
2007			return (EACCES);
2008	}
2009	if (prot & VM_PROT_WRITE) {
2010		if (!mac_biba_dominate_single(subj, obj))
2011			return (EACCES);
2012	}
2013
2014	return (0);
2015}
2016
2017static int
2018mac_biba_check_vnode_open(struct ucred *cred, struct vnode *vp,
2019    struct label *vnodelabel, mode_t acc_mode)
2020{
2021	struct mac_biba *subj, *obj;
2022
2023	if (!mac_biba_enabled)
2024		return (0);
2025
2026	subj = SLOT(&cred->cr_label);
2027	obj = SLOT(vnodelabel);
2028
2029	/* XXX privilege override for admin? */
2030	if (acc_mode & (VREAD | VEXEC | VSTAT)) {
2031		if (!mac_biba_dominate_single(obj, subj))
2032			return (EACCES);
2033	}
2034	if (acc_mode & (VWRITE | VAPPEND | VADMIN)) {
2035		if (!mac_biba_dominate_single(subj, obj))
2036			return (EACCES);
2037	}
2038
2039	return (0);
2040}
2041
2042static int
2043mac_biba_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred,
2044    struct vnode *vp, struct label *label)
2045{
2046	struct mac_biba *subj, *obj;
2047
2048	if (!mac_biba_enabled || !revocation_enabled)
2049		return (0);
2050
2051	subj = SLOT(&active_cred->cr_label);
2052	obj = SLOT(label);
2053
2054	if (!mac_biba_dominate_single(obj, subj))
2055		return (EACCES);
2056
2057	return (0);
2058}
2059
2060static int
2061mac_biba_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
2062    struct vnode *vp, struct label *label)
2063{
2064	struct mac_biba *subj, *obj;
2065
2066	if (!mac_biba_enabled || !revocation_enabled)
2067		return (0);
2068
2069	subj = SLOT(&active_cred->cr_label);
2070	obj = SLOT(label);
2071
2072	if (!mac_biba_dominate_single(obj, subj))
2073		return (EACCES);
2074
2075	return (0);
2076}
2077
2078static int
2079mac_biba_check_vnode_readdir(struct ucred *cred, struct vnode *dvp,
2080    struct label *dlabel)
2081{
2082	struct mac_biba *subj, *obj;
2083
2084	if (!mac_biba_enabled)
2085		return (0);
2086
2087	subj = SLOT(&cred->cr_label);
2088	obj = SLOT(dlabel);
2089
2090	if (!mac_biba_dominate_single(obj, subj))
2091		return (EACCES);
2092
2093	return (0);
2094}
2095
2096static int
2097mac_biba_check_vnode_readlink(struct ucred *cred, struct vnode *vp,
2098    struct label *label)
2099{
2100	struct mac_biba *subj, *obj;
2101
2102	if (!mac_biba_enabled)
2103		return (0);
2104
2105	subj = SLOT(&cred->cr_label);
2106	obj = SLOT(label);
2107
2108	if (!mac_biba_dominate_single(obj, subj))
2109		return (EACCES);
2110
2111	return (0);
2112}
2113
2114static int
2115mac_biba_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
2116    struct label *vnodelabel, struct label *newlabel)
2117{
2118	struct mac_biba *old, *new, *subj;
2119	int error;
2120
2121	old = SLOT(vnodelabel);
2122	new = SLOT(newlabel);
2123	subj = SLOT(&cred->cr_label);
2124
2125	/*
2126	 * If there is a Biba label update for the vnode, it must be a
2127	 * single label.
2128	 */
2129	error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE);
2130	if (error)
2131		return (error);
2132
2133	/*
2134	 * To perform a relabel of the vnode (Biba label or not), Biba must
2135	 * authorize the relabel.
2136	 */
2137	if (!mac_biba_single_in_range(old, subj))
2138		return (EPERM);
2139
2140	/*
2141	 * If the Biba label is to be changed, authorize as appropriate.
2142	 */
2143	if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) {
2144		/*
2145		 * To change the Biba label on a vnode, the new vnode label
2146		 * must be in the subject range.
2147		 */
2148		if (!mac_biba_single_in_range(new, subj))
2149			return (EPERM);
2150
2151		/*
2152		 * To change the Biba label on the vnode to be EQUAL,
2153		 * the subject must have appropriate privilege.
2154		 */
2155		if (mac_biba_contains_equal(new)) {
2156			error = mac_biba_subject_equal_ok(subj);
2157			if (error)
2158				return (error);
2159		}
2160	}
2161
2162	return (0);
2163}
2164
2165static int
2166mac_biba_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
2167    struct label *dlabel, struct vnode *vp, struct label *label,
2168    struct componentname *cnp)
2169{
2170	struct mac_biba *subj, *obj;
2171
2172	if (!mac_biba_enabled)
2173		return (0);
2174
2175	subj = SLOT(&cred->cr_label);
2176	obj = SLOT(dlabel);
2177
2178	if (!mac_biba_dominate_single(subj, obj))
2179		return (EACCES);
2180
2181	obj = SLOT(label);
2182
2183	if (!mac_biba_dominate_single(subj, obj))
2184		return (EACCES);
2185
2186	return (0);
2187}
2188
2189static int
2190mac_biba_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
2191    struct label *dlabel, struct vnode *vp, struct label *label, int samedir,
2192    struct componentname *cnp)
2193{
2194	struct mac_biba *subj, *obj;
2195
2196	if (!mac_biba_enabled)
2197		return (0);
2198
2199	subj = SLOT(&cred->cr_label);
2200	obj = SLOT(dlabel);
2201
2202	if (!mac_biba_dominate_single(subj, obj))
2203		return (EACCES);
2204
2205	if (vp != NULL) {
2206		obj = SLOT(label);
2207
2208		if (!mac_biba_dominate_single(subj, obj))
2209			return (EACCES);
2210	}
2211
2212	return (0);
2213}
2214
2215static int
2216mac_biba_check_vnode_revoke(struct ucred *cred, struct vnode *vp,
2217    struct label *label)
2218{
2219	struct mac_biba *subj, *obj;
2220
2221	if (!mac_biba_enabled)
2222		return (0);
2223
2224	subj = SLOT(&cred->cr_label);
2225	obj = SLOT(label);
2226
2227	if (!mac_biba_dominate_single(subj, obj))
2228		return (EACCES);
2229
2230	return (0);
2231}
2232
2233static int
2234mac_biba_check_vnode_setacl(struct ucred *cred, struct vnode *vp,
2235    struct label *label, acl_type_t type, struct acl *acl)
2236{
2237	struct mac_biba *subj, *obj;
2238
2239	if (!mac_biba_enabled)
2240		return (0);
2241
2242	subj = SLOT(&cred->cr_label);
2243	obj = SLOT(label);
2244
2245	if (!mac_biba_dominate_single(subj, obj))
2246		return (EACCES);
2247
2248	return (0);
2249}
2250
2251static int
2252mac_biba_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
2253    struct label *vnodelabel, int attrnamespace, const char *name,
2254    struct uio *uio)
2255{
2256	struct mac_biba *subj, *obj;
2257
2258	if (!mac_biba_enabled)
2259		return (0);
2260
2261	subj = SLOT(&cred->cr_label);
2262	obj = SLOT(vnodelabel);
2263
2264	if (!mac_biba_dominate_single(subj, obj))
2265		return (EACCES);
2266
2267	/* XXX: protect the MAC EA in a special way? */
2268
2269	return (0);
2270}
2271
2272static int
2273mac_biba_check_vnode_setflags(struct ucred *cred, struct vnode *vp,
2274    struct label *vnodelabel, u_long flags)
2275{
2276	struct mac_biba *subj, *obj;
2277
2278	if (!mac_biba_enabled)
2279		return (0);
2280
2281	subj = SLOT(&cred->cr_label);
2282	obj = SLOT(vnodelabel);
2283
2284	if (!mac_biba_dominate_single(subj, obj))
2285		return (EACCES);
2286
2287	return (0);
2288}
2289
2290static int
2291mac_biba_check_vnode_setmode(struct ucred *cred, struct vnode *vp,
2292    struct label *vnodelabel, mode_t mode)
2293{
2294	struct mac_biba *subj, *obj;
2295
2296	if (!mac_biba_enabled)
2297		return (0);
2298
2299	subj = SLOT(&cred->cr_label);
2300	obj = SLOT(vnodelabel);
2301
2302	if (!mac_biba_dominate_single(subj, obj))
2303		return (EACCES);
2304
2305	return (0);
2306}
2307
2308static int
2309mac_biba_check_vnode_setowner(struct ucred *cred, struct vnode *vp,
2310    struct label *vnodelabel, uid_t uid, gid_t gid)
2311{
2312	struct mac_biba *subj, *obj;
2313
2314	if (!mac_biba_enabled)
2315		return (0);
2316
2317	subj = SLOT(&cred->cr_label);
2318	obj = SLOT(vnodelabel);
2319
2320	if (!mac_biba_dominate_single(subj, obj))
2321		return (EACCES);
2322
2323	return (0);
2324}
2325
2326static int
2327mac_biba_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
2328    struct label *vnodelabel, struct timespec atime, struct timespec mtime)
2329{
2330	struct mac_biba *subj, *obj;
2331
2332	if (!mac_biba_enabled)
2333		return (0);
2334
2335	subj = SLOT(&cred->cr_label);
2336	obj = SLOT(vnodelabel);
2337
2338	if (!mac_biba_dominate_single(subj, obj))
2339		return (EACCES);
2340
2341	return (0);
2342}
2343
2344static int
2345mac_biba_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
2346    struct vnode *vp, struct label *vnodelabel)
2347{
2348	struct mac_biba *subj, *obj;
2349
2350	if (!mac_biba_enabled)
2351		return (0);
2352
2353	subj = SLOT(&active_cred->cr_label);
2354	obj = SLOT(vnodelabel);
2355
2356	if (!mac_biba_dominate_single(obj, subj))
2357		return (EACCES);
2358
2359	return (0);
2360}
2361
2362static int
2363mac_biba_check_vnode_write(struct ucred *active_cred,
2364    struct ucred *file_cred, struct vnode *vp, struct label *label)
2365{
2366	struct mac_biba *subj, *obj;
2367
2368	if (!mac_biba_enabled || !revocation_enabled)
2369		return (0);
2370
2371	subj = SLOT(&active_cred->cr_label);
2372	obj = SLOT(label);
2373
2374	if (!mac_biba_dominate_single(subj, obj))
2375		return (EACCES);
2376
2377	return (0);
2378}
2379
2380static struct mac_policy_op_entry mac_biba_ops[] =
2381{
2382	{ MAC_DESTROY,
2383	    (macop_t)mac_biba_destroy },
2384	{ MAC_INIT,
2385	    (macop_t)mac_biba_init },
2386	{ MAC_INIT_BPFDESC_LABEL,
2387	    (macop_t)mac_biba_init_label },
2388	{ MAC_INIT_CRED_LABEL,
2389	    (macop_t)mac_biba_init_label },
2390	{ MAC_INIT_DEVFSDIRENT_LABEL,
2391	    (macop_t)mac_biba_init_label },
2392	{ MAC_INIT_IFNET_LABEL,
2393	    (macop_t)mac_biba_init_label },
2394	{ MAC_INIT_IPQ_LABEL,
2395	    (macop_t)mac_biba_init_label },
2396	{ MAC_INIT_MBUF_LABEL,
2397	    (macop_t)mac_biba_init_label_waitcheck },
2398	{ MAC_INIT_MOUNT_LABEL,
2399	    (macop_t)mac_biba_init_label },
2400	{ MAC_INIT_MOUNT_FS_LABEL,
2401	    (macop_t)mac_biba_init_label },
2402	{ MAC_INIT_PIPE_LABEL,
2403	    (macop_t)mac_biba_init_label },
2404	{ MAC_INIT_SOCKET_LABEL,
2405	    (macop_t)mac_biba_init_label_waitcheck },
2406	{ MAC_INIT_SOCKET_PEER_LABEL,
2407	    (macop_t)mac_biba_init_label_waitcheck },
2408	{ MAC_INIT_VNODE_LABEL,
2409	    (macop_t)mac_biba_init_label },
2410	{ MAC_DESTROY_BPFDESC_LABEL,
2411	    (macop_t)mac_biba_destroy_label },
2412	{ MAC_DESTROY_CRED_LABEL,
2413	    (macop_t)mac_biba_destroy_label },
2414	{ MAC_DESTROY_DEVFSDIRENT_LABEL,
2415	    (macop_t)mac_biba_destroy_label },
2416	{ MAC_DESTROY_IFNET_LABEL,
2417	    (macop_t)mac_biba_destroy_label },
2418	{ MAC_DESTROY_IPQ_LABEL,
2419	    (macop_t)mac_biba_destroy_label },
2420	{ MAC_DESTROY_MBUF_LABEL,
2421	    (macop_t)mac_biba_destroy_label },
2422	{ MAC_DESTROY_MOUNT_LABEL,
2423	    (macop_t)mac_biba_destroy_label },
2424	{ MAC_DESTROY_MOUNT_FS_LABEL,
2425	    (macop_t)mac_biba_destroy_label },
2426	{ MAC_DESTROY_PIPE_LABEL,
2427	    (macop_t)mac_biba_destroy_label },
2428	{ MAC_DESTROY_SOCKET_LABEL,
2429	    (macop_t)mac_biba_destroy_label },
2430	{ MAC_DESTROY_SOCKET_PEER_LABEL,
2431	    (macop_t)mac_biba_destroy_label },
2432	{ MAC_DESTROY_VNODE_LABEL,
2433	    (macop_t)mac_biba_destroy_label },
2434	{ MAC_COPY_PIPE_LABEL,
2435	    (macop_t)mac_biba_copy_label },
2436	{ MAC_COPY_VNODE_LABEL,
2437	    (macop_t)mac_biba_copy_label },
2438	{ MAC_EXTERNALIZE_CRED_LABEL,
2439	    (macop_t)mac_biba_externalize_label },
2440	{ MAC_EXTERNALIZE_IFNET_LABEL,
2441	    (macop_t)mac_biba_externalize_label },
2442	{ MAC_EXTERNALIZE_PIPE_LABEL,
2443	    (macop_t)mac_biba_externalize_label },
2444	{ MAC_EXTERNALIZE_SOCKET_LABEL,
2445	    (macop_t)mac_biba_externalize_label },
2446	{ MAC_EXTERNALIZE_SOCKET_PEER_LABEL,
2447	    (macop_t)mac_biba_externalize_label },
2448	{ MAC_EXTERNALIZE_VNODE_LABEL,
2449	    (macop_t)mac_biba_externalize_label },
2450	{ MAC_EXTERNALIZE_VNODE_OLDMAC,
2451	    (macop_t)mac_biba_externalize_vnode_oldmac },
2452	{ MAC_INTERNALIZE_CRED_LABEL,
2453	    (macop_t)mac_biba_internalize_label },
2454	{ MAC_INTERNALIZE_IFNET_LABEL,
2455	    (macop_t)mac_biba_internalize_label },
2456	{ MAC_INTERNALIZE_PIPE_LABEL,
2457	    (macop_t)mac_biba_internalize_label },
2458	{ MAC_INTERNALIZE_SOCKET_LABEL,
2459	    (macop_t)mac_biba_internalize_label },
2460	{ MAC_INTERNALIZE_VNODE_LABEL,
2461	    (macop_t)mac_biba_internalize_label },
2462	{ MAC_CREATE_DEVFS_DEVICE,
2463	    (macop_t)mac_biba_create_devfs_device },
2464	{ MAC_CREATE_DEVFS_DIRECTORY,
2465	    (macop_t)mac_biba_create_devfs_directory },
2466	{ MAC_CREATE_DEVFS_SYMLINK,
2467	    (macop_t)mac_biba_create_devfs_symlink },
2468	{ MAC_CREATE_DEVFS_VNODE,
2469	    (macop_t)mac_biba_create_devfs_vnode },
2470	{ MAC_CREATE_VNODE,
2471	    (macop_t)mac_biba_create_vnode },
2472	{ MAC_CREATE_MOUNT,
2473	    (macop_t)mac_biba_create_mount },
2474	{ MAC_CREATE_ROOT_MOUNT,
2475	    (macop_t)mac_biba_create_root_mount },
2476	{ MAC_RELABEL_VNODE,
2477	    (macop_t)mac_biba_relabel_vnode },
2478	{ MAC_UPDATE_DEVFSDIRENT,
2479	    (macop_t)mac_biba_update_devfsdirent },
2480	{ MAC_UPDATE_PROCFSVNODE,
2481	    (macop_t)mac_biba_update_procfsvnode },
2482	{ MAC_UPDATE_VNODE_FROM_EXTERNALIZED,
2483	    (macop_t)mac_biba_update_vnode_from_externalized },
2484	{ MAC_UPDATE_VNODE_FROM_MOUNT,
2485	    (macop_t)mac_biba_update_vnode_from_mount },
2486	{ MAC_CREATE_MBUF_FROM_SOCKET,
2487	    (macop_t)mac_biba_create_mbuf_from_socket },
2488	{ MAC_CREATE_PIPE,
2489	    (macop_t)mac_biba_create_pipe },
2490	{ MAC_CREATE_SOCKET,
2491	    (macop_t)mac_biba_create_socket },
2492	{ MAC_CREATE_SOCKET_FROM_SOCKET,
2493	    (macop_t)mac_biba_create_socket_from_socket },
2494	{ MAC_RELABEL_PIPE,
2495	    (macop_t)mac_biba_relabel_pipe },
2496	{ MAC_RELABEL_SOCKET,
2497	    (macop_t)mac_biba_relabel_socket },
2498	{ MAC_SET_SOCKET_PEER_FROM_MBUF,
2499	    (macop_t)mac_biba_set_socket_peer_from_mbuf },
2500	{ MAC_SET_SOCKET_PEER_FROM_SOCKET,
2501	    (macop_t)mac_biba_set_socket_peer_from_socket },
2502	{ MAC_CREATE_BPFDESC,
2503	    (macop_t)mac_biba_create_bpfdesc },
2504	{ MAC_CREATE_DATAGRAM_FROM_IPQ,
2505	    (macop_t)mac_biba_create_datagram_from_ipq },
2506	{ MAC_CREATE_FRAGMENT,
2507	    (macop_t)mac_biba_create_fragment },
2508	{ MAC_CREATE_IFNET,
2509	    (macop_t)mac_biba_create_ifnet },
2510	{ MAC_CREATE_IPQ,
2511	    (macop_t)mac_biba_create_ipq },
2512	{ MAC_CREATE_MBUF_FROM_MBUF,
2513	    (macop_t)mac_biba_create_mbuf_from_mbuf },
2514	{ MAC_CREATE_MBUF_LINKLAYER,
2515	    (macop_t)mac_biba_create_mbuf_linklayer },
2516	{ MAC_CREATE_MBUF_FROM_BPFDESC,
2517	    (macop_t)mac_biba_create_mbuf_from_bpfdesc },
2518	{ MAC_CREATE_MBUF_FROM_IFNET,
2519	    (macop_t)mac_biba_create_mbuf_from_ifnet },
2520	{ MAC_CREATE_MBUF_MULTICAST_ENCAP,
2521	    (macop_t)mac_biba_create_mbuf_multicast_encap },
2522	{ MAC_CREATE_MBUF_NETLAYER,
2523	    (macop_t)mac_biba_create_mbuf_netlayer },
2524	{ MAC_FRAGMENT_MATCH,
2525	    (macop_t)mac_biba_fragment_match },
2526	{ MAC_RELABEL_IFNET,
2527	    (macop_t)mac_biba_relabel_ifnet },
2528	{ MAC_UPDATE_IPQ,
2529	    (macop_t)mac_biba_update_ipq },
2530	{ MAC_CREATE_CRED,
2531	    (macop_t)mac_biba_create_cred },
2532	{ MAC_EXECVE_TRANSITION,
2533	    (macop_t)mac_biba_execve_transition },
2534	{ MAC_EXECVE_WILL_TRANSITION,
2535	    (macop_t)mac_biba_execve_will_transition },
2536	{ MAC_CREATE_PROC0,
2537	    (macop_t)mac_biba_create_proc0 },
2538	{ MAC_CREATE_PROC1,
2539	    (macop_t)mac_biba_create_proc1 },
2540	{ MAC_RELABEL_CRED,
2541	    (macop_t)mac_biba_relabel_cred },
2542	{ MAC_CHECK_BPFDESC_RECEIVE,
2543	    (macop_t)mac_biba_check_bpfdesc_receive },
2544	{ MAC_CHECK_CRED_RELABEL,
2545	    (macop_t)mac_biba_check_cred_relabel },
2546	{ MAC_CHECK_CRED_VISIBLE,
2547	    (macop_t)mac_biba_check_cred_visible },
2548	{ MAC_CHECK_IFNET_RELABEL,
2549	    (macop_t)mac_biba_check_ifnet_relabel },
2550	{ MAC_CHECK_IFNET_TRANSMIT,
2551	    (macop_t)mac_biba_check_ifnet_transmit },
2552	{ MAC_CHECK_MOUNT_STAT,
2553	    (macop_t)mac_biba_check_mount_stat },
2554	{ MAC_CHECK_PIPE_IOCTL,
2555	    (macop_t)mac_biba_check_pipe_ioctl },
2556	{ MAC_CHECK_PIPE_POLL,
2557	    (macop_t)mac_biba_check_pipe_poll },
2558	{ MAC_CHECK_PIPE_READ,
2559	    (macop_t)mac_biba_check_pipe_read },
2560	{ MAC_CHECK_PIPE_RELABEL,
2561	    (macop_t)mac_biba_check_pipe_relabel },
2562	{ MAC_CHECK_PIPE_STAT,
2563	    (macop_t)mac_biba_check_pipe_stat },
2564	{ MAC_CHECK_PIPE_WRITE,
2565	    (macop_t)mac_biba_check_pipe_write },
2566	{ MAC_CHECK_PROC_DEBUG,
2567	    (macop_t)mac_biba_check_proc_debug },
2568	{ MAC_CHECK_PROC_SCHED,
2569	    (macop_t)mac_biba_check_proc_sched },
2570	{ MAC_CHECK_PROC_SIGNAL,
2571	    (macop_t)mac_biba_check_proc_signal },
2572	{ MAC_CHECK_SOCKET_DELIVER,
2573	    (macop_t)mac_biba_check_socket_deliver },
2574	{ MAC_CHECK_SOCKET_RELABEL,
2575	    (macop_t)mac_biba_check_socket_relabel },
2576	{ MAC_CHECK_SOCKET_VISIBLE,
2577	    (macop_t)mac_biba_check_socket_visible },
2578	{ MAC_CHECK_VNODE_ACCESS,
2579	    (macop_t)mac_biba_check_vnode_open },
2580	{ MAC_CHECK_VNODE_CHDIR,
2581	    (macop_t)mac_biba_check_vnode_chdir },
2582	{ MAC_CHECK_VNODE_CHROOT,
2583	    (macop_t)mac_biba_check_vnode_chroot },
2584	{ MAC_CHECK_VNODE_CREATE,
2585	    (macop_t)mac_biba_check_vnode_create },
2586	{ MAC_CHECK_VNODE_DELETE,
2587	    (macop_t)mac_biba_check_vnode_delete },
2588	{ MAC_CHECK_VNODE_DELETEACL,
2589	    (macop_t)mac_biba_check_vnode_deleteacl },
2590	{ MAC_CHECK_VNODE_EXEC,
2591	    (macop_t)mac_biba_check_vnode_exec },
2592	{ MAC_CHECK_VNODE_GETACL,
2593	    (macop_t)mac_biba_check_vnode_getacl },
2594	{ MAC_CHECK_VNODE_GETEXTATTR,
2595	    (macop_t)mac_biba_check_vnode_getextattr },
2596	{ MAC_CHECK_VNODE_LINK,
2597	    (macop_t)mac_biba_check_vnode_link },
2598	{ MAC_CHECK_VNODE_LOOKUP,
2599	    (macop_t)mac_biba_check_vnode_lookup },
2600	{ MAC_CHECK_VNODE_MMAP,
2601	    (macop_t)mac_biba_check_vnode_mmap },
2602	{ MAC_CHECK_VNODE_MPROTECT,
2603	    (macop_t)mac_biba_check_vnode_mmap },
2604	{ MAC_CHECK_VNODE_OPEN,
2605	    (macop_t)mac_biba_check_vnode_open },
2606	{ MAC_CHECK_VNODE_POLL,
2607	    (macop_t)mac_biba_check_vnode_poll },
2608	{ MAC_CHECK_VNODE_READ,
2609	    (macop_t)mac_biba_check_vnode_read },
2610	{ MAC_CHECK_VNODE_READDIR,
2611	    (macop_t)mac_biba_check_vnode_readdir },
2612	{ MAC_CHECK_VNODE_READLINK,
2613	    (macop_t)mac_biba_check_vnode_readlink },
2614	{ MAC_CHECK_VNODE_RELABEL,
2615	    (macop_t)mac_biba_check_vnode_relabel },
2616	{ MAC_CHECK_VNODE_RENAME_FROM,
2617	    (macop_t)mac_biba_check_vnode_rename_from },
2618	{ MAC_CHECK_VNODE_RENAME_TO,
2619	    (macop_t)mac_biba_check_vnode_rename_to },
2620	{ MAC_CHECK_VNODE_REVOKE,
2621	    (macop_t)mac_biba_check_vnode_revoke },
2622	{ MAC_CHECK_VNODE_SETACL,
2623	    (macop_t)mac_biba_check_vnode_setacl },
2624	{ MAC_CHECK_VNODE_SETEXTATTR,
2625	    (macop_t)mac_biba_check_vnode_setextattr },
2626	{ MAC_CHECK_VNODE_SETFLAGS,
2627	    (macop_t)mac_biba_check_vnode_setflags },
2628	{ MAC_CHECK_VNODE_SETMODE,
2629	    (macop_t)mac_biba_check_vnode_setmode },
2630	{ MAC_CHECK_VNODE_SETOWNER,
2631	    (macop_t)mac_biba_check_vnode_setowner },
2632	{ MAC_CHECK_VNODE_SETUTIMES,
2633	    (macop_t)mac_biba_check_vnode_setutimes },
2634	{ MAC_CHECK_VNODE_STAT,
2635	    (macop_t)mac_biba_check_vnode_stat },
2636	{ MAC_CHECK_VNODE_WRITE,
2637	    (macop_t)mac_biba_check_vnode_write },
2638	{ MAC_OP_LAST, NULL }
2639};
2640
2641MAC_POLICY_SET(mac_biba_ops, trustedbsd_mac_biba, "TrustedBSD MAC/Biba",
2642    MPC_LOADTIME_FLAG_NOTLATE, &mac_biba_slot);
2643