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