mac_biba.c revision 105643
1/*-
2 * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson
3 * Copyright (c) 2001, 2002 Networks Associates Technology, 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 NAI Labs,
9 * the Security Research Division of Network Associates, 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 * 3. The names of the authors may not be used to endorse or promote
22 *    products derived from this software without specific prior written
23 *    permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 *
37 * $FreeBSD: head/sys/security/mac_biba/mac_biba.c 105643 2002-10-21 18:42:01Z rwatson $
38 */
39
40/*
41 * Developed by the TrustedBSD Project.
42 * Biba fixed label mandatory integrity policy.
43 */
44
45#include <sys/types.h>
46#include <sys/param.h>
47#include <sys/acl.h>
48#include <sys/conf.h>
49#include <sys/kernel.h>
50#include <sys/mac.h>
51#include <sys/malloc.h>
52#include <sys/mount.h>
53#include <sys/proc.h>
54#include <sys/systm.h>
55#include <sys/sysproto.h>
56#include <sys/sysent.h>
57#include <sys/vnode.h>
58#include <sys/file.h>
59#include <sys/socket.h>
60#include <sys/socketvar.h>
61#include <sys/pipe.h>
62#include <sys/sysctl.h>
63
64#include <fs/devfs/devfs.h>
65
66#include <net/bpfdesc.h>
67#include <net/if.h>
68#include <net/if_types.h>
69#include <net/if_var.h>
70
71#include <netinet/in.h>
72#include <netinet/ip_var.h>
73
74#include <vm/vm.h>
75
76#include <sys/mac_policy.h>
77
78#include <security/mac_biba/mac_biba.h>
79
80SYSCTL_DECL(_security_mac);
81
82SYSCTL_NODE(_security_mac, OID_AUTO, biba, CTLFLAG_RW, 0,
83    "TrustedBSD mac_biba policy controls");
84
85static int	mac_biba_enabled = 0;
86SYSCTL_INT(_security_mac_biba, OID_AUTO, enabled, CTLFLAG_RW,
87    &mac_biba_enabled, 0, "Enforce MAC/Biba policy");
88TUNABLE_INT("security.mac.biba.enabled", &mac_biba_enabled);
89
90static int	destroyed_not_inited;
91SYSCTL_INT(_security_mac_biba, OID_AUTO, destroyed_not_inited, CTLFLAG_RD,
92    &destroyed_not_inited, 0, "Count of labels destroyed but not inited");
93
94static int	trust_all_interfaces = 0;
95SYSCTL_INT(_security_mac_biba, OID_AUTO, trust_all_interfaces, CTLFLAG_RD,
96    &trust_all_interfaces, 0, "Consider all interfaces 'trusted' by MAC/Biba");
97TUNABLE_INT("security.mac.biba.trust_all_interfaces", &trust_all_interfaces);
98
99static char	trusted_interfaces[128];
100SYSCTL_STRING(_security_mac_biba, OID_AUTO, trusted_interfaces, CTLFLAG_RD,
101    trusted_interfaces, 0, "Interfaces considered 'trusted' by MAC/Biba");
102TUNABLE_STR("security.mac.biba.trusted_interfaces", trusted_interfaces,
103    sizeof(trusted_interfaces));
104
105static int	max_compartments = MAC_BIBA_MAX_COMPARTMENTS;
106SYSCTL_INT(_security_mac_biba, OID_AUTO, max_compartments, CTLFLAG_RD,
107    &max_compartments, 0, "Maximum supported compartments");
108
109static int	ptys_equal = 0;
110SYSCTL_INT(_security_mac_biba, OID_AUTO, ptys_equal, CTLFLAG_RW,
111    &ptys_equal, 0, "Label pty devices as biba/equal on create");
112TUNABLE_INT("security.mac.biba.ptys_equal", &ptys_equal);
113
114static int	revocation_enabled = 0;
115SYSCTL_INT(_security_mac_biba, OID_AUTO, revocation_enabled, CTLFLAG_RW,
116    &revocation_enabled, 0, "Revoke access to objects on relabel");
117TUNABLE_INT("security.mac.biba.revocation_enabled", &revocation_enabled);
118
119static int	mac_biba_slot;
120#define	SLOT(l)	((struct mac_biba *)LABEL_TO_SLOT((l), mac_biba_slot).l_ptr)
121
122MALLOC_DEFINE(M_MACBIBA, "biba label", "MAC/Biba labels");
123
124static __inline int
125biba_bit_set_empty(u_char *set) {
126	int i;
127
128	for (i = 0; i < MAC_BIBA_MAX_COMPARTMENTS >> 3; i++)
129		if (set[i] != 0)
130			return (0);
131	return (1);
132}
133
134static struct mac_biba *
135biba_alloc(int flag)
136{
137	struct mac_biba *mac_biba;
138
139	mac_biba = malloc(sizeof(struct mac_biba), M_MACBIBA, M_ZERO | flag);
140
141	return (mac_biba);
142}
143
144static void
145biba_free(struct mac_biba *mac_biba)
146{
147
148	if (mac_biba != NULL)
149		free(mac_biba, M_MACBIBA);
150	else
151		atomic_add_int(&destroyed_not_inited, 1);
152}
153
154static int
155biba_atmostflags(struct mac_biba *mac_biba, int flags)
156{
157
158	if ((mac_biba->mb_flags & flags) != mac_biba->mb_flags)
159		return (EINVAL);
160	return (0);
161}
162
163static int
164mac_biba_dominate_element(struct mac_biba_element *a,
165    struct mac_biba_element *b)
166{
167	int bit;
168
169	switch(a->mbe_type) {
170	case MAC_BIBA_TYPE_EQUAL:
171	case MAC_BIBA_TYPE_HIGH:
172		return (1);
173
174	case MAC_BIBA_TYPE_LOW:
175		switch (b->mbe_type) {
176		case MAC_BIBA_TYPE_GRADE:
177		case MAC_BIBA_TYPE_HIGH:
178			return (0);
179
180		case MAC_BIBA_TYPE_EQUAL:
181		case MAC_BIBA_TYPE_LOW:
182			return (1);
183
184		default:
185			panic("mac_biba_dominate_element: b->mbe_type invalid");
186		}
187
188	case MAC_BIBA_TYPE_GRADE:
189		switch (b->mbe_type) {
190		case MAC_BIBA_TYPE_EQUAL:
191		case MAC_BIBA_TYPE_LOW:
192			return (1);
193
194		case MAC_BIBA_TYPE_HIGH:
195			return (0);
196
197		case MAC_BIBA_TYPE_GRADE:
198			for (bit = 1; bit <= MAC_BIBA_MAX_COMPARTMENTS; bit++)
199				if (!MAC_BIBA_BIT_TEST(bit,
200				    a->mbe_compartments) &&
201				    MAC_BIBA_BIT_TEST(bit, b->mbe_compartments))
202					return (0);
203			return (a->mbe_grade >= b->mbe_grade);
204
205		default:
206			panic("mac_biba_dominate_element: b->mbe_type invalid");
207		}
208
209	default:
210		panic("mac_biba_dominate_element: a->mbe_type invalid");
211	}
212
213	return (0);
214}
215
216static int
217mac_biba_range_in_range(struct mac_biba *rangea, struct mac_biba *rangeb)
218{
219
220	return (mac_biba_dominate_element(&rangeb->mb_rangehigh,
221	    &rangea->mb_rangehigh) &&
222	    mac_biba_dominate_element(&rangea->mb_rangelow,
223	    &rangeb->mb_rangelow));
224}
225
226static int
227mac_biba_single_in_range(struct mac_biba *single, struct mac_biba *range)
228{
229
230	KASSERT((single->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
231	    ("mac_biba_single_in_range: a not single"));
232	KASSERT((range->mb_flags & MAC_BIBA_FLAG_RANGE) != 0,
233	    ("mac_biba_single_in_range: b not range"));
234
235	return (mac_biba_dominate_element(&range->mb_rangehigh,
236	    &single->mb_single) &&
237	    mac_biba_dominate_element(&single->mb_single,
238	    &range->mb_rangelow));
239
240	return (1);
241}
242
243static int
244mac_biba_dominate_single(struct mac_biba *a, struct mac_biba *b)
245{
246	KASSERT((a->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
247	    ("mac_biba_dominate_single: a not single"));
248	KASSERT((b->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
249	    ("mac_biba_dominate_single: b not single"));
250
251	return (mac_biba_dominate_element(&a->mb_single, &b->mb_single));
252}
253
254static int
255mac_biba_equal_element(struct mac_biba_element *a, struct mac_biba_element *b)
256{
257
258	if (a->mbe_type == MAC_BIBA_TYPE_EQUAL ||
259	    b->mbe_type == MAC_BIBA_TYPE_EQUAL)
260		return (1);
261
262	return (a->mbe_type == b->mbe_type && a->mbe_grade == b->mbe_grade);
263}
264
265static int
266mac_biba_equal_single(struct mac_biba *a, struct mac_biba *b)
267{
268
269	KASSERT((a->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
270	    ("mac_biba_equal_single: a not single"));
271	KASSERT((b->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
272	    ("mac_biba_equal_single: b not single"));
273
274	return (mac_biba_equal_element(&a->mb_single, &b->mb_single));
275}
276
277static int
278mac_biba_contains_equal(struct mac_biba *mac_biba)
279{
280
281	if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE)
282		if (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_EQUAL)
283			return (1);
284
285	if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
286		if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL)
287			return (1);
288		if (mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL)
289			return (1);
290	}
291
292	return (0);
293}
294
295static int
296mac_biba_subject_equal_ok(struct mac_biba *mac_biba)
297{
298
299	KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAGS_BOTH) ==
300	    MAC_BIBA_FLAGS_BOTH,
301	    ("mac_biba_subject_equal_ok: subject doesn't have both labels"));
302
303	/* If the single is EQUAL, it's ok. */
304	if (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_EQUAL)
305		return (0);
306
307	/* If either range endpoint is EQUAL, it's ok. */
308	if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL ||
309	    mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL)
310		return (0);
311
312	/* If the range is low-high, it's ok. */
313	if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_LOW &&
314	    mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_HIGH)
315		return (0);
316
317	/* It's not ok. */
318	return (EPERM);
319}
320
321static int
322mac_biba_valid(struct mac_biba *mac_biba)
323{
324
325	if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) {
326		switch (mac_biba->mb_single.mbe_type) {
327		case MAC_BIBA_TYPE_GRADE:
328			break;
329
330		case MAC_BIBA_TYPE_EQUAL:
331		case MAC_BIBA_TYPE_HIGH:
332		case MAC_BIBA_TYPE_LOW:
333			if (mac_biba->mb_single.mbe_grade != 0 ||
334			    !MAC_BIBA_BIT_SET_EMPTY(
335			    mac_biba->mb_single.mbe_compartments))
336				return (EINVAL);
337			break;
338
339		default:
340			return (EINVAL);
341		}
342	} else {
343		if (mac_biba->mb_single.mbe_type != MAC_BIBA_TYPE_UNDEF)
344			return (EINVAL);
345	}
346
347	if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
348		switch (mac_biba->mb_rangelow.mbe_type) {
349		case MAC_BIBA_TYPE_GRADE:
350			break;
351
352		case MAC_BIBA_TYPE_EQUAL:
353		case MAC_BIBA_TYPE_HIGH:
354		case MAC_BIBA_TYPE_LOW:
355			if (mac_biba->mb_rangelow.mbe_grade != 0 ||
356			    !MAC_BIBA_BIT_SET_EMPTY(
357			    mac_biba->mb_rangelow.mbe_compartments))
358				return (EINVAL);
359			break;
360
361		default:
362			return (EINVAL);
363		}
364
365		switch (mac_biba->mb_rangehigh.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_rangehigh.mbe_grade != 0 ||
373			    !MAC_BIBA_BIT_SET_EMPTY(
374			    mac_biba->mb_rangehigh.mbe_compartments))
375				return (EINVAL);
376			break;
377
378		default:
379			return (EINVAL);
380		}
381		if (!mac_biba_dominate_element(&mac_biba->mb_rangehigh,
382		    &mac_biba->mb_rangelow))
383			return (EINVAL);
384	} else {
385		if (mac_biba->mb_rangelow.mbe_type != MAC_BIBA_TYPE_UNDEF ||
386		    mac_biba->mb_rangehigh.mbe_type != MAC_BIBA_TYPE_UNDEF)
387			return (EINVAL);
388	}
389
390	return (0);
391}
392
393static void
394mac_biba_set_range(struct mac_biba *mac_biba, u_short typelow,
395    u_short gradelow, u_char *compartmentslow, u_short typehigh,
396    u_short gradehigh, u_char *compartmentshigh)
397{
398
399	mac_biba->mb_rangelow.mbe_type = typelow;
400	mac_biba->mb_rangelow.mbe_grade = gradelow;
401	if (compartmentslow != NULL)
402		memcpy(mac_biba->mb_rangelow.mbe_compartments,
403		    compartmentslow,
404		    sizeof(mac_biba->mb_rangelow.mbe_compartments));
405	mac_biba->mb_rangehigh.mbe_type = typehigh;
406	mac_biba->mb_rangehigh.mbe_grade = gradehigh;
407	if (compartmentshigh != NULL)
408		memcpy(mac_biba->mb_rangehigh.mbe_compartments,
409		    compartmentshigh,
410		    sizeof(mac_biba->mb_rangehigh.mbe_compartments));
411	mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE;
412}
413
414static void
415mac_biba_set_single(struct mac_biba *mac_biba, u_short type, u_short grade,
416    u_char *compartments)
417{
418
419	mac_biba->mb_single.mbe_type = type;
420	mac_biba->mb_single.mbe_grade = grade;
421	if (compartments != NULL)
422		memcpy(mac_biba->mb_single.mbe_compartments, compartments,
423		    sizeof(mac_biba->mb_single.mbe_compartments));
424	mac_biba->mb_flags |= MAC_BIBA_FLAG_SINGLE;
425}
426
427static void
428mac_biba_copy_range(struct mac_biba *labelfrom, struct mac_biba *labelto)
429{
430
431	KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_RANGE) != 0,
432	    ("mac_biba_copy_range: labelfrom not range"));
433
434	labelto->mb_rangelow = labelfrom->mb_rangelow;
435	labelto->mb_rangehigh = labelfrom->mb_rangehigh;
436	labelto->mb_flags |= MAC_BIBA_FLAG_RANGE;
437}
438
439static void
440mac_biba_copy_single(struct mac_biba *labelfrom, struct mac_biba *labelto)
441{
442
443	KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
444	    ("mac_biba_copy_single: labelfrom not single"));
445
446	labelto->mb_single = labelfrom->mb_single;
447	labelto->mb_flags |= MAC_BIBA_FLAG_SINGLE;
448}
449
450/*
451 * Policy module operations.
452 */
453static void
454mac_biba_destroy(struct mac_policy_conf *conf)
455{
456
457}
458
459static void
460mac_biba_init(struct mac_policy_conf *conf)
461{
462
463}
464
465/*
466 * Label operations.
467 */
468static void
469mac_biba_init_label(struct label *label)
470{
471
472	SLOT(label) = biba_alloc(M_WAITOK);
473}
474
475static int
476mac_biba_init_label_waitcheck(struct label *label, int flag)
477{
478
479	SLOT(label) = biba_alloc(flag);
480	if (SLOT(label) == NULL)
481		return (ENOMEM);
482
483	return (0);
484}
485
486static void
487mac_biba_destroy_label(struct label *label)
488{
489
490	biba_free(SLOT(label));
491	SLOT(label) = NULL;
492}
493
494static int
495mac_biba_externalize(struct label *label, struct mac *extmac)
496{
497	struct mac_biba *mac_biba;
498
499	mac_biba = SLOT(label);
500
501	if (mac_biba == NULL) {
502		printf("mac_biba_externalize: NULL pointer\n");
503		return (0);
504	}
505
506	extmac->m_biba = *mac_biba;
507
508	return (0);
509}
510
511static int
512mac_biba_internalize(struct label *label, struct mac *extmac)
513{
514	struct mac_biba *mac_biba;
515	int error;
516
517	mac_biba = SLOT(label);
518
519	error = mac_biba_valid(mac_biba);
520	if (error)
521		return (error);
522
523	*mac_biba = extmac->m_biba;
524
525	return (0);
526}
527
528/*
529 * Labeling event operations: file system objects, and things that look
530 * a lot like file system objects.
531 */
532static void
533mac_biba_create_devfs_device(dev_t dev, struct devfs_dirent *devfs_dirent,
534    struct label *label)
535{
536	struct mac_biba *mac_biba;
537	int biba_type;
538
539	mac_biba = SLOT(label);
540	if (strcmp(dev->si_name, "null") == 0 ||
541	    strcmp(dev->si_name, "zero") == 0 ||
542	    strcmp(dev->si_name, "random") == 0 ||
543	    strncmp(dev->si_name, "fd/", strlen("fd/")) == 0)
544		biba_type = MAC_BIBA_TYPE_EQUAL;
545	else if (ptys_equal &&
546	    (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 ||
547	    strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0))
548		biba_type = MAC_BIBA_TYPE_EQUAL;
549	else
550		biba_type = MAC_BIBA_TYPE_HIGH;
551	mac_biba_set_single(mac_biba, biba_type, 0, NULL);
552}
553
554static void
555mac_biba_create_devfs_directory(char *dirname, int dirnamelen,
556    struct devfs_dirent *devfs_dirent, struct label *label)
557{
558	struct mac_biba *mac_biba;
559
560	mac_biba = SLOT(label);
561	mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
562}
563
564static void
565mac_biba_create_devfs_symlink(struct ucred *cred, struct devfs_dirent *dd,
566    struct label *ddlabel, struct devfs_dirent *de, struct label *delabel)
567{
568	struct mac_biba *source, *dest;
569
570	source = SLOT(&cred->cr_label);
571	dest = SLOT(delabel);
572
573	mac_biba_copy_single(source, dest);
574}
575
576static void
577mac_biba_create_devfs_vnode(struct devfs_dirent *devfs_dirent,
578    struct label *direntlabel, struct vnode *vp, struct label *vnodelabel)
579{
580	struct mac_biba *source, *dest;
581
582	source = SLOT(direntlabel);
583	dest = SLOT(vnodelabel);
584	mac_biba_copy_single(source, dest);
585}
586
587static void
588mac_biba_create_vnode(struct ucred *cred, struct vnode *parent,
589    struct label *parentlabel, struct vnode *child, struct label *childlabel)
590{
591	struct mac_biba *source, *dest;
592
593	source = SLOT(&cred->cr_label);
594	dest = SLOT(childlabel);
595
596	mac_biba_copy_single(source, dest);
597}
598
599static void
600mac_biba_create_mount(struct ucred *cred, struct mount *mp,
601    struct label *mntlabel, struct label *fslabel)
602{
603	struct mac_biba *source, *dest;
604
605	source = SLOT(&cred->cr_label);
606	dest = SLOT(mntlabel);
607	mac_biba_copy_single(source, dest);
608	dest = SLOT(fslabel);
609	mac_biba_copy_single(source, dest);
610}
611
612static void
613mac_biba_create_root_mount(struct ucred *cred, struct mount *mp,
614    struct label *mntlabel, struct label *fslabel)
615{
616	struct mac_biba *mac_biba;
617
618	/* Always mount root as high integrity. */
619	mac_biba = SLOT(fslabel);
620	mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
621	mac_biba = SLOT(mntlabel);
622	mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
623}
624
625static void
626mac_biba_relabel_vnode(struct ucred *cred, struct vnode *vp,
627    struct label *vnodelabel, struct label *label)
628{
629	struct mac_biba *source, *dest;
630
631	source = SLOT(label);
632	dest = SLOT(vnodelabel);
633
634	mac_biba_copy_single(source, dest);
635}
636
637static void
638mac_biba_update_devfsdirent(struct devfs_dirent *devfs_dirent,
639    struct label *direntlabel, struct vnode *vp, struct label *vnodelabel)
640{
641	struct mac_biba *source, *dest;
642
643	source = SLOT(vnodelabel);
644	dest = SLOT(direntlabel);
645
646	mac_biba_copy_single(source, dest);
647}
648
649static void
650mac_biba_update_procfsvnode(struct vnode *vp, struct label *vnodelabel,
651    struct ucred *cred)
652{
653	struct mac_biba *source, *dest;
654
655	source = SLOT(&cred->cr_label);
656	dest = SLOT(vnodelabel);
657
658	/*
659	 * Only copy the single, not the range, since vnodes only have
660	 * a single.
661	 */
662	mac_biba_copy_single(source, dest);
663}
664
665static int
666mac_biba_update_vnode_from_externalized(struct vnode *vp,
667    struct label *vnodelabel, struct mac *extmac)
668{
669	struct mac_biba *source, *dest;
670	int error;
671
672	source = &extmac->m_biba;
673	dest = SLOT(vnodelabel);
674
675	error = mac_biba_valid(source);
676	if (error)
677		return (error);
678
679	if ((source->mb_flags & MAC_BIBA_FLAGS_BOTH) != MAC_BIBA_FLAG_SINGLE)
680		return (EINVAL);
681
682	mac_biba_copy_single(source, dest);
683
684	return (0);
685}
686
687static void
688mac_biba_update_vnode_from_mount(struct vnode *vp, struct label *vnodelabel,
689    struct mount *mp, struct label *fslabel)
690{
691	struct mac_biba *source, *dest;
692
693	source = SLOT(fslabel);
694	dest = SLOT(vnodelabel);
695
696	mac_biba_copy_single(source, dest);
697}
698
699/*
700 * Labeling event operations: IPC object.
701 */
702static void
703mac_biba_create_mbuf_from_socket(struct socket *so, struct label *socketlabel,
704    struct mbuf *m, struct label *mbuflabel)
705{
706	struct mac_biba *source, *dest;
707
708	source = SLOT(socketlabel);
709	dest = SLOT(mbuflabel);
710
711	mac_biba_copy_single(source, dest);
712}
713
714static void
715mac_biba_create_socket(struct ucred *cred, struct socket *socket,
716    struct label *socketlabel)
717{
718	struct mac_biba *source, *dest;
719
720	source = SLOT(&cred->cr_label);
721	dest = SLOT(socketlabel);
722
723	mac_biba_copy_single(source, dest);
724}
725
726static void
727mac_biba_create_pipe(struct ucred *cred, struct pipe *pipe,
728    struct label *pipelabel)
729{
730	struct mac_biba *source, *dest;
731
732	source = SLOT(&cred->cr_label);
733	dest = SLOT(pipelabel);
734
735	mac_biba_copy_single(source, dest);
736}
737
738static void
739mac_biba_create_socket_from_socket(struct socket *oldsocket,
740    struct label *oldsocketlabel, struct socket *newsocket,
741    struct label *newsocketlabel)
742{
743	struct mac_biba *source, *dest;
744
745	source = SLOT(oldsocketlabel);
746	dest = SLOT(newsocketlabel);
747
748	mac_biba_copy_single(source, dest);
749}
750
751static void
752mac_biba_relabel_socket(struct ucred *cred, struct socket *socket,
753    struct label *socketlabel, struct label *newlabel)
754{
755	struct mac_biba *source, *dest;
756
757	source = SLOT(newlabel);
758	dest = SLOT(socketlabel);
759
760	mac_biba_copy_single(source, dest);
761}
762
763static void
764mac_biba_relabel_pipe(struct ucred *cred, struct pipe *pipe,
765    struct label *pipelabel, struct label *newlabel)
766{
767	struct mac_biba *source, *dest;
768
769	source = SLOT(newlabel);
770	dest = SLOT(pipelabel);
771
772	mac_biba_copy_single(source, dest);
773}
774
775static void
776mac_biba_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel,
777    struct socket *socket, struct label *socketpeerlabel)
778{
779	struct mac_biba *source, *dest;
780
781	source = SLOT(mbuflabel);
782	dest = SLOT(socketpeerlabel);
783
784	mac_biba_copy_single(source, dest);
785}
786
787/*
788 * Labeling event operations: network objects.
789 */
790static void
791mac_biba_set_socket_peer_from_socket(struct socket *oldsocket,
792    struct label *oldsocketlabel, struct socket *newsocket,
793    struct label *newsocketpeerlabel)
794{
795	struct mac_biba *source, *dest;
796
797	source = SLOT(oldsocketlabel);
798	dest = SLOT(newsocketpeerlabel);
799
800	mac_biba_copy_single(source, dest);
801}
802
803static void
804mac_biba_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d,
805    struct label *bpflabel)
806{
807	struct mac_biba *source, *dest;
808
809	source = SLOT(&cred->cr_label);
810	dest = SLOT(bpflabel);
811
812	mac_biba_copy_single(source, dest);
813}
814
815static void
816mac_biba_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel)
817{
818	char tifname[IFNAMSIZ], ifname[IFNAMSIZ], *p, *q;
819	char tiflist[sizeof(trusted_interfaces)];
820	struct mac_biba *dest;
821	int len, grade;
822
823	dest = SLOT(ifnetlabel);
824
825	if (ifnet->if_type == IFT_LOOP) {
826		grade = MAC_BIBA_TYPE_EQUAL;
827		goto set;
828	}
829
830	if (trust_all_interfaces) {
831		grade = MAC_BIBA_TYPE_HIGH;
832		goto set;
833	}
834
835	grade = MAC_BIBA_TYPE_LOW;
836
837	if (trusted_interfaces[0] == '\0' ||
838	    !strvalid(trusted_interfaces, sizeof(trusted_interfaces)))
839		goto set;
840
841	for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++)
842		if(*p != ' ' && *p != '\t')
843			*q = *p;
844
845	snprintf(ifname, IFNAMSIZ, "%s%d", ifnet->if_name, ifnet->if_unit);
846
847	for (p = q = tiflist;; p++) {
848		if (*p == ',' || *p == '\0') {
849			len = p - q;
850			if (len < IFNAMSIZ) {
851				bzero(tifname, sizeof(tifname));
852				bcopy(q, tifname, len);
853				if (strcmp(tifname, ifname) == 0) {
854					grade = MAC_BIBA_TYPE_HIGH;
855					break;
856				}
857			}
858			if (*p == '\0')
859				break;
860			q = p + 1;
861		}
862	}
863set:
864	mac_biba_set_single(dest, grade, 0, NULL);
865	mac_biba_set_range(dest, grade, 0, NULL, grade, 0, NULL);
866}
867
868static void
869mac_biba_create_ipq(struct mbuf *fragment, struct label *fragmentlabel,
870    struct ipq *ipq, struct label *ipqlabel)
871{
872	struct mac_biba *source, *dest;
873
874	source = SLOT(fragmentlabel);
875	dest = SLOT(ipqlabel);
876
877	mac_biba_copy_single(source, dest);
878}
879
880static void
881mac_biba_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel,
882    struct mbuf *datagram, struct label *datagramlabel)
883{
884	struct mac_biba *source, *dest;
885
886	source = SLOT(ipqlabel);
887	dest = SLOT(datagramlabel);
888
889	/* Just use the head, since we require them all to match. */
890	mac_biba_copy_single(source, dest);
891}
892
893static void
894mac_biba_create_fragment(struct mbuf *datagram, struct label *datagramlabel,
895    struct mbuf *fragment, struct label *fragmentlabel)
896{
897	struct mac_biba *source, *dest;
898
899	source = SLOT(datagramlabel);
900	dest = SLOT(fragmentlabel);
901
902	mac_biba_copy_single(source, dest);
903}
904
905static void
906mac_biba_create_mbuf_from_mbuf(struct mbuf *oldmbuf,
907    struct label *oldmbuflabel, struct mbuf *newmbuf,
908    struct label *newmbuflabel)
909{
910	struct mac_biba *source, *dest;
911
912	source = SLOT(oldmbuflabel);
913	dest = SLOT(newmbuflabel);
914
915	mac_biba_copy_single(source, dest);
916}
917
918static void
919mac_biba_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel,
920    struct mbuf *mbuf, struct label *mbuflabel)
921{
922	struct mac_biba *dest;
923
924	dest = SLOT(mbuflabel);
925
926	mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
927}
928
929static void
930mac_biba_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel,
931    struct mbuf *mbuf, struct label *mbuflabel)
932{
933	struct mac_biba *source, *dest;
934
935	source = SLOT(bpflabel);
936	dest = SLOT(mbuflabel);
937
938	mac_biba_copy_single(source, dest);
939}
940
941static void
942mac_biba_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel,
943    struct mbuf *m, struct label *mbuflabel)
944{
945	struct mac_biba *source, *dest;
946
947	source = SLOT(ifnetlabel);
948	dest = SLOT(mbuflabel);
949
950	mac_biba_copy_single(source, dest);
951}
952
953static void
954mac_biba_create_mbuf_multicast_encap(struct mbuf *oldmbuf,
955    struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel,
956    struct mbuf *newmbuf, struct label *newmbuflabel)
957{
958	struct mac_biba *source, *dest;
959
960	source = SLOT(oldmbuflabel);
961	dest = SLOT(newmbuflabel);
962
963	mac_biba_copy_single(source, dest);
964}
965
966static void
967mac_biba_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel,
968    struct mbuf *newmbuf, struct label *newmbuflabel)
969{
970	struct mac_biba *source, *dest;
971
972	source = SLOT(oldmbuflabel);
973	dest = SLOT(newmbuflabel);
974
975	mac_biba_copy_single(source, dest);
976}
977
978static int
979mac_biba_fragment_match(struct mbuf *fragment, struct label *fragmentlabel,
980    struct ipq *ipq, struct label *ipqlabel)
981{
982	struct mac_biba *a, *b;
983
984	a = SLOT(ipqlabel);
985	b = SLOT(fragmentlabel);
986
987	return (mac_biba_equal_single(a, b));
988}
989
990static void
991mac_biba_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet,
992    struct label *ifnetlabel, struct label *newlabel)
993{
994	struct mac_biba *source, *dest;
995
996	source = SLOT(newlabel);
997	dest = SLOT(ifnetlabel);
998
999	mac_biba_copy_single(source, dest);
1000	mac_biba_copy_range(source, dest);
1001}
1002
1003static void
1004mac_biba_update_ipq(struct mbuf *fragment, struct label *fragmentlabel,
1005    struct ipq *ipq, struct label *ipqlabel)
1006{
1007
1008	/* NOOP: we only accept matching labels, so no need to update */
1009}
1010
1011/*
1012 * Labeling event operations: processes.
1013 */
1014static void
1015mac_biba_create_cred(struct ucred *cred_parent, struct ucred *cred_child)
1016{
1017	struct mac_biba *source, *dest;
1018
1019	source = SLOT(&cred_parent->cr_label);
1020	dest = SLOT(&cred_child->cr_label);
1021
1022	mac_biba_copy_single(source, dest);
1023	mac_biba_copy_range(source, dest);
1024}
1025
1026static void
1027mac_biba_execve_transition(struct ucred *old, struct ucred *new,
1028    struct vnode *vp, struct mac *vnodelabel)
1029{
1030	struct mac_biba *source, *dest;
1031
1032	source = SLOT(&old->cr_label);
1033	dest = SLOT(&new->cr_label);
1034
1035	mac_biba_copy_single(source, dest);
1036	mac_biba_copy_range(source, dest);
1037}
1038
1039static int
1040mac_biba_execve_will_transition(struct ucred *old, struct vnode *vp,
1041    struct mac *vnodelabel)
1042{
1043
1044	return (0);
1045}
1046
1047static void
1048mac_biba_create_proc0(struct ucred *cred)
1049{
1050	struct mac_biba *dest;
1051
1052	dest = SLOT(&cred->cr_label);
1053
1054	mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1055	mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL,
1056	    MAC_BIBA_TYPE_HIGH, 0, NULL);
1057}
1058
1059static void
1060mac_biba_create_proc1(struct ucred *cred)
1061{
1062	struct mac_biba *dest;
1063
1064	dest = SLOT(&cred->cr_label);
1065
1066	mac_biba_set_single(dest, MAC_BIBA_TYPE_HIGH, 0, NULL);
1067	mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL,
1068	    MAC_BIBA_TYPE_HIGH, 0, NULL);
1069}
1070
1071static void
1072mac_biba_relabel_cred(struct ucred *cred, struct label *newlabel)
1073{
1074	struct mac_biba *source, *dest;
1075
1076	source = SLOT(newlabel);
1077	dest = SLOT(&cred->cr_label);
1078
1079	mac_biba_copy_single(source, dest);
1080	mac_biba_copy_range(source, dest);
1081}
1082
1083/*
1084 * Access control checks.
1085 */
1086static int
1087mac_biba_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel,
1088    struct ifnet *ifnet, struct label *ifnetlabel)
1089{
1090	struct mac_biba *a, *b;
1091
1092	if (!mac_biba_enabled)
1093		return (0);
1094
1095	a = SLOT(bpflabel);
1096	b = SLOT(ifnetlabel);
1097
1098	if (mac_biba_equal_single(a, b))
1099		return (0);
1100	return (EACCES);
1101}
1102
1103static int
1104mac_biba_check_cred_relabel(struct ucred *cred, struct label *newlabel)
1105{
1106	struct mac_biba *subj, *new;
1107	int error;
1108
1109	subj = SLOT(&cred->cr_label);
1110	new = SLOT(newlabel);
1111
1112	/*
1113	 * If there is a Biba label update for the credential, it may
1114	 * be an update of the single, range, or both.
1115	 */
1116	error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
1117	if (error)
1118		return (error);
1119
1120	/*
1121	 * If the Biba label is to be changed, authorize as appropriate.
1122	 */
1123	if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) {
1124		/*
1125		 * To change the Biba single label on a credential, the
1126		 * new single label must be in the current range.
1127		 */
1128		if (new->mb_flags & MAC_BIBA_FLAG_SINGLE &&
1129		    !mac_biba_single_in_range(new, subj))
1130			return (EPERM);
1131
1132		/*
1133		 * To change the Biba range on a credential, the new
1134		 * range label must be in the current range.
1135		 */
1136		if (new->mb_flags & MAC_BIBA_FLAG_RANGE &&
1137		    !mac_biba_range_in_range(new, subj))
1138			return (EPERM);
1139
1140		/*
1141		 * To have EQUAL in any component of the new credential
1142		 * Biba label, the subject must already have EQUAL in
1143		 * their label.
1144		 */
1145		if (mac_biba_contains_equal(new)) {
1146			error = mac_biba_subject_equal_ok(subj);
1147			if (error)
1148				return (error);
1149		}
1150
1151		/*
1152		 * XXXMAC: Additional consistency tests regarding the
1153		 * single and range of the new label might be performed
1154		 * here.
1155		 */
1156	}
1157
1158	return (0);
1159}
1160
1161static int
1162mac_biba_check_cred_visible(struct ucred *u1, struct ucred *u2)
1163{
1164	struct mac_biba *subj, *obj;
1165
1166	if (!mac_biba_enabled)
1167		return (0);
1168
1169	subj = SLOT(&u1->cr_label);
1170	obj = SLOT(&u2->cr_label);
1171
1172	/* XXX: range */
1173	if (!mac_biba_dominate_single(obj, subj))
1174		return (ESRCH);
1175
1176	return (0);
1177}
1178
1179static int
1180mac_biba_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet,
1181    struct label *ifnetlabel, struct label *newlabel)
1182{
1183	struct mac_biba *subj, *new;
1184	int error;
1185
1186	subj = SLOT(&cred->cr_label);
1187	new = SLOT(newlabel);
1188
1189	/*
1190	 * If there is a Biba label update for the interface, it may
1191	 * be an update of the single, range, or both.
1192	 */
1193	error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
1194	if (error)
1195		return (error);
1196
1197	/*
1198	 * If the Biba label is to be changed, authorize as appropriate.
1199	 */
1200	if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) {
1201		/*
1202		 * Rely on the traditional superuser status for the Biba
1203		 * interface relabel requirements.  XXXMAC: This will go
1204		 * away.
1205		 */
1206		error = suser_cred(cred, 0);
1207		if (error)
1208			return (EPERM);
1209
1210		/*
1211		 * XXXMAC: Additional consistency tests regarding the single
1212		 * and the range of the new label might be performed here.
1213		 */
1214	}
1215
1216	return (0);
1217}
1218
1219static int
1220mac_biba_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel,
1221    struct mbuf *m, struct label *mbuflabel)
1222{
1223	struct mac_biba *p, *i;
1224
1225	if (!mac_biba_enabled)
1226		return (0);
1227
1228	p = SLOT(mbuflabel);
1229	i = SLOT(ifnetlabel);
1230
1231	return (mac_biba_single_in_range(p, i) ? 0 : EACCES);
1232}
1233
1234static int
1235mac_biba_check_mount_stat(struct ucred *cred, struct mount *mp,
1236    struct label *mntlabel)
1237{
1238	struct mac_biba *subj, *obj;
1239
1240	if (!mac_biba_enabled)
1241		return (0);
1242
1243	subj = SLOT(&cred->cr_label);
1244	obj = SLOT(mntlabel);
1245
1246	if (!mac_biba_dominate_single(obj, subj))
1247		return (EACCES);
1248
1249	return (0);
1250}
1251
1252static int
1253mac_biba_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe,
1254    struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data)
1255{
1256
1257	if(!mac_biba_enabled)
1258		return (0);
1259
1260	/* XXX: This will be implemented soon... */
1261
1262	return (0);
1263}
1264
1265static int
1266mac_biba_check_pipe_poll(struct ucred *cred, struct pipe *pipe,
1267    struct label *pipelabel)
1268{
1269	struct mac_biba *subj, *obj;
1270
1271	if (!mac_biba_enabled)
1272		return (0);
1273
1274	subj = SLOT(&cred->cr_label);
1275	obj = SLOT((pipelabel));
1276
1277	if (!mac_biba_dominate_single(obj, subj))
1278		return (EACCES);
1279
1280	return (0);
1281}
1282
1283static int
1284mac_biba_check_pipe_read(struct ucred *cred, struct pipe *pipe,
1285    struct label *pipelabel)
1286{
1287	struct mac_biba *subj, *obj;
1288
1289	if (!mac_biba_enabled)
1290		return (0);
1291
1292	subj = SLOT(&cred->cr_label);
1293	obj = SLOT((pipelabel));
1294
1295	if (!mac_biba_dominate_single(obj, subj))
1296		return (EACCES);
1297
1298	return (0);
1299}
1300
1301static int
1302mac_biba_check_pipe_relabel(struct ucred *cred, struct pipe *pipe,
1303    struct label *pipelabel, struct label *newlabel)
1304{
1305	struct mac_biba *subj, *obj, *new;
1306	int error;
1307
1308	new = SLOT(newlabel);
1309	subj = SLOT(&cred->cr_label);
1310	obj = SLOT(pipelabel);
1311
1312	/*
1313	 * If there is a Biba label update for a pipe, it must be a
1314	 * single update.
1315	 */
1316	error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE);
1317	if (error)
1318		return (error);
1319
1320	/*
1321	 * To perform a relabel of a pipe (Biba label or not), Biba must
1322	 * authorize the relabel.
1323	 */
1324	if (!mac_biba_single_in_range(obj, subj))
1325		return (EPERM);
1326
1327	/*
1328	 * If the Biba label is to be changed, authorize as appropriate.
1329	 */
1330	if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) {
1331		/*
1332		 * To change the Biba label on a pipe, the new pipe label
1333		 * must be in the subject range.
1334		 */
1335		if (!mac_biba_single_in_range(new, subj))
1336			return (EPERM);
1337
1338		/*
1339		 * To change the Biba label on a pipe to be EQUAL, the
1340		 * subject must have appropriate privilege.
1341		 */
1342		if (mac_biba_contains_equal(new)) {
1343			error = mac_biba_subject_equal_ok(subj);
1344			if (error)
1345				return (error);
1346		}
1347	}
1348
1349	return (0);
1350}
1351
1352static int
1353mac_biba_check_pipe_stat(struct ucred *cred, struct pipe *pipe,
1354    struct label *pipelabel)
1355{
1356	struct mac_biba *subj, *obj;
1357
1358	if (!mac_biba_enabled)
1359		return (0);
1360
1361	subj = SLOT(&cred->cr_label);
1362	obj = SLOT((pipelabel));
1363
1364	if (!mac_biba_dominate_single(obj, subj))
1365		return (EACCES);
1366
1367	return (0);
1368}
1369
1370static int
1371mac_biba_check_pipe_write(struct ucred *cred, struct pipe *pipe,
1372    struct label *pipelabel)
1373{
1374	struct mac_biba *subj, *obj;
1375
1376	if (!mac_biba_enabled)
1377		return (0);
1378
1379	subj = SLOT(&cred->cr_label);
1380	obj = SLOT((pipelabel));
1381
1382	if (!mac_biba_dominate_single(subj, obj))
1383		return (EACCES);
1384
1385	return (0);
1386}
1387
1388static int
1389mac_biba_check_proc_debug(struct ucred *cred, struct proc *proc)
1390{
1391	struct mac_biba *subj, *obj;
1392
1393	if (!mac_biba_enabled)
1394		return (0);
1395
1396	subj = SLOT(&cred->cr_label);
1397	obj = SLOT(&proc->p_ucred->cr_label);
1398
1399	/* XXX: range checks */
1400	if (!mac_biba_dominate_single(obj, subj))
1401		return (ESRCH);
1402	if (!mac_biba_dominate_single(subj, obj))
1403		return (EACCES);
1404
1405	return (0);
1406}
1407
1408static int
1409mac_biba_check_proc_sched(struct ucred *cred, struct proc *proc)
1410{
1411	struct mac_biba *subj, *obj;
1412
1413	if (!mac_biba_enabled)
1414		return (0);
1415
1416	subj = SLOT(&cred->cr_label);
1417	obj = SLOT(&proc->p_ucred->cr_label);
1418
1419	/* XXX: range checks */
1420	if (!mac_biba_dominate_single(obj, subj))
1421		return (ESRCH);
1422	if (!mac_biba_dominate_single(subj, obj))
1423		return (EACCES);
1424
1425	return (0);
1426}
1427
1428static int
1429mac_biba_check_proc_signal(struct ucred *cred, struct proc *proc, int signum)
1430{
1431	struct mac_biba *subj, *obj;
1432
1433	if (!mac_biba_enabled)
1434		return (0);
1435
1436	subj = SLOT(&cred->cr_label);
1437	obj = SLOT(&proc->p_ucred->cr_label);
1438
1439	/* XXX: range checks */
1440	if (!mac_biba_dominate_single(obj, subj))
1441		return (ESRCH);
1442	if (!mac_biba_dominate_single(subj, obj))
1443		return (EACCES);
1444
1445	return (0);
1446}
1447
1448static int
1449mac_biba_check_socket_deliver(struct socket *so, struct label *socketlabel,
1450    struct mbuf *m, struct label *mbuflabel)
1451{
1452	struct mac_biba *p, *s;
1453
1454	if (!mac_biba_enabled)
1455		return (0);
1456
1457	p = SLOT(mbuflabel);
1458	s = SLOT(socketlabel);
1459
1460	return (mac_biba_equal_single(p, s) ? 0 : EACCES);
1461}
1462
1463static int
1464mac_biba_check_socket_relabel(struct ucred *cred, struct socket *socket,
1465    struct label *socketlabel, struct label *newlabel)
1466{
1467	struct mac_biba *subj, *obj, *new;
1468	int error;
1469
1470	new = SLOT(newlabel);
1471	subj = SLOT(&cred->cr_label);
1472	obj = SLOT(socketlabel);
1473
1474	/*
1475	 * If there is a Biba label update for the socket, it may be
1476	 * an update of single.
1477	 */
1478	error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE);
1479	if (error)
1480		return (error);
1481
1482	/*
1483	 * To relabel a socket, the old socket single must be in the subject
1484	 * range.
1485	 */
1486	if (!mac_biba_single_in_range(obj, subj))
1487		return (EPERM);
1488
1489	/*
1490	 * If the Biba label is to be changed, authorize as appropriate.
1491	 */
1492	if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) {
1493		/*
1494		 * To relabel a socket, the new socket single must be in
1495		 * the subject range.
1496		 */
1497		if (!mac_biba_single_in_range(new, subj))
1498			return (EPERM);
1499
1500		/*
1501		 * To change the Biba label on the socket to contain EQUAL,
1502		 * the subject must have appropriate privilege.
1503		 */
1504		if (mac_biba_contains_equal(new)) {
1505			error = mac_biba_subject_equal_ok(subj);
1506			if (error)
1507				return (error);
1508		}
1509	}
1510
1511	return (0);
1512}
1513
1514static int
1515mac_biba_check_socket_visible(struct ucred *cred, struct socket *socket,
1516    struct label *socketlabel)
1517{
1518	struct mac_biba *subj, *obj;
1519
1520	subj = SLOT(&cred->cr_label);
1521	obj = SLOT(socketlabel);
1522
1523	if (!mac_biba_dominate_single(obj, subj))
1524		return (ENOENT);
1525
1526	return (0);
1527}
1528
1529static int
1530mac_biba_check_vnode_chdir(struct ucred *cred, struct vnode *dvp,
1531    struct label *dlabel)
1532{
1533	struct mac_biba *subj, *obj;
1534
1535	if (!mac_biba_enabled)
1536		return (0);
1537
1538	subj = SLOT(&cred->cr_label);
1539	obj = SLOT(dlabel);
1540
1541	if (!mac_biba_dominate_single(obj, subj))
1542		return (EACCES);
1543
1544	return (0);
1545}
1546
1547static int
1548mac_biba_check_vnode_chroot(struct ucred *cred, struct vnode *dvp,
1549    struct label *dlabel)
1550{
1551	struct mac_biba *subj, *obj;
1552
1553	if (!mac_biba_enabled)
1554		return (0);
1555
1556	subj = SLOT(&cred->cr_label);
1557	obj = SLOT(dlabel);
1558
1559	if (!mac_biba_dominate_single(obj, subj))
1560		return (EACCES);
1561
1562	return (0);
1563}
1564
1565static int
1566mac_biba_check_vnode_create(struct ucred *cred, struct vnode *dvp,
1567    struct label *dlabel, struct componentname *cnp, struct vattr *vap)
1568{
1569	struct mac_biba *subj, *obj;
1570
1571	if (!mac_biba_enabled)
1572		return (0);
1573
1574	subj = SLOT(&cred->cr_label);
1575	obj = SLOT(dlabel);
1576
1577	if (!mac_biba_dominate_single(subj, obj))
1578		return (EACCES);
1579
1580	return (0);
1581}
1582
1583static int
1584mac_biba_check_vnode_delete(struct ucred *cred, struct vnode *dvp,
1585    struct label *dlabel, struct vnode *vp, struct label *label,
1586    struct componentname *cnp)
1587{
1588	struct mac_biba *subj, *obj;
1589
1590	if (!mac_biba_enabled)
1591		return (0);
1592
1593	subj = SLOT(&cred->cr_label);
1594	obj = SLOT(dlabel);
1595
1596	if (!mac_biba_dominate_single(subj, obj))
1597		return (EACCES);
1598
1599	obj = SLOT(label);
1600
1601	if (!mac_biba_dominate_single(subj, obj))
1602		return (EACCES);
1603
1604	return (0);
1605}
1606
1607static int
1608mac_biba_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
1609    struct label *label, acl_type_t type)
1610{
1611	struct mac_biba *subj, *obj;
1612
1613	if (!mac_biba_enabled)
1614		return (0);
1615
1616	subj = SLOT(&cred->cr_label);
1617	obj = SLOT(label);
1618
1619	if (!mac_biba_dominate_single(subj, obj))
1620		return (EACCES);
1621
1622	return (0);
1623}
1624
1625static int
1626mac_biba_check_vnode_exec(struct ucred *cred, struct vnode *vp,
1627    struct label *label)
1628{
1629	struct mac_biba *subj, *obj;
1630
1631	if (!mac_biba_enabled)
1632		return (0);
1633
1634	subj = SLOT(&cred->cr_label);
1635	obj = SLOT(label);
1636
1637	if (!mac_biba_dominate_single(obj, subj))
1638		return (EACCES);
1639
1640	return (0);
1641}
1642
1643static int
1644mac_biba_check_vnode_getacl(struct ucred *cred, struct vnode *vp,
1645    struct label *label, acl_type_t type)
1646{
1647	struct mac_biba *subj, *obj;
1648
1649	if (!mac_biba_enabled)
1650		return (0);
1651
1652	subj = SLOT(&cred->cr_label);
1653	obj = SLOT(label);
1654
1655	if (!mac_biba_dominate_single(obj, subj))
1656		return (EACCES);
1657
1658	return (0);
1659}
1660
1661static int
1662mac_biba_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
1663    struct label *label, int attrnamespace, const char *name, struct uio *uio)
1664{
1665	struct mac_biba *subj, *obj;
1666
1667	if (!mac_biba_enabled)
1668		return (0);
1669
1670	subj = SLOT(&cred->cr_label);
1671	obj = SLOT(label);
1672
1673	if (!mac_biba_dominate_single(obj, subj))
1674		return (EACCES);
1675
1676	return (0);
1677}
1678
1679static int
1680mac_biba_check_vnode_link(struct ucred *cred, struct vnode *dvp,
1681    struct label *dlabel, struct vnode *vp, struct label *label,
1682    struct componentname *cnp)
1683{
1684	struct mac_biba *subj, *obj;
1685
1686	if (!mac_biba_enabled)
1687		return (0);
1688
1689	subj = SLOT(&cred->cr_label);
1690	obj = SLOT(dlabel);
1691
1692	if (!mac_biba_dominate_single(subj, obj))
1693		return (EACCES);
1694
1695	obj = SLOT(label);
1696
1697	if (!mac_biba_dominate_single(subj, obj))
1698		return (EACCES);
1699
1700	return (0);
1701}
1702
1703static int
1704mac_biba_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
1705    struct label *dlabel, struct componentname *cnp)
1706{
1707	struct mac_biba *subj, *obj;
1708
1709	if (!mac_biba_enabled)
1710		return (0);
1711
1712	subj = SLOT(&cred->cr_label);
1713	obj = SLOT(dlabel);
1714
1715	if (!mac_biba_dominate_single(obj, subj))
1716		return (EACCES);
1717
1718	return (0);
1719}
1720
1721static int
1722mac_biba_check_vnode_mmap(struct ucred *cred, struct vnode *vp,
1723    struct label *label, int prot)
1724{
1725	struct mac_biba *subj, *obj;
1726
1727	/*
1728	 * Rely on the use of open()-time protections to handle
1729	 * non-revocation cases.
1730	 */
1731	if (!mac_biba_enabled || !revocation_enabled)
1732		return (0);
1733
1734	subj = SLOT(&cred->cr_label);
1735	obj = SLOT(label);
1736
1737	if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
1738		if (!mac_biba_dominate_single(obj, subj))
1739			return (EACCES);
1740	}
1741	if (prot & VM_PROT_WRITE) {
1742		if (!mac_biba_dominate_single(subj, obj))
1743			return (EACCES);
1744	}
1745
1746	return (0);
1747}
1748
1749static int
1750mac_biba_check_vnode_open(struct ucred *cred, struct vnode *vp,
1751    struct label *vnodelabel, mode_t acc_mode)
1752{
1753	struct mac_biba *subj, *obj;
1754
1755	if (!mac_biba_enabled)
1756		return (0);
1757
1758	subj = SLOT(&cred->cr_label);
1759	obj = SLOT(vnodelabel);
1760
1761	/* XXX privilege override for admin? */
1762	if (acc_mode & (VREAD | VEXEC | VSTAT)) {
1763		if (!mac_biba_dominate_single(obj, subj))
1764			return (EACCES);
1765	}
1766	if (acc_mode & (VWRITE | VAPPEND | VADMIN)) {
1767		if (!mac_biba_dominate_single(subj, obj))
1768			return (EACCES);
1769	}
1770
1771	return (0);
1772}
1773
1774static int
1775mac_biba_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred,
1776    struct vnode *vp, struct label *label)
1777{
1778	struct mac_biba *subj, *obj;
1779
1780	if (!mac_biba_enabled || !revocation_enabled)
1781		return (0);
1782
1783	subj = SLOT(&active_cred->cr_label);
1784	obj = SLOT(label);
1785
1786	if (!mac_biba_dominate_single(obj, subj))
1787		return (EACCES);
1788
1789	return (0);
1790}
1791
1792static int
1793mac_biba_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
1794    struct vnode *vp, struct label *label)
1795{
1796	struct mac_biba *subj, *obj;
1797
1798	if (!mac_biba_enabled || !revocation_enabled)
1799		return (0);
1800
1801	subj = SLOT(&active_cred->cr_label);
1802	obj = SLOT(label);
1803
1804	if (!mac_biba_dominate_single(obj, subj))
1805		return (EACCES);
1806
1807	return (0);
1808}
1809
1810static int
1811mac_biba_check_vnode_readdir(struct ucred *cred, struct vnode *dvp,
1812    struct label *dlabel)
1813{
1814	struct mac_biba *subj, *obj;
1815
1816	if (!mac_biba_enabled)
1817		return (0);
1818
1819	subj = SLOT(&cred->cr_label);
1820	obj = SLOT(dlabel);
1821
1822	if (!mac_biba_dominate_single(obj, subj))
1823		return (EACCES);
1824
1825	return (0);
1826}
1827
1828static int
1829mac_biba_check_vnode_readlink(struct ucred *cred, struct vnode *vp,
1830    struct label *label)
1831{
1832	struct mac_biba *subj, *obj;
1833
1834	if (!mac_biba_enabled)
1835		return (0);
1836
1837	subj = SLOT(&cred->cr_label);
1838	obj = SLOT(label);
1839
1840	if (!mac_biba_dominate_single(obj, subj))
1841		return (EACCES);
1842
1843	return (0);
1844}
1845
1846static int
1847mac_biba_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
1848    struct label *vnodelabel, struct label *newlabel)
1849{
1850	struct mac_biba *old, *new, *subj;
1851	int error;
1852
1853	old = SLOT(vnodelabel);
1854	new = SLOT(newlabel);
1855	subj = SLOT(&cred->cr_label);
1856
1857	/*
1858	 * If there is a Biba label update for the vnode, it must be a
1859	 * single label.
1860	 */
1861	error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE);
1862	if (error)
1863		return (error);
1864
1865	/*
1866	 * To perform a relabel of the vnode (Biba label or not), Biba must
1867	 * authorize the relabel.
1868	 */
1869	if (!mac_biba_single_in_range(old, subj))
1870		return (EPERM);
1871
1872	/*
1873	 * If the Biba label is to be changed, authorize as appropriate.
1874	 */
1875	if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) {
1876		/*
1877		 * To change the Biba label on a vnode, the new vnode label
1878		 * must be in the subject range.
1879		 */
1880		if (!mac_biba_single_in_range(new, subj))
1881			return (EPERM);
1882
1883		/*
1884		 * To change the Biba label on the vnode to be EQUAL,
1885		 * the subject must have appropriate privilege.
1886		 */
1887		if (mac_biba_contains_equal(new)) {
1888			error = mac_biba_subject_equal_ok(subj);
1889			if (error)
1890				return (error);
1891		}
1892	}
1893
1894	return (0);
1895}
1896
1897static int
1898mac_biba_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
1899    struct label *dlabel, struct vnode *vp, struct label *label,
1900    struct componentname *cnp)
1901{
1902	struct mac_biba *subj, *obj;
1903
1904	if (!mac_biba_enabled)
1905		return (0);
1906
1907	subj = SLOT(&cred->cr_label);
1908	obj = SLOT(dlabel);
1909
1910	if (!mac_biba_dominate_single(subj, obj))
1911		return (EACCES);
1912
1913	obj = SLOT(label);
1914
1915	if (!mac_biba_dominate_single(subj, obj))
1916		return (EACCES);
1917
1918	return (0);
1919}
1920
1921static int
1922mac_biba_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
1923    struct label *dlabel, struct vnode *vp, struct label *label, int samedir,
1924    struct componentname *cnp)
1925{
1926	struct mac_biba *subj, *obj;
1927
1928	if (!mac_biba_enabled)
1929		return (0);
1930
1931	subj = SLOT(&cred->cr_label);
1932	obj = SLOT(dlabel);
1933
1934	if (!mac_biba_dominate_single(subj, obj))
1935		return (EACCES);
1936
1937	if (vp != NULL) {
1938		obj = SLOT(label);
1939
1940		if (!mac_biba_dominate_single(subj, obj))
1941			return (EACCES);
1942	}
1943
1944	return (0);
1945}
1946
1947static int
1948mac_biba_check_vnode_revoke(struct ucred *cred, struct vnode *vp,
1949    struct label *label)
1950{
1951	struct mac_biba *subj, *obj;
1952
1953	if (!mac_biba_enabled)
1954		return (0);
1955
1956	subj = SLOT(&cred->cr_label);
1957	obj = SLOT(label);
1958
1959	if (!mac_biba_dominate_single(subj, obj))
1960		return (EACCES);
1961
1962	return (0);
1963}
1964
1965static int
1966mac_biba_check_vnode_setacl(struct ucred *cred, struct vnode *vp,
1967    struct label *label, acl_type_t type, struct acl *acl)
1968{
1969	struct mac_biba *subj, *obj;
1970
1971	if (!mac_biba_enabled)
1972		return (0);
1973
1974	subj = SLOT(&cred->cr_label);
1975	obj = SLOT(label);
1976
1977	if (!mac_biba_dominate_single(subj, obj))
1978		return (EACCES);
1979
1980	return (0);
1981}
1982
1983static int
1984mac_biba_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
1985    struct label *vnodelabel, int attrnamespace, const char *name,
1986    struct uio *uio)
1987{
1988	struct mac_biba *subj, *obj;
1989
1990	if (!mac_biba_enabled)
1991		return (0);
1992
1993	subj = SLOT(&cred->cr_label);
1994	obj = SLOT(vnodelabel);
1995
1996	if (!mac_biba_dominate_single(subj, obj))
1997		return (EACCES);
1998
1999	/* XXX: protect the MAC EA in a special way? */
2000
2001	return (0);
2002}
2003
2004static int
2005mac_biba_check_vnode_setflags(struct ucred *cred, struct vnode *vp,
2006    struct label *vnodelabel, u_long flags)
2007{
2008	struct mac_biba *subj, *obj;
2009
2010	if (!mac_biba_enabled)
2011		return (0);
2012
2013	subj = SLOT(&cred->cr_label);
2014	obj = SLOT(vnodelabel);
2015
2016	if (!mac_biba_dominate_single(subj, obj))
2017		return (EACCES);
2018
2019	return (0);
2020}
2021
2022static int
2023mac_biba_check_vnode_setmode(struct ucred *cred, struct vnode *vp,
2024    struct label *vnodelabel, mode_t mode)
2025{
2026	struct mac_biba *subj, *obj;
2027
2028	if (!mac_biba_enabled)
2029		return (0);
2030
2031	subj = SLOT(&cred->cr_label);
2032	obj = SLOT(vnodelabel);
2033
2034	if (!mac_biba_dominate_single(subj, obj))
2035		return (EACCES);
2036
2037	return (0);
2038}
2039
2040static int
2041mac_biba_check_vnode_setowner(struct ucred *cred, struct vnode *vp,
2042    struct label *vnodelabel, uid_t uid, gid_t gid)
2043{
2044	struct mac_biba *subj, *obj;
2045
2046	if (!mac_biba_enabled)
2047		return (0);
2048
2049	subj = SLOT(&cred->cr_label);
2050	obj = SLOT(vnodelabel);
2051
2052	if (!mac_biba_dominate_single(subj, obj))
2053		return (EACCES);
2054
2055	return (0);
2056}
2057
2058static int
2059mac_biba_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
2060    struct label *vnodelabel, struct timespec atime, struct timespec mtime)
2061{
2062	struct mac_biba *subj, *obj;
2063
2064	if (!mac_biba_enabled)
2065		return (0);
2066
2067	subj = SLOT(&cred->cr_label);
2068	obj = SLOT(vnodelabel);
2069
2070	if (!mac_biba_dominate_single(subj, obj))
2071		return (EACCES);
2072
2073	return (0);
2074}
2075
2076static int
2077mac_biba_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
2078    struct vnode *vp, struct label *vnodelabel)
2079{
2080	struct mac_biba *subj, *obj;
2081
2082	if (!mac_biba_enabled)
2083		return (0);
2084
2085	subj = SLOT(&active_cred->cr_label);
2086	obj = SLOT(vnodelabel);
2087
2088	if (!mac_biba_dominate_single(obj, subj))
2089		return (EACCES);
2090
2091	return (0);
2092}
2093
2094static int
2095mac_biba_check_vnode_write(struct ucred *active_cred,
2096    struct ucred *file_cred, struct vnode *vp, struct label *label)
2097{
2098	struct mac_biba *subj, *obj;
2099
2100	if (!mac_biba_enabled || !revocation_enabled)
2101		return (0);
2102
2103	subj = SLOT(&active_cred->cr_label);
2104	obj = SLOT(label);
2105
2106	if (!mac_biba_dominate_single(subj, obj))
2107		return (EACCES);
2108
2109	return (0);
2110}
2111
2112static struct mac_policy_op_entry mac_biba_ops[] =
2113{
2114	{ MAC_DESTROY,
2115	    (macop_t)mac_biba_destroy },
2116	{ MAC_INIT,
2117	    (macop_t)mac_biba_init },
2118	{ MAC_INIT_BPFDESC_LABEL,
2119	    (macop_t)mac_biba_init_label },
2120	{ MAC_INIT_CRED_LABEL,
2121	    (macop_t)mac_biba_init_label },
2122	{ MAC_INIT_DEVFSDIRENT_LABEL,
2123	    (macop_t)mac_biba_init_label },
2124	{ MAC_INIT_IFNET_LABEL,
2125	    (macop_t)mac_biba_init_label },
2126	{ MAC_INIT_IPQ_LABEL,
2127	    (macop_t)mac_biba_init_label },
2128	{ MAC_INIT_MBUF_LABEL,
2129	    (macop_t)mac_biba_init_label_waitcheck },
2130	{ MAC_INIT_MOUNT_LABEL,
2131	    (macop_t)mac_biba_init_label },
2132	{ MAC_INIT_MOUNT_FS_LABEL,
2133	    (macop_t)mac_biba_init_label },
2134	{ MAC_INIT_PIPE_LABEL,
2135	    (macop_t)mac_biba_init_label },
2136	{ MAC_INIT_SOCKET_LABEL,
2137	    (macop_t)mac_biba_init_label_waitcheck },
2138	{ MAC_INIT_SOCKET_PEER_LABEL,
2139	    (macop_t)mac_biba_init_label_waitcheck },
2140	{ MAC_INIT_TEMP_LABEL,
2141	    (macop_t)mac_biba_init_label },
2142	{ MAC_INIT_VNODE_LABEL,
2143	    (macop_t)mac_biba_init_label },
2144	{ MAC_DESTROY_BPFDESC_LABEL,
2145	    (macop_t)mac_biba_destroy_label },
2146	{ MAC_DESTROY_CRED_LABEL,
2147	    (macop_t)mac_biba_destroy_label },
2148	{ MAC_DESTROY_DEVFSDIRENT_LABEL,
2149	    (macop_t)mac_biba_destroy_label },
2150	{ MAC_DESTROY_IFNET_LABEL,
2151	    (macop_t)mac_biba_destroy_label },
2152	{ MAC_DESTROY_IPQ_LABEL,
2153	    (macop_t)mac_biba_destroy_label },
2154	{ MAC_DESTROY_MBUF_LABEL,
2155	    (macop_t)mac_biba_destroy_label },
2156	{ MAC_DESTROY_MOUNT_LABEL,
2157	    (macop_t)mac_biba_destroy_label },
2158	{ MAC_DESTROY_MOUNT_FS_LABEL,
2159	    (macop_t)mac_biba_destroy_label },
2160	{ MAC_DESTROY_PIPE_LABEL,
2161	    (macop_t)mac_biba_destroy_label },
2162	{ MAC_DESTROY_SOCKET_LABEL,
2163	    (macop_t)mac_biba_destroy_label },
2164	{ MAC_DESTROY_SOCKET_PEER_LABEL,
2165	    (macop_t)mac_biba_destroy_label },
2166	{ MAC_DESTROY_TEMP_LABEL,
2167	    (macop_t)mac_biba_destroy_label },
2168	{ MAC_DESTROY_VNODE_LABEL,
2169	    (macop_t)mac_biba_destroy_label },
2170	{ MAC_EXTERNALIZE,
2171	    (macop_t)mac_biba_externalize },
2172	{ MAC_INTERNALIZE,
2173	    (macop_t)mac_biba_internalize },
2174	{ MAC_CREATE_DEVFS_DEVICE,
2175	    (macop_t)mac_biba_create_devfs_device },
2176	{ MAC_CREATE_DEVFS_DIRECTORY,
2177	    (macop_t)mac_biba_create_devfs_directory },
2178	{ MAC_CREATE_DEVFS_SYMLINK,
2179	    (macop_t)mac_biba_create_devfs_symlink },
2180	{ MAC_CREATE_DEVFS_VNODE,
2181	    (macop_t)mac_biba_create_devfs_vnode },
2182	{ MAC_CREATE_VNODE,
2183	    (macop_t)mac_biba_create_vnode },
2184	{ MAC_CREATE_MOUNT,
2185	    (macop_t)mac_biba_create_mount },
2186	{ MAC_CREATE_ROOT_MOUNT,
2187	    (macop_t)mac_biba_create_root_mount },
2188	{ MAC_RELABEL_VNODE,
2189	    (macop_t)mac_biba_relabel_vnode },
2190	{ MAC_UPDATE_DEVFSDIRENT,
2191	    (macop_t)mac_biba_update_devfsdirent },
2192	{ MAC_UPDATE_PROCFSVNODE,
2193	    (macop_t)mac_biba_update_procfsvnode },
2194	{ MAC_UPDATE_VNODE_FROM_EXTERNALIZED,
2195	    (macop_t)mac_biba_update_vnode_from_externalized },
2196	{ MAC_UPDATE_VNODE_FROM_MOUNT,
2197	    (macop_t)mac_biba_update_vnode_from_mount },
2198	{ MAC_CREATE_MBUF_FROM_SOCKET,
2199	    (macop_t)mac_biba_create_mbuf_from_socket },
2200	{ MAC_CREATE_PIPE,
2201	    (macop_t)mac_biba_create_pipe },
2202	{ MAC_CREATE_SOCKET,
2203	    (macop_t)mac_biba_create_socket },
2204	{ MAC_CREATE_SOCKET_FROM_SOCKET,
2205	    (macop_t)mac_biba_create_socket_from_socket },
2206	{ MAC_RELABEL_PIPE,
2207	    (macop_t)mac_biba_relabel_pipe },
2208	{ MAC_RELABEL_SOCKET,
2209	    (macop_t)mac_biba_relabel_socket },
2210	{ MAC_SET_SOCKET_PEER_FROM_MBUF,
2211	    (macop_t)mac_biba_set_socket_peer_from_mbuf },
2212	{ MAC_SET_SOCKET_PEER_FROM_SOCKET,
2213	    (macop_t)mac_biba_set_socket_peer_from_socket },
2214	{ MAC_CREATE_BPFDESC,
2215	    (macop_t)mac_biba_create_bpfdesc },
2216	{ MAC_CREATE_DATAGRAM_FROM_IPQ,
2217	    (macop_t)mac_biba_create_datagram_from_ipq },
2218	{ MAC_CREATE_FRAGMENT,
2219	    (macop_t)mac_biba_create_fragment },
2220	{ MAC_CREATE_IFNET,
2221	    (macop_t)mac_biba_create_ifnet },
2222	{ MAC_CREATE_IPQ,
2223	    (macop_t)mac_biba_create_ipq },
2224	{ MAC_CREATE_MBUF_FROM_MBUF,
2225	    (macop_t)mac_biba_create_mbuf_from_mbuf },
2226	{ MAC_CREATE_MBUF_LINKLAYER,
2227	    (macop_t)mac_biba_create_mbuf_linklayer },
2228	{ MAC_CREATE_MBUF_FROM_BPFDESC,
2229	    (macop_t)mac_biba_create_mbuf_from_bpfdesc },
2230	{ MAC_CREATE_MBUF_FROM_IFNET,
2231	    (macop_t)mac_biba_create_mbuf_from_ifnet },
2232	{ MAC_CREATE_MBUF_MULTICAST_ENCAP,
2233	    (macop_t)mac_biba_create_mbuf_multicast_encap },
2234	{ MAC_CREATE_MBUF_NETLAYER,
2235	    (macop_t)mac_biba_create_mbuf_netlayer },
2236	{ MAC_FRAGMENT_MATCH,
2237	    (macop_t)mac_biba_fragment_match },
2238	{ MAC_RELABEL_IFNET,
2239	    (macop_t)mac_biba_relabel_ifnet },
2240	{ MAC_UPDATE_IPQ,
2241	    (macop_t)mac_biba_update_ipq },
2242	{ MAC_CREATE_CRED,
2243	    (macop_t)mac_biba_create_cred },
2244	{ MAC_EXECVE_TRANSITION,
2245	    (macop_t)mac_biba_execve_transition },
2246	{ MAC_EXECVE_WILL_TRANSITION,
2247	    (macop_t)mac_biba_execve_will_transition },
2248	{ MAC_CREATE_PROC0,
2249	    (macop_t)mac_biba_create_proc0 },
2250	{ MAC_CREATE_PROC1,
2251	    (macop_t)mac_biba_create_proc1 },
2252	{ MAC_RELABEL_CRED,
2253	    (macop_t)mac_biba_relabel_cred },
2254	{ MAC_CHECK_BPFDESC_RECEIVE,
2255	    (macop_t)mac_biba_check_bpfdesc_receive },
2256	{ MAC_CHECK_CRED_RELABEL,
2257	    (macop_t)mac_biba_check_cred_relabel },
2258	{ MAC_CHECK_CRED_VISIBLE,
2259	    (macop_t)mac_biba_check_cred_visible },
2260	{ MAC_CHECK_IFNET_RELABEL,
2261	    (macop_t)mac_biba_check_ifnet_relabel },
2262	{ MAC_CHECK_IFNET_TRANSMIT,
2263	    (macop_t)mac_biba_check_ifnet_transmit },
2264	{ MAC_CHECK_MOUNT_STAT,
2265	    (macop_t)mac_biba_check_mount_stat },
2266	{ MAC_CHECK_PIPE_IOCTL,
2267	    (macop_t)mac_biba_check_pipe_ioctl },
2268	{ MAC_CHECK_PIPE_POLL,
2269	    (macop_t)mac_biba_check_pipe_poll },
2270	{ MAC_CHECK_PIPE_READ,
2271	    (macop_t)mac_biba_check_pipe_read },
2272	{ MAC_CHECK_PIPE_RELABEL,
2273	    (macop_t)mac_biba_check_pipe_relabel },
2274	{ MAC_CHECK_PIPE_STAT,
2275	    (macop_t)mac_biba_check_pipe_stat },
2276	{ MAC_CHECK_PIPE_WRITE,
2277	    (macop_t)mac_biba_check_pipe_write },
2278	{ MAC_CHECK_PROC_DEBUG,
2279	    (macop_t)mac_biba_check_proc_debug },
2280	{ MAC_CHECK_PROC_SCHED,
2281	    (macop_t)mac_biba_check_proc_sched },
2282	{ MAC_CHECK_PROC_SIGNAL,
2283	    (macop_t)mac_biba_check_proc_signal },
2284	{ MAC_CHECK_SOCKET_DELIVER,
2285	    (macop_t)mac_biba_check_socket_deliver },
2286	{ MAC_CHECK_SOCKET_RELABEL,
2287	    (macop_t)mac_biba_check_socket_relabel },
2288	{ MAC_CHECK_SOCKET_VISIBLE,
2289	    (macop_t)mac_biba_check_socket_visible },
2290	{ MAC_CHECK_VNODE_ACCESS,
2291	    (macop_t)mac_biba_check_vnode_open },
2292	{ MAC_CHECK_VNODE_CHDIR,
2293	    (macop_t)mac_biba_check_vnode_chdir },
2294	{ MAC_CHECK_VNODE_CHROOT,
2295	    (macop_t)mac_biba_check_vnode_chroot },
2296	{ MAC_CHECK_VNODE_CREATE,
2297	    (macop_t)mac_biba_check_vnode_create },
2298	{ MAC_CHECK_VNODE_DELETE,
2299	    (macop_t)mac_biba_check_vnode_delete },
2300	{ MAC_CHECK_VNODE_DELETEACL,
2301	    (macop_t)mac_biba_check_vnode_deleteacl },
2302	{ MAC_CHECK_VNODE_EXEC,
2303	    (macop_t)mac_biba_check_vnode_exec },
2304	{ MAC_CHECK_VNODE_GETACL,
2305	    (macop_t)mac_biba_check_vnode_getacl },
2306	{ MAC_CHECK_VNODE_GETEXTATTR,
2307	    (macop_t)mac_biba_check_vnode_getextattr },
2308	{ MAC_CHECK_VNODE_LINK,
2309	    (macop_t)mac_biba_check_vnode_link },
2310	{ MAC_CHECK_VNODE_LOOKUP,
2311	    (macop_t)mac_biba_check_vnode_lookup },
2312	{ MAC_CHECK_VNODE_MMAP,
2313	    (macop_t)mac_biba_check_vnode_mmap },
2314	{ MAC_CHECK_VNODE_MPROTECT,
2315	    (macop_t)mac_biba_check_vnode_mmap },
2316	{ MAC_CHECK_VNODE_OPEN,
2317	    (macop_t)mac_biba_check_vnode_open },
2318	{ MAC_CHECK_VNODE_POLL,
2319	    (macop_t)mac_biba_check_vnode_poll },
2320	{ MAC_CHECK_VNODE_READ,
2321	    (macop_t)mac_biba_check_vnode_read },
2322	{ MAC_CHECK_VNODE_READDIR,
2323	    (macop_t)mac_biba_check_vnode_readdir },
2324	{ MAC_CHECK_VNODE_READLINK,
2325	    (macop_t)mac_biba_check_vnode_readlink },
2326	{ MAC_CHECK_VNODE_RELABEL,
2327	    (macop_t)mac_biba_check_vnode_relabel },
2328	{ MAC_CHECK_VNODE_RENAME_FROM,
2329	    (macop_t)mac_biba_check_vnode_rename_from },
2330	{ MAC_CHECK_VNODE_RENAME_TO,
2331	    (macop_t)mac_biba_check_vnode_rename_to },
2332	{ MAC_CHECK_VNODE_REVOKE,
2333	    (macop_t)mac_biba_check_vnode_revoke },
2334	{ MAC_CHECK_VNODE_SETACL,
2335	    (macop_t)mac_biba_check_vnode_setacl },
2336	{ MAC_CHECK_VNODE_SETEXTATTR,
2337	    (macop_t)mac_biba_check_vnode_setextattr },
2338	{ MAC_CHECK_VNODE_SETFLAGS,
2339	    (macop_t)mac_biba_check_vnode_setflags },
2340	{ MAC_CHECK_VNODE_SETMODE,
2341	    (macop_t)mac_biba_check_vnode_setmode },
2342	{ MAC_CHECK_VNODE_SETOWNER,
2343	    (macop_t)mac_biba_check_vnode_setowner },
2344	{ MAC_CHECK_VNODE_SETUTIMES,
2345	    (macop_t)mac_biba_check_vnode_setutimes },
2346	{ MAC_CHECK_VNODE_STAT,
2347	    (macop_t)mac_biba_check_vnode_stat },
2348	{ MAC_CHECK_VNODE_WRITE,
2349	    (macop_t)mac_biba_check_vnode_write },
2350	{ MAC_OP_LAST, NULL }
2351};
2352
2353MAC_POLICY_SET(mac_biba_ops, trustedbsd_mac_biba, "TrustedBSD MAC/Biba",
2354    MPC_LOADTIME_FLAG_NOTLATE, &mac_biba_slot);
2355