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