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