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