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