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