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