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