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