mac_biba.c revision 168954
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 168954 2007-04-22 16:18:10Z 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)
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}
840
841static void
842mac_biba_relabel_vnode(struct ucred *cred, struct vnode *vp,
843    struct label *vnodelabel, struct label *label)
844{
845	struct mac_biba *source, *dest;
846
847	source = SLOT(label);
848	dest = SLOT(vnodelabel);
849
850	mac_biba_copy(source, dest);
851}
852
853static void
854mac_biba_update_devfsdirent(struct mount *mp,
855    struct devfs_dirent *devfs_dirent, struct label *direntlabel,
856    struct vnode *vp, struct label *vnodelabel)
857{
858	struct mac_biba *source, *dest;
859
860	source = SLOT(vnodelabel);
861	dest = SLOT(direntlabel);
862
863	mac_biba_copy(source, dest);
864}
865
866static void
867mac_biba_associate_vnode_devfs(struct mount *mp, struct label *mntlabel,
868    struct devfs_dirent *de, struct label *delabel, struct vnode *vp,
869    struct label *vlabel)
870{
871	struct mac_biba *source, *dest;
872
873	source = SLOT(delabel);
874	dest = SLOT(vlabel);
875
876	mac_biba_copy_effective(source, dest);
877}
878
879static int
880mac_biba_associate_vnode_extattr(struct mount *mp, struct label *mntlabel,
881    struct vnode *vp, struct label *vlabel)
882{
883	struct mac_biba temp, *source, *dest;
884	int buflen, error;
885
886	source = SLOT(mntlabel);
887	dest = SLOT(vlabel);
888
889	buflen = sizeof(temp);
890	bzero(&temp, buflen);
891
892	error = vn_extattr_get(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
893	    MAC_BIBA_EXTATTR_NAME, &buflen, (char *) &temp, curthread);
894	if (error == ENOATTR || error == EOPNOTSUPP) {
895		/* Fall back to the mntlabel. */
896		mac_biba_copy_effective(source, dest);
897		return (0);
898	} else if (error)
899		return (error);
900
901	if (buflen != sizeof(temp)) {
902		printf("mac_biba_associate_vnode_extattr: bad size %d\n",
903		    buflen);
904		return (EPERM);
905	}
906	if (mac_biba_valid(&temp) != 0) {
907		printf("mac_biba_associate_vnode_extattr: invalid\n");
908		return (EPERM);
909	}
910	if ((temp.mb_flags & MAC_BIBA_FLAGS_BOTH) != MAC_BIBA_FLAG_EFFECTIVE) {
911		printf("mac_biba_associate_vnode_extattr: not effective\n");
912		return (EPERM);
913	}
914
915	mac_biba_copy_effective(&temp, dest);
916	return (0);
917}
918
919static void
920mac_biba_associate_vnode_singlelabel(struct mount *mp,
921    struct label *mntlabel, struct vnode *vp, struct label *vlabel)
922{
923	struct mac_biba *source, *dest;
924
925	source = SLOT(mntlabel);
926	dest = SLOT(vlabel);
927
928	mac_biba_copy_effective(source, dest);
929}
930
931static int
932mac_biba_create_vnode_extattr(struct ucred *cred, struct mount *mp,
933    struct label *mntlabel, struct vnode *dvp, struct label *dlabel,
934    struct vnode *vp, struct label *vlabel, struct componentname *cnp)
935{
936	struct mac_biba *source, *dest, temp;
937	size_t buflen;
938	int error;
939
940	buflen = sizeof(temp);
941	bzero(&temp, buflen);
942
943	source = SLOT(cred->cr_label);
944	dest = SLOT(vlabel);
945	mac_biba_copy_effective(source, &temp);
946
947	error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
948	    MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread);
949	if (error == 0)
950		mac_biba_copy_effective(source, dest);
951	return (error);
952}
953
954static int
955mac_biba_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp,
956    struct label *vlabel, struct label *intlabel)
957{
958	struct mac_biba *source, temp;
959	size_t buflen;
960	int error;
961
962	buflen = sizeof(temp);
963	bzero(&temp, buflen);
964
965	source = SLOT(intlabel);
966	if ((source->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) == 0)
967		return (0);
968
969	mac_biba_copy_effective(source, &temp);
970
971	error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
972	    MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread);
973	return (error);
974}
975
976/*
977 * Labeling event operations: IPC object.
978 */
979static void
980mac_biba_create_inpcb_from_socket(struct socket *so, struct label *solabel,
981    struct inpcb *inp, struct label *inplabel)
982{
983	struct mac_biba *source, *dest;
984
985	source = SLOT(solabel);
986	dest = SLOT(inplabel);
987
988	mac_biba_copy_effective(source, dest);
989}
990
991static void
992mac_biba_create_mbuf_from_socket(struct socket *so, struct label *socketlabel,
993    struct mbuf *m, struct label *mbuflabel)
994{
995	struct mac_biba *source, *dest;
996
997	source = SLOT(socketlabel);
998	dest = SLOT(mbuflabel);
999
1000	mac_biba_copy_effective(source, dest);
1001}
1002
1003static void
1004mac_biba_create_socket(struct ucred *cred, struct socket *socket,
1005    struct label *socketlabel)
1006{
1007	struct mac_biba *source, *dest;
1008
1009	source = SLOT(cred->cr_label);
1010	dest = SLOT(socketlabel);
1011
1012	mac_biba_copy_effective(source, dest);
1013}
1014
1015static void
1016mac_biba_create_pipe(struct ucred *cred, struct pipepair *pp,
1017    struct label *pipelabel)
1018{
1019	struct mac_biba *source, *dest;
1020
1021	source = SLOT(cred->cr_label);
1022	dest = SLOT(pipelabel);
1023
1024	mac_biba_copy_effective(source, dest);
1025}
1026
1027static void
1028mac_biba_create_posix_sem(struct ucred *cred, struct ksem *ksemptr,
1029    struct label *ks_label)
1030{
1031	struct mac_biba *source, *dest;
1032
1033	source = SLOT(cred->cr_label);
1034	dest = SLOT(ks_label);
1035
1036	mac_biba_copy_effective(source, dest);
1037}
1038
1039static void
1040mac_biba_create_socket_from_socket(struct socket *oldsocket,
1041    struct label *oldsocketlabel, struct socket *newsocket,
1042    struct label *newsocketlabel)
1043{
1044	struct mac_biba *source, *dest;
1045
1046	source = SLOT(oldsocketlabel);
1047	dest = SLOT(newsocketlabel);
1048
1049	mac_biba_copy_effective(source, dest);
1050}
1051
1052static void
1053mac_biba_relabel_socket(struct ucred *cred, struct socket *socket,
1054    struct label *socketlabel, struct label *newlabel)
1055{
1056	struct mac_biba *source, *dest;
1057
1058	source = SLOT(newlabel);
1059	dest = SLOT(socketlabel);
1060
1061	mac_biba_copy(source, dest);
1062}
1063
1064static void
1065mac_biba_relabel_pipe(struct ucred *cred, struct pipepair *pp,
1066    struct label *pipelabel, struct label *newlabel)
1067{
1068	struct mac_biba *source, *dest;
1069
1070	source = SLOT(newlabel);
1071	dest = SLOT(pipelabel);
1072
1073	mac_biba_copy(source, dest);
1074}
1075
1076static void
1077mac_biba_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel,
1078    struct socket *socket, struct label *socketpeerlabel)
1079{
1080	struct mac_biba *source, *dest;
1081
1082	source = SLOT(mbuflabel);
1083	dest = SLOT(socketpeerlabel);
1084
1085	mac_biba_copy_effective(source, dest);
1086}
1087
1088/*
1089 * Labeling event operations: System V IPC objects.
1090 */
1091
1092static void
1093mac_biba_create_sysv_msgmsg(struct ucred *cred, struct msqid_kernel *msqkptr,
1094    struct label *msqlabel, struct msg *msgptr, struct label *msglabel)
1095{
1096	struct mac_biba *source, *dest;
1097
1098	/* Ignore the msgq label */
1099	source = SLOT(cred->cr_label);
1100	dest = SLOT(msglabel);
1101
1102	mac_biba_copy_effective(source, dest);
1103}
1104
1105static void
1106mac_biba_create_sysv_msgqueue(struct ucred *cred,
1107    struct msqid_kernel *msqkptr, struct label *msqlabel)
1108{
1109	struct mac_biba *source, *dest;
1110
1111	source = SLOT(cred->cr_label);
1112	dest = SLOT(msqlabel);
1113
1114	mac_biba_copy_effective(source, dest);
1115}
1116
1117static void
1118mac_biba_create_sysv_sem(struct ucred *cred, struct semid_kernel *semakptr,
1119    struct label *semalabel)
1120{
1121	struct mac_biba *source, *dest;
1122
1123	source = SLOT(cred->cr_label);
1124	dest = SLOT(semalabel);
1125
1126	mac_biba_copy_effective(source, dest);
1127}
1128
1129static void
1130mac_biba_create_sysv_shm(struct ucred *cred, struct shmid_kernel *shmsegptr,
1131    struct label *shmlabel)
1132{
1133	struct mac_biba *source, *dest;
1134
1135	source = SLOT(cred->cr_label);
1136	dest = SLOT(shmlabel);
1137
1138	mac_biba_copy_effective(source, dest);
1139}
1140
1141/*
1142 * Labeling event operations: network objects.
1143 */
1144static void
1145mac_biba_set_socket_peer_from_socket(struct socket *oldsocket,
1146    struct label *oldsocketlabel, struct socket *newsocket,
1147    struct label *newsocketpeerlabel)
1148{
1149	struct mac_biba *source, *dest;
1150
1151	source = SLOT(oldsocketlabel);
1152	dest = SLOT(newsocketpeerlabel);
1153
1154	mac_biba_copy_effective(source, dest);
1155}
1156
1157static void
1158mac_biba_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d,
1159    struct label *bpflabel)
1160{
1161	struct mac_biba *source, *dest;
1162
1163	source = SLOT(cred->cr_label);
1164	dest = SLOT(bpflabel);
1165
1166	mac_biba_copy_effective(source, dest);
1167}
1168
1169static void
1170mac_biba_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel)
1171{
1172	char tifname[IFNAMSIZ], *p, *q;
1173	char tiflist[sizeof(trusted_interfaces)];
1174	struct mac_biba *dest;
1175	int len, type;
1176
1177	dest = SLOT(ifnetlabel);
1178
1179	if (ifnet->if_type == IFT_LOOP || interfaces_equal != 0) {
1180		type = MAC_BIBA_TYPE_EQUAL;
1181		goto set;
1182	}
1183
1184	if (trust_all_interfaces) {
1185		type = MAC_BIBA_TYPE_HIGH;
1186		goto set;
1187	}
1188
1189	type = MAC_BIBA_TYPE_LOW;
1190
1191	if (trusted_interfaces[0] == '\0' ||
1192	    !strvalid(trusted_interfaces, sizeof(trusted_interfaces)))
1193		goto set;
1194
1195	bzero(tiflist, sizeof(tiflist));
1196	for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++)
1197		if(*p != ' ' && *p != '\t')
1198			*q = *p;
1199
1200	for (p = q = tiflist;; p++) {
1201		if (*p == ',' || *p == '\0') {
1202			len = p - q;
1203			if (len < IFNAMSIZ) {
1204				bzero(tifname, sizeof(tifname));
1205				bcopy(q, tifname, len);
1206				if (strcmp(tifname, ifnet->if_xname) == 0) {
1207					type = MAC_BIBA_TYPE_HIGH;
1208					break;
1209				}
1210			} else {
1211				*p = '\0';
1212				printf("mac_biba warning: interface name "
1213				    "\"%s\" is too long (must be < %d)\n",
1214				    q, IFNAMSIZ);
1215			}
1216			if (*p == '\0')
1217				break;
1218			q = p + 1;
1219		}
1220	}
1221set:
1222	mac_biba_set_effective(dest, type, 0, NULL);
1223	mac_biba_set_range(dest, type, 0, NULL, type, 0, NULL);
1224}
1225
1226static void
1227mac_biba_create_ipq(struct mbuf *fragment, struct label *fragmentlabel,
1228    struct ipq *ipq, struct label *ipqlabel)
1229{
1230	struct mac_biba *source, *dest;
1231
1232	source = SLOT(fragmentlabel);
1233	dest = SLOT(ipqlabel);
1234
1235	mac_biba_copy_effective(source, dest);
1236}
1237
1238static void
1239mac_biba_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel,
1240    struct mbuf *datagram, struct label *datagramlabel)
1241{
1242	struct mac_biba *source, *dest;
1243
1244	source = SLOT(ipqlabel);
1245	dest = SLOT(datagramlabel);
1246
1247	/* Just use the head, since we require them all to match. */
1248	mac_biba_copy_effective(source, dest);
1249}
1250
1251static void
1252mac_biba_create_fragment(struct mbuf *datagram, struct label *datagramlabel,
1253    struct mbuf *fragment, struct label *fragmentlabel)
1254{
1255	struct mac_biba *source, *dest;
1256
1257	source = SLOT(datagramlabel);
1258	dest = SLOT(fragmentlabel);
1259
1260	mac_biba_copy_effective(source, dest);
1261}
1262
1263static void
1264mac_biba_create_mbuf_from_inpcb(struct inpcb *inp, struct label *inplabel,
1265    struct mbuf *m, struct label *mlabel)
1266{
1267	struct mac_biba *source, *dest;
1268
1269	source = SLOT(inplabel);
1270	dest = SLOT(mlabel);
1271
1272	mac_biba_copy_effective(source, dest);
1273}
1274
1275static void
1276mac_biba_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel,
1277    struct mbuf *mbuf, struct label *mbuflabel)
1278{
1279	struct mac_biba *dest;
1280
1281	dest = SLOT(mbuflabel);
1282
1283	mac_biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1284}
1285
1286static void
1287mac_biba_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel,
1288    struct mbuf *mbuf, struct label *mbuflabel)
1289{
1290	struct mac_biba *source, *dest;
1291
1292	source = SLOT(bpflabel);
1293	dest = SLOT(mbuflabel);
1294
1295	mac_biba_copy_effective(source, dest);
1296}
1297
1298static void
1299mac_biba_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel,
1300    struct mbuf *m, struct label *mbuflabel)
1301{
1302	struct mac_biba *source, *dest;
1303
1304	source = SLOT(ifnetlabel);
1305	dest = SLOT(mbuflabel);
1306
1307	mac_biba_copy_effective(source, dest);
1308}
1309
1310static void
1311mac_biba_create_mbuf_multicast_encap(struct mbuf *oldmbuf,
1312    struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel,
1313    struct mbuf *newmbuf, struct label *newmbuflabel)
1314{
1315	struct mac_biba *source, *dest;
1316
1317	source = SLOT(oldmbuflabel);
1318	dest = SLOT(newmbuflabel);
1319
1320	mac_biba_copy_effective(source, dest);
1321}
1322
1323static void
1324mac_biba_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel,
1325    struct mbuf *newmbuf, struct label *newmbuflabel)
1326{
1327	struct mac_biba *source, *dest;
1328
1329	source = SLOT(oldmbuflabel);
1330	dest = SLOT(newmbuflabel);
1331
1332	mac_biba_copy_effective(source, dest);
1333}
1334
1335static int
1336mac_biba_fragment_match(struct mbuf *fragment, struct label *fragmentlabel,
1337    struct ipq *ipq, struct label *ipqlabel)
1338{
1339	struct mac_biba *a, *b;
1340
1341	a = SLOT(ipqlabel);
1342	b = SLOT(fragmentlabel);
1343
1344	return (mac_biba_equal_effective(a, b));
1345}
1346
1347static void
1348mac_biba_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet,
1349    struct label *ifnetlabel, struct label *newlabel)
1350{
1351	struct mac_biba *source, *dest;
1352
1353	source = SLOT(newlabel);
1354	dest = SLOT(ifnetlabel);
1355
1356	mac_biba_copy(source, dest);
1357}
1358
1359static void
1360mac_biba_update_ipq(struct mbuf *fragment, struct label *fragmentlabel,
1361    struct ipq *ipq, struct label *ipqlabel)
1362{
1363
1364	/* NOOP: we only accept matching labels, so no need to update */
1365}
1366
1367static void
1368mac_biba_inpcb_sosetlabel(struct socket *so, struct label *solabel,
1369    struct inpcb *inp, struct label *inplabel)
1370{
1371	struct mac_biba *source, *dest;
1372
1373	source = SLOT(solabel);
1374	dest = SLOT(inplabel);
1375
1376	mac_biba_copy(source, dest);
1377}
1378
1379static void
1380mac_biba_create_mbuf_from_firewall(struct mbuf *m, struct label *label)
1381{
1382	struct mac_biba *dest;
1383
1384	dest = SLOT(label);
1385
1386	/* XXX: where is the label for the firewall really comming from? */
1387	mac_biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1388}
1389
1390/*
1391 * Labeling event operations: processes.
1392 */
1393static void
1394mac_biba_create_proc0(struct ucred *cred)
1395{
1396	struct mac_biba *dest;
1397
1398	dest = SLOT(cred->cr_label);
1399
1400	mac_biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1401	mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL,
1402	    MAC_BIBA_TYPE_HIGH, 0, NULL);
1403}
1404
1405static void
1406mac_biba_create_proc1(struct ucred *cred)
1407{
1408	struct mac_biba *dest;
1409
1410	dest = SLOT(cred->cr_label);
1411
1412	mac_biba_set_effective(dest, MAC_BIBA_TYPE_HIGH, 0, NULL);
1413	mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL,
1414	    MAC_BIBA_TYPE_HIGH, 0, NULL);
1415}
1416
1417static void
1418mac_biba_relabel_cred(struct ucred *cred, struct label *newlabel)
1419{
1420	struct mac_biba *source, *dest;
1421
1422	source = SLOT(newlabel);
1423	dest = SLOT(cred->cr_label);
1424
1425	mac_biba_copy(source, dest);
1426}
1427
1428/*
1429 * Label cleanup/flush operations
1430 */
1431static void
1432mac_biba_cleanup_sysv_msgmsg(struct label *msglabel)
1433{
1434
1435	bzero(SLOT(msglabel), sizeof(struct mac_biba));
1436}
1437
1438static void
1439mac_biba_cleanup_sysv_msgqueue(struct label *msqlabel)
1440{
1441
1442	bzero(SLOT(msqlabel), sizeof(struct mac_biba));
1443}
1444
1445static void
1446mac_biba_cleanup_sysv_sem(struct label *semalabel)
1447{
1448
1449	bzero(SLOT(semalabel), sizeof(struct mac_biba));
1450}
1451
1452static void
1453mac_biba_cleanup_sysv_shm(struct label *shmlabel)
1454{
1455	bzero(SLOT(shmlabel), sizeof(struct mac_biba));
1456}
1457
1458/*
1459 * Access control checks.
1460 */
1461static int
1462mac_biba_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel,
1463    struct ifnet *ifnet, struct label *ifnetlabel)
1464{
1465	struct mac_biba *a, *b;
1466
1467	if (!mac_biba_enabled)
1468		return (0);
1469
1470	a = SLOT(bpflabel);
1471	b = SLOT(ifnetlabel);
1472
1473	if (mac_biba_equal_effective(a, b))
1474		return (0);
1475	return (EACCES);
1476}
1477
1478static int
1479mac_biba_check_cred_relabel(struct ucred *cred, struct label *newlabel)
1480{
1481	struct mac_biba *subj, *new;
1482	int error;
1483
1484	subj = SLOT(cred->cr_label);
1485	new = SLOT(newlabel);
1486
1487	/*
1488	 * If there is a Biba label update for the credential, it may
1489	 * be an update of the effective, range, or both.
1490	 */
1491	error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
1492	if (error)
1493		return (error);
1494
1495	/*
1496	 * If the Biba label is to be changed, authorize as appropriate.
1497	 */
1498	if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) {
1499		/*
1500		 * If the change request modifies both the Biba label
1501		 * effective and range, check that the new effective will be
1502		 * in the new range.
1503		 */
1504		if ((new->mb_flags & MAC_BIBA_FLAGS_BOTH) ==
1505		    MAC_BIBA_FLAGS_BOTH &&
1506		    !mac_biba_effective_in_range(new, new))
1507			return (EINVAL);
1508
1509		/*
1510		 * To change the Biba effective label on a credential, the
1511		 * new effective label must be in the current range.
1512		 */
1513		if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE &&
1514		    !mac_biba_effective_in_range(new, subj))
1515			return (EPERM);
1516
1517		/*
1518		 * To change the Biba range on a credential, the new
1519		 * range label must be in the current range.
1520		 */
1521		if (new->mb_flags & MAC_BIBA_FLAG_RANGE &&
1522		    !mac_biba_range_in_range(new, subj))
1523			return (EPERM);
1524
1525		/*
1526		 * To have EQUAL in any component of the new credential
1527		 * Biba label, the subject must already have EQUAL in
1528		 * their label.
1529		 */
1530		if (mac_biba_contains_equal(new)) {
1531			error = mac_biba_subject_privileged(subj);
1532			if (error)
1533				return (error);
1534		}
1535	}
1536
1537	return (0);
1538}
1539
1540static int
1541mac_biba_check_cred_visible(struct ucred *u1, struct ucred *u2)
1542{
1543	struct mac_biba *subj, *obj;
1544
1545	if (!mac_biba_enabled)
1546		return (0);
1547
1548	subj = SLOT(u1->cr_label);
1549	obj = SLOT(u2->cr_label);
1550
1551	/* XXX: range */
1552	if (!mac_biba_dominate_effective(obj, subj))
1553		return (ESRCH);
1554
1555	return (0);
1556}
1557
1558static int
1559mac_biba_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet,
1560    struct label *ifnetlabel, struct label *newlabel)
1561{
1562	struct mac_biba *subj, *new;
1563	int error;
1564
1565	subj = SLOT(cred->cr_label);
1566	new = SLOT(newlabel);
1567
1568	/*
1569	 * If there is a Biba label update for the interface, it may
1570	 * be an update of the effective, range, or both.
1571	 */
1572	error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
1573	if (error)
1574		return (error);
1575
1576	/*
1577	 * Relabling network interfaces requires Biba privilege.
1578	 */
1579	error = mac_biba_subject_privileged(subj);
1580	if (error)
1581		return (error);
1582
1583	return (0);
1584}
1585
1586static int
1587mac_biba_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel,
1588    struct mbuf *m, struct label *mbuflabel)
1589{
1590	struct mac_biba *p, *i;
1591
1592	if (!mac_biba_enabled)
1593		return (0);
1594
1595	p = SLOT(mbuflabel);
1596	i = SLOT(ifnetlabel);
1597
1598	return (mac_biba_effective_in_range(p, i) ? 0 : EACCES);
1599}
1600
1601static int
1602mac_biba_check_inpcb_deliver(struct inpcb *inp, struct label *inplabel,
1603    struct mbuf *m, struct label *mlabel)
1604{
1605	struct mac_biba *p, *i;
1606
1607	if (!mac_biba_enabled)
1608		return (0);
1609
1610	p = SLOT(mlabel);
1611	i = SLOT(inplabel);
1612
1613	return (mac_biba_equal_effective(p, i) ? 0 : EACCES);
1614}
1615
1616static int
1617mac_biba_check_sysv_msgrcv(struct ucred *cred, struct msg *msgptr,
1618    struct label *msglabel)
1619{
1620	struct mac_biba *subj, *obj;
1621
1622	if (!mac_biba_enabled)
1623		return (0);
1624
1625	subj = SLOT(cred->cr_label);
1626	obj = SLOT(msglabel);
1627
1628	if (!mac_biba_dominate_effective(obj, subj))
1629		return (EACCES);
1630
1631	return (0);
1632}
1633
1634static int
1635mac_biba_check_sysv_msgrmid(struct ucred *cred, struct msg *msgptr,
1636    struct label *msglabel)
1637{
1638	struct mac_biba *subj, *obj;
1639
1640	if (!mac_biba_enabled)
1641		return (0);
1642
1643	subj = SLOT(cred->cr_label);
1644	obj = SLOT(msglabel);
1645
1646	if (!mac_biba_dominate_effective(subj, obj))
1647		return (EACCES);
1648
1649	return (0);
1650}
1651
1652static int
1653mac_biba_check_sysv_msqget(struct ucred *cred, struct msqid_kernel *msqkptr,
1654    struct label *msqklabel)
1655{
1656	struct mac_biba *subj, *obj;
1657
1658	if (!mac_biba_enabled)
1659		return (0);
1660
1661	subj = SLOT(cred->cr_label);
1662	obj = SLOT(msqklabel);
1663
1664	if (!mac_biba_dominate_effective(obj, subj))
1665		return (EACCES);
1666
1667	return (0);
1668}
1669
1670static int
1671mac_biba_check_sysv_msqsnd(struct ucred *cred, struct msqid_kernel *msqkptr,
1672    struct label *msqklabel)
1673{
1674	struct mac_biba *subj, *obj;
1675
1676	if (!mac_biba_enabled)
1677		return (0);
1678
1679	subj = SLOT(cred->cr_label);
1680	obj = SLOT(msqklabel);
1681
1682	if (!mac_biba_dominate_effective(subj, obj))
1683		return (EACCES);
1684
1685	return (0);
1686}
1687
1688static int
1689mac_biba_check_sysv_msqrcv(struct ucred *cred, struct msqid_kernel *msqkptr,
1690    struct label *msqklabel)
1691{
1692	struct mac_biba *subj, *obj;
1693
1694	if (!mac_biba_enabled)
1695		return (0);
1696
1697	subj = SLOT(cred->cr_label);
1698	obj = SLOT(msqklabel);
1699
1700	if (!mac_biba_dominate_effective(obj, subj))
1701		return (EACCES);
1702
1703	return (0);
1704}
1705
1706
1707static int
1708mac_biba_check_sysv_msqctl(struct ucred *cred, struct msqid_kernel *msqkptr,
1709    struct label *msqklabel, int cmd)
1710{
1711	struct mac_biba *subj, *obj;
1712
1713	if (!mac_biba_enabled)
1714		return (0);
1715
1716	subj = SLOT(cred->cr_label);
1717	obj = SLOT(msqklabel);
1718
1719	switch(cmd) {
1720	case IPC_RMID:
1721	case IPC_SET:
1722		if (!mac_biba_dominate_effective(subj, obj))
1723			return (EACCES);
1724		break;
1725
1726	case IPC_STAT:
1727		if (!mac_biba_dominate_effective(obj, subj))
1728			return (EACCES);
1729		break;
1730
1731	default:
1732		return (EACCES);
1733	}
1734
1735	return (0);
1736}
1737
1738static int
1739mac_biba_check_sysv_semctl(struct ucred *cred, struct semid_kernel *semakptr,
1740    struct label *semaklabel, int cmd)
1741{
1742	struct mac_biba *subj, *obj;
1743
1744	if (!mac_biba_enabled)
1745		return (0);
1746
1747	subj = SLOT(cred->cr_label);
1748	obj = SLOT(semaklabel);
1749
1750	switch(cmd) {
1751	case IPC_RMID:
1752	case IPC_SET:
1753	case SETVAL:
1754	case SETALL:
1755		if (!mac_biba_dominate_effective(subj, obj))
1756			return (EACCES);
1757		break;
1758
1759	case IPC_STAT:
1760	case GETVAL:
1761	case GETPID:
1762	case GETNCNT:
1763	case GETZCNT:
1764	case GETALL:
1765		if (!mac_biba_dominate_effective(obj, subj))
1766			return (EACCES);
1767		break;
1768
1769	default:
1770		return (EACCES);
1771	}
1772
1773	return (0);
1774}
1775
1776
1777static int
1778mac_biba_check_sysv_semget(struct ucred *cred, struct semid_kernel *semakptr,
1779    struct label *semaklabel)
1780{
1781	struct mac_biba *subj, *obj;
1782
1783	if (!mac_biba_enabled)
1784		return (0);
1785
1786	subj = SLOT(cred->cr_label);
1787	obj = SLOT(semaklabel);
1788
1789	if (!mac_biba_dominate_effective(obj, subj))
1790		return (EACCES);
1791
1792	return (0);
1793}
1794
1795
1796static int
1797mac_biba_check_sysv_semop(struct ucred *cred, struct semid_kernel *semakptr,
1798    struct label *semaklabel, size_t accesstype)
1799{
1800	struct mac_biba *subj, *obj;
1801
1802	if (!mac_biba_enabled)
1803		return (0);
1804
1805	subj = SLOT(cred->cr_label);
1806	obj = SLOT(semaklabel);
1807
1808	if (accesstype & SEM_R)
1809		if (!mac_biba_dominate_effective(obj, subj))
1810			return (EACCES);
1811
1812	if (accesstype & SEM_A)
1813		if (!mac_biba_dominate_effective(subj, obj))
1814			return (EACCES);
1815
1816	return (0);
1817}
1818
1819static int
1820mac_biba_check_sysv_shmat(struct ucred *cred, struct shmid_kernel *shmsegptr,
1821    struct label *shmseglabel, int shmflg)
1822{
1823	struct mac_biba *subj, *obj;
1824
1825	if (!mac_biba_enabled)
1826		return (0);
1827
1828	subj = SLOT(cred->cr_label);
1829	obj = SLOT(shmseglabel);
1830
1831	if (!mac_biba_dominate_effective(obj, subj))
1832		return (EACCES);
1833	if ((shmflg & SHM_RDONLY) == 0) {
1834		if (!mac_biba_dominate_effective(subj, obj))
1835			return (EACCES);
1836	}
1837
1838	return (0);
1839}
1840
1841static int
1842mac_biba_check_sysv_shmctl(struct ucred *cred, struct shmid_kernel *shmsegptr,
1843    struct label *shmseglabel, int cmd)
1844{
1845	struct mac_biba *subj, *obj;
1846
1847	if (!mac_biba_enabled)
1848		return (0);
1849
1850	subj = SLOT(cred->cr_label);
1851	obj = SLOT(shmseglabel);
1852
1853	switch(cmd) {
1854	case IPC_RMID:
1855	case IPC_SET:
1856		if (!mac_biba_dominate_effective(subj, obj))
1857			return (EACCES);
1858		break;
1859
1860	case IPC_STAT:
1861	case SHM_STAT:
1862		if (!mac_biba_dominate_effective(obj, subj))
1863			return (EACCES);
1864		break;
1865
1866	default:
1867		return (EACCES);
1868	}
1869
1870	return (0);
1871}
1872
1873static int
1874mac_biba_check_sysv_shmget(struct ucred *cred, struct shmid_kernel *shmsegptr,
1875    struct label *shmseglabel, int shmflg)
1876{
1877	struct mac_biba *subj, *obj;
1878
1879	if (!mac_biba_enabled)
1880		return (0);
1881
1882	subj = SLOT(cred->cr_label);
1883	obj = SLOT(shmseglabel);
1884
1885	if (!mac_biba_dominate_effective(obj, subj))
1886		return (EACCES);
1887
1888	return (0);
1889}
1890
1891static int
1892mac_biba_check_kld_load(struct ucred *cred, struct vnode *vp,
1893    struct label *label)
1894{
1895	struct mac_biba *subj, *obj;
1896	int error;
1897
1898	if (!mac_biba_enabled)
1899		return (0);
1900
1901	subj = SLOT(cred->cr_label);
1902
1903	error = mac_biba_subject_privileged(subj);
1904	if (error)
1905		return (error);
1906
1907	obj = SLOT(label);
1908	if (!mac_biba_high_effective(obj))
1909		return (EACCES);
1910
1911	return (0);
1912}
1913
1914
1915static int
1916mac_biba_check_mount_stat(struct ucred *cred, struct mount *mp,
1917    struct label *mntlabel)
1918{
1919	struct mac_biba *subj, *obj;
1920
1921	if (!mac_biba_enabled)
1922		return (0);
1923
1924	subj = SLOT(cred->cr_label);
1925	obj = SLOT(mntlabel);
1926
1927	if (!mac_biba_dominate_effective(obj, subj))
1928		return (EACCES);
1929
1930	return (0);
1931}
1932
1933static int
1934mac_biba_check_pipe_ioctl(struct ucred *cred, struct pipepair *pp,
1935    struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data)
1936{
1937
1938	if(!mac_biba_enabled)
1939		return (0);
1940
1941	/* XXX: This will be implemented soon... */
1942
1943	return (0);
1944}
1945
1946static int
1947mac_biba_check_pipe_poll(struct ucred *cred, struct pipepair *pp,
1948    struct label *pipelabel)
1949{
1950	struct mac_biba *subj, *obj;
1951
1952	if (!mac_biba_enabled)
1953		return (0);
1954
1955	subj = SLOT(cred->cr_label);
1956	obj = SLOT((pipelabel));
1957
1958	if (!mac_biba_dominate_effective(obj, subj))
1959		return (EACCES);
1960
1961	return (0);
1962}
1963
1964static int
1965mac_biba_check_pipe_read(struct ucred *cred, struct pipepair *pp,
1966    struct label *pipelabel)
1967{
1968	struct mac_biba *subj, *obj;
1969
1970	if (!mac_biba_enabled)
1971		return (0);
1972
1973	subj = SLOT(cred->cr_label);
1974	obj = SLOT((pipelabel));
1975
1976	if (!mac_biba_dominate_effective(obj, subj))
1977		return (EACCES);
1978
1979	return (0);
1980}
1981
1982static int
1983mac_biba_check_pipe_relabel(struct ucred *cred, struct pipepair *pp,
1984    struct label *pipelabel, struct label *newlabel)
1985{
1986	struct mac_biba *subj, *obj, *new;
1987	int error;
1988
1989	new = SLOT(newlabel);
1990	subj = SLOT(cred->cr_label);
1991	obj = SLOT(pipelabel);
1992
1993	/*
1994	 * If there is a Biba label update for a pipe, it must be a
1995	 * effective update.
1996	 */
1997	error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE);
1998	if (error)
1999		return (error);
2000
2001	/*
2002	 * To perform a relabel of a pipe (Biba label or not), Biba must
2003	 * authorize the relabel.
2004	 */
2005	if (!mac_biba_effective_in_range(obj, subj))
2006		return (EPERM);
2007
2008	/*
2009	 * If the Biba label is to be changed, authorize as appropriate.
2010	 */
2011	if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
2012		/*
2013		 * To change the Biba label on a pipe, the new pipe label
2014		 * must be in the subject range.
2015		 */
2016		if (!mac_biba_effective_in_range(new, subj))
2017			return (EPERM);
2018
2019		/*
2020		 * To change the Biba label on a pipe to be EQUAL, the
2021		 * subject must have appropriate privilege.
2022		 */
2023		if (mac_biba_contains_equal(new)) {
2024			error = mac_biba_subject_privileged(subj);
2025			if (error)
2026				return (error);
2027		}
2028	}
2029
2030	return (0);
2031}
2032
2033static int
2034mac_biba_check_pipe_stat(struct ucred *cred, struct pipepair *pp,
2035    struct label *pipelabel)
2036{
2037	struct mac_biba *subj, *obj;
2038
2039	if (!mac_biba_enabled)
2040		return (0);
2041
2042	subj = SLOT(cred->cr_label);
2043	obj = SLOT((pipelabel));
2044
2045	if (!mac_biba_dominate_effective(obj, subj))
2046		return (EACCES);
2047
2048	return (0);
2049}
2050
2051static int
2052mac_biba_check_pipe_write(struct ucred *cred, struct pipepair *pp,
2053    struct label *pipelabel)
2054{
2055	struct mac_biba *subj, *obj;
2056
2057	if (!mac_biba_enabled)
2058		return (0);
2059
2060	subj = SLOT(cred->cr_label);
2061	obj = SLOT((pipelabel));
2062
2063	if (!mac_biba_dominate_effective(subj, obj))
2064		return (EACCES);
2065
2066	return (0);
2067}
2068
2069static int
2070mac_biba_check_posix_sem_write(struct ucred *cred, struct ksem *ksemptr,
2071    struct label *ks_label)
2072{
2073	struct mac_biba *subj, *obj;
2074
2075	if (!mac_biba_enabled)
2076		return (0);
2077
2078	subj = SLOT(cred->cr_label);
2079	obj = SLOT(ks_label);
2080
2081	if (!mac_biba_dominate_effective(subj, obj))
2082		return (EACCES);
2083
2084	return (0);
2085}
2086
2087static int
2088mac_biba_check_posix_sem_rdonly(struct ucred *cred, struct ksem *ksemptr,
2089    struct label *ks_label)
2090{
2091	struct mac_biba *subj, *obj;
2092
2093	if (!mac_biba_enabled)
2094		return (0);
2095
2096	subj = SLOT(cred->cr_label);
2097	obj = SLOT(ks_label);
2098
2099	if (!mac_biba_dominate_effective(obj, subj))
2100		return (EACCES);
2101
2102	return (0);
2103}
2104
2105static int
2106mac_biba_check_proc_debug(struct ucred *cred, struct proc *proc)
2107{
2108	struct mac_biba *subj, *obj;
2109
2110	if (!mac_biba_enabled)
2111		return (0);
2112
2113	subj = SLOT(cred->cr_label);
2114	obj = SLOT(proc->p_ucred->cr_label);
2115
2116	/* XXX: range checks */
2117	if (!mac_biba_dominate_effective(obj, subj))
2118		return (ESRCH);
2119	if (!mac_biba_dominate_effective(subj, obj))
2120		return (EACCES);
2121
2122	return (0);
2123}
2124
2125static int
2126mac_biba_check_proc_sched(struct ucred *cred, struct proc *proc)
2127{
2128	struct mac_biba *subj, *obj;
2129
2130	if (!mac_biba_enabled)
2131		return (0);
2132
2133	subj = SLOT(cred->cr_label);
2134	obj = SLOT(proc->p_ucred->cr_label);
2135
2136	/* XXX: range checks */
2137	if (!mac_biba_dominate_effective(obj, subj))
2138		return (ESRCH);
2139	if (!mac_biba_dominate_effective(subj, obj))
2140		return (EACCES);
2141
2142	return (0);
2143}
2144
2145static int
2146mac_biba_check_proc_signal(struct ucred *cred, struct proc *proc, int signum)
2147{
2148	struct mac_biba *subj, *obj;
2149
2150	if (!mac_biba_enabled)
2151		return (0);
2152
2153	subj = SLOT(cred->cr_label);
2154	obj = SLOT(proc->p_ucred->cr_label);
2155
2156	/* XXX: range checks */
2157	if (!mac_biba_dominate_effective(obj, subj))
2158		return (ESRCH);
2159	if (!mac_biba_dominate_effective(subj, obj))
2160		return (EACCES);
2161
2162	return (0);
2163}
2164
2165static int
2166mac_biba_check_socket_deliver(struct socket *so, struct label *socketlabel,
2167    struct mbuf *m, struct label *mbuflabel)
2168{
2169	struct mac_biba *p, *s;
2170
2171	if (!mac_biba_enabled)
2172		return (0);
2173
2174	p = SLOT(mbuflabel);
2175	s = SLOT(socketlabel);
2176
2177	return (mac_biba_equal_effective(p, s) ? 0 : EACCES);
2178}
2179
2180static int
2181mac_biba_check_socket_relabel(struct ucred *cred, struct socket *so,
2182    struct label *socketlabel, struct label *newlabel)
2183{
2184	struct mac_biba *subj, *obj, *new;
2185	int error;
2186
2187	new = SLOT(newlabel);
2188	subj = SLOT(cred->cr_label);
2189	obj = SLOT(socketlabel);
2190
2191	/*
2192	 * If there is a Biba label update for the socket, it may be
2193	 * an update of effective.
2194	 */
2195	error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE);
2196	if (error)
2197		return (error);
2198
2199	/*
2200	 * To relabel a socket, the old socket effective must be in the subject
2201	 * range.
2202	 */
2203	if (!mac_biba_effective_in_range(obj, subj))
2204		return (EPERM);
2205
2206	/*
2207	 * If the Biba label is to be changed, authorize as appropriate.
2208	 */
2209	if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
2210		/*
2211		 * To relabel a socket, the new socket effective must be in
2212		 * the subject range.
2213		 */
2214		if (!mac_biba_effective_in_range(new, subj))
2215			return (EPERM);
2216
2217		/*
2218		 * To change the Biba label on the socket to contain EQUAL,
2219		 * the subject must have appropriate privilege.
2220		 */
2221		if (mac_biba_contains_equal(new)) {
2222			error = mac_biba_subject_privileged(subj);
2223			if (error)
2224				return (error);
2225		}
2226	}
2227
2228	return (0);
2229}
2230
2231static int
2232mac_biba_check_socket_visible(struct ucred *cred, struct socket *socket,
2233    struct label *socketlabel)
2234{
2235	struct mac_biba *subj, *obj;
2236
2237	if (!mac_biba_enabled)
2238		return (0);
2239
2240	subj = SLOT(cred->cr_label);
2241	obj = SLOT(socketlabel);
2242
2243	if (!mac_biba_dominate_effective(obj, subj))
2244		return (ENOENT);
2245
2246	return (0);
2247}
2248
2249/*
2250 * Some system privileges are allowed regardless of integrity grade; others
2251 * are allowed only when running with privilege with respect to the Biba
2252 * policy as they might otherwise allow bypassing of the integrity policy.
2253 */
2254static int
2255mac_biba_priv_check(struct ucred *cred, int priv)
2256{
2257	struct mac_biba *subj;
2258	int error;
2259
2260	if (!mac_biba_enabled)
2261		return (0);
2262
2263	/*
2264	 * Exempt only specific privileges from the Biba integrity policy.
2265	 */
2266	switch (priv) {
2267	case PRIV_KTRACE:
2268	case PRIV_MSGBUF:
2269
2270	/*
2271	 * Allow processes to manipulate basic process audit properties, and
2272	 * to submit audit records.
2273	 */
2274	case PRIV_AUDIT_GETAUDIT:
2275	case PRIV_AUDIT_SETAUDIT:
2276	case PRIV_AUDIT_SUBMIT:
2277
2278	/*
2279	 * Allow processes to manipulate their regular UNIX credentials.
2280	 */
2281	case PRIV_CRED_SETUID:
2282	case PRIV_CRED_SETEUID:
2283	case PRIV_CRED_SETGID:
2284	case PRIV_CRED_SETEGID:
2285	case PRIV_CRED_SETGROUPS:
2286	case PRIV_CRED_SETREUID:
2287	case PRIV_CRED_SETREGID:
2288	case PRIV_CRED_SETRESUID:
2289	case PRIV_CRED_SETRESGID:
2290
2291	/*
2292	 * Allow processes to perform system monitoring.
2293	 */
2294	case PRIV_SEEOTHERGIDS:
2295	case PRIV_SEEOTHERUIDS:
2296		break;
2297
2298	/*
2299	 * Allow access to general process debugging facilities.  We
2300	 * separately control debugging based on MAC label.
2301	 */
2302	case PRIV_DEBUG_DIFFCRED:
2303	case PRIV_DEBUG_SUGID:
2304	case PRIV_DEBUG_UNPRIV:
2305
2306	/*
2307	 * Allow manipulating jails.
2308	 */
2309	case PRIV_JAIL_ATTACH:
2310
2311	/*
2312	 * Allow privilege with respect to the Partition policy, but not the
2313	 * Privs policy.
2314	 */
2315	case PRIV_MAC_PARTITION:
2316
2317	/*
2318	 * Allow privilege with respect to process resource limits and login
2319	 * context.
2320	 */
2321	case PRIV_PROC_LIMIT:
2322	case PRIV_PROC_SETLOGIN:
2323	case PRIV_PROC_SETRLIMIT:
2324
2325	/*
2326	 * Allow System V and POSIX IPC privileges.
2327	 */
2328	case PRIV_IPC_READ:
2329	case PRIV_IPC_WRITE:
2330	case PRIV_IPC_ADMIN:
2331	case PRIV_IPC_MSGSIZE:
2332	case PRIV_MQ_ADMIN:
2333
2334	/*
2335	 * Allow certain scheduler manipulations -- possibly this should be
2336	 * controlled by more fine-grained policy, as potentially low
2337	 * integrity processes can deny CPU to higher integrity ones.
2338	 */
2339	case PRIV_SCHED_DIFFCRED:
2340	case PRIV_SCHED_SETPRIORITY:
2341	case PRIV_SCHED_RTPRIO:
2342	case PRIV_SCHED_SETPOLICY:
2343	case PRIV_SCHED_SET:
2344	case PRIV_SCHED_SETPARAM:
2345
2346	/*
2347	 * More IPC privileges.
2348	 */
2349	case PRIV_SEM_WRITE:
2350
2351	/*
2352	 * Allow signaling privileges subject to integrity policy.
2353	 */
2354	case PRIV_SIGNAL_DIFFCRED:
2355	case PRIV_SIGNAL_SUGID:
2356
2357	/*
2358	 * Allow access to only limited sysctls from lower integrity levels;
2359	 * piggy-back on the Jail definition.
2360	 */
2361	case PRIV_SYSCTL_WRITEJAIL:
2362
2363	/*
2364	 * Allow TTY-based privileges, subject to general device access using
2365	 * labels on TTY device nodes, but not console privilege.
2366	 */
2367	case PRIV_TTY_DRAINWAIT:
2368	case PRIV_TTY_DTRWAIT:
2369	case PRIV_TTY_EXCLUSIVE:
2370	case PRIV_TTY_PRISON:
2371	case PRIV_TTY_STI:
2372	case PRIV_TTY_SETA:
2373
2374	/*
2375	 * Grant most VFS privileges, as almost all are in practice bounded
2376	 * by more specific checks using labels.
2377	 */
2378	case PRIV_VFS_READ:
2379	case PRIV_VFS_WRITE:
2380	case PRIV_VFS_ADMIN:
2381	case PRIV_VFS_EXEC:
2382	case PRIV_VFS_LOOKUP:
2383	case PRIV_VFS_CHFLAGS_DEV:
2384	case PRIV_VFS_CHOWN:
2385	case PRIV_VFS_CHROOT:
2386	case PRIV_VFS_RETAINSUGID:
2387	case PRIV_VFS_EXCEEDQUOTA:
2388	case PRIV_VFS_FCHROOT:
2389	case PRIV_VFS_FHOPEN:
2390	case PRIV_VFS_FHSTATFS:
2391	case PRIV_VFS_GENERATION:
2392	case PRIV_VFS_GETFH:
2393	case PRIV_VFS_GETQUOTA:
2394	case PRIV_VFS_LINK:
2395	case PRIV_VFS_MOUNT:
2396	case PRIV_VFS_MOUNT_OWNER:
2397	case PRIV_VFS_MOUNT_PERM:
2398	case PRIV_VFS_MOUNT_SUIDDIR:
2399	case PRIV_VFS_MOUNT_NONUSER:
2400	case PRIV_VFS_SETGID:
2401	case PRIV_VFS_STICKYFILE:
2402	case PRIV_VFS_SYSFLAGS:
2403	case PRIV_VFS_UNMOUNT:
2404
2405	/*
2406	 * Allow VM privileges; it would be nice if these were subject to
2407	 * resource limits.
2408	 */
2409	case PRIV_VM_MADV_PROTECT:
2410	case PRIV_VM_MLOCK:
2411	case PRIV_VM_MUNLOCK:
2412
2413	/*
2414	 * Allow some but not all network privileges.  In general, dont allow
2415	 * reconfiguring the network stack, just normal use.
2416	 */
2417	case PRIV_NETATALK_RESERVEDPORT:
2418	case PRIV_NETINET_RESERVEDPORT:
2419	case PRIV_NETINET_RAW:
2420	case PRIV_NETINET_REUSEPORT:
2421	case PRIV_NETIPX_RESERVEDPORT:
2422	case PRIV_NETIPX_RAW:
2423		break;
2424
2425	/*
2426	 * All remaining system privileges are allow only if the process
2427	 * holds privilege with respect to the Biba policy.
2428	 */
2429	default:
2430		subj = SLOT(cred->cr_label);
2431		error = mac_biba_subject_privileged(subj);
2432		if (error)
2433			return (error);
2434	}
2435	return (0);
2436}
2437
2438static int
2439mac_biba_check_system_acct(struct ucred *cred, struct vnode *vp,
2440    struct label *label)
2441{
2442	struct mac_biba *subj, *obj;
2443	int error;
2444
2445	if (!mac_biba_enabled)
2446		return (0);
2447
2448	subj = SLOT(cred->cr_label);
2449
2450	error = mac_biba_subject_privileged(subj);
2451	if (error)
2452		return (error);
2453
2454	if (label == NULL)
2455		return (0);
2456
2457	obj = SLOT(label);
2458	if (!mac_biba_high_effective(obj))
2459		return (EACCES);
2460
2461	return (0);
2462}
2463
2464static int
2465mac_biba_check_system_auditctl(struct ucred *cred, struct vnode *vp,
2466    struct label *vplabel)
2467{
2468	struct mac_biba *subj, *obj;
2469	int error;
2470
2471	if (!mac_biba_enabled)
2472		return (0);
2473
2474	subj = SLOT(cred->cr_label);
2475
2476	error = mac_biba_subject_privileged(subj);
2477	if (error)
2478		return (error);
2479
2480	if (vplabel == NULL)
2481		return (0);
2482
2483	obj = SLOT(vplabel);
2484	if (!mac_biba_high_effective(obj))
2485		return (EACCES);
2486
2487	return (0);
2488}
2489
2490static int
2491mac_biba_check_system_auditon(struct ucred *cred, int cmd)
2492{
2493	struct mac_biba *subj;
2494	int error;
2495
2496	if (!mac_biba_enabled)
2497		return (0);
2498
2499	subj = SLOT(cred->cr_label);
2500
2501	error = mac_biba_subject_privileged(subj);
2502	if (error)
2503		return (error);
2504
2505	return (0);
2506}
2507
2508static int
2509mac_biba_check_system_swapon(struct ucred *cred, struct vnode *vp,
2510    struct label *label)
2511{
2512	struct mac_biba *subj, *obj;
2513	int error;
2514
2515	if (!mac_biba_enabled)
2516		return (0);
2517
2518	subj = SLOT(cred->cr_label);
2519	obj = SLOT(label);
2520
2521	error = mac_biba_subject_privileged(subj);
2522	if (error)
2523		return (error);
2524
2525	if (!mac_biba_high_effective(obj))
2526		return (EACCES);
2527
2528	return (0);
2529}
2530
2531static int
2532mac_biba_check_system_swapoff(struct ucred *cred, struct vnode *vp,
2533    struct label *label)
2534{
2535	struct mac_biba *subj;
2536	int error;
2537
2538	if (!mac_biba_enabled)
2539		return (0);
2540
2541	subj = SLOT(cred->cr_label);
2542
2543	error = mac_biba_subject_privileged(subj);
2544	if (error)
2545		return (error);
2546
2547	return (0);
2548}
2549
2550static int
2551mac_biba_check_system_sysctl(struct ucred *cred, struct sysctl_oid *oidp,
2552    void *arg1, int arg2, struct sysctl_req *req)
2553{
2554	struct mac_biba *subj;
2555	int error;
2556
2557	if (!mac_biba_enabled)
2558		return (0);
2559
2560	subj = SLOT(cred->cr_label);
2561
2562	/*
2563	 * Treat sysctl variables without CTLFLAG_ANYBODY flag as
2564	 * biba/high, but also require privilege to change them.
2565	 */
2566	if (req->newptr != NULL && (oidp->oid_kind & CTLFLAG_ANYBODY) == 0) {
2567		if (!mac_biba_subject_dominate_high(subj))
2568			return (EACCES);
2569
2570		error = mac_biba_subject_privileged(subj);
2571		if (error)
2572			return (error);
2573	}
2574
2575	return (0);
2576}
2577
2578static int
2579mac_biba_check_vnode_chdir(struct ucred *cred, struct vnode *dvp,
2580    struct label *dlabel)
2581{
2582	struct mac_biba *subj, *obj;
2583
2584	if (!mac_biba_enabled)
2585		return (0);
2586
2587	subj = SLOT(cred->cr_label);
2588	obj = SLOT(dlabel);
2589
2590	if (!mac_biba_dominate_effective(obj, subj))
2591		return (EACCES);
2592
2593	return (0);
2594}
2595
2596static int
2597mac_biba_check_vnode_chroot(struct ucred *cred, struct vnode *dvp,
2598    struct label *dlabel)
2599{
2600	struct mac_biba *subj, *obj;
2601
2602	if (!mac_biba_enabled)
2603		return (0);
2604
2605	subj = SLOT(cred->cr_label);
2606	obj = SLOT(dlabel);
2607
2608	if (!mac_biba_dominate_effective(obj, subj))
2609		return (EACCES);
2610
2611	return (0);
2612}
2613
2614static int
2615mac_biba_check_vnode_create(struct ucred *cred, struct vnode *dvp,
2616    struct label *dlabel, struct componentname *cnp, struct vattr *vap)
2617{
2618	struct mac_biba *subj, *obj;
2619
2620	if (!mac_biba_enabled)
2621		return (0);
2622
2623	subj = SLOT(cred->cr_label);
2624	obj = SLOT(dlabel);
2625
2626	if (!mac_biba_dominate_effective(subj, obj))
2627		return (EACCES);
2628
2629	return (0);
2630}
2631
2632static int
2633mac_biba_check_vnode_delete(struct ucred *cred, struct vnode *dvp,
2634    struct label *dlabel, struct vnode *vp, struct label *label,
2635    struct componentname *cnp)
2636{
2637	struct mac_biba *subj, *obj;
2638
2639	if (!mac_biba_enabled)
2640		return (0);
2641
2642	subj = SLOT(cred->cr_label);
2643	obj = SLOT(dlabel);
2644
2645	if (!mac_biba_dominate_effective(subj, obj))
2646		return (EACCES);
2647
2648	obj = SLOT(label);
2649
2650	if (!mac_biba_dominate_effective(subj, obj))
2651		return (EACCES);
2652
2653	return (0);
2654}
2655
2656static int
2657mac_biba_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
2658    struct label *label, acl_type_t type)
2659{
2660	struct mac_biba *subj, *obj;
2661
2662	if (!mac_biba_enabled)
2663		return (0);
2664
2665	subj = SLOT(cred->cr_label);
2666	obj = SLOT(label);
2667
2668	if (!mac_biba_dominate_effective(subj, obj))
2669		return (EACCES);
2670
2671	return (0);
2672}
2673
2674static int
2675mac_biba_check_vnode_deleteextattr(struct ucred *cred, struct vnode *vp,
2676    struct label *label, int attrnamespace, const char *name)
2677{
2678	struct mac_biba *subj, *obj;
2679
2680	if (!mac_biba_enabled)
2681		return (0);
2682
2683	subj = SLOT(cred->cr_label);
2684	obj = SLOT(label);
2685
2686	if (!mac_biba_dominate_effective(subj, obj))
2687		return (EACCES);
2688
2689	return (0);
2690}
2691
2692static int
2693mac_biba_check_vnode_exec(struct ucred *cred, struct vnode *vp,
2694    struct label *label, struct image_params *imgp,
2695    struct label *execlabel)
2696{
2697	struct mac_biba *subj, *obj, *exec;
2698	int error;
2699
2700	if (execlabel != NULL) {
2701		/*
2702		 * We currently don't permit labels to be changed at
2703		 * exec-time as part of Biba, so disallow non-NULL
2704		 * Biba label elements in the execlabel.
2705		 */
2706		exec = SLOT(execlabel);
2707		error = biba_atmostflags(exec, 0);
2708		if (error)
2709			return (error);
2710	}
2711
2712	if (!mac_biba_enabled)
2713		return (0);
2714
2715	subj = SLOT(cred->cr_label);
2716	obj = SLOT(label);
2717
2718	if (!mac_biba_dominate_effective(obj, subj))
2719		return (EACCES);
2720
2721	return (0);
2722}
2723
2724static int
2725mac_biba_check_vnode_getacl(struct ucred *cred, struct vnode *vp,
2726    struct label *label, acl_type_t type)
2727{
2728	struct mac_biba *subj, *obj;
2729
2730	if (!mac_biba_enabled)
2731		return (0);
2732
2733	subj = SLOT(cred->cr_label);
2734	obj = SLOT(label);
2735
2736	if (!mac_biba_dominate_effective(obj, subj))
2737		return (EACCES);
2738
2739	return (0);
2740}
2741
2742static int
2743mac_biba_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
2744    struct label *label, int attrnamespace, const char *name, struct uio *uio)
2745{
2746	struct mac_biba *subj, *obj;
2747
2748	if (!mac_biba_enabled)
2749		return (0);
2750
2751	subj = SLOT(cred->cr_label);
2752	obj = SLOT(label);
2753
2754	if (!mac_biba_dominate_effective(obj, subj))
2755		return (EACCES);
2756
2757	return (0);
2758}
2759
2760static int
2761mac_biba_check_vnode_link(struct ucred *cred, struct vnode *dvp,
2762    struct label *dlabel, struct vnode *vp, struct label *label,
2763    struct componentname *cnp)
2764{
2765	struct mac_biba *subj, *obj;
2766
2767	if (!mac_biba_enabled)
2768		return (0);
2769
2770	subj = SLOT(cred->cr_label);
2771	obj = SLOT(dlabel);
2772
2773	if (!mac_biba_dominate_effective(subj, obj))
2774		return (EACCES);
2775
2776	obj = SLOT(label);
2777
2778	if (!mac_biba_dominate_effective(subj, obj))
2779		return (EACCES);
2780
2781	return (0);
2782}
2783
2784static int
2785mac_biba_check_vnode_listextattr(struct ucred *cred, struct vnode *vp,
2786    struct label *label, int attrnamespace)
2787{
2788	struct mac_biba *subj, *obj;
2789
2790	if (!mac_biba_enabled)
2791		return (0);
2792
2793	subj = SLOT(cred->cr_label);
2794	obj = SLOT(label);
2795
2796	if (!mac_biba_dominate_effective(obj, subj))
2797		return (EACCES);
2798
2799	return (0);
2800}
2801
2802static int
2803mac_biba_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
2804    struct label *dlabel, struct componentname *cnp)
2805{
2806	struct mac_biba *subj, *obj;
2807
2808	if (!mac_biba_enabled)
2809		return (0);
2810
2811	subj = SLOT(cred->cr_label);
2812	obj = SLOT(dlabel);
2813
2814	if (!mac_biba_dominate_effective(obj, subj))
2815		return (EACCES);
2816
2817	return (0);
2818}
2819
2820static int
2821mac_biba_check_vnode_mmap(struct ucred *cred, struct vnode *vp,
2822    struct label *label, int prot, int flags)
2823{
2824	struct mac_biba *subj, *obj;
2825
2826	/*
2827	 * Rely on the use of open()-time protections to handle
2828	 * non-revocation cases.
2829	 */
2830	if (!mac_biba_enabled || !revocation_enabled)
2831		return (0);
2832
2833	subj = SLOT(cred->cr_label);
2834	obj = SLOT(label);
2835
2836	if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
2837		if (!mac_biba_dominate_effective(obj, subj))
2838			return (EACCES);
2839	}
2840	if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) {
2841		if (!mac_biba_dominate_effective(subj, obj))
2842			return (EACCES);
2843	}
2844
2845	return (0);
2846}
2847
2848static int
2849mac_biba_check_vnode_open(struct ucred *cred, struct vnode *vp,
2850    struct label *vnodelabel, int acc_mode)
2851{
2852	struct mac_biba *subj, *obj;
2853
2854	if (!mac_biba_enabled)
2855		return (0);
2856
2857	subj = SLOT(cred->cr_label);
2858	obj = SLOT(vnodelabel);
2859
2860	/* XXX privilege override for admin? */
2861	if (acc_mode & (VREAD | VEXEC | VSTAT)) {
2862		if (!mac_biba_dominate_effective(obj, subj))
2863			return (EACCES);
2864	}
2865	if (acc_mode & (VWRITE | VAPPEND | VADMIN)) {
2866		if (!mac_biba_dominate_effective(subj, obj))
2867			return (EACCES);
2868	}
2869
2870	return (0);
2871}
2872
2873static int
2874mac_biba_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred,
2875    struct vnode *vp, struct label *label)
2876{
2877	struct mac_biba *subj, *obj;
2878
2879	if (!mac_biba_enabled || !revocation_enabled)
2880		return (0);
2881
2882	subj = SLOT(active_cred->cr_label);
2883	obj = SLOT(label);
2884
2885	if (!mac_biba_dominate_effective(obj, subj))
2886		return (EACCES);
2887
2888	return (0);
2889}
2890
2891static int
2892mac_biba_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
2893    struct vnode *vp, struct label *label)
2894{
2895	struct mac_biba *subj, *obj;
2896
2897	if (!mac_biba_enabled || !revocation_enabled)
2898		return (0);
2899
2900	subj = SLOT(active_cred->cr_label);
2901	obj = SLOT(label);
2902
2903	if (!mac_biba_dominate_effective(obj, subj))
2904		return (EACCES);
2905
2906	return (0);
2907}
2908
2909static int
2910mac_biba_check_vnode_readdir(struct ucred *cred, struct vnode *dvp,
2911    struct label *dlabel)
2912{
2913	struct mac_biba *subj, *obj;
2914
2915	if (!mac_biba_enabled)
2916		return (0);
2917
2918	subj = SLOT(cred->cr_label);
2919	obj = SLOT(dlabel);
2920
2921	if (!mac_biba_dominate_effective(obj, subj))
2922		return (EACCES);
2923
2924	return (0);
2925}
2926
2927static int
2928mac_biba_check_vnode_readlink(struct ucred *cred, struct vnode *vp,
2929    struct label *label)
2930{
2931	struct mac_biba *subj, *obj;
2932
2933	if (!mac_biba_enabled)
2934		return (0);
2935
2936	subj = SLOT(cred->cr_label);
2937	obj = SLOT(label);
2938
2939	if (!mac_biba_dominate_effective(obj, subj))
2940		return (EACCES);
2941
2942	return (0);
2943}
2944
2945static int
2946mac_biba_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
2947    struct label *vnodelabel, struct label *newlabel)
2948{
2949	struct mac_biba *old, *new, *subj;
2950	int error;
2951
2952	old = SLOT(vnodelabel);
2953	new = SLOT(newlabel);
2954	subj = SLOT(cred->cr_label);
2955
2956	/*
2957	 * If there is a Biba label update for the vnode, it must be a
2958	 * effective label.
2959	 */
2960	error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE);
2961	if (error)
2962		return (error);
2963
2964	/*
2965	 * To perform a relabel of the vnode (Biba label or not), Biba must
2966	 * authorize the relabel.
2967	 */
2968	if (!mac_biba_effective_in_range(old, subj))
2969		return (EPERM);
2970
2971	/*
2972	 * If the Biba label is to be changed, authorize as appropriate.
2973	 */
2974	if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
2975		/*
2976		 * To change the Biba label on a vnode, the new vnode label
2977		 * must be in the subject range.
2978		 */
2979		if (!mac_biba_effective_in_range(new, subj))
2980			return (EPERM);
2981
2982		/*
2983		 * To change the Biba label on the vnode to be EQUAL,
2984		 * the subject must have appropriate privilege.
2985		 */
2986		if (mac_biba_contains_equal(new)) {
2987			error = mac_biba_subject_privileged(subj);
2988			if (error)
2989				return (error);
2990		}
2991	}
2992
2993	return (0);
2994}
2995
2996static int
2997mac_biba_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
2998    struct label *dlabel, struct vnode *vp, struct label *label,
2999    struct componentname *cnp)
3000{
3001	struct mac_biba *subj, *obj;
3002
3003	if (!mac_biba_enabled)
3004		return (0);
3005
3006	subj = SLOT(cred->cr_label);
3007	obj = SLOT(dlabel);
3008
3009	if (!mac_biba_dominate_effective(subj, obj))
3010		return (EACCES);
3011
3012	obj = SLOT(label);
3013
3014	if (!mac_biba_dominate_effective(subj, obj))
3015		return (EACCES);
3016
3017	return (0);
3018}
3019
3020static int
3021mac_biba_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
3022    struct label *dlabel, struct vnode *vp, struct label *label, int samedir,
3023    struct componentname *cnp)
3024{
3025	struct mac_biba *subj, *obj;
3026
3027	if (!mac_biba_enabled)
3028		return (0);
3029
3030	subj = SLOT(cred->cr_label);
3031	obj = SLOT(dlabel);
3032
3033	if (!mac_biba_dominate_effective(subj, obj))
3034		return (EACCES);
3035
3036	if (vp != NULL) {
3037		obj = SLOT(label);
3038
3039		if (!mac_biba_dominate_effective(subj, obj))
3040			return (EACCES);
3041	}
3042
3043	return (0);
3044}
3045
3046static int
3047mac_biba_check_vnode_revoke(struct ucred *cred, struct vnode *vp,
3048    struct label *label)
3049{
3050	struct mac_biba *subj, *obj;
3051
3052	if (!mac_biba_enabled)
3053		return (0);
3054
3055	subj = SLOT(cred->cr_label);
3056	obj = SLOT(label);
3057
3058	if (!mac_biba_dominate_effective(subj, obj))
3059		return (EACCES);
3060
3061	return (0);
3062}
3063
3064static int
3065mac_biba_check_vnode_setacl(struct ucred *cred, struct vnode *vp,
3066    struct label *label, acl_type_t type, struct acl *acl)
3067{
3068	struct mac_biba *subj, *obj;
3069
3070	if (!mac_biba_enabled)
3071		return (0);
3072
3073	subj = SLOT(cred->cr_label);
3074	obj = SLOT(label);
3075
3076	if (!mac_biba_dominate_effective(subj, obj))
3077		return (EACCES);
3078
3079	return (0);
3080}
3081
3082static int
3083mac_biba_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
3084    struct label *vnodelabel, int attrnamespace, const char *name,
3085    struct uio *uio)
3086{
3087	struct mac_biba *subj, *obj;
3088
3089	if (!mac_biba_enabled)
3090		return (0);
3091
3092	subj = SLOT(cred->cr_label);
3093	obj = SLOT(vnodelabel);
3094
3095	if (!mac_biba_dominate_effective(subj, obj))
3096		return (EACCES);
3097
3098	/* XXX: protect the MAC EA in a special way? */
3099
3100	return (0);
3101}
3102
3103static int
3104mac_biba_check_vnode_setflags(struct ucred *cred, struct vnode *vp,
3105    struct label *vnodelabel, u_long flags)
3106{
3107	struct mac_biba *subj, *obj;
3108
3109	if (!mac_biba_enabled)
3110		return (0);
3111
3112	subj = SLOT(cred->cr_label);
3113	obj = SLOT(vnodelabel);
3114
3115	if (!mac_biba_dominate_effective(subj, obj))
3116		return (EACCES);
3117
3118	return (0);
3119}
3120
3121static int
3122mac_biba_check_vnode_setmode(struct ucred *cred, struct vnode *vp,
3123    struct label *vnodelabel, mode_t mode)
3124{
3125	struct mac_biba *subj, *obj;
3126
3127	if (!mac_biba_enabled)
3128		return (0);
3129
3130	subj = SLOT(cred->cr_label);
3131	obj = SLOT(vnodelabel);
3132
3133	if (!mac_biba_dominate_effective(subj, obj))
3134		return (EACCES);
3135
3136	return (0);
3137}
3138
3139static int
3140mac_biba_check_vnode_setowner(struct ucred *cred, struct vnode *vp,
3141    struct label *vnodelabel, uid_t uid, gid_t gid)
3142{
3143	struct mac_biba *subj, *obj;
3144
3145	if (!mac_biba_enabled)
3146		return (0);
3147
3148	subj = SLOT(cred->cr_label);
3149	obj = SLOT(vnodelabel);
3150
3151	if (!mac_biba_dominate_effective(subj, obj))
3152		return (EACCES);
3153
3154	return (0);
3155}
3156
3157static int
3158mac_biba_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
3159    struct label *vnodelabel, struct timespec atime, struct timespec mtime)
3160{
3161	struct mac_biba *subj, *obj;
3162
3163	if (!mac_biba_enabled)
3164		return (0);
3165
3166	subj = SLOT(cred->cr_label);
3167	obj = SLOT(vnodelabel);
3168
3169	if (!mac_biba_dominate_effective(subj, obj))
3170		return (EACCES);
3171
3172	return (0);
3173}
3174
3175static int
3176mac_biba_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
3177    struct vnode *vp, struct label *vnodelabel)
3178{
3179	struct mac_biba *subj, *obj;
3180
3181	if (!mac_biba_enabled)
3182		return (0);
3183
3184	subj = SLOT(active_cred->cr_label);
3185	obj = SLOT(vnodelabel);
3186
3187	if (!mac_biba_dominate_effective(obj, subj))
3188		return (EACCES);
3189
3190	return (0);
3191}
3192
3193static int
3194mac_biba_check_vnode_write(struct ucred *active_cred,
3195    struct ucred *file_cred, struct vnode *vp, struct label *label)
3196{
3197	struct mac_biba *subj, *obj;
3198
3199	if (!mac_biba_enabled || !revocation_enabled)
3200		return (0);
3201
3202	subj = SLOT(active_cred->cr_label);
3203	obj = SLOT(label);
3204
3205	if (!mac_biba_dominate_effective(subj, obj))
3206		return (EACCES);
3207
3208	return (0);
3209}
3210
3211static void
3212mac_biba_associate_nfsd_label(struct ucred *cred)
3213{
3214	struct mac_biba *label;
3215
3216	label = SLOT(cred->cr_label);
3217	mac_biba_set_effective(label, MAC_BIBA_TYPE_LOW, 0, NULL);
3218	mac_biba_set_range(label, MAC_BIBA_TYPE_LOW, 0, NULL,
3219	    MAC_BIBA_TYPE_HIGH, 0, NULL);
3220}
3221
3222static void
3223mac_biba_init_syncache_from_inpcb(struct label *label, struct inpcb *inp)
3224{
3225	struct mac_biba *source, *dest;
3226
3227	source = SLOT(inp->inp_label);
3228	dest = SLOT(label);
3229	mac_biba_copy_effective(source, dest);
3230}
3231
3232static void
3233mac_biba_create_mbuf_from_syncache(struct label *sc_label, struct mbuf *m,
3234    struct label *mbuf_label)
3235{
3236	struct mac_biba *source, *dest;
3237
3238	source = SLOT(sc_label);
3239	dest = SLOT(mbuf_label);
3240	mac_biba_copy_effective(source, dest);
3241}
3242
3243static struct mac_policy_ops mac_biba_ops =
3244{
3245	.mpo_init = mac_biba_init,
3246	.mpo_init_bpfdesc_label = mac_biba_init_label,
3247	.mpo_init_cred_label = mac_biba_init_label,
3248	.mpo_init_devfsdirent_label = mac_biba_init_label,
3249	.mpo_init_ifnet_label = mac_biba_init_label,
3250	.mpo_init_inpcb_label = mac_biba_init_label_waitcheck,
3251	.mpo_init_syncache_label = mac_biba_init_label_waitcheck,
3252	.mpo_init_sysv_msgmsg_label = mac_biba_init_label,
3253	.mpo_init_sysv_msgqueue_label = mac_biba_init_label,
3254	.mpo_init_sysv_sem_label = mac_biba_init_label,
3255	.mpo_init_sysv_shm_label = mac_biba_init_label,
3256	.mpo_init_ipq_label = mac_biba_init_label_waitcheck,
3257	.mpo_init_mbuf_label = mac_biba_init_label_waitcheck,
3258	.mpo_init_mount_label = mac_biba_init_label,
3259	.mpo_init_pipe_label = mac_biba_init_label,
3260	.mpo_init_posix_sem_label = mac_biba_init_label,
3261	.mpo_init_socket_label = mac_biba_init_label_waitcheck,
3262	.mpo_init_socket_peer_label = mac_biba_init_label_waitcheck,
3263	.mpo_init_syncache_from_inpcb = mac_biba_init_syncache_from_inpcb,
3264	.mpo_init_vnode_label = mac_biba_init_label,
3265	.mpo_destroy_bpfdesc_label = mac_biba_destroy_label,
3266	.mpo_destroy_cred_label = mac_biba_destroy_label,
3267	.mpo_destroy_devfsdirent_label = mac_biba_destroy_label,
3268	.mpo_destroy_ifnet_label = mac_biba_destroy_label,
3269	.mpo_destroy_inpcb_label = mac_biba_destroy_label,
3270	.mpo_destroy_syncache_label = mac_biba_destroy_label,
3271	.mpo_destroy_sysv_msgmsg_label = mac_biba_destroy_label,
3272	.mpo_destroy_sysv_msgqueue_label = mac_biba_destroy_label,
3273	.mpo_destroy_sysv_sem_label = mac_biba_destroy_label,
3274	.mpo_destroy_sysv_shm_label = mac_biba_destroy_label,
3275	.mpo_destroy_ipq_label = mac_biba_destroy_label,
3276	.mpo_destroy_mbuf_label = mac_biba_destroy_label,
3277	.mpo_destroy_mount_label = mac_biba_destroy_label,
3278	.mpo_destroy_pipe_label = mac_biba_destroy_label,
3279	.mpo_destroy_posix_sem_label = mac_biba_destroy_label,
3280	.mpo_destroy_socket_label = mac_biba_destroy_label,
3281	.mpo_destroy_socket_peer_label = mac_biba_destroy_label,
3282	.mpo_destroy_vnode_label = mac_biba_destroy_label,
3283	.mpo_copy_cred_label = mac_biba_copy_label,
3284	.mpo_copy_ifnet_label = mac_biba_copy_label,
3285	.mpo_copy_mbuf_label = mac_biba_copy_label,
3286	.mpo_copy_pipe_label = mac_biba_copy_label,
3287	.mpo_copy_socket_label = mac_biba_copy_label,
3288	.mpo_copy_vnode_label = mac_biba_copy_label,
3289	.mpo_externalize_cred_label = mac_biba_externalize_label,
3290	.mpo_externalize_ifnet_label = mac_biba_externalize_label,
3291	.mpo_externalize_pipe_label = mac_biba_externalize_label,
3292	.mpo_externalize_socket_label = mac_biba_externalize_label,
3293	.mpo_externalize_socket_peer_label = mac_biba_externalize_label,
3294	.mpo_externalize_vnode_label = mac_biba_externalize_label,
3295	.mpo_internalize_cred_label = mac_biba_internalize_label,
3296	.mpo_internalize_ifnet_label = mac_biba_internalize_label,
3297	.mpo_internalize_pipe_label = mac_biba_internalize_label,
3298	.mpo_internalize_socket_label = mac_biba_internalize_label,
3299	.mpo_internalize_vnode_label = mac_biba_internalize_label,
3300	.mpo_create_devfs_device = mac_biba_create_devfs_device,
3301	.mpo_create_devfs_directory = mac_biba_create_devfs_directory,
3302	.mpo_create_devfs_symlink = mac_biba_create_devfs_symlink,
3303	.mpo_create_mount = mac_biba_create_mount,
3304	.mpo_relabel_vnode = mac_biba_relabel_vnode,
3305	.mpo_update_devfsdirent = mac_biba_update_devfsdirent,
3306	.mpo_associate_vnode_devfs = mac_biba_associate_vnode_devfs,
3307	.mpo_associate_vnode_extattr = mac_biba_associate_vnode_extattr,
3308	.mpo_associate_vnode_singlelabel = mac_biba_associate_vnode_singlelabel,
3309	.mpo_create_vnode_extattr = mac_biba_create_vnode_extattr,
3310	.mpo_setlabel_vnode_extattr = mac_biba_setlabel_vnode_extattr,
3311	.mpo_create_mbuf_from_socket = mac_biba_create_mbuf_from_socket,
3312	.mpo_create_mbuf_from_syncache = mac_biba_create_mbuf_from_syncache,
3313	.mpo_create_pipe = mac_biba_create_pipe,
3314	.mpo_create_posix_sem = mac_biba_create_posix_sem,
3315	.mpo_create_socket = mac_biba_create_socket,
3316	.mpo_create_socket_from_socket = mac_biba_create_socket_from_socket,
3317	.mpo_relabel_pipe = mac_biba_relabel_pipe,
3318	.mpo_relabel_socket = mac_biba_relabel_socket,
3319	.mpo_set_socket_peer_from_mbuf = mac_biba_set_socket_peer_from_mbuf,
3320	.mpo_set_socket_peer_from_socket = mac_biba_set_socket_peer_from_socket,
3321	.mpo_create_bpfdesc = mac_biba_create_bpfdesc,
3322	.mpo_create_datagram_from_ipq = mac_biba_create_datagram_from_ipq,
3323	.mpo_create_fragment = mac_biba_create_fragment,
3324	.mpo_create_ifnet = mac_biba_create_ifnet,
3325	.mpo_create_inpcb_from_socket = mac_biba_create_inpcb_from_socket,
3326	.mpo_create_sysv_msgmsg = mac_biba_create_sysv_msgmsg,
3327	.mpo_create_sysv_msgqueue = mac_biba_create_sysv_msgqueue,
3328	.mpo_create_sysv_sem = mac_biba_create_sysv_sem,
3329	.mpo_create_sysv_shm = mac_biba_create_sysv_shm,
3330	.mpo_create_ipq = mac_biba_create_ipq,
3331	.mpo_create_mbuf_from_inpcb = mac_biba_create_mbuf_from_inpcb,
3332	.mpo_create_mbuf_linklayer = mac_biba_create_mbuf_linklayer,
3333	.mpo_create_mbuf_from_bpfdesc = mac_biba_create_mbuf_from_bpfdesc,
3334	.mpo_create_mbuf_from_ifnet = mac_biba_create_mbuf_from_ifnet,
3335	.mpo_create_mbuf_multicast_encap = mac_biba_create_mbuf_multicast_encap,
3336	.mpo_create_mbuf_netlayer = mac_biba_create_mbuf_netlayer,
3337	.mpo_fragment_match = mac_biba_fragment_match,
3338	.mpo_relabel_ifnet = mac_biba_relabel_ifnet,
3339	.mpo_update_ipq = mac_biba_update_ipq,
3340	.mpo_inpcb_sosetlabel = mac_biba_inpcb_sosetlabel,
3341	.mpo_create_proc0 = mac_biba_create_proc0,
3342	.mpo_create_proc1 = mac_biba_create_proc1,
3343	.mpo_relabel_cred = mac_biba_relabel_cred,
3344	.mpo_cleanup_sysv_msgmsg = mac_biba_cleanup_sysv_msgmsg,
3345	.mpo_cleanup_sysv_msgqueue = mac_biba_cleanup_sysv_msgqueue,
3346	.mpo_cleanup_sysv_sem = mac_biba_cleanup_sysv_sem,
3347	.mpo_cleanup_sysv_shm = mac_biba_cleanup_sysv_shm,
3348	.mpo_check_bpfdesc_receive = mac_biba_check_bpfdesc_receive,
3349	.mpo_check_cred_relabel = mac_biba_check_cred_relabel,
3350	.mpo_check_cred_visible = mac_biba_check_cred_visible,
3351	.mpo_check_ifnet_relabel = mac_biba_check_ifnet_relabel,
3352	.mpo_check_ifnet_transmit = mac_biba_check_ifnet_transmit,
3353	.mpo_check_inpcb_deliver = mac_biba_check_inpcb_deliver,
3354	.mpo_check_sysv_msgrcv = mac_biba_check_sysv_msgrcv,
3355	.mpo_check_sysv_msgrmid = mac_biba_check_sysv_msgrmid,
3356	.mpo_check_sysv_msqget = mac_biba_check_sysv_msqget,
3357	.mpo_check_sysv_msqsnd = mac_biba_check_sysv_msqsnd,
3358	.mpo_check_sysv_msqrcv = mac_biba_check_sysv_msqrcv,
3359	.mpo_check_sysv_msqctl = mac_biba_check_sysv_msqctl,
3360	.mpo_check_sysv_semctl = mac_biba_check_sysv_semctl,
3361	.mpo_check_sysv_semget = mac_biba_check_sysv_semget,
3362	.mpo_check_sysv_semop = mac_biba_check_sysv_semop,
3363	.mpo_check_sysv_shmat = mac_biba_check_sysv_shmat,
3364	.mpo_check_sysv_shmctl = mac_biba_check_sysv_shmctl,
3365	.mpo_check_sysv_shmget = mac_biba_check_sysv_shmget,
3366	.mpo_check_kld_load = mac_biba_check_kld_load,
3367	.mpo_check_mount_stat = mac_biba_check_mount_stat,
3368	.mpo_check_pipe_ioctl = mac_biba_check_pipe_ioctl,
3369	.mpo_check_pipe_poll = mac_biba_check_pipe_poll,
3370	.mpo_check_pipe_read = mac_biba_check_pipe_read,
3371	.mpo_check_pipe_relabel = mac_biba_check_pipe_relabel,
3372	.mpo_check_pipe_stat = mac_biba_check_pipe_stat,
3373	.mpo_check_pipe_write = mac_biba_check_pipe_write,
3374	.mpo_check_posix_sem_destroy = mac_biba_check_posix_sem_write,
3375	.mpo_check_posix_sem_getvalue = mac_biba_check_posix_sem_rdonly,
3376	.mpo_check_posix_sem_open = mac_biba_check_posix_sem_write,
3377	.mpo_check_posix_sem_post = mac_biba_check_posix_sem_write,
3378	.mpo_check_posix_sem_unlink = mac_biba_check_posix_sem_write,
3379	.mpo_check_posix_sem_wait = mac_biba_check_posix_sem_write,
3380	.mpo_check_proc_debug = mac_biba_check_proc_debug,
3381	.mpo_check_proc_sched = mac_biba_check_proc_sched,
3382	.mpo_check_proc_signal = mac_biba_check_proc_signal,
3383	.mpo_check_socket_deliver = mac_biba_check_socket_deliver,
3384	.mpo_check_socket_relabel = mac_biba_check_socket_relabel,
3385	.mpo_check_socket_visible = mac_biba_check_socket_visible,
3386	.mpo_check_system_acct = mac_biba_check_system_acct,
3387	.mpo_check_system_auditctl = mac_biba_check_system_auditctl,
3388	.mpo_check_system_auditon = mac_biba_check_system_auditon,
3389	.mpo_check_system_swapon = mac_biba_check_system_swapon,
3390	.mpo_check_system_swapoff = mac_biba_check_system_swapoff,
3391	.mpo_check_system_sysctl = mac_biba_check_system_sysctl,
3392	.mpo_check_vnode_access = mac_biba_check_vnode_open,
3393	.mpo_check_vnode_chdir = mac_biba_check_vnode_chdir,
3394	.mpo_check_vnode_chroot = mac_biba_check_vnode_chroot,
3395	.mpo_check_vnode_create = mac_biba_check_vnode_create,
3396	.mpo_check_vnode_delete = mac_biba_check_vnode_delete,
3397	.mpo_check_vnode_deleteacl = mac_biba_check_vnode_deleteacl,
3398	.mpo_check_vnode_deleteextattr = mac_biba_check_vnode_deleteextattr,
3399	.mpo_check_vnode_exec = mac_biba_check_vnode_exec,
3400	.mpo_check_vnode_getacl = mac_biba_check_vnode_getacl,
3401	.mpo_check_vnode_getextattr = mac_biba_check_vnode_getextattr,
3402	.mpo_check_vnode_link = mac_biba_check_vnode_link,
3403	.mpo_check_vnode_listextattr = mac_biba_check_vnode_listextattr,
3404	.mpo_check_vnode_lookup = mac_biba_check_vnode_lookup,
3405	.mpo_check_vnode_mmap = mac_biba_check_vnode_mmap,
3406	.mpo_check_vnode_open = mac_biba_check_vnode_open,
3407	.mpo_check_vnode_poll = mac_biba_check_vnode_poll,
3408	.mpo_check_vnode_read = mac_biba_check_vnode_read,
3409	.mpo_check_vnode_readdir = mac_biba_check_vnode_readdir,
3410	.mpo_check_vnode_readlink = mac_biba_check_vnode_readlink,
3411	.mpo_check_vnode_relabel = mac_biba_check_vnode_relabel,
3412	.mpo_check_vnode_rename_from = mac_biba_check_vnode_rename_from,
3413	.mpo_check_vnode_rename_to = mac_biba_check_vnode_rename_to,
3414	.mpo_check_vnode_revoke = mac_biba_check_vnode_revoke,
3415	.mpo_check_vnode_setacl = mac_biba_check_vnode_setacl,
3416	.mpo_check_vnode_setextattr = mac_biba_check_vnode_setextattr,
3417	.mpo_check_vnode_setflags = mac_biba_check_vnode_setflags,
3418	.mpo_check_vnode_setmode = mac_biba_check_vnode_setmode,
3419	.mpo_check_vnode_setowner = mac_biba_check_vnode_setowner,
3420	.mpo_check_vnode_setutimes = mac_biba_check_vnode_setutimes,
3421	.mpo_check_vnode_stat = mac_biba_check_vnode_stat,
3422	.mpo_check_vnode_write = mac_biba_check_vnode_write,
3423	.mpo_associate_nfsd_label = mac_biba_associate_nfsd_label,
3424	.mpo_create_mbuf_from_firewall = mac_biba_create_mbuf_from_firewall,
3425	.mpo_priv_check = mac_biba_priv_check,
3426};
3427
3428MAC_POLICY_SET(&mac_biba_ops, mac_biba, "TrustedBSD MAC/Biba",
3429    MPC_LOADTIME_FLAG_NOTLATE | MPC_LOADTIME_FLAG_LABELMBUFS, &mac_biba_slot);
3430