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