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$
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 return (mac_mls_subject_privileged(subj));
1510 }
1511
1512 static int
1513 mac_mls_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel,
1514 struct mbuf *m, struct label *mbuflabel)
1515 {
1516 struct mac_mls *p, *i;
1517
1518 if (!mac_mls_enabled)
1519 return (0);
1520
1521 p = SLOT(mbuflabel);
1522 i = SLOT(ifnetlabel);
1523
1524 return (mac_mls_effective_in_range(p, i) ? 0 : EACCES);
1525 }
1526
1527 static int
1528 mac_mls_check_inpcb_deliver(struct inpcb *inp, struct label *inplabel,
1529 struct mbuf *m, struct label *mlabel)
1530 {
1531 struct mac_mls *p, *i;
1532
1533 if (!mac_mls_enabled)
1534 return (0);
1535
1536 p = SLOT(mlabel);
1537 i = SLOT(inplabel);
1538
1539 return (mac_mls_equal_effective(p, i) ? 0 : EACCES);
1540 }
1541
1542 static int
1543 mac_mls_check_sysv_msgrcv(struct ucred *cred, struct msg *msgptr,
1544 struct label *msglabel)
1545 {
1546 struct mac_mls *subj, *obj;
1547
1548 if (!mac_mls_enabled)
1549 return (0);
1550
1551 subj = SLOT(cred->cr_label);
1552 obj = SLOT(msglabel);
1553
1554 if (!mac_mls_dominate_effective(subj, obj))
1555 return (EACCES);
1556
1557 return (0);
1558 }
1559
1560 static int
1561 mac_mls_check_sysv_msgrmid(struct ucred *cred, struct msg *msgptr,
1562 struct label *msglabel)
1563 {
1564 struct mac_mls *subj, *obj;
1565
1566 if (!mac_mls_enabled)
1567 return (0);
1568
1569 subj = SLOT(cred->cr_label);
1570 obj = SLOT(msglabel);
1571
1572 if (!mac_mls_dominate_effective(obj, subj))
1573 return (EACCES);
1574
1575 return (0);
1576 }
1577
1578 static int
1579 mac_mls_check_sysv_msqget(struct ucred *cred, struct msqid_kernel *msqkptr,
1580 struct label *msqklabel)
1581 {
1582 struct mac_mls *subj, *obj;
1583
1584 if (!mac_mls_enabled)
1585 return (0);
1586
1587 subj = SLOT(cred->cr_label);
1588 obj = SLOT(msqklabel);
1589
1590 if (!mac_mls_dominate_effective(subj, obj))
1591 return (EACCES);
1592
1593 return (0);
1594 }
1595
1596 static int
1597 mac_mls_check_sysv_msqsnd(struct ucred *cred, struct msqid_kernel *msqkptr,
1598 struct label *msqklabel)
1599 {
1600 struct mac_mls *subj, *obj;
1601
1602 if (!mac_mls_enabled)
1603 return (0);
1604
1605 subj = SLOT(cred->cr_label);
1606 obj = SLOT(msqklabel);
1607
1608 if (!mac_mls_dominate_effective(obj, subj))
1609 return (EACCES);
1610
1611 return (0);
1612 }
1613
1614 static int
1615 mac_mls_check_sysv_msqrcv(struct ucred *cred, struct msqid_kernel *msqkptr,
1616 struct label *msqklabel)
1617 {
1618 struct mac_mls *subj, *obj;
1619
1620 if (!mac_mls_enabled)
1621 return (0);
1622
1623 subj = SLOT(cred->cr_label);
1624 obj = SLOT(msqklabel);
1625
1626 if (!mac_mls_dominate_effective(subj, obj))
1627 return (EACCES);
1628
1629 return (0);
1630 }
1631
1632 static int
1633 mac_mls_check_sysv_msqctl(struct ucred *cred, struct msqid_kernel *msqkptr,
1634 struct label *msqklabel, int cmd)
1635 {
1636 struct mac_mls *subj, *obj;
1637
1638 if (!mac_mls_enabled)
1639 return (0);
1640
1641 subj = SLOT(cred->cr_label);
1642 obj = SLOT(msqklabel);
1643
1644 switch(cmd) {
1645 case IPC_RMID:
1646 case IPC_SET:
1647 if (!mac_mls_dominate_effective(obj, subj))
1648 return (EACCES);
1649 break;
1650
1651 case IPC_STAT:
1652 if (!mac_mls_dominate_effective(subj, obj))
1653 return (EACCES);
1654 break;
1655
1656 default:
1657 return (EACCES);
1658 }
1659
1660 return (0);
1661 }
1662
1663 static int
1664 mac_mls_check_sysv_semctl(struct ucred *cred, struct semid_kernel *semakptr,
1665 struct label *semaklabel, int cmd)
1666 {
1667 struct mac_mls *subj, *obj;
1668
1669 if (!mac_mls_enabled)
1670 return (0);
1671
1672 subj = SLOT(cred->cr_label);
1673 obj = SLOT(semaklabel);
1674
1675 switch(cmd) {
1676 case IPC_RMID:
1677 case IPC_SET:
1678 case SETVAL:
1679 case SETALL:
1680 if (!mac_mls_dominate_effective(obj, subj))
1681 return (EACCES);
1682 break;
1683
1684 case IPC_STAT:
1685 case GETVAL:
1686 case GETPID:
1687 case GETNCNT:
1688 case GETZCNT:
1689 case GETALL:
1690 if (!mac_mls_dominate_effective(subj, obj))
1691 return (EACCES);
1692 break;
1693
1694 default:
1695 return (EACCES);
1696 }
1697
1698 return (0);
1699 }
1700
1701 static int
1702 mac_mls_check_sysv_semget(struct ucred *cred, struct semid_kernel *semakptr,
1703 struct label *semaklabel)
1704 {
1705 struct mac_mls *subj, *obj;
1706
1707 if (!mac_mls_enabled)
1708 return (0);
1709
1710 subj = SLOT(cred->cr_label);
1711 obj = SLOT(semaklabel);
1712
1713 if (!mac_mls_dominate_effective(subj, obj))
1714 return (EACCES);
1715
1716 return (0);
1717 }
1718
1719 static int
1720 mac_mls_check_sysv_semop(struct ucred *cred, struct semid_kernel *semakptr,
1721 struct label *semaklabel, size_t accesstype)
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(semaklabel);
1730
1731 if( accesstype & SEM_R )
1732 if (!mac_mls_dominate_effective(subj, obj))
1733 return (EACCES);
1734
1735 if( accesstype & SEM_A )
1736 if (!mac_mls_dominate_effective(obj, subj))
1737 return (EACCES);
1738
1739 return (0);
1740 }
1741
1742 static int
1743 mac_mls_check_sysv_shmat(struct ucred *cred, struct shmid_kernel *shmsegptr,
1744 struct label *shmseglabel, int shmflg)
1745 {
1746 struct mac_mls *subj, *obj;
1747
1748 if (!mac_mls_enabled)
1749 return (0);
1750
1751 subj = SLOT(cred->cr_label);
1752 obj = SLOT(shmseglabel);
1753
1754 if (!mac_mls_dominate_effective(subj, obj))
1755 return (EACCES);
1756 if ((shmflg & SHM_RDONLY) == 0)
1757 if (!mac_mls_dominate_effective(obj, subj))
1758 return (EACCES);
1759
1760 return (0);
1761 }
1762
1763 static int
1764 mac_mls_check_sysv_shmctl(struct ucred *cred, struct shmid_kernel *shmsegptr,
1765 struct label *shmseglabel, int cmd)
1766 {
1767 struct mac_mls *subj, *obj;
1768
1769 if (!mac_mls_enabled)
1770 return (0);
1771
1772 subj = SLOT(cred->cr_label);
1773 obj = SLOT(shmseglabel);
1774
1775 switch(cmd) {
1776 case IPC_RMID:
1777 case IPC_SET:
1778 if (!mac_mls_dominate_effective(obj, subj))
1779 return (EACCES);
1780 break;
1781
1782 case IPC_STAT:
1783 case SHM_STAT:
1784 if (!mac_mls_dominate_effective(subj, obj))
1785 return (EACCES);
1786 break;
1787
1788 default:
1789 return (EACCES);
1790 }
1791
1792 return (0);
1793 }
1794
1795 static int
1796 mac_mls_check_sysv_shmget(struct ucred *cred, struct shmid_kernel *shmsegptr,
1797 struct label *shmseglabel, int shmflg)
1798 {
1799 struct mac_mls *subj, *obj;
1800
1801 if (!mac_mls_enabled)
1802 return (0);
1803
1804 subj = SLOT(cred->cr_label);
1805 obj = SLOT(shmseglabel);
1806
1807 if (!mac_mls_dominate_effective(obj, subj))
1808 return (EACCES);
1809
1810 return (0);
1811 }
1812
1813 static int
1814 mac_mls_check_mount_stat(struct ucred *cred, struct mount *mp,
1815 struct label *mntlabel)
1816 {
1817 struct mac_mls *subj, *obj;
1818
1819 if (!mac_mls_enabled)
1820 return (0);
1821
1822 subj = SLOT(cred->cr_label);
1823 obj = SLOT(mntlabel);
1824
1825 if (!mac_mls_dominate_effective(subj, obj))
1826 return (EACCES);
1827
1828 return (0);
1829 }
1830
1831 static int
1832 mac_mls_check_pipe_ioctl(struct ucred *cred, struct pipepair *pp,
1833 struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data)
1834 {
1835
1836 if(!mac_mls_enabled)
1837 return (0);
1838
1839 /* XXX: This will be implemented soon... */
1840
1841 return (0);
1842 }
1843
1844 static int
1845 mac_mls_check_pipe_poll(struct ucred *cred, struct pipepair *pp,
1846 struct label *pipelabel)
1847 {
1848 struct mac_mls *subj, *obj;
1849
1850 if (!mac_mls_enabled)
1851 return (0);
1852
1853 subj = SLOT(cred->cr_label);
1854 obj = SLOT((pipelabel));
1855
1856 if (!mac_mls_dominate_effective(subj, obj))
1857 return (EACCES);
1858
1859 return (0);
1860 }
1861
1862 static int
1863 mac_mls_check_pipe_read(struct ucred *cred, struct pipepair *pp,
1864 struct label *pipelabel)
1865 {
1866 struct mac_mls *subj, *obj;
1867
1868 if (!mac_mls_enabled)
1869 return (0);
1870
1871 subj = SLOT(cred->cr_label);
1872 obj = SLOT((pipelabel));
1873
1874 if (!mac_mls_dominate_effective(subj, obj))
1875 return (EACCES);
1876
1877 return (0);
1878 }
1879
1880 static int
1881 mac_mls_check_pipe_relabel(struct ucred *cred, struct pipepair *pp,
1882 struct label *pipelabel, struct label *newlabel)
1883 {
1884 struct mac_mls *subj, *obj, *new;
1885 int error;
1886
1887 new = SLOT(newlabel);
1888 subj = SLOT(cred->cr_label);
1889 obj = SLOT(pipelabel);
1890
1891 /*
1892 * If there is an MLS label update for a pipe, it must be a
1893 * effective update.
1894 */
1895 error = mls_atmostflags(new, MAC_MLS_FLAG_EFFECTIVE);
1896 if (error)
1897 return (error);
1898
1899 /*
1900 * To perform a relabel of a pipe (MLS label or not), MLS must
1901 * authorize the relabel.
1902 */
1903 if (!mac_mls_effective_in_range(obj, subj))
1904 return (EPERM);
1905
1906 /*
1907 * If the MLS label is to be changed, authorize as appropriate.
1908 */
1909 if (new->mm_flags & MAC_MLS_FLAG_EFFECTIVE) {
1910 /*
1911 * To change the MLS label on a pipe, the new pipe label
1912 * must be in the subject range.
1913 */
1914 if (!mac_mls_effective_in_range(new, subj))
1915 return (EPERM);
1916
1917 /*
1918 * To change the MLS label on a pipe to be EQUAL, the
1919 * subject must have appropriate privilege.
1920 */
1921 if (mac_mls_contains_equal(new)) {
1922 error = mac_mls_subject_privileged(subj);
1923 if (error)
1924 return (error);
1925 }
1926 }
1927
1928 return (0);
1929 }
1930
1931 static int
1932 mac_mls_check_pipe_stat(struct ucred *cred, struct pipepair *pp,
1933 struct label *pipelabel)
1934 {
1935 struct mac_mls *subj, *obj;
1936
1937 if (!mac_mls_enabled)
1938 return (0);
1939
1940 subj = SLOT(cred->cr_label);
1941 obj = SLOT((pipelabel));
1942
1943 if (!mac_mls_dominate_effective(subj, obj))
1944 return (EACCES);
1945
1946 return (0);
1947 }
1948
1949 static int
1950 mac_mls_check_pipe_write(struct ucred *cred, struct pipepair *pp,
1951 struct label *pipelabel)
1952 {
1953 struct mac_mls *subj, *obj;
1954
1955 if (!mac_mls_enabled)
1956 return (0);
1957
1958 subj = SLOT(cred->cr_label);
1959 obj = SLOT((pipelabel));
1960
1961 if (!mac_mls_dominate_effective(obj, subj))
1962 return (EACCES);
1963
1964 return (0);
1965 }
1966
1967 static int
1968 mac_mls_check_posix_sem_write(struct ucred *cred, struct ksem *ksemptr,
1969 struct label *ks_label)
1970 {
1971 struct mac_mls *subj, *obj;
1972
1973 if (!mac_mls_enabled)
1974 return (0);
1975
1976 subj = SLOT(cred->cr_label);
1977 obj = SLOT(ks_label);
1978
1979 if (!mac_mls_dominate_effective(obj, subj))
1980 return (EACCES);
1981
1982 return (0);
1983 }
1984
1985 static int
1986 mac_mls_check_posix_sem_rdonly(struct ucred *cred, struct ksem *ksemptr,
1987 struct label *ks_label)
1988 {
1989 struct mac_mls *subj, *obj;
1990
1991 if (!mac_mls_enabled)
1992 return (0);
1993
1994 subj = SLOT(cred->cr_label);
1995 obj = SLOT(ks_label);
1996
1997 if (!mac_mls_dominate_effective(subj, obj))
1998 return (EACCES);
1999
2000 return (0);
2001 }
2002
2003 static int
2004 mac_mls_check_proc_debug(struct ucred *cred, struct proc *proc)
2005 {
2006 struct mac_mls *subj, *obj;
2007
2008 if (!mac_mls_enabled)
2009 return (0);
2010
2011 subj = SLOT(cred->cr_label);
2012 obj = SLOT(proc->p_ucred->cr_label);
2013
2014 /* XXX: range checks */
2015 if (!mac_mls_dominate_effective(subj, obj))
2016 return (ESRCH);
2017 if (!mac_mls_dominate_effective(obj, subj))
2018 return (EACCES);
2019
2020 return (0);
2021 }
2022
2023 static int
2024 mac_mls_check_proc_sched(struct ucred *cred, struct proc *proc)
2025 {
2026 struct mac_mls *subj, *obj;
2027
2028 if (!mac_mls_enabled)
2029 return (0);
2030
2031 subj = SLOT(cred->cr_label);
2032 obj = SLOT(proc->p_ucred->cr_label);
2033
2034 /* XXX: range checks */
2035 if (!mac_mls_dominate_effective(subj, obj))
2036 return (ESRCH);
2037 if (!mac_mls_dominate_effective(obj, subj))
2038 return (EACCES);
2039
2040 return (0);
2041 }
2042
2043 static int
2044 mac_mls_check_proc_signal(struct ucred *cred, struct proc *proc, int signum)
2045 {
2046 struct mac_mls *subj, *obj;
2047
2048 if (!mac_mls_enabled)
2049 return (0);
2050
2051 subj = SLOT(cred->cr_label);
2052 obj = SLOT(proc->p_ucred->cr_label);
2053
2054 /* XXX: range checks */
2055 if (!mac_mls_dominate_effective(subj, obj))
2056 return (ESRCH);
2057 if (!mac_mls_dominate_effective(obj, subj))
2058 return (EACCES);
2059
2060 return (0);
2061 }
2062
2063 static int
2064 mac_mls_check_socket_deliver(struct socket *so, struct label *socketlabel,
2065 struct mbuf *m, struct label *mbuflabel)
2066 {
2067 struct mac_mls *p, *s;
2068
2069 if (!mac_mls_enabled)
2070 return (0);
2071
2072 p = SLOT(mbuflabel);
2073 s = SLOT(socketlabel);
2074
2075 return (mac_mls_equal_effective(p, s) ? 0 : EACCES);
2076 }
2077
2078 static int
2079 mac_mls_check_socket_relabel(struct ucred *cred, struct socket *socket,
2080 struct label *socketlabel, struct label *newlabel)
2081 {
2082 struct mac_mls *subj, *obj, *new;
2083 int error;
2084
2085 new = SLOT(newlabel);
2086 subj = SLOT(cred->cr_label);
2087 obj = SLOT(socketlabel);
2088
2089 /*
2090 * If there is an MLS label update for the socket, it may be
2091 * an update of effective.
2092 */
2093 error = mls_atmostflags(new, MAC_MLS_FLAG_EFFECTIVE);
2094 if (error)
2095 return (error);
2096
2097 /*
2098 * To relabel a socket, the old socket effective must be in the subject
2099 * range.
2100 */
2101 if (!mac_mls_effective_in_range(obj, subj))
2102 return (EPERM);
2103
2104 /*
2105 * If the MLS label is to be changed, authorize as appropriate.
2106 */
2107 if (new->mm_flags & MAC_MLS_FLAG_EFFECTIVE) {
2108 /*
2109 * To relabel a socket, the new socket effective must be in
2110 * the subject range.
2111 */
2112 if (!mac_mls_effective_in_range(new, subj))
2113 return (EPERM);
2114
2115 /*
2116 * To change the MLS label on the socket to contain EQUAL,
2117 * the subject must have appropriate privilege.
2118 */
2119 if (mac_mls_contains_equal(new)) {
2120 error = mac_mls_subject_privileged(subj);
2121 if (error)
2122 return (error);
2123 }
2124 }
2125
2126 return (0);
2127 }
2128
2129 static int
2130 mac_mls_check_socket_visible(struct ucred *cred, struct socket *socket,
2131 struct label *socketlabel)
2132 {
2133 struct mac_mls *subj, *obj;
2134
2135 if (!mac_mls_enabled)
2136 return (0);
2137
2138 subj = SLOT(cred->cr_label);
2139 obj = SLOT(socketlabel);
2140
2141 if (!mac_mls_dominate_effective(subj, obj))
2142 return (ENOENT);
2143
2144 return (0);
2145 }
2146
2147 static int
2148 mac_mls_check_system_swapon(struct ucred *cred, struct vnode *vp,
2149 struct label *label)
2150 {
2151 struct mac_mls *subj, *obj;
2152
2153 if (!mac_mls_enabled)
2154 return (0);
2155
2156 subj = SLOT(cred->cr_label);
2157 obj = SLOT(label);
2158
2159 if (!mac_mls_dominate_effective(obj, subj) ||
2160 !mac_mls_dominate_effective(subj, obj))
2161 return (EACCES);
2162
2163 return (0);
2164 }
2165
2166 static int
2167 mac_mls_check_vnode_chdir(struct ucred *cred, struct vnode *dvp,
2168 struct label *dlabel)
2169 {
2170 struct mac_mls *subj, *obj;
2171
2172 if (!mac_mls_enabled)
2173 return (0);
2174
2175 subj = SLOT(cred->cr_label);
2176 obj = SLOT(dlabel);
2177
2178 if (!mac_mls_dominate_effective(subj, obj))
2179 return (EACCES);
2180
2181 return (0);
2182 }
2183
2184 static int
2185 mac_mls_check_vnode_chroot(struct ucred *cred, struct vnode *dvp,
2186 struct label *dlabel)
2187 {
2188 struct mac_mls *subj, *obj;
2189
2190 if (!mac_mls_enabled)
2191 return (0);
2192
2193 subj = SLOT(cred->cr_label);
2194 obj = SLOT(dlabel);
2195
2196 if (!mac_mls_dominate_effective(subj, obj))
2197 return (EACCES);
2198
2199 return (0);
2200 }
2201
2202 static int
2203 mac_mls_check_vnode_create(struct ucred *cred, struct vnode *dvp,
2204 struct label *dlabel, struct componentname *cnp, struct vattr *vap)
2205 {
2206 struct mac_mls *subj, *obj;
2207
2208 if (!mac_mls_enabled)
2209 return (0);
2210
2211 subj = SLOT(cred->cr_label);
2212 obj = SLOT(dlabel);
2213
2214 if (!mac_mls_dominate_effective(obj, subj))
2215 return (EACCES);
2216
2217 return (0);
2218 }
2219
2220 static int
2221 mac_mls_check_vnode_delete(struct ucred *cred, struct vnode *dvp,
2222 struct label *dlabel, struct vnode *vp, struct label *label,
2223 struct componentname *cnp)
2224 {
2225 struct mac_mls *subj, *obj;
2226
2227 if (!mac_mls_enabled)
2228 return (0);
2229
2230 subj = SLOT(cred->cr_label);
2231 obj = SLOT(dlabel);
2232
2233 if (!mac_mls_dominate_effective(obj, subj))
2234 return (EACCES);
2235
2236 obj = SLOT(label);
2237
2238 if (!mac_mls_dominate_effective(obj, subj))
2239 return (EACCES);
2240
2241 return (0);
2242 }
2243
2244 static int
2245 mac_mls_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
2246 struct label *label, acl_type_t type)
2247 {
2248 struct mac_mls *subj, *obj;
2249
2250 if (!mac_mls_enabled)
2251 return (0);
2252
2253 subj = SLOT(cred->cr_label);
2254 obj = SLOT(label);
2255
2256 if (!mac_mls_dominate_effective(obj, subj))
2257 return (EACCES);
2258
2259 return (0);
2260 }
2261
2262 static int
2263 mac_mls_check_vnode_deleteextattr(struct ucred *cred, struct vnode *vp,
2264 struct label *label, int attrnamespace, const char *name)
2265 {
2266 struct mac_mls *subj, *obj;
2267
2268 if (!mac_mls_enabled)
2269 return (0);
2270
2271 subj = SLOT(cred->cr_label);
2272 obj = SLOT(label);
2273
2274 if (!mac_mls_dominate_effective(obj, subj))
2275 return (EACCES);
2276
2277 return (0);
2278 }
2279
2280 static int
2281 mac_mls_check_vnode_exec(struct ucred *cred, struct vnode *vp,
2282 struct label *label, struct image_params *imgp,
2283 struct label *execlabel)
2284 {
2285 struct mac_mls *subj, *obj, *exec;
2286 int error;
2287
2288 if (execlabel != NULL) {
2289 /*
2290 * We currently don't permit labels to be changed at
2291 * exec-time as part of MLS, so disallow non-NULL
2292 * MLS label elements in the execlabel.
2293 */
2294 exec = SLOT(execlabel);
2295 error = mls_atmostflags(exec, 0);
2296 if (error)
2297 return (error);
2298 }
2299
2300 if (!mac_mls_enabled)
2301 return (0);
2302
2303 subj = SLOT(cred->cr_label);
2304 obj = SLOT(label);
2305
2306 if (!mac_mls_dominate_effective(subj, obj))
2307 return (EACCES);
2308
2309 return (0);
2310 }
2311
2312 static int
2313 mac_mls_check_vnode_getacl(struct ucred *cred, struct vnode *vp,
2314 struct label *label, acl_type_t type)
2315 {
2316 struct mac_mls *subj, *obj;
2317
2318 if (!mac_mls_enabled)
2319 return (0);
2320
2321 subj = SLOT(cred->cr_label);
2322 obj = SLOT(label);
2323
2324 if (!mac_mls_dominate_effective(subj, obj))
2325 return (EACCES);
2326
2327 return (0);
2328 }
2329
2330 static int
2331 mac_mls_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
2332 struct label *label, int attrnamespace, const char *name, struct uio *uio)
2333 {
2334 struct mac_mls *subj, *obj;
2335
2336 if (!mac_mls_enabled)
2337 return (0);
2338
2339 subj = SLOT(cred->cr_label);
2340 obj = SLOT(label);
2341
2342 if (!mac_mls_dominate_effective(subj, obj))
2343 return (EACCES);
2344
2345 return (0);
2346 }
2347
2348 static int
2349 mac_mls_check_vnode_link(struct ucred *cred, struct vnode *dvp,
2350 struct label *dlabel, struct vnode *vp, struct label *label,
2351 struct componentname *cnp)
2352 {
2353 struct mac_mls *subj, *obj;
2354
2355 if (!mac_mls_enabled)
2356 return (0);
2357
2358 subj = SLOT(cred->cr_label);
2359 obj = SLOT(dlabel);
2360
2361 if (!mac_mls_dominate_effective(obj, subj))
2362 return (EACCES);
2363
2364 obj = SLOT(dlabel);
2365 if (!mac_mls_dominate_effective(obj, subj))
2366 return (EACCES);
2367
2368 return (0);
2369 }
2370
2371 static int
2372 mac_mls_check_vnode_listextattr(struct ucred *cred, struct vnode *vp,
2373 struct label *label, int attrnamespace)
2374 {
2375
2376 struct mac_mls *subj, *obj;
2377
2378 if (!mac_mls_enabled)
2379 return (0);
2380
2381 subj = SLOT(cred->cr_label);
2382 obj = SLOT(label);
2383
2384 if (!mac_mls_dominate_effective(subj, obj))
2385 return (EACCES);
2386
2387 return (0);
2388 }
2389
2390 static int
2391 mac_mls_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
2392 struct label *dlabel, struct componentname *cnp)
2393 {
2394 struct mac_mls *subj, *obj;
2395
2396 if (!mac_mls_enabled)
2397 return (0);
2398
2399 subj = SLOT(cred->cr_label);
2400 obj = SLOT(dlabel);
2401
2402 if (!mac_mls_dominate_effective(subj, obj))
2403 return (EACCES);
2404
2405 return (0);
2406 }
2407
2408 static int
2409 mac_mls_check_vnode_mmap(struct ucred *cred, struct vnode *vp,
2410 struct label *label, int prot, int flags)
2411 {
2412 struct mac_mls *subj, *obj;
2413
2414 /*
2415 * Rely on the use of open()-time protections to handle
2416 * non-revocation cases.
2417 */
2418 if (!mac_mls_enabled || !revocation_enabled)
2419 return (0);
2420
2421 subj = SLOT(cred->cr_label);
2422 obj = SLOT(label);
2423
2424 if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
2425 if (!mac_mls_dominate_effective(subj, obj))
2426 return (EACCES);
2427 }
2428 if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) {
2429 if (!mac_mls_dominate_effective(obj, subj))
2430 return (EACCES);
2431 }
2432
2433 return (0);
2434 }
2435
2436 static int
2437 mac_mls_check_vnode_open(struct ucred *cred, struct vnode *vp,
2438 struct label *vnodelabel, int acc_mode)
2439 {
2440 struct mac_mls *subj, *obj;
2441
2442 if (!mac_mls_enabled)
2443 return (0);
2444
2445 subj = SLOT(cred->cr_label);
2446 obj = SLOT(vnodelabel);
2447
2448 /* XXX privilege override for admin? */
2449 if (acc_mode & (VREAD | VEXEC | VSTAT)) {
2450 if (!mac_mls_dominate_effective(subj, obj))
2451 return (EACCES);
2452 }
2453 if (acc_mode & (VWRITE | VAPPEND | VADMIN)) {
2454 if (!mac_mls_dominate_effective(obj, subj))
2455 return (EACCES);
2456 }
2457
2458 return (0);
2459 }
2460
2461 static int
2462 mac_mls_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred,
2463 struct vnode *vp, struct label *label)
2464 {
2465 struct mac_mls *subj, *obj;
2466
2467 if (!mac_mls_enabled || !revocation_enabled)
2468 return (0);
2469
2470 subj = SLOT(active_cred->cr_label);
2471 obj = SLOT(label);
2472
2473 if (!mac_mls_dominate_effective(subj, obj))
2474 return (EACCES);
2475
2476 return (0);
2477 }
2478
2479 static int
2480 mac_mls_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
2481 struct vnode *vp, struct label *label)
2482 {
2483 struct mac_mls *subj, *obj;
2484
2485 if (!mac_mls_enabled || !revocation_enabled)
2486 return (0);
2487
2488 subj = SLOT(active_cred->cr_label);
2489 obj = SLOT(label);
2490
2491 if (!mac_mls_dominate_effective(subj, obj))
2492 return (EACCES);
2493
2494 return (0);
2495 }
2496
2497 static int
2498 mac_mls_check_vnode_readdir(struct ucred *cred, struct vnode *dvp,
2499 struct label *dlabel)
2500 {
2501 struct mac_mls *subj, *obj;
2502
2503 if (!mac_mls_enabled)
2504 return (0);
2505
2506 subj = SLOT(cred->cr_label);
2507 obj = SLOT(dlabel);
2508
2509 if (!mac_mls_dominate_effective(subj, obj))
2510 return (EACCES);
2511
2512 return (0);
2513 }
2514
2515 static int
2516 mac_mls_check_vnode_readlink(struct ucred *cred, struct vnode *vp,
2517 struct label *vnodelabel)
2518 {
2519 struct mac_mls *subj, *obj;
2520
2521 if (!mac_mls_enabled)
2522 return (0);
2523
2524 subj = SLOT(cred->cr_label);
2525 obj = SLOT(vnodelabel);
2526
2527 if (!mac_mls_dominate_effective(subj, obj))
2528 return (EACCES);
2529
2530 return (0);
2531 }
2532
2533 static int
2534 mac_mls_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
2535 struct label *vnodelabel, struct label *newlabel)
2536 {
2537 struct mac_mls *old, *new, *subj;
2538 int error;
2539
2540 old = SLOT(vnodelabel);
2541 new = SLOT(newlabel);
2542 subj = SLOT(cred->cr_label);
2543
2544 /*
2545 * If there is an MLS label update for the vnode, it must be a
2546 * effective label.
2547 */
2548 error = mls_atmostflags(new, MAC_MLS_FLAG_EFFECTIVE);
2549 if (error)
2550 return (error);
2551
2552 /*
2553 * To perform a relabel of the vnode (MLS label or not), MLS must
2554 * authorize the relabel.
2555 */
2556 if (!mac_mls_effective_in_range(old, subj))
2557 return (EPERM);
2558
2559 /*
2560 * If the MLS label is to be changed, authorize as appropriate.
2561 */
2562 if (new->mm_flags & MAC_MLS_FLAG_EFFECTIVE) {
2563 /*
2564 * To change the MLS label on a vnode, the new vnode label
2565 * must be in the subject range.
2566 */
2567 if (!mac_mls_effective_in_range(new, subj))
2568 return (EPERM);
2569
2570 /*
2571 * To change the MLS label on the vnode to be EQUAL,
2572 * the subject must have appropriate privilege.
2573 */
2574 if (mac_mls_contains_equal(new)) {
2575 error = mac_mls_subject_privileged(subj);
2576 if (error)
2577 return (error);
2578 }
2579 }
2580
2581 return (0);
2582 }
2583
2584
2585 static int
2586 mac_mls_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
2587 struct label *dlabel, struct vnode *vp, struct label *label,
2588 struct componentname *cnp)
2589 {
2590 struct mac_mls *subj, *obj;
2591
2592 if (!mac_mls_enabled)
2593 return (0);
2594
2595 subj = SLOT(cred->cr_label);
2596 obj = SLOT(dlabel);
2597
2598 if (!mac_mls_dominate_effective(obj, subj))
2599 return (EACCES);
2600
2601 obj = SLOT(label);
2602
2603 if (!mac_mls_dominate_effective(obj, subj))
2604 return (EACCES);
2605
2606 return (0);
2607 }
2608
2609 static int
2610 mac_mls_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
2611 struct label *dlabel, struct vnode *vp, struct label *label, int samedir,
2612 struct componentname *cnp)
2613 {
2614 struct mac_mls *subj, *obj;
2615
2616 if (!mac_mls_enabled)
2617 return (0);
2618
2619 subj = SLOT(cred->cr_label);
2620 obj = SLOT(dlabel);
2621
2622 if (!mac_mls_dominate_effective(obj, subj))
2623 return (EACCES);
2624
2625 if (vp != NULL) {
2626 obj = SLOT(label);
2627
2628 if (!mac_mls_dominate_effective(obj, subj))
2629 return (EACCES);
2630 }
2631
2632 return (0);
2633 }
2634
2635 static int
2636 mac_mls_check_vnode_revoke(struct ucred *cred, struct vnode *vp,
2637 struct label *label)
2638 {
2639 struct mac_mls *subj, *obj;
2640
2641 if (!mac_mls_enabled)
2642 return (0);
2643
2644 subj = SLOT(cred->cr_label);
2645 obj = SLOT(label);
2646
2647 if (!mac_mls_dominate_effective(obj, subj))
2648 return (EACCES);
2649
2650 return (0);
2651 }
2652
2653 static int
2654 mac_mls_check_vnode_setacl(struct ucred *cred, struct vnode *vp,
2655 struct label *label, acl_type_t type, struct acl *acl)
2656 {
2657 struct mac_mls *subj, *obj;
2658
2659 if (!mac_mls_enabled)
2660 return (0);
2661
2662 subj = SLOT(cred->cr_label);
2663 obj = SLOT(label);
2664
2665 if (!mac_mls_dominate_effective(obj, subj))
2666 return (EACCES);
2667
2668 return (0);
2669 }
2670
2671 static int
2672 mac_mls_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
2673 struct label *vnodelabel, int attrnamespace, const char *name,
2674 struct uio *uio)
2675 {
2676 struct mac_mls *subj, *obj;
2677
2678 if (!mac_mls_enabled)
2679 return (0);
2680
2681 subj = SLOT(cred->cr_label);
2682 obj = SLOT(vnodelabel);
2683
2684 if (!mac_mls_dominate_effective(obj, subj))
2685 return (EACCES);
2686
2687 /* XXX: protect the MAC EA in a special way? */
2688
2689 return (0);
2690 }
2691
2692 static int
2693 mac_mls_check_vnode_setflags(struct ucred *cred, struct vnode *vp,
2694 struct label *vnodelabel, u_long flags)
2695 {
2696 struct mac_mls *subj, *obj;
2697
2698 if (!mac_mls_enabled)
2699 return (0);
2700
2701 subj = SLOT(cred->cr_label);
2702 obj = SLOT(vnodelabel);
2703
2704 if (!mac_mls_dominate_effective(obj, subj))
2705 return (EACCES);
2706
2707 return (0);
2708 }
2709
2710 static int
2711 mac_mls_check_vnode_setmode(struct ucred *cred, struct vnode *vp,
2712 struct label *vnodelabel, mode_t mode)
2713 {
2714 struct mac_mls *subj, *obj;
2715
2716 if (!mac_mls_enabled)
2717 return (0);
2718
2719 subj = SLOT(cred->cr_label);
2720 obj = SLOT(vnodelabel);
2721
2722 if (!mac_mls_dominate_effective(obj, subj))
2723 return (EACCES);
2724
2725 return (0);
2726 }
2727
2728 static int
2729 mac_mls_check_vnode_setowner(struct ucred *cred, struct vnode *vp,
2730 struct label *vnodelabel, uid_t uid, gid_t gid)
2731 {
2732 struct mac_mls *subj, *obj;
2733
2734 if (!mac_mls_enabled)
2735 return (0);
2736
2737 subj = SLOT(cred->cr_label);
2738 obj = SLOT(vnodelabel);
2739
2740 if (!mac_mls_dominate_effective(obj, subj))
2741 return (EACCES);
2742
2743 return (0);
2744 }
2745
2746 static int
2747 mac_mls_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
2748 struct label *vnodelabel, struct timespec atime, struct timespec mtime)
2749 {
2750 struct mac_mls *subj, *obj;
2751
2752 if (!mac_mls_enabled)
2753 return (0);
2754
2755 subj = SLOT(cred->cr_label);
2756 obj = SLOT(vnodelabel);
2757
2758 if (!mac_mls_dominate_effective(obj, subj))
2759 return (EACCES);
2760
2761 return (0);
2762 }
2763
2764 static int
2765 mac_mls_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
2766 struct vnode *vp, struct label *vnodelabel)
2767 {
2768 struct mac_mls *subj, *obj;
2769
2770 if (!mac_mls_enabled)
2771 return (0);
2772
2773 subj = SLOT(active_cred->cr_label);
2774 obj = SLOT(vnodelabel);
2775
2776 if (!mac_mls_dominate_effective(subj, obj))
2777 return (EACCES);
2778
2779 return (0);
2780 }
2781
2782 static int
2783 mac_mls_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred,
2784 struct vnode *vp, struct label *label)
2785 {
2786 struct mac_mls *subj, *obj;
2787
2788 if (!mac_mls_enabled || !revocation_enabled)
2789 return (0);
2790
2791 subj = SLOT(active_cred->cr_label);
2792 obj = SLOT(label);
2793
2794 if (!mac_mls_dominate_effective(obj, subj))
2795 return (EACCES);
2796
2797 return (0);
2798 }
2799
2800 static void
2801 mac_mls_associate_nfsd_label(struct ucred *cred)
2802 {
2803 struct mac_mls *label;
2804
2805 label = SLOT(cred->cr_label);
2806 mac_mls_set_effective(label, MAC_MLS_TYPE_LOW, 0, NULL);
2807 mac_mls_set_range(label, MAC_MLS_TYPE_LOW, 0, NULL,
2808 MAC_MLS_TYPE_HIGH, 0, NULL);
2809 }
2810
2811 static struct mac_policy_ops mac_mls_ops =
2812 {
2813 .mpo_init = mac_mls_init,
2814 .mpo_init_bpfdesc_label = mac_mls_init_label,
2815 .mpo_init_cred_label = mac_mls_init_label,
2816 .mpo_init_devfsdirent_label = mac_mls_init_label,
2817 .mpo_init_ifnet_label = mac_mls_init_label,
2818 .mpo_init_inpcb_label = mac_mls_init_label_waitcheck,
2819 .mpo_init_sysv_msgmsg_label = mac_mls_init_label,
2820 .mpo_init_sysv_msgqueue_label = mac_mls_init_label,
2821 .mpo_init_sysv_sem_label = mac_mls_init_label,
2822 .mpo_init_sysv_shm_label = mac_mls_init_label,
2823 .mpo_init_ipq_label = mac_mls_init_label_waitcheck,
2824 .mpo_init_mbuf_label = mac_mls_init_label_waitcheck,
2825 .mpo_init_mount_label = mac_mls_init_label,
2826 .mpo_init_mount_fs_label = mac_mls_init_label,
2827 .mpo_init_pipe_label = mac_mls_init_label,
2828 .mpo_init_posix_sem_label = mac_mls_init_label,
2829 .mpo_init_socket_label = mac_mls_init_label_waitcheck,
2830 .mpo_init_socket_peer_label = mac_mls_init_label_waitcheck,
2831 .mpo_init_vnode_label = mac_mls_init_label,
2832 .mpo_destroy_bpfdesc_label = mac_mls_destroy_label,
2833 .mpo_destroy_cred_label = mac_mls_destroy_label,
2834 .mpo_destroy_devfsdirent_label = mac_mls_destroy_label,
2835 .mpo_destroy_ifnet_label = mac_mls_destroy_label,
2836 .mpo_destroy_inpcb_label = mac_mls_destroy_label,
2837 .mpo_destroy_sysv_msgmsg_label = mac_mls_destroy_label,
2838 .mpo_destroy_sysv_msgqueue_label = mac_mls_destroy_label,
2839 .mpo_destroy_sysv_sem_label = mac_mls_destroy_label,
2840 .mpo_destroy_sysv_shm_label = mac_mls_destroy_label,
2841 .mpo_destroy_ipq_label = mac_mls_destroy_label,
2842 .mpo_destroy_mbuf_label = mac_mls_destroy_label,
2843 .mpo_destroy_mount_label = mac_mls_destroy_label,
2844 .mpo_destroy_mount_fs_label = mac_mls_destroy_label,
2845 .mpo_destroy_pipe_label = mac_mls_destroy_label,
2846 .mpo_destroy_posix_sem_label = mac_mls_destroy_label,
2847 .mpo_destroy_socket_label = mac_mls_destroy_label,
2848 .mpo_destroy_socket_peer_label = mac_mls_destroy_label,
2849 .mpo_destroy_vnode_label = mac_mls_destroy_label,
2850 .mpo_copy_cred_label = mac_mls_copy_label,
2851 .mpo_copy_ifnet_label = mac_mls_copy_label,
2852 .mpo_copy_mbuf_label = mac_mls_copy_label,
2853 .mpo_copy_pipe_label = mac_mls_copy_label,
2854 .mpo_copy_socket_label = mac_mls_copy_label,
2855 .mpo_copy_vnode_label = mac_mls_copy_label,
2856 .mpo_externalize_cred_label = mac_mls_externalize_label,
2857 .mpo_externalize_ifnet_label = mac_mls_externalize_label,
2858 .mpo_externalize_pipe_label = mac_mls_externalize_label,
2859 .mpo_externalize_socket_label = mac_mls_externalize_label,
2860 .mpo_externalize_socket_peer_label = mac_mls_externalize_label,
2861 .mpo_externalize_vnode_label = mac_mls_externalize_label,
2862 .mpo_internalize_cred_label = mac_mls_internalize_label,
2863 .mpo_internalize_ifnet_label = mac_mls_internalize_label,
2864 .mpo_internalize_pipe_label = mac_mls_internalize_label,
2865 .mpo_internalize_socket_label = mac_mls_internalize_label,
2866 .mpo_internalize_vnode_label = mac_mls_internalize_label,
2867 .mpo_create_devfs_device = mac_mls_create_devfs_device,
2868 .mpo_create_devfs_directory = mac_mls_create_devfs_directory,
2869 .mpo_create_devfs_symlink = mac_mls_create_devfs_symlink,
2870 .mpo_create_mount = mac_mls_create_mount,
2871 .mpo_relabel_vnode = mac_mls_relabel_vnode,
2872 .mpo_update_devfsdirent = mac_mls_update_devfsdirent,
2873 .mpo_associate_vnode_devfs = mac_mls_associate_vnode_devfs,
2874 .mpo_associate_vnode_extattr = mac_mls_associate_vnode_extattr,
2875 .mpo_associate_vnode_singlelabel = mac_mls_associate_vnode_singlelabel,
2876 .mpo_create_vnode_extattr = mac_mls_create_vnode_extattr,
2877 .mpo_setlabel_vnode_extattr = mac_mls_setlabel_vnode_extattr,
2878 .mpo_create_mbuf_from_socket = mac_mls_create_mbuf_from_socket,
2879 .mpo_create_pipe = mac_mls_create_pipe,
2880 .mpo_create_posix_sem = mac_mls_create_posix_sem,
2881 .mpo_create_socket = mac_mls_create_socket,
2882 .mpo_create_socket_from_socket = mac_mls_create_socket_from_socket,
2883 .mpo_relabel_pipe = mac_mls_relabel_pipe,
2884 .mpo_relabel_socket = mac_mls_relabel_socket,
2885 .mpo_set_socket_peer_from_mbuf = mac_mls_set_socket_peer_from_mbuf,
2886 .mpo_set_socket_peer_from_socket = mac_mls_set_socket_peer_from_socket,
2887 .mpo_create_bpfdesc = mac_mls_create_bpfdesc,
2888 .mpo_create_datagram_from_ipq = mac_mls_create_datagram_from_ipq,
2889 .mpo_create_fragment = mac_mls_create_fragment,
2890 .mpo_create_ifnet = mac_mls_create_ifnet,
2891 .mpo_create_inpcb_from_socket = mac_mls_create_inpcb_from_socket,
2892 .mpo_create_ipq = mac_mls_create_ipq,
2893 .mpo_create_sysv_msgmsg = mac_mls_create_sysv_msgmsg,
2894 .mpo_create_sysv_msgqueue = mac_mls_create_sysv_msgqueue,
2895 .mpo_create_sysv_sem = mac_mls_create_sysv_sem,
2896 .mpo_create_sysv_shm = mac_mls_create_sysv_shm,
2897 .mpo_create_mbuf_from_inpcb = mac_mls_create_mbuf_from_inpcb,
2898 .mpo_create_mbuf_linklayer = mac_mls_create_mbuf_linklayer,
2899 .mpo_create_mbuf_from_bpfdesc = mac_mls_create_mbuf_from_bpfdesc,
2900 .mpo_create_mbuf_from_ifnet = mac_mls_create_mbuf_from_ifnet,
2901 .mpo_create_mbuf_multicast_encap = mac_mls_create_mbuf_multicast_encap,
2902 .mpo_create_mbuf_netlayer = mac_mls_create_mbuf_netlayer,
2903 .mpo_fragment_match = mac_mls_fragment_match,
2904 .mpo_relabel_ifnet = mac_mls_relabel_ifnet,
2905 .mpo_update_ipq = mac_mls_update_ipq,
2906 .mpo_inpcb_sosetlabel = mac_mls_inpcb_sosetlabel,
2907 .mpo_create_proc0 = mac_mls_create_proc0,
2908 .mpo_create_proc1 = mac_mls_create_proc1,
2909 .mpo_relabel_cred = mac_mls_relabel_cred,
2910 .mpo_cleanup_sysv_msgmsg = mac_mls_cleanup_sysv_msgmsg,
2911 .mpo_cleanup_sysv_msgqueue = mac_mls_cleanup_sysv_msgqueue,
2912 .mpo_cleanup_sysv_sem = mac_mls_cleanup_sysv_sem,
2913 .mpo_cleanup_sysv_shm = mac_mls_cleanup_sysv_shm,
2914 .mpo_check_bpfdesc_receive = mac_mls_check_bpfdesc_receive,
2915 .mpo_check_cred_relabel = mac_mls_check_cred_relabel,
2916 .mpo_check_cred_visible = mac_mls_check_cred_visible,
2917 .mpo_check_ifnet_relabel = mac_mls_check_ifnet_relabel,
2918 .mpo_check_ifnet_transmit = mac_mls_check_ifnet_transmit,
2919 .mpo_check_inpcb_deliver = mac_mls_check_inpcb_deliver,
2920 .mpo_check_sysv_msgrcv = mac_mls_check_sysv_msgrcv,
2921 .mpo_check_sysv_msgrmid = mac_mls_check_sysv_msgrmid,
2922 .mpo_check_sysv_msqget = mac_mls_check_sysv_msqget,
2923 .mpo_check_sysv_msqsnd = mac_mls_check_sysv_msqsnd,
2924 .mpo_check_sysv_msqrcv = mac_mls_check_sysv_msqrcv,
2925 .mpo_check_sysv_msqctl = mac_mls_check_sysv_msqctl,
2926 .mpo_check_sysv_semctl = mac_mls_check_sysv_semctl,
2927 .mpo_check_sysv_semget = mac_mls_check_sysv_semget,
2928 .mpo_check_sysv_semop = mac_mls_check_sysv_semop,
2929 .mpo_check_sysv_shmat = mac_mls_check_sysv_shmat,
2930 .mpo_check_sysv_shmctl = mac_mls_check_sysv_shmctl,
2931 .mpo_check_sysv_shmget = mac_mls_check_sysv_shmget,
2932 .mpo_check_mount_stat = mac_mls_check_mount_stat,
2933 .mpo_check_pipe_ioctl = mac_mls_check_pipe_ioctl,
2934 .mpo_check_pipe_poll = mac_mls_check_pipe_poll,
2935 .mpo_check_pipe_read = mac_mls_check_pipe_read,
2936 .mpo_check_pipe_relabel = mac_mls_check_pipe_relabel,
2937 .mpo_check_pipe_stat = mac_mls_check_pipe_stat,
2938 .mpo_check_pipe_write = mac_mls_check_pipe_write,
2939 .mpo_check_posix_sem_destroy = mac_mls_check_posix_sem_write,
2940 .mpo_check_posix_sem_getvalue = mac_mls_check_posix_sem_rdonly,
2941 .mpo_check_posix_sem_open = mac_mls_check_posix_sem_write,
2942 .mpo_check_posix_sem_post = mac_mls_check_posix_sem_write,
2943 .mpo_check_posix_sem_unlink = mac_mls_check_posix_sem_write,
2944 .mpo_check_posix_sem_wait = mac_mls_check_posix_sem_write,
2945 .mpo_check_proc_debug = mac_mls_check_proc_debug,
2946 .mpo_check_proc_sched = mac_mls_check_proc_sched,
2947 .mpo_check_proc_signal = mac_mls_check_proc_signal,
2948 .mpo_check_socket_deliver = mac_mls_check_socket_deliver,
2949 .mpo_check_socket_relabel = mac_mls_check_socket_relabel,
2950 .mpo_check_socket_visible = mac_mls_check_socket_visible,
2951 .mpo_check_system_swapon = mac_mls_check_system_swapon,
2952 .mpo_check_vnode_access = mac_mls_check_vnode_open,
2953 .mpo_check_vnode_chdir = mac_mls_check_vnode_chdir,
2954 .mpo_check_vnode_chroot = mac_mls_check_vnode_chroot,
2955 .mpo_check_vnode_create = mac_mls_check_vnode_create,
2956 .mpo_check_vnode_delete = mac_mls_check_vnode_delete,
2957 .mpo_check_vnode_deleteacl = mac_mls_check_vnode_deleteacl,
2958 .mpo_check_vnode_deleteextattr = mac_mls_check_vnode_deleteextattr,
2959 .mpo_check_vnode_exec = mac_mls_check_vnode_exec,
2960 .mpo_check_vnode_getacl = mac_mls_check_vnode_getacl,
2961 .mpo_check_vnode_getextattr = mac_mls_check_vnode_getextattr,
2962 .mpo_check_vnode_link = mac_mls_check_vnode_link,
2963 .mpo_check_vnode_listextattr = mac_mls_check_vnode_listextattr,
2964 .mpo_check_vnode_lookup = mac_mls_check_vnode_lookup,
2965 .mpo_check_vnode_mmap = mac_mls_check_vnode_mmap,
2966 .mpo_check_vnode_open = mac_mls_check_vnode_open,
2967 .mpo_check_vnode_poll = mac_mls_check_vnode_poll,
2968 .mpo_check_vnode_read = mac_mls_check_vnode_read,
2969 .mpo_check_vnode_readdir = mac_mls_check_vnode_readdir,
2970 .mpo_check_vnode_readlink = mac_mls_check_vnode_readlink,
2971 .mpo_check_vnode_relabel = mac_mls_check_vnode_relabel,
2972 .mpo_check_vnode_rename_from = mac_mls_check_vnode_rename_from,
2973 .mpo_check_vnode_rename_to = mac_mls_check_vnode_rename_to,
2974 .mpo_check_vnode_revoke = mac_mls_check_vnode_revoke,
2975 .mpo_check_vnode_setacl = mac_mls_check_vnode_setacl,
2976 .mpo_check_vnode_setextattr = mac_mls_check_vnode_setextattr,
2977 .mpo_check_vnode_setflags = mac_mls_check_vnode_setflags,
2978 .mpo_check_vnode_setmode = mac_mls_check_vnode_setmode,
2979 .mpo_check_vnode_setowner = mac_mls_check_vnode_setowner,
2980 .mpo_check_vnode_setutimes = mac_mls_check_vnode_setutimes,
2981 .mpo_check_vnode_stat = mac_mls_check_vnode_stat,
2982 .mpo_check_vnode_write = mac_mls_check_vnode_write,
2983 .mpo_associate_nfsd_label = mac_mls_associate_nfsd_label,
2984 .mpo_create_mbuf_from_firewall = mac_mls_create_mbuf_from_firewall,
2985 };
2986
2987 MAC_POLICY_SET(&mac_mls_ops, mac_mls, "TrustedBSD MAC/MLS",
2988 MPC_LOADTIME_FLAG_NOTLATE | MPC_LOADTIME_FLAG_LABELMBUFS, &mac_mls_slot);
Cache object: 0657752ea9917696da9a0e339f3e80d1
|