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: releng/6.2/sys/security/mac_biba/mac_biba.c 162448 2006-09-19 15:45:22Z csjp $
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/sx.h>
64 #include <sys/sysctl.h>
65 #include <sys/msg.h>
66 #include <sys/sem.h>
67 #include <sys/shm.h>
68
69 #include <posix4/ksem.h>
70
71 #include <fs/devfs/devfs.h>
72
73 #include <net/bpfdesc.h>
74 #include <net/if.h>
75 #include <net/if_types.h>
76 #include <net/if_var.h>
77
78 #include <netinet/in.h>
79 #include <netinet/in_pcb.h>
80 #include <netinet/ip_var.h>
81
82 #include <vm/uma.h>
83 #include <vm/vm.h>
84
85 #include <sys/mac_policy.h>
86
87 #include <security/mac_biba/mac_biba.h>
88
89 SYSCTL_DECL(_security_mac);
90
91 SYSCTL_NODE(_security_mac, OID_AUTO, biba, CTLFLAG_RW, 0,
92 "TrustedBSD mac_biba policy controls");
93
94 static int mac_biba_label_size = sizeof(struct mac_biba);
95 SYSCTL_INT(_security_mac_biba, OID_AUTO, label_size, CTLFLAG_RD,
96 &mac_biba_label_size, 0, "Size of struct mac_biba");
97
98 static int mac_biba_enabled = 1;
99 SYSCTL_INT(_security_mac_biba, OID_AUTO, enabled, CTLFLAG_RW,
100 &mac_biba_enabled, 0, "Enforce MAC/Biba policy");
101 TUNABLE_INT("security.mac.biba.enabled", &mac_biba_enabled);
102
103 static int destroyed_not_inited;
104 SYSCTL_INT(_security_mac_biba, OID_AUTO, destroyed_not_inited, CTLFLAG_RD,
105 &destroyed_not_inited, 0, "Count of labels destroyed but not inited");
106
107 static int trust_all_interfaces = 0;
108 SYSCTL_INT(_security_mac_biba, OID_AUTO, trust_all_interfaces, CTLFLAG_RD,
109 &trust_all_interfaces, 0, "Consider all interfaces 'trusted' by MAC/Biba");
110 TUNABLE_INT("security.mac.biba.trust_all_interfaces", &trust_all_interfaces);
111
112 static char trusted_interfaces[128];
113 SYSCTL_STRING(_security_mac_biba, OID_AUTO, trusted_interfaces, CTLFLAG_RD,
114 trusted_interfaces, 0, "Interfaces considered 'trusted' by MAC/Biba");
115 TUNABLE_STR("security.mac.biba.trusted_interfaces", trusted_interfaces,
116 sizeof(trusted_interfaces));
117
118 static int max_compartments = MAC_BIBA_MAX_COMPARTMENTS;
119 SYSCTL_INT(_security_mac_biba, OID_AUTO, max_compartments, CTLFLAG_RD,
120 &max_compartments, 0, "Maximum supported compartments");
121
122 static int ptys_equal = 0;
123 SYSCTL_INT(_security_mac_biba, OID_AUTO, ptys_equal, CTLFLAG_RW,
124 &ptys_equal, 0, "Label pty devices as biba/equal on create");
125 TUNABLE_INT("security.mac.biba.ptys_equal", &ptys_equal);
126
127 static int interfaces_equal;
128 SYSCTL_INT(_security_mac_biba, OID_AUTO, interfaces_equal, CTLFLAG_RW,
129 &interfaces_equal, 0, "Label network interfaces as biba/equal on create");
130 TUNABLE_INT("security.mac.biba.interfaces_equal", &interfaces_equal);
131
132 static int revocation_enabled = 0;
133 SYSCTL_INT(_security_mac_biba, OID_AUTO, revocation_enabled, CTLFLAG_RW,
134 &revocation_enabled, 0, "Revoke access to objects on relabel");
135 TUNABLE_INT("security.mac.biba.revocation_enabled", &revocation_enabled);
136
137 static int mac_biba_slot;
138 #define SLOT(l) ((struct mac_biba *)LABEL_TO_SLOT((l), mac_biba_slot).l_ptr)
139 #define SLOT_SET(l, val) (LABEL_TO_SLOT((l), mac_biba_slot).l_ptr = (val))
140
141 static uma_zone_t zone_biba;
142
143 static __inline int
144 biba_bit_set_empty(u_char *set) {
145 int i;
146
147 for (i = 0; i < MAC_BIBA_MAX_COMPARTMENTS >> 3; i++)
148 if (set[i] != 0)
149 return (0);
150 return (1);
151 }
152
153 static struct mac_biba *
154 biba_alloc(int flag)
155 {
156
157 return (uma_zalloc(zone_biba, flag | M_ZERO));
158 }
159
160 static void
161 biba_free(struct mac_biba *mac_biba)
162 {
163
164 if (mac_biba != NULL)
165 uma_zfree(zone_biba, mac_biba);
166 else
167 atomic_add_int(&destroyed_not_inited, 1);
168 }
169
170 static int
171 biba_atmostflags(struct mac_biba *mac_biba, int flags)
172 {
173
174 if ((mac_biba->mb_flags & flags) != mac_biba->mb_flags)
175 return (EINVAL);
176 return (0);
177 }
178
179 static int
180 mac_biba_dominate_element(struct mac_biba_element *a,
181 struct mac_biba_element *b)
182 {
183 int bit;
184
185 switch (a->mbe_type) {
186 case MAC_BIBA_TYPE_EQUAL:
187 case MAC_BIBA_TYPE_HIGH:
188 return (1);
189
190 case MAC_BIBA_TYPE_LOW:
191 switch (b->mbe_type) {
192 case MAC_BIBA_TYPE_GRADE:
193 case MAC_BIBA_TYPE_HIGH:
194 return (0);
195
196 case MAC_BIBA_TYPE_EQUAL:
197 case MAC_BIBA_TYPE_LOW:
198 return (1);
199
200 default:
201 panic("mac_biba_dominate_element: b->mbe_type invalid");
202 }
203
204 case MAC_BIBA_TYPE_GRADE:
205 switch (b->mbe_type) {
206 case MAC_BIBA_TYPE_EQUAL:
207 case MAC_BIBA_TYPE_LOW:
208 return (1);
209
210 case MAC_BIBA_TYPE_HIGH:
211 return (0);
212
213 case MAC_BIBA_TYPE_GRADE:
214 for (bit = 1; bit <= MAC_BIBA_MAX_COMPARTMENTS; bit++)
215 if (!MAC_BIBA_BIT_TEST(bit,
216 a->mbe_compartments) &&
217 MAC_BIBA_BIT_TEST(bit, b->mbe_compartments))
218 return (0);
219 return (a->mbe_grade >= b->mbe_grade);
220
221 default:
222 panic("mac_biba_dominate_element: b->mbe_type invalid");
223 }
224
225 default:
226 panic("mac_biba_dominate_element: a->mbe_type invalid");
227 }
228
229 return (0);
230 }
231
232 static int
233 mac_biba_subject_dominate_high(struct mac_biba *mac_biba)
234 {
235 struct mac_biba_element *element;
236
237 KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
238 ("mac_biba_effective_in_range: mac_biba not effective"));
239 element = &mac_biba->mb_effective;
240
241 return (element->mbe_type == MAC_BIBA_TYPE_EQUAL ||
242 element->mbe_type == MAC_BIBA_TYPE_HIGH);
243 }
244
245 static int
246 mac_biba_range_in_range(struct mac_biba *rangea, struct mac_biba *rangeb)
247 {
248
249 return (mac_biba_dominate_element(&rangeb->mb_rangehigh,
250 &rangea->mb_rangehigh) &&
251 mac_biba_dominate_element(&rangea->mb_rangelow,
252 &rangeb->mb_rangelow));
253 }
254
255 static int
256 mac_biba_effective_in_range(struct mac_biba *effective,
257 struct mac_biba *range)
258 {
259
260 KASSERT((effective->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
261 ("mac_biba_effective_in_range: a not effective"));
262 KASSERT((range->mb_flags & MAC_BIBA_FLAG_RANGE) != 0,
263 ("mac_biba_effective_in_range: b not range"));
264
265 return (mac_biba_dominate_element(&range->mb_rangehigh,
266 &effective->mb_effective) &&
267 mac_biba_dominate_element(&effective->mb_effective,
268 &range->mb_rangelow));
269
270 return (1);
271 }
272
273 static int
274 mac_biba_dominate_effective(struct mac_biba *a, struct mac_biba *b)
275 {
276 KASSERT((a->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
277 ("mac_biba_dominate_effective: a not effective"));
278 KASSERT((b->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
279 ("mac_biba_dominate_effective: b not effective"));
280
281 return (mac_biba_dominate_element(&a->mb_effective, &b->mb_effective));
282 }
283
284 static int
285 mac_biba_equal_element(struct mac_biba_element *a, struct mac_biba_element *b)
286 {
287
288 if (a->mbe_type == MAC_BIBA_TYPE_EQUAL ||
289 b->mbe_type == MAC_BIBA_TYPE_EQUAL)
290 return (1);
291
292 return (a->mbe_type == b->mbe_type && a->mbe_grade == b->mbe_grade);
293 }
294
295 static int
296 mac_biba_equal_effective(struct mac_biba *a, struct mac_biba *b)
297 {
298
299 KASSERT((a->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
300 ("mac_biba_equal_effective: a not effective"));
301 KASSERT((b->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
302 ("mac_biba_equal_effective: b not effective"));
303
304 return (mac_biba_equal_element(&a->mb_effective, &b->mb_effective));
305 }
306
307 static int
308 mac_biba_contains_equal(struct mac_biba *mac_biba)
309 {
310
311 if (mac_biba->mb_flags & MAC_BIBA_FLAG_EFFECTIVE)
312 if (mac_biba->mb_effective.mbe_type == MAC_BIBA_TYPE_EQUAL)
313 return (1);
314
315 if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
316 if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL)
317 return (1);
318 if (mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL)
319 return (1);
320 }
321
322 return (0);
323 }
324
325 static int
326 mac_biba_subject_privileged(struct mac_biba *mac_biba)
327 {
328
329 KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAGS_BOTH) ==
330 MAC_BIBA_FLAGS_BOTH,
331 ("mac_biba_subject_privileged: subject doesn't have both labels"));
332
333 /* If the effective is EQUAL, it's ok. */
334 if (mac_biba->mb_effective.mbe_type == MAC_BIBA_TYPE_EQUAL)
335 return (0);
336
337 /* If either range endpoint is EQUAL, it's ok. */
338 if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL ||
339 mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL)
340 return (0);
341
342 /* If the range is low-high, it's ok. */
343 if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_LOW &&
344 mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_HIGH)
345 return (0);
346
347 /* It's not ok. */
348 return (EPERM);
349 }
350
351 static int
352 mac_biba_high_effective(struct mac_biba *mac_biba)
353 {
354
355 KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
356 ("mac_biba_equal_effective: mac_biba not effective"));
357
358 return (mac_biba->mb_effective.mbe_type == MAC_BIBA_TYPE_HIGH);
359 }
360
361 static int
362 mac_biba_valid(struct mac_biba *mac_biba)
363 {
364
365 if (mac_biba->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
366 switch (mac_biba->mb_effective.mbe_type) {
367 case MAC_BIBA_TYPE_GRADE:
368 break;
369
370 case MAC_BIBA_TYPE_EQUAL:
371 case MAC_BIBA_TYPE_HIGH:
372 case MAC_BIBA_TYPE_LOW:
373 if (mac_biba->mb_effective.mbe_grade != 0 ||
374 !MAC_BIBA_BIT_SET_EMPTY(
375 mac_biba->mb_effective.mbe_compartments))
376 return (EINVAL);
377 break;
378
379 default:
380 return (EINVAL);
381 }
382 } else {
383 if (mac_biba->mb_effective.mbe_type != MAC_BIBA_TYPE_UNDEF)
384 return (EINVAL);
385 }
386
387 if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
388 switch (mac_biba->mb_rangelow.mbe_type) {
389 case MAC_BIBA_TYPE_GRADE:
390 break;
391
392 case MAC_BIBA_TYPE_EQUAL:
393 case MAC_BIBA_TYPE_HIGH:
394 case MAC_BIBA_TYPE_LOW:
395 if (mac_biba->mb_rangelow.mbe_grade != 0 ||
396 !MAC_BIBA_BIT_SET_EMPTY(
397 mac_biba->mb_rangelow.mbe_compartments))
398 return (EINVAL);
399 break;
400
401 default:
402 return (EINVAL);
403 }
404
405 switch (mac_biba->mb_rangehigh.mbe_type) {
406 case MAC_BIBA_TYPE_GRADE:
407 break;
408
409 case MAC_BIBA_TYPE_EQUAL:
410 case MAC_BIBA_TYPE_HIGH:
411 case MAC_BIBA_TYPE_LOW:
412 if (mac_biba->mb_rangehigh.mbe_grade != 0 ||
413 !MAC_BIBA_BIT_SET_EMPTY(
414 mac_biba->mb_rangehigh.mbe_compartments))
415 return (EINVAL);
416 break;
417
418 default:
419 return (EINVAL);
420 }
421 if (!mac_biba_dominate_element(&mac_biba->mb_rangehigh,
422 &mac_biba->mb_rangelow))
423 return (EINVAL);
424 } else {
425 if (mac_biba->mb_rangelow.mbe_type != MAC_BIBA_TYPE_UNDEF ||
426 mac_biba->mb_rangehigh.mbe_type != MAC_BIBA_TYPE_UNDEF)
427 return (EINVAL);
428 }
429
430 return (0);
431 }
432
433 static void
434 mac_biba_set_range(struct mac_biba *mac_biba, u_short typelow,
435 u_short gradelow, u_char *compartmentslow, u_short typehigh,
436 u_short gradehigh, u_char *compartmentshigh)
437 {
438
439 mac_biba->mb_rangelow.mbe_type = typelow;
440 mac_biba->mb_rangelow.mbe_grade = gradelow;
441 if (compartmentslow != NULL)
442 memcpy(mac_biba->mb_rangelow.mbe_compartments,
443 compartmentslow,
444 sizeof(mac_biba->mb_rangelow.mbe_compartments));
445 mac_biba->mb_rangehigh.mbe_type = typehigh;
446 mac_biba->mb_rangehigh.mbe_grade = gradehigh;
447 if (compartmentshigh != NULL)
448 memcpy(mac_biba->mb_rangehigh.mbe_compartments,
449 compartmentshigh,
450 sizeof(mac_biba->mb_rangehigh.mbe_compartments));
451 mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE;
452 }
453
454 static void
455 mac_biba_set_effective(struct mac_biba *mac_biba, u_short type, u_short grade,
456 u_char *compartments)
457 {
458
459 mac_biba->mb_effective.mbe_type = type;
460 mac_biba->mb_effective.mbe_grade = grade;
461 if (compartments != NULL)
462 memcpy(mac_biba->mb_effective.mbe_compartments, compartments,
463 sizeof(mac_biba->mb_effective.mbe_compartments));
464 mac_biba->mb_flags |= MAC_BIBA_FLAG_EFFECTIVE;
465 }
466
467 static void
468 mac_biba_copy_range(struct mac_biba *labelfrom, struct mac_biba *labelto)
469 {
470
471 KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_RANGE) != 0,
472 ("mac_biba_copy_range: labelfrom not range"));
473
474 labelto->mb_rangelow = labelfrom->mb_rangelow;
475 labelto->mb_rangehigh = labelfrom->mb_rangehigh;
476 labelto->mb_flags |= MAC_BIBA_FLAG_RANGE;
477 }
478
479 static void
480 mac_biba_copy_effective(struct mac_biba *labelfrom, struct mac_biba *labelto)
481 {
482
483 KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
484 ("mac_biba_copy_effective: labelfrom not effective"));
485
486 labelto->mb_effective = labelfrom->mb_effective;
487 labelto->mb_flags |= MAC_BIBA_FLAG_EFFECTIVE;
488 }
489
490 static void
491 mac_biba_copy(struct mac_biba *source, struct mac_biba *dest)
492 {
493
494 if (source->mb_flags & MAC_BIBA_FLAG_EFFECTIVE)
495 mac_biba_copy_effective(source, dest);
496 if (source->mb_flags & MAC_BIBA_FLAG_RANGE)
497 mac_biba_copy_range(source, dest);
498 }
499
500 /*
501 * Policy module operations.
502 */
503 static void
504 mac_biba_init(struct mac_policy_conf *conf)
505 {
506
507 zone_biba = uma_zcreate("mac_biba", sizeof(struct mac_biba), NULL,
508 NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
509 }
510
511 /*
512 * Label operations.
513 */
514 static void
515 mac_biba_init_label(struct label *label)
516 {
517
518 SLOT_SET(label, biba_alloc(M_WAITOK));
519 }
520
521 static int
522 mac_biba_init_label_waitcheck(struct label *label, int flag)
523 {
524
525 SLOT_SET(label, biba_alloc(flag));
526 if (SLOT(label) == NULL)
527 return (ENOMEM);
528
529 return (0);
530 }
531
532 static void
533 mac_biba_destroy_label(struct label *label)
534 {
535
536 biba_free(SLOT(label));
537 SLOT_SET(label, NULL);
538 }
539
540 /*
541 * mac_biba_element_to_string() accepts an sbuf and Biba element. It
542 * converts the Biba element to a string and stores the result in the
543 * sbuf; if there isn't space in the sbuf, -1 is returned.
544 */
545 static int
546 mac_biba_element_to_string(struct sbuf *sb, struct mac_biba_element *element)
547 {
548 int i, first;
549
550 switch (element->mbe_type) {
551 case MAC_BIBA_TYPE_HIGH:
552 return (sbuf_printf(sb, "high"));
553
554 case MAC_BIBA_TYPE_LOW:
555 return (sbuf_printf(sb, "low"));
556
557 case MAC_BIBA_TYPE_EQUAL:
558 return (sbuf_printf(sb, "equal"));
559
560 case MAC_BIBA_TYPE_GRADE:
561 if (sbuf_printf(sb, "%d", element->mbe_grade) == -1)
562 return (-1);
563
564 first = 1;
565 for (i = 1; i <= MAC_BIBA_MAX_COMPARTMENTS; i++) {
566 if (MAC_BIBA_BIT_TEST(i, element->mbe_compartments)) {
567 if (first) {
568 if (sbuf_putc(sb, ':') == -1)
569 return (-1);
570 if (sbuf_printf(sb, "%d", i) == -1)
571 return (-1);
572 first = 0;
573 } else {
574 if (sbuf_printf(sb, "+%d", i) == -1)
575 return (-1);
576 }
577 }
578 }
579 return (0);
580
581 default:
582 panic("mac_biba_element_to_string: invalid type (%d)",
583 element->mbe_type);
584 }
585 }
586
587 /*
588 * mac_biba_to_string() converts a Biba label to a string, and places
589 * the results in the passed sbuf. It returns 0 on success, or EINVAL
590 * if there isn't room in the sbuf. Note: the sbuf will be modified
591 * even in a failure case, so the caller may need to revert the sbuf
592 * by restoring the offset if that's undesired.
593 */
594 static int
595 mac_biba_to_string(struct sbuf *sb, struct mac_biba *mac_biba)
596 {
597
598 if (mac_biba->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
599 if (mac_biba_element_to_string(sb, &mac_biba->mb_effective)
600 == -1)
601 return (EINVAL);
602 }
603
604 if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
605 if (sbuf_putc(sb, '(') == -1)
606 return (EINVAL);
607
608 if (mac_biba_element_to_string(sb, &mac_biba->mb_rangelow)
609 == -1)
610 return (EINVAL);
611
612 if (sbuf_putc(sb, '-') == -1)
613 return (EINVAL);
614
615 if (mac_biba_element_to_string(sb, &mac_biba->mb_rangehigh)
616 == -1)
617 return (EINVAL);
618
619 if (sbuf_putc(sb, ')') == -1)
620 return (EINVAL);
621 }
622
623 return (0);
624 }
625
626 static int
627 mac_biba_externalize_label(struct label *label, char *element_name,
628 struct sbuf *sb, int *claimed)
629 {
630 struct mac_biba *mac_biba;
631
632 if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0)
633 return (0);
634
635 (*claimed)++;
636
637 mac_biba = SLOT(label);
638 return (mac_biba_to_string(sb, mac_biba));
639 }
640
641 static int
642 mac_biba_parse_element(struct mac_biba_element *element, char *string)
643 {
644 char *compartment, *end, *grade;
645 int value;
646
647 if (strcmp(string, "high") == 0 ||
648 strcmp(string, "hi") == 0) {
649 element->mbe_type = MAC_BIBA_TYPE_HIGH;
650 element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
651 } else if (strcmp(string, "low") == 0 ||
652 strcmp(string, "lo") == 0) {
653 element->mbe_type = MAC_BIBA_TYPE_LOW;
654 element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
655 } else if (strcmp(string, "equal") == 0 ||
656 strcmp(string, "eq") == 0) {
657 element->mbe_type = MAC_BIBA_TYPE_EQUAL;
658 element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
659 } else {
660 element->mbe_type = MAC_BIBA_TYPE_GRADE;
661
662 /*
663 * Numeric grade piece of the element.
664 */
665 grade = strsep(&string, ":");
666 value = strtol(grade, &end, 10);
667 if (end == grade || *end != '\0')
668 return (EINVAL);
669 if (value < 0 || value > 65535)
670 return (EINVAL);
671 element->mbe_grade = value;
672
673 /*
674 * Optional compartment piece of the element. If none
675 * are included, we assume that the label has no
676 * compartments.
677 */
678 if (string == NULL)
679 return (0);
680 if (*string == '\0')
681 return (0);
682
683 while ((compartment = strsep(&string, "+")) != NULL) {
684 value = strtol(compartment, &end, 10);
685 if (compartment == end || *end != '\0')
686 return (EINVAL);
687 if (value < 1 || value > MAC_BIBA_MAX_COMPARTMENTS)
688 return (EINVAL);
689 MAC_BIBA_BIT_SET(value, element->mbe_compartments);
690 }
691 }
692
693 return (0);
694 }
695
696 /*
697 * Note: destructively consumes the string, make a local copy before
698 * calling if that's a problem.
699 */
700 static int
701 mac_biba_parse(struct mac_biba *mac_biba, char *string)
702 {
703 char *rangehigh, *rangelow, *effective;
704 int error;
705
706 effective = strsep(&string, "(");
707 if (*effective == '\0')
708 effective = NULL;
709
710 if (string != NULL) {
711 rangelow = strsep(&string, "-");
712 if (string == NULL)
713 return (EINVAL);
714 rangehigh = strsep(&string, ")");
715 if (string == NULL)
716 return (EINVAL);
717 if (*string != '\0')
718 return (EINVAL);
719 } else {
720 rangelow = NULL;
721 rangehigh = NULL;
722 }
723
724 KASSERT((rangelow != NULL && rangehigh != NULL) ||
725 (rangelow == NULL && rangehigh == NULL),
726 ("mac_biba_parse: range mismatch"));
727
728 bzero(mac_biba, sizeof(*mac_biba));
729 if (effective != NULL) {
730 error = mac_biba_parse_element(&mac_biba->mb_effective, effective);
731 if (error)
732 return (error);
733 mac_biba->mb_flags |= MAC_BIBA_FLAG_EFFECTIVE;
734 }
735
736 if (rangelow != NULL) {
737 error = mac_biba_parse_element(&mac_biba->mb_rangelow,
738 rangelow);
739 if (error)
740 return (error);
741 error = mac_biba_parse_element(&mac_biba->mb_rangehigh,
742 rangehigh);
743 if (error)
744 return (error);
745 mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE;
746 }
747
748 error = mac_biba_valid(mac_biba);
749 if (error)
750 return (error);
751
752 return (0);
753 }
754
755 static int
756 mac_biba_internalize_label(struct label *label, char *element_name,
757 char *element_data, int *claimed)
758 {
759 struct mac_biba *mac_biba, mac_biba_temp;
760 int error;
761
762 if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0)
763 return (0);
764
765 (*claimed)++;
766
767 error = mac_biba_parse(&mac_biba_temp, element_data);
768 if (error)
769 return (error);
770
771 mac_biba = SLOT(label);
772 *mac_biba = mac_biba_temp;
773
774 return (0);
775 }
776
777 static void
778 mac_biba_copy_label(struct label *src, struct label *dest)
779 {
780
781 *SLOT(dest) = *SLOT(src);
782 }
783
784 /*
785 * Labeling event operations: file system objects, and things that look
786 * a lot like file system objects.
787 */
788 static void
789 mac_biba_create_devfs_device(struct ucred *cred, struct mount *mp,
790 struct cdev *dev, struct devfs_dirent *devfs_dirent, struct label *label)
791 {
792 struct mac_biba *mac_biba;
793 int biba_type;
794
795 mac_biba = SLOT(label);
796 if (strcmp(dev->si_name, "null") == 0 ||
797 strcmp(dev->si_name, "zero") == 0 ||
798 strcmp(dev->si_name, "random") == 0 ||
799 strncmp(dev->si_name, "fd/", strlen("fd/")) == 0)
800 biba_type = MAC_BIBA_TYPE_EQUAL;
801 else if (ptys_equal &&
802 (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 ||
803 strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0))
804 biba_type = MAC_BIBA_TYPE_EQUAL;
805 else
806 biba_type = MAC_BIBA_TYPE_HIGH;
807 mac_biba_set_effective(mac_biba, biba_type, 0, NULL);
808 }
809
810 static void
811 mac_biba_create_devfs_directory(struct mount *mp, char *dirname,
812 int dirnamelen, struct devfs_dirent *devfs_dirent, struct label *label)
813 {
814 struct mac_biba *mac_biba;
815
816 mac_biba = SLOT(label);
817 mac_biba_set_effective(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
818 }
819
820 static void
821 mac_biba_create_devfs_symlink(struct ucred *cred, struct mount *mp,
822 struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de,
823 struct label *delabel)
824 {
825 struct mac_biba *source, *dest;
826
827 source = SLOT(cred->cr_label);
828 dest = SLOT(delabel);
829
830 mac_biba_copy_effective(source, dest);
831 }
832
833 static void
834 mac_biba_create_mount(struct ucred *cred, struct mount *mp,
835 struct label *mntlabel, struct label *fslabel)
836 {
837 struct mac_biba *source, *dest;
838
839 source = SLOT(cred->cr_label);
840 dest = SLOT(mntlabel);
841 mac_biba_copy_effective(source, dest);
842 dest = SLOT(fslabel);
843 mac_biba_copy_effective(source, dest);
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_posix_sem(struct ucred *cred, struct ksem *ksemptr,
1034 struct label *ks_label)
1035 {
1036 struct mac_biba *source, *dest;
1037
1038 source = SLOT(cred->cr_label);
1039 dest = SLOT(ks_label);
1040
1041 mac_biba_copy_effective(source, dest);
1042 }
1043
1044 static void
1045 mac_biba_create_socket_from_socket(struct socket *oldsocket,
1046 struct label *oldsocketlabel, struct socket *newsocket,
1047 struct label *newsocketlabel)
1048 {
1049 struct mac_biba *source, *dest;
1050
1051 source = SLOT(oldsocketlabel);
1052 dest = SLOT(newsocketlabel);
1053
1054 mac_biba_copy_effective(source, dest);
1055 }
1056
1057 static void
1058 mac_biba_relabel_socket(struct ucred *cred, struct socket *socket,
1059 struct label *socketlabel, struct label *newlabel)
1060 {
1061 struct mac_biba *source, *dest;
1062
1063 source = SLOT(newlabel);
1064 dest = SLOT(socketlabel);
1065
1066 mac_biba_copy(source, dest);
1067 }
1068
1069 static void
1070 mac_biba_relabel_pipe(struct ucred *cred, struct pipepair *pp,
1071 struct label *pipelabel, struct label *newlabel)
1072 {
1073 struct mac_biba *source, *dest;
1074
1075 source = SLOT(newlabel);
1076 dest = SLOT(pipelabel);
1077
1078 mac_biba_copy(source, dest);
1079 }
1080
1081 static void
1082 mac_biba_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel,
1083 struct socket *socket, struct label *socketpeerlabel)
1084 {
1085 struct mac_biba *source, *dest;
1086
1087 source = SLOT(mbuflabel);
1088 dest = SLOT(socketpeerlabel);
1089
1090 mac_biba_copy_effective(source, dest);
1091 }
1092
1093 /*
1094 * Labeling event operations: System V IPC objects.
1095 */
1096
1097 static void
1098 mac_biba_create_sysv_msgmsg(struct ucred *cred, struct msqid_kernel *msqkptr,
1099 struct label *msqlabel, struct msg *msgptr, struct label *msglabel)
1100 {
1101 struct mac_biba *source, *dest;
1102
1103 /* Ignore the msgq label */
1104 source = SLOT(cred->cr_label);
1105 dest = SLOT(msglabel);
1106
1107 mac_biba_copy_effective(source, dest);
1108 }
1109
1110 static void
1111 mac_biba_create_sysv_msgqueue(struct ucred *cred,
1112 struct msqid_kernel *msqkptr, struct label *msqlabel)
1113 {
1114 struct mac_biba *source, *dest;
1115
1116 source = SLOT(cred->cr_label);
1117 dest = SLOT(msqlabel);
1118
1119 mac_biba_copy_effective(source, dest);
1120 }
1121
1122 static void
1123 mac_biba_create_sysv_sem(struct ucred *cred, struct semid_kernel *semakptr,
1124 struct label *semalabel)
1125 {
1126 struct mac_biba *source, *dest;
1127
1128 source = SLOT(cred->cr_label);
1129 dest = SLOT(semalabel);
1130
1131 mac_biba_copy_effective(source, dest);
1132 }
1133
1134 static void
1135 mac_biba_create_sysv_shm(struct ucred *cred, struct shmid_kernel *shmsegptr,
1136 struct label *shmlabel)
1137 {
1138 struct mac_biba *source, *dest;
1139
1140 source = SLOT(cred->cr_label);
1141 dest = SLOT(shmlabel);
1142
1143 mac_biba_copy_effective(source, dest);
1144 }
1145
1146 /*
1147 * Labeling event operations: network objects.
1148 */
1149 static void
1150 mac_biba_set_socket_peer_from_socket(struct socket *oldsocket,
1151 struct label *oldsocketlabel, struct socket *newsocket,
1152 struct label *newsocketpeerlabel)
1153 {
1154 struct mac_biba *source, *dest;
1155
1156 source = SLOT(oldsocketlabel);
1157 dest = SLOT(newsocketpeerlabel);
1158
1159 mac_biba_copy_effective(source, dest);
1160 }
1161
1162 static void
1163 mac_biba_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d,
1164 struct label *bpflabel)
1165 {
1166 struct mac_biba *source, *dest;
1167
1168 source = SLOT(cred->cr_label);
1169 dest = SLOT(bpflabel);
1170
1171 mac_biba_copy_effective(source, dest);
1172 }
1173
1174 static void
1175 mac_biba_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel)
1176 {
1177 char tifname[IFNAMSIZ], *p, *q;
1178 char tiflist[sizeof(trusted_interfaces)];
1179 struct mac_biba *dest;
1180 int len, type;
1181
1182 dest = SLOT(ifnetlabel);
1183
1184 if (ifnet->if_type == IFT_LOOP || interfaces_equal != 0) {
1185 type = MAC_BIBA_TYPE_EQUAL;
1186 goto set;
1187 }
1188
1189 if (trust_all_interfaces) {
1190 type = MAC_BIBA_TYPE_HIGH;
1191 goto set;
1192 }
1193
1194 type = MAC_BIBA_TYPE_LOW;
1195
1196 if (trusted_interfaces[0] == '\0' ||
1197 !strvalid(trusted_interfaces, sizeof(trusted_interfaces)))
1198 goto set;
1199
1200 bzero(tiflist, sizeof(tiflist));
1201 for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++)
1202 if(*p != ' ' && *p != '\t')
1203 *q = *p;
1204
1205 for (p = q = tiflist;; p++) {
1206 if (*p == ',' || *p == '\0') {
1207 len = p - q;
1208 if (len < IFNAMSIZ) {
1209 bzero(tifname, sizeof(tifname));
1210 bcopy(q, tifname, len);
1211 if (strcmp(tifname, ifnet->if_xname) == 0) {
1212 type = MAC_BIBA_TYPE_HIGH;
1213 break;
1214 }
1215 } else {
1216 *p = '\0';
1217 printf("mac_biba warning: interface name "
1218 "\"%s\" is too long (must be < %d)\n",
1219 q, IFNAMSIZ);
1220 }
1221 if (*p == '\0')
1222 break;
1223 q = p + 1;
1224 }
1225 }
1226 set:
1227 mac_biba_set_effective(dest, type, 0, NULL);
1228 mac_biba_set_range(dest, type, 0, NULL, type, 0, NULL);
1229 }
1230
1231 static void
1232 mac_biba_create_ipq(struct mbuf *fragment, struct label *fragmentlabel,
1233 struct ipq *ipq, struct label *ipqlabel)
1234 {
1235 struct mac_biba *source, *dest;
1236
1237 source = SLOT(fragmentlabel);
1238 dest = SLOT(ipqlabel);
1239
1240 mac_biba_copy_effective(source, dest);
1241 }
1242
1243 static void
1244 mac_biba_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel,
1245 struct mbuf *datagram, struct label *datagramlabel)
1246 {
1247 struct mac_biba *source, *dest;
1248
1249 source = SLOT(ipqlabel);
1250 dest = SLOT(datagramlabel);
1251
1252 /* Just use the head, since we require them all to match. */
1253 mac_biba_copy_effective(source, dest);
1254 }
1255
1256 static void
1257 mac_biba_create_fragment(struct mbuf *datagram, struct label *datagramlabel,
1258 struct mbuf *fragment, struct label *fragmentlabel)
1259 {
1260 struct mac_biba *source, *dest;
1261
1262 source = SLOT(datagramlabel);
1263 dest = SLOT(fragmentlabel);
1264
1265 mac_biba_copy_effective(source, dest);
1266 }
1267
1268 static void
1269 mac_biba_create_mbuf_from_inpcb(struct inpcb *inp, struct label *inplabel,
1270 struct mbuf *m, struct label *mlabel)
1271 {
1272 struct mac_biba *source, *dest;
1273
1274 source = SLOT(inplabel);
1275 dest = SLOT(mlabel);
1276
1277 mac_biba_copy_effective(source, dest);
1278 }
1279
1280 static void
1281 mac_biba_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel,
1282 struct mbuf *mbuf, struct label *mbuflabel)
1283 {
1284 struct mac_biba *dest;
1285
1286 dest = SLOT(mbuflabel);
1287
1288 mac_biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1289 }
1290
1291 static void
1292 mac_biba_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel,
1293 struct mbuf *mbuf, struct label *mbuflabel)
1294 {
1295 struct mac_biba *source, *dest;
1296
1297 source = SLOT(bpflabel);
1298 dest = SLOT(mbuflabel);
1299
1300 mac_biba_copy_effective(source, dest);
1301 }
1302
1303 static void
1304 mac_biba_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel,
1305 struct mbuf *m, struct label *mbuflabel)
1306 {
1307 struct mac_biba *source, *dest;
1308
1309 source = SLOT(ifnetlabel);
1310 dest = SLOT(mbuflabel);
1311
1312 mac_biba_copy_effective(source, dest);
1313 }
1314
1315 static void
1316 mac_biba_create_mbuf_multicast_encap(struct mbuf *oldmbuf,
1317 struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel,
1318 struct mbuf *newmbuf, struct label *newmbuflabel)
1319 {
1320 struct mac_biba *source, *dest;
1321
1322 source = SLOT(oldmbuflabel);
1323 dest = SLOT(newmbuflabel);
1324
1325 mac_biba_copy_effective(source, dest);
1326 }
1327
1328 static void
1329 mac_biba_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel,
1330 struct mbuf *newmbuf, struct label *newmbuflabel)
1331 {
1332 struct mac_biba *source, *dest;
1333
1334 source = SLOT(oldmbuflabel);
1335 dest = SLOT(newmbuflabel);
1336
1337 mac_biba_copy_effective(source, dest);
1338 }
1339
1340 static int
1341 mac_biba_fragment_match(struct mbuf *fragment, struct label *fragmentlabel,
1342 struct ipq *ipq, struct label *ipqlabel)
1343 {
1344 struct mac_biba *a, *b;
1345
1346 a = SLOT(ipqlabel);
1347 b = SLOT(fragmentlabel);
1348
1349 return (mac_biba_equal_effective(a, b));
1350 }
1351
1352 static void
1353 mac_biba_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet,
1354 struct label *ifnetlabel, struct label *newlabel)
1355 {
1356 struct mac_biba *source, *dest;
1357
1358 source = SLOT(newlabel);
1359 dest = SLOT(ifnetlabel);
1360
1361 mac_biba_copy(source, dest);
1362 }
1363
1364 static void
1365 mac_biba_update_ipq(struct mbuf *fragment, struct label *fragmentlabel,
1366 struct ipq *ipq, struct label *ipqlabel)
1367 {
1368
1369 /* NOOP: we only accept matching labels, so no need to update */
1370 }
1371
1372 static void
1373 mac_biba_inpcb_sosetlabel(struct socket *so, struct label *solabel,
1374 struct inpcb *inp, struct label *inplabel)
1375 {
1376 struct mac_biba *source, *dest;
1377
1378 source = SLOT(solabel);
1379 dest = SLOT(inplabel);
1380
1381 mac_biba_copy(source, dest);
1382 }
1383
1384 static void
1385 mac_biba_create_mbuf_from_firewall(struct mbuf *m, struct label *label)
1386 {
1387 struct mac_biba *dest;
1388
1389 dest = SLOT(label);
1390
1391 /* XXX: where is the label for the firewall really comming from? */
1392 mac_biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1393 }
1394
1395 /*
1396 * Labeling event operations: processes.
1397 */
1398 static void
1399 mac_biba_create_proc0(struct ucred *cred)
1400 {
1401 struct mac_biba *dest;
1402
1403 dest = SLOT(cred->cr_label);
1404
1405 mac_biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1406 mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL,
1407 MAC_BIBA_TYPE_HIGH, 0, NULL);
1408 }
1409
1410 static void
1411 mac_biba_create_proc1(struct ucred *cred)
1412 {
1413 struct mac_biba *dest;
1414
1415 dest = SLOT(cred->cr_label);
1416
1417 mac_biba_set_effective(dest, MAC_BIBA_TYPE_HIGH, 0, NULL);
1418 mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL,
1419 MAC_BIBA_TYPE_HIGH, 0, NULL);
1420 }
1421
1422 static void
1423 mac_biba_relabel_cred(struct ucred *cred, struct label *newlabel)
1424 {
1425 struct mac_biba *source, *dest;
1426
1427 source = SLOT(newlabel);
1428 dest = SLOT(cred->cr_label);
1429
1430 mac_biba_copy(source, dest);
1431 }
1432
1433 /*
1434 * Label cleanup/flush operations
1435 */
1436 static void
1437 mac_biba_cleanup_sysv_msgmsg(struct label *msglabel)
1438 {
1439
1440 bzero(SLOT(msglabel), sizeof(struct mac_biba));
1441 }
1442
1443 static void
1444 mac_biba_cleanup_sysv_msgqueue(struct label *msqlabel)
1445 {
1446
1447 bzero(SLOT(msqlabel), sizeof(struct mac_biba));
1448 }
1449
1450 static void
1451 mac_biba_cleanup_sysv_sem(struct label *semalabel)
1452 {
1453
1454 bzero(SLOT(semalabel), sizeof(struct mac_biba));
1455 }
1456
1457 static void
1458 mac_biba_cleanup_sysv_shm(struct label *shmlabel)
1459 {
1460 bzero(SLOT(shmlabel), sizeof(struct mac_biba));
1461 }
1462
1463 /*
1464 * Access control checks.
1465 */
1466 static int
1467 mac_biba_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel,
1468 struct ifnet *ifnet, struct label *ifnetlabel)
1469 {
1470 struct mac_biba *a, *b;
1471
1472 if (!mac_biba_enabled)
1473 return (0);
1474
1475 a = SLOT(bpflabel);
1476 b = SLOT(ifnetlabel);
1477
1478 if (mac_biba_equal_effective(a, b))
1479 return (0);
1480 return (EACCES);
1481 }
1482
1483 static int
1484 mac_biba_check_cred_relabel(struct ucred *cred, struct label *newlabel)
1485 {
1486 struct mac_biba *subj, *new;
1487 int error;
1488
1489 subj = SLOT(cred->cr_label);
1490 new = SLOT(newlabel);
1491
1492 /*
1493 * If there is a Biba label update for the credential, it may
1494 * be an update of the effective, range, or both.
1495 */
1496 error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
1497 if (error)
1498 return (error);
1499
1500 /*
1501 * If the Biba label is to be changed, authorize as appropriate.
1502 */
1503 if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) {
1504 /*
1505 * If the change request modifies both the Biba label
1506 * effective and range, check that the new effective will be
1507 * in the new range.
1508 */
1509 if ((new->mb_flags & MAC_BIBA_FLAGS_BOTH) ==
1510 MAC_BIBA_FLAGS_BOTH &&
1511 !mac_biba_effective_in_range(new, new))
1512 return (EINVAL);
1513
1514 /*
1515 * To change the Biba effective label on a credential, the
1516 * new effective label must be in the current range.
1517 */
1518 if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE &&
1519 !mac_biba_effective_in_range(new, subj))
1520 return (EPERM);
1521
1522 /*
1523 * To change the Biba range on a credential, the new
1524 * range label must be in the current range.
1525 */
1526 if (new->mb_flags & MAC_BIBA_FLAG_RANGE &&
1527 !mac_biba_range_in_range(new, subj))
1528 return (EPERM);
1529
1530 /*
1531 * To have EQUAL in any component of the new credential
1532 * Biba label, the subject must already have EQUAL in
1533 * their label.
1534 */
1535 if (mac_biba_contains_equal(new)) {
1536 error = mac_biba_subject_privileged(subj);
1537 if (error)
1538 return (error);
1539 }
1540 }
1541
1542 return (0);
1543 }
1544
1545 static int
1546 mac_biba_check_cred_visible(struct ucred *u1, struct ucred *u2)
1547 {
1548 struct mac_biba *subj, *obj;
1549
1550 if (!mac_biba_enabled)
1551 return (0);
1552
1553 subj = SLOT(u1->cr_label);
1554 obj = SLOT(u2->cr_label);
1555
1556 /* XXX: range */
1557 if (!mac_biba_dominate_effective(obj, subj))
1558 return (ESRCH);
1559
1560 return (0);
1561 }
1562
1563 static int
1564 mac_biba_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet,
1565 struct label *ifnetlabel, struct label *newlabel)
1566 {
1567 struct mac_biba *subj, *new;
1568 int error;
1569
1570 subj = SLOT(cred->cr_label);
1571 new = SLOT(newlabel);
1572
1573 /*
1574 * If there is a Biba label update for the interface, it may
1575 * be an update of the effective, range, or both.
1576 */
1577 error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
1578 if (error)
1579 return (error);
1580
1581 /*
1582 * Relabling network interfaces requires Biba privilege.
1583 */
1584 error = mac_biba_subject_privileged(subj);
1585 if (error)
1586 return (error);
1587
1588 return (0);
1589 }
1590
1591 static int
1592 mac_biba_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel,
1593 struct mbuf *m, struct label *mbuflabel)
1594 {
1595 struct mac_biba *p, *i;
1596
1597 if (!mac_biba_enabled)
1598 return (0);
1599
1600 p = SLOT(mbuflabel);
1601 i = SLOT(ifnetlabel);
1602
1603 return (mac_biba_effective_in_range(p, i) ? 0 : EACCES);
1604 }
1605
1606 static int
1607 mac_biba_check_inpcb_deliver(struct inpcb *inp, struct label *inplabel,
1608 struct mbuf *m, struct label *mlabel)
1609 {
1610 struct mac_biba *p, *i;
1611
1612 if (!mac_biba_enabled)
1613 return (0);
1614
1615 p = SLOT(mlabel);
1616 i = SLOT(inplabel);
1617
1618 return (mac_biba_equal_effective(p, i) ? 0 : EACCES);
1619 }
1620
1621 static int
1622 mac_biba_check_sysv_msgrcv(struct ucred *cred, struct msg *msgptr,
1623 struct label *msglabel)
1624 {
1625 struct mac_biba *subj, *obj;
1626
1627 if (!mac_biba_enabled)
1628 return (0);
1629
1630 subj = SLOT(cred->cr_label);
1631 obj = SLOT(msglabel);
1632
1633 if (!mac_biba_dominate_effective(obj, subj))
1634 return (EACCES);
1635
1636 return (0);
1637 }
1638
1639 static int
1640 mac_biba_check_sysv_msgrmid(struct ucred *cred, struct msg *msgptr,
1641 struct label *msglabel)
1642 {
1643 struct mac_biba *subj, *obj;
1644
1645 if (!mac_biba_enabled)
1646 return (0);
1647
1648 subj = SLOT(cred->cr_label);
1649 obj = SLOT(msglabel);
1650
1651 if (!mac_biba_dominate_effective(subj, obj))
1652 return (EACCES);
1653
1654 return (0);
1655 }
1656
1657 static int
1658 mac_biba_check_sysv_msqget(struct ucred *cred, struct msqid_kernel *msqkptr,
1659 struct label *msqklabel)
1660 {
1661 struct mac_biba *subj, *obj;
1662
1663 if (!mac_biba_enabled)
1664 return (0);
1665
1666 subj = SLOT(cred->cr_label);
1667 obj = SLOT(msqklabel);
1668
1669 if (!mac_biba_dominate_effective(obj, subj))
1670 return (EACCES);
1671
1672 return (0);
1673 }
1674
1675 static int
1676 mac_biba_check_sysv_msqsnd(struct ucred *cred, struct msqid_kernel *msqkptr,
1677 struct label *msqklabel)
1678 {
1679 struct mac_biba *subj, *obj;
1680
1681 if (!mac_biba_enabled)
1682 return (0);
1683
1684 subj = SLOT(cred->cr_label);
1685 obj = SLOT(msqklabel);
1686
1687 if (!mac_biba_dominate_effective(subj, obj))
1688 return (EACCES);
1689
1690 return (0);
1691 }
1692
1693 static int
1694 mac_biba_check_sysv_msqrcv(struct ucred *cred, struct msqid_kernel *msqkptr,
1695 struct label *msqklabel)
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(msqklabel);
1704
1705 if (!mac_biba_dominate_effective(obj, subj))
1706 return (EACCES);
1707
1708 return (0);
1709 }
1710
1711
1712 static int
1713 mac_biba_check_sysv_msqctl(struct ucred *cred, struct msqid_kernel *msqkptr,
1714 struct label *msqklabel, int cmd)
1715 {
1716 struct mac_biba *subj, *obj;
1717
1718 if (!mac_biba_enabled)
1719 return (0);
1720
1721 subj = SLOT(cred->cr_label);
1722 obj = SLOT(msqklabel);
1723
1724 switch(cmd) {
1725 case IPC_RMID:
1726 case IPC_SET:
1727 if (!mac_biba_dominate_effective(subj, obj))
1728 return (EACCES);
1729 break;
1730
1731 case IPC_STAT:
1732 if (!mac_biba_dominate_effective(obj, subj))
1733 return (EACCES);
1734 break;
1735
1736 default:
1737 return (EACCES);
1738 }
1739
1740 return (0);
1741 }
1742
1743 static int
1744 mac_biba_check_sysv_semctl(struct ucred *cred, struct semid_kernel *semakptr,
1745 struct label *semaklabel, int cmd)
1746 {
1747 struct mac_biba *subj, *obj;
1748
1749 if (!mac_biba_enabled)
1750 return (0);
1751
1752 subj = SLOT(cred->cr_label);
1753 obj = SLOT(semaklabel);
1754
1755 switch(cmd) {
1756 case IPC_RMID:
1757 case IPC_SET:
1758 case SETVAL:
1759 case SETALL:
1760 if (!mac_biba_dominate_effective(subj, obj))
1761 return (EACCES);
1762 break;
1763
1764 case IPC_STAT:
1765 case GETVAL:
1766 case GETPID:
1767 case GETNCNT:
1768 case GETZCNT:
1769 case GETALL:
1770 if (!mac_biba_dominate_effective(obj, subj))
1771 return (EACCES);
1772 break;
1773
1774 default:
1775 return (EACCES);
1776 }
1777
1778 return (0);
1779 }
1780
1781
1782 static int
1783 mac_biba_check_sysv_semget(struct ucred *cred, struct semid_kernel *semakptr,
1784 struct label *semaklabel)
1785 {
1786 struct mac_biba *subj, *obj;
1787
1788 if (!mac_biba_enabled)
1789 return (0);
1790
1791 subj = SLOT(cred->cr_label);
1792 obj = SLOT(semaklabel);
1793
1794 if (!mac_biba_dominate_effective(obj, subj))
1795 return (EACCES);
1796
1797 return (0);
1798 }
1799
1800
1801 static int
1802 mac_biba_check_sysv_semop(struct ucred *cred, struct semid_kernel *semakptr,
1803 struct label *semaklabel, size_t accesstype)
1804 {
1805 struct mac_biba *subj, *obj;
1806
1807 if (!mac_biba_enabled)
1808 return (0);
1809
1810 subj = SLOT(cred->cr_label);
1811 obj = SLOT(semaklabel);
1812
1813 if (accesstype & SEM_R)
1814 if (!mac_biba_dominate_effective(obj, subj))
1815 return (EACCES);
1816
1817 if (accesstype & SEM_A)
1818 if (!mac_biba_dominate_effective(subj, obj))
1819 return (EACCES);
1820
1821 return (0);
1822 }
1823
1824 static int
1825 mac_biba_check_sysv_shmat(struct ucred *cred, struct shmid_kernel *shmsegptr,
1826 struct label *shmseglabel, int shmflg)
1827 {
1828 struct mac_biba *subj, *obj;
1829
1830 if (!mac_biba_enabled)
1831 return (0);
1832
1833 subj = SLOT(cred->cr_label);
1834 obj = SLOT(shmseglabel);
1835
1836 if (!mac_biba_dominate_effective(obj, subj))
1837 return (EACCES);
1838 if ((shmflg & SHM_RDONLY) == 0) {
1839 if (!mac_biba_dominate_effective(subj, obj))
1840 return (EACCES);
1841 }
1842
1843 return (0);
1844 }
1845
1846 static int
1847 mac_biba_check_sysv_shmctl(struct ucred *cred, struct shmid_kernel *shmsegptr,
1848 struct label *shmseglabel, int cmd)
1849 {
1850 struct mac_biba *subj, *obj;
1851
1852 if (!mac_biba_enabled)
1853 return (0);
1854
1855 subj = SLOT(cred->cr_label);
1856 obj = SLOT(shmseglabel);
1857
1858 switch(cmd) {
1859 case IPC_RMID:
1860 case IPC_SET:
1861 if (!mac_biba_dominate_effective(subj, obj))
1862 return (EACCES);
1863 break;
1864
1865 case IPC_STAT:
1866 case SHM_STAT:
1867 if (!mac_biba_dominate_effective(obj, subj))
1868 return (EACCES);
1869 break;
1870
1871 default:
1872 return (EACCES);
1873 }
1874
1875 return (0);
1876 }
1877
1878 static int
1879 mac_biba_check_sysv_shmget(struct ucred *cred, struct shmid_kernel *shmsegptr,
1880 struct label *shmseglabel, int shmflg)
1881 {
1882 struct mac_biba *subj, *obj;
1883
1884 if (!mac_biba_enabled)
1885 return (0);
1886
1887 subj = SLOT(cred->cr_label);
1888 obj = SLOT(shmseglabel);
1889
1890 if (!mac_biba_dominate_effective(obj, subj))
1891 return (EACCES);
1892
1893 return (0);
1894 }
1895
1896 static int
1897 mac_biba_check_kld_load(struct ucred *cred, struct vnode *vp,
1898 struct label *label)
1899 {
1900 struct mac_biba *subj, *obj;
1901 int error;
1902
1903 if (!mac_biba_enabled)
1904 return (0);
1905
1906 subj = SLOT(cred->cr_label);
1907
1908 error = mac_biba_subject_privileged(subj);
1909 if (error)
1910 return (error);
1911
1912 obj = SLOT(label);
1913 if (!mac_biba_high_effective(obj))
1914 return (EACCES);
1915
1916 return (0);
1917 }
1918
1919
1920 static int
1921 mac_biba_check_kld_unload(struct ucred *cred)
1922 {
1923 struct mac_biba *subj;
1924
1925 if (!mac_biba_enabled)
1926 return (0);
1927
1928 subj = SLOT(cred->cr_label);
1929
1930 return (mac_biba_subject_privileged(subj));
1931 }
1932
1933 static int
1934 mac_biba_check_mount_stat(struct ucred *cred, struct mount *mp,
1935 struct label *mntlabel)
1936 {
1937 struct mac_biba *subj, *obj;
1938
1939 if (!mac_biba_enabled)
1940 return (0);
1941
1942 subj = SLOT(cred->cr_label);
1943 obj = SLOT(mntlabel);
1944
1945 if (!mac_biba_dominate_effective(obj, subj))
1946 return (EACCES);
1947
1948 return (0);
1949 }
1950
1951 static int
1952 mac_biba_check_pipe_ioctl(struct ucred *cred, struct pipepair *pp,
1953 struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data)
1954 {
1955
1956 if(!mac_biba_enabled)
1957 return (0);
1958
1959 /* XXX: This will be implemented soon... */
1960
1961 return (0);
1962 }
1963
1964 static int
1965 mac_biba_check_pipe_poll(struct ucred *cred, struct pipepair *pp,
1966 struct label *pipelabel)
1967 {
1968 struct mac_biba *subj, *obj;
1969
1970 if (!mac_biba_enabled)
1971 return (0);
1972
1973 subj = SLOT(cred->cr_label);
1974 obj = SLOT((pipelabel));
1975
1976 if (!mac_biba_dominate_effective(obj, subj))
1977 return (EACCES);
1978
1979 return (0);
1980 }
1981
1982 static int
1983 mac_biba_check_pipe_read(struct ucred *cred, struct pipepair *pp,
1984 struct label *pipelabel)
1985 {
1986 struct mac_biba *subj, *obj;
1987
1988 if (!mac_biba_enabled)
1989 return (0);
1990
1991 subj = SLOT(cred->cr_label);
1992 obj = SLOT((pipelabel));
1993
1994 if (!mac_biba_dominate_effective(obj, subj))
1995 return (EACCES);
1996
1997 return (0);
1998 }
1999
2000 static int
2001 mac_biba_check_pipe_relabel(struct ucred *cred, struct pipepair *pp,
2002 struct label *pipelabel, struct label *newlabel)
2003 {
2004 struct mac_biba *subj, *obj, *new;
2005 int error;
2006
2007 new = SLOT(newlabel);
2008 subj = SLOT(cred->cr_label);
2009 obj = SLOT(pipelabel);
2010
2011 /*
2012 * If there is a Biba label update for a pipe, it must be a
2013 * effective update.
2014 */
2015 error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE);
2016 if (error)
2017 return (error);
2018
2019 /*
2020 * To perform a relabel of a pipe (Biba label or not), Biba must
2021 * authorize the relabel.
2022 */
2023 if (!mac_biba_effective_in_range(obj, subj))
2024 return (EPERM);
2025
2026 /*
2027 * If the Biba label is to be changed, authorize as appropriate.
2028 */
2029 if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
2030 /*
2031 * To change the Biba label on a pipe, the new pipe label
2032 * must be in the subject range.
2033 */
2034 if (!mac_biba_effective_in_range(new, subj))
2035 return (EPERM);
2036
2037 /*
2038 * To change the Biba label on a pipe to be EQUAL, the
2039 * subject must have appropriate privilege.
2040 */
2041 if (mac_biba_contains_equal(new)) {
2042 error = mac_biba_subject_privileged(subj);
2043 if (error)
2044 return (error);
2045 }
2046 }
2047
2048 return (0);
2049 }
2050
2051 static int
2052 mac_biba_check_pipe_stat(struct ucred *cred, struct pipepair *pp,
2053 struct label *pipelabel)
2054 {
2055 struct mac_biba *subj, *obj;
2056
2057 if (!mac_biba_enabled)
2058 return (0);
2059
2060 subj = SLOT(cred->cr_label);
2061 obj = SLOT((pipelabel));
2062
2063 if (!mac_biba_dominate_effective(obj, subj))
2064 return (EACCES);
2065
2066 return (0);
2067 }
2068
2069 static int
2070 mac_biba_check_pipe_write(struct ucred *cred, struct pipepair *pp,
2071 struct label *pipelabel)
2072 {
2073 struct mac_biba *subj, *obj;
2074
2075 if (!mac_biba_enabled)
2076 return (0);
2077
2078 subj = SLOT(cred->cr_label);
2079 obj = SLOT((pipelabel));
2080
2081 if (!mac_biba_dominate_effective(subj, obj))
2082 return (EACCES);
2083
2084 return (0);
2085 }
2086
2087 static int
2088 mac_biba_check_posix_sem_write(struct ucred *cred, struct ksem *ksemptr,
2089 struct label *ks_label)
2090 {
2091 struct mac_biba *subj, *obj;
2092
2093 if (!mac_biba_enabled)
2094 return (0);
2095
2096 subj = SLOT(cred->cr_label);
2097 obj = SLOT(ks_label);
2098
2099 if (!mac_biba_dominate_effective(subj, obj))
2100 return (EACCES);
2101
2102 return (0);
2103 }
2104
2105 static int
2106 mac_biba_check_posix_sem_rdonly(struct ucred *cred, struct ksem *ksemptr,
2107 struct label *ks_label)
2108 {
2109 struct mac_biba *subj, *obj;
2110
2111 if (!mac_biba_enabled)
2112 return (0);
2113
2114 subj = SLOT(cred->cr_label);
2115 obj = SLOT(ks_label);
2116
2117 if (!mac_biba_dominate_effective(obj, subj))
2118 return (EACCES);
2119
2120 return (0);
2121 }
2122
2123 static int
2124 mac_biba_check_proc_debug(struct ucred *cred, struct proc *proc)
2125 {
2126 struct mac_biba *subj, *obj;
2127
2128 if (!mac_biba_enabled)
2129 return (0);
2130
2131 subj = SLOT(cred->cr_label);
2132 obj = SLOT(proc->p_ucred->cr_label);
2133
2134 /* XXX: range checks */
2135 if (!mac_biba_dominate_effective(obj, subj))
2136 return (ESRCH);
2137 if (!mac_biba_dominate_effective(subj, obj))
2138 return (EACCES);
2139
2140 return (0);
2141 }
2142
2143 static int
2144 mac_biba_check_proc_sched(struct ucred *cred, struct proc *proc)
2145 {
2146 struct mac_biba *subj, *obj;
2147
2148 if (!mac_biba_enabled)
2149 return (0);
2150
2151 subj = SLOT(cred->cr_label);
2152 obj = SLOT(proc->p_ucred->cr_label);
2153
2154 /* XXX: range checks */
2155 if (!mac_biba_dominate_effective(obj, subj))
2156 return (ESRCH);
2157 if (!mac_biba_dominate_effective(subj, obj))
2158 return (EACCES);
2159
2160 return (0);
2161 }
2162
2163 static int
2164 mac_biba_check_proc_signal(struct ucred *cred, struct proc *proc, int signum)
2165 {
2166 struct mac_biba *subj, *obj;
2167
2168 if (!mac_biba_enabled)
2169 return (0);
2170
2171 subj = SLOT(cred->cr_label);
2172 obj = SLOT(proc->p_ucred->cr_label);
2173
2174 /* XXX: range checks */
2175 if (!mac_biba_dominate_effective(obj, subj))
2176 return (ESRCH);
2177 if (!mac_biba_dominate_effective(subj, obj))
2178 return (EACCES);
2179
2180 return (0);
2181 }
2182
2183 static int
2184 mac_biba_check_socket_deliver(struct socket *so, struct label *socketlabel,
2185 struct mbuf *m, struct label *mbuflabel)
2186 {
2187 struct mac_biba *p, *s;
2188
2189 if (!mac_biba_enabled)
2190 return (0);
2191
2192 p = SLOT(mbuflabel);
2193 s = SLOT(socketlabel);
2194
2195 return (mac_biba_equal_effective(p, s) ? 0 : EACCES);
2196 }
2197
2198 static int
2199 mac_biba_check_socket_relabel(struct ucred *cred, struct socket *so,
2200 struct label *socketlabel, struct label *newlabel)
2201 {
2202 struct mac_biba *subj, *obj, *new;
2203 int error;
2204
2205 new = SLOT(newlabel);
2206 subj = SLOT(cred->cr_label);
2207 obj = SLOT(socketlabel);
2208
2209 /*
2210 * If there is a Biba label update for the socket, it may be
2211 * an update of effective.
2212 */
2213 error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE);
2214 if (error)
2215 return (error);
2216
2217 /*
2218 * To relabel a socket, the old socket effective must be in the subject
2219 * range.
2220 */
2221 if (!mac_biba_effective_in_range(obj, subj))
2222 return (EPERM);
2223
2224 /*
2225 * If the Biba label is to be changed, authorize as appropriate.
2226 */
2227 if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
2228 /*
2229 * To relabel a socket, the new socket effective must be in
2230 * the subject range.
2231 */
2232 if (!mac_biba_effective_in_range(new, subj))
2233 return (EPERM);
2234
2235 /*
2236 * To change the Biba label on the socket to contain EQUAL,
2237 * the subject must have appropriate privilege.
2238 */
2239 if (mac_biba_contains_equal(new)) {
2240 error = mac_biba_subject_privileged(subj);
2241 if (error)
2242 return (error);
2243 }
2244 }
2245
2246 return (0);
2247 }
2248
2249 static int
2250 mac_biba_check_socket_visible(struct ucred *cred, struct socket *socket,
2251 struct label *socketlabel)
2252 {
2253 struct mac_biba *subj, *obj;
2254
2255 if (!mac_biba_enabled)
2256 return (0);
2257
2258 subj = SLOT(cred->cr_label);
2259 obj = SLOT(socketlabel);
2260
2261 if (!mac_biba_dominate_effective(obj, subj))
2262 return (ENOENT);
2263
2264 return (0);
2265 }
2266
2267 static int
2268 mac_biba_check_sysarch_ioperm(struct ucred *cred)
2269 {
2270 struct mac_biba *subj;
2271 int error;
2272
2273 if (!mac_biba_enabled)
2274 return (0);
2275
2276 subj = SLOT(cred->cr_label);
2277
2278 error = mac_biba_subject_privileged(subj);
2279 if (error)
2280 return (error);
2281
2282 return (0);
2283 }
2284
2285 static int
2286 mac_biba_check_system_acct(struct ucred *cred, struct vnode *vp,
2287 struct label *label)
2288 {
2289 struct mac_biba *subj, *obj;
2290 int error;
2291
2292 if (!mac_biba_enabled)
2293 return (0);
2294
2295 subj = SLOT(cred->cr_label);
2296
2297 error = mac_biba_subject_privileged(subj);
2298 if (error)
2299 return (error);
2300
2301 if (label == NULL)
2302 return (0);
2303
2304 obj = SLOT(label);
2305 if (!mac_biba_high_effective(obj))
2306 return (EACCES);
2307
2308 return (0);
2309 }
2310
2311 static int
2312 mac_biba_check_system_settime(struct ucred *cred)
2313 {
2314 struct mac_biba *subj;
2315 int error;
2316
2317 if (!mac_biba_enabled)
2318 return (0);
2319
2320 subj = SLOT(cred->cr_label);
2321
2322 error = mac_biba_subject_privileged(subj);
2323 if (error)
2324 return (error);
2325
2326 return (0);
2327 }
2328
2329 static int
2330 mac_biba_check_system_swapon(struct ucred *cred, struct vnode *vp,
2331 struct label *label)
2332 {
2333 struct mac_biba *subj, *obj;
2334 int error;
2335
2336 if (!mac_biba_enabled)
2337 return (0);
2338
2339 subj = SLOT(cred->cr_label);
2340 obj = SLOT(label);
2341
2342 error = mac_biba_subject_privileged(subj);
2343 if (error)
2344 return (error);
2345
2346 if (!mac_biba_high_effective(obj))
2347 return (EACCES);
2348
2349 return (0);
2350 }
2351
2352 static int
2353 mac_biba_check_system_swapoff(struct ucred *cred, struct vnode *vp,
2354 struct label *label)
2355 {
2356 struct mac_biba *subj, *obj;
2357 int error;
2358
2359 if (!mac_biba_enabled)
2360 return (0);
2361
2362 subj = SLOT(cred->cr_label);
2363 obj = SLOT(label);
2364
2365 error = mac_biba_subject_privileged(subj);
2366 if (error)
2367 return (error);
2368
2369 return (0);
2370 }
2371
2372 static int
2373 mac_biba_check_system_sysctl(struct ucred *cred, struct sysctl_oid *oidp,
2374 void *arg1, int arg2, struct sysctl_req *req)
2375 {
2376 struct mac_biba *subj;
2377 int error;
2378
2379 if (!mac_biba_enabled)
2380 return (0);
2381
2382 subj = SLOT(cred->cr_label);
2383
2384 /*
2385 * Treat sysctl variables without CTLFLAG_ANYBODY flag as
2386 * biba/high, but also require privilege to change them.
2387 */
2388 if (req->newptr != NULL && (oidp->oid_kind & CTLFLAG_ANYBODY) == 0) {
2389 if (!mac_biba_subject_dominate_high(subj))
2390 return (EACCES);
2391
2392 error = mac_biba_subject_privileged(subj);
2393 if (error)
2394 return (error);
2395 }
2396
2397 return (0);
2398 }
2399
2400 static int
2401 mac_biba_check_vnode_chdir(struct ucred *cred, struct vnode *dvp,
2402 struct label *dlabel)
2403 {
2404 struct mac_biba *subj, *obj;
2405
2406 if (!mac_biba_enabled)
2407 return (0);
2408
2409 subj = SLOT(cred->cr_label);
2410 obj = SLOT(dlabel);
2411
2412 if (!mac_biba_dominate_effective(obj, subj))
2413 return (EACCES);
2414
2415 return (0);
2416 }
2417
2418 static int
2419 mac_biba_check_vnode_chroot(struct ucred *cred, struct vnode *dvp,
2420 struct label *dlabel)
2421 {
2422 struct mac_biba *subj, *obj;
2423
2424 if (!mac_biba_enabled)
2425 return (0);
2426
2427 subj = SLOT(cred->cr_label);
2428 obj = SLOT(dlabel);
2429
2430 if (!mac_biba_dominate_effective(obj, subj))
2431 return (EACCES);
2432
2433 return (0);
2434 }
2435
2436 static int
2437 mac_biba_check_vnode_create(struct ucred *cred, struct vnode *dvp,
2438 struct label *dlabel, struct componentname *cnp, struct vattr *vap)
2439 {
2440 struct mac_biba *subj, *obj;
2441
2442 if (!mac_biba_enabled)
2443 return (0);
2444
2445 subj = SLOT(cred->cr_label);
2446 obj = SLOT(dlabel);
2447
2448 if (!mac_biba_dominate_effective(subj, obj))
2449 return (EACCES);
2450
2451 return (0);
2452 }
2453
2454 static int
2455 mac_biba_check_vnode_delete(struct ucred *cred, struct vnode *dvp,
2456 struct label *dlabel, struct vnode *vp, struct label *label,
2457 struct componentname *cnp)
2458 {
2459 struct mac_biba *subj, *obj;
2460
2461 if (!mac_biba_enabled)
2462 return (0);
2463
2464 subj = SLOT(cred->cr_label);
2465 obj = SLOT(dlabel);
2466
2467 if (!mac_biba_dominate_effective(subj, obj))
2468 return (EACCES);
2469
2470 obj = SLOT(label);
2471
2472 if (!mac_biba_dominate_effective(subj, obj))
2473 return (EACCES);
2474
2475 return (0);
2476 }
2477
2478 static int
2479 mac_biba_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
2480 struct label *label, acl_type_t type)
2481 {
2482 struct mac_biba *subj, *obj;
2483
2484 if (!mac_biba_enabled)
2485 return (0);
2486
2487 subj = SLOT(cred->cr_label);
2488 obj = SLOT(label);
2489
2490 if (!mac_biba_dominate_effective(subj, obj))
2491 return (EACCES);
2492
2493 return (0);
2494 }
2495
2496 static int
2497 mac_biba_check_vnode_deleteextattr(struct ucred *cred, struct vnode *vp,
2498 struct label *label, int attrnamespace, const char *name)
2499 {
2500 struct mac_biba *subj, *obj;
2501
2502 if (!mac_biba_enabled)
2503 return (0);
2504
2505 subj = SLOT(cred->cr_label);
2506 obj = SLOT(label);
2507
2508 if (!mac_biba_dominate_effective(subj, obj))
2509 return (EACCES);
2510
2511 return (0);
2512 }
2513
2514 static int
2515 mac_biba_check_vnode_exec(struct ucred *cred, struct vnode *vp,
2516 struct label *label, struct image_params *imgp,
2517 struct label *execlabel)
2518 {
2519 struct mac_biba *subj, *obj, *exec;
2520 int error;
2521
2522 if (execlabel != NULL) {
2523 /*
2524 * We currently don't permit labels to be changed at
2525 * exec-time as part of Biba, so disallow non-NULL
2526 * Biba label elements in the execlabel.
2527 */
2528 exec = SLOT(execlabel);
2529 error = biba_atmostflags(exec, 0);
2530 if (error)
2531 return (error);
2532 }
2533
2534 if (!mac_biba_enabled)
2535 return (0);
2536
2537 subj = SLOT(cred->cr_label);
2538 obj = SLOT(label);
2539
2540 if (!mac_biba_dominate_effective(obj, subj))
2541 return (EACCES);
2542
2543 return (0);
2544 }
2545
2546 static int
2547 mac_biba_check_vnode_getacl(struct ucred *cred, struct vnode *vp,
2548 struct label *label, acl_type_t type)
2549 {
2550 struct mac_biba *subj, *obj;
2551
2552 if (!mac_biba_enabled)
2553 return (0);
2554
2555 subj = SLOT(cred->cr_label);
2556 obj = SLOT(label);
2557
2558 if (!mac_biba_dominate_effective(obj, subj))
2559 return (EACCES);
2560
2561 return (0);
2562 }
2563
2564 static int
2565 mac_biba_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
2566 struct label *label, int attrnamespace, const char *name, struct uio *uio)
2567 {
2568 struct mac_biba *subj, *obj;
2569
2570 if (!mac_biba_enabled)
2571 return (0);
2572
2573 subj = SLOT(cred->cr_label);
2574 obj = SLOT(label);
2575
2576 if (!mac_biba_dominate_effective(obj, subj))
2577 return (EACCES);
2578
2579 return (0);
2580 }
2581
2582 static int
2583 mac_biba_check_vnode_link(struct ucred *cred, struct vnode *dvp,
2584 struct label *dlabel, struct vnode *vp, struct label *label,
2585 struct componentname *cnp)
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(dlabel);
2594
2595 if (!mac_biba_dominate_effective(subj, obj))
2596 return (EACCES);
2597
2598 obj = SLOT(label);
2599
2600 if (!mac_biba_dominate_effective(subj, obj))
2601 return (EACCES);
2602
2603 return (0);
2604 }
2605
2606 static int
2607 mac_biba_check_vnode_listextattr(struct ucred *cred, struct vnode *vp,
2608 struct label *label, int attrnamespace)
2609 {
2610 struct mac_biba *subj, *obj;
2611
2612 if (!mac_biba_enabled)
2613 return (0);
2614
2615 subj = SLOT(cred->cr_label);
2616 obj = SLOT(label);
2617
2618 if (!mac_biba_dominate_effective(obj, subj))
2619 return (EACCES);
2620
2621 return (0);
2622 }
2623
2624 static int
2625 mac_biba_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
2626 struct label *dlabel, struct componentname *cnp)
2627 {
2628 struct mac_biba *subj, *obj;
2629
2630 if (!mac_biba_enabled)
2631 return (0);
2632
2633 subj = SLOT(cred->cr_label);
2634 obj = SLOT(dlabel);
2635
2636 if (!mac_biba_dominate_effective(obj, subj))
2637 return (EACCES);
2638
2639 return (0);
2640 }
2641
2642 static int
2643 mac_biba_check_vnode_mmap(struct ucred *cred, struct vnode *vp,
2644 struct label *label, int prot, int flags)
2645 {
2646 struct mac_biba *subj, *obj;
2647
2648 /*
2649 * Rely on the use of open()-time protections to handle
2650 * non-revocation cases.
2651 */
2652 if (!mac_biba_enabled || !revocation_enabled)
2653 return (0);
2654
2655 subj = SLOT(cred->cr_label);
2656 obj = SLOT(label);
2657
2658 if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
2659 if (!mac_biba_dominate_effective(obj, subj))
2660 return (EACCES);
2661 }
2662 if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) {
2663 if (!mac_biba_dominate_effective(subj, obj))
2664 return (EACCES);
2665 }
2666
2667 return (0);
2668 }
2669
2670 static int
2671 mac_biba_check_vnode_open(struct ucred *cred, struct vnode *vp,
2672 struct label *vnodelabel, int acc_mode)
2673 {
2674 struct mac_biba *subj, *obj;
2675
2676 if (!mac_biba_enabled)
2677 return (0);
2678
2679 subj = SLOT(cred->cr_label);
2680 obj = SLOT(vnodelabel);
2681
2682 /* XXX privilege override for admin? */
2683 if (acc_mode & (VREAD | VEXEC | VSTAT)) {
2684 if (!mac_biba_dominate_effective(obj, subj))
2685 return (EACCES);
2686 }
2687 if (acc_mode & (VWRITE | VAPPEND | VADMIN)) {
2688 if (!mac_biba_dominate_effective(subj, obj))
2689 return (EACCES);
2690 }
2691
2692 return (0);
2693 }
2694
2695 static int
2696 mac_biba_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred,
2697 struct vnode *vp, struct label *label)
2698 {
2699 struct mac_biba *subj, *obj;
2700
2701 if (!mac_biba_enabled || !revocation_enabled)
2702 return (0);
2703
2704 subj = SLOT(active_cred->cr_label);
2705 obj = SLOT(label);
2706
2707 if (!mac_biba_dominate_effective(obj, subj))
2708 return (EACCES);
2709
2710 return (0);
2711 }
2712
2713 static int
2714 mac_biba_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
2715 struct vnode *vp, struct label *label)
2716 {
2717 struct mac_biba *subj, *obj;
2718
2719 if (!mac_biba_enabled || !revocation_enabled)
2720 return (0);
2721
2722 subj = SLOT(active_cred->cr_label);
2723 obj = SLOT(label);
2724
2725 if (!mac_biba_dominate_effective(obj, subj))
2726 return (EACCES);
2727
2728 return (0);
2729 }
2730
2731 static int
2732 mac_biba_check_vnode_readdir(struct ucred *cred, struct vnode *dvp,
2733 struct label *dlabel)
2734 {
2735 struct mac_biba *subj, *obj;
2736
2737 if (!mac_biba_enabled)
2738 return (0);
2739
2740 subj = SLOT(cred->cr_label);
2741 obj = SLOT(dlabel);
2742
2743 if (!mac_biba_dominate_effective(obj, subj))
2744 return (EACCES);
2745
2746 return (0);
2747 }
2748
2749 static int
2750 mac_biba_check_vnode_readlink(struct ucred *cred, struct vnode *vp,
2751 struct label *label)
2752 {
2753 struct mac_biba *subj, *obj;
2754
2755 if (!mac_biba_enabled)
2756 return (0);
2757
2758 subj = SLOT(cred->cr_label);
2759 obj = SLOT(label);
2760
2761 if (!mac_biba_dominate_effective(obj, subj))
2762 return (EACCES);
2763
2764 return (0);
2765 }
2766
2767 static int
2768 mac_biba_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
2769 struct label *vnodelabel, struct label *newlabel)
2770 {
2771 struct mac_biba *old, *new, *subj;
2772 int error;
2773
2774 old = SLOT(vnodelabel);
2775 new = SLOT(newlabel);
2776 subj = SLOT(cred->cr_label);
2777
2778 /*
2779 * If there is a Biba label update for the vnode, it must be a
2780 * effective label.
2781 */
2782 error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE);
2783 if (error)
2784 return (error);
2785
2786 /*
2787 * To perform a relabel of the vnode (Biba label or not), Biba must
2788 * authorize the relabel.
2789 */
2790 if (!mac_biba_effective_in_range(old, subj))
2791 return (EPERM);
2792
2793 /*
2794 * If the Biba label is to be changed, authorize as appropriate.
2795 */
2796 if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
2797 /*
2798 * To change the Biba label on a vnode, the new vnode label
2799 * must be in the subject range.
2800 */
2801 if (!mac_biba_effective_in_range(new, subj))
2802 return (EPERM);
2803
2804 /*
2805 * To change the Biba label on the vnode to be EQUAL,
2806 * the subject must have appropriate privilege.
2807 */
2808 if (mac_biba_contains_equal(new)) {
2809 error = mac_biba_subject_privileged(subj);
2810 if (error)
2811 return (error);
2812 }
2813 }
2814
2815 return (0);
2816 }
2817
2818 static int
2819 mac_biba_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
2820 struct label *dlabel, struct vnode *vp, struct label *label,
2821 struct componentname *cnp)
2822 {
2823 struct mac_biba *subj, *obj;
2824
2825 if (!mac_biba_enabled)
2826 return (0);
2827
2828 subj = SLOT(cred->cr_label);
2829 obj = SLOT(dlabel);
2830
2831 if (!mac_biba_dominate_effective(subj, obj))
2832 return (EACCES);
2833
2834 obj = SLOT(label);
2835
2836 if (!mac_biba_dominate_effective(subj, obj))
2837 return (EACCES);
2838
2839 return (0);
2840 }
2841
2842 static int
2843 mac_biba_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
2844 struct label *dlabel, struct vnode *vp, struct label *label, int samedir,
2845 struct componentname *cnp)
2846 {
2847 struct mac_biba *subj, *obj;
2848
2849 if (!mac_biba_enabled)
2850 return (0);
2851
2852 subj = SLOT(cred->cr_label);
2853 obj = SLOT(dlabel);
2854
2855 if (!mac_biba_dominate_effective(subj, obj))
2856 return (EACCES);
2857
2858 if (vp != NULL) {
2859 obj = SLOT(label);
2860
2861 if (!mac_biba_dominate_effective(subj, obj))
2862 return (EACCES);
2863 }
2864
2865 return (0);
2866 }
2867
2868 static int
2869 mac_biba_check_vnode_revoke(struct ucred *cred, struct vnode *vp,
2870 struct label *label)
2871 {
2872 struct mac_biba *subj, *obj;
2873
2874 if (!mac_biba_enabled)
2875 return (0);
2876
2877 subj = SLOT(cred->cr_label);
2878 obj = SLOT(label);
2879
2880 if (!mac_biba_dominate_effective(subj, obj))
2881 return (EACCES);
2882
2883 return (0);
2884 }
2885
2886 static int
2887 mac_biba_check_vnode_setacl(struct ucred *cred, struct vnode *vp,
2888 struct label *label, acl_type_t type, struct acl *acl)
2889 {
2890 struct mac_biba *subj, *obj;
2891
2892 if (!mac_biba_enabled)
2893 return (0);
2894
2895 subj = SLOT(cred->cr_label);
2896 obj = SLOT(label);
2897
2898 if (!mac_biba_dominate_effective(subj, obj))
2899 return (EACCES);
2900
2901 return (0);
2902 }
2903
2904 static int
2905 mac_biba_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
2906 struct label *vnodelabel, int attrnamespace, const char *name,
2907 struct uio *uio)
2908 {
2909 struct mac_biba *subj, *obj;
2910
2911 if (!mac_biba_enabled)
2912 return (0);
2913
2914 subj = SLOT(cred->cr_label);
2915 obj = SLOT(vnodelabel);
2916
2917 if (!mac_biba_dominate_effective(subj, obj))
2918 return (EACCES);
2919
2920 /* XXX: protect the MAC EA in a special way? */
2921
2922 return (0);
2923 }
2924
2925 static int
2926 mac_biba_check_vnode_setflags(struct ucred *cred, struct vnode *vp,
2927 struct label *vnodelabel, u_long flags)
2928 {
2929 struct mac_biba *subj, *obj;
2930
2931 if (!mac_biba_enabled)
2932 return (0);
2933
2934 subj = SLOT(cred->cr_label);
2935 obj = SLOT(vnodelabel);
2936
2937 if (!mac_biba_dominate_effective(subj, obj))
2938 return (EACCES);
2939
2940 return (0);
2941 }
2942
2943 static int
2944 mac_biba_check_vnode_setmode(struct ucred *cred, struct vnode *vp,
2945 struct label *vnodelabel, mode_t mode)
2946 {
2947 struct mac_biba *subj, *obj;
2948
2949 if (!mac_biba_enabled)
2950 return (0);
2951
2952 subj = SLOT(cred->cr_label);
2953 obj = SLOT(vnodelabel);
2954
2955 if (!mac_biba_dominate_effective(subj, obj))
2956 return (EACCES);
2957
2958 return (0);
2959 }
2960
2961 static int
2962 mac_biba_check_vnode_setowner(struct ucred *cred, struct vnode *vp,
2963 struct label *vnodelabel, uid_t uid, gid_t gid)
2964 {
2965 struct mac_biba *subj, *obj;
2966
2967 if (!mac_biba_enabled)
2968 return (0);
2969
2970 subj = SLOT(cred->cr_label);
2971 obj = SLOT(vnodelabel);
2972
2973 if (!mac_biba_dominate_effective(subj, obj))
2974 return (EACCES);
2975
2976 return (0);
2977 }
2978
2979 static int
2980 mac_biba_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
2981 struct label *vnodelabel, struct timespec atime, struct timespec mtime)
2982 {
2983 struct mac_biba *subj, *obj;
2984
2985 if (!mac_biba_enabled)
2986 return (0);
2987
2988 subj = SLOT(cred->cr_label);
2989 obj = SLOT(vnodelabel);
2990
2991 if (!mac_biba_dominate_effective(subj, obj))
2992 return (EACCES);
2993
2994 return (0);
2995 }
2996
2997 static int
2998 mac_biba_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
2999 struct vnode *vp, struct label *vnodelabel)
3000 {
3001 struct mac_biba *subj, *obj;
3002
3003 if (!mac_biba_enabled)
3004 return (0);
3005
3006 subj = SLOT(active_cred->cr_label);
3007 obj = SLOT(vnodelabel);
3008
3009 if (!mac_biba_dominate_effective(obj, subj))
3010 return (EACCES);
3011
3012 return (0);
3013 }
3014
3015 static int
3016 mac_biba_check_vnode_write(struct ucred *active_cred,
3017 struct ucred *file_cred, struct vnode *vp, struct label *label)
3018 {
3019 struct mac_biba *subj, *obj;
3020
3021 if (!mac_biba_enabled || !revocation_enabled)
3022 return (0);
3023
3024 subj = SLOT(active_cred->cr_label);
3025 obj = SLOT(label);
3026
3027 if (!mac_biba_dominate_effective(subj, obj))
3028 return (EACCES);
3029
3030 return (0);
3031 }
3032
3033 static void
3034 mac_biba_associate_nfsd_label(struct ucred *cred)
3035 {
3036 struct mac_biba *label;
3037
3038 label = SLOT(cred->cr_label);
3039 mac_biba_set_effective(label, MAC_BIBA_TYPE_LOW, 0, NULL);
3040 mac_biba_set_range(label, MAC_BIBA_TYPE_LOW, 0, NULL,
3041 MAC_BIBA_TYPE_HIGH, 0, NULL);
3042 }
3043
3044 static struct mac_policy_ops mac_biba_ops =
3045 {
3046 .mpo_init = mac_biba_init,
3047 .mpo_init_bpfdesc_label = mac_biba_init_label,
3048 .mpo_init_cred_label = mac_biba_init_label,
3049 .mpo_init_devfsdirent_label = mac_biba_init_label,
3050 .mpo_init_ifnet_label = mac_biba_init_label,
3051 .mpo_init_inpcb_label = mac_biba_init_label_waitcheck,
3052 .mpo_init_sysv_msgmsg_label = mac_biba_init_label,
3053 .mpo_init_sysv_msgqueue_label = mac_biba_init_label,
3054 .mpo_init_sysv_sem_label = mac_biba_init_label,
3055 .mpo_init_sysv_shm_label = mac_biba_init_label,
3056 .mpo_init_ipq_label = mac_biba_init_label_waitcheck,
3057 .mpo_init_mbuf_label = mac_biba_init_label_waitcheck,
3058 .mpo_init_mount_label = mac_biba_init_label,
3059 .mpo_init_mount_fs_label = mac_biba_init_label,
3060 .mpo_init_pipe_label = mac_biba_init_label,
3061 .mpo_init_posix_sem_label = mac_biba_init_label,
3062 .mpo_init_socket_label = mac_biba_init_label_waitcheck,
3063 .mpo_init_socket_peer_label = mac_biba_init_label_waitcheck,
3064 .mpo_init_vnode_label = mac_biba_init_label,
3065 .mpo_destroy_bpfdesc_label = mac_biba_destroy_label,
3066 .mpo_destroy_cred_label = mac_biba_destroy_label,
3067 .mpo_destroy_devfsdirent_label = mac_biba_destroy_label,
3068 .mpo_destroy_ifnet_label = mac_biba_destroy_label,
3069 .mpo_destroy_inpcb_label = mac_biba_destroy_label,
3070 .mpo_destroy_sysv_msgmsg_label = mac_biba_destroy_label,
3071 .mpo_destroy_sysv_msgqueue_label = mac_biba_destroy_label,
3072 .mpo_destroy_sysv_sem_label = mac_biba_destroy_label,
3073 .mpo_destroy_sysv_shm_label = mac_biba_destroy_label,
3074 .mpo_destroy_ipq_label = mac_biba_destroy_label,
3075 .mpo_destroy_mbuf_label = mac_biba_destroy_label,
3076 .mpo_destroy_mount_label = mac_biba_destroy_label,
3077 .mpo_destroy_mount_fs_label = mac_biba_destroy_label,
3078 .mpo_destroy_pipe_label = mac_biba_destroy_label,
3079 .mpo_destroy_posix_sem_label = mac_biba_destroy_label,
3080 .mpo_destroy_socket_label = mac_biba_destroy_label,
3081 .mpo_destroy_socket_peer_label = mac_biba_destroy_label,
3082 .mpo_destroy_vnode_label = mac_biba_destroy_label,
3083 .mpo_copy_cred_label = mac_biba_copy_label,
3084 .mpo_copy_ifnet_label = mac_biba_copy_label,
3085 .mpo_copy_mbuf_label = mac_biba_copy_label,
3086 .mpo_copy_pipe_label = mac_biba_copy_label,
3087 .mpo_copy_socket_label = mac_biba_copy_label,
3088 .mpo_copy_vnode_label = mac_biba_copy_label,
3089 .mpo_externalize_cred_label = mac_biba_externalize_label,
3090 .mpo_externalize_ifnet_label = mac_biba_externalize_label,
3091 .mpo_externalize_pipe_label = mac_biba_externalize_label,
3092 .mpo_externalize_socket_label = mac_biba_externalize_label,
3093 .mpo_externalize_socket_peer_label = mac_biba_externalize_label,
3094 .mpo_externalize_vnode_label = mac_biba_externalize_label,
3095 .mpo_internalize_cred_label = mac_biba_internalize_label,
3096 .mpo_internalize_ifnet_label = mac_biba_internalize_label,
3097 .mpo_internalize_pipe_label = mac_biba_internalize_label,
3098 .mpo_internalize_socket_label = mac_biba_internalize_label,
3099 .mpo_internalize_vnode_label = mac_biba_internalize_label,
3100 .mpo_create_devfs_device = mac_biba_create_devfs_device,
3101 .mpo_create_devfs_directory = mac_biba_create_devfs_directory,
3102 .mpo_create_devfs_symlink = mac_biba_create_devfs_symlink,
3103 .mpo_create_mount = mac_biba_create_mount,
3104 .mpo_relabel_vnode = mac_biba_relabel_vnode,
3105 .mpo_update_devfsdirent = mac_biba_update_devfsdirent,
3106 .mpo_associate_vnode_devfs = mac_biba_associate_vnode_devfs,
3107 .mpo_associate_vnode_extattr = mac_biba_associate_vnode_extattr,
3108 .mpo_associate_vnode_singlelabel = mac_biba_associate_vnode_singlelabel,
3109 .mpo_create_vnode_extattr = mac_biba_create_vnode_extattr,
3110 .mpo_setlabel_vnode_extattr = mac_biba_setlabel_vnode_extattr,
3111 .mpo_create_mbuf_from_socket = mac_biba_create_mbuf_from_socket,
3112 .mpo_create_pipe = mac_biba_create_pipe,
3113 .mpo_create_posix_sem = mac_biba_create_posix_sem,
3114 .mpo_create_socket = mac_biba_create_socket,
3115 .mpo_create_socket_from_socket = mac_biba_create_socket_from_socket,
3116 .mpo_relabel_pipe = mac_biba_relabel_pipe,
3117 .mpo_relabel_socket = mac_biba_relabel_socket,
3118 .mpo_set_socket_peer_from_mbuf = mac_biba_set_socket_peer_from_mbuf,
3119 .mpo_set_socket_peer_from_socket = mac_biba_set_socket_peer_from_socket,
3120 .mpo_create_bpfdesc = mac_biba_create_bpfdesc,
3121 .mpo_create_datagram_from_ipq = mac_biba_create_datagram_from_ipq,
3122 .mpo_create_fragment = mac_biba_create_fragment,
3123 .mpo_create_ifnet = mac_biba_create_ifnet,
3124 .mpo_create_inpcb_from_socket = mac_biba_create_inpcb_from_socket,
3125 .mpo_create_sysv_msgmsg = mac_biba_create_sysv_msgmsg,
3126 .mpo_create_sysv_msgqueue = mac_biba_create_sysv_msgqueue,
3127 .mpo_create_sysv_sem = mac_biba_create_sysv_sem,
3128 .mpo_create_sysv_shm = mac_biba_create_sysv_shm,
3129 .mpo_create_ipq = mac_biba_create_ipq,
3130 .mpo_create_mbuf_from_inpcb = mac_biba_create_mbuf_from_inpcb,
3131 .mpo_create_mbuf_linklayer = mac_biba_create_mbuf_linklayer,
3132 .mpo_create_mbuf_from_bpfdesc = mac_biba_create_mbuf_from_bpfdesc,
3133 .mpo_create_mbuf_from_ifnet = mac_biba_create_mbuf_from_ifnet,
3134 .mpo_create_mbuf_multicast_encap = mac_biba_create_mbuf_multicast_encap,
3135 .mpo_create_mbuf_netlayer = mac_biba_create_mbuf_netlayer,
3136 .mpo_fragment_match = mac_biba_fragment_match,
3137 .mpo_relabel_ifnet = mac_biba_relabel_ifnet,
3138 .mpo_update_ipq = mac_biba_update_ipq,
3139 .mpo_inpcb_sosetlabel = mac_biba_inpcb_sosetlabel,
3140 .mpo_create_proc0 = mac_biba_create_proc0,
3141 .mpo_create_proc1 = mac_biba_create_proc1,
3142 .mpo_relabel_cred = mac_biba_relabel_cred,
3143 .mpo_cleanup_sysv_msgmsg = mac_biba_cleanup_sysv_msgmsg,
3144 .mpo_cleanup_sysv_msgqueue = mac_biba_cleanup_sysv_msgqueue,
3145 .mpo_cleanup_sysv_sem = mac_biba_cleanup_sysv_sem,
3146 .mpo_cleanup_sysv_shm = mac_biba_cleanup_sysv_shm,
3147 .mpo_check_bpfdesc_receive = mac_biba_check_bpfdesc_receive,
3148 .mpo_check_cred_relabel = mac_biba_check_cred_relabel,
3149 .mpo_check_cred_visible = mac_biba_check_cred_visible,
3150 .mpo_check_ifnet_relabel = mac_biba_check_ifnet_relabel,
3151 .mpo_check_ifnet_transmit = mac_biba_check_ifnet_transmit,
3152 .mpo_check_inpcb_deliver = mac_biba_check_inpcb_deliver,
3153 .mpo_check_sysv_msgrcv = mac_biba_check_sysv_msgrcv,
3154 .mpo_check_sysv_msgrmid = mac_biba_check_sysv_msgrmid,
3155 .mpo_check_sysv_msqget = mac_biba_check_sysv_msqget,
3156 .mpo_check_sysv_msqsnd = mac_biba_check_sysv_msqsnd,
3157 .mpo_check_sysv_msqrcv = mac_biba_check_sysv_msqrcv,
3158 .mpo_check_sysv_msqctl = mac_biba_check_sysv_msqctl,
3159 .mpo_check_sysv_semctl = mac_biba_check_sysv_semctl,
3160 .mpo_check_sysv_semget = mac_biba_check_sysv_semget,
3161 .mpo_check_sysv_semop = mac_biba_check_sysv_semop,
3162 .mpo_check_sysv_shmat = mac_biba_check_sysv_shmat,
3163 .mpo_check_sysv_shmctl = mac_biba_check_sysv_shmctl,
3164 .mpo_check_sysv_shmget = mac_biba_check_sysv_shmget,
3165 .mpo_check_kld_load = mac_biba_check_kld_load,
3166 .mpo_check_kld_unload = mac_biba_check_kld_unload,
3167 .mpo_check_mount_stat = mac_biba_check_mount_stat,
3168 .mpo_check_pipe_ioctl = mac_biba_check_pipe_ioctl,
3169 .mpo_check_pipe_poll = mac_biba_check_pipe_poll,
3170 .mpo_check_pipe_read = mac_biba_check_pipe_read,
3171 .mpo_check_pipe_relabel = mac_biba_check_pipe_relabel,
3172 .mpo_check_pipe_stat = mac_biba_check_pipe_stat,
3173 .mpo_check_pipe_write = mac_biba_check_pipe_write,
3174 .mpo_check_posix_sem_destroy = mac_biba_check_posix_sem_write,
3175 .mpo_check_posix_sem_getvalue = mac_biba_check_posix_sem_rdonly,
3176 .mpo_check_posix_sem_open = mac_biba_check_posix_sem_write,
3177 .mpo_check_posix_sem_post = mac_biba_check_posix_sem_write,
3178 .mpo_check_posix_sem_unlink = mac_biba_check_posix_sem_write,
3179 .mpo_check_posix_sem_wait = mac_biba_check_posix_sem_write,
3180 .mpo_check_proc_debug = mac_biba_check_proc_debug,
3181 .mpo_check_proc_sched = mac_biba_check_proc_sched,
3182 .mpo_check_proc_signal = mac_biba_check_proc_signal,
3183 .mpo_check_socket_deliver = mac_biba_check_socket_deliver,
3184 .mpo_check_socket_relabel = mac_biba_check_socket_relabel,
3185 .mpo_check_socket_visible = mac_biba_check_socket_visible,
3186 .mpo_check_sysarch_ioperm = mac_biba_check_sysarch_ioperm,
3187 .mpo_check_system_acct = mac_biba_check_system_acct,
3188 .mpo_check_system_settime = mac_biba_check_system_settime,
3189 .mpo_check_system_swapon = mac_biba_check_system_swapon,
3190 .mpo_check_system_swapoff = mac_biba_check_system_swapoff,
3191 .mpo_check_system_sysctl = mac_biba_check_system_sysctl,
3192 .mpo_check_vnode_access = mac_biba_check_vnode_open,
3193 .mpo_check_vnode_chdir = mac_biba_check_vnode_chdir,
3194 .mpo_check_vnode_chroot = mac_biba_check_vnode_chroot,
3195 .mpo_check_vnode_create = mac_biba_check_vnode_create,
3196 .mpo_check_vnode_delete = mac_biba_check_vnode_delete,
3197 .mpo_check_vnode_deleteacl = mac_biba_check_vnode_deleteacl,
3198 .mpo_check_vnode_deleteextattr = mac_biba_check_vnode_deleteextattr,
3199 .mpo_check_vnode_exec = mac_biba_check_vnode_exec,
3200 .mpo_check_vnode_getacl = mac_biba_check_vnode_getacl,
3201 .mpo_check_vnode_getextattr = mac_biba_check_vnode_getextattr,
3202 .mpo_check_vnode_link = mac_biba_check_vnode_link,
3203 .mpo_check_vnode_listextattr = mac_biba_check_vnode_listextattr,
3204 .mpo_check_vnode_lookup = mac_biba_check_vnode_lookup,
3205 .mpo_check_vnode_mmap = mac_biba_check_vnode_mmap,
3206 .mpo_check_vnode_open = mac_biba_check_vnode_open,
3207 .mpo_check_vnode_poll = mac_biba_check_vnode_poll,
3208 .mpo_check_vnode_read = mac_biba_check_vnode_read,
3209 .mpo_check_vnode_readdir = mac_biba_check_vnode_readdir,
3210 .mpo_check_vnode_readlink = mac_biba_check_vnode_readlink,
3211 .mpo_check_vnode_relabel = mac_biba_check_vnode_relabel,
3212 .mpo_check_vnode_rename_from = mac_biba_check_vnode_rename_from,
3213 .mpo_check_vnode_rename_to = mac_biba_check_vnode_rename_to,
3214 .mpo_check_vnode_revoke = mac_biba_check_vnode_revoke,
3215 .mpo_check_vnode_setacl = mac_biba_check_vnode_setacl,
3216 .mpo_check_vnode_setextattr = mac_biba_check_vnode_setextattr,
3217 .mpo_check_vnode_setflags = mac_biba_check_vnode_setflags,
3218 .mpo_check_vnode_setmode = mac_biba_check_vnode_setmode,
3219 .mpo_check_vnode_setowner = mac_biba_check_vnode_setowner,
3220 .mpo_check_vnode_setutimes = mac_biba_check_vnode_setutimes,
3221 .mpo_check_vnode_stat = mac_biba_check_vnode_stat,
3222 .mpo_check_vnode_write = mac_biba_check_vnode_write,
3223 .mpo_associate_nfsd_label = mac_biba_associate_nfsd_label,
3224 .mpo_create_mbuf_from_firewall = mac_biba_create_mbuf_from_firewall,
3225 };
3226
3227 MAC_POLICY_SET(&mac_biba_ops, mac_biba, "TrustedBSD MAC/Biba",
3228 MPC_LOADTIME_FLAG_NOTLATE | MPC_LOADTIME_FLAG_LABELMBUFS, &mac_biba_slot);
Cache object: f668c95d9909310492dea716b1efd7a7
|