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