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