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