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