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