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