1 /*-
2 * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson
3 * Copyright (c) 2001, 2002 Networks Associates Technology, Inc.
4 * All rights reserved.
5 *
6 * This software was developed by Robert Watson for the TrustedBSD Project.
7 *
8 * This software was developed for the FreeBSD Project in part by Network
9 * Associates Laboratories, the Security Research Division of Network
10 * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"),
11 * as part of the DARPA CHATS research program.
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 *
34 * $FreeBSD: releng/5.0/sys/security/mac_biba/mac_biba.c 107731 2002-12-10 16:20:34Z rwatson $
35 */
36
37 /*
38 * Developed by the TrustedBSD Project.
39 * Biba fixed label mandatory integrity 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/malloc.h>
50 #include <sys/mount.h>
51 #include <sys/proc.h>
52 #include <sys/systm.h>
53 #include <sys/sysproto.h>
54 #include <sys/sysent.h>
55 #include <sys/systm.h>
56 #include <sys/vnode.h>
57 #include <sys/file.h>
58 #include <sys/socket.h>
59 #include <sys/socketvar.h>
60 #include <sys/pipe.h>
61 #include <sys/sysctl.h>
62
63 #include <fs/devfs/devfs.h>
64
65 #include <net/bpfdesc.h>
66 #include <net/if.h>
67 #include <net/if_types.h>
68 #include <net/if_var.h>
69
70 #include <netinet/in.h>
71 #include <netinet/ip_var.h>
72
73 #include <vm/vm.h>
74
75 #include <sys/mac_policy.h>
76
77 #include <security/mac_biba/mac_biba.h>
78
79 SYSCTL_DECL(_security_mac);
80
81 SYSCTL_NODE(_security_mac, OID_AUTO, biba, CTLFLAG_RW, 0,
82 "TrustedBSD mac_biba policy controls");
83
84 static int mac_biba_label_size = sizeof(struct mac_biba);
85 SYSCTL_INT(_security_mac_biba, OID_AUTO, label_size, CTLFLAG_RD,
86 &mac_biba_label_size, 0, "Size of struct mac_biba");
87
88 static int mac_biba_enabled = 1;
89 SYSCTL_INT(_security_mac_biba, OID_AUTO, enabled, CTLFLAG_RW,
90 &mac_biba_enabled, 0, "Enforce MAC/Biba policy");
91 TUNABLE_INT("security.mac.biba.enabled", &mac_biba_enabled);
92
93 static int destroyed_not_inited;
94 SYSCTL_INT(_security_mac_biba, OID_AUTO, destroyed_not_inited, CTLFLAG_RD,
95 &destroyed_not_inited, 0, "Count of labels destroyed but not inited");
96
97 static int trust_all_interfaces = 0;
98 SYSCTL_INT(_security_mac_biba, OID_AUTO, trust_all_interfaces, CTLFLAG_RD,
99 &trust_all_interfaces, 0, "Consider all interfaces 'trusted' by MAC/Biba");
100 TUNABLE_INT("security.mac.biba.trust_all_interfaces", &trust_all_interfaces);
101
102 static char trusted_interfaces[128];
103 SYSCTL_STRING(_security_mac_biba, OID_AUTO, trusted_interfaces, CTLFLAG_RD,
104 trusted_interfaces, 0, "Interfaces considered 'trusted' by MAC/Biba");
105 TUNABLE_STR("security.mac.biba.trusted_interfaces", trusted_interfaces,
106 sizeof(trusted_interfaces));
107
108 static int max_compartments = MAC_BIBA_MAX_COMPARTMENTS;
109 SYSCTL_INT(_security_mac_biba, OID_AUTO, max_compartments, CTLFLAG_RD,
110 &max_compartments, 0, "Maximum supported compartments");
111
112 static int ptys_equal = 0;
113 SYSCTL_INT(_security_mac_biba, OID_AUTO, ptys_equal, CTLFLAG_RW,
114 &ptys_equal, 0, "Label pty devices as biba/equal on create");
115 TUNABLE_INT("security.mac.biba.ptys_equal", &ptys_equal);
116
117 static int revocation_enabled = 0;
118 SYSCTL_INT(_security_mac_biba, OID_AUTO, revocation_enabled, CTLFLAG_RW,
119 &revocation_enabled, 0, "Revoke access to objects on relabel");
120 TUNABLE_INT("security.mac.biba.revocation_enabled", &revocation_enabled);
121
122 static int mac_biba_slot;
123 #define SLOT(l) ((struct mac_biba *)LABEL_TO_SLOT((l), mac_biba_slot).l_ptr)
124
125 MALLOC_DEFINE(M_MACBIBA, "biba label", "MAC/Biba labels");
126
127 static __inline int
128 biba_bit_set_empty(u_char *set) {
129 int i;
130
131 for (i = 0; i < MAC_BIBA_MAX_COMPARTMENTS >> 3; i++)
132 if (set[i] != 0)
133 return (0);
134 return (1);
135 }
136
137 static struct mac_biba *
138 biba_alloc(int flag)
139 {
140 struct mac_biba *mac_biba;
141
142 mac_biba = malloc(sizeof(struct mac_biba), M_MACBIBA, M_ZERO | flag);
143
144 return (mac_biba);
145 }
146
147 static void
148 biba_free(struct mac_biba *mac_biba)
149 {
150
151 if (mac_biba != NULL)
152 free(mac_biba, M_MACBIBA);
153 else
154 atomic_add_int(&destroyed_not_inited, 1);
155 }
156
157 static int
158 biba_atmostflags(struct mac_biba *mac_biba, int flags)
159 {
160
161 if ((mac_biba->mb_flags & flags) != mac_biba->mb_flags)
162 return (EINVAL);
163 return (0);
164 }
165
166 static int
167 mac_biba_dominate_element(struct mac_biba_element *a,
168 struct mac_biba_element *b)
169 {
170 int bit;
171
172 switch (a->mbe_type) {
173 case MAC_BIBA_TYPE_EQUAL:
174 case MAC_BIBA_TYPE_HIGH:
175 return (1);
176
177 case MAC_BIBA_TYPE_LOW:
178 switch (b->mbe_type) {
179 case MAC_BIBA_TYPE_GRADE:
180 case MAC_BIBA_TYPE_HIGH:
181 return (0);
182
183 case MAC_BIBA_TYPE_EQUAL:
184 case MAC_BIBA_TYPE_LOW:
185 return (1);
186
187 default:
188 panic("mac_biba_dominate_element: b->mbe_type invalid");
189 }
190
191 case MAC_BIBA_TYPE_GRADE:
192 switch (b->mbe_type) {
193 case MAC_BIBA_TYPE_EQUAL:
194 case MAC_BIBA_TYPE_LOW:
195 return (1);
196
197 case MAC_BIBA_TYPE_HIGH:
198 return (0);
199
200 case MAC_BIBA_TYPE_GRADE:
201 for (bit = 1; bit <= MAC_BIBA_MAX_COMPARTMENTS; bit++)
202 if (!MAC_BIBA_BIT_TEST(bit,
203 a->mbe_compartments) &&
204 MAC_BIBA_BIT_TEST(bit, b->mbe_compartments))
205 return (0);
206 return (a->mbe_grade >= b->mbe_grade);
207
208 default:
209 panic("mac_biba_dominate_element: b->mbe_type invalid");
210 }
211
212 default:
213 panic("mac_biba_dominate_element: a->mbe_type invalid");
214 }
215
216 return (0);
217 }
218
219 static int
220 mac_biba_subject_dominate_high(struct mac_biba *mac_biba)
221 {
222 struct mac_biba_element *element;
223
224 KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
225 ("mac_biba_single_in_range: mac_biba not single"));
226 element = &mac_biba->mb_single;
227
228 return (element->mbe_type == MAC_BIBA_TYPE_EQUAL ||
229 element->mbe_type == MAC_BIBA_TYPE_HIGH);
230 }
231
232 static int
233 mac_biba_range_in_range(struct mac_biba *rangea, struct mac_biba *rangeb)
234 {
235
236 return (mac_biba_dominate_element(&rangeb->mb_rangehigh,
237 &rangea->mb_rangehigh) &&
238 mac_biba_dominate_element(&rangea->mb_rangelow,
239 &rangeb->mb_rangelow));
240 }
241
242 static int
243 mac_biba_single_in_range(struct mac_biba *single, struct mac_biba *range)
244 {
245
246 KASSERT((single->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
247 ("mac_biba_single_in_range: a not single"));
248 KASSERT((range->mb_flags & MAC_BIBA_FLAG_RANGE) != 0,
249 ("mac_biba_single_in_range: b not range"));
250
251 return (mac_biba_dominate_element(&range->mb_rangehigh,
252 &single->mb_single) &&
253 mac_biba_dominate_element(&single->mb_single,
254 &range->mb_rangelow));
255
256 return (1);
257 }
258
259 static int
260 mac_biba_dominate_single(struct mac_biba *a, struct mac_biba *b)
261 {
262 KASSERT((a->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
263 ("mac_biba_dominate_single: a not single"));
264 KASSERT((b->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
265 ("mac_biba_dominate_single: b not single"));
266
267 return (mac_biba_dominate_element(&a->mb_single, &b->mb_single));
268 }
269
270 static int
271 mac_biba_equal_element(struct mac_biba_element *a, struct mac_biba_element *b)
272 {
273
274 if (a->mbe_type == MAC_BIBA_TYPE_EQUAL ||
275 b->mbe_type == MAC_BIBA_TYPE_EQUAL)
276 return (1);
277
278 return (a->mbe_type == b->mbe_type && a->mbe_grade == b->mbe_grade);
279 }
280
281 static int
282 mac_biba_equal_single(struct mac_biba *a, struct mac_biba *b)
283 {
284
285 KASSERT((a->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
286 ("mac_biba_equal_single: a not single"));
287 KASSERT((b->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
288 ("mac_biba_equal_single: b not single"));
289
290 return (mac_biba_equal_element(&a->mb_single, &b->mb_single));
291 }
292
293 static int
294 mac_biba_contains_equal(struct mac_biba *mac_biba)
295 {
296
297 if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE)
298 if (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_EQUAL)
299 return (1);
300
301 if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
302 if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL)
303 return (1);
304 if (mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL)
305 return (1);
306 }
307
308 return (0);
309 }
310
311 static int
312 mac_biba_subject_privileged(struct mac_biba *mac_biba)
313 {
314
315 KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAGS_BOTH) ==
316 MAC_BIBA_FLAGS_BOTH,
317 ("mac_biba_subject_privileged: subject doesn't have both labels"));
318
319 /* If the single is EQUAL, it's ok. */
320 if (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_EQUAL)
321 return (0);
322
323 /* If either range endpoint is EQUAL, it's ok. */
324 if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL ||
325 mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL)
326 return (0);
327
328 /* If the range is low-high, it's ok. */
329 if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_LOW &&
330 mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_HIGH)
331 return (0);
332
333 /* It's not ok. */
334 return (EPERM);
335 }
336
337 static int
338 mac_biba_high_single(struct mac_biba *mac_biba)
339 {
340
341 KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
342 ("mac_biba_equal_single: mac_biba not single"));
343
344 return (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_HIGH);
345 }
346
347 static int
348 mac_biba_valid(struct mac_biba *mac_biba)
349 {
350
351 if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) {
352 switch (mac_biba->mb_single.mbe_type) {
353 case MAC_BIBA_TYPE_GRADE:
354 break;
355
356 case MAC_BIBA_TYPE_EQUAL:
357 case MAC_BIBA_TYPE_HIGH:
358 case MAC_BIBA_TYPE_LOW:
359 if (mac_biba->mb_single.mbe_grade != 0 ||
360 !MAC_BIBA_BIT_SET_EMPTY(
361 mac_biba->mb_single.mbe_compartments))
362 return (EINVAL);
363 break;
364
365 default:
366 return (EINVAL);
367 }
368 } else {
369 if (mac_biba->mb_single.mbe_type != MAC_BIBA_TYPE_UNDEF)
370 return (EINVAL);
371 }
372
373 if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
374 switch (mac_biba->mb_rangelow.mbe_type) {
375 case MAC_BIBA_TYPE_GRADE:
376 break;
377
378 case MAC_BIBA_TYPE_EQUAL:
379 case MAC_BIBA_TYPE_HIGH:
380 case MAC_BIBA_TYPE_LOW:
381 if (mac_biba->mb_rangelow.mbe_grade != 0 ||
382 !MAC_BIBA_BIT_SET_EMPTY(
383 mac_biba->mb_rangelow.mbe_compartments))
384 return (EINVAL);
385 break;
386
387 default:
388 return (EINVAL);
389 }
390
391 switch (mac_biba->mb_rangehigh.mbe_type) {
392 case MAC_BIBA_TYPE_GRADE:
393 break;
394
395 case MAC_BIBA_TYPE_EQUAL:
396 case MAC_BIBA_TYPE_HIGH:
397 case MAC_BIBA_TYPE_LOW:
398 if (mac_biba->mb_rangehigh.mbe_grade != 0 ||
399 !MAC_BIBA_BIT_SET_EMPTY(
400 mac_biba->mb_rangehigh.mbe_compartments))
401 return (EINVAL);
402 break;
403
404 default:
405 return (EINVAL);
406 }
407 if (!mac_biba_dominate_element(&mac_biba->mb_rangehigh,
408 &mac_biba->mb_rangelow))
409 return (EINVAL);
410 } else {
411 if (mac_biba->mb_rangelow.mbe_type != MAC_BIBA_TYPE_UNDEF ||
412 mac_biba->mb_rangehigh.mbe_type != MAC_BIBA_TYPE_UNDEF)
413 return (EINVAL);
414 }
415
416 return (0);
417 }
418
419 static void
420 mac_biba_set_range(struct mac_biba *mac_biba, u_short typelow,
421 u_short gradelow, u_char *compartmentslow, u_short typehigh,
422 u_short gradehigh, u_char *compartmentshigh)
423 {
424
425 mac_biba->mb_rangelow.mbe_type = typelow;
426 mac_biba->mb_rangelow.mbe_grade = gradelow;
427 if (compartmentslow != NULL)
428 memcpy(mac_biba->mb_rangelow.mbe_compartments,
429 compartmentslow,
430 sizeof(mac_biba->mb_rangelow.mbe_compartments));
431 mac_biba->mb_rangehigh.mbe_type = typehigh;
432 mac_biba->mb_rangehigh.mbe_grade = gradehigh;
433 if (compartmentshigh != NULL)
434 memcpy(mac_biba->mb_rangehigh.mbe_compartments,
435 compartmentshigh,
436 sizeof(mac_biba->mb_rangehigh.mbe_compartments));
437 mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE;
438 }
439
440 static void
441 mac_biba_set_single(struct mac_biba *mac_biba, u_short type, u_short grade,
442 u_char *compartments)
443 {
444
445 mac_biba->mb_single.mbe_type = type;
446 mac_biba->mb_single.mbe_grade = grade;
447 if (compartments != NULL)
448 memcpy(mac_biba->mb_single.mbe_compartments, compartments,
449 sizeof(mac_biba->mb_single.mbe_compartments));
450 mac_biba->mb_flags |= MAC_BIBA_FLAG_SINGLE;
451 }
452
453 static void
454 mac_biba_copy_range(struct mac_biba *labelfrom, struct mac_biba *labelto)
455 {
456
457 KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_RANGE) != 0,
458 ("mac_biba_copy_range: labelfrom not range"));
459
460 labelto->mb_rangelow = labelfrom->mb_rangelow;
461 labelto->mb_rangehigh = labelfrom->mb_rangehigh;
462 labelto->mb_flags |= MAC_BIBA_FLAG_RANGE;
463 }
464
465 static void
466 mac_biba_copy_single(struct mac_biba *labelfrom, struct mac_biba *labelto)
467 {
468
469 KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
470 ("mac_biba_copy_single: labelfrom not single"));
471
472 labelto->mb_single = labelfrom->mb_single;
473 labelto->mb_flags |= MAC_BIBA_FLAG_SINGLE;
474 }
475
476 static void
477 mac_biba_copy(struct mac_biba *source, struct mac_biba *dest)
478 {
479
480 if (source->mb_flags & MAC_BIBA_FLAG_SINGLE)
481 mac_biba_copy_single(source, dest);
482 if (source->mb_flags & MAC_BIBA_FLAG_RANGE)
483 mac_biba_copy_range(source, dest);
484 }
485
486 /*
487 * Policy module operations.
488 */
489 static void
490 mac_biba_destroy(struct mac_policy_conf *conf)
491 {
492
493 }
494
495 static void
496 mac_biba_init(struct mac_policy_conf *conf)
497 {
498
499 }
500
501 /*
502 * Label operations.
503 */
504 static void
505 mac_biba_init_label(struct label *label)
506 {
507
508 SLOT(label) = biba_alloc(M_WAITOK);
509 }
510
511 static int
512 mac_biba_init_label_waitcheck(struct label *label, int flag)
513 {
514
515 SLOT(label) = biba_alloc(flag);
516 if (SLOT(label) == NULL)
517 return (ENOMEM);
518
519 return (0);
520 }
521
522 static void
523 mac_biba_destroy_label(struct label *label)
524 {
525
526 biba_free(SLOT(label));
527 SLOT(label) = NULL;
528 }
529
530 /*
531 * mac_biba_element_to_string() is basically an snprintf wrapper with
532 * the same properties as snprintf(). It returns the length it would
533 * have added to the string in the event the string is too short.
534 */
535 static size_t
536 mac_biba_element_to_string(char *string, size_t size,
537 struct mac_biba_element *element)
538 {
539 int pos, bit = 1;
540
541 switch (element->mbe_type) {
542 case MAC_BIBA_TYPE_HIGH:
543 return (snprintf(string, size, "high"));
544
545 case MAC_BIBA_TYPE_LOW:
546 return (snprintf(string, size, "low"));
547
548 case MAC_BIBA_TYPE_EQUAL:
549 return (snprintf(string, size, "equal"));
550
551 case MAC_BIBA_TYPE_GRADE:
552 pos = snprintf(string, size, "%d:", element->mbe_grade);
553 for (bit = 1; bit <= MAC_BIBA_MAX_COMPARTMENTS; bit++) {
554 if (MAC_BIBA_BIT_TEST(bit, element->mbe_compartments))
555 pos += snprintf(string + pos, size - pos,
556 "%d+", bit);
557 }
558 if (string[pos - 1] == '+' || string[pos - 1] == ':')
559 string[--pos] = '\0';
560 return (pos);
561
562 default:
563 panic("mac_biba_element_to_string: invalid type (%d)",
564 element->mbe_type);
565 }
566 }
567
568 static int
569 mac_biba_to_string(char *string, size_t size, size_t *caller_len,
570 struct mac_biba *mac_biba)
571 {
572 size_t left, len;
573 char *curptr;
574
575 bzero(string, size);
576 curptr = string;
577 left = size;
578
579 if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) {
580 len = mac_biba_element_to_string(curptr, left,
581 &mac_biba->mb_single);
582 if (len >= left)
583 return (EINVAL);
584 left -= len;
585 curptr += len;
586 }
587
588 if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
589 len = snprintf(curptr, left, "(");
590 if (len >= left)
591 return (EINVAL);
592 left -= len;
593 curptr += len;
594
595 len = mac_biba_element_to_string(curptr, left,
596 &mac_biba->mb_rangelow);
597 if (len >= left)
598 return (EINVAL);
599 left -= len;
600 curptr += len;
601
602 len = snprintf(curptr, left, "-");
603 if (len >= left)
604 return (EINVAL);
605 left -= len;
606 curptr += len;
607
608 len = mac_biba_element_to_string(curptr, left,
609 &mac_biba->mb_rangehigh);
610 if (len >= left)
611 return (EINVAL);
612 left -= len;
613 curptr += len;
614
615 len = snprintf(curptr, left, ")");
616 if (len >= left)
617 return (EINVAL);
618 left -= len;
619 curptr += len;
620 }
621
622 *caller_len = strlen(string);
623 return (0);
624 }
625
626 static int
627 mac_biba_externalize_label(struct label *label, char *element_name,
628 char *element_data, size_t size, size_t *len, int *claimed)
629 {
630 struct mac_biba *mac_biba;
631 int error;
632
633 if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0)
634 return (0);
635
636 (*claimed)++;
637
638 mac_biba = SLOT(label);
639 error = mac_biba_to_string(element_data, size, len, mac_biba);
640 if (error)
641 return (error);
642
643 *len = strlen(element_data);
644 return (0);
645 }
646
647 static int
648 mac_biba_parse_element(struct mac_biba_element *element, char *string)
649 {
650
651 if (strcmp(string, "high") == 0 ||
652 strcmp(string, "hi") == 0) {
653 element->mbe_type = MAC_BIBA_TYPE_HIGH;
654 element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
655 } else if (strcmp(string, "low") == 0 ||
656 strcmp(string, "lo") == 0) {
657 element->mbe_type = MAC_BIBA_TYPE_LOW;
658 element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
659 } else if (strcmp(string, "equal") == 0 ||
660 strcmp(string, "eq") == 0) {
661 element->mbe_type = MAC_BIBA_TYPE_EQUAL;
662 element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
663 } else {
664 char *p0, *p1;
665 int d;
666
667 p0 = string;
668 d = strtol(p0, &p1, 10);
669
670 if (d < 0 || d > 65535)
671 return (EINVAL);
672 element->mbe_type = MAC_BIBA_TYPE_GRADE;
673 element->mbe_grade = d;
674
675 if (*p1 != ':') {
676 if (p1 == p0 || *p1 != '\0')
677 return (EINVAL);
678 else
679 return (0);
680 }
681 else
682 if (*(p1 + 1) == '\0')
683 return (0);
684
685 while ((p0 = ++p1)) {
686 d = strtol(p0, &p1, 10);
687 if (d < 1 || d > MAC_BIBA_MAX_COMPARTMENTS)
688 return (EINVAL);
689
690 MAC_BIBA_BIT_SET(d, element->mbe_compartments);
691
692 if (*p1 == '\0')
693 break;
694 if (p1 == p0 || *p1 != '+')
695 return (EINVAL);
696 }
697 }
698
699 return (0);
700 }
701
702 /*
703 * Note: destructively consumes the string, make a local copy before
704 * calling if that's a problem.
705 */
706 static int
707 mac_biba_parse(struct mac_biba *mac_biba, char *string)
708 {
709 char *range, *rangeend, *rangehigh, *rangelow, *single;
710 int error;
711
712 /* Do we have a range? */
713 single = string;
714 range = index(string, '(');
715 if (range == single)
716 single = NULL;
717 rangelow = rangehigh = NULL;
718 if (range != NULL) {
719 /* Nul terminate the end of the single string. */
720 *range = '\0';
721 range++;
722 rangelow = range;
723 rangehigh = index(rangelow, '-');
724 if (rangehigh == NULL)
725 return (EINVAL);
726 rangehigh++;
727 if (*rangelow == '\0' || *rangehigh == '\0')
728 return (EINVAL);
729 rangeend = index(rangehigh, ')');
730 if (rangeend == NULL)
731 return (EINVAL);
732 if (*(rangeend + 1) != '\0')
733 return (EINVAL);
734 /* Nul terminate the ends of the ranges. */
735 *(rangehigh - 1) = '\0';
736 *rangeend = '\0';
737 }
738 KASSERT((rangelow != NULL && rangehigh != NULL) ||
739 (rangelow == NULL && rangehigh == NULL),
740 ("mac_biba_internalize_label: range mismatch"));
741
742 bzero(mac_biba, sizeof(*mac_biba));
743 if (single != NULL) {
744 error = mac_biba_parse_element(&mac_biba->mb_single, single);
745 if (error)
746 return (error);
747 mac_biba->mb_flags |= MAC_BIBA_FLAG_SINGLE;
748 }
749
750 if (rangelow != NULL) {
751 error = mac_biba_parse_element(&mac_biba->mb_rangelow,
752 rangelow);
753 if (error)
754 return (error);
755 error = mac_biba_parse_element(&mac_biba->mb_rangehigh,
756 rangehigh);
757 if (error)
758 return (error);
759 mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE;
760 }
761
762 error = mac_biba_valid(mac_biba);
763 if (error)
764 return (error);
765
766 return (0);
767 }
768
769 static int
770 mac_biba_internalize_label(struct label *label, char *element_name,
771 char *element_data, int *claimed)
772 {
773 struct mac_biba *mac_biba, mac_biba_temp;
774 int error;
775
776 if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0)
777 return (0);
778
779 (*claimed)++;
780
781 error = mac_biba_parse(&mac_biba_temp, element_data);
782 if (error)
783 return (error);
784
785 mac_biba = SLOT(label);
786 *mac_biba = mac_biba_temp;
787
788 return (0);
789 }
790
791 static void
792 mac_biba_copy_label(struct label *src, struct label *dest)
793 {
794
795 *SLOT(dest) = *SLOT(src);
796 }
797
798 /*
799 * Labeling event operations: file system objects, and things that look
800 * a lot like file system objects.
801 */
802 static void
803 mac_biba_create_devfs_device(struct mount *mp, dev_t dev,
804 struct devfs_dirent *devfs_dirent, struct label *label)
805 {
806 struct mac_biba *mac_biba;
807 int biba_type;
808
809 mac_biba = SLOT(label);
810 if (strcmp(dev->si_name, "null") == 0 ||
811 strcmp(dev->si_name, "zero") == 0 ||
812 strcmp(dev->si_name, "random") == 0 ||
813 strncmp(dev->si_name, "fd/", strlen("fd/")) == 0)
814 biba_type = MAC_BIBA_TYPE_EQUAL;
815 else if (ptys_equal &&
816 (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 ||
817 strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0))
818 biba_type = MAC_BIBA_TYPE_EQUAL;
819 else
820 biba_type = MAC_BIBA_TYPE_HIGH;
821 mac_biba_set_single(mac_biba, biba_type, 0, NULL);
822 }
823
824 static void
825 mac_biba_create_devfs_directory(struct mount *mp, char *dirname,
826 int dirnamelen, struct devfs_dirent *devfs_dirent, struct label *label)
827 {
828 struct mac_biba *mac_biba;
829
830 mac_biba = SLOT(label);
831 mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
832 }
833
834 static void
835 mac_biba_create_devfs_symlink(struct ucred *cred, struct mount *mp,
836 struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de,
837 struct label *delabel)
838 {
839 struct mac_biba *source, *dest;
840
841 source = SLOT(&cred->cr_label);
842 dest = SLOT(delabel);
843
844 mac_biba_copy_single(source, dest);
845 }
846
847 static void
848 mac_biba_create_mount(struct ucred *cred, struct mount *mp,
849 struct label *mntlabel, struct label *fslabel)
850 {
851 struct mac_biba *source, *dest;
852
853 source = SLOT(&cred->cr_label);
854 dest = SLOT(mntlabel);
855 mac_biba_copy_single(source, dest);
856 dest = SLOT(fslabel);
857 mac_biba_copy_single(source, dest);
858 }
859
860 static void
861 mac_biba_create_root_mount(struct ucred *cred, struct mount *mp,
862 struct label *mntlabel, struct label *fslabel)
863 {
864 struct mac_biba *mac_biba;
865
866 /* Always mount root as high integrity. */
867 mac_biba = SLOT(fslabel);
868 mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
869 mac_biba = SLOT(mntlabel);
870 mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
871 }
872
873 static void
874 mac_biba_relabel_vnode(struct ucred *cred, struct vnode *vp,
875 struct label *vnodelabel, struct label *label)
876 {
877 struct mac_biba *source, *dest;
878
879 source = SLOT(label);
880 dest = SLOT(vnodelabel);
881
882 mac_biba_copy(source, dest);
883 }
884
885 static void
886 mac_biba_update_devfsdirent(struct mount *mp,
887 struct devfs_dirent *devfs_dirent, struct label *direntlabel,
888 struct vnode *vp, struct label *vnodelabel)
889 {
890 struct mac_biba *source, *dest;
891
892 source = SLOT(vnodelabel);
893 dest = SLOT(direntlabel);
894
895 mac_biba_copy(source, dest);
896 }
897
898 static void
899 mac_biba_associate_vnode_devfs(struct mount *mp, struct label *fslabel,
900 struct devfs_dirent *de, struct label *delabel, struct vnode *vp,
901 struct label *vlabel)
902 {
903 struct mac_biba *source, *dest;
904
905 source = SLOT(delabel);
906 dest = SLOT(vlabel);
907
908 mac_biba_copy_single(source, dest);
909 }
910
911 static int
912 mac_biba_associate_vnode_extattr(struct mount *mp, struct label *fslabel,
913 struct vnode *vp, struct label *vlabel)
914 {
915 struct mac_biba temp, *source, *dest;
916 int buflen, error;
917
918 source = SLOT(fslabel);
919 dest = SLOT(vlabel);
920
921 buflen = sizeof(temp);
922 bzero(&temp, buflen);
923
924 error = vn_extattr_get(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
925 MAC_BIBA_EXTATTR_NAME, &buflen, (char *) &temp, curthread);
926 if (error == ENOATTR || error == EOPNOTSUPP) {
927 /* Fall back to the fslabel. */
928 mac_biba_copy_single(source, dest);
929 return (0);
930 } else if (error)
931 return (error);
932
933 if (buflen != sizeof(temp)) {
934 printf("mac_biba_associate_vnode_extattr: bad size %d\n",
935 buflen);
936 return (EPERM);
937 }
938 if (mac_biba_valid(&temp) != 0) {
939 printf("mac_biba_associate_vnode_extattr: invalid\n");
940 return (EPERM);
941 }
942 if ((temp.mb_flags & MAC_BIBA_FLAGS_BOTH) != MAC_BIBA_FLAG_SINGLE) {
943 printf("mac_biba_associate_vnode_extattr: not single\n");
944 return (EPERM);
945 }
946
947 mac_biba_copy_single(&temp, dest);
948 return (0);
949 }
950
951 static void
952 mac_biba_associate_vnode_singlelabel(struct mount *mp,
953 struct label *fslabel, struct vnode *vp, struct label *vlabel)
954 {
955 struct mac_biba *source, *dest;
956
957 source = SLOT(fslabel);
958 dest = SLOT(vlabel);
959
960 mac_biba_copy_single(source, dest);
961 }
962
963 static int
964 mac_biba_create_vnode_extattr(struct ucred *cred, struct mount *mp,
965 struct label *fslabel, struct vnode *dvp, struct label *dlabel,
966 struct vnode *vp, struct label *vlabel, struct componentname *cnp)
967 {
968 struct mac_biba *source, *dest, temp;
969 size_t buflen;
970 int error;
971
972 buflen = sizeof(temp);
973 bzero(&temp, buflen);
974
975 source = SLOT(&cred->cr_label);
976 dest = SLOT(vlabel);
977 mac_biba_copy_single(source, &temp);
978
979 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
980 MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread);
981 if (error == 0)
982 mac_biba_copy_single(source, dest);
983 return (error);
984 }
985
986 static int
987 mac_biba_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp,
988 struct label *vlabel, struct label *intlabel)
989 {
990 struct mac_biba *source, temp;
991 size_t buflen;
992 int error;
993
994 buflen = sizeof(temp);
995 bzero(&temp, buflen);
996
997 source = SLOT(intlabel);
998 if ((source->mb_flags & MAC_BIBA_FLAG_SINGLE) == 0)
999 return (0);
1000
1001 mac_biba_copy_single(source, &temp);
1002
1003 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
1004 MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread);
1005 return (error);
1006 }
1007
1008 /*
1009 * Labeling event operations: IPC object.
1010 */
1011 static void
1012 mac_biba_create_mbuf_from_socket(struct socket *so, struct label *socketlabel,
1013 struct mbuf *m, struct label *mbuflabel)
1014 {
1015 struct mac_biba *source, *dest;
1016
1017 source = SLOT(socketlabel);
1018 dest = SLOT(mbuflabel);
1019
1020 mac_biba_copy_single(source, dest);
1021 }
1022
1023 static void
1024 mac_biba_create_socket(struct ucred *cred, struct socket *socket,
1025 struct label *socketlabel)
1026 {
1027 struct mac_biba *source, *dest;
1028
1029 source = SLOT(&cred->cr_label);
1030 dest = SLOT(socketlabel);
1031
1032 mac_biba_copy_single(source, dest);
1033 }
1034
1035 static void
1036 mac_biba_create_pipe(struct ucred *cred, struct pipe *pipe,
1037 struct label *pipelabel)
1038 {
1039 struct mac_biba *source, *dest;
1040
1041 source = SLOT(&cred->cr_label);
1042 dest = SLOT(pipelabel);
1043
1044 mac_biba_copy_single(source, dest);
1045 }
1046
1047 static void
1048 mac_biba_create_socket_from_socket(struct socket *oldsocket,
1049 struct label *oldsocketlabel, struct socket *newsocket,
1050 struct label *newsocketlabel)
1051 {
1052 struct mac_biba *source, *dest;
1053
1054 source = SLOT(oldsocketlabel);
1055 dest = SLOT(newsocketlabel);
1056
1057 mac_biba_copy_single(source, dest);
1058 }
1059
1060 static void
1061 mac_biba_relabel_socket(struct ucred *cred, struct socket *socket,
1062 struct label *socketlabel, struct label *newlabel)
1063 {
1064 struct mac_biba *source, *dest;
1065
1066 source = SLOT(newlabel);
1067 dest = SLOT(socketlabel);
1068
1069 mac_biba_copy(source, dest);
1070 }
1071
1072 static void
1073 mac_biba_relabel_pipe(struct ucred *cred, struct pipe *pipe,
1074 struct label *pipelabel, struct label *newlabel)
1075 {
1076 struct mac_biba *source, *dest;
1077
1078 source = SLOT(newlabel);
1079 dest = SLOT(pipelabel);
1080
1081 mac_biba_copy(source, dest);
1082 }
1083
1084 static void
1085 mac_biba_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel,
1086 struct socket *socket, struct label *socketpeerlabel)
1087 {
1088 struct mac_biba *source, *dest;
1089
1090 source = SLOT(mbuflabel);
1091 dest = SLOT(socketpeerlabel);
1092
1093 mac_biba_copy_single(source, dest);
1094 }
1095
1096 /*
1097 * Labeling event operations: network objects.
1098 */
1099 static void
1100 mac_biba_set_socket_peer_from_socket(struct socket *oldsocket,
1101 struct label *oldsocketlabel, struct socket *newsocket,
1102 struct label *newsocketpeerlabel)
1103 {
1104 struct mac_biba *source, *dest;
1105
1106 source = SLOT(oldsocketlabel);
1107 dest = SLOT(newsocketpeerlabel);
1108
1109 mac_biba_copy_single(source, dest);
1110 }
1111
1112 static void
1113 mac_biba_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d,
1114 struct label *bpflabel)
1115 {
1116 struct mac_biba *source, *dest;
1117
1118 source = SLOT(&cred->cr_label);
1119 dest = SLOT(bpflabel);
1120
1121 mac_biba_copy_single(source, dest);
1122 }
1123
1124 static void
1125 mac_biba_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel)
1126 {
1127 char tifname[IFNAMSIZ], ifname[IFNAMSIZ], *p, *q;
1128 char tiflist[sizeof(trusted_interfaces)];
1129 struct mac_biba *dest;
1130 int len, grade;
1131
1132 dest = SLOT(ifnetlabel);
1133
1134 if (ifnet->if_type == IFT_LOOP) {
1135 grade = MAC_BIBA_TYPE_EQUAL;
1136 goto set;
1137 }
1138
1139 if (trust_all_interfaces) {
1140 grade = MAC_BIBA_TYPE_HIGH;
1141 goto set;
1142 }
1143
1144 grade = MAC_BIBA_TYPE_LOW;
1145
1146 if (trusted_interfaces[0] == '\0' ||
1147 !strvalid(trusted_interfaces, sizeof(trusted_interfaces)))
1148 goto set;
1149
1150 bzero(tiflist, sizeof(tiflist));
1151 for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++)
1152 if(*p != ' ' && *p != '\t')
1153 *q = *p;
1154
1155 snprintf(ifname, IFNAMSIZ, "%s%d", ifnet->if_name, ifnet->if_unit);
1156
1157 for (p = q = tiflist;; p++) {
1158 if (*p == ',' || *p == '\0') {
1159 len = p - q;
1160 if (len < IFNAMSIZ) {
1161 bzero(tifname, sizeof(tifname));
1162 bcopy(q, tifname, len);
1163 if (strcmp(tifname, ifname) == 0) {
1164 grade = MAC_BIBA_TYPE_HIGH;
1165 break;
1166 }
1167 } else {
1168 *p = '\0';
1169 printf("mac_biba warning: interface name "
1170 "\"%s\" is too long (must be < %d)\n",
1171 q, IFNAMSIZ);
1172 }
1173 if (*p == '\0')
1174 break;
1175 q = p + 1;
1176 }
1177 }
1178 set:
1179 mac_biba_set_single(dest, grade, 0, NULL);
1180 mac_biba_set_range(dest, grade, 0, NULL, grade, 0, NULL);
1181 }
1182
1183 static void
1184 mac_biba_create_ipq(struct mbuf *fragment, struct label *fragmentlabel,
1185 struct ipq *ipq, struct label *ipqlabel)
1186 {
1187 struct mac_biba *source, *dest;
1188
1189 source = SLOT(fragmentlabel);
1190 dest = SLOT(ipqlabel);
1191
1192 mac_biba_copy_single(source, dest);
1193 }
1194
1195 static void
1196 mac_biba_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel,
1197 struct mbuf *datagram, struct label *datagramlabel)
1198 {
1199 struct mac_biba *source, *dest;
1200
1201 source = SLOT(ipqlabel);
1202 dest = SLOT(datagramlabel);
1203
1204 /* Just use the head, since we require them all to match. */
1205 mac_biba_copy_single(source, dest);
1206 }
1207
1208 static void
1209 mac_biba_create_fragment(struct mbuf *datagram, struct label *datagramlabel,
1210 struct mbuf *fragment, struct label *fragmentlabel)
1211 {
1212 struct mac_biba *source, *dest;
1213
1214 source = SLOT(datagramlabel);
1215 dest = SLOT(fragmentlabel);
1216
1217 mac_biba_copy_single(source, dest);
1218 }
1219
1220 static void
1221 mac_biba_create_mbuf_from_mbuf(struct mbuf *oldmbuf,
1222 struct label *oldmbuflabel, struct mbuf *newmbuf,
1223 struct label *newmbuflabel)
1224 {
1225 struct mac_biba *source, *dest;
1226
1227 source = SLOT(oldmbuflabel);
1228 dest = SLOT(newmbuflabel);
1229
1230 /*
1231 * Because the source mbuf may not yet have been "created",
1232 * just initialized, we do a conditional copy. Since we don't
1233 * allow mbufs to have ranges, do a KASSERT to make sure that
1234 * doesn't happen.
1235 */
1236 KASSERT((source->mb_flags & MAC_BIBA_FLAG_RANGE) == 0,
1237 ("mac_biba_create_mbuf_from_mbuf: source mbuf has range"));
1238 mac_biba_copy(source, dest);
1239 }
1240
1241 static void
1242 mac_biba_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel,
1243 struct mbuf *mbuf, struct label *mbuflabel)
1244 {
1245 struct mac_biba *dest;
1246
1247 dest = SLOT(mbuflabel);
1248
1249 mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1250 }
1251
1252 static void
1253 mac_biba_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel,
1254 struct mbuf *mbuf, struct label *mbuflabel)
1255 {
1256 struct mac_biba *source, *dest;
1257
1258 source = SLOT(bpflabel);
1259 dest = SLOT(mbuflabel);
1260
1261 mac_biba_copy_single(source, dest);
1262 }
1263
1264 static void
1265 mac_biba_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel,
1266 struct mbuf *m, struct label *mbuflabel)
1267 {
1268 struct mac_biba *source, *dest;
1269
1270 source = SLOT(ifnetlabel);
1271 dest = SLOT(mbuflabel);
1272
1273 mac_biba_copy_single(source, dest);
1274 }
1275
1276 static void
1277 mac_biba_create_mbuf_multicast_encap(struct mbuf *oldmbuf,
1278 struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel,
1279 struct mbuf *newmbuf, struct label *newmbuflabel)
1280 {
1281 struct mac_biba *source, *dest;
1282
1283 source = SLOT(oldmbuflabel);
1284 dest = SLOT(newmbuflabel);
1285
1286 mac_biba_copy_single(source, dest);
1287 }
1288
1289 static void
1290 mac_biba_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel,
1291 struct mbuf *newmbuf, struct label *newmbuflabel)
1292 {
1293 struct mac_biba *source, *dest;
1294
1295 source = SLOT(oldmbuflabel);
1296 dest = SLOT(newmbuflabel);
1297
1298 mac_biba_copy_single(source, dest);
1299 }
1300
1301 static int
1302 mac_biba_fragment_match(struct mbuf *fragment, struct label *fragmentlabel,
1303 struct ipq *ipq, struct label *ipqlabel)
1304 {
1305 struct mac_biba *a, *b;
1306
1307 a = SLOT(ipqlabel);
1308 b = SLOT(fragmentlabel);
1309
1310 return (mac_biba_equal_single(a, b));
1311 }
1312
1313 static void
1314 mac_biba_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet,
1315 struct label *ifnetlabel, struct label *newlabel)
1316 {
1317 struct mac_biba *source, *dest;
1318
1319 source = SLOT(newlabel);
1320 dest = SLOT(ifnetlabel);
1321
1322 mac_biba_copy(source, dest);
1323 }
1324
1325 static void
1326 mac_biba_update_ipq(struct mbuf *fragment, struct label *fragmentlabel,
1327 struct ipq *ipq, struct label *ipqlabel)
1328 {
1329
1330 /* NOOP: we only accept matching labels, so no need to update */
1331 }
1332
1333 /*
1334 * Labeling event operations: processes.
1335 */
1336 static void
1337 mac_biba_create_cred(struct ucred *cred_parent, struct ucred *cred_child)
1338 {
1339 struct mac_biba *source, *dest;
1340
1341 source = SLOT(&cred_parent->cr_label);
1342 dest = SLOT(&cred_child->cr_label);
1343
1344 mac_biba_copy_single(source, dest);
1345 mac_biba_copy_range(source, dest);
1346 }
1347
1348 static void
1349 mac_biba_create_proc0(struct ucred *cred)
1350 {
1351 struct mac_biba *dest;
1352
1353 dest = SLOT(&cred->cr_label);
1354
1355 mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1356 mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL,
1357 MAC_BIBA_TYPE_HIGH, 0, NULL);
1358 }
1359
1360 static void
1361 mac_biba_create_proc1(struct ucred *cred)
1362 {
1363 struct mac_biba *dest;
1364
1365 dest = SLOT(&cred->cr_label);
1366
1367 mac_biba_set_single(dest, MAC_BIBA_TYPE_HIGH, 0, NULL);
1368 mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL,
1369 MAC_BIBA_TYPE_HIGH, 0, NULL);
1370 }
1371
1372 static void
1373 mac_biba_relabel_cred(struct ucred *cred, struct label *newlabel)
1374 {
1375 struct mac_biba *source, *dest;
1376
1377 source = SLOT(newlabel);
1378 dest = SLOT(&cred->cr_label);
1379
1380 mac_biba_copy(source, dest);
1381 }
1382
1383 /*
1384 * Access control checks.
1385 */
1386 static int
1387 mac_biba_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel,
1388 struct ifnet *ifnet, struct label *ifnetlabel)
1389 {
1390 struct mac_biba *a, *b;
1391
1392 if (!mac_biba_enabled)
1393 return (0);
1394
1395 a = SLOT(bpflabel);
1396 b = SLOT(ifnetlabel);
1397
1398 if (mac_biba_equal_single(a, b))
1399 return (0);
1400 return (EACCES);
1401 }
1402
1403 static int
1404 mac_biba_check_cred_relabel(struct ucred *cred, struct label *newlabel)
1405 {
1406 struct mac_biba *subj, *new;
1407 int error;
1408
1409 subj = SLOT(&cred->cr_label);
1410 new = SLOT(newlabel);
1411
1412 /*
1413 * If there is a Biba label update for the credential, it may
1414 * be an update of the single, range, or both.
1415 */
1416 error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
1417 if (error)
1418 return (error);
1419
1420 /*
1421 * If the Biba label is to be changed, authorize as appropriate.
1422 */
1423 if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) {
1424 /*
1425 * To change the Biba single label on a credential, the
1426 * new single label must be in the current range.
1427 */
1428 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE &&
1429 !mac_biba_single_in_range(new, subj))
1430 return (EPERM);
1431
1432 /*
1433 * To change the Biba range on a credential, the new
1434 * range label must be in the current range.
1435 */
1436 if (new->mb_flags & MAC_BIBA_FLAG_RANGE &&
1437 !mac_biba_range_in_range(new, subj))
1438 return (EPERM);
1439
1440 /*
1441 * To have EQUAL in any component of the new credential
1442 * Biba label, the subject must already have EQUAL in
1443 * their label.
1444 */
1445 if (mac_biba_contains_equal(new)) {
1446 error = mac_biba_subject_privileged(subj);
1447 if (error)
1448 return (error);
1449 }
1450
1451 /*
1452 * XXXMAC: Additional consistency tests regarding the
1453 * single and range of the new label might be performed
1454 * here.
1455 */
1456 }
1457
1458 return (0);
1459 }
1460
1461 static int
1462 mac_biba_check_cred_visible(struct ucred *u1, struct ucred *u2)
1463 {
1464 struct mac_biba *subj, *obj;
1465
1466 if (!mac_biba_enabled)
1467 return (0);
1468
1469 subj = SLOT(&u1->cr_label);
1470 obj = SLOT(&u2->cr_label);
1471
1472 /* XXX: range */
1473 if (!mac_biba_dominate_single(obj, subj))
1474 return (ESRCH);
1475
1476 return (0);
1477 }
1478
1479 static int
1480 mac_biba_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet,
1481 struct label *ifnetlabel, struct label *newlabel)
1482 {
1483 struct mac_biba *subj, *new;
1484 int error;
1485
1486 subj = SLOT(&cred->cr_label);
1487 new = SLOT(newlabel);
1488
1489 /*
1490 * If there is a Biba label update for the interface, it may
1491 * be an update of the single, range, or both.
1492 */
1493 error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
1494 if (error)
1495 return (error);
1496
1497 /*
1498 * Relabling network interfaces requires Biba privilege.
1499 */
1500 error = mac_biba_subject_privileged(subj);
1501 if (error)
1502 return (error);
1503
1504 /*
1505 * If the Biba label is to be changed, authorize as appropriate.
1506 */
1507 if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) {
1508 /*
1509 * Rely on the traditional superuser status for the Biba
1510 * interface relabel requirements. XXXMAC: This will go
1511 * away.
1512 */
1513 error = suser_cred(cred, 0);
1514 if (error)
1515 return (EPERM);
1516
1517 /*
1518 * XXXMAC: Additional consistency tests regarding the single
1519 * and the range of the new label might be performed here.
1520 */
1521 }
1522
1523 return (0);
1524 }
1525
1526 static int
1527 mac_biba_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel,
1528 struct mbuf *m, struct label *mbuflabel)
1529 {
1530 struct mac_biba *p, *i;
1531
1532 if (!mac_biba_enabled)
1533 return (0);
1534
1535 p = SLOT(mbuflabel);
1536 i = SLOT(ifnetlabel);
1537
1538 return (mac_biba_single_in_range(p, i) ? 0 : EACCES);
1539 }
1540
1541 static int
1542 mac_biba_check_mount_stat(struct ucred *cred, struct mount *mp,
1543 struct label *mntlabel)
1544 {
1545 struct mac_biba *subj, *obj;
1546
1547 if (!mac_biba_enabled)
1548 return (0);
1549
1550 subj = SLOT(&cred->cr_label);
1551 obj = SLOT(mntlabel);
1552
1553 if (!mac_biba_dominate_single(obj, subj))
1554 return (EACCES);
1555
1556 return (0);
1557 }
1558
1559 static int
1560 mac_biba_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe,
1561 struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data)
1562 {
1563
1564 if(!mac_biba_enabled)
1565 return (0);
1566
1567 /* XXX: This will be implemented soon... */
1568
1569 return (0);
1570 }
1571
1572 static int
1573 mac_biba_check_pipe_poll(struct ucred *cred, struct pipe *pipe,
1574 struct label *pipelabel)
1575 {
1576 struct mac_biba *subj, *obj;
1577
1578 if (!mac_biba_enabled)
1579 return (0);
1580
1581 subj = SLOT(&cred->cr_label);
1582 obj = SLOT((pipelabel));
1583
1584 if (!mac_biba_dominate_single(obj, subj))
1585 return (EACCES);
1586
1587 return (0);
1588 }
1589
1590 static int
1591 mac_biba_check_pipe_read(struct ucred *cred, struct pipe *pipe,
1592 struct label *pipelabel)
1593 {
1594 struct mac_biba *subj, *obj;
1595
1596 if (!mac_biba_enabled)
1597 return (0);
1598
1599 subj = SLOT(&cred->cr_label);
1600 obj = SLOT((pipelabel));
1601
1602 if (!mac_biba_dominate_single(obj, subj))
1603 return (EACCES);
1604
1605 return (0);
1606 }
1607
1608 static int
1609 mac_biba_check_pipe_relabel(struct ucred *cred, struct pipe *pipe,
1610 struct label *pipelabel, struct label *newlabel)
1611 {
1612 struct mac_biba *subj, *obj, *new;
1613 int error;
1614
1615 new = SLOT(newlabel);
1616 subj = SLOT(&cred->cr_label);
1617 obj = SLOT(pipelabel);
1618
1619 /*
1620 * If there is a Biba label update for a pipe, it must be a
1621 * single update.
1622 */
1623 error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE);
1624 if (error)
1625 return (error);
1626
1627 /*
1628 * To perform a relabel of a pipe (Biba label or not), Biba must
1629 * authorize the relabel.
1630 */
1631 if (!mac_biba_single_in_range(obj, subj))
1632 return (EPERM);
1633
1634 /*
1635 * If the Biba label is to be changed, authorize as appropriate.
1636 */
1637 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) {
1638 /*
1639 * To change the Biba label on a pipe, the new pipe label
1640 * must be in the subject range.
1641 */
1642 if (!mac_biba_single_in_range(new, subj))
1643 return (EPERM);
1644
1645 /*
1646 * To change the Biba label on a pipe to be EQUAL, the
1647 * subject must have appropriate privilege.
1648 */
1649 if (mac_biba_contains_equal(new)) {
1650 error = mac_biba_subject_privileged(subj);
1651 if (error)
1652 return (error);
1653 }
1654 }
1655
1656 return (0);
1657 }
1658
1659 static int
1660 mac_biba_check_pipe_stat(struct ucred *cred, struct pipe *pipe,
1661 struct label *pipelabel)
1662 {
1663 struct mac_biba *subj, *obj;
1664
1665 if (!mac_biba_enabled)
1666 return (0);
1667
1668 subj = SLOT(&cred->cr_label);
1669 obj = SLOT((pipelabel));
1670
1671 if (!mac_biba_dominate_single(obj, subj))
1672 return (EACCES);
1673
1674 return (0);
1675 }
1676
1677 static int
1678 mac_biba_check_pipe_write(struct ucred *cred, struct pipe *pipe,
1679 struct label *pipelabel)
1680 {
1681 struct mac_biba *subj, *obj;
1682
1683 if (!mac_biba_enabled)
1684 return (0);
1685
1686 subj = SLOT(&cred->cr_label);
1687 obj = SLOT((pipelabel));
1688
1689 if (!mac_biba_dominate_single(subj, obj))
1690 return (EACCES);
1691
1692 return (0);
1693 }
1694
1695 static int
1696 mac_biba_check_proc_debug(struct ucred *cred, struct proc *proc)
1697 {
1698 struct mac_biba *subj, *obj;
1699
1700 if (!mac_biba_enabled)
1701 return (0);
1702
1703 subj = SLOT(&cred->cr_label);
1704 obj = SLOT(&proc->p_ucred->cr_label);
1705
1706 /* XXX: range checks */
1707 if (!mac_biba_dominate_single(obj, subj))
1708 return (ESRCH);
1709 if (!mac_biba_dominate_single(subj, obj))
1710 return (EACCES);
1711
1712 return (0);
1713 }
1714
1715 static int
1716 mac_biba_check_proc_sched(struct ucred *cred, struct proc *proc)
1717 {
1718 struct mac_biba *subj, *obj;
1719
1720 if (!mac_biba_enabled)
1721 return (0);
1722
1723 subj = SLOT(&cred->cr_label);
1724 obj = SLOT(&proc->p_ucred->cr_label);
1725
1726 /* XXX: range checks */
1727 if (!mac_biba_dominate_single(obj, subj))
1728 return (ESRCH);
1729 if (!mac_biba_dominate_single(subj, obj))
1730 return (EACCES);
1731
1732 return (0);
1733 }
1734
1735 static int
1736 mac_biba_check_proc_signal(struct ucred *cred, struct proc *proc, int signum)
1737 {
1738 struct mac_biba *subj, *obj;
1739
1740 if (!mac_biba_enabled)
1741 return (0);
1742
1743 subj = SLOT(&cred->cr_label);
1744 obj = SLOT(&proc->p_ucred->cr_label);
1745
1746 /* XXX: range checks */
1747 if (!mac_biba_dominate_single(obj, subj))
1748 return (ESRCH);
1749 if (!mac_biba_dominate_single(subj, obj))
1750 return (EACCES);
1751
1752 return (0);
1753 }
1754
1755 static int
1756 mac_biba_check_socket_deliver(struct socket *so, struct label *socketlabel,
1757 struct mbuf *m, struct label *mbuflabel)
1758 {
1759 struct mac_biba *p, *s;
1760
1761 if (!mac_biba_enabled)
1762 return (0);
1763
1764 p = SLOT(mbuflabel);
1765 s = SLOT(socketlabel);
1766
1767 return (mac_biba_equal_single(p, s) ? 0 : EACCES);
1768 }
1769
1770 static int
1771 mac_biba_check_socket_relabel(struct ucred *cred, struct socket *so,
1772 struct label *socketlabel, struct label *newlabel)
1773 {
1774 struct mac_biba *subj, *obj, *new;
1775 int error;
1776
1777 new = SLOT(newlabel);
1778 subj = SLOT(&cred->cr_label);
1779 obj = SLOT(socketlabel);
1780
1781 /*
1782 * If there is a Biba label update for the socket, it may be
1783 * an update of single.
1784 */
1785 error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE);
1786 if (error)
1787 return (error);
1788
1789 /*
1790 * To relabel a socket, the old socket single must be in the subject
1791 * range.
1792 */
1793 if (!mac_biba_single_in_range(obj, subj))
1794 return (EPERM);
1795
1796 /*
1797 * If the Biba label is to be changed, authorize as appropriate.
1798 */
1799 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) {
1800 /*
1801 * To relabel a socket, the new socket single must be in
1802 * the subject range.
1803 */
1804 if (!mac_biba_single_in_range(new, subj))
1805 return (EPERM);
1806
1807 /*
1808 * To change the Biba label on the socket to contain EQUAL,
1809 * the subject must have appropriate privilege.
1810 */
1811 if (mac_biba_contains_equal(new)) {
1812 error = mac_biba_subject_privileged(subj);
1813 if (error)
1814 return (error);
1815 }
1816 }
1817
1818 return (0);
1819 }
1820
1821 static int
1822 mac_biba_check_socket_visible(struct ucred *cred, struct socket *socket,
1823 struct label *socketlabel)
1824 {
1825 struct mac_biba *subj, *obj;
1826
1827 if (!mac_biba_enabled)
1828 return (0);
1829
1830 subj = SLOT(&cred->cr_label);
1831 obj = SLOT(socketlabel);
1832
1833 if (!mac_biba_dominate_single(obj, subj))
1834 return (ENOENT);
1835
1836 return (0);
1837 }
1838
1839 static int
1840 mac_biba_check_system_acct(struct ucred *cred, struct vnode *vp,
1841 struct label *label)
1842 {
1843 struct mac_biba *subj, *obj;
1844 int error;
1845
1846 if (!mac_biba_enabled)
1847 return (0);
1848
1849 subj = SLOT(&cred->cr_label);
1850
1851 error = mac_biba_subject_privileged(subj);
1852 if (error)
1853 return (error);
1854
1855 if (label == NULL)
1856 return (0);
1857
1858 obj = SLOT(label);
1859 if (!mac_biba_high_single(obj))
1860 return (EACCES);
1861
1862 return (0);
1863 }
1864
1865 static int
1866 mac_biba_check_system_settime(struct ucred *cred)
1867 {
1868 struct mac_biba *subj;
1869 int error;
1870
1871 if (!mac_biba_enabled)
1872 return (0);
1873
1874 subj = SLOT(&cred->cr_label);
1875
1876 error = mac_biba_subject_privileged(subj);
1877 if (error)
1878 return (error);
1879
1880 return (0);
1881 }
1882
1883 static int
1884 mac_biba_check_system_swapon(struct ucred *cred, struct vnode *vp,
1885 struct label *label)
1886 {
1887 struct mac_biba *subj, *obj;
1888 int error;
1889
1890 if (!mac_biba_enabled)
1891 return (0);
1892
1893 subj = SLOT(&cred->cr_label);
1894 obj = SLOT(label);
1895
1896 error = mac_biba_subject_privileged(subj);
1897 if (error)
1898 return (error);
1899
1900 if (!mac_biba_high_single(obj))
1901 return (EACCES);
1902
1903 return (0);
1904 }
1905
1906 static int
1907 mac_biba_check_system_sysctl(struct ucred *cred, int *name, u_int namelen,
1908 void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen)
1909 {
1910 struct mac_biba *subj;
1911 int error;
1912
1913 if (!mac_biba_enabled)
1914 return (0);
1915
1916 subj = SLOT(&cred->cr_label);
1917
1918 /*
1919 * In general, treat sysctl variables as biba/high, but also
1920 * require privilege to change them, since they are a
1921 * communications channel between grades. Exempt MIB
1922 * queries from this due to undocmented sysctl magic.
1923 * XXXMAC: This probably requires some more review.
1924 */
1925 if (new != NULL) {
1926 if (namelen > 0 && name[0] == 0)
1927 return (0);
1928
1929 if (!mac_biba_subject_dominate_high(subj))
1930 return (EACCES);
1931
1932 error = mac_biba_subject_privileged(subj);
1933 if (error)
1934 return (error);
1935 }
1936
1937 return (0);
1938 }
1939
1940 static int
1941 mac_biba_check_vnode_chdir(struct ucred *cred, struct vnode *dvp,
1942 struct label *dlabel)
1943 {
1944 struct mac_biba *subj, *obj;
1945
1946 if (!mac_biba_enabled)
1947 return (0);
1948
1949 subj = SLOT(&cred->cr_label);
1950 obj = SLOT(dlabel);
1951
1952 if (!mac_biba_dominate_single(obj, subj))
1953 return (EACCES);
1954
1955 return (0);
1956 }
1957
1958 static int
1959 mac_biba_check_vnode_chroot(struct ucred *cred, struct vnode *dvp,
1960 struct label *dlabel)
1961 {
1962 struct mac_biba *subj, *obj;
1963
1964 if (!mac_biba_enabled)
1965 return (0);
1966
1967 subj = SLOT(&cred->cr_label);
1968 obj = SLOT(dlabel);
1969
1970 if (!mac_biba_dominate_single(obj, subj))
1971 return (EACCES);
1972
1973 return (0);
1974 }
1975
1976 static int
1977 mac_biba_check_vnode_create(struct ucred *cred, struct vnode *dvp,
1978 struct label *dlabel, struct componentname *cnp, struct vattr *vap)
1979 {
1980 struct mac_biba *subj, *obj;
1981
1982 if (!mac_biba_enabled)
1983 return (0);
1984
1985 subj = SLOT(&cred->cr_label);
1986 obj = SLOT(dlabel);
1987
1988 if (!mac_biba_dominate_single(subj, obj))
1989 return (EACCES);
1990
1991 return (0);
1992 }
1993
1994 static int
1995 mac_biba_check_vnode_delete(struct ucred *cred, struct vnode *dvp,
1996 struct label *dlabel, struct vnode *vp, struct label *label,
1997 struct componentname *cnp)
1998 {
1999 struct mac_biba *subj, *obj;
2000
2001 if (!mac_biba_enabled)
2002 return (0);
2003
2004 subj = SLOT(&cred->cr_label);
2005 obj = SLOT(dlabel);
2006
2007 if (!mac_biba_dominate_single(subj, obj))
2008 return (EACCES);
2009
2010 obj = SLOT(label);
2011
2012 if (!mac_biba_dominate_single(subj, obj))
2013 return (EACCES);
2014
2015 return (0);
2016 }
2017
2018 static int
2019 mac_biba_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
2020 struct label *label, acl_type_t type)
2021 {
2022 struct mac_biba *subj, *obj;
2023
2024 if (!mac_biba_enabled)
2025 return (0);
2026
2027 subj = SLOT(&cred->cr_label);
2028 obj = SLOT(label);
2029
2030 if (!mac_biba_dominate_single(subj, obj))
2031 return (EACCES);
2032
2033 return (0);
2034 }
2035
2036 static int
2037 mac_biba_check_vnode_exec(struct ucred *cred, struct vnode *vp,
2038 struct label *label, struct image_params *imgp,
2039 struct label *execlabel)
2040 {
2041 struct mac_biba *subj, *obj, *exec;
2042 int error;
2043
2044 if (execlabel != NULL) {
2045 /*
2046 * We currently don't permit labels to be changed at
2047 * exec-time as part of Biba, so disallow non-NULL
2048 * Biba label elements in the execlabel.
2049 */
2050 exec = SLOT(execlabel);
2051 error = biba_atmostflags(exec, 0);
2052 if (error)
2053 return (error);
2054 }
2055
2056 if (!mac_biba_enabled)
2057 return (0);
2058
2059 subj = SLOT(&cred->cr_label);
2060 obj = SLOT(label);
2061
2062 if (!mac_biba_dominate_single(obj, subj))
2063 return (EACCES);
2064
2065 return (0);
2066 }
2067
2068 static int
2069 mac_biba_check_vnode_getacl(struct ucred *cred, struct vnode *vp,
2070 struct label *label, acl_type_t type)
2071 {
2072 struct mac_biba *subj, *obj;
2073
2074 if (!mac_biba_enabled)
2075 return (0);
2076
2077 subj = SLOT(&cred->cr_label);
2078 obj = SLOT(label);
2079
2080 if (!mac_biba_dominate_single(obj, subj))
2081 return (EACCES);
2082
2083 return (0);
2084 }
2085
2086 static int
2087 mac_biba_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
2088 struct label *label, int attrnamespace, const char *name, struct uio *uio)
2089 {
2090 struct mac_biba *subj, *obj;
2091
2092 if (!mac_biba_enabled)
2093 return (0);
2094
2095 subj = SLOT(&cred->cr_label);
2096 obj = SLOT(label);
2097
2098 if (!mac_biba_dominate_single(obj, subj))
2099 return (EACCES);
2100
2101 return (0);
2102 }
2103
2104 static int
2105 mac_biba_check_vnode_link(struct ucred *cred, struct vnode *dvp,
2106 struct label *dlabel, struct vnode *vp, struct label *label,
2107 struct componentname *cnp)
2108 {
2109 struct mac_biba *subj, *obj;
2110
2111 if (!mac_biba_enabled)
2112 return (0);
2113
2114 subj = SLOT(&cred->cr_label);
2115 obj = SLOT(dlabel);
2116
2117 if (!mac_biba_dominate_single(subj, obj))
2118 return (EACCES);
2119
2120 obj = SLOT(label);
2121
2122 if (!mac_biba_dominate_single(subj, obj))
2123 return (EACCES);
2124
2125 return (0);
2126 }
2127
2128 static int
2129 mac_biba_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
2130 struct label *dlabel, struct componentname *cnp)
2131 {
2132 struct mac_biba *subj, *obj;
2133
2134 if (!mac_biba_enabled)
2135 return (0);
2136
2137 subj = SLOT(&cred->cr_label);
2138 obj = SLOT(dlabel);
2139
2140 if (!mac_biba_dominate_single(obj, subj))
2141 return (EACCES);
2142
2143 return (0);
2144 }
2145
2146 static int
2147 mac_biba_check_vnode_mmap(struct ucred *cred, struct vnode *vp,
2148 struct label *label, int prot)
2149 {
2150 struct mac_biba *subj, *obj;
2151
2152 /*
2153 * Rely on the use of open()-time protections to handle
2154 * non-revocation cases.
2155 */
2156 if (!mac_biba_enabled || !revocation_enabled)
2157 return (0);
2158
2159 subj = SLOT(&cred->cr_label);
2160 obj = SLOT(label);
2161
2162 if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
2163 if (!mac_biba_dominate_single(obj, subj))
2164 return (EACCES);
2165 }
2166 if (prot & VM_PROT_WRITE) {
2167 if (!mac_biba_dominate_single(subj, obj))
2168 return (EACCES);
2169 }
2170
2171 return (0);
2172 }
2173
2174 static int
2175 mac_biba_check_vnode_open(struct ucred *cred, struct vnode *vp,
2176 struct label *vnodelabel, int acc_mode)
2177 {
2178 struct mac_biba *subj, *obj;
2179
2180 if (!mac_biba_enabled)
2181 return (0);
2182
2183 subj = SLOT(&cred->cr_label);
2184 obj = SLOT(vnodelabel);
2185
2186 /* XXX privilege override for admin? */
2187 if (acc_mode & (VREAD | VEXEC | VSTAT)) {
2188 if (!mac_biba_dominate_single(obj, subj))
2189 return (EACCES);
2190 }
2191 if (acc_mode & (VWRITE | VAPPEND | VADMIN)) {
2192 if (!mac_biba_dominate_single(subj, obj))
2193 return (EACCES);
2194 }
2195
2196 return (0);
2197 }
2198
2199 static int
2200 mac_biba_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred,
2201 struct vnode *vp, struct label *label)
2202 {
2203 struct mac_biba *subj, *obj;
2204
2205 if (!mac_biba_enabled || !revocation_enabled)
2206 return (0);
2207
2208 subj = SLOT(&active_cred->cr_label);
2209 obj = SLOT(label);
2210
2211 if (!mac_biba_dominate_single(obj, subj))
2212 return (EACCES);
2213
2214 return (0);
2215 }
2216
2217 static int
2218 mac_biba_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
2219 struct vnode *vp, struct label *label)
2220 {
2221 struct mac_biba *subj, *obj;
2222
2223 if (!mac_biba_enabled || !revocation_enabled)
2224 return (0);
2225
2226 subj = SLOT(&active_cred->cr_label);
2227 obj = SLOT(label);
2228
2229 if (!mac_biba_dominate_single(obj, subj))
2230 return (EACCES);
2231
2232 return (0);
2233 }
2234
2235 static int
2236 mac_biba_check_vnode_readdir(struct ucred *cred, struct vnode *dvp,
2237 struct label *dlabel)
2238 {
2239 struct mac_biba *subj, *obj;
2240
2241 if (!mac_biba_enabled)
2242 return (0);
2243
2244 subj = SLOT(&cred->cr_label);
2245 obj = SLOT(dlabel);
2246
2247 if (!mac_biba_dominate_single(obj, subj))
2248 return (EACCES);
2249
2250 return (0);
2251 }
2252
2253 static int
2254 mac_biba_check_vnode_readlink(struct ucred *cred, struct vnode *vp,
2255 struct label *label)
2256 {
2257 struct mac_biba *subj, *obj;
2258
2259 if (!mac_biba_enabled)
2260 return (0);
2261
2262 subj = SLOT(&cred->cr_label);
2263 obj = SLOT(label);
2264
2265 if (!mac_biba_dominate_single(obj, subj))
2266 return (EACCES);
2267
2268 return (0);
2269 }
2270
2271 static int
2272 mac_biba_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
2273 struct label *vnodelabel, struct label *newlabel)
2274 {
2275 struct mac_biba *old, *new, *subj;
2276 int error;
2277
2278 old = SLOT(vnodelabel);
2279 new = SLOT(newlabel);
2280 subj = SLOT(&cred->cr_label);
2281
2282 /*
2283 * If there is a Biba label update for the vnode, it must be a
2284 * single label.
2285 */
2286 error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE);
2287 if (error)
2288 return (error);
2289
2290 /*
2291 * To perform a relabel of the vnode (Biba label or not), Biba must
2292 * authorize the relabel.
2293 */
2294 if (!mac_biba_single_in_range(old, subj))
2295 return (EPERM);
2296
2297 /*
2298 * If the Biba label is to be changed, authorize as appropriate.
2299 */
2300 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) {
2301 /*
2302 * To change the Biba label on a vnode, the new vnode label
2303 * must be in the subject range.
2304 */
2305 if (!mac_biba_single_in_range(new, subj))
2306 return (EPERM);
2307
2308 /*
2309 * To change the Biba label on the vnode to be EQUAL,
2310 * the subject must have appropriate privilege.
2311 */
2312 if (mac_biba_contains_equal(new)) {
2313 error = mac_biba_subject_privileged(subj);
2314 if (error)
2315 return (error);
2316 }
2317 }
2318
2319 return (0);
2320 }
2321
2322 static int
2323 mac_biba_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
2324 struct label *dlabel, struct vnode *vp, struct label *label,
2325 struct componentname *cnp)
2326 {
2327 struct mac_biba *subj, *obj;
2328
2329 if (!mac_biba_enabled)
2330 return (0);
2331
2332 subj = SLOT(&cred->cr_label);
2333 obj = SLOT(dlabel);
2334
2335 if (!mac_biba_dominate_single(subj, obj))
2336 return (EACCES);
2337
2338 obj = SLOT(label);
2339
2340 if (!mac_biba_dominate_single(subj, obj))
2341 return (EACCES);
2342
2343 return (0);
2344 }
2345
2346 static int
2347 mac_biba_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
2348 struct label *dlabel, struct vnode *vp, struct label *label, int samedir,
2349 struct componentname *cnp)
2350 {
2351 struct mac_biba *subj, *obj;
2352
2353 if (!mac_biba_enabled)
2354 return (0);
2355
2356 subj = SLOT(&cred->cr_label);
2357 obj = SLOT(dlabel);
2358
2359 if (!mac_biba_dominate_single(subj, obj))
2360 return (EACCES);
2361
2362 if (vp != NULL) {
2363 obj = SLOT(label);
2364
2365 if (!mac_biba_dominate_single(subj, obj))
2366 return (EACCES);
2367 }
2368
2369 return (0);
2370 }
2371
2372 static int
2373 mac_biba_check_vnode_revoke(struct ucred *cred, struct vnode *vp,
2374 struct label *label)
2375 {
2376 struct mac_biba *subj, *obj;
2377
2378 if (!mac_biba_enabled)
2379 return (0);
2380
2381 subj = SLOT(&cred->cr_label);
2382 obj = SLOT(label);
2383
2384 if (!mac_biba_dominate_single(subj, obj))
2385 return (EACCES);
2386
2387 return (0);
2388 }
2389
2390 static int
2391 mac_biba_check_vnode_setacl(struct ucred *cred, struct vnode *vp,
2392 struct label *label, acl_type_t type, struct acl *acl)
2393 {
2394 struct mac_biba *subj, *obj;
2395
2396 if (!mac_biba_enabled)
2397 return (0);
2398
2399 subj = SLOT(&cred->cr_label);
2400 obj = SLOT(label);
2401
2402 if (!mac_biba_dominate_single(subj, obj))
2403 return (EACCES);
2404
2405 return (0);
2406 }
2407
2408 static int
2409 mac_biba_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
2410 struct label *vnodelabel, int attrnamespace, const char *name,
2411 struct uio *uio)
2412 {
2413 struct mac_biba *subj, *obj;
2414
2415 if (!mac_biba_enabled)
2416 return (0);
2417
2418 subj = SLOT(&cred->cr_label);
2419 obj = SLOT(vnodelabel);
2420
2421 if (!mac_biba_dominate_single(subj, obj))
2422 return (EACCES);
2423
2424 /* XXX: protect the MAC EA in a special way? */
2425
2426 return (0);
2427 }
2428
2429 static int
2430 mac_biba_check_vnode_setflags(struct ucred *cred, struct vnode *vp,
2431 struct label *vnodelabel, u_long flags)
2432 {
2433 struct mac_biba *subj, *obj;
2434
2435 if (!mac_biba_enabled)
2436 return (0);
2437
2438 subj = SLOT(&cred->cr_label);
2439 obj = SLOT(vnodelabel);
2440
2441 if (!mac_biba_dominate_single(subj, obj))
2442 return (EACCES);
2443
2444 return (0);
2445 }
2446
2447 static int
2448 mac_biba_check_vnode_setmode(struct ucred *cred, struct vnode *vp,
2449 struct label *vnodelabel, mode_t mode)
2450 {
2451 struct mac_biba *subj, *obj;
2452
2453 if (!mac_biba_enabled)
2454 return (0);
2455
2456 subj = SLOT(&cred->cr_label);
2457 obj = SLOT(vnodelabel);
2458
2459 if (!mac_biba_dominate_single(subj, obj))
2460 return (EACCES);
2461
2462 return (0);
2463 }
2464
2465 static int
2466 mac_biba_check_vnode_setowner(struct ucred *cred, struct vnode *vp,
2467 struct label *vnodelabel, uid_t uid, gid_t gid)
2468 {
2469 struct mac_biba *subj, *obj;
2470
2471 if (!mac_biba_enabled)
2472 return (0);
2473
2474 subj = SLOT(&cred->cr_label);
2475 obj = SLOT(vnodelabel);
2476
2477 if (!mac_biba_dominate_single(subj, obj))
2478 return (EACCES);
2479
2480 return (0);
2481 }
2482
2483 static int
2484 mac_biba_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
2485 struct label *vnodelabel, struct timespec atime, struct timespec mtime)
2486 {
2487 struct mac_biba *subj, *obj;
2488
2489 if (!mac_biba_enabled)
2490 return (0);
2491
2492 subj = SLOT(&cred->cr_label);
2493 obj = SLOT(vnodelabel);
2494
2495 if (!mac_biba_dominate_single(subj, obj))
2496 return (EACCES);
2497
2498 return (0);
2499 }
2500
2501 static int
2502 mac_biba_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
2503 struct vnode *vp, struct label *vnodelabel)
2504 {
2505 struct mac_biba *subj, *obj;
2506
2507 if (!mac_biba_enabled)
2508 return (0);
2509
2510 subj = SLOT(&active_cred->cr_label);
2511 obj = SLOT(vnodelabel);
2512
2513 if (!mac_biba_dominate_single(obj, subj))
2514 return (EACCES);
2515
2516 return (0);
2517 }
2518
2519 static int
2520 mac_biba_check_vnode_write(struct ucred *active_cred,
2521 struct ucred *file_cred, struct vnode *vp, struct label *label)
2522 {
2523 struct mac_biba *subj, *obj;
2524
2525 if (!mac_biba_enabled || !revocation_enabled)
2526 return (0);
2527
2528 subj = SLOT(&active_cred->cr_label);
2529 obj = SLOT(label);
2530
2531 if (!mac_biba_dominate_single(subj, obj))
2532 return (EACCES);
2533
2534 return (0);
2535 }
2536
2537 static struct mac_policy_ops mac_biba_ops =
2538 {
2539 .mpo_destroy = mac_biba_destroy,
2540 .mpo_init = mac_biba_init,
2541 .mpo_init_bpfdesc_label = mac_biba_init_label,
2542 .mpo_init_cred_label = mac_biba_init_label,
2543 .mpo_init_devfsdirent_label = mac_biba_init_label,
2544 .mpo_init_ifnet_label = mac_biba_init_label,
2545 .mpo_init_ipq_label = mac_biba_init_label,
2546 .mpo_init_mbuf_label = mac_biba_init_label_waitcheck,
2547 .mpo_init_mount_label = mac_biba_init_label,
2548 .mpo_init_mount_fs_label = mac_biba_init_label,
2549 .mpo_init_pipe_label = mac_biba_init_label,
2550 .mpo_init_socket_label = mac_biba_init_label_waitcheck,
2551 .mpo_init_socket_peer_label = mac_biba_init_label_waitcheck,
2552 .mpo_init_vnode_label = mac_biba_init_label,
2553 .mpo_destroy_bpfdesc_label = mac_biba_destroy_label,
2554 .mpo_destroy_cred_label = mac_biba_destroy_label,
2555 .mpo_destroy_devfsdirent_label = mac_biba_destroy_label,
2556 .mpo_destroy_ifnet_label = mac_biba_destroy_label,
2557 .mpo_destroy_ipq_label = mac_biba_destroy_label,
2558 .mpo_destroy_mbuf_label = mac_biba_destroy_label,
2559 .mpo_destroy_mount_label = mac_biba_destroy_label,
2560 .mpo_destroy_mount_fs_label = mac_biba_destroy_label,
2561 .mpo_destroy_pipe_label = mac_biba_destroy_label,
2562 .mpo_destroy_socket_label = mac_biba_destroy_label,
2563 .mpo_destroy_socket_peer_label = mac_biba_destroy_label,
2564 .mpo_destroy_vnode_label = mac_biba_destroy_label,
2565 .mpo_copy_pipe_label = mac_biba_copy_label,
2566 .mpo_copy_vnode_label = mac_biba_copy_label,
2567 .mpo_externalize_cred_label = mac_biba_externalize_label,
2568 .mpo_externalize_ifnet_label = mac_biba_externalize_label,
2569 .mpo_externalize_pipe_label = mac_biba_externalize_label,
2570 .mpo_externalize_socket_label = mac_biba_externalize_label,
2571 .mpo_externalize_socket_peer_label = mac_biba_externalize_label,
2572 .mpo_externalize_vnode_label = mac_biba_externalize_label,
2573 .mpo_internalize_cred_label = mac_biba_internalize_label,
2574 .mpo_internalize_ifnet_label = mac_biba_internalize_label,
2575 .mpo_internalize_pipe_label = mac_biba_internalize_label,
2576 .mpo_internalize_socket_label = mac_biba_internalize_label,
2577 .mpo_internalize_vnode_label = mac_biba_internalize_label,
2578 .mpo_create_devfs_device = mac_biba_create_devfs_device,
2579 .mpo_create_devfs_directory = mac_biba_create_devfs_directory,
2580 .mpo_create_devfs_symlink = mac_biba_create_devfs_symlink,
2581 .mpo_create_mount = mac_biba_create_mount,
2582 .mpo_create_root_mount = mac_biba_create_root_mount,
2583 .mpo_relabel_vnode = mac_biba_relabel_vnode,
2584 .mpo_update_devfsdirent = mac_biba_update_devfsdirent,
2585 .mpo_associate_vnode_devfs = mac_biba_associate_vnode_devfs,
2586 .mpo_associate_vnode_extattr = mac_biba_associate_vnode_extattr,
2587 .mpo_associate_vnode_singlelabel = mac_biba_associate_vnode_singlelabel,
2588 .mpo_create_vnode_extattr = mac_biba_create_vnode_extattr,
2589 .mpo_setlabel_vnode_extattr = mac_biba_setlabel_vnode_extattr,
2590 .mpo_create_mbuf_from_socket = mac_biba_create_mbuf_from_socket,
2591 .mpo_create_pipe = mac_biba_create_pipe,
2592 .mpo_create_socket = mac_biba_create_socket,
2593 .mpo_create_socket_from_socket = mac_biba_create_socket_from_socket,
2594 .mpo_relabel_pipe = mac_biba_relabel_pipe,
2595 .mpo_relabel_socket = mac_biba_relabel_socket,
2596 .mpo_set_socket_peer_from_mbuf = mac_biba_set_socket_peer_from_mbuf,
2597 .mpo_set_socket_peer_from_socket = mac_biba_set_socket_peer_from_socket,
2598 .mpo_create_bpfdesc = mac_biba_create_bpfdesc,
2599 .mpo_create_datagram_from_ipq = mac_biba_create_datagram_from_ipq,
2600 .mpo_create_fragment = mac_biba_create_fragment,
2601 .mpo_create_ifnet = mac_biba_create_ifnet,
2602 .mpo_create_ipq = mac_biba_create_ipq,
2603 .mpo_create_mbuf_from_mbuf = mac_biba_create_mbuf_from_mbuf,
2604 .mpo_create_mbuf_linklayer = mac_biba_create_mbuf_linklayer,
2605 .mpo_create_mbuf_from_bpfdesc = mac_biba_create_mbuf_from_bpfdesc,
2606 .mpo_create_mbuf_from_ifnet = mac_biba_create_mbuf_from_ifnet,
2607 .mpo_create_mbuf_multicast_encap = mac_biba_create_mbuf_multicast_encap,
2608 .mpo_create_mbuf_netlayer = mac_biba_create_mbuf_netlayer,
2609 .mpo_fragment_match = mac_biba_fragment_match,
2610 .mpo_relabel_ifnet = mac_biba_relabel_ifnet,
2611 .mpo_update_ipq = mac_biba_update_ipq,
2612 .mpo_create_cred = mac_biba_create_cred,
2613 .mpo_create_proc0 = mac_biba_create_proc0,
2614 .mpo_create_proc1 = mac_biba_create_proc1,
2615 .mpo_relabel_cred = mac_biba_relabel_cred,
2616 .mpo_check_bpfdesc_receive = mac_biba_check_bpfdesc_receive,
2617 .mpo_check_cred_relabel = mac_biba_check_cred_relabel,
2618 .mpo_check_cred_visible = mac_biba_check_cred_visible,
2619 .mpo_check_ifnet_relabel = mac_biba_check_ifnet_relabel,
2620 .mpo_check_ifnet_transmit = mac_biba_check_ifnet_transmit,
2621 .mpo_check_mount_stat = mac_biba_check_mount_stat,
2622 .mpo_check_pipe_ioctl = mac_biba_check_pipe_ioctl,
2623 .mpo_check_pipe_poll = mac_biba_check_pipe_poll,
2624 .mpo_check_pipe_read = mac_biba_check_pipe_read,
2625 .mpo_check_pipe_relabel = mac_biba_check_pipe_relabel,
2626 .mpo_check_pipe_stat = mac_biba_check_pipe_stat,
2627 .mpo_check_pipe_write = mac_biba_check_pipe_write,
2628 .mpo_check_proc_debug = mac_biba_check_proc_debug,
2629 .mpo_check_proc_sched = mac_biba_check_proc_sched,
2630 .mpo_check_proc_signal = mac_biba_check_proc_signal,
2631 .mpo_check_socket_deliver = mac_biba_check_socket_deliver,
2632 .mpo_check_socket_relabel = mac_biba_check_socket_relabel,
2633 .mpo_check_socket_visible = mac_biba_check_socket_visible,
2634 .mpo_check_system_acct = mac_biba_check_system_acct,
2635 .mpo_check_system_settime = mac_biba_check_system_settime,
2636 .mpo_check_system_swapon = mac_biba_check_system_swapon,
2637 .mpo_check_system_sysctl = mac_biba_check_system_sysctl,
2638 .mpo_check_vnode_access = mac_biba_check_vnode_open,
2639 .mpo_check_vnode_chdir = mac_biba_check_vnode_chdir,
2640 .mpo_check_vnode_chroot = mac_biba_check_vnode_chroot,
2641 .mpo_check_vnode_create = mac_biba_check_vnode_create,
2642 .mpo_check_vnode_delete = mac_biba_check_vnode_delete,
2643 .mpo_check_vnode_deleteacl = mac_biba_check_vnode_deleteacl,
2644 .mpo_check_vnode_exec = mac_biba_check_vnode_exec,
2645 .mpo_check_vnode_getacl = mac_biba_check_vnode_getacl,
2646 .mpo_check_vnode_getextattr = mac_biba_check_vnode_getextattr,
2647 .mpo_check_vnode_link = mac_biba_check_vnode_link,
2648 .mpo_check_vnode_lookup = mac_biba_check_vnode_lookup,
2649 .mpo_check_vnode_mmap = mac_biba_check_vnode_mmap,
2650 .mpo_check_vnode_mprotect = mac_biba_check_vnode_mmap,
2651 .mpo_check_vnode_open = mac_biba_check_vnode_open,
2652 .mpo_check_vnode_poll = mac_biba_check_vnode_poll,
2653 .mpo_check_vnode_read = mac_biba_check_vnode_read,
2654 .mpo_check_vnode_readdir = mac_biba_check_vnode_readdir,
2655 .mpo_check_vnode_readlink = mac_biba_check_vnode_readlink,
2656 .mpo_check_vnode_relabel = mac_biba_check_vnode_relabel,
2657 .mpo_check_vnode_rename_from = mac_biba_check_vnode_rename_from,
2658 .mpo_check_vnode_rename_to = mac_biba_check_vnode_rename_to,
2659 .mpo_check_vnode_revoke = mac_biba_check_vnode_revoke,
2660 .mpo_check_vnode_setacl = mac_biba_check_vnode_setacl,
2661 .mpo_check_vnode_setextattr = mac_biba_check_vnode_setextattr,
2662 .mpo_check_vnode_setflags = mac_biba_check_vnode_setflags,
2663 .mpo_check_vnode_setmode = mac_biba_check_vnode_setmode,
2664 .mpo_check_vnode_setowner = mac_biba_check_vnode_setowner,
2665 .mpo_check_vnode_setutimes = mac_biba_check_vnode_setutimes,
2666 .mpo_check_vnode_stat = mac_biba_check_vnode_stat,
2667 .mpo_check_vnode_write = mac_biba_check_vnode_write,
2668 };
2669
2670 MAC_POLICY_SET(&mac_biba_ops, trustedbsd_mac_biba, "TrustedBSD MAC/Biba",
2671 MPC_LOADTIME_FLAG_NOTLATE, &mac_biba_slot);
Cache object: b743a6f31c78f5f3861c23e5524bf480
|