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