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