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