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