1 /*-
2 * Copyright (c) 1999-2002 Robert N. M. Watson
3 * Copyright (c) 2001-2005 McAfee, 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 McAfee
9 * Research, the Security Research Division of McAfee, 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 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 *
34 * $FreeBSD: releng/6.2/sys/security/mac_mls/mac_mls.c 162448 2006-09-19 15:45:22Z csjp $
35 */
36
37 /*
38 * Developed by the TrustedBSD Project.
39 * MLS fixed label mandatory confidentiality policy.
40 */
41
42 #include <sys/types.h>
43 #include <sys/param.h>
44 #include <sys/acl.h>
45 #include <sys/conf.h>
46 #include <sys/extattr.h>
47 #include <sys/kernel.h>
48 #include <sys/mac.h>
49 #include <sys/mman.h>
50 #include <sys/malloc.h>
51 #include <sys/mount.h>
52 #include <sys/proc.h>
53 #include <sys/sbuf.h>
54 #include <sys/systm.h>
55 #include <sys/sysproto.h>
56 #include <sys/sysent.h>
57 #include <sys/systm.h>
58 #include <sys/vnode.h>
59 #include <sys/file.h>
60 #include <sys/socket.h>
61 #include <sys/socketvar.h>
62 #include <sys/pipe.h>
63 #include <sys/sx.h>
64 #include <sys/sysctl.h>
65 #include <sys/msg.h>
66 #include <sys/sem.h>
67 #include <sys/shm.h>
68
69 #include <posix4/ksem.h>
70
71 #include <fs/devfs/devfs.h>
72
73 #include <net/bpfdesc.h>
74 #include <net/if.h>
75 #include <net/if_types.h>
76 #include <net/if_var.h>
77
78 #include <netinet/in.h>
79 #include <netinet/in_pcb.h>
80 #include <netinet/ip_var.h>
81
82 #include <vm/uma.h>
83 #include <vm/vm.h>
84
85 #include <sys/mac_policy.h>
86
87 #include <security/mac_mls/mac_mls.h>
88
89 SYSCTL_DECL(_security_mac);
90
91 SYSCTL_NODE(_security_mac, OID_AUTO, mls, CTLFLAG_RW, 0,
92 "TrustedBSD mac_mls policy controls");
93
94 static int mac_mls_label_size = sizeof(struct mac_mls);
95 SYSCTL_INT(_security_mac_mls, OID_AUTO, label_size, CTLFLAG_RD,
96 &mac_mls_label_size, 0, "Size of struct mac_mls");
97
98 static int mac_mls_enabled = 1;
99 SYSCTL_INT(_security_mac_mls, OID_AUTO, enabled, CTLFLAG_RW,
100 &mac_mls_enabled, 0, "Enforce MAC/MLS policy");
101 TUNABLE_INT("security.mac.mls.enabled", &mac_mls_enabled);
102
103 static int destroyed_not_inited;
104 SYSCTL_INT(_security_mac_mls, OID_AUTO, destroyed_not_inited, CTLFLAG_RD,
105 &destroyed_not_inited, 0, "Count of labels destroyed but not inited");
106
107 static int ptys_equal = 0;
108 SYSCTL_INT(_security_mac_mls, OID_AUTO, ptys_equal, CTLFLAG_RW,
109 &ptys_equal, 0, "Label pty devices as mls/equal on create");
110 TUNABLE_INT("security.mac.mls.ptys_equal", &ptys_equal);
111
112 static int revocation_enabled = 0;
113 SYSCTL_INT(_security_mac_mls, OID_AUTO, revocation_enabled, CTLFLAG_RW,
114 &revocation_enabled, 0, "Revoke access to objects on relabel");
115 TUNABLE_INT("security.mac.mls.revocation_enabled", &revocation_enabled);
116
117 static int max_compartments = MAC_MLS_MAX_COMPARTMENTS;
118 SYSCTL_INT(_security_mac_mls, OID_AUTO, max_compartments, CTLFLAG_RD,
119 &max_compartments, 0, "Maximum compartments the policy supports");
120
121 static int mac_mls_slot;
122 #define SLOT(l) ((struct mac_mls *)LABEL_TO_SLOT((l), mac_mls_slot).l_ptr)
123 #define SLOT_SET(l, val) (LABEL_TO_SLOT((l), mac_mls_slot).l_ptr = (val))
124
125 static uma_zone_t zone_mls;
126
127 static __inline int
128 mls_bit_set_empty(u_char *set) {
129 int i;
130
131 for (i = 0; i < MAC_MLS_MAX_COMPARTMENTS >> 3; i++)
132 if (set[i] != 0)
133 return (0);
134 return (1);
135 }
136
137 static struct mac_mls *
138 mls_alloc(int flag)
139 {
140
141 return (uma_zalloc(zone_mls, flag | M_ZERO));
142 }
143
144 static void
145 mls_free(struct mac_mls *mac_mls)
146 {
147
148 if (mac_mls != NULL)
149 uma_zfree(zone_mls, mac_mls);
150 else
151 atomic_add_int(&destroyed_not_inited, 1);
152 }
153
154 static int
155 mls_atmostflags(struct mac_mls *mac_mls, int flags)
156 {
157
158 if ((mac_mls->mm_flags & flags) != mac_mls->mm_flags)
159 return (EINVAL);
160 return (0);
161 }
162
163 static int
164 mac_mls_dominate_element(struct mac_mls_element *a,
165 struct mac_mls_element *b)
166 {
167 int bit;
168
169 switch (a->mme_type) {
170 case MAC_MLS_TYPE_EQUAL:
171 case MAC_MLS_TYPE_HIGH:
172 return (1);
173
174 case MAC_MLS_TYPE_LOW:
175 switch (b->mme_type) {
176 case MAC_MLS_TYPE_LEVEL:
177 case MAC_MLS_TYPE_HIGH:
178 return (0);
179
180 case MAC_MLS_TYPE_EQUAL:
181 case MAC_MLS_TYPE_LOW:
182 return (1);
183
184 default:
185 panic("mac_mls_dominate_element: b->mme_type invalid");
186 }
187
188 case MAC_MLS_TYPE_LEVEL:
189 switch (b->mme_type) {
190 case MAC_MLS_TYPE_EQUAL:
191 case MAC_MLS_TYPE_LOW:
192 return (1);
193
194 case MAC_MLS_TYPE_HIGH:
195 return (0);
196
197 case MAC_MLS_TYPE_LEVEL:
198 for (bit = 1; bit <= MAC_MLS_MAX_COMPARTMENTS; bit++)
199 if (!MAC_MLS_BIT_TEST(bit,
200 a->mme_compartments) &&
201 MAC_MLS_BIT_TEST(bit, b->mme_compartments))
202 return (0);
203 return (a->mme_level >= b->mme_level);
204
205 default:
206 panic("mac_mls_dominate_element: b->mme_type invalid");
207 }
208
209 default:
210 panic("mac_mls_dominate_element: a->mme_type invalid");
211 }
212
213 return (0);
214 }
215
216 static int
217 mac_mls_range_in_range(struct mac_mls *rangea, struct mac_mls *rangeb)
218 {
219
220 return (mac_mls_dominate_element(&rangeb->mm_rangehigh,
221 &rangea->mm_rangehigh) &&
222 mac_mls_dominate_element(&rangea->mm_rangelow,
223 &rangeb->mm_rangelow));
224 }
225
226 static int
227 mac_mls_effective_in_range(struct mac_mls *effective, struct mac_mls *range)
228 {
229
230 KASSERT((effective->mm_flags & MAC_MLS_FLAG_EFFECTIVE) != 0,
231 ("mac_mls_effective_in_range: a not effective"));
232 KASSERT((range->mm_flags & MAC_MLS_FLAG_RANGE) != 0,
233 ("mac_mls_effective_in_range: b not range"));
234
235 return (mac_mls_dominate_element(&range->mm_rangehigh,
236 &effective->mm_effective) &&
237 mac_mls_dominate_element(&effective->mm_effective,
238 &range->mm_rangelow));
239
240 return (1);
241 }
242
243 static int
244 mac_mls_dominate_effective(struct mac_mls *a, struct mac_mls *b)
245 {
246 KASSERT((a->mm_flags & MAC_MLS_FLAG_EFFECTIVE) != 0,
247 ("mac_mls_dominate_effective: a not effective"));
248 KASSERT((b->mm_flags & MAC_MLS_FLAG_EFFECTIVE) != 0,
249 ("mac_mls_dominate_effective: b not effective"));
250
251 return (mac_mls_dominate_element(&a->mm_effective, &b->mm_effective));
252 }
253
254 static int
255 mac_mls_equal_element(struct mac_mls_element *a, struct mac_mls_element *b)
256 {
257
258 if (a->mme_type == MAC_MLS_TYPE_EQUAL ||
259 b->mme_type == MAC_MLS_TYPE_EQUAL)
260 return (1);
261
262 return (a->mme_type == b->mme_type && a->mme_level == b->mme_level);
263 }
264
265 static int
266 mac_mls_equal_effective(struct mac_mls *a, struct mac_mls *b)
267 {
268
269 KASSERT((a->mm_flags & MAC_MLS_FLAG_EFFECTIVE) != 0,
270 ("mac_mls_equal_effective: a not effective"));
271 KASSERT((b->mm_flags & MAC_MLS_FLAG_EFFECTIVE) != 0,
272 ("mac_mls_equal_effective: b not effective"));
273
274 return (mac_mls_equal_element(&a->mm_effective, &b->mm_effective));
275 }
276
277 static int
278 mac_mls_contains_equal(struct mac_mls *mac_mls)
279 {
280
281 if (mac_mls->mm_flags & MAC_MLS_FLAG_EFFECTIVE)
282 if (mac_mls->mm_effective.mme_type == MAC_MLS_TYPE_EQUAL)
283 return (1);
284
285 if (mac_mls->mm_flags & MAC_MLS_FLAG_RANGE) {
286 if (mac_mls->mm_rangelow.mme_type == MAC_MLS_TYPE_EQUAL)
287 return (1);
288 if (mac_mls->mm_rangehigh.mme_type == MAC_MLS_TYPE_EQUAL)
289 return (1);
290 }
291
292 return (0);
293 }
294
295 static int
296 mac_mls_subject_privileged(struct mac_mls *mac_mls)
297 {
298
299 KASSERT((mac_mls->mm_flags & MAC_MLS_FLAGS_BOTH) ==
300 MAC_MLS_FLAGS_BOTH,
301 ("mac_mls_subject_privileged: subject doesn't have both labels"));
302
303 /* If the effective is EQUAL, it's ok. */
304 if (mac_mls->mm_effective.mme_type == MAC_MLS_TYPE_EQUAL)
305 return (0);
306
307 /* If either range endpoint is EQUAL, it's ok. */
308 if (mac_mls->mm_rangelow.mme_type == MAC_MLS_TYPE_EQUAL ||
309 mac_mls->mm_rangehigh.mme_type == MAC_MLS_TYPE_EQUAL)
310 return (0);
311
312 /* If the range is low-high, it's ok. */
313 if (mac_mls->mm_rangelow.mme_type == MAC_MLS_TYPE_LOW &&
314 mac_mls->mm_rangehigh.mme_type == MAC_MLS_TYPE_HIGH)
315 return (0);
316
317 /* It's not ok. */
318 return (EPERM);
319 }
320
321 static int
322 mac_mls_valid(struct mac_mls *mac_mls)
323 {
324
325 if (mac_mls->mm_flags & MAC_MLS_FLAG_EFFECTIVE) {
326 switch (mac_mls->mm_effective.mme_type) {
327 case MAC_MLS_TYPE_LEVEL:
328 break;
329
330 case MAC_MLS_TYPE_EQUAL:
331 case MAC_MLS_TYPE_HIGH:
332 case MAC_MLS_TYPE_LOW:
333 if (mac_mls->mm_effective.mme_level != 0 ||
334 !MAC_MLS_BIT_SET_EMPTY(
335 mac_mls->mm_effective.mme_compartments))
336 return (EINVAL);
337 break;
338
339 default:
340 return (EINVAL);
341 }
342 } else {
343 if (mac_mls->mm_effective.mme_type != MAC_MLS_TYPE_UNDEF)
344 return (EINVAL);
345 }
346
347 if (mac_mls->mm_flags & MAC_MLS_FLAG_RANGE) {
348 switch (mac_mls->mm_rangelow.mme_type) {
349 case MAC_MLS_TYPE_LEVEL:
350 break;
351
352 case MAC_MLS_TYPE_EQUAL:
353 case MAC_MLS_TYPE_HIGH:
354 case MAC_MLS_TYPE_LOW:
355 if (mac_mls->mm_rangelow.mme_level != 0 ||
356 !MAC_MLS_BIT_SET_EMPTY(
357 mac_mls->mm_rangelow.mme_compartments))
358 return (EINVAL);
359 break;
360
361 default:
362 return (EINVAL);
363 }
364
365 switch (mac_mls->mm_rangehigh.mme_type) {
366 case MAC_MLS_TYPE_LEVEL:
367 break;
368
369 case MAC_MLS_TYPE_EQUAL:
370 case MAC_MLS_TYPE_HIGH:
371 case MAC_MLS_TYPE_LOW:
372 if (mac_mls->mm_rangehigh.mme_level != 0 ||
373 !MAC_MLS_BIT_SET_EMPTY(
374 mac_mls->mm_rangehigh.mme_compartments))
375 return (EINVAL);
376 break;
377
378 default:
379 return (EINVAL);
380 }
381 if (!mac_mls_dominate_element(&mac_mls->mm_rangehigh,
382 &mac_mls->mm_rangelow))
383 return (EINVAL);
384 } else {
385 if (mac_mls->mm_rangelow.mme_type != MAC_MLS_TYPE_UNDEF ||
386 mac_mls->mm_rangehigh.mme_type != MAC_MLS_TYPE_UNDEF)
387 return (EINVAL);
388 }
389
390 return (0);
391 }
392
393 static void
394 mac_mls_set_range(struct mac_mls *mac_mls, u_short typelow,
395 u_short levellow, u_char *compartmentslow, u_short typehigh,
396 u_short levelhigh, u_char *compartmentshigh)
397 {
398
399 mac_mls->mm_rangelow.mme_type = typelow;
400 mac_mls->mm_rangelow.mme_level = levellow;
401 if (compartmentslow != NULL)
402 memcpy(mac_mls->mm_rangelow.mme_compartments,
403 compartmentslow,
404 sizeof(mac_mls->mm_rangelow.mme_compartments));
405 mac_mls->mm_rangehigh.mme_type = typehigh;
406 mac_mls->mm_rangehigh.mme_level = levelhigh;
407 if (compartmentshigh != NULL)
408 memcpy(mac_mls->mm_rangehigh.mme_compartments,
409 compartmentshigh,
410 sizeof(mac_mls->mm_rangehigh.mme_compartments));
411 mac_mls->mm_flags |= MAC_MLS_FLAG_RANGE;
412 }
413
414 static void
415 mac_mls_set_effective(struct mac_mls *mac_mls, u_short type, u_short level,
416 u_char *compartments)
417 {
418
419 mac_mls->mm_effective.mme_type = type;
420 mac_mls->mm_effective.mme_level = level;
421 if (compartments != NULL)
422 memcpy(mac_mls->mm_effective.mme_compartments, compartments,
423 sizeof(mac_mls->mm_effective.mme_compartments));
424 mac_mls->mm_flags |= MAC_MLS_FLAG_EFFECTIVE;
425 }
426
427 static void
428 mac_mls_copy_range(struct mac_mls *labelfrom, struct mac_mls *labelto)
429 {
430
431 KASSERT((labelfrom->mm_flags & MAC_MLS_FLAG_RANGE) != 0,
432 ("mac_mls_copy_range: labelfrom not range"));
433
434 labelto->mm_rangelow = labelfrom->mm_rangelow;
435 labelto->mm_rangehigh = labelfrom->mm_rangehigh;
436 labelto->mm_flags |= MAC_MLS_FLAG_RANGE;
437 }
438
439 static void
440 mac_mls_copy_effective(struct mac_mls *labelfrom, struct mac_mls *labelto)
441 {
442
443 KASSERT((labelfrom->mm_flags & MAC_MLS_FLAG_EFFECTIVE) != 0,
444 ("mac_mls_copy_effective: labelfrom not effective"));
445
446 labelto->mm_effective = labelfrom->mm_effective;
447 labelto->mm_flags |= MAC_MLS_FLAG_EFFECTIVE;
448 }
449
450 static void
451 mac_mls_copy(struct mac_mls *source, struct mac_mls *dest)
452 {
453
454 if (source->mm_flags & MAC_MLS_FLAG_EFFECTIVE)
455 mac_mls_copy_effective(source, dest);
456 if (source->mm_flags & MAC_MLS_FLAG_RANGE)
457 mac_mls_copy_range(source, dest);
458 }
459
460 /*
461 * Policy module operations.
462 */
463 static void
464 mac_mls_init(struct mac_policy_conf *conf)
465 {
466
467 zone_mls = uma_zcreate("mac_mls", sizeof(struct mac_mls), NULL,
468 NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
469 }
470
471 /*
472 * Label operations.
473 */
474 static void
475 mac_mls_init_label(struct label *label)
476 {
477
478 SLOT_SET(label, mls_alloc(M_WAITOK));
479 }
480
481 static int
482 mac_mls_init_label_waitcheck(struct label *label, int flag)
483 {
484
485 SLOT_SET(label, mls_alloc(flag));
486 if (SLOT(label) == NULL)
487 return (ENOMEM);
488
489 return (0);
490 }
491
492 static void
493 mac_mls_destroy_label(struct label *label)
494 {
495
496 mls_free(SLOT(label));
497 SLOT_SET(label, NULL);
498 }
499
500 /*
501 * mac_mls_element_to_string() accepts an sbuf and MLS element. It
502 * converts the MLS element to a string and stores the result in the
503 * sbuf; if there isn't space in the sbuf, -1 is returned.
504 */
505 static int
506 mac_mls_element_to_string(struct sbuf *sb, struct mac_mls_element *element)
507 {
508 int i, first;
509
510 switch (element->mme_type) {
511 case MAC_MLS_TYPE_HIGH:
512 return (sbuf_printf(sb, "high"));
513
514 case MAC_MLS_TYPE_LOW:
515 return (sbuf_printf(sb, "low"));
516
517 case MAC_MLS_TYPE_EQUAL:
518 return (sbuf_printf(sb, "equal"));
519
520 case MAC_MLS_TYPE_LEVEL:
521 if (sbuf_printf(sb, "%d", element->mme_level) == -1)
522 return (-1);
523
524 first = 1;
525 for (i = 1; i <= MAC_MLS_MAX_COMPARTMENTS; i++) {
526 if (MAC_MLS_BIT_TEST(i, element->mme_compartments)) {
527 if (first) {
528 if (sbuf_putc(sb, ':') == -1)
529 return (-1);
530 if (sbuf_printf(sb, "%d", i) == -1)
531 return (-1);
532 first = 0;
533 } else {
534 if (sbuf_printf(sb, "+%d", i) == -1)
535 return (-1);
536 }
537 }
538 }
539 return (0);
540
541 default:
542 panic("mac_mls_element_to_string: invalid type (%d)",
543 element->mme_type);
544 }
545 }
546
547 /*
548 * mac_mls_to_string() converts an MLS label to a string, and places
549 * the results in the passed sbuf. It returns 0 on success, or EINVAL
550 * if there isn't room in the sbuf. Note: the sbuf will be modified
551 * even in a failure case, so the caller may need to revert the sbuf
552 * by restoring the offset if that's undesired.
553 */
554 static int
555 mac_mls_to_string(struct sbuf *sb, struct mac_mls *mac_mls)
556 {
557
558 if (mac_mls->mm_flags & MAC_MLS_FLAG_EFFECTIVE) {
559 if (mac_mls_element_to_string(sb, &mac_mls->mm_effective)
560 == -1)
561 return (EINVAL);
562 }
563
564 if (mac_mls->mm_flags & MAC_MLS_FLAG_RANGE) {
565 if (sbuf_putc(sb, '(') == -1)
566 return (EINVAL);
567
568 if (mac_mls_element_to_string(sb, &mac_mls->mm_rangelow)
569 == -1)
570 return (EINVAL);
571
572 if (sbuf_putc(sb, '-') == -1)
573 return (EINVAL);
574
575 if (mac_mls_element_to_string(sb, &mac_mls->mm_rangehigh)
576 == -1)
577 return (EINVAL);
578
579 if (sbuf_putc(sb, ')') == -1)
580 return (EINVAL);
581 }
582
583 return (0);
584 }
585
586 static int
587 mac_mls_externalize_label(struct label *label, char *element_name,
588 struct sbuf *sb, int *claimed)
589 {
590 struct mac_mls *mac_mls;
591
592 if (strcmp(MAC_MLS_LABEL_NAME, element_name) != 0)
593 return (0);
594
595 (*claimed)++;
596
597 mac_mls = SLOT(label);
598
599 return (mac_mls_to_string(sb, mac_mls));
600 }
601
602 static int
603 mac_mls_parse_element(struct mac_mls_element *element, char *string)
604 {
605 char *compartment, *end, *level;
606 int value;
607
608 if (strcmp(string, "high") == 0 ||
609 strcmp(string, "hi") == 0) {
610 element->mme_type = MAC_MLS_TYPE_HIGH;
611 element->mme_level = MAC_MLS_TYPE_UNDEF;
612 } else if (strcmp(string, "low") == 0 ||
613 strcmp(string, "lo") == 0) {
614 element->mme_type = MAC_MLS_TYPE_LOW;
615 element->mme_level = MAC_MLS_TYPE_UNDEF;
616 } else if (strcmp(string, "equal") == 0 ||
617 strcmp(string, "eq") == 0) {
618 element->mme_type = MAC_MLS_TYPE_EQUAL;
619 element->mme_level = MAC_MLS_TYPE_UNDEF;
620 } else {
621 element->mme_type = MAC_MLS_TYPE_LEVEL;
622
623 /*
624 * Numeric level piece of the element.
625 */
626 level = strsep(&string, ":");
627 value = strtol(level, &end, 10);
628 if (end == level || *end != '\0')
629 return (EINVAL);
630 if (value < 0 || value > 65535)
631 return (EINVAL);
632 element->mme_level = value;
633
634 /*
635 * Optional compartment piece of the element. If none
636 * are included, we assume that the label has no
637 * compartments.
638 */
639 if (string == NULL)
640 return (0);
641 if (*string == '\0')
642 return (0);
643
644 while ((compartment = strsep(&string, "+")) != NULL) {
645 value = strtol(compartment, &end, 10);
646 if (compartment == end || *end != '\0')
647 return (EINVAL);
648 if (value < 1 || value > MAC_MLS_MAX_COMPARTMENTS)
649 return (EINVAL);
650 MAC_MLS_BIT_SET(value, element->mme_compartments);
651 }
652 }
653
654 return (0);
655 }
656
657 /*
658 * Note: destructively consumes the string, make a local copy before
659 * calling if that's a problem.
660 */
661 static int
662 mac_mls_parse(struct mac_mls *mac_mls, char *string)
663 {
664 char *rangehigh, *rangelow, *effective;
665 int error;
666
667 effective = strsep(&string, "(");
668 if (*effective == '\0')
669 effective = NULL;
670
671 if (string != NULL) {
672 rangelow = strsep(&string, "-");
673 if (string == NULL)
674 return (EINVAL);
675 rangehigh = strsep(&string, ")");
676 if (string == NULL)
677 return (EINVAL);
678 if (*string != '\0')
679 return (EINVAL);
680 } else {
681 rangelow = NULL;
682 rangehigh = NULL;
683 }
684
685 KASSERT((rangelow != NULL && rangehigh != NULL) ||
686 (rangelow == NULL && rangehigh == NULL),
687 ("mac_mls_parse: range mismatch"));
688
689 bzero(mac_mls, sizeof(*mac_mls));
690 if (effective != NULL) {
691 error = mac_mls_parse_element(&mac_mls->mm_effective, effective);
692 if (error)
693 return (error);
694 mac_mls->mm_flags |= MAC_MLS_FLAG_EFFECTIVE;
695 }
696
697 if (rangelow != NULL) {
698 error = mac_mls_parse_element(&mac_mls->mm_rangelow,
699 rangelow);
700 if (error)
701 return (error);
702 error = mac_mls_parse_element(&mac_mls->mm_rangehigh,
703 rangehigh);
704 if (error)
705 return (error);
706 mac_mls->mm_flags |= MAC_MLS_FLAG_RANGE;
707 }
708
709 error = mac_mls_valid(mac_mls);
710 if (error)
711 return (error);
712
713 return (0);
714 }
715
716 static int
717 mac_mls_internalize_label(struct label *label, char *element_name,
718 char *element_data, int *claimed)
719 {
720 struct mac_mls *mac_mls, mac_mls_temp;
721 int error;
722
723 if (strcmp(MAC_MLS_LABEL_NAME, element_name) != 0)
724 return (0);
725
726 (*claimed)++;
727
728 error = mac_mls_parse(&mac_mls_temp, element_data);
729 if (error)
730 return (error);
731
732 mac_mls = SLOT(label);
733 *mac_mls = mac_mls_temp;
734
735 return (0);
736 }
737
738 static void
739 mac_mls_copy_label(struct label *src, struct label *dest)
740 {
741
742 *SLOT(dest) = *SLOT(src);
743 }
744
745 /*
746 * Labeling event operations: file system objects, and things that look
747 * a lot like file system objects.
748 */
749 static void
750 mac_mls_create_devfs_device(struct ucred *cred, struct mount *mp,
751 struct cdev *dev, struct devfs_dirent *devfs_dirent, struct label *label)
752 {
753 struct mac_mls *mac_mls;
754 int mls_type;
755
756 mac_mls = SLOT(label);
757 if (strcmp(dev->si_name, "null") == 0 ||
758 strcmp(dev->si_name, "zero") == 0 ||
759 strcmp(dev->si_name, "random") == 0 ||
760 strncmp(dev->si_name, "fd/", strlen("fd/")) == 0)
761 mls_type = MAC_MLS_TYPE_EQUAL;
762 else if (strcmp(dev->si_name, "kmem") == 0 ||
763 strcmp(dev->si_name, "mem") == 0)
764 mls_type = MAC_MLS_TYPE_HIGH;
765 else if (ptys_equal &&
766 (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 ||
767 strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0))
768 mls_type = MAC_MLS_TYPE_EQUAL;
769 else
770 mls_type = MAC_MLS_TYPE_LOW;
771 mac_mls_set_effective(mac_mls, mls_type, 0, NULL);
772 }
773
774 static void
775 mac_mls_create_devfs_directory(struct mount *mp, char *dirname,
776 int dirnamelen, struct devfs_dirent *devfs_dirent, struct label *label)
777 {
778 struct mac_mls *mac_mls;
779
780 mac_mls = SLOT(label);
781 mac_mls_set_effective(mac_mls, MAC_MLS_TYPE_LOW, 0, NULL);
782 }
783
784 static void
785 mac_mls_create_devfs_symlink(struct ucred *cred, struct mount *mp,
786 struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de,
787 struct label *delabel)
788 {
789 struct mac_mls *source, *dest;
790
791 source = SLOT(cred->cr_label);
792 dest = SLOT(delabel);
793
794 mac_mls_copy_effective(source, dest);
795 }
796
797 static void
798 mac_mls_create_mount(struct ucred *cred, struct mount *mp,
799 struct label *mntlabel, struct label *fslabel)
800 {
801 struct mac_mls *source, *dest;
802
803 source = SLOT(cred->cr_label);
804 dest = SLOT(mntlabel);
805 mac_mls_copy_effective(source, dest);
806 dest = SLOT(fslabel);
807 mac_mls_copy_effective(source, dest);
808 }
809
810 static void
811 mac_mls_relabel_vnode(struct ucred *cred, struct vnode *vp,
812 struct label *vnodelabel, struct label *label)
813 {
814 struct mac_mls *source, *dest;
815
816 source = SLOT(label);
817 dest = SLOT(vnodelabel);
818
819 mac_mls_copy(source, dest);
820 }
821
822 static void
823 mac_mls_update_devfsdirent(struct mount *mp,
824 struct devfs_dirent *devfs_dirent, struct label *direntlabel,
825 struct vnode *vp, struct label *vnodelabel)
826 {
827 struct mac_mls *source, *dest;
828
829 source = SLOT(vnodelabel);
830 dest = SLOT(direntlabel);
831
832 mac_mls_copy_effective(source, dest);
833 }
834
835 static void
836 mac_mls_associate_vnode_devfs(struct mount *mp, struct label *fslabel,
837 struct devfs_dirent *de, struct label *delabel, struct vnode *vp,
838 struct label *vlabel)
839 {
840 struct mac_mls *source, *dest;
841
842 source = SLOT(delabel);
843 dest = SLOT(vlabel);
844
845 mac_mls_copy_effective(source, dest);
846 }
847
848 static int
849 mac_mls_associate_vnode_extattr(struct mount *mp, struct label *fslabel,
850 struct vnode *vp, struct label *vlabel)
851 {
852 struct mac_mls temp, *source, *dest;
853 int buflen, error;
854
855 source = SLOT(fslabel);
856 dest = SLOT(vlabel);
857
858 buflen = sizeof(temp);
859 bzero(&temp, buflen);
860
861 error = vn_extattr_get(vp, IO_NODELOCKED, MAC_MLS_EXTATTR_NAMESPACE,
862 MAC_MLS_EXTATTR_NAME, &buflen, (char *) &temp, curthread);
863 if (error == ENOATTR || error == EOPNOTSUPP) {
864 /* Fall back to the fslabel. */
865 mac_mls_copy_effective(source, dest);
866 return (0);
867 } else if (error)
868 return (error);
869
870 if (buflen != sizeof(temp)) {
871 printf("mac_mls_associate_vnode_extattr: bad size %d\n",
872 buflen);
873 return (EPERM);
874 }
875 if (mac_mls_valid(&temp) != 0) {
876 printf("mac_mls_associate_vnode_extattr: invalid\n");
877 return (EPERM);
878 }
879 if ((temp.mm_flags & MAC_MLS_FLAGS_BOTH) != MAC_MLS_FLAG_EFFECTIVE) {
880 printf("mac_mls_associated_vnode_extattr: not effective\n");
881 return (EPERM);
882 }
883
884 mac_mls_copy_effective(&temp, dest);
885 return (0);
886 }
887
888 static void
889 mac_mls_associate_vnode_singlelabel(struct mount *mp,
890 struct label *fslabel, struct vnode *vp, struct label *vlabel)
891 {
892 struct mac_mls *source, *dest;
893
894 source = SLOT(fslabel);
895 dest = SLOT(vlabel);
896
897 mac_mls_copy_effective(source, dest);
898 }
899
900 static int
901 mac_mls_create_vnode_extattr(struct ucred *cred, struct mount *mp,
902 struct label *fslabel, struct vnode *dvp, struct label *dlabel,
903 struct vnode *vp, struct label *vlabel, struct componentname *cnp)
904 {
905 struct mac_mls *source, *dest, temp;
906 size_t buflen;
907 int error;
908
909 buflen = sizeof(temp);
910 bzero(&temp, buflen);
911
912 source = SLOT(cred->cr_label);
913 dest = SLOT(vlabel);
914 mac_mls_copy_effective(source, &temp);
915
916 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_MLS_EXTATTR_NAMESPACE,
917 MAC_MLS_EXTATTR_NAME, buflen, (char *) &temp, curthread);
918 if (error == 0)
919 mac_mls_copy_effective(source, dest);
920 return (error);
921 }
922
923 static int
924 mac_mls_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp,
925 struct label *vlabel, struct label *intlabel)
926 {
927 struct mac_mls *source, temp;
928 size_t buflen;
929 int error;
930
931 buflen = sizeof(temp);
932 bzero(&temp, buflen);
933
934 source = SLOT(intlabel);
935 if ((source->mm_flags & MAC_MLS_FLAG_EFFECTIVE) == 0)
936 return (0);
937
938 mac_mls_copy_effective(source, &temp);
939
940 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_MLS_EXTATTR_NAMESPACE,
941 MAC_MLS_EXTATTR_NAME, buflen, (char *) &temp, curthread);
942 return (error);
943 }
944
945 /*
946 * Labeling event operations: IPC object.
947 */
948 static void
949 mac_mls_create_inpcb_from_socket(struct socket *so, struct label *solabel,
950 struct inpcb *inp, struct label *inplabel)
951 {
952 struct mac_mls *source, *dest;
953
954 source = SLOT(solabel);
955 dest = SLOT(inplabel);
956
957 mac_mls_copy_effective(source, dest);
958 }
959
960 static void
961 mac_mls_create_mbuf_from_socket(struct socket *so, struct label *socketlabel,
962 struct mbuf *m, struct label *mbuflabel)
963 {
964 struct mac_mls *source, *dest;
965
966 source = SLOT(socketlabel);
967 dest = SLOT(mbuflabel);
968
969 mac_mls_copy_effective(source, dest);
970 }
971
972 static void
973 mac_mls_create_socket(struct ucred *cred, struct socket *socket,
974 struct label *socketlabel)
975 {
976 struct mac_mls *source, *dest;
977
978 source = SLOT(cred->cr_label);
979 dest = SLOT(socketlabel);
980
981 mac_mls_copy_effective(source, dest);
982 }
983
984 static void
985 mac_mls_create_pipe(struct ucred *cred, struct pipepair *pp,
986 struct label *pipelabel)
987 {
988 struct mac_mls *source, *dest;
989
990 source = SLOT(cred->cr_label);
991 dest = SLOT(pipelabel);
992
993 mac_mls_copy_effective(source, dest);
994 }
995
996 static void
997 mac_mls_create_posix_sem(struct ucred *cred, struct ksem *ksemptr,
998 struct label *ks_label)
999 {
1000 struct mac_mls *source, *dest;
1001
1002 source = SLOT(cred->cr_label);
1003 dest = SLOT(ks_label);
1004
1005 mac_mls_copy_effective(source, dest);
1006 }
1007
1008 static void
1009 mac_mls_create_socket_from_socket(struct socket *oldsocket,
1010 struct label *oldsocketlabel, struct socket *newsocket,
1011 struct label *newsocketlabel)
1012 {
1013 struct mac_mls *source, *dest;
1014
1015 source = SLOT(oldsocketlabel);
1016 dest = SLOT(newsocketlabel);
1017
1018 mac_mls_copy_effective(source, dest);
1019 }
1020
1021 static void
1022 mac_mls_relabel_socket(struct ucred *cred, struct socket *socket,
1023 struct label *socketlabel, struct label *newlabel)
1024 {
1025 struct mac_mls *source, *dest;
1026
1027 source = SLOT(newlabel);
1028 dest = SLOT(socketlabel);
1029
1030 mac_mls_copy(source, dest);
1031 }
1032
1033 static void
1034 mac_mls_relabel_pipe(struct ucred *cred, struct pipepair *pp,
1035 struct label *pipelabel, struct label *newlabel)
1036 {
1037 struct mac_mls *source, *dest;
1038
1039 source = SLOT(newlabel);
1040 dest = SLOT(pipelabel);
1041
1042 mac_mls_copy(source, dest);
1043 }
1044
1045 static void
1046 mac_mls_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel,
1047 struct socket *socket, struct label *socketpeerlabel)
1048 {
1049 struct mac_mls *source, *dest;
1050
1051 source = SLOT(mbuflabel);
1052 dest = SLOT(socketpeerlabel);
1053
1054 mac_mls_copy_effective(source, dest);
1055 }
1056
1057 /*
1058 * Labeling event operations: System V IPC objects.
1059 */
1060
1061 static void
1062 mac_mls_create_sysv_msgmsg(struct ucred *cred, struct msqid_kernel *msqkptr,
1063 struct label *msqlabel, struct msg *msgptr, struct label *msglabel)
1064 {
1065 struct mac_mls *source, *dest;
1066
1067 /* Ignore the msgq label */
1068 source = SLOT(cred->cr_label);
1069 dest = SLOT(msglabel);
1070
1071 mac_mls_copy_effective(source, dest);
1072 }
1073
1074 static void
1075 mac_mls_create_sysv_msgqueue(struct ucred *cred, struct msqid_kernel *msqkptr,
1076 struct label *msqlabel)
1077 {
1078 struct mac_mls *source, *dest;
1079
1080 source = SLOT(cred->cr_label);
1081 dest = SLOT(msqlabel);
1082
1083 mac_mls_copy_effective(source, dest);
1084 }
1085
1086 static void
1087 mac_mls_create_sysv_sem(struct ucred *cred, struct semid_kernel *semakptr,
1088 struct label *semalabel)
1089 {
1090 struct mac_mls *source, *dest;
1091
1092 source = SLOT(cred->cr_label);
1093 dest = SLOT(semalabel);
1094
1095 mac_mls_copy_effective(source, dest);
1096 }
1097
1098 static void
1099 mac_mls_create_sysv_shm(struct ucred *cred, struct shmid_kernel *shmsegptr,
1100 struct label *shmlabel)
1101 {
1102 struct mac_mls *source, *dest;
1103
1104 source = SLOT(cred->cr_label);
1105 dest = SLOT(shmlabel);
1106
1107 mac_mls_copy_effective(source, dest);
1108 }
1109
1110 /*
1111 * Labeling event operations: network objects.
1112 */
1113 static void
1114 mac_mls_set_socket_peer_from_socket(struct socket *oldsocket,
1115 struct label *oldsocketlabel, struct socket *newsocket,
1116 struct label *newsocketpeerlabel)
1117 {
1118 struct mac_mls *source, *dest;
1119
1120 source = SLOT(oldsocketlabel);
1121 dest = SLOT(newsocketpeerlabel);
1122
1123 mac_mls_copy_effective(source, dest);
1124 }
1125
1126 static void
1127 mac_mls_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d,
1128 struct label *bpflabel)
1129 {
1130 struct mac_mls *source, *dest;
1131
1132 source = SLOT(cred->cr_label);
1133 dest = SLOT(bpflabel);
1134
1135 mac_mls_copy_effective(source, dest);
1136 }
1137
1138 static void
1139 mac_mls_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel)
1140 {
1141 struct mac_mls *dest;
1142 int type;
1143
1144 dest = SLOT(ifnetlabel);
1145
1146 if (ifnet->if_type == IFT_LOOP)
1147 type = MAC_MLS_TYPE_EQUAL;
1148 else
1149 type = MAC_MLS_TYPE_LOW;
1150
1151 mac_mls_set_effective(dest, type, 0, NULL);
1152 mac_mls_set_range(dest, type, 0, NULL, type, 0, NULL);
1153 }
1154
1155 static void
1156 mac_mls_create_ipq(struct mbuf *fragment, struct label *fragmentlabel,
1157 struct ipq *ipq, struct label *ipqlabel)
1158 {
1159 struct mac_mls *source, *dest;
1160
1161 source = SLOT(fragmentlabel);
1162 dest = SLOT(ipqlabel);
1163
1164 mac_mls_copy_effective(source, dest);
1165 }
1166
1167 static void
1168 mac_mls_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel,
1169 struct mbuf *datagram, struct label *datagramlabel)
1170 {
1171 struct mac_mls *source, *dest;
1172
1173 source = SLOT(ipqlabel);
1174 dest = SLOT(datagramlabel);
1175
1176 /* Just use the head, since we require them all to match. */
1177 mac_mls_copy_effective(source, dest);
1178 }
1179
1180 static void
1181 mac_mls_create_fragment(struct mbuf *datagram, struct label *datagramlabel,
1182 struct mbuf *fragment, struct label *fragmentlabel)
1183 {
1184 struct mac_mls *source, *dest;
1185
1186 source = SLOT(datagramlabel);
1187 dest = SLOT(fragmentlabel);
1188
1189 mac_mls_copy_effective(source, dest);
1190 }
1191
1192 static void
1193 mac_mls_create_mbuf_from_inpcb(struct inpcb *inp, struct label *inplabel,
1194 struct mbuf *m, struct label *mlabel)
1195 {
1196 struct mac_mls *source, *dest;
1197
1198 source = SLOT(inplabel);
1199 dest = SLOT(mlabel);
1200
1201 mac_mls_copy_effective(source, dest);
1202 }
1203
1204 static void
1205 mac_mls_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel,
1206 struct mbuf *mbuf, struct label *mbuflabel)
1207 {
1208 struct mac_mls *dest;
1209
1210 dest = SLOT(mbuflabel);
1211
1212 mac_mls_set_effective(dest, MAC_MLS_TYPE_EQUAL, 0, NULL);
1213 }
1214
1215 static void
1216 mac_mls_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel,
1217 struct mbuf *mbuf, struct label *mbuflabel)
1218 {
1219 struct mac_mls *source, *dest;
1220
1221 source = SLOT(bpflabel);
1222 dest = SLOT(mbuflabel);
1223
1224 mac_mls_copy_effective(source, dest);
1225 }
1226
1227 static void
1228 mac_mls_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel,
1229 struct mbuf *m, struct label *mbuflabel)
1230 {
1231 struct mac_mls *source, *dest;
1232
1233 source = SLOT(ifnetlabel);
1234 dest = SLOT(mbuflabel);
1235
1236 mac_mls_copy_effective(source, dest);
1237 }
1238
1239 static void
1240 mac_mls_create_mbuf_multicast_encap(struct mbuf *oldmbuf,
1241 struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel,
1242 struct mbuf *newmbuf, struct label *newmbuflabel)
1243 {
1244 struct mac_mls *source, *dest;
1245
1246 source = SLOT(oldmbuflabel);
1247 dest = SLOT(newmbuflabel);
1248
1249 mac_mls_copy_effective(source, dest);
1250 }
1251
1252 static void
1253 mac_mls_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel,
1254 struct mbuf *newmbuf, struct label *newmbuflabel)
1255 {
1256 struct mac_mls *source, *dest;
1257
1258 source = SLOT(oldmbuflabel);
1259 dest = SLOT(newmbuflabel);
1260
1261 mac_mls_copy_effective(source, dest);
1262 }
1263
1264 static int
1265 mac_mls_fragment_match(struct mbuf *fragment, struct label *fragmentlabel,
1266 struct ipq *ipq, struct label *ipqlabel)
1267 {
1268 struct mac_mls *a, *b;
1269
1270 a = SLOT(ipqlabel);
1271 b = SLOT(fragmentlabel);
1272
1273 return (mac_mls_equal_effective(a, b));
1274 }
1275
1276 static void
1277 mac_mls_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet,
1278 struct label *ifnetlabel, struct label *newlabel)
1279 {
1280 struct mac_mls *source, *dest;
1281
1282 source = SLOT(newlabel);
1283 dest = SLOT(ifnetlabel);
1284
1285 mac_mls_copy(source, dest);
1286 }
1287
1288 static void
1289 mac_mls_update_ipq(struct mbuf *fragment, struct label *fragmentlabel,
1290 struct ipq *ipq, struct label *ipqlabel)
1291 {
1292
1293 /* NOOP: we only accept matching labels, so no need to update */
1294 }
1295
1296 static void
1297 mac_mls_inpcb_sosetlabel(struct socket *so, struct label *solabel,
1298 struct inpcb *inp, struct label *inplabel)
1299 {
1300 struct mac_mls *source, *dest;
1301
1302 source = SLOT(solabel);
1303 dest = SLOT(inplabel);
1304
1305 mac_mls_copy(source, dest);
1306 }
1307
1308 static void
1309 mac_mls_create_mbuf_from_firewall(struct mbuf *m, struct label *mbuflabel)
1310 {
1311 struct mac_mls *dest;
1312
1313 dest = SLOT(mbuflabel);
1314
1315 /* XXX: where is the label for the firewall really comming from? */
1316 mac_mls_set_effective(dest, MAC_MLS_TYPE_EQUAL, 0, NULL);
1317 }
1318
1319 /*
1320 * Labeling event operations: processes.
1321 */
1322 static void
1323 mac_mls_create_proc0(struct ucred *cred)
1324 {
1325 struct mac_mls *dest;
1326
1327 dest = SLOT(cred->cr_label);
1328
1329 mac_mls_set_effective(dest, MAC_MLS_TYPE_EQUAL, 0, NULL);
1330 mac_mls_set_range(dest, MAC_MLS_TYPE_LOW, 0, NULL, MAC_MLS_TYPE_HIGH,
1331 0, NULL);
1332 }
1333
1334 static void
1335 mac_mls_create_proc1(struct ucred *cred)
1336 {
1337 struct mac_mls *dest;
1338
1339 dest = SLOT(cred->cr_label);
1340
1341 mac_mls_set_effective(dest, MAC_MLS_TYPE_LOW, 0, NULL);
1342 mac_mls_set_range(dest, MAC_MLS_TYPE_LOW, 0, NULL, MAC_MLS_TYPE_HIGH,
1343 0, NULL);
1344 }
1345
1346 static void
1347 mac_mls_relabel_cred(struct ucred *cred, struct label *newlabel)
1348 {
1349 struct mac_mls *source, *dest;
1350
1351 source = SLOT(newlabel);
1352 dest = SLOT(cred->cr_label);
1353
1354 mac_mls_copy(source, dest);
1355 }
1356
1357 /*
1358 * Label cleanup/flush operations.
1359 */
1360 static void
1361 mac_mls_cleanup_sysv_msgmsg(struct label *msglabel)
1362 {
1363
1364 bzero(SLOT(msglabel), sizeof(struct mac_mls));
1365 }
1366
1367 static void
1368 mac_mls_cleanup_sysv_msgqueue(struct label *msqlabel)
1369 {
1370
1371 bzero(SLOT(msqlabel), sizeof(struct mac_mls));
1372 }
1373
1374 static void
1375 mac_mls_cleanup_sysv_sem(struct label *semalabel)
1376 {
1377
1378 bzero(SLOT(semalabel), sizeof(struct mac_mls));
1379 }
1380
1381 static void
1382 mac_mls_cleanup_sysv_shm(struct label *shmlabel)
1383 {
1384
1385 bzero(SLOT(shmlabel), sizeof(struct mac_mls));
1386 }
1387
1388 /*
1389 * Access control checks.
1390 */
1391 static int
1392 mac_mls_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel,
1393 struct ifnet *ifnet, struct label *ifnetlabel)
1394 {
1395 struct mac_mls *a, *b;
1396
1397 if (!mac_mls_enabled)
1398 return (0);
1399
1400 a = SLOT(bpflabel);
1401 b = SLOT(ifnetlabel);
1402
1403 if (mac_mls_equal_effective(a, b))
1404 return (0);
1405 return (EACCES);
1406 }
1407
1408 static int
1409 mac_mls_check_cred_relabel(struct ucred *cred, struct label *newlabel)
1410 {
1411 struct mac_mls *subj, *new;
1412 int error;
1413
1414 subj = SLOT(cred->cr_label);
1415 new = SLOT(newlabel);
1416
1417 /*
1418 * If there is an MLS label update for the credential, it may be
1419 * an update of effective, range, or both.
1420 */
1421 error = mls_atmostflags(new, MAC_MLS_FLAGS_BOTH);
1422 if (error)
1423 return (error);
1424
1425 /*
1426 * If the MLS label is to be changed, authorize as appropriate.
1427 */
1428 if (new->mm_flags & MAC_MLS_FLAGS_BOTH) {
1429 /*
1430 * If the change request modifies both the MLS label effective
1431 * and range, check that the new effective will be in the
1432 * new range.
1433 */
1434 if ((new->mm_flags & MAC_MLS_FLAGS_BOTH) ==
1435 MAC_MLS_FLAGS_BOTH &&
1436 !mac_mls_effective_in_range(new, new))
1437 return (EINVAL);
1438
1439 /*
1440 * To change the MLS effective label on a credential, the
1441 * new effective label must be in the current range.
1442 */
1443 if (new->mm_flags & MAC_MLS_FLAG_EFFECTIVE &&
1444 !mac_mls_effective_in_range(new, subj))
1445 return (EPERM);
1446
1447 /*
1448 * To change the MLS range label on a credential, the
1449 * new range must be in the current range.
1450 */
1451 if (new->mm_flags & MAC_MLS_FLAG_RANGE &&
1452 !mac_mls_range_in_range(new, subj))
1453 return (EPERM);
1454
1455 /*
1456 * To have EQUAL in any component of the new credential
1457 * MLS label, the subject must already have EQUAL in
1458 * their label.
1459 */
1460 if (mac_mls_contains_equal(new)) {
1461 error = mac_mls_subject_privileged(subj);
1462 if (error)
1463 return (error);
1464 }
1465 }
1466
1467 return (0);
1468 }
1469
1470 static int
1471 mac_mls_check_cred_visible(struct ucred *u1, struct ucred *u2)
1472 {
1473 struct mac_mls *subj, *obj;
1474
1475 if (!mac_mls_enabled)
1476 return (0);
1477
1478 subj = SLOT(u1->cr_label);
1479 obj = SLOT(u2->cr_label);
1480
1481 /* XXX: range */
1482 if (!mac_mls_dominate_effective(subj, obj))
1483 return (ESRCH);
1484
1485 return (0);
1486 }
1487
1488 static int
1489 mac_mls_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet,
1490 struct label *ifnetlabel, struct label *newlabel)
1491 {
1492 struct mac_mls *subj, *new;
1493 int error;
1494
1495 subj = SLOT(cred->cr_label);
1496 new = SLOT(newlabel);
1497
1498 /*
1499 * If there is an MLS label update for the interface, it may
1500 * be an update of effective, range, or both.
1501 */
1502 error = mls_atmostflags(new, MAC_MLS_FLAGS_BOTH);
1503 if (error)
1504 return (error);
1505
1506 /*
1507 * Relabeling network interfaces requires MLS privilege.
1508 */
1509 error = mac_mls_subject_privileged(subj);
1510
1511 return (0);
1512 }
1513
1514 static int
1515 mac_mls_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel,
1516 struct mbuf *m, struct label *mbuflabel)
1517 {
1518 struct mac_mls *p, *i;
1519
1520 if (!mac_mls_enabled)
1521 return (0);
1522
1523 p = SLOT(mbuflabel);
1524 i = SLOT(ifnetlabel);
1525
1526 return (mac_mls_effective_in_range(p, i) ? 0 : EACCES);
1527 }
1528
1529 static int
1530 mac_mls_check_inpcb_deliver(struct inpcb *inp, struct label *inplabel,
1531 struct mbuf *m, struct label *mlabel)
1532 {
1533 struct mac_mls *p, *i;
1534
1535 if (!mac_mls_enabled)
1536 return (0);
1537
1538 p = SLOT(mlabel);
1539 i = SLOT(inplabel);
1540
1541 return (mac_mls_equal_effective(p, i) ? 0 : EACCES);
1542 }
1543
1544 static int
1545 mac_mls_check_sysv_msgrcv(struct ucred *cred, struct msg *msgptr,
1546 struct label *msglabel)
1547 {
1548 struct mac_mls *subj, *obj;
1549
1550 if (!mac_mls_enabled)
1551 return (0);
1552
1553 subj = SLOT(cred->cr_label);
1554 obj = SLOT(msglabel);
1555
1556 if (!mac_mls_dominate_effective(subj, obj))
1557 return (EACCES);
1558
1559 return (0);
1560 }
1561
1562 static int
1563 mac_mls_check_sysv_msgrmid(struct ucred *cred, struct msg *msgptr,
1564 struct label *msglabel)
1565 {
1566 struct mac_mls *subj, *obj;
1567
1568 if (!mac_mls_enabled)
1569 return (0);
1570
1571 subj = SLOT(cred->cr_label);
1572 obj = SLOT(msglabel);
1573
1574 if (!mac_mls_dominate_effective(obj, subj))
1575 return (EACCES);
1576
1577 return (0);
1578 }
1579
1580 static int
1581 mac_mls_check_sysv_msqget(struct ucred *cred, struct msqid_kernel *msqkptr,
1582 struct label *msqklabel)
1583 {
1584 struct mac_mls *subj, *obj;
1585
1586 if (!mac_mls_enabled)
1587 return (0);
1588
1589 subj = SLOT(cred->cr_label);
1590 obj = SLOT(msqklabel);
1591
1592 if (!mac_mls_dominate_effective(subj, obj))
1593 return (EACCES);
1594
1595 return (0);
1596 }
1597
1598 static int
1599 mac_mls_check_sysv_msqsnd(struct ucred *cred, struct msqid_kernel *msqkptr,
1600 struct label *msqklabel)
1601 {
1602 struct mac_mls *subj, *obj;
1603
1604 if (!mac_mls_enabled)
1605 return (0);
1606
1607 subj = SLOT(cred->cr_label);
1608 obj = SLOT(msqklabel);
1609
1610 if (!mac_mls_dominate_effective(obj, subj))
1611 return (EACCES);
1612
1613 return (0);
1614 }
1615
1616 static int
1617 mac_mls_check_sysv_msqrcv(struct ucred *cred, struct msqid_kernel *msqkptr,
1618 struct label *msqklabel)
1619 {
1620 struct mac_mls *subj, *obj;
1621
1622 if (!mac_mls_enabled)
1623 return (0);
1624
1625 subj = SLOT(cred->cr_label);
1626 obj = SLOT(msqklabel);
1627
1628 if (!mac_mls_dominate_effective(subj, obj))
1629 return (EACCES);
1630
1631 return (0);
1632 }
1633
1634 static int
1635 mac_mls_check_sysv_msqctl(struct ucred *cred, struct msqid_kernel *msqkptr,
1636 struct label *msqklabel, int cmd)
1637 {
1638 struct mac_mls *subj, *obj;
1639
1640 if (!mac_mls_enabled)
1641 return (0);
1642
1643 subj = SLOT(cred->cr_label);
1644 obj = SLOT(msqklabel);
1645
1646 switch(cmd) {
1647 case IPC_RMID:
1648 case IPC_SET:
1649 if (!mac_mls_dominate_effective(obj, subj))
1650 return (EACCES);
1651 break;
1652
1653 case IPC_STAT:
1654 if (!mac_mls_dominate_effective(subj, obj))
1655 return (EACCES);
1656 break;
1657
1658 default:
1659 return (EACCES);
1660 }
1661
1662 return (0);
1663 }
1664
1665 static int
1666 mac_mls_check_sysv_semctl(struct ucred *cred, struct semid_kernel *semakptr,
1667 struct label *semaklabel, int cmd)
1668 {
1669 struct mac_mls *subj, *obj;
1670
1671 if (!mac_mls_enabled)
1672 return (0);
1673
1674 subj = SLOT(cred->cr_label);
1675 obj = SLOT(semaklabel);
1676
1677 switch(cmd) {
1678 case IPC_RMID:
1679 case IPC_SET:
1680 case SETVAL:
1681 case SETALL:
1682 if (!mac_mls_dominate_effective(obj, subj))
1683 return (EACCES);
1684 break;
1685
1686 case IPC_STAT:
1687 case GETVAL:
1688 case GETPID:
1689 case GETNCNT:
1690 case GETZCNT:
1691 case GETALL:
1692 if (!mac_mls_dominate_effective(subj, obj))
1693 return (EACCES);
1694 break;
1695
1696 default:
1697 return (EACCES);
1698 }
1699
1700 return (0);
1701 }
1702
1703 static int
1704 mac_mls_check_sysv_semget(struct ucred *cred, struct semid_kernel *semakptr,
1705 struct label *semaklabel)
1706 {
1707 struct mac_mls *subj, *obj;
1708
1709 if (!mac_mls_enabled)
1710 return (0);
1711
1712 subj = SLOT(cred->cr_label);
1713 obj = SLOT(semaklabel);
1714
1715 if (!mac_mls_dominate_effective(subj, obj))
1716 return (EACCES);
1717
1718 return (0);
1719 }
1720
1721 static int
1722 mac_mls_check_sysv_semop(struct ucred *cred, struct semid_kernel *semakptr,
1723 struct label *semaklabel, size_t accesstype)
1724 {
1725 struct mac_mls *subj, *obj;
1726
1727 if (!mac_mls_enabled)
1728 return (0);
1729
1730 subj = SLOT(cred->cr_label);
1731 obj = SLOT(semaklabel);
1732
1733 if( accesstype & SEM_R )
1734 if (!mac_mls_dominate_effective(subj, obj))
1735 return (EACCES);
1736
1737 if( accesstype & SEM_A )
1738 if (!mac_mls_dominate_effective(obj, subj))
1739 return (EACCES);
1740
1741 return (0);
1742 }
1743
1744 static int
1745 mac_mls_check_sysv_shmat(struct ucred *cred, struct shmid_kernel *shmsegptr,
1746 struct label *shmseglabel, int shmflg)
1747 {
1748 struct mac_mls *subj, *obj;
1749
1750 if (!mac_mls_enabled)
1751 return (0);
1752
1753 subj = SLOT(cred->cr_label);
1754 obj = SLOT(shmseglabel);
1755
1756 if (!mac_mls_dominate_effective(subj, obj))
1757 return (EACCES);
1758 if ((shmflg & SHM_RDONLY) == 0)
1759 if (!mac_mls_dominate_effective(obj, subj))
1760 return (EACCES);
1761
1762 return (0);
1763 }
1764
1765 static int
1766 mac_mls_check_sysv_shmctl(struct ucred *cred, struct shmid_kernel *shmsegptr,
1767 struct label *shmseglabel, int cmd)
1768 {
1769 struct mac_mls *subj, *obj;
1770
1771 if (!mac_mls_enabled)
1772 return (0);
1773
1774 subj = SLOT(cred->cr_label);
1775 obj = SLOT(shmseglabel);
1776
1777 switch(cmd) {
1778 case IPC_RMID:
1779 case IPC_SET:
1780 if (!mac_mls_dominate_effective(obj, subj))
1781 return (EACCES);
1782 break;
1783
1784 case IPC_STAT:
1785 case SHM_STAT:
1786 if (!mac_mls_dominate_effective(subj, obj))
1787 return (EACCES);
1788 break;
1789
1790 default:
1791 return (EACCES);
1792 }
1793
1794 return (0);
1795 }
1796
1797 static int
1798 mac_mls_check_sysv_shmget(struct ucred *cred, struct shmid_kernel *shmsegptr,
1799 struct label *shmseglabel, int shmflg)
1800 {
1801 struct mac_mls *subj, *obj;
1802
1803 if (!mac_mls_enabled)
1804 return (0);
1805
1806 subj = SLOT(cred->cr_label);
1807 obj = SLOT(shmseglabel);
1808
1809 if (!mac_mls_dominate_effective(obj, subj))
1810 return (EACCES);
1811
1812 return (0);
1813 }
1814
1815 static int
1816 mac_mls_check_mount_stat(struct ucred *cred, struct mount *mp,
1817 struct label *mntlabel)
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(mntlabel);
1826
1827 if (!mac_mls_dominate_effective(subj, obj))
1828 return (EACCES);
1829
1830 return (0);
1831 }
1832
1833 static int
1834 mac_mls_check_pipe_ioctl(struct ucred *cred, struct pipepair *pp,
1835 struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data)
1836 {
1837
1838 if(!mac_mls_enabled)
1839 return (0);
1840
1841 /* XXX: This will be implemented soon... */
1842
1843 return (0);
1844 }
1845
1846 static int
1847 mac_mls_check_pipe_poll(struct ucred *cred, struct pipepair *pp,
1848 struct label *pipelabel)
1849 {
1850 struct mac_mls *subj, *obj;
1851
1852 if (!mac_mls_enabled)
1853 return (0);
1854
1855 subj = SLOT(cred->cr_label);
1856 obj = SLOT((pipelabel));
1857
1858 if (!mac_mls_dominate_effective(subj, obj))
1859 return (EACCES);
1860
1861 return (0);
1862 }
1863
1864 static int
1865 mac_mls_check_pipe_read(struct ucred *cred, struct pipepair *pp,
1866 struct label *pipelabel)
1867 {
1868 struct mac_mls *subj, *obj;
1869
1870 if (!mac_mls_enabled)
1871 return (0);
1872
1873 subj = SLOT(cred->cr_label);
1874 obj = SLOT((pipelabel));
1875
1876 if (!mac_mls_dominate_effective(subj, obj))
1877 return (EACCES);
1878
1879 return (0);
1880 }
1881
1882 static int
1883 mac_mls_check_pipe_relabel(struct ucred *cred, struct pipepair *pp,
1884 struct label *pipelabel, struct label *newlabel)
1885 {
1886 struct mac_mls *subj, *obj, *new;
1887 int error;
1888
1889 new = SLOT(newlabel);
1890 subj = SLOT(cred->cr_label);
1891 obj = SLOT(pipelabel);
1892
1893 /*
1894 * If there is an MLS label update for a pipe, it must be a
1895 * effective update.
1896 */
1897 error = mls_atmostflags(new, MAC_MLS_FLAG_EFFECTIVE);
1898 if (error)
1899 return (error);
1900
1901 /*
1902 * To perform a relabel of a pipe (MLS label or not), MLS must
1903 * authorize the relabel.
1904 */
1905 if (!mac_mls_effective_in_range(obj, subj))
1906 return (EPERM);
1907
1908 /*
1909 * If the MLS label is to be changed, authorize as appropriate.
1910 */
1911 if (new->mm_flags & MAC_MLS_FLAG_EFFECTIVE) {
1912 /*
1913 * To change the MLS label on a pipe, the new pipe label
1914 * must be in the subject range.
1915 */
1916 if (!mac_mls_effective_in_range(new, subj))
1917 return (EPERM);
1918
1919 /*
1920 * To change the MLS label on a pipe to be EQUAL, the
1921 * subject must have appropriate privilege.
1922 */
1923 if (mac_mls_contains_equal(new)) {
1924 error = mac_mls_subject_privileged(subj);
1925 if (error)
1926 return (error);
1927 }
1928 }
1929
1930 return (0);
1931 }
1932
1933 static int
1934 mac_mls_check_pipe_stat(struct ucred *cred, struct pipepair *pp,
1935 struct label *pipelabel)
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((pipelabel));
1944
1945 if (!mac_mls_dominate_effective(subj, obj))
1946 return (EACCES);
1947
1948 return (0);
1949 }
1950
1951 static int
1952 mac_mls_check_pipe_write(struct ucred *cred, struct pipepair *pp,
1953 struct label *pipelabel)
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((pipelabel));
1962
1963 if (!mac_mls_dominate_effective(obj, subj))
1964 return (EACCES);
1965
1966 return (0);
1967 }
1968
1969 static int
1970 mac_mls_check_posix_sem_write(struct ucred *cred, struct ksem *ksemptr,
1971 struct label *ks_label)
1972 {
1973 struct mac_mls *subj, *obj;
1974
1975 if (!mac_mls_enabled)
1976 return (0);
1977
1978 subj = SLOT(cred->cr_label);
1979 obj = SLOT(ks_label);
1980
1981 if (!mac_mls_dominate_effective(obj, subj))
1982 return (EACCES);
1983
1984 return (0);
1985 }
1986
1987 static int
1988 mac_mls_check_posix_sem_rdonly(struct ucred *cred, struct ksem *ksemptr,
1989 struct label *ks_label)
1990 {
1991 struct mac_mls *subj, *obj;
1992
1993 if (!mac_mls_enabled)
1994 return (0);
1995
1996 subj = SLOT(cred->cr_label);
1997 obj = SLOT(ks_label);
1998
1999 if (!mac_mls_dominate_effective(subj, obj))
2000 return (EACCES);
2001
2002 return (0);
2003 }
2004
2005 static int
2006 mac_mls_check_proc_debug(struct ucred *cred, struct proc *proc)
2007 {
2008 struct mac_mls *subj, *obj;
2009
2010 if (!mac_mls_enabled)
2011 return (0);
2012
2013 subj = SLOT(cred->cr_label);
2014 obj = SLOT(proc->p_ucred->cr_label);
2015
2016 /* XXX: range checks */
2017 if (!mac_mls_dominate_effective(subj, obj))
2018 return (ESRCH);
2019 if (!mac_mls_dominate_effective(obj, subj))
2020 return (EACCES);
2021
2022 return (0);
2023 }
2024
2025 static int
2026 mac_mls_check_proc_sched(struct ucred *cred, struct proc *proc)
2027 {
2028 struct mac_mls *subj, *obj;
2029
2030 if (!mac_mls_enabled)
2031 return (0);
2032
2033 subj = SLOT(cred->cr_label);
2034 obj = SLOT(proc->p_ucred->cr_label);
2035
2036 /* XXX: range checks */
2037 if (!mac_mls_dominate_effective(subj, obj))
2038 return (ESRCH);
2039 if (!mac_mls_dominate_effective(obj, subj))
2040 return (EACCES);
2041
2042 return (0);
2043 }
2044
2045 static int
2046 mac_mls_check_proc_signal(struct ucred *cred, struct proc *proc, int signum)
2047 {
2048 struct mac_mls *subj, *obj;
2049
2050 if (!mac_mls_enabled)
2051 return (0);
2052
2053 subj = SLOT(cred->cr_label);
2054 obj = SLOT(proc->p_ucred->cr_label);
2055
2056 /* XXX: range checks */
2057 if (!mac_mls_dominate_effective(subj, obj))
2058 return (ESRCH);
2059 if (!mac_mls_dominate_effective(obj, subj))
2060 return (EACCES);
2061
2062 return (0);
2063 }
2064
2065 static int
2066 mac_mls_check_socket_deliver(struct socket *so, struct label *socketlabel,
2067 struct mbuf *m, struct label *mbuflabel)
2068 {
2069 struct mac_mls *p, *s;
2070
2071 if (!mac_mls_enabled)
2072 return (0);
2073
2074 p = SLOT(mbuflabel);
2075 s = SLOT(socketlabel);
2076
2077 return (mac_mls_equal_effective(p, s) ? 0 : EACCES);
2078 }
2079
2080 static int
2081 mac_mls_check_socket_relabel(struct ucred *cred, struct socket *socket,
2082 struct label *socketlabel, struct label *newlabel)
2083 {
2084 struct mac_mls *subj, *obj, *new;
2085 int error;
2086
2087 new = SLOT(newlabel);
2088 subj = SLOT(cred->cr_label);
2089 obj = SLOT(socketlabel);
2090
2091 /*
2092 * If there is an MLS label update for the socket, it may be
2093 * an update of effective.
2094 */
2095 error = mls_atmostflags(new, MAC_MLS_FLAG_EFFECTIVE);
2096 if (error)
2097 return (error);
2098
2099 /*
2100 * To relabel a socket, the old socket effective must be in the subject
2101 * range.
2102 */
2103 if (!mac_mls_effective_in_range(obj, subj))
2104 return (EPERM);
2105
2106 /*
2107 * If the MLS label is to be changed, authorize as appropriate.
2108 */
2109 if (new->mm_flags & MAC_MLS_FLAG_EFFECTIVE) {
2110 /*
2111 * To relabel a socket, the new socket effective must be in
2112 * the subject range.
2113 */
2114 if (!mac_mls_effective_in_range(new, subj))
2115 return (EPERM);
2116
2117 /*
2118 * To change the MLS label on the socket to contain EQUAL,
2119 * the subject must have appropriate privilege.
2120 */
2121 if (mac_mls_contains_equal(new)) {
2122 error = mac_mls_subject_privileged(subj);
2123 if (error)
2124 return (error);
2125 }
2126 }
2127
2128 return (0);
2129 }
2130
2131 static int
2132 mac_mls_check_socket_visible(struct ucred *cred, struct socket *socket,
2133 struct label *socketlabel)
2134 {
2135 struct mac_mls *subj, *obj;
2136
2137 if (!mac_mls_enabled)
2138 return (0);
2139
2140 subj = SLOT(cred->cr_label);
2141 obj = SLOT(socketlabel);
2142
2143 if (!mac_mls_dominate_effective(subj, obj))
2144 return (ENOENT);
2145
2146 return (0);
2147 }
2148
2149 static int
2150 mac_mls_check_system_swapon(struct ucred *cred, struct vnode *vp,
2151 struct label *label)
2152 {
2153 struct mac_mls *subj, *obj;
2154
2155 if (!mac_mls_enabled)
2156 return (0);
2157
2158 subj = SLOT(cred->cr_label);
2159 obj = SLOT(label);
2160
2161 if (!mac_mls_dominate_effective(obj, subj) ||
2162 !mac_mls_dominate_effective(subj, obj))
2163 return (EACCES);
2164
2165 return (0);
2166 }
2167
2168 static int
2169 mac_mls_check_vnode_chdir(struct ucred *cred, struct vnode *dvp,
2170 struct label *dlabel)
2171 {
2172 struct mac_mls *subj, *obj;
2173
2174 if (!mac_mls_enabled)
2175 return (0);
2176
2177 subj = SLOT(cred->cr_label);
2178 obj = SLOT(dlabel);
2179
2180 if (!mac_mls_dominate_effective(subj, obj))
2181 return (EACCES);
2182
2183 return (0);
2184 }
2185
2186 static int
2187 mac_mls_check_vnode_chroot(struct ucred *cred, struct vnode *dvp,
2188 struct label *dlabel)
2189 {
2190 struct mac_mls *subj, *obj;
2191
2192 if (!mac_mls_enabled)
2193 return (0);
2194
2195 subj = SLOT(cred->cr_label);
2196 obj = SLOT(dlabel);
2197
2198 if (!mac_mls_dominate_effective(subj, obj))
2199 return (EACCES);
2200
2201 return (0);
2202 }
2203
2204 static int
2205 mac_mls_check_vnode_create(struct ucred *cred, struct vnode *dvp,
2206 struct label *dlabel, struct componentname *cnp, struct vattr *vap)
2207 {
2208 struct mac_mls *subj, *obj;
2209
2210 if (!mac_mls_enabled)
2211 return (0);
2212
2213 subj = SLOT(cred->cr_label);
2214 obj = SLOT(dlabel);
2215
2216 if (!mac_mls_dominate_effective(obj, subj))
2217 return (EACCES);
2218
2219 return (0);
2220 }
2221
2222 static int
2223 mac_mls_check_vnode_delete(struct ucred *cred, struct vnode *dvp,
2224 struct label *dlabel, struct vnode *vp, struct label *label,
2225 struct componentname *cnp)
2226 {
2227 struct mac_mls *subj, *obj;
2228
2229 if (!mac_mls_enabled)
2230 return (0);
2231
2232 subj = SLOT(cred->cr_label);
2233 obj = SLOT(dlabel);
2234
2235 if (!mac_mls_dominate_effective(obj, subj))
2236 return (EACCES);
2237
2238 obj = SLOT(label);
2239
2240 if (!mac_mls_dominate_effective(obj, subj))
2241 return (EACCES);
2242
2243 return (0);
2244 }
2245
2246 static int
2247 mac_mls_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
2248 struct label *label, acl_type_t type)
2249 {
2250 struct mac_mls *subj, *obj;
2251
2252 if (!mac_mls_enabled)
2253 return (0);
2254
2255 subj = SLOT(cred->cr_label);
2256 obj = SLOT(label);
2257
2258 if (!mac_mls_dominate_effective(obj, subj))
2259 return (EACCES);
2260
2261 return (0);
2262 }
2263
2264 static int
2265 mac_mls_check_vnode_deleteextattr(struct ucred *cred, struct vnode *vp,
2266 struct label *label, int attrnamespace, const char *name)
2267 {
2268 struct mac_mls *subj, *obj;
2269
2270 if (!mac_mls_enabled)
2271 return (0);
2272
2273 subj = SLOT(cred->cr_label);
2274 obj = SLOT(label);
2275
2276 if (!mac_mls_dominate_effective(obj, subj))
2277 return (EACCES);
2278
2279 return (0);
2280 }
2281
2282 static int
2283 mac_mls_check_vnode_exec(struct ucred *cred, struct vnode *vp,
2284 struct label *label, struct image_params *imgp,
2285 struct label *execlabel)
2286 {
2287 struct mac_mls *subj, *obj, *exec;
2288 int error;
2289
2290 if (execlabel != NULL) {
2291 /*
2292 * We currently don't permit labels to be changed at
2293 * exec-time as part of MLS, so disallow non-NULL
2294 * MLS label elements in the execlabel.
2295 */
2296 exec = SLOT(execlabel);
2297 error = mls_atmostflags(exec, 0);
2298 if (error)
2299 return (error);
2300 }
2301
2302 if (!mac_mls_enabled)
2303 return (0);
2304
2305 subj = SLOT(cred->cr_label);
2306 obj = SLOT(label);
2307
2308 if (!mac_mls_dominate_effective(subj, obj))
2309 return (EACCES);
2310
2311 return (0);
2312 }
2313
2314 static int
2315 mac_mls_check_vnode_getacl(struct ucred *cred, struct vnode *vp,
2316 struct label *label, acl_type_t type)
2317 {
2318 struct mac_mls *subj, *obj;
2319
2320 if (!mac_mls_enabled)
2321 return (0);
2322
2323 subj = SLOT(cred->cr_label);
2324 obj = SLOT(label);
2325
2326 if (!mac_mls_dominate_effective(subj, obj))
2327 return (EACCES);
2328
2329 return (0);
2330 }
2331
2332 static int
2333 mac_mls_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
2334 struct label *label, int attrnamespace, const char *name, struct uio *uio)
2335 {
2336 struct mac_mls *subj, *obj;
2337
2338 if (!mac_mls_enabled)
2339 return (0);
2340
2341 subj = SLOT(cred->cr_label);
2342 obj = SLOT(label);
2343
2344 if (!mac_mls_dominate_effective(subj, obj))
2345 return (EACCES);
2346
2347 return (0);
2348 }
2349
2350 static int
2351 mac_mls_check_vnode_link(struct ucred *cred, struct vnode *dvp,
2352 struct label *dlabel, struct vnode *vp, struct label *label,
2353 struct componentname *cnp)
2354 {
2355 struct mac_mls *subj, *obj;
2356
2357 if (!mac_mls_enabled)
2358 return (0);
2359
2360 subj = SLOT(cred->cr_label);
2361 obj = SLOT(dlabel);
2362
2363 if (!mac_mls_dominate_effective(obj, subj))
2364 return (EACCES);
2365
2366 obj = SLOT(dlabel);
2367 if (!mac_mls_dominate_effective(obj, subj))
2368 return (EACCES);
2369
2370 return (0);
2371 }
2372
2373 static int
2374 mac_mls_check_vnode_listextattr(struct ucred *cred, struct vnode *vp,
2375 struct label *label, int attrnamespace)
2376 {
2377
2378 struct mac_mls *subj, *obj;
2379
2380 if (!mac_mls_enabled)
2381 return (0);
2382
2383 subj = SLOT(cred->cr_label);
2384 obj = SLOT(label);
2385
2386 if (!mac_mls_dominate_effective(subj, obj))
2387 return (EACCES);
2388
2389 return (0);
2390 }
2391
2392 static int
2393 mac_mls_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
2394 struct label *dlabel, struct componentname *cnp)
2395 {
2396 struct mac_mls *subj, *obj;
2397
2398 if (!mac_mls_enabled)
2399 return (0);
2400
2401 subj = SLOT(cred->cr_label);
2402 obj = SLOT(dlabel);
2403
2404 if (!mac_mls_dominate_effective(subj, obj))
2405 return (EACCES);
2406
2407 return (0);
2408 }
2409
2410 static int
2411 mac_mls_check_vnode_mmap(struct ucred *cred, struct vnode *vp,
2412 struct label *label, int prot, int flags)
2413 {
2414 struct mac_mls *subj, *obj;
2415
2416 /*
2417 * Rely on the use of open()-time protections to handle
2418 * non-revocation cases.
2419 */
2420 if (!mac_mls_enabled || !revocation_enabled)
2421 return (0);
2422
2423 subj = SLOT(cred->cr_label);
2424 obj = SLOT(label);
2425
2426 if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
2427 if (!mac_mls_dominate_effective(subj, obj))
2428 return (EACCES);
2429 }
2430 if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) {
2431 if (!mac_mls_dominate_effective(obj, subj))
2432 return (EACCES);
2433 }
2434
2435 return (0);
2436 }
2437
2438 static int
2439 mac_mls_check_vnode_open(struct ucred *cred, struct vnode *vp,
2440 struct label *vnodelabel, int acc_mode)
2441 {
2442 struct mac_mls *subj, *obj;
2443
2444 if (!mac_mls_enabled)
2445 return (0);
2446
2447 subj = SLOT(cred->cr_label);
2448 obj = SLOT(vnodelabel);
2449
2450 /* XXX privilege override for admin? */
2451 if (acc_mode & (VREAD | VEXEC | VSTAT)) {
2452 if (!mac_mls_dominate_effective(subj, obj))
2453 return (EACCES);
2454 }
2455 if (acc_mode & (VWRITE | VAPPEND | VADMIN)) {
2456 if (!mac_mls_dominate_effective(obj, subj))
2457 return (EACCES);
2458 }
2459
2460 return (0);
2461 }
2462
2463 static int
2464 mac_mls_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred,
2465 struct vnode *vp, struct label *label)
2466 {
2467 struct mac_mls *subj, *obj;
2468
2469 if (!mac_mls_enabled || !revocation_enabled)
2470 return (0);
2471
2472 subj = SLOT(active_cred->cr_label);
2473 obj = SLOT(label);
2474
2475 if (!mac_mls_dominate_effective(subj, obj))
2476 return (EACCES);
2477
2478 return (0);
2479 }
2480
2481 static int
2482 mac_mls_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
2483 struct vnode *vp, struct label *label)
2484 {
2485 struct mac_mls *subj, *obj;
2486
2487 if (!mac_mls_enabled || !revocation_enabled)
2488 return (0);
2489
2490 subj = SLOT(active_cred->cr_label);
2491 obj = SLOT(label);
2492
2493 if (!mac_mls_dominate_effective(subj, obj))
2494 return (EACCES);
2495
2496 return (0);
2497 }
2498
2499 static int
2500 mac_mls_check_vnode_readdir(struct ucred *cred, struct vnode *dvp,
2501 struct label *dlabel)
2502 {
2503 struct mac_mls *subj, *obj;
2504
2505 if (!mac_mls_enabled)
2506 return (0);
2507
2508 subj = SLOT(cred->cr_label);
2509 obj = SLOT(dlabel);
2510
2511 if (!mac_mls_dominate_effective(subj, obj))
2512 return (EACCES);
2513
2514 return (0);
2515 }
2516
2517 static int
2518 mac_mls_check_vnode_readlink(struct ucred *cred, struct vnode *vp,
2519 struct label *vnodelabel)
2520 {
2521 struct mac_mls *subj, *obj;
2522
2523 if (!mac_mls_enabled)
2524 return (0);
2525
2526 subj = SLOT(cred->cr_label);
2527 obj = SLOT(vnodelabel);
2528
2529 if (!mac_mls_dominate_effective(subj, obj))
2530 return (EACCES);
2531
2532 return (0);
2533 }
2534
2535 static int
2536 mac_mls_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
2537 struct label *vnodelabel, struct label *newlabel)
2538 {
2539 struct mac_mls *old, *new, *subj;
2540 int error;
2541
2542 old = SLOT(vnodelabel);
2543 new = SLOT(newlabel);
2544 subj = SLOT(cred->cr_label);
2545
2546 /*
2547 * If there is an MLS label update for the vnode, it must be a
2548 * effective label.
2549 */
2550 error = mls_atmostflags(new, MAC_MLS_FLAG_EFFECTIVE);
2551 if (error)
2552 return (error);
2553
2554 /*
2555 * To perform a relabel of the vnode (MLS label or not), MLS must
2556 * authorize the relabel.
2557 */
2558 if (!mac_mls_effective_in_range(old, subj))
2559 return (EPERM);
2560
2561 /*
2562 * If the MLS label is to be changed, authorize as appropriate.
2563 */
2564 if (new->mm_flags & MAC_MLS_FLAG_EFFECTIVE) {
2565 /*
2566 * To change the MLS label on a vnode, the new vnode label
2567 * must be in the subject range.
2568 */
2569 if (!mac_mls_effective_in_range(new, subj))
2570 return (EPERM);
2571
2572 /*
2573 * To change the MLS label on the vnode to be EQUAL,
2574 * the subject must have appropriate privilege.
2575 */
2576 if (mac_mls_contains_equal(new)) {
2577 error = mac_mls_subject_privileged(subj);
2578 if (error)
2579 return (error);
2580 }
2581 }
2582
2583 return (0);
2584 }
2585
2586
2587 static int
2588 mac_mls_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
2589 struct label *dlabel, struct vnode *vp, struct label *label,
2590 struct componentname *cnp)
2591 {
2592 struct mac_mls *subj, *obj;
2593
2594 if (!mac_mls_enabled)
2595 return (0);
2596
2597 subj = SLOT(cred->cr_label);
2598 obj = SLOT(dlabel);
2599
2600 if (!mac_mls_dominate_effective(obj, subj))
2601 return (EACCES);
2602
2603 obj = SLOT(label);
2604
2605 if (!mac_mls_dominate_effective(obj, subj))
2606 return (EACCES);
2607
2608 return (0);
2609 }
2610
2611 static int
2612 mac_mls_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
2613 struct label *dlabel, struct vnode *vp, struct label *label, int samedir,
2614 struct componentname *cnp)
2615 {
2616 struct mac_mls *subj, *obj;
2617
2618 if (!mac_mls_enabled)
2619 return (0);
2620
2621 subj = SLOT(cred->cr_label);
2622 obj = SLOT(dlabel);
2623
2624 if (!mac_mls_dominate_effective(obj, subj))
2625 return (EACCES);
2626
2627 if (vp != NULL) {
2628 obj = SLOT(label);
2629
2630 if (!mac_mls_dominate_effective(obj, subj))
2631 return (EACCES);
2632 }
2633
2634 return (0);
2635 }
2636
2637 static int
2638 mac_mls_check_vnode_revoke(struct ucred *cred, struct vnode *vp,
2639 struct label *label)
2640 {
2641 struct mac_mls *subj, *obj;
2642
2643 if (!mac_mls_enabled)
2644 return (0);
2645
2646 subj = SLOT(cred->cr_label);
2647 obj = SLOT(label);
2648
2649 if (!mac_mls_dominate_effective(obj, subj))
2650 return (EACCES);
2651
2652 return (0);
2653 }
2654
2655 static int
2656 mac_mls_check_vnode_setacl(struct ucred *cred, struct vnode *vp,
2657 struct label *label, acl_type_t type, struct acl *acl)
2658 {
2659 struct mac_mls *subj, *obj;
2660
2661 if (!mac_mls_enabled)
2662 return (0);
2663
2664 subj = SLOT(cred->cr_label);
2665 obj = SLOT(label);
2666
2667 if (!mac_mls_dominate_effective(obj, subj))
2668 return (EACCES);
2669
2670 return (0);
2671 }
2672
2673 static int
2674 mac_mls_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
2675 struct label *vnodelabel, int attrnamespace, const char *name,
2676 struct uio *uio)
2677 {
2678 struct mac_mls *subj, *obj;
2679
2680 if (!mac_mls_enabled)
2681 return (0);
2682
2683 subj = SLOT(cred->cr_label);
2684 obj = SLOT(vnodelabel);
2685
2686 if (!mac_mls_dominate_effective(obj, subj))
2687 return (EACCES);
2688
2689 /* XXX: protect the MAC EA in a special way? */
2690
2691 return (0);
2692 }
2693
2694 static int
2695 mac_mls_check_vnode_setflags(struct ucred *cred, struct vnode *vp,
2696 struct label *vnodelabel, u_long flags)
2697 {
2698 struct mac_mls *subj, *obj;
2699
2700 if (!mac_mls_enabled)
2701 return (0);
2702
2703 subj = SLOT(cred->cr_label);
2704 obj = SLOT(vnodelabel);
2705
2706 if (!mac_mls_dominate_effective(obj, subj))
2707 return (EACCES);
2708
2709 return (0);
2710 }
2711
2712 static int
2713 mac_mls_check_vnode_setmode(struct ucred *cred, struct vnode *vp,
2714 struct label *vnodelabel, mode_t mode)
2715 {
2716 struct mac_mls *subj, *obj;
2717
2718 if (!mac_mls_enabled)
2719 return (0);
2720
2721 subj = SLOT(cred->cr_label);
2722 obj = SLOT(vnodelabel);
2723
2724 if (!mac_mls_dominate_effective(obj, subj))
2725 return (EACCES);
2726
2727 return (0);
2728 }
2729
2730 static int
2731 mac_mls_check_vnode_setowner(struct ucred *cred, struct vnode *vp,
2732 struct label *vnodelabel, uid_t uid, gid_t gid)
2733 {
2734 struct mac_mls *subj, *obj;
2735
2736 if (!mac_mls_enabled)
2737 return (0);
2738
2739 subj = SLOT(cred->cr_label);
2740 obj = SLOT(vnodelabel);
2741
2742 if (!mac_mls_dominate_effective(obj, subj))
2743 return (EACCES);
2744
2745 return (0);
2746 }
2747
2748 static int
2749 mac_mls_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
2750 struct label *vnodelabel, struct timespec atime, struct timespec mtime)
2751 {
2752 struct mac_mls *subj, *obj;
2753
2754 if (!mac_mls_enabled)
2755 return (0);
2756
2757 subj = SLOT(cred->cr_label);
2758 obj = SLOT(vnodelabel);
2759
2760 if (!mac_mls_dominate_effective(obj, subj))
2761 return (EACCES);
2762
2763 return (0);
2764 }
2765
2766 static int
2767 mac_mls_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
2768 struct vnode *vp, struct label *vnodelabel)
2769 {
2770 struct mac_mls *subj, *obj;
2771
2772 if (!mac_mls_enabled)
2773 return (0);
2774
2775 subj = SLOT(active_cred->cr_label);
2776 obj = SLOT(vnodelabel);
2777
2778 if (!mac_mls_dominate_effective(subj, obj))
2779 return (EACCES);
2780
2781 return (0);
2782 }
2783
2784 static int
2785 mac_mls_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred,
2786 struct vnode *vp, struct label *label)
2787 {
2788 struct mac_mls *subj, *obj;
2789
2790 if (!mac_mls_enabled || !revocation_enabled)
2791 return (0);
2792
2793 subj = SLOT(active_cred->cr_label);
2794 obj = SLOT(label);
2795
2796 if (!mac_mls_dominate_effective(obj, subj))
2797 return (EACCES);
2798
2799 return (0);
2800 }
2801
2802 static void
2803 mac_mls_associate_nfsd_label(struct ucred *cred)
2804 {
2805 struct mac_mls *label;
2806
2807 label = SLOT(cred->cr_label);
2808 mac_mls_set_effective(label, MAC_MLS_TYPE_LOW, 0, NULL);
2809 mac_mls_set_range(label, MAC_MLS_TYPE_LOW, 0, NULL,
2810 MAC_MLS_TYPE_HIGH, 0, NULL);
2811 }
2812
2813 static struct mac_policy_ops mac_mls_ops =
2814 {
2815 .mpo_init = mac_mls_init,
2816 .mpo_init_bpfdesc_label = mac_mls_init_label,
2817 .mpo_init_cred_label = mac_mls_init_label,
2818 .mpo_init_devfsdirent_label = mac_mls_init_label,
2819 .mpo_init_ifnet_label = mac_mls_init_label,
2820 .mpo_init_inpcb_label = mac_mls_init_label_waitcheck,
2821 .mpo_init_sysv_msgmsg_label = mac_mls_init_label,
2822 .mpo_init_sysv_msgqueue_label = mac_mls_init_label,
2823 .mpo_init_sysv_sem_label = mac_mls_init_label,
2824 .mpo_init_sysv_shm_label = mac_mls_init_label,
2825 .mpo_init_ipq_label = mac_mls_init_label_waitcheck,
2826 .mpo_init_mbuf_label = mac_mls_init_label_waitcheck,
2827 .mpo_init_mount_label = mac_mls_init_label,
2828 .mpo_init_mount_fs_label = mac_mls_init_label,
2829 .mpo_init_pipe_label = mac_mls_init_label,
2830 .mpo_init_posix_sem_label = mac_mls_init_label,
2831 .mpo_init_socket_label = mac_mls_init_label_waitcheck,
2832 .mpo_init_socket_peer_label = mac_mls_init_label_waitcheck,
2833 .mpo_init_vnode_label = mac_mls_init_label,
2834 .mpo_destroy_bpfdesc_label = mac_mls_destroy_label,
2835 .mpo_destroy_cred_label = mac_mls_destroy_label,
2836 .mpo_destroy_devfsdirent_label = mac_mls_destroy_label,
2837 .mpo_destroy_ifnet_label = mac_mls_destroy_label,
2838 .mpo_destroy_inpcb_label = mac_mls_destroy_label,
2839 .mpo_destroy_sysv_msgmsg_label = mac_mls_destroy_label,
2840 .mpo_destroy_sysv_msgqueue_label = mac_mls_destroy_label,
2841 .mpo_destroy_sysv_sem_label = mac_mls_destroy_label,
2842 .mpo_destroy_sysv_shm_label = mac_mls_destroy_label,
2843 .mpo_destroy_ipq_label = mac_mls_destroy_label,
2844 .mpo_destroy_mbuf_label = mac_mls_destroy_label,
2845 .mpo_destroy_mount_label = mac_mls_destroy_label,
2846 .mpo_destroy_mount_fs_label = mac_mls_destroy_label,
2847 .mpo_destroy_pipe_label = mac_mls_destroy_label,
2848 .mpo_destroy_posix_sem_label = mac_mls_destroy_label,
2849 .mpo_destroy_socket_label = mac_mls_destroy_label,
2850 .mpo_destroy_socket_peer_label = mac_mls_destroy_label,
2851 .mpo_destroy_vnode_label = mac_mls_destroy_label,
2852 .mpo_copy_cred_label = mac_mls_copy_label,
2853 .mpo_copy_ifnet_label = mac_mls_copy_label,
2854 .mpo_copy_mbuf_label = mac_mls_copy_label,
2855 .mpo_copy_pipe_label = mac_mls_copy_label,
2856 .mpo_copy_socket_label = mac_mls_copy_label,
2857 .mpo_copy_vnode_label = mac_mls_copy_label,
2858 .mpo_externalize_cred_label = mac_mls_externalize_label,
2859 .mpo_externalize_ifnet_label = mac_mls_externalize_label,
2860 .mpo_externalize_pipe_label = mac_mls_externalize_label,
2861 .mpo_externalize_socket_label = mac_mls_externalize_label,
2862 .mpo_externalize_socket_peer_label = mac_mls_externalize_label,
2863 .mpo_externalize_vnode_label = mac_mls_externalize_label,
2864 .mpo_internalize_cred_label = mac_mls_internalize_label,
2865 .mpo_internalize_ifnet_label = mac_mls_internalize_label,
2866 .mpo_internalize_pipe_label = mac_mls_internalize_label,
2867 .mpo_internalize_socket_label = mac_mls_internalize_label,
2868 .mpo_internalize_vnode_label = mac_mls_internalize_label,
2869 .mpo_create_devfs_device = mac_mls_create_devfs_device,
2870 .mpo_create_devfs_directory = mac_mls_create_devfs_directory,
2871 .mpo_create_devfs_symlink = mac_mls_create_devfs_symlink,
2872 .mpo_create_mount = mac_mls_create_mount,
2873 .mpo_relabel_vnode = mac_mls_relabel_vnode,
2874 .mpo_update_devfsdirent = mac_mls_update_devfsdirent,
2875 .mpo_associate_vnode_devfs = mac_mls_associate_vnode_devfs,
2876 .mpo_associate_vnode_extattr = mac_mls_associate_vnode_extattr,
2877 .mpo_associate_vnode_singlelabel = mac_mls_associate_vnode_singlelabel,
2878 .mpo_create_vnode_extattr = mac_mls_create_vnode_extattr,
2879 .mpo_setlabel_vnode_extattr = mac_mls_setlabel_vnode_extattr,
2880 .mpo_create_mbuf_from_socket = mac_mls_create_mbuf_from_socket,
2881 .mpo_create_pipe = mac_mls_create_pipe,
2882 .mpo_create_posix_sem = mac_mls_create_posix_sem,
2883 .mpo_create_socket = mac_mls_create_socket,
2884 .mpo_create_socket_from_socket = mac_mls_create_socket_from_socket,
2885 .mpo_relabel_pipe = mac_mls_relabel_pipe,
2886 .mpo_relabel_socket = mac_mls_relabel_socket,
2887 .mpo_set_socket_peer_from_mbuf = mac_mls_set_socket_peer_from_mbuf,
2888 .mpo_set_socket_peer_from_socket = mac_mls_set_socket_peer_from_socket,
2889 .mpo_create_bpfdesc = mac_mls_create_bpfdesc,
2890 .mpo_create_datagram_from_ipq = mac_mls_create_datagram_from_ipq,
2891 .mpo_create_fragment = mac_mls_create_fragment,
2892 .mpo_create_ifnet = mac_mls_create_ifnet,
2893 .mpo_create_inpcb_from_socket = mac_mls_create_inpcb_from_socket,
2894 .mpo_create_ipq = mac_mls_create_ipq,
2895 .mpo_create_sysv_msgmsg = mac_mls_create_sysv_msgmsg,
2896 .mpo_create_sysv_msgqueue = mac_mls_create_sysv_msgqueue,
2897 .mpo_create_sysv_sem = mac_mls_create_sysv_sem,
2898 .mpo_create_sysv_shm = mac_mls_create_sysv_shm,
2899 .mpo_create_mbuf_from_inpcb = mac_mls_create_mbuf_from_inpcb,
2900 .mpo_create_mbuf_linklayer = mac_mls_create_mbuf_linklayer,
2901 .mpo_create_mbuf_from_bpfdesc = mac_mls_create_mbuf_from_bpfdesc,
2902 .mpo_create_mbuf_from_ifnet = mac_mls_create_mbuf_from_ifnet,
2903 .mpo_create_mbuf_multicast_encap = mac_mls_create_mbuf_multicast_encap,
2904 .mpo_create_mbuf_netlayer = mac_mls_create_mbuf_netlayer,
2905 .mpo_fragment_match = mac_mls_fragment_match,
2906 .mpo_relabel_ifnet = mac_mls_relabel_ifnet,
2907 .mpo_update_ipq = mac_mls_update_ipq,
2908 .mpo_inpcb_sosetlabel = mac_mls_inpcb_sosetlabel,
2909 .mpo_create_proc0 = mac_mls_create_proc0,
2910 .mpo_create_proc1 = mac_mls_create_proc1,
2911 .mpo_relabel_cred = mac_mls_relabel_cred,
2912 .mpo_cleanup_sysv_msgmsg = mac_mls_cleanup_sysv_msgmsg,
2913 .mpo_cleanup_sysv_msgqueue = mac_mls_cleanup_sysv_msgqueue,
2914 .mpo_cleanup_sysv_sem = mac_mls_cleanup_sysv_sem,
2915 .mpo_cleanup_sysv_shm = mac_mls_cleanup_sysv_shm,
2916 .mpo_check_bpfdesc_receive = mac_mls_check_bpfdesc_receive,
2917 .mpo_check_cred_relabel = mac_mls_check_cred_relabel,
2918 .mpo_check_cred_visible = mac_mls_check_cred_visible,
2919 .mpo_check_ifnet_relabel = mac_mls_check_ifnet_relabel,
2920 .mpo_check_ifnet_transmit = mac_mls_check_ifnet_transmit,
2921 .mpo_check_inpcb_deliver = mac_mls_check_inpcb_deliver,
2922 .mpo_check_sysv_msgrcv = mac_mls_check_sysv_msgrcv,
2923 .mpo_check_sysv_msgrmid = mac_mls_check_sysv_msgrmid,
2924 .mpo_check_sysv_msqget = mac_mls_check_sysv_msqget,
2925 .mpo_check_sysv_msqsnd = mac_mls_check_sysv_msqsnd,
2926 .mpo_check_sysv_msqrcv = mac_mls_check_sysv_msqrcv,
2927 .mpo_check_sysv_msqctl = mac_mls_check_sysv_msqctl,
2928 .mpo_check_sysv_semctl = mac_mls_check_sysv_semctl,
2929 .mpo_check_sysv_semget = mac_mls_check_sysv_semget,
2930 .mpo_check_sysv_semop = mac_mls_check_sysv_semop,
2931 .mpo_check_sysv_shmat = mac_mls_check_sysv_shmat,
2932 .mpo_check_sysv_shmctl = mac_mls_check_sysv_shmctl,
2933 .mpo_check_sysv_shmget = mac_mls_check_sysv_shmget,
2934 .mpo_check_mount_stat = mac_mls_check_mount_stat,
2935 .mpo_check_pipe_ioctl = mac_mls_check_pipe_ioctl,
2936 .mpo_check_pipe_poll = mac_mls_check_pipe_poll,
2937 .mpo_check_pipe_read = mac_mls_check_pipe_read,
2938 .mpo_check_pipe_relabel = mac_mls_check_pipe_relabel,
2939 .mpo_check_pipe_stat = mac_mls_check_pipe_stat,
2940 .mpo_check_pipe_write = mac_mls_check_pipe_write,
2941 .mpo_check_posix_sem_destroy = mac_mls_check_posix_sem_write,
2942 .mpo_check_posix_sem_getvalue = mac_mls_check_posix_sem_rdonly,
2943 .mpo_check_posix_sem_open = mac_mls_check_posix_sem_write,
2944 .mpo_check_posix_sem_post = mac_mls_check_posix_sem_write,
2945 .mpo_check_posix_sem_unlink = mac_mls_check_posix_sem_write,
2946 .mpo_check_posix_sem_wait = mac_mls_check_posix_sem_write,
2947 .mpo_check_proc_debug = mac_mls_check_proc_debug,
2948 .mpo_check_proc_sched = mac_mls_check_proc_sched,
2949 .mpo_check_proc_signal = mac_mls_check_proc_signal,
2950 .mpo_check_socket_deliver = mac_mls_check_socket_deliver,
2951 .mpo_check_socket_relabel = mac_mls_check_socket_relabel,
2952 .mpo_check_socket_visible = mac_mls_check_socket_visible,
2953 .mpo_check_system_swapon = mac_mls_check_system_swapon,
2954 .mpo_check_vnode_access = mac_mls_check_vnode_open,
2955 .mpo_check_vnode_chdir = mac_mls_check_vnode_chdir,
2956 .mpo_check_vnode_chroot = mac_mls_check_vnode_chroot,
2957 .mpo_check_vnode_create = mac_mls_check_vnode_create,
2958 .mpo_check_vnode_delete = mac_mls_check_vnode_delete,
2959 .mpo_check_vnode_deleteacl = mac_mls_check_vnode_deleteacl,
2960 .mpo_check_vnode_deleteextattr = mac_mls_check_vnode_deleteextattr,
2961 .mpo_check_vnode_exec = mac_mls_check_vnode_exec,
2962 .mpo_check_vnode_getacl = mac_mls_check_vnode_getacl,
2963 .mpo_check_vnode_getextattr = mac_mls_check_vnode_getextattr,
2964 .mpo_check_vnode_link = mac_mls_check_vnode_link,
2965 .mpo_check_vnode_listextattr = mac_mls_check_vnode_listextattr,
2966 .mpo_check_vnode_lookup = mac_mls_check_vnode_lookup,
2967 .mpo_check_vnode_mmap = mac_mls_check_vnode_mmap,
2968 .mpo_check_vnode_open = mac_mls_check_vnode_open,
2969 .mpo_check_vnode_poll = mac_mls_check_vnode_poll,
2970 .mpo_check_vnode_read = mac_mls_check_vnode_read,
2971 .mpo_check_vnode_readdir = mac_mls_check_vnode_readdir,
2972 .mpo_check_vnode_readlink = mac_mls_check_vnode_readlink,
2973 .mpo_check_vnode_relabel = mac_mls_check_vnode_relabel,
2974 .mpo_check_vnode_rename_from = mac_mls_check_vnode_rename_from,
2975 .mpo_check_vnode_rename_to = mac_mls_check_vnode_rename_to,
2976 .mpo_check_vnode_revoke = mac_mls_check_vnode_revoke,
2977 .mpo_check_vnode_setacl = mac_mls_check_vnode_setacl,
2978 .mpo_check_vnode_setextattr = mac_mls_check_vnode_setextattr,
2979 .mpo_check_vnode_setflags = mac_mls_check_vnode_setflags,
2980 .mpo_check_vnode_setmode = mac_mls_check_vnode_setmode,
2981 .mpo_check_vnode_setowner = mac_mls_check_vnode_setowner,
2982 .mpo_check_vnode_setutimes = mac_mls_check_vnode_setutimes,
2983 .mpo_check_vnode_stat = mac_mls_check_vnode_stat,
2984 .mpo_check_vnode_write = mac_mls_check_vnode_write,
2985 .mpo_associate_nfsd_label = mac_mls_associate_nfsd_label,
2986 .mpo_create_mbuf_from_firewall = mac_mls_create_mbuf_from_firewall,
2987 };
2988
2989 MAC_POLICY_SET(&mac_mls_ops, mac_mls, "TrustedBSD MAC/MLS",
2990 MPC_LOADTIME_FLAG_NOTLATE | MPC_LOADTIME_FLAG_LABELMBUFS, &mac_mls_slot);
Cache object: 9404fe1f3b8a713aaaac59e3049f1019
|