1/*-
2 * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson
3 * Copyright (c) 2001, 2002, 2003 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 122879 2003-11-18 04:11:52Z 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/sbuf.h>
53#include <sys/systm.h>
54#include <sys/sysproto.h>
55#include <sys/sysent.h>
56#include <sys/systm.h>
57#include <sys/vnode.h>
58#include <sys/file.h>
59#include <sys/socket.h>
60#include <sys/socketvar.h>
61#include <sys/pipe.h>
62#include <sys/sysctl.h>
63
64#include <fs/devfs/devfs.h>
65
66#include <net/bpfdesc.h>
67#include <net/if.h>
68#include <net/if_types.h>
69#include <net/if_var.h>
70
71#include <netinet/in.h>
72#include <netinet/in_pcb.h>
73#include <netinet/ip_var.h>
74
75#include <vm/uma.h>
76#include <vm/vm.h>
77
78#include <sys/mac_policy.h>
79
80#include <security/mac_biba/mac_biba.h>
81
82SYSCTL_DECL(_security_mac);
83
84SYSCTL_NODE(_security_mac, OID_AUTO, biba, CTLFLAG_RW, 0,
85 "TrustedBSD mac_biba policy controls");
86
87static int mac_biba_label_size = sizeof(struct mac_biba);
88SYSCTL_INT(_security_mac_biba, OID_AUTO, label_size, CTLFLAG_RD,
89 &mac_biba_label_size, 0, "Size of struct mac_biba");
90
91static int mac_biba_enabled = 1;
92SYSCTL_INT(_security_mac_biba, OID_AUTO, enabled, CTLFLAG_RW,
93 &mac_biba_enabled, 0, "Enforce MAC/Biba policy");
94TUNABLE_INT("security.mac.biba.enabled", &mac_biba_enabled);
95
96static int destroyed_not_inited;
97SYSCTL_INT(_security_mac_biba, OID_AUTO, destroyed_not_inited, CTLFLAG_RD,
98 &destroyed_not_inited, 0, "Count of labels destroyed but not inited");
99
100static int trust_all_interfaces = 0;
101SYSCTL_INT(_security_mac_biba, OID_AUTO, trust_all_interfaces, CTLFLAG_RD,
102 &trust_all_interfaces, 0, "Consider all interfaces 'trusted' by MAC/Biba");
103TUNABLE_INT("security.mac.biba.trust_all_interfaces", &trust_all_interfaces);
104
105static char trusted_interfaces[128];
106SYSCTL_STRING(_security_mac_biba, OID_AUTO, trusted_interfaces, CTLFLAG_RD,
107 trusted_interfaces, 0, "Interfaces considered 'trusted' by MAC/Biba");
108TUNABLE_STR("security.mac.biba.trusted_interfaces", trusted_interfaces,
109 sizeof(trusted_interfaces));
110
111static int max_compartments = MAC_BIBA_MAX_COMPARTMENTS;
112SYSCTL_INT(_security_mac_biba, OID_AUTO, max_compartments, CTLFLAG_RD,
113 &max_compartments, 0, "Maximum supported compartments");
114
115static int ptys_equal = 0;
116SYSCTL_INT(_security_mac_biba, OID_AUTO, ptys_equal, CTLFLAG_RW,
117 &ptys_equal, 0, "Label pty devices as biba/equal on create");
118TUNABLE_INT("security.mac.biba.ptys_equal", &ptys_equal);
119
120static int revocation_enabled = 0;
121SYSCTL_INT(_security_mac_biba, OID_AUTO, revocation_enabled, CTLFLAG_RW,
122 &revocation_enabled, 0, "Revoke access to objects on relabel");
123TUNABLE_INT("security.mac.biba.revocation_enabled", &revocation_enabled);
124
125static int mac_biba_slot;
126#define SLOT(l) ((struct mac_biba *)LABEL_TO_SLOT((l), mac_biba_slot).l_ptr)
127
128static uma_zone_t zone_biba;
129
130static __inline int
131biba_bit_set_empty(u_char *set) {
132 int i;
133
134 for (i = 0; i < MAC_BIBA_MAX_COMPARTMENTS >> 3; i++)
135 if (set[i] != 0)
136 return (0);
137 return (1);
138}
139
140static struct mac_biba *
141biba_alloc(int flag)
142{
143
144 return (uma_zalloc(zone_biba, flag | M_ZERO));
145}
146
147static void
148biba_free(struct mac_biba *mac_biba)
149{
150
151 if (mac_biba != NULL)
152 uma_zfree(zone_biba, mac_biba);
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_init(struct mac_policy_conf *conf)
491{
492
493 zone_biba = uma_zcreate("mac_biba", sizeof(struct mac_biba), NULL,
494 NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
495}
496
497/*
498 * Label operations.
499 */
500static void
501mac_biba_init_label(struct label *label)
502{
503
504 SLOT(label) = biba_alloc(M_WAITOK);
505}
506
507static int
508mac_biba_init_label_waitcheck(struct label *label, int flag)
509{
510
511 SLOT(label) = biba_alloc(flag);
512 if (SLOT(label) == NULL)
513 return (ENOMEM);
514
515 return (0);
516}
517
518static void
519mac_biba_destroy_label(struct label *label)
520{
521
522 biba_free(SLOT(label));
523 SLOT(label) = NULL;
524}
525
526/*
527 * mac_biba_element_to_string() accepts an sbuf and Biba element. It
528 * converts the Biba element to a string and stores the result in the
529 * sbuf; if there isn't space in the sbuf, -1 is returned.
530 */
531static int
532mac_biba_element_to_string(struct sbuf *sb, struct mac_biba_element *element)
533{
534 int i, first;
535
536 switch (element->mbe_type) {
537 case MAC_BIBA_TYPE_HIGH:
538 return (sbuf_printf(sb, "high"));
539
540 case MAC_BIBA_TYPE_LOW:
541 return (sbuf_printf(sb, "low"));
542
543 case MAC_BIBA_TYPE_EQUAL:
544 return (sbuf_printf(sb, "equal"));
545
546 case MAC_BIBA_TYPE_GRADE:
547 if (sbuf_printf(sb, "%d", element->mbe_grade) == -1)
548 return (-1);
549
550 first = 1;
551 for (i = 1; i <= MAC_BIBA_MAX_COMPARTMENTS; i++) {
552 if (MAC_BIBA_BIT_TEST(i, element->mbe_compartments)) {
553 if (first) {
554 if (sbuf_putc(sb, ':') == -1)
555 return (-1);
556 if (sbuf_printf(sb, "%d", i) == -1)
557 return (-1);
558 first = 0;
559 } else {
560 if (sbuf_printf(sb, "+%d", i) == -1)
561 return (-1);
562 }
563 }
564 }
565 return (0);
566
567 default:
568 panic("mac_biba_element_to_string: invalid type (%d)",
569 element->mbe_type);
570 }
571}
572
573/*
574 * mac_biba_to_string() converts a Biba label to a string, and places
575 * the results in the passed sbuf. It returns 0 on success, or EINVAL
576 * if there isn't room in the sbuf. Note: the sbuf will be modified
577 * even in a failure case, so the caller may need to revert the sbuf
578 * by restoring the offset if that's undesired.
579 */
580static int
581mac_biba_to_string(struct sbuf *sb, struct mac_biba *mac_biba)
582{
583
584 if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) {
585 if (mac_biba_element_to_string(sb, &mac_biba->mb_single)
586 == -1)
587 return (EINVAL);
588 }
589
590 if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
591 if (sbuf_putc(sb, '(') == -1)
592 return (EINVAL);
593
594 if (mac_biba_element_to_string(sb, &mac_biba->mb_rangelow)
595 == -1)
596 return (EINVAL);
597
598 if (sbuf_putc(sb, '-') == -1)
599 return (EINVAL);
600
601 if (mac_biba_element_to_string(sb, &mac_biba->mb_rangehigh)
602 == -1)
603 return (EINVAL);
604
605 if (sbuf_putc(sb, ')') == -1)
606 return (EINVAL);
607 }
608
609 return (0);
610}
611
612static int
613mac_biba_externalize_label(struct label *label, char *element_name,
614 struct sbuf *sb, int *claimed)
615{
616 struct mac_biba *mac_biba;
617
618 if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0)
619 return (0);
620
621 (*claimed)++;
622
623 mac_biba = SLOT(label);
624 return (mac_biba_to_string(sb, mac_biba));
625}
626
627static int
628mac_biba_parse_element(struct mac_biba_element *element, char *string)
629{
630 char *compartment, *end, *grade;
631 int value;
632
633 if (strcmp(string, "high") == 0 ||
634 strcmp(string, "hi") == 0) {
635 element->mbe_type = MAC_BIBA_TYPE_HIGH;
636 element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
637 } else if (strcmp(string, "low") == 0 ||
638 strcmp(string, "lo") == 0) {
639 element->mbe_type = MAC_BIBA_TYPE_LOW;
640 element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
641 } else if (strcmp(string, "equal") == 0 ||
642 strcmp(string, "eq") == 0) {
643 element->mbe_type = MAC_BIBA_TYPE_EQUAL;
644 element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
645 } else {
646 element->mbe_type = MAC_BIBA_TYPE_GRADE;
647
648 /*
649 * Numeric grade piece of the element.
650 */
651 grade = strsep(&string, ":");
652 value = strtol(grade, &end, 10);
653 if (end == grade || *end != '\0')
654 return (EINVAL);
655 if (value < 0 || value > 65535)
656 return (EINVAL);
657 element->mbe_grade = value;
658
659 /*
660 * Optional compartment piece of the element. If none
661 * are included, we assume that the label has no
662 * compartments.
663 */
664 if (string == NULL)
665 return (0);
666 if (*string == '\0')
667 return (0);
668
669 while ((compartment = strsep(&string, "+")) != NULL) {
670 value = strtol(compartment, &end, 10);
671 if (compartment == end || *end != '\0')
672 return (EINVAL);
673 if (value < 1 || value > MAC_BIBA_MAX_COMPARTMENTS)
674 return (EINVAL);
675 MAC_BIBA_BIT_SET(value, element->mbe_compartments);
676 }
677 }
678
679 return (0);
680}
681
682/*
683 * Note: destructively consumes the string, make a local copy before
684 * calling if that's a problem.
685 */
686static int
687mac_biba_parse(struct mac_biba *mac_biba, char *string)
688{
689 char *rangehigh, *rangelow, *single;
690 int error;
691
692 single = strsep(&string, "(");
693 if (*single == '\0')
694 single = NULL;
695
696 if (string != NULL) {
697 rangelow = strsep(&string, "-");
698 if (string == NULL)
699 return (EINVAL);
700 rangehigh = strsep(&string, ")");
701 if (string == NULL)
702 return (EINVAL);
703 if (*string != '\0')
704 return (EINVAL);
705 } else {
706 rangelow = NULL;
707 rangehigh = NULL;
708 }
709
710 KASSERT((rangelow != NULL && rangehigh != NULL) ||
711 (rangelow == NULL && rangehigh == NULL),
712 ("mac_biba_parse: range mismatch"));
713
714 bzero(mac_biba, sizeof(*mac_biba));
715 if (single != NULL) {
716 error = mac_biba_parse_element(&mac_biba->mb_single, single);
717 if (error)
718 return (error);
719 mac_biba->mb_flags |= MAC_BIBA_FLAG_SINGLE;
720 }
721
722 if (rangelow != NULL) {
723 error = mac_biba_parse_element(&mac_biba->mb_rangelow,
724 rangelow);
725 if (error)
726 return (error);
727 error = mac_biba_parse_element(&mac_biba->mb_rangehigh,
728 rangehigh);
729 if (error)
730 return (error);
731 mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE;
732 }
733
734 error = mac_biba_valid(mac_biba);
735 if (error)
736 return (error);
737
738 return (0);
739}
740
741static int
742mac_biba_internalize_label(struct label *label, char *element_name,
743 char *element_data, int *claimed)
744{
745 struct mac_biba *mac_biba, mac_biba_temp;
746 int error;
747
748 if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0)
749 return (0);
750
751 (*claimed)++;
752
753 error = mac_biba_parse(&mac_biba_temp, element_data);
754 if (error)
755 return (error);
756
757 mac_biba = SLOT(label);
758 *mac_biba = mac_biba_temp;
759
760 return (0);
761}
762
763static void
764mac_biba_copy_label(struct label *src, struct label *dest)
765{
766
767 *SLOT(dest) = *SLOT(src);
768}
769
770/*
771 * Labeling event operations: file system objects, and things that look
772 * a lot like file system objects.
773 */
774static void
775mac_biba_create_devfs_device(struct mount *mp, dev_t dev,
776 struct devfs_dirent *devfs_dirent, struct label *label)
777{
778 struct mac_biba *mac_biba;
779 int biba_type;
780
781 mac_biba = SLOT(label);
782 if (strcmp(dev->si_name, "null") == 0 ||
783 strcmp(dev->si_name, "zero") == 0 ||
784 strcmp(dev->si_name, "random") == 0 ||
785 strncmp(dev->si_name, "fd/", strlen("fd/")) == 0)
786 biba_type = MAC_BIBA_TYPE_EQUAL;
787 else if (ptys_equal &&
788 (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 ||
789 strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0))
790 biba_type = MAC_BIBA_TYPE_EQUAL;
791 else
792 biba_type = MAC_BIBA_TYPE_HIGH;
793 mac_biba_set_single(mac_biba, biba_type, 0, NULL);
794}
795
796static void
797mac_biba_create_devfs_directory(struct mount *mp, char *dirname,
798 int dirnamelen, struct devfs_dirent *devfs_dirent, struct label *label)
799{
800 struct mac_biba *mac_biba;
801
802 mac_biba = SLOT(label);
803 mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
804}
805
806static void
807mac_biba_create_devfs_symlink(struct ucred *cred, struct mount *mp,
808 struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de,
809 struct label *delabel)
810{
811 struct mac_biba *source, *dest;
812
813 source = SLOT(cred->cr_label);
814 dest = SLOT(delabel);
815
816 mac_biba_copy_single(source, dest);
817}
818
819static void
820mac_biba_create_mount(struct ucred *cred, struct mount *mp,
821 struct label *mntlabel, struct label *fslabel)
822{
823 struct mac_biba *source, *dest;
824
825 source = SLOT(cred->cr_label);
826 dest = SLOT(mntlabel);
827 mac_biba_copy_single(source, dest);
828 dest = SLOT(fslabel);
829 mac_biba_copy_single(source, dest);
830}
831
832static void
833mac_biba_create_root_mount(struct ucred *cred, struct mount *mp,
834 struct label *mntlabel, struct label *fslabel)
835{
836 struct mac_biba *mac_biba;
837
838 /* Always mount root as high integrity. */
839 mac_biba = SLOT(fslabel);
840 mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
841 mac_biba = SLOT(mntlabel);
842 mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
843}
844
845static void
846mac_biba_relabel_vnode(struct ucred *cred, struct vnode *vp,
847 struct label *vnodelabel, struct label *label)
848{
849 struct mac_biba *source, *dest;
850
851 source = SLOT(label);
852 dest = SLOT(vnodelabel);
853
854 mac_biba_copy(source, dest);
855}
856
857static void
858mac_biba_update_devfsdirent(struct mount *mp,
859 struct devfs_dirent *devfs_dirent, struct label *direntlabel,
860 struct vnode *vp, struct label *vnodelabel)
861{
862 struct mac_biba *source, *dest;
863
864 source = SLOT(vnodelabel);
865 dest = SLOT(direntlabel);
866
867 mac_biba_copy(source, dest);
868}
869
870static void
871mac_biba_associate_vnode_devfs(struct mount *mp, struct label *fslabel,
872 struct devfs_dirent *de, struct label *delabel, struct vnode *vp,
873 struct label *vlabel)
874{
875 struct mac_biba *source, *dest;
876
877 source = SLOT(delabel);
878 dest = SLOT(vlabel);
879
880 mac_biba_copy_single(source, dest);
881}
882
883static int
884mac_biba_associate_vnode_extattr(struct mount *mp, struct label *fslabel,
885 struct vnode *vp, struct label *vlabel)
886{
887 struct mac_biba temp, *source, *dest;
888 int buflen, error;
889
890 source = SLOT(fslabel);
891 dest = SLOT(vlabel);
892
893 buflen = sizeof(temp);
894 bzero(&temp, buflen);
895
896 error = vn_extattr_get(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
897 MAC_BIBA_EXTATTR_NAME, &buflen, (char *) &temp, curthread);
898 if (error == ENOATTR || error == EOPNOTSUPP) {
899 /* Fall back to the fslabel. */
900 mac_biba_copy_single(source, dest);
901 return (0);
902 } else if (error)
903 return (error);
904
905 if (buflen != sizeof(temp)) {
906 printf("mac_biba_associate_vnode_extattr: bad size %d\n",
907 buflen);
908 return (EPERM);
909 }
910 if (mac_biba_valid(&temp) != 0) {
911 printf("mac_biba_associate_vnode_extattr: invalid\n");
912 return (EPERM);
913 }
914 if ((temp.mb_flags & MAC_BIBA_FLAGS_BOTH) != MAC_BIBA_FLAG_SINGLE) {
915 printf("mac_biba_associate_vnode_extattr: not single\n");
916 return (EPERM);
917 }
918
919 mac_biba_copy_single(&temp, dest);
920 return (0);
921}
922
923static void
924mac_biba_associate_vnode_singlelabel(struct mount *mp,
925 struct label *fslabel, struct vnode *vp, struct label *vlabel)
926{
927 struct mac_biba *source, *dest;
928
929 source = SLOT(fslabel);
930 dest = SLOT(vlabel);
931
932 mac_biba_copy_single(source, dest);
933}
934
935static int
936mac_biba_create_vnode_extattr(struct ucred *cred, struct mount *mp,
937 struct label *fslabel, struct vnode *dvp, struct label *dlabel,
938 struct vnode *vp, struct label *vlabel, struct componentname *cnp)
939{
940 struct mac_biba *source, *dest, temp;
941 size_t buflen;
942 int error;
943
944 buflen = sizeof(temp);
945 bzero(&temp, buflen);
946
947 source = SLOT(cred->cr_label);
948 dest = SLOT(vlabel);
949 mac_biba_copy_single(source, &temp);
950
951 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
952 MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread);
953 if (error == 0)
954 mac_biba_copy_single(source, dest);
955 return (error);
956}
957
958static int
959mac_biba_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp,
960 struct label *vlabel, struct label *intlabel)
961{
962 struct mac_biba *source, temp;
963 size_t buflen;
964 int error;
965
966 buflen = sizeof(temp);
967 bzero(&temp, buflen);
968
969 source = SLOT(intlabel);
970 if ((source->mb_flags & MAC_BIBA_FLAG_SINGLE) == 0)
971 return (0);
972
973 mac_biba_copy_single(source, &temp);
974
975 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
976 MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread);
977 return (error);
978}
979
980/*
981 * Labeling event operations: IPC object.
982 */
983static void
984mac_biba_create_inpcb_from_socket(struct socket *so, struct label *solabel,
985 struct inpcb *inp, struct label *inplabel)
986{
987 struct mac_biba *source, *dest;
988
989 source = SLOT(solabel);
990 dest = SLOT(inplabel);
991
992 mac_biba_copy_single(source, dest);
993}
994
995static void
996mac_biba_create_mbuf_from_socket(struct socket *so, struct label *socketlabel,
997 struct mbuf *m, struct label *mbuflabel)
998{
999 struct mac_biba *source, *dest;
1000
1001 source = SLOT(socketlabel);
1002 dest = SLOT(mbuflabel);
1003
1004 mac_biba_copy_single(source, dest);
1005}
1006
1007static void
1008mac_biba_create_socket(struct ucred *cred, struct socket *socket,
1009 struct label *socketlabel)
1010{
1011 struct mac_biba *source, *dest;
1012
1013 source = SLOT(cred->cr_label);
1014 dest = SLOT(socketlabel);
1015
1016 mac_biba_copy_single(source, dest);
1017}
1018
1019static void
1020mac_biba_create_pipe(struct ucred *cred, struct pipe *pipe,
1021 struct label *pipelabel)
1022{
1023 struct mac_biba *source, *dest;
1024
1025 source = SLOT(cred->cr_label);
1026 dest = SLOT(pipelabel);
1027
1028 mac_biba_copy_single(source, dest);
1029}
1030
1031static void
1032mac_biba_create_socket_from_socket(struct socket *oldsocket,
1033 struct label *oldsocketlabel, struct socket *newsocket,
1034 struct label *newsocketlabel)
1035{
1036 struct mac_biba *source, *dest;
1037
1038 source = SLOT(oldsocketlabel);
1039 dest = SLOT(newsocketlabel);
1040
1041 mac_biba_copy_single(source, dest);
1042}
1043
1044static void
1045mac_biba_relabel_socket(struct ucred *cred, struct socket *socket,
1046 struct label *socketlabel, struct label *newlabel)
1047{
1048 struct mac_biba *source, *dest;
1049
1050 source = SLOT(newlabel);
1051 dest = SLOT(socketlabel);
1052
1053 mac_biba_copy(source, dest);
1054}
1055
1056static void
1057mac_biba_relabel_pipe(struct ucred *cred, struct pipe *pipe,
1058 struct label *pipelabel, struct label *newlabel)
1059{
1060 struct mac_biba *source, *dest;
1061
1062 source = SLOT(newlabel);
1063 dest = SLOT(pipelabel);
1064
1065 mac_biba_copy(source, dest);
1066}
1067
1068static void
1069mac_biba_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel,
1070 struct socket *socket, struct label *socketpeerlabel)
1071{
1072 struct mac_biba *source, *dest;
1073
1074 source = SLOT(mbuflabel);
1075 dest = SLOT(socketpeerlabel);
1076
1077 mac_biba_copy_single(source, dest);
1078}
1079
1080/*
1081 * Labeling event operations: network objects.
1082 */
1083static void
1084mac_biba_set_socket_peer_from_socket(struct socket *oldsocket,
1085 struct label *oldsocketlabel, struct socket *newsocket,
1086 struct label *newsocketpeerlabel)
1087{
1088 struct mac_biba *source, *dest;
1089
1090 source = SLOT(oldsocketlabel);
1091 dest = SLOT(newsocketpeerlabel);
1092
1093 mac_biba_copy_single(source, dest);
1094}
1095
1096static void
1097mac_biba_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d,
1098 struct label *bpflabel)
1099{
1100 struct mac_biba *source, *dest;
1101
1102 source = SLOT(cred->cr_label);
1103 dest = SLOT(bpflabel);
1104
1105 mac_biba_copy_single(source, dest);
1106}
1107
1108static void
1109mac_biba_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel)
1110{
1111 char tifname[IFNAMSIZ], *p, *q;
1112 char tiflist[sizeof(trusted_interfaces)];
1113 struct mac_biba *dest;
1114 int len, type;
1115
1116 dest = SLOT(ifnetlabel);
1117
1118 if (ifnet->if_type == IFT_LOOP) {
1119 type = MAC_BIBA_TYPE_EQUAL;
1120 goto set;
1121 }
1122
1123 if (trust_all_interfaces) {
1124 type = MAC_BIBA_TYPE_HIGH;
1125 goto set;
1126 }
1127
1128 type = MAC_BIBA_TYPE_LOW;
1129
1130 if (trusted_interfaces[0] == '\0' ||
1131 !strvalid(trusted_interfaces, sizeof(trusted_interfaces)))
1132 goto set;
1133
1134 bzero(tiflist, sizeof(tiflist));
1135 for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++)
1136 if(*p != ' ' && *p != '\t')
1137 *q = *p;
1138
1139 for (p = q = tiflist;; p++) {
1140 if (*p == ',' || *p == '\0') {
1141 len = p - q;
1142 if (len < IFNAMSIZ) {
1143 bzero(tifname, sizeof(tifname));
1144 bcopy(q, tifname, len);
1145 if (strcmp(tifname, ifnet->if_xname) == 0) {
1146 type = MAC_BIBA_TYPE_HIGH;
1147 break;
1148 }
1149 } else {
1150 *p = '\0';
1151 printf("mac_biba warning: interface name "
1152 "\"%s\" is too long (must be < %d)\n",
1153 q, IFNAMSIZ);
1154 }
1155 if (*p == '\0')
1156 break;
1157 q = p + 1;
1158 }
1159 }
1160set:
1161 mac_biba_set_single(dest, type, 0, NULL);
1162 mac_biba_set_range(dest, type, 0, NULL, type, 0, NULL);
1163}
1164
1165static void
1166mac_biba_create_ipq(struct mbuf *fragment, struct label *fragmentlabel,
1167 struct ipq *ipq, struct label *ipqlabel)
1168{
1169 struct mac_biba *source, *dest;
1170
1171 source = SLOT(fragmentlabel);
1172 dest = SLOT(ipqlabel);
1173
1174 mac_biba_copy_single(source, dest);
1175}
1176
1177static void
1178mac_biba_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel,
1179 struct mbuf *datagram, struct label *datagramlabel)
1180{
1181 struct mac_biba *source, *dest;
1182
1183 source = SLOT(ipqlabel);
1184 dest = SLOT(datagramlabel);
1185
1186 /* Just use the head, since we require them all to match. */
1187 mac_biba_copy_single(source, dest);
1188}
1189
1190static void
1191mac_biba_create_fragment(struct mbuf *datagram, struct label *datagramlabel,
1192 struct mbuf *fragment, struct label *fragmentlabel)
1193{
1194 struct mac_biba *source, *dest;
1195
1196 source = SLOT(datagramlabel);
1197 dest = SLOT(fragmentlabel);
1198
1199 mac_biba_copy_single(source, dest);
1200}
1201
1202static void
1203mac_biba_create_mbuf_from_mbuf(struct mbuf *oldmbuf,
1204 struct label *oldmbuflabel, struct mbuf *newmbuf,
1205 struct label *newmbuflabel)
1206{
1207 struct mac_biba *source, *dest;
1208
1209 source = SLOT(oldmbuflabel);
1210 dest = SLOT(newmbuflabel);
1211
1212 /*
1213 * Because the source mbuf may not yet have been "created",
1214 * just initialized, we do a conditional copy. Since we don't
1215 * allow mbufs to have ranges, do a KASSERT to make sure that
1216 * doesn't happen.
1217 */
1218 KASSERT((source->mb_flags & MAC_BIBA_FLAG_RANGE) == 0,
1219 ("mac_biba_create_mbuf_from_mbuf: source mbuf has range"));
1220 mac_biba_copy(source, dest);
1221}
1222
1223static void
1224mac_biba_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel,
1225 struct mbuf *mbuf, struct label *mbuflabel)
1226{
1227 struct mac_biba *dest;
1228
1229 dest = SLOT(mbuflabel);
1230
1231 mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1232}
1233
1234static void
1235mac_biba_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel,
1236 struct mbuf *mbuf, struct label *mbuflabel)
1237{
1238 struct mac_biba *source, *dest;
1239
1240 source = SLOT(bpflabel);
1241 dest = SLOT(mbuflabel);
1242
1243 mac_biba_copy_single(source, dest);
1244}
1245
1246static void
1247mac_biba_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel,
1248 struct mbuf *m, struct label *mbuflabel)
1249{
1250 struct mac_biba *source, *dest;
1251
1252 source = SLOT(ifnetlabel);
1253 dest = SLOT(mbuflabel);
1254
1255 mac_biba_copy_single(source, dest);
1256}
1257
1258static void
1259mac_biba_create_mbuf_multicast_encap(struct mbuf *oldmbuf,
1260 struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel,
1261 struct mbuf *newmbuf, struct label *newmbuflabel)
1262{
1263 struct mac_biba *source, *dest;
1264
1265 source = SLOT(oldmbuflabel);
1266 dest = SLOT(newmbuflabel);
1267
1268 mac_biba_copy_single(source, dest);
1269}
1270
1271static void
1272mac_biba_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel,
1273 struct mbuf *newmbuf, struct label *newmbuflabel)
1274{
1275 struct mac_biba *source, *dest;
1276
1277 source = SLOT(oldmbuflabel);
1278 dest = SLOT(newmbuflabel);
1279
1280 mac_biba_copy_single(source, dest);
1281}
1282
1283static int
1284mac_biba_fragment_match(struct mbuf *fragment, struct label *fragmentlabel,
1285 struct ipq *ipq, struct label *ipqlabel)
1286{
1287 struct mac_biba *a, *b;
1288
1289 a = SLOT(ipqlabel);
1290 b = SLOT(fragmentlabel);
1291
1292 return (mac_biba_equal_single(a, b));
1293}
1294
1295static void
1296mac_biba_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet,
1297 struct label *ifnetlabel, struct label *newlabel)
1298{
1299 struct mac_biba *source, *dest;
1300
1301 source = SLOT(newlabel);
1302 dest = SLOT(ifnetlabel);
1303
1304 mac_biba_copy(source, dest);
1305}
1306
1307static void
1308mac_biba_update_ipq(struct mbuf *fragment, struct label *fragmentlabel,
1309 struct ipq *ipq, struct label *ipqlabel)
1310{
1311
1312 /* NOOP: we only accept matching labels, so no need to update */
1313}
1314
1315static void
1316mac_biba_inpcb_sosetlabel(struct socket *so, struct label *solabel,
1317 struct inpcb *inp, struct label *inplabel)
1318{
1319 struct mac_biba *source, *dest;
1320
1321 source = SLOT(solabel);
1322 dest = SLOT(inplabel);
1323
1324 mac_biba_copy(source, dest);
1325}
1326
1327/*
1328 * Labeling event operations: processes.
1329 */
1330static void
1331mac_biba_create_cred(struct ucred *cred_parent, struct ucred *cred_child)
1332{
1333 struct mac_biba *source, *dest;
1334
1335 source = SLOT(cred_parent->cr_label);
1336 dest = SLOT(cred_child->cr_label);
1337
1338 mac_biba_copy_single(source, dest);
1339 mac_biba_copy_range(source, dest);
1340}
1341
1342static void
1343mac_biba_create_proc0(struct ucred *cred)
1344{
1345 struct mac_biba *dest;
1346
1347 dest = SLOT(cred->cr_label);
1348
1349 mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1350 mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL,
1351 MAC_BIBA_TYPE_HIGH, 0, NULL);
1352}
1353
1354static void
1355mac_biba_create_proc1(struct ucred *cred)
1356{
1357 struct mac_biba *dest;
1358
1359 dest = SLOT(cred->cr_label);
1360
1361 mac_biba_set_single(dest, MAC_BIBA_TYPE_HIGH, 0, NULL);
1362 mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL,
1363 MAC_BIBA_TYPE_HIGH, 0, NULL);
1364}
1365
1366static void
1367mac_biba_relabel_cred(struct ucred *cred, struct label *newlabel)
1368{
1369 struct mac_biba *source, *dest;
1370
1371 source = SLOT(newlabel);
1372 dest = SLOT(cred->cr_label);
1373
1374 mac_biba_copy(source, dest);
1375}
1376
1377/*
1378 * Access control checks.
1379 */
1380static int
1381mac_biba_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel,
1382 struct ifnet *ifnet, struct label *ifnetlabel)
1383{
1384 struct mac_biba *a, *b;
1385
1386 if (!mac_biba_enabled)
1387 return (0);
1388
1389 a = SLOT(bpflabel);
1390 b = SLOT(ifnetlabel);
1391
1392 if (mac_biba_equal_single(a, b))
1393 return (0);
1394 return (EACCES);
1395}
1396
1397static int
1398mac_biba_check_cred_relabel(struct ucred *cred, struct label *newlabel)
1399{
1400 struct mac_biba *subj, *new;
1401 int error;
1402
1403 subj = SLOT(cred->cr_label);
1404 new = SLOT(newlabel);
1405
1406 /*
1407 * If there is a Biba label update for the credential, it may
1408 * be an update of the single, range, or both.
1409 */
1410 error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
1411 if (error)
1412 return (error);
1413
1414 /*
1415 * If the Biba label is to be changed, authorize as appropriate.
1416 */
1417 if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) {
1418 /*
1419 * If the change request modifies both the Biba label
1420 * single and range, check that the new single will be
1421 * in the new range.
1422 */
1423 if ((new->mb_flags & MAC_BIBA_FLAGS_BOTH) ==
1424 MAC_BIBA_FLAGS_BOTH &&
1425 !mac_biba_single_in_range(new, new))
1426 return (EINVAL);
1427
1428 /*
1429 * To change the Biba single label on a credential, the
1430 * new single label must be in the current range.
1431 */
1432 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE &&
1433 !mac_biba_single_in_range(new, subj))
1434 return (EPERM);
1435
1436 /*
1437 * To change the Biba range on a credential, the new
1438 * range label must be in the current range.
1439 */
1440 if (new->mb_flags & MAC_BIBA_FLAG_RANGE &&
1441 !mac_biba_range_in_range(new, subj))
1442 return (EPERM);
1443
1444 /*
1445 * To have EQUAL in any component of the new credential
1446 * Biba label, the subject must already have EQUAL in
1447 * their label.
1448 */
1449 if (mac_biba_contains_equal(new)) {
1450 error = mac_biba_subject_privileged(subj);
1451 if (error)
1452 return (error);
1453 }
1454 }
1455
1456 return (0);
1457}
1458
1459static int
1460mac_biba_check_cred_visible(struct ucred *u1, struct ucred *u2)
1461{
1462 struct mac_biba *subj, *obj;
1463
1464 if (!mac_biba_enabled)
1465 return (0);
1466
1467 subj = SLOT(u1->cr_label);
1468 obj = SLOT(u2->cr_label);
1469
1470 /* XXX: range */
1471 if (!mac_biba_dominate_single(obj, subj))
1472 return (ESRCH);
1473
1474 return (0);
1475}
1476
1477static int
1478mac_biba_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet,
1479 struct label *ifnetlabel, struct label *newlabel)
1480{
1481 struct mac_biba *subj, *new;
1482 int error;
1483
1484 subj = SLOT(cred->cr_label);
1485 new = SLOT(newlabel);
1486
1487 /*
1488 * If there is a Biba label update for the interface, it may
1489 * be an update of the single, range, or both.
1490 */
1491 error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
1492 if (error)
1493 return (error);
1494
1495 /*
1496 * Relabling network interfaces requires Biba privilege.
1497 */
1498 error = mac_biba_subject_privileged(subj);
1499 if (error)
1500 return (error);
1501
1502 return (0);
1503}
1504
1505static int
1506mac_biba_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel,
1507 struct mbuf *m, struct label *mbuflabel)
1508{
1509 struct mac_biba *p, *i;
1510
1511 if (!mac_biba_enabled)
1512 return (0);
1513
1514 p = SLOT(mbuflabel);
1515 i = SLOT(ifnetlabel);
1516
1517 return (mac_biba_single_in_range(p, i) ? 0 : EACCES);
1518}
1519
1520static int
1521mac_biba_check_inpcb_deliver(struct inpcb *inp, struct label *inplabel,
1522 struct mbuf *m, struct label *mlabel)
1523{
1524 struct mac_biba *p, *i;
1525
1526 if (!mac_biba_enabled)
1527 return (0);
1528
1529 p = SLOT(mlabel);
1530 i = SLOT(inplabel);
1531
1532 return (mac_biba_equal_single(p, i) ? 0 : EACCES);
1533}
1534
1535static int
1536mac_biba_check_kld_load(struct ucred *cred, struct vnode *vp,
1537 struct label *label)
1538{
1539 struct mac_biba *subj, *obj;
1540 int error;
1541
1542 if (!mac_biba_enabled)
1543 return (0);
1544
1545 subj = SLOT(cred->cr_label);
1546
1547 error = mac_biba_subject_privileged(subj);
1548 if (error)
1549 return (error);
1550
1551 obj = SLOT(label);
1552 if (!mac_biba_high_single(obj))
1553 return (EACCES);
1554
1555 return (0);
1556}
1557
1558
1559static int
1560mac_biba_check_kld_unload(struct ucred *cred)
1561{
1562 struct mac_biba *subj;
1563
1564 if (!mac_biba_enabled)
1565 return (0);
1566
1567 subj = SLOT(cred->cr_label);
1568
1569 return (mac_biba_subject_privileged(subj));
1570}
1571
1572static int
1573mac_biba_check_mount_stat(struct ucred *cred, struct mount *mp,
1574 struct label *mntlabel)
1575{
1576 struct mac_biba *subj, *obj;
1577
1578 if (!mac_biba_enabled)
1579 return (0);
1580
1581 subj = SLOT(cred->cr_label);
1582 obj = SLOT(mntlabel);
1583
1584 if (!mac_biba_dominate_single(obj, subj))
1585 return (EACCES);
1586
1587 return (0);
1588}
1589
1590static int
1591mac_biba_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe,
1592 struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data)
1593{
1594
1595 if(!mac_biba_enabled)
1596 return (0);
1597
1598 /* XXX: This will be implemented soon... */
1599
1600 return (0);
1601}
1602
1603static int
1604mac_biba_check_pipe_poll(struct ucred *cred, struct pipe *pipe,
1605 struct label *pipelabel)
1606{
1607 struct mac_biba *subj, *obj;
1608
1609 if (!mac_biba_enabled)
1610 return (0);
1611
1612 subj = SLOT(cred->cr_label);
1613 obj = SLOT((pipelabel));
1614
1615 if (!mac_biba_dominate_single(obj, subj))
1616 return (EACCES);
1617
1618 return (0);
1619}
1620
1621static int
1622mac_biba_check_pipe_read(struct ucred *cred, struct pipe *pipe,
1623 struct label *pipelabel)
1624{
1625 struct mac_biba *subj, *obj;
1626
1627 if (!mac_biba_enabled)
1628 return (0);
1629
1630 subj = SLOT(cred->cr_label);
1631 obj = SLOT((pipelabel));
1632
1633 if (!mac_biba_dominate_single(obj, subj))
1634 return (EACCES);
1635
1636 return (0);
1637}
1638
1639static int
1640mac_biba_check_pipe_relabel(struct ucred *cred, struct pipe *pipe,
1641 struct label *pipelabel, struct label *newlabel)
1642{
1643 struct mac_biba *subj, *obj, *new;
1644 int error;
1645
1646 new = SLOT(newlabel);
1647 subj = SLOT(cred->cr_label);
1648 obj = SLOT(pipelabel);
1649
1650 /*
1651 * If there is a Biba label update for a pipe, it must be a
1652 * single update.
1653 */
1654 error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE);
1655 if (error)
1656 return (error);
1657
1658 /*
1659 * To perform a relabel of a pipe (Biba label or not), Biba must
1660 * authorize the relabel.
1661 */
1662 if (!mac_biba_single_in_range(obj, subj))
1663 return (EPERM);
1664
1665 /*
1666 * If the Biba label is to be changed, authorize as appropriate.
1667 */
1668 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) {
1669 /*
1670 * To change the Biba label on a pipe, the new pipe label
1671 * must be in the subject range.
1672 */
1673 if (!mac_biba_single_in_range(new, subj))
1674 return (EPERM);
1675
1676 /*
1677 * To change the Biba label on a pipe to be EQUAL, the
1678 * subject must have appropriate privilege.
1679 */
1680 if (mac_biba_contains_equal(new)) {
1681 error = mac_biba_subject_privileged(subj);
1682 if (error)
1683 return (error);
1684 }
1685 }
1686
1687 return (0);
1688}
1689
1690static int
1691mac_biba_check_pipe_stat(struct ucred *cred, struct pipe *pipe,
1692 struct label *pipelabel)
1693{
1694 struct mac_biba *subj, *obj;
1695
1696 if (!mac_biba_enabled)
1697 return (0);
1698
1699 subj = SLOT(cred->cr_label);
1700 obj = SLOT((pipelabel));
1701
1702 if (!mac_biba_dominate_single(obj, subj))
1703 return (EACCES);
1704
1705 return (0);
1706}
1707
1708static int
1709mac_biba_check_pipe_write(struct ucred *cred, struct pipe *pipe,
1710 struct label *pipelabel)
1711{
1712 struct mac_biba *subj, *obj;
1713
1714 if (!mac_biba_enabled)
1715 return (0);
1716
1717 subj = SLOT(cred->cr_label);
1718 obj = SLOT((pipelabel));
1719
1720 if (!mac_biba_dominate_single(subj, obj))
1721 return (EACCES);
1722
1723 return (0);
1724}
1725
1726static int
1727mac_biba_check_proc_debug(struct ucred *cred, struct proc *proc)
1728{
1729 struct mac_biba *subj, *obj;
1730
1731 if (!mac_biba_enabled)
1732 return (0);
1733
1734 subj = SLOT(cred->cr_label);
1735 obj = SLOT(proc->p_ucred->cr_label);
1736
1737 /* XXX: range checks */
1738 if (!mac_biba_dominate_single(obj, subj))
1739 return (ESRCH);
1740 if (!mac_biba_dominate_single(subj, obj))
1741 return (EACCES);
1742
1743 return (0);
1744}
1745
1746static int
1747mac_biba_check_proc_sched(struct ucred *cred, struct proc *proc)
1748{
1749 struct mac_biba *subj, *obj;
1750
1751 if (!mac_biba_enabled)
1752 return (0);
1753
1754 subj = SLOT(cred->cr_label);
1755 obj = SLOT(proc->p_ucred->cr_label);
1756
1757 /* XXX: range checks */
1758 if (!mac_biba_dominate_single(obj, subj))
1759 return (ESRCH);
1760 if (!mac_biba_dominate_single(subj, obj))
1761 return (EACCES);
1762
1763 return (0);
1764}
1765
1766static int
1767mac_biba_check_proc_signal(struct ucred *cred, struct proc *proc, int signum)
1768{
1769 struct mac_biba *subj, *obj;
1770
1771 if (!mac_biba_enabled)
1772 return (0);
1773
1774 subj = SLOT(cred->cr_label);
1775 obj = SLOT(proc->p_ucred->cr_label);
1776
1777 /* XXX: range checks */
1778 if (!mac_biba_dominate_single(obj, subj))
1779 return (ESRCH);
1780 if (!mac_biba_dominate_single(subj, obj))
1781 return (EACCES);
1782
1783 return (0);
1784}
1785
1786static int
1787mac_biba_check_socket_deliver(struct socket *so, struct label *socketlabel,
1788 struct mbuf *m, struct label *mbuflabel)
1789{
1790 struct mac_biba *p, *s;
1791
1792 if (!mac_biba_enabled)
1793 return (0);
1794
1795 p = SLOT(mbuflabel);
1796 s = SLOT(socketlabel);
1797
1798 return (mac_biba_equal_single(p, s) ? 0 : EACCES);
1799}
1800
1801static int
1802mac_biba_check_socket_relabel(struct ucred *cred, struct socket *so,
1803 struct label *socketlabel, struct label *newlabel)
1804{
1805 struct mac_biba *subj, *obj, *new;
1806 int error;
1807
1808 new = SLOT(newlabel);
1809 subj = SLOT(cred->cr_label);
1810 obj = SLOT(socketlabel);
1811
1812 /*
1813 * If there is a Biba label update for the socket, it may be
1814 * an update of single.
1815 */
1816 error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE);
1817 if (error)
1818 return (error);
1819
1820 /*
1821 * To relabel a socket, the old socket single must be in the subject
1822 * range.
1823 */
1824 if (!mac_biba_single_in_range(obj, subj))
1825 return (EPERM);
1826
1827 /*
1828 * If the Biba label is to be changed, authorize as appropriate.
1829 */
1830 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) {
1831 /*
1832 * To relabel a socket, the new socket single must be in
1833 * the subject range.
1834 */
1835 if (!mac_biba_single_in_range(new, subj))
1836 return (EPERM);
1837
1838 /*
1839 * To change the Biba label on the socket to contain EQUAL,
1840 * the subject must have appropriate privilege.
1841 */
1842 if (mac_biba_contains_equal(new)) {
1843 error = mac_biba_subject_privileged(subj);
1844 if (error)
1845 return (error);
1846 }
1847 }
1848
1849 return (0);
1850}
1851
1852static int
1853mac_biba_check_socket_visible(struct ucred *cred, struct socket *socket,
1854 struct label *socketlabel)
1855{
1856 struct mac_biba *subj, *obj;
1857
1858 if (!mac_biba_enabled)
1859 return (0);
1860
1861 subj = SLOT(cred->cr_label);
1862 obj = SLOT(socketlabel);
1863
1864 if (!mac_biba_dominate_single(obj, subj))
1865 return (ENOENT);
1866
1867 return (0);
1868}
1869
1870static int
1871mac_biba_check_sysarch_ioperm(struct ucred *cred)
1872{
1873 struct mac_biba *subj;
1874 int error;
1875
1876 if (!mac_biba_enabled)
1877 return (0);
1878
1879 subj = SLOT(cred->cr_label);
1880
1881 error = mac_biba_subject_privileged(subj);
1882 if (error)
1883 return (error);
1884
1885 return (0);
1886}
1887
1888static int
1889mac_biba_check_system_acct(struct ucred *cred, struct vnode *vp,
1890 struct label *label)
1891{
1892 struct mac_biba *subj, *obj;
1893 int error;
1894
1895 if (!mac_biba_enabled)
1896 return (0);
1897
1898 subj = SLOT(cred->cr_label);
1899
1900 error = mac_biba_subject_privileged(subj);
1901 if (error)
1902 return (error);
1903
1904 if (label == NULL)
1905 return (0);
1906
1907 obj = SLOT(label);
1908 if (!mac_biba_high_single(obj))
1909 return (EACCES);
1910
1911 return (0);
1912}
1913
1914static int
1915mac_biba_check_system_settime(struct ucred *cred)
1916{
1917 struct mac_biba *subj;
1918 int error;
1919
1920 if (!mac_biba_enabled)
1921 return (0);
1922
1923 subj = SLOT(cred->cr_label);
1924
1925 error = mac_biba_subject_privileged(subj);
1926 if (error)
1927 return (error);
1928
1929 return (0);
1930}
1931
1932static int
1933mac_biba_check_system_swapon(struct ucred *cred, struct vnode *vp,
1934 struct label *label)
1935{
1936 struct mac_biba *subj, *obj;
1937 int error;
1938
1939 if (!mac_biba_enabled)
1940 return (0);
1941
1942 subj = SLOT(cred->cr_label);
1943 obj = SLOT(label);
1944
1945 error = mac_biba_subject_privileged(subj);
1946 if (error)
1947 return (error);
1948
1949 if (!mac_biba_high_single(obj))
1950 return (EACCES);
1951
1952 return (0);
1953}
1954
1955static int
1956mac_biba_check_system_swapoff(struct ucred *cred, struct vnode *vp,
1957 struct label *label)
1958{
1959 struct mac_biba *subj, *obj;
1960 int error;
1961
1962 if (!mac_biba_enabled)
1963 return (0);
1964
1965 subj = SLOT(cred->cr_label);
1966 obj = SLOT(label);
1967
1968 error = mac_biba_subject_privileged(subj);
1969 if (error)
1970 return (error);
1971
1972 return (0);
1973}
1974
1975static int
1976mac_biba_check_system_sysctl(struct ucred *cred, int *name, u_int namelen,
1977 void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen)
1978{
1979 struct mac_biba *subj;
1980 int error;
1981
1982 if (!mac_biba_enabled)
1983 return (0);
1984
1985 subj = SLOT(cred->cr_label);
1986
1987 /*
1988 * In general, treat sysctl variables as biba/high, but also
1989 * require privilege to change them, since they are a
1990 * communications channel between grades. Exempt MIB
1991 * queries from this due to undocmented sysctl magic.
1992 * XXXMAC: This probably requires some more review.
1993 */
1994 if (new != NULL) {
1995 if (namelen > 0 && name[0] == 0)
1996 return (0);
1997
1998 if (!mac_biba_subject_dominate_high(subj))
1999 return (EACCES);
2000
2001 error = mac_biba_subject_privileged(subj);
2002 if (error)
2003 return (error);
2004 }
2005
2006 return (0);
2007}
2008
2009static int
2010mac_biba_check_vnode_chdir(struct ucred *cred, struct vnode *dvp,
2011 struct label *dlabel)
2012{
2013 struct mac_biba *subj, *obj;
2014
2015 if (!mac_biba_enabled)
2016 return (0);
2017
2018 subj = SLOT(cred->cr_label);
2019 obj = SLOT(dlabel);
2020
2021 if (!mac_biba_dominate_single(obj, subj))
2022 return (EACCES);
2023
2024 return (0);
2025}
2026
2027static int
2028mac_biba_check_vnode_chroot(struct ucred *cred, struct vnode *dvp,
2029 struct label *dlabel)
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(dlabel);
2038
2039 if (!mac_biba_dominate_single(obj, subj))
2040 return (EACCES);
2041
2042 return (0);
2043}
2044
2045static int
2046mac_biba_check_vnode_create(struct ucred *cred, struct vnode *dvp,
2047 struct label *dlabel, struct componentname *cnp, struct vattr *vap)
2048{
2049 struct mac_biba *subj, *obj;
2050
2051 if (!mac_biba_enabled)
2052 return (0);
2053
2054 subj = SLOT(cred->cr_label);
2055 obj = SLOT(dlabel);
2056
2057 if (!mac_biba_dominate_single(subj, obj))
2058 return (EACCES);
2059
2060 return (0);
2061}
2062
2063static int
2064mac_biba_check_vnode_delete(struct ucred *cred, struct vnode *dvp,
2065 struct label *dlabel, struct vnode *vp, struct label *label,
2066 struct componentname *cnp)
2067{
2068 struct mac_biba *subj, *obj;
2069
2070 if (!mac_biba_enabled)
2071 return (0);
2072
2073 subj = SLOT(cred->cr_label);
2074 obj = SLOT(dlabel);
2075
2076 if (!mac_biba_dominate_single(subj, obj))
2077 return (EACCES);
2078
2079 obj = SLOT(label);
2080
2081 if (!mac_biba_dominate_single(subj, obj))
2082 return (EACCES);
2083
2084 return (0);
2085}
2086
2087static int
2088mac_biba_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
2089 struct label *label, acl_type_t type)
2090{
2091 struct mac_biba *subj, *obj;
2092
2093 if (!mac_biba_enabled)
2094 return (0);
2095
2096 subj = SLOT(cred->cr_label);
2097 obj = SLOT(label);
2098
2099 if (!mac_biba_dominate_single(subj, obj))
2100 return (EACCES);
2101
2102 return (0);
2103}
2104
2105static int
2106mac_biba_check_vnode_deleteextattr(struct ucred *cred, struct vnode *vp,
2107 struct label *label, int attrnamespace, const char *name)
2108{
2109 struct mac_biba *subj, *obj;
2110
2111 if (!mac_biba_enabled)
2112 return (0);
2113
2114 subj = SLOT(cred->cr_label);
2115 obj = SLOT(label);
2116
2117 if (!mac_biba_dominate_single(subj, obj))
2118 return (EACCES);
2119
2120 return (0);
2121}
2122
2123static int
2124mac_biba_check_vnode_exec(struct ucred *cred, struct vnode *vp,
2125 struct label *label, struct image_params *imgp,
2126 struct label *execlabel)
2127{
2128 struct mac_biba *subj, *obj, *exec;
2129 int error;
2130
2131 if (execlabel != NULL) {
2132 /*
2133 * We currently don't permit labels to be changed at
2134 * exec-time as part of Biba, so disallow non-NULL
2135 * Biba label elements in the execlabel.
2136 */
2137 exec = SLOT(execlabel);
2138 error = biba_atmostflags(exec, 0);
2139 if (error)
2140 return (error);
2141 }
2142
2143 if (!mac_biba_enabled)
2144 return (0);
2145
2146 subj = SLOT(cred->cr_label);
2147 obj = SLOT(label);
2148
2149 if (!mac_biba_dominate_single(obj, subj))
2150 return (EACCES);
2151
2152 return (0);
2153}
2154
2155static int
2156mac_biba_check_vnode_getacl(struct ucred *cred, struct vnode *vp,
2157 struct label *label, acl_type_t type)
2158{
2159 struct mac_biba *subj, *obj;
2160
2161 if (!mac_biba_enabled)
2162 return (0);
2163
2164 subj = SLOT(cred->cr_label);
2165 obj = SLOT(label);
2166
2167 if (!mac_biba_dominate_single(obj, subj))
2168 return (EACCES);
2169
2170 return (0);
2171}
2172
2173static int
2174mac_biba_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
2175 struct label *label, int attrnamespace, const char *name, struct uio *uio)
2176{
2177 struct mac_biba *subj, *obj;
2178
2179 if (!mac_biba_enabled)
2180 return (0);
2181
2182 subj = SLOT(cred->cr_label);
2183 obj = SLOT(label);
2184
2185 if (!mac_biba_dominate_single(obj, subj))
2186 return (EACCES);
2187
2188 return (0);
2189}
2190
2191static int
2192mac_biba_check_vnode_link(struct ucred *cred, struct vnode *dvp,
2193 struct label *dlabel, struct vnode *vp, struct label *label,
2194 struct componentname *cnp)
2195{
2196 struct mac_biba *subj, *obj;
2197
2198 if (!mac_biba_enabled)
2199 return (0);
2200
2201 subj = SLOT(cred->cr_label);
2202 obj = SLOT(dlabel);
2203
2204 if (!mac_biba_dominate_single(subj, obj))
2205 return (EACCES);
2206
2207 obj = SLOT(label);
2208
2209 if (!mac_biba_dominate_single(subj, obj))
2210 return (EACCES);
2211
2212 return (0);
2213}
2214
2215static int
2216mac_biba_check_vnode_listextattr(struct ucred *cred, struct vnode *vp,
2217 struct label *label, int attrnamespace)
2218{
2219 struct mac_biba *subj, *obj;
2220
2221 if (!mac_biba_enabled)
2222 return (0);
2223
2224 subj = SLOT(cred->cr_label);
2225 obj = SLOT(label);
2226
2227 if (!mac_biba_dominate_single(obj, subj))
2228 return (EACCES);
2229
2230 return (0);
2231}
2232
2233static int
2234mac_biba_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
2235 struct label *dlabel, struct componentname *cnp)
2236{
2237 struct mac_biba *subj, *obj;
2238
2239 if (!mac_biba_enabled)
2240 return (0);
2241
2242 subj = SLOT(cred->cr_label);
2243 obj = SLOT(dlabel);
2244
2245 if (!mac_biba_dominate_single(obj, subj))
2246 return (EACCES);
2247
2248 return (0);
2249}
2250
2251static int
2252mac_biba_check_vnode_mmap(struct ucred *cred, struct vnode *vp,
2253 struct label *label, int prot)
2254{
2255 struct mac_biba *subj, *obj;
2256
2257 /*
2258 * Rely on the use of open()-time protections to handle
2259 * non-revocation cases.
2260 */
2261 if (!mac_biba_enabled || !revocation_enabled)
2262 return (0);
2263
2264 subj = SLOT(cred->cr_label);
2265 obj = SLOT(label);
2266
2267 if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
2268 if (!mac_biba_dominate_single(obj, subj))
2269 return (EACCES);
2270 }
2271 if (prot & VM_PROT_WRITE) {
2272 if (!mac_biba_dominate_single(subj, obj))
2273 return (EACCES);
2274 }
2275
2276 return (0);
2277}
2278
2279static int
2280mac_biba_check_vnode_open(struct ucred *cred, struct vnode *vp,
2281 struct label *vnodelabel, int acc_mode)
2282{
2283 struct mac_biba *subj, *obj;
2284
2285 if (!mac_biba_enabled)
2286 return (0);
2287
2288 subj = SLOT(cred->cr_label);
2289 obj = SLOT(vnodelabel);
2290
2291 /* XXX privilege override for admin? */
2292 if (acc_mode & (VREAD | VEXEC | VSTAT)) {
2293 if (!mac_biba_dominate_single(obj, subj))
2294 return (EACCES);
2295 }
2296 if (acc_mode & (VWRITE | VAPPEND | VADMIN)) {
2297 if (!mac_biba_dominate_single(subj, obj))
2298 return (EACCES);
2299 }
2300
2301 return (0);
2302}
2303
2304static int
2305mac_biba_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred,
2306 struct vnode *vp, struct label *label)
2307{
2308 struct mac_biba *subj, *obj;
2309
2310 if (!mac_biba_enabled || !revocation_enabled)
2311 return (0);
2312
2313 subj = SLOT(active_cred->cr_label);
2314 obj = SLOT(label);
2315
2316 if (!mac_biba_dominate_single(obj, subj))
2317 return (EACCES);
2318
2319 return (0);
2320}
2321
2322static int
2323mac_biba_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
2324 struct vnode *vp, struct label *label)
2325{
2326 struct mac_biba *subj, *obj;
2327
2328 if (!mac_biba_enabled || !revocation_enabled)
2329 return (0);
2330
2331 subj = SLOT(active_cred->cr_label);
2332 obj = SLOT(label);
2333
2334 if (!mac_biba_dominate_single(obj, subj))
2335 return (EACCES);
2336
2337 return (0);
2338}
2339
2340static int
2341mac_biba_check_vnode_readdir(struct ucred *cred, struct vnode *dvp,
2342 struct label *dlabel)
2343{
2344 struct mac_biba *subj, *obj;
2345
2346 if (!mac_biba_enabled)
2347 return (0);
2348
2349 subj = SLOT(cred->cr_label);
2350 obj = SLOT(dlabel);
2351
2352 if (!mac_biba_dominate_single(obj, subj))
2353 return (EACCES);
2354
2355 return (0);
2356}
2357
2358static int
2359mac_biba_check_vnode_readlink(struct ucred *cred, struct vnode *vp,
2360 struct label *label)
2361{
2362 struct mac_biba *subj, *obj;
2363
2364 if (!mac_biba_enabled)
2365 return (0);
2366
2367 subj = SLOT(cred->cr_label);
2368 obj = SLOT(label);
2369
2370 if (!mac_biba_dominate_single(obj, subj))
2371 return (EACCES);
2372
2373 return (0);
2374}
2375
2376static int
2377mac_biba_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
2378 struct label *vnodelabel, struct label *newlabel)
2379{
2380 struct mac_biba *old, *new, *subj;
2381 int error;
2382
2383 old = SLOT(vnodelabel);
2384 new = SLOT(newlabel);
2385 subj = SLOT(cred->cr_label);
2386
2387 /*
2388 * If there is a Biba label update for the vnode, it must be a
2389 * single label.
2390 */
2391 error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE);
2392 if (error)
2393 return (error);
2394
2395 /*
2396 * To perform a relabel of the vnode (Biba label or not), Biba must
2397 * authorize the relabel.
2398 */
2399 if (!mac_biba_single_in_range(old, subj))
2400 return (EPERM);
2401
2402 /*
2403 * If the Biba label is to be changed, authorize as appropriate.
2404 */
2405 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) {
2406 /*
2407 * To change the Biba label on a vnode, the new vnode label
2408 * must be in the subject range.
2409 */
2410 if (!mac_biba_single_in_range(new, subj))
2411 return (EPERM);
2412
2413 /*
2414 * To change the Biba label on the vnode to be EQUAL,
2415 * the subject must have appropriate privilege.
2416 */
2417 if (mac_biba_contains_equal(new)) {
2418 error = mac_biba_subject_privileged(subj);
2419 if (error)
2420 return (error);
2421 }
2422 }
2423
2424 return (0);
2425}
2426
2427static int
2428mac_biba_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
2429 struct label *dlabel, struct vnode *vp, struct label *label,
2430 struct componentname *cnp)
2431{
2432 struct mac_biba *subj, *obj;
2433
2434 if (!mac_biba_enabled)
2435 return (0);
2436
2437 subj = SLOT(cred->cr_label);
2438 obj = SLOT(dlabel);
2439
2440 if (!mac_biba_dominate_single(subj, obj))
2441 return (EACCES);
2442
2443 obj = SLOT(label);
2444
2445 if (!mac_biba_dominate_single(subj, obj))
2446 return (EACCES);
2447
2448 return (0);
2449}
2450
2451static int
2452mac_biba_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
2453 struct label *dlabel, struct vnode *vp, struct label *label, int samedir,
2454 struct componentname *cnp)
2455{
2456 struct mac_biba *subj, *obj;
2457
2458 if (!mac_biba_enabled)
2459 return (0);
2460
2461 subj = SLOT(cred->cr_label);
2462 obj = SLOT(dlabel);
2463
2464 if (!mac_biba_dominate_single(subj, obj))
2465 return (EACCES);
2466
2467 if (vp != NULL) {
2468 obj = SLOT(label);
2469
2470 if (!mac_biba_dominate_single(subj, obj))
2471 return (EACCES);
2472 }
2473
2474 return (0);
2475}
2476
2477static int
2478mac_biba_check_vnode_revoke(struct ucred *cred, struct vnode *vp,
2479 struct label *label)
2480{
2481 struct mac_biba *subj, *obj;
2482
2483 if (!mac_biba_enabled)
2484 return (0);
2485
2486 subj = SLOT(cred->cr_label);
2487 obj = SLOT(label);
2488
2489 if (!mac_biba_dominate_single(subj, obj))
2490 return (EACCES);
2491
2492 return (0);
2493}
2494
2495static int
2496mac_biba_check_vnode_setacl(struct ucred *cred, struct vnode *vp,
2497 struct label *label, acl_type_t type, struct acl *acl)
2498{
2499 struct mac_biba *subj, *obj;
2500
2501 if (!mac_biba_enabled)
2502 return (0);
2503
2504 subj = SLOT(cred->cr_label);
2505 obj = SLOT(label);
2506
2507 if (!mac_biba_dominate_single(subj, obj))
2508 return (EACCES);
2509
2510 return (0);
2511}
2512
2513static int
2514mac_biba_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
2515 struct label *vnodelabel, int attrnamespace, const char *name,
2516 struct uio *uio)
2517{
2518 struct mac_biba *subj, *obj;
2519
2520 if (!mac_biba_enabled)
2521 return (0);
2522
2523 subj = SLOT(cred->cr_label);
2524 obj = SLOT(vnodelabel);
2525
2526 if (!mac_biba_dominate_single(subj, obj))
2527 return (EACCES);
2528
2529 /* XXX: protect the MAC EA in a special way? */
2530
2531 return (0);
2532}
2533
2534static int
2535mac_biba_check_vnode_setflags(struct ucred *cred, struct vnode *vp,
2536 struct label *vnodelabel, u_long flags)
2537{
2538 struct mac_biba *subj, *obj;
2539
2540 if (!mac_biba_enabled)
2541 return (0);
2542
2543 subj = SLOT(cred->cr_label);
2544 obj = SLOT(vnodelabel);
2545
2546 if (!mac_biba_dominate_single(subj, obj))
2547 return (EACCES);
2548
2549 return (0);
2550}
2551
2552static int
2553mac_biba_check_vnode_setmode(struct ucred *cred, struct vnode *vp,
2554 struct label *vnodelabel, mode_t mode)
2555{
2556 struct mac_biba *subj, *obj;
2557
2558 if (!mac_biba_enabled)
2559 return (0);
2560
2561 subj = SLOT(cred->cr_label);
2562 obj = SLOT(vnodelabel);
2563
2564 if (!mac_biba_dominate_single(subj, obj))
2565 return (EACCES);
2566
2567 return (0);
2568}
2569
2570static int
2571mac_biba_check_vnode_setowner(struct ucred *cred, struct vnode *vp,
2572 struct label *vnodelabel, uid_t uid, gid_t gid)
2573{
2574 struct mac_biba *subj, *obj;
2575
2576 if (!mac_biba_enabled)
2577 return (0);
2578
2579 subj = SLOT(cred->cr_label);
2580 obj = SLOT(vnodelabel);
2581
2582 if (!mac_biba_dominate_single(subj, obj))
2583 return (EACCES);
2584
2585 return (0);
2586}
2587
2588static int
2589mac_biba_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
2590 struct label *vnodelabel, struct timespec atime, struct timespec mtime)
2591{
2592 struct mac_biba *subj, *obj;
2593
2594 if (!mac_biba_enabled)
2595 return (0);
2596
2597 subj = SLOT(cred->cr_label);
2598 obj = SLOT(vnodelabel);
2599
2600 if (!mac_biba_dominate_single(subj, obj))
2601 return (EACCES);
2602
2603 return (0);
2604}
2605
2606static int
2607mac_biba_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
2608 struct vnode *vp, struct label *vnodelabel)
2609{
2610 struct mac_biba *subj, *obj;
2611
2612 if (!mac_biba_enabled)
2613 return (0);
2614
2615 subj = SLOT(active_cred->cr_label);
2616 obj = SLOT(vnodelabel);
2617
2618 if (!mac_biba_dominate_single(obj, subj))
2619 return (EACCES);
2620
2621 return (0);
2622}
2623
2624static int
2625mac_biba_check_vnode_write(struct ucred *active_cred,
2626 struct ucred *file_cred, struct vnode *vp, struct label *label)
2627{
2628 struct mac_biba *subj, *obj;
2629
2630 if (!mac_biba_enabled || !revocation_enabled)
2631 return (0);
2632
2633 subj = SLOT(active_cred->cr_label);
2634 obj = SLOT(label);
2635
2636 if (!mac_biba_dominate_single(subj, obj))
2637 return (EACCES);
2638
2639 return (0);
2640}
2641
2642static struct mac_policy_ops mac_biba_ops =
2643{
2644 .mpo_init = mac_biba_init,
2645 .mpo_init_bpfdesc_label = mac_biba_init_label,
2646 .mpo_init_cred_label = mac_biba_init_label,
2647 .mpo_init_devfsdirent_label = mac_biba_init_label,
2648 .mpo_init_ifnet_label = mac_biba_init_label,
2649 .mpo_init_inpcb_label = mac_biba_init_label_waitcheck,
2650 .mpo_init_ipq_label = mac_biba_init_label_waitcheck,
2651 .mpo_init_mbuf_label = mac_biba_init_label_waitcheck,
2652 .mpo_init_mount_label = mac_biba_init_label,
2653 .mpo_init_mount_fs_label = mac_biba_init_label,
2654 .mpo_init_pipe_label = mac_biba_init_label,
2655 .mpo_init_socket_label = mac_biba_init_label_waitcheck,
2656 .mpo_init_socket_peer_label = mac_biba_init_label_waitcheck,
2657 .mpo_init_vnode_label = mac_biba_init_label,
2658 .mpo_destroy_bpfdesc_label = mac_biba_destroy_label,
2659 .mpo_destroy_cred_label = mac_biba_destroy_label,
2660 .mpo_destroy_devfsdirent_label = mac_biba_destroy_label,
2661 .mpo_destroy_ifnet_label = mac_biba_destroy_label,
2662 .mpo_destroy_inpcb_label = mac_biba_destroy_label,
2663 .mpo_destroy_ipq_label = mac_biba_destroy_label,
2664 .mpo_destroy_mbuf_label = mac_biba_destroy_label,
2665 .mpo_destroy_mount_label = mac_biba_destroy_label,
2666 .mpo_destroy_mount_fs_label = mac_biba_destroy_label,
2667 .mpo_destroy_pipe_label = mac_biba_destroy_label,
2668 .mpo_destroy_socket_label = mac_biba_destroy_label,
2669 .mpo_destroy_socket_peer_label = mac_biba_destroy_label,
2670 .mpo_destroy_vnode_label = mac_biba_destroy_label,
2671 .mpo_copy_mbuf_label = mac_biba_copy_label,
2672 .mpo_copy_pipe_label = mac_biba_copy_label,
2673 .mpo_copy_socket_label = mac_biba_copy_label,
2674 .mpo_copy_vnode_label = mac_biba_copy_label,
2675 .mpo_externalize_cred_label = mac_biba_externalize_label,
2676 .mpo_externalize_ifnet_label = mac_biba_externalize_label,
2677 .mpo_externalize_pipe_label = mac_biba_externalize_label,
2678 .mpo_externalize_socket_label = mac_biba_externalize_label,
2679 .mpo_externalize_socket_peer_label = mac_biba_externalize_label,
2680 .mpo_externalize_vnode_label = mac_biba_externalize_label,
2681 .mpo_internalize_cred_label = mac_biba_internalize_label,
2682 .mpo_internalize_ifnet_label = mac_biba_internalize_label,
2683 .mpo_internalize_pipe_label = mac_biba_internalize_label,
2684 .mpo_internalize_socket_label = mac_biba_internalize_label,
2685 .mpo_internalize_vnode_label = mac_biba_internalize_label,
2686 .mpo_create_devfs_device = mac_biba_create_devfs_device,
2687 .mpo_create_devfs_directory = mac_biba_create_devfs_directory,
2688 .mpo_create_devfs_symlink = mac_biba_create_devfs_symlink,
2689 .mpo_create_mount = mac_biba_create_mount,
2690 .mpo_create_root_mount = mac_biba_create_root_mount,
2691 .mpo_relabel_vnode = mac_biba_relabel_vnode,
2692 .mpo_update_devfsdirent = mac_biba_update_devfsdirent,
2693 .mpo_associate_vnode_devfs = mac_biba_associate_vnode_devfs,
2694 .mpo_associate_vnode_extattr = mac_biba_associate_vnode_extattr,
2695 .mpo_associate_vnode_singlelabel = mac_biba_associate_vnode_singlelabel,
2696 .mpo_create_vnode_extattr = mac_biba_create_vnode_extattr,
2697 .mpo_setlabel_vnode_extattr = mac_biba_setlabel_vnode_extattr,
2698 .mpo_create_mbuf_from_socket = mac_biba_create_mbuf_from_socket,
2699 .mpo_create_pipe = mac_biba_create_pipe,
2700 .mpo_create_socket = mac_biba_create_socket,
2701 .mpo_create_socket_from_socket = mac_biba_create_socket_from_socket,
2702 .mpo_relabel_pipe = mac_biba_relabel_pipe,
2703 .mpo_relabel_socket = mac_biba_relabel_socket,
2704 .mpo_set_socket_peer_from_mbuf = mac_biba_set_socket_peer_from_mbuf,
2705 .mpo_set_socket_peer_from_socket = mac_biba_set_socket_peer_from_socket,
2706 .mpo_create_bpfdesc = mac_biba_create_bpfdesc,
2707 .mpo_create_datagram_from_ipq = mac_biba_create_datagram_from_ipq,
2708 .mpo_create_fragment = mac_biba_create_fragment,
2709 .mpo_create_ifnet = mac_biba_create_ifnet,
2710 .mpo_create_inpcb_from_socket = mac_biba_create_inpcb_from_socket,
2711 .mpo_create_ipq = mac_biba_create_ipq,
2712 .mpo_create_mbuf_from_mbuf = mac_biba_create_mbuf_from_mbuf,
2713 .mpo_create_mbuf_linklayer = mac_biba_create_mbuf_linklayer,
2714 .mpo_create_mbuf_from_bpfdesc = mac_biba_create_mbuf_from_bpfdesc,
2715 .mpo_create_mbuf_from_ifnet = mac_biba_create_mbuf_from_ifnet,
2716 .mpo_create_mbuf_multicast_encap = mac_biba_create_mbuf_multicast_encap,
2717 .mpo_create_mbuf_netlayer = mac_biba_create_mbuf_netlayer,
2718 .mpo_fragment_match = mac_biba_fragment_match,
2719 .mpo_relabel_ifnet = mac_biba_relabel_ifnet,
2720 .mpo_update_ipq = mac_biba_update_ipq,
2721 .mpo_inpcb_sosetlabel = mac_biba_inpcb_sosetlabel,
2722 .mpo_create_cred = mac_biba_create_cred,
2723 .mpo_create_proc0 = mac_biba_create_proc0,
2724 .mpo_create_proc1 = mac_biba_create_proc1,
2725 .mpo_relabel_cred = mac_biba_relabel_cred,
2726 .mpo_check_bpfdesc_receive = mac_biba_check_bpfdesc_receive,
2727 .mpo_check_cred_relabel = mac_biba_check_cred_relabel,
2728 .mpo_check_cred_visible = mac_biba_check_cred_visible,
2729 .mpo_check_ifnet_relabel = mac_biba_check_ifnet_relabel,
2730 .mpo_check_ifnet_transmit = mac_biba_check_ifnet_transmit,
2731 .mpo_check_inpcb_deliver = mac_biba_check_inpcb_deliver,
2732 .mpo_check_kld_load = mac_biba_check_kld_load,
2733 .mpo_check_kld_unload = mac_biba_check_kld_unload,
2734 .mpo_check_mount_stat = mac_biba_check_mount_stat,
2735 .mpo_check_pipe_ioctl = mac_biba_check_pipe_ioctl,
2736 .mpo_check_pipe_poll = mac_biba_check_pipe_poll,
2737 .mpo_check_pipe_read = mac_biba_check_pipe_read,
2738 .mpo_check_pipe_relabel = mac_biba_check_pipe_relabel,
2739 .mpo_check_pipe_stat = mac_biba_check_pipe_stat,
2740 .mpo_check_pipe_write = mac_biba_check_pipe_write,
2741 .mpo_check_proc_debug = mac_biba_check_proc_debug,
2742 .mpo_check_proc_sched = mac_biba_check_proc_sched,
2743 .mpo_check_proc_signal = mac_biba_check_proc_signal,
2744 .mpo_check_socket_deliver = mac_biba_check_socket_deliver,
2745 .mpo_check_socket_relabel = mac_biba_check_socket_relabel,
2746 .mpo_check_socket_visible = mac_biba_check_socket_visible,
2747 .mpo_check_sysarch_ioperm = mac_biba_check_sysarch_ioperm,
2748 .mpo_check_system_acct = mac_biba_check_system_acct,
2749 .mpo_check_system_settime = mac_biba_check_system_settime,
2750 .mpo_check_system_swapon = mac_biba_check_system_swapon,
2751 .mpo_check_system_swapoff = mac_biba_check_system_swapoff,
2752 .mpo_check_system_sysctl = mac_biba_check_system_sysctl,
2753 .mpo_check_vnode_access = mac_biba_check_vnode_open,
2754 .mpo_check_vnode_chdir = mac_biba_check_vnode_chdir,
2755 .mpo_check_vnode_chroot = mac_biba_check_vnode_chroot,
2756 .mpo_check_vnode_create = mac_biba_check_vnode_create,
2757 .mpo_check_vnode_delete = mac_biba_check_vnode_delete,
2758 .mpo_check_vnode_deleteacl = mac_biba_check_vnode_deleteacl,
2759 .mpo_check_vnode_deleteextattr = mac_biba_check_vnode_deleteextattr,
2760 .mpo_check_vnode_exec = mac_biba_check_vnode_exec,
2761 .mpo_check_vnode_getacl = mac_biba_check_vnode_getacl,
2762 .mpo_check_vnode_getextattr = mac_biba_check_vnode_getextattr,
2763 .mpo_check_vnode_link = mac_biba_check_vnode_link,
2764 .mpo_check_vnode_listextattr = mac_biba_check_vnode_listextattr,
2765 .mpo_check_vnode_lookup = mac_biba_check_vnode_lookup,
2766 .mpo_check_vnode_mmap = mac_biba_check_vnode_mmap,
2767 .mpo_check_vnode_mprotect = mac_biba_check_vnode_mmap,
2768 .mpo_check_vnode_open = mac_biba_check_vnode_open,
2769 .mpo_check_vnode_poll = mac_biba_check_vnode_poll,
2770 .mpo_check_vnode_read = mac_biba_check_vnode_read,
2771 .mpo_check_vnode_readdir = mac_biba_check_vnode_readdir,
2772 .mpo_check_vnode_readlink = mac_biba_check_vnode_readlink,
2773 .mpo_check_vnode_relabel = mac_biba_check_vnode_relabel,
2774 .mpo_check_vnode_rename_from = mac_biba_check_vnode_rename_from,
2775 .mpo_check_vnode_rename_to = mac_biba_check_vnode_rename_to,
2776 .mpo_check_vnode_revoke = mac_biba_check_vnode_revoke,
2777 .mpo_check_vnode_setacl = mac_biba_check_vnode_setacl,
2778 .mpo_check_vnode_setextattr = mac_biba_check_vnode_setextattr,
2779 .mpo_check_vnode_setflags = mac_biba_check_vnode_setflags,
2780 .mpo_check_vnode_setmode = mac_biba_check_vnode_setmode,
2781 .mpo_check_vnode_setowner = mac_biba_check_vnode_setowner,
2782 .mpo_check_vnode_setutimes = mac_biba_check_vnode_setutimes,
2783 .mpo_check_vnode_stat = mac_biba_check_vnode_stat,
2784 .mpo_check_vnode_write = mac_biba_check_vnode_write,
2785};
2786
2787MAC_POLICY_SET(&mac_biba_ops, mac_biba, "TrustedBSD MAC/Biba",
2788 MPC_LOADTIME_FLAG_NOTLATE | MPC_LOADTIME_FLAG_LABELMBUFS, &mac_biba_slot);
2 * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson
3 * Copyright (c) 2001, 2002, 2003 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 122879 2003-11-18 04:11:52Z 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/sbuf.h>
53#include <sys/systm.h>
54#include <sys/sysproto.h>
55#include <sys/sysent.h>
56#include <sys/systm.h>
57#include <sys/vnode.h>
58#include <sys/file.h>
59#include <sys/socket.h>
60#include <sys/socketvar.h>
61#include <sys/pipe.h>
62#include <sys/sysctl.h>
63
64#include <fs/devfs/devfs.h>
65
66#include <net/bpfdesc.h>
67#include <net/if.h>
68#include <net/if_types.h>
69#include <net/if_var.h>
70
71#include <netinet/in.h>
72#include <netinet/in_pcb.h>
73#include <netinet/ip_var.h>
74
75#include <vm/uma.h>
76#include <vm/vm.h>
77
78#include <sys/mac_policy.h>
79
80#include <security/mac_biba/mac_biba.h>
81
82SYSCTL_DECL(_security_mac);
83
84SYSCTL_NODE(_security_mac, OID_AUTO, biba, CTLFLAG_RW, 0,
85 "TrustedBSD mac_biba policy controls");
86
87static int mac_biba_label_size = sizeof(struct mac_biba);
88SYSCTL_INT(_security_mac_biba, OID_AUTO, label_size, CTLFLAG_RD,
89 &mac_biba_label_size, 0, "Size of struct mac_biba");
90
91static int mac_biba_enabled = 1;
92SYSCTL_INT(_security_mac_biba, OID_AUTO, enabled, CTLFLAG_RW,
93 &mac_biba_enabled, 0, "Enforce MAC/Biba policy");
94TUNABLE_INT("security.mac.biba.enabled", &mac_biba_enabled);
95
96static int destroyed_not_inited;
97SYSCTL_INT(_security_mac_biba, OID_AUTO, destroyed_not_inited, CTLFLAG_RD,
98 &destroyed_not_inited, 0, "Count of labels destroyed but not inited");
99
100static int trust_all_interfaces = 0;
101SYSCTL_INT(_security_mac_biba, OID_AUTO, trust_all_interfaces, CTLFLAG_RD,
102 &trust_all_interfaces, 0, "Consider all interfaces 'trusted' by MAC/Biba");
103TUNABLE_INT("security.mac.biba.trust_all_interfaces", &trust_all_interfaces);
104
105static char trusted_interfaces[128];
106SYSCTL_STRING(_security_mac_biba, OID_AUTO, trusted_interfaces, CTLFLAG_RD,
107 trusted_interfaces, 0, "Interfaces considered 'trusted' by MAC/Biba");
108TUNABLE_STR("security.mac.biba.trusted_interfaces", trusted_interfaces,
109 sizeof(trusted_interfaces));
110
111static int max_compartments = MAC_BIBA_MAX_COMPARTMENTS;
112SYSCTL_INT(_security_mac_biba, OID_AUTO, max_compartments, CTLFLAG_RD,
113 &max_compartments, 0, "Maximum supported compartments");
114
115static int ptys_equal = 0;
116SYSCTL_INT(_security_mac_biba, OID_AUTO, ptys_equal, CTLFLAG_RW,
117 &ptys_equal, 0, "Label pty devices as biba/equal on create");
118TUNABLE_INT("security.mac.biba.ptys_equal", &ptys_equal);
119
120static int revocation_enabled = 0;
121SYSCTL_INT(_security_mac_biba, OID_AUTO, revocation_enabled, CTLFLAG_RW,
122 &revocation_enabled, 0, "Revoke access to objects on relabel");
123TUNABLE_INT("security.mac.biba.revocation_enabled", &revocation_enabled);
124
125static int mac_biba_slot;
126#define SLOT(l) ((struct mac_biba *)LABEL_TO_SLOT((l), mac_biba_slot).l_ptr)
127
128static uma_zone_t zone_biba;
129
130static __inline int
131biba_bit_set_empty(u_char *set) {
132 int i;
133
134 for (i = 0; i < MAC_BIBA_MAX_COMPARTMENTS >> 3; i++)
135 if (set[i] != 0)
136 return (0);
137 return (1);
138}
139
140static struct mac_biba *
141biba_alloc(int flag)
142{
143
144 return (uma_zalloc(zone_biba, flag | M_ZERO));
145}
146
147static void
148biba_free(struct mac_biba *mac_biba)
149{
150
151 if (mac_biba != NULL)
152 uma_zfree(zone_biba, mac_biba);
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_init(struct mac_policy_conf *conf)
491{
492
493 zone_biba = uma_zcreate("mac_biba", sizeof(struct mac_biba), NULL,
494 NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
495}
496
497/*
498 * Label operations.
499 */
500static void
501mac_biba_init_label(struct label *label)
502{
503
504 SLOT(label) = biba_alloc(M_WAITOK);
505}
506
507static int
508mac_biba_init_label_waitcheck(struct label *label, int flag)
509{
510
511 SLOT(label) = biba_alloc(flag);
512 if (SLOT(label) == NULL)
513 return (ENOMEM);
514
515 return (0);
516}
517
518static void
519mac_biba_destroy_label(struct label *label)
520{
521
522 biba_free(SLOT(label));
523 SLOT(label) = NULL;
524}
525
526/*
527 * mac_biba_element_to_string() accepts an sbuf and Biba element. It
528 * converts the Biba element to a string and stores the result in the
529 * sbuf; if there isn't space in the sbuf, -1 is returned.
530 */
531static int
532mac_biba_element_to_string(struct sbuf *sb, struct mac_biba_element *element)
533{
534 int i, first;
535
536 switch (element->mbe_type) {
537 case MAC_BIBA_TYPE_HIGH:
538 return (sbuf_printf(sb, "high"));
539
540 case MAC_BIBA_TYPE_LOW:
541 return (sbuf_printf(sb, "low"));
542
543 case MAC_BIBA_TYPE_EQUAL:
544 return (sbuf_printf(sb, "equal"));
545
546 case MAC_BIBA_TYPE_GRADE:
547 if (sbuf_printf(sb, "%d", element->mbe_grade) == -1)
548 return (-1);
549
550 first = 1;
551 for (i = 1; i <= MAC_BIBA_MAX_COMPARTMENTS; i++) {
552 if (MAC_BIBA_BIT_TEST(i, element->mbe_compartments)) {
553 if (first) {
554 if (sbuf_putc(sb, ':') == -1)
555 return (-1);
556 if (sbuf_printf(sb, "%d", i) == -1)
557 return (-1);
558 first = 0;
559 } else {
560 if (sbuf_printf(sb, "+%d", i) == -1)
561 return (-1);
562 }
563 }
564 }
565 return (0);
566
567 default:
568 panic("mac_biba_element_to_string: invalid type (%d)",
569 element->mbe_type);
570 }
571}
572
573/*
574 * mac_biba_to_string() converts a Biba label to a string, and places
575 * the results in the passed sbuf. It returns 0 on success, or EINVAL
576 * if there isn't room in the sbuf. Note: the sbuf will be modified
577 * even in a failure case, so the caller may need to revert the sbuf
578 * by restoring the offset if that's undesired.
579 */
580static int
581mac_biba_to_string(struct sbuf *sb, struct mac_biba *mac_biba)
582{
583
584 if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) {
585 if (mac_biba_element_to_string(sb, &mac_biba->mb_single)
586 == -1)
587 return (EINVAL);
588 }
589
590 if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
591 if (sbuf_putc(sb, '(') == -1)
592 return (EINVAL);
593
594 if (mac_biba_element_to_string(sb, &mac_biba->mb_rangelow)
595 == -1)
596 return (EINVAL);
597
598 if (sbuf_putc(sb, '-') == -1)
599 return (EINVAL);
600
601 if (mac_biba_element_to_string(sb, &mac_biba->mb_rangehigh)
602 == -1)
603 return (EINVAL);
604
605 if (sbuf_putc(sb, ')') == -1)
606 return (EINVAL);
607 }
608
609 return (0);
610}
611
612static int
613mac_biba_externalize_label(struct label *label, char *element_name,
614 struct sbuf *sb, int *claimed)
615{
616 struct mac_biba *mac_biba;
617
618 if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0)
619 return (0);
620
621 (*claimed)++;
622
623 mac_biba = SLOT(label);
624 return (mac_biba_to_string(sb, mac_biba));
625}
626
627static int
628mac_biba_parse_element(struct mac_biba_element *element, char *string)
629{
630 char *compartment, *end, *grade;
631 int value;
632
633 if (strcmp(string, "high") == 0 ||
634 strcmp(string, "hi") == 0) {
635 element->mbe_type = MAC_BIBA_TYPE_HIGH;
636 element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
637 } else if (strcmp(string, "low") == 0 ||
638 strcmp(string, "lo") == 0) {
639 element->mbe_type = MAC_BIBA_TYPE_LOW;
640 element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
641 } else if (strcmp(string, "equal") == 0 ||
642 strcmp(string, "eq") == 0) {
643 element->mbe_type = MAC_BIBA_TYPE_EQUAL;
644 element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
645 } else {
646 element->mbe_type = MAC_BIBA_TYPE_GRADE;
647
648 /*
649 * Numeric grade piece of the element.
650 */
651 grade = strsep(&string, ":");
652 value = strtol(grade, &end, 10);
653 if (end == grade || *end != '\0')
654 return (EINVAL);
655 if (value < 0 || value > 65535)
656 return (EINVAL);
657 element->mbe_grade = value;
658
659 /*
660 * Optional compartment piece of the element. If none
661 * are included, we assume that the label has no
662 * compartments.
663 */
664 if (string == NULL)
665 return (0);
666 if (*string == '\0')
667 return (0);
668
669 while ((compartment = strsep(&string, "+")) != NULL) {
670 value = strtol(compartment, &end, 10);
671 if (compartment == end || *end != '\0')
672 return (EINVAL);
673 if (value < 1 || value > MAC_BIBA_MAX_COMPARTMENTS)
674 return (EINVAL);
675 MAC_BIBA_BIT_SET(value, element->mbe_compartments);
676 }
677 }
678
679 return (0);
680}
681
682/*
683 * Note: destructively consumes the string, make a local copy before
684 * calling if that's a problem.
685 */
686static int
687mac_biba_parse(struct mac_biba *mac_biba, char *string)
688{
689 char *rangehigh, *rangelow, *single;
690 int error;
691
692 single = strsep(&string, "(");
693 if (*single == '\0')
694 single = NULL;
695
696 if (string != NULL) {
697 rangelow = strsep(&string, "-");
698 if (string == NULL)
699 return (EINVAL);
700 rangehigh = strsep(&string, ")");
701 if (string == NULL)
702 return (EINVAL);
703 if (*string != '\0')
704 return (EINVAL);
705 } else {
706 rangelow = NULL;
707 rangehigh = NULL;
708 }
709
710 KASSERT((rangelow != NULL && rangehigh != NULL) ||
711 (rangelow == NULL && rangehigh == NULL),
712 ("mac_biba_parse: range mismatch"));
713
714 bzero(mac_biba, sizeof(*mac_biba));
715 if (single != NULL) {
716 error = mac_biba_parse_element(&mac_biba->mb_single, single);
717 if (error)
718 return (error);
719 mac_biba->mb_flags |= MAC_BIBA_FLAG_SINGLE;
720 }
721
722 if (rangelow != NULL) {
723 error = mac_biba_parse_element(&mac_biba->mb_rangelow,
724 rangelow);
725 if (error)
726 return (error);
727 error = mac_biba_parse_element(&mac_biba->mb_rangehigh,
728 rangehigh);
729 if (error)
730 return (error);
731 mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE;
732 }
733
734 error = mac_biba_valid(mac_biba);
735 if (error)
736 return (error);
737
738 return (0);
739}
740
741static int
742mac_biba_internalize_label(struct label *label, char *element_name,
743 char *element_data, int *claimed)
744{
745 struct mac_biba *mac_biba, mac_biba_temp;
746 int error;
747
748 if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0)
749 return (0);
750
751 (*claimed)++;
752
753 error = mac_biba_parse(&mac_biba_temp, element_data);
754 if (error)
755 return (error);
756
757 mac_biba = SLOT(label);
758 *mac_biba = mac_biba_temp;
759
760 return (0);
761}
762
763static void
764mac_biba_copy_label(struct label *src, struct label *dest)
765{
766
767 *SLOT(dest) = *SLOT(src);
768}
769
770/*
771 * Labeling event operations: file system objects, and things that look
772 * a lot like file system objects.
773 */
774static void
775mac_biba_create_devfs_device(struct mount *mp, dev_t dev,
776 struct devfs_dirent *devfs_dirent, struct label *label)
777{
778 struct mac_biba *mac_biba;
779 int biba_type;
780
781 mac_biba = SLOT(label);
782 if (strcmp(dev->si_name, "null") == 0 ||
783 strcmp(dev->si_name, "zero") == 0 ||
784 strcmp(dev->si_name, "random") == 0 ||
785 strncmp(dev->si_name, "fd/", strlen("fd/")) == 0)
786 biba_type = MAC_BIBA_TYPE_EQUAL;
787 else if (ptys_equal &&
788 (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 ||
789 strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0))
790 biba_type = MAC_BIBA_TYPE_EQUAL;
791 else
792 biba_type = MAC_BIBA_TYPE_HIGH;
793 mac_biba_set_single(mac_biba, biba_type, 0, NULL);
794}
795
796static void
797mac_biba_create_devfs_directory(struct mount *mp, char *dirname,
798 int dirnamelen, struct devfs_dirent *devfs_dirent, struct label *label)
799{
800 struct mac_biba *mac_biba;
801
802 mac_biba = SLOT(label);
803 mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
804}
805
806static void
807mac_biba_create_devfs_symlink(struct ucred *cred, struct mount *mp,
808 struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de,
809 struct label *delabel)
810{
811 struct mac_biba *source, *dest;
812
813 source = SLOT(cred->cr_label);
814 dest = SLOT(delabel);
815
816 mac_biba_copy_single(source, dest);
817}
818
819static void
820mac_biba_create_mount(struct ucred *cred, struct mount *mp,
821 struct label *mntlabel, struct label *fslabel)
822{
823 struct mac_biba *source, *dest;
824
825 source = SLOT(cred->cr_label);
826 dest = SLOT(mntlabel);
827 mac_biba_copy_single(source, dest);
828 dest = SLOT(fslabel);
829 mac_biba_copy_single(source, dest);
830}
831
832static void
833mac_biba_create_root_mount(struct ucred *cred, struct mount *mp,
834 struct label *mntlabel, struct label *fslabel)
835{
836 struct mac_biba *mac_biba;
837
838 /* Always mount root as high integrity. */
839 mac_biba = SLOT(fslabel);
840 mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
841 mac_biba = SLOT(mntlabel);
842 mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
843}
844
845static void
846mac_biba_relabel_vnode(struct ucred *cred, struct vnode *vp,
847 struct label *vnodelabel, struct label *label)
848{
849 struct mac_biba *source, *dest;
850
851 source = SLOT(label);
852 dest = SLOT(vnodelabel);
853
854 mac_biba_copy(source, dest);
855}
856
857static void
858mac_biba_update_devfsdirent(struct mount *mp,
859 struct devfs_dirent *devfs_dirent, struct label *direntlabel,
860 struct vnode *vp, struct label *vnodelabel)
861{
862 struct mac_biba *source, *dest;
863
864 source = SLOT(vnodelabel);
865 dest = SLOT(direntlabel);
866
867 mac_biba_copy(source, dest);
868}
869
870static void
871mac_biba_associate_vnode_devfs(struct mount *mp, struct label *fslabel,
872 struct devfs_dirent *de, struct label *delabel, struct vnode *vp,
873 struct label *vlabel)
874{
875 struct mac_biba *source, *dest;
876
877 source = SLOT(delabel);
878 dest = SLOT(vlabel);
879
880 mac_biba_copy_single(source, dest);
881}
882
883static int
884mac_biba_associate_vnode_extattr(struct mount *mp, struct label *fslabel,
885 struct vnode *vp, struct label *vlabel)
886{
887 struct mac_biba temp, *source, *dest;
888 int buflen, error;
889
890 source = SLOT(fslabel);
891 dest = SLOT(vlabel);
892
893 buflen = sizeof(temp);
894 bzero(&temp, buflen);
895
896 error = vn_extattr_get(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
897 MAC_BIBA_EXTATTR_NAME, &buflen, (char *) &temp, curthread);
898 if (error == ENOATTR || error == EOPNOTSUPP) {
899 /* Fall back to the fslabel. */
900 mac_biba_copy_single(source, dest);
901 return (0);
902 } else if (error)
903 return (error);
904
905 if (buflen != sizeof(temp)) {
906 printf("mac_biba_associate_vnode_extattr: bad size %d\n",
907 buflen);
908 return (EPERM);
909 }
910 if (mac_biba_valid(&temp) != 0) {
911 printf("mac_biba_associate_vnode_extattr: invalid\n");
912 return (EPERM);
913 }
914 if ((temp.mb_flags & MAC_BIBA_FLAGS_BOTH) != MAC_BIBA_FLAG_SINGLE) {
915 printf("mac_biba_associate_vnode_extattr: not single\n");
916 return (EPERM);
917 }
918
919 mac_biba_copy_single(&temp, dest);
920 return (0);
921}
922
923static void
924mac_biba_associate_vnode_singlelabel(struct mount *mp,
925 struct label *fslabel, struct vnode *vp, struct label *vlabel)
926{
927 struct mac_biba *source, *dest;
928
929 source = SLOT(fslabel);
930 dest = SLOT(vlabel);
931
932 mac_biba_copy_single(source, dest);
933}
934
935static int
936mac_biba_create_vnode_extattr(struct ucred *cred, struct mount *mp,
937 struct label *fslabel, struct vnode *dvp, struct label *dlabel,
938 struct vnode *vp, struct label *vlabel, struct componentname *cnp)
939{
940 struct mac_biba *source, *dest, temp;
941 size_t buflen;
942 int error;
943
944 buflen = sizeof(temp);
945 bzero(&temp, buflen);
946
947 source = SLOT(cred->cr_label);
948 dest = SLOT(vlabel);
949 mac_biba_copy_single(source, &temp);
950
951 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
952 MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread);
953 if (error == 0)
954 mac_biba_copy_single(source, dest);
955 return (error);
956}
957
958static int
959mac_biba_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp,
960 struct label *vlabel, struct label *intlabel)
961{
962 struct mac_biba *source, temp;
963 size_t buflen;
964 int error;
965
966 buflen = sizeof(temp);
967 bzero(&temp, buflen);
968
969 source = SLOT(intlabel);
970 if ((source->mb_flags & MAC_BIBA_FLAG_SINGLE) == 0)
971 return (0);
972
973 mac_biba_copy_single(source, &temp);
974
975 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
976 MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread);
977 return (error);
978}
979
980/*
981 * Labeling event operations: IPC object.
982 */
983static void
984mac_biba_create_inpcb_from_socket(struct socket *so, struct label *solabel,
985 struct inpcb *inp, struct label *inplabel)
986{
987 struct mac_biba *source, *dest;
988
989 source = SLOT(solabel);
990 dest = SLOT(inplabel);
991
992 mac_biba_copy_single(source, dest);
993}
994
995static void
996mac_biba_create_mbuf_from_socket(struct socket *so, struct label *socketlabel,
997 struct mbuf *m, struct label *mbuflabel)
998{
999 struct mac_biba *source, *dest;
1000
1001 source = SLOT(socketlabel);
1002 dest = SLOT(mbuflabel);
1003
1004 mac_biba_copy_single(source, dest);
1005}
1006
1007static void
1008mac_biba_create_socket(struct ucred *cred, struct socket *socket,
1009 struct label *socketlabel)
1010{
1011 struct mac_biba *source, *dest;
1012
1013 source = SLOT(cred->cr_label);
1014 dest = SLOT(socketlabel);
1015
1016 mac_biba_copy_single(source, dest);
1017}
1018
1019static void
1020mac_biba_create_pipe(struct ucred *cred, struct pipe *pipe,
1021 struct label *pipelabel)
1022{
1023 struct mac_biba *source, *dest;
1024
1025 source = SLOT(cred->cr_label);
1026 dest = SLOT(pipelabel);
1027
1028 mac_biba_copy_single(source, dest);
1029}
1030
1031static void
1032mac_biba_create_socket_from_socket(struct socket *oldsocket,
1033 struct label *oldsocketlabel, struct socket *newsocket,
1034 struct label *newsocketlabel)
1035{
1036 struct mac_biba *source, *dest;
1037
1038 source = SLOT(oldsocketlabel);
1039 dest = SLOT(newsocketlabel);
1040
1041 mac_biba_copy_single(source, dest);
1042}
1043
1044static void
1045mac_biba_relabel_socket(struct ucred *cred, struct socket *socket,
1046 struct label *socketlabel, struct label *newlabel)
1047{
1048 struct mac_biba *source, *dest;
1049
1050 source = SLOT(newlabel);
1051 dest = SLOT(socketlabel);
1052
1053 mac_biba_copy(source, dest);
1054}
1055
1056static void
1057mac_biba_relabel_pipe(struct ucred *cred, struct pipe *pipe,
1058 struct label *pipelabel, struct label *newlabel)
1059{
1060 struct mac_biba *source, *dest;
1061
1062 source = SLOT(newlabel);
1063 dest = SLOT(pipelabel);
1064
1065 mac_biba_copy(source, dest);
1066}
1067
1068static void
1069mac_biba_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel,
1070 struct socket *socket, struct label *socketpeerlabel)
1071{
1072 struct mac_biba *source, *dest;
1073
1074 source = SLOT(mbuflabel);
1075 dest = SLOT(socketpeerlabel);
1076
1077 mac_biba_copy_single(source, dest);
1078}
1079
1080/*
1081 * Labeling event operations: network objects.
1082 */
1083static void
1084mac_biba_set_socket_peer_from_socket(struct socket *oldsocket,
1085 struct label *oldsocketlabel, struct socket *newsocket,
1086 struct label *newsocketpeerlabel)
1087{
1088 struct mac_biba *source, *dest;
1089
1090 source = SLOT(oldsocketlabel);
1091 dest = SLOT(newsocketpeerlabel);
1092
1093 mac_biba_copy_single(source, dest);
1094}
1095
1096static void
1097mac_biba_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d,
1098 struct label *bpflabel)
1099{
1100 struct mac_biba *source, *dest;
1101
1102 source = SLOT(cred->cr_label);
1103 dest = SLOT(bpflabel);
1104
1105 mac_biba_copy_single(source, dest);
1106}
1107
1108static void
1109mac_biba_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel)
1110{
1111 char tifname[IFNAMSIZ], *p, *q;
1112 char tiflist[sizeof(trusted_interfaces)];
1113 struct mac_biba *dest;
1114 int len, type;
1115
1116 dest = SLOT(ifnetlabel);
1117
1118 if (ifnet->if_type == IFT_LOOP) {
1119 type = MAC_BIBA_TYPE_EQUAL;
1120 goto set;
1121 }
1122
1123 if (trust_all_interfaces) {
1124 type = MAC_BIBA_TYPE_HIGH;
1125 goto set;
1126 }
1127
1128 type = MAC_BIBA_TYPE_LOW;
1129
1130 if (trusted_interfaces[0] == '\0' ||
1131 !strvalid(trusted_interfaces, sizeof(trusted_interfaces)))
1132 goto set;
1133
1134 bzero(tiflist, sizeof(tiflist));
1135 for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++)
1136 if(*p != ' ' && *p != '\t')
1137 *q = *p;
1138
1139 for (p = q = tiflist;; p++) {
1140 if (*p == ',' || *p == '\0') {
1141 len = p - q;
1142 if (len < IFNAMSIZ) {
1143 bzero(tifname, sizeof(tifname));
1144 bcopy(q, tifname, len);
1145 if (strcmp(tifname, ifnet->if_xname) == 0) {
1146 type = MAC_BIBA_TYPE_HIGH;
1147 break;
1148 }
1149 } else {
1150 *p = '\0';
1151 printf("mac_biba warning: interface name "
1152 "\"%s\" is too long (must be < %d)\n",
1153 q, IFNAMSIZ);
1154 }
1155 if (*p == '\0')
1156 break;
1157 q = p + 1;
1158 }
1159 }
1160set:
1161 mac_biba_set_single(dest, type, 0, NULL);
1162 mac_biba_set_range(dest, type, 0, NULL, type, 0, NULL);
1163}
1164
1165static void
1166mac_biba_create_ipq(struct mbuf *fragment, struct label *fragmentlabel,
1167 struct ipq *ipq, struct label *ipqlabel)
1168{
1169 struct mac_biba *source, *dest;
1170
1171 source = SLOT(fragmentlabel);
1172 dest = SLOT(ipqlabel);
1173
1174 mac_biba_copy_single(source, dest);
1175}
1176
1177static void
1178mac_biba_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel,
1179 struct mbuf *datagram, struct label *datagramlabel)
1180{
1181 struct mac_biba *source, *dest;
1182
1183 source = SLOT(ipqlabel);
1184 dest = SLOT(datagramlabel);
1185
1186 /* Just use the head, since we require them all to match. */
1187 mac_biba_copy_single(source, dest);
1188}
1189
1190static void
1191mac_biba_create_fragment(struct mbuf *datagram, struct label *datagramlabel,
1192 struct mbuf *fragment, struct label *fragmentlabel)
1193{
1194 struct mac_biba *source, *dest;
1195
1196 source = SLOT(datagramlabel);
1197 dest = SLOT(fragmentlabel);
1198
1199 mac_biba_copy_single(source, dest);
1200}
1201
1202static void
1203mac_biba_create_mbuf_from_mbuf(struct mbuf *oldmbuf,
1204 struct label *oldmbuflabel, struct mbuf *newmbuf,
1205 struct label *newmbuflabel)
1206{
1207 struct mac_biba *source, *dest;
1208
1209 source = SLOT(oldmbuflabel);
1210 dest = SLOT(newmbuflabel);
1211
1212 /*
1213 * Because the source mbuf may not yet have been "created",
1214 * just initialized, we do a conditional copy. Since we don't
1215 * allow mbufs to have ranges, do a KASSERT to make sure that
1216 * doesn't happen.
1217 */
1218 KASSERT((source->mb_flags & MAC_BIBA_FLAG_RANGE) == 0,
1219 ("mac_biba_create_mbuf_from_mbuf: source mbuf has range"));
1220 mac_biba_copy(source, dest);
1221}
1222
1223static void
1224mac_biba_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel,
1225 struct mbuf *mbuf, struct label *mbuflabel)
1226{
1227 struct mac_biba *dest;
1228
1229 dest = SLOT(mbuflabel);
1230
1231 mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1232}
1233
1234static void
1235mac_biba_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel,
1236 struct mbuf *mbuf, struct label *mbuflabel)
1237{
1238 struct mac_biba *source, *dest;
1239
1240 source = SLOT(bpflabel);
1241 dest = SLOT(mbuflabel);
1242
1243 mac_biba_copy_single(source, dest);
1244}
1245
1246static void
1247mac_biba_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel,
1248 struct mbuf *m, struct label *mbuflabel)
1249{
1250 struct mac_biba *source, *dest;
1251
1252 source = SLOT(ifnetlabel);
1253 dest = SLOT(mbuflabel);
1254
1255 mac_biba_copy_single(source, dest);
1256}
1257
1258static void
1259mac_biba_create_mbuf_multicast_encap(struct mbuf *oldmbuf,
1260 struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel,
1261 struct mbuf *newmbuf, struct label *newmbuflabel)
1262{
1263 struct mac_biba *source, *dest;
1264
1265 source = SLOT(oldmbuflabel);
1266 dest = SLOT(newmbuflabel);
1267
1268 mac_biba_copy_single(source, dest);
1269}
1270
1271static void
1272mac_biba_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel,
1273 struct mbuf *newmbuf, struct label *newmbuflabel)
1274{
1275 struct mac_biba *source, *dest;
1276
1277 source = SLOT(oldmbuflabel);
1278 dest = SLOT(newmbuflabel);
1279
1280 mac_biba_copy_single(source, dest);
1281}
1282
1283static int
1284mac_biba_fragment_match(struct mbuf *fragment, struct label *fragmentlabel,
1285 struct ipq *ipq, struct label *ipqlabel)
1286{
1287 struct mac_biba *a, *b;
1288
1289 a = SLOT(ipqlabel);
1290 b = SLOT(fragmentlabel);
1291
1292 return (mac_biba_equal_single(a, b));
1293}
1294
1295static void
1296mac_biba_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet,
1297 struct label *ifnetlabel, struct label *newlabel)
1298{
1299 struct mac_biba *source, *dest;
1300
1301 source = SLOT(newlabel);
1302 dest = SLOT(ifnetlabel);
1303
1304 mac_biba_copy(source, dest);
1305}
1306
1307static void
1308mac_biba_update_ipq(struct mbuf *fragment, struct label *fragmentlabel,
1309 struct ipq *ipq, struct label *ipqlabel)
1310{
1311
1312 /* NOOP: we only accept matching labels, so no need to update */
1313}
1314
1315static void
1316mac_biba_inpcb_sosetlabel(struct socket *so, struct label *solabel,
1317 struct inpcb *inp, struct label *inplabel)
1318{
1319 struct mac_biba *source, *dest;
1320
1321 source = SLOT(solabel);
1322 dest = SLOT(inplabel);
1323
1324 mac_biba_copy(source, dest);
1325}
1326
1327/*
1328 * Labeling event operations: processes.
1329 */
1330static void
1331mac_biba_create_cred(struct ucred *cred_parent, struct ucred *cred_child)
1332{
1333 struct mac_biba *source, *dest;
1334
1335 source = SLOT(cred_parent->cr_label);
1336 dest = SLOT(cred_child->cr_label);
1337
1338 mac_biba_copy_single(source, dest);
1339 mac_biba_copy_range(source, dest);
1340}
1341
1342static void
1343mac_biba_create_proc0(struct ucred *cred)
1344{
1345 struct mac_biba *dest;
1346
1347 dest = SLOT(cred->cr_label);
1348
1349 mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1350 mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL,
1351 MAC_BIBA_TYPE_HIGH, 0, NULL);
1352}
1353
1354static void
1355mac_biba_create_proc1(struct ucred *cred)
1356{
1357 struct mac_biba *dest;
1358
1359 dest = SLOT(cred->cr_label);
1360
1361 mac_biba_set_single(dest, MAC_BIBA_TYPE_HIGH, 0, NULL);
1362 mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL,
1363 MAC_BIBA_TYPE_HIGH, 0, NULL);
1364}
1365
1366static void
1367mac_biba_relabel_cred(struct ucred *cred, struct label *newlabel)
1368{
1369 struct mac_biba *source, *dest;
1370
1371 source = SLOT(newlabel);
1372 dest = SLOT(cred->cr_label);
1373
1374 mac_biba_copy(source, dest);
1375}
1376
1377/*
1378 * Access control checks.
1379 */
1380static int
1381mac_biba_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel,
1382 struct ifnet *ifnet, struct label *ifnetlabel)
1383{
1384 struct mac_biba *a, *b;
1385
1386 if (!mac_biba_enabled)
1387 return (0);
1388
1389 a = SLOT(bpflabel);
1390 b = SLOT(ifnetlabel);
1391
1392 if (mac_biba_equal_single(a, b))
1393 return (0);
1394 return (EACCES);
1395}
1396
1397static int
1398mac_biba_check_cred_relabel(struct ucred *cred, struct label *newlabel)
1399{
1400 struct mac_biba *subj, *new;
1401 int error;
1402
1403 subj = SLOT(cred->cr_label);
1404 new = SLOT(newlabel);
1405
1406 /*
1407 * If there is a Biba label update for the credential, it may
1408 * be an update of the single, range, or both.
1409 */
1410 error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
1411 if (error)
1412 return (error);
1413
1414 /*
1415 * If the Biba label is to be changed, authorize as appropriate.
1416 */
1417 if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) {
1418 /*
1419 * If the change request modifies both the Biba label
1420 * single and range, check that the new single will be
1421 * in the new range.
1422 */
1423 if ((new->mb_flags & MAC_BIBA_FLAGS_BOTH) ==
1424 MAC_BIBA_FLAGS_BOTH &&
1425 !mac_biba_single_in_range(new, new))
1426 return (EINVAL);
1427
1428 /*
1429 * To change the Biba single label on a credential, the
1430 * new single label must be in the current range.
1431 */
1432 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE &&
1433 !mac_biba_single_in_range(new, subj))
1434 return (EPERM);
1435
1436 /*
1437 * To change the Biba range on a credential, the new
1438 * range label must be in the current range.
1439 */
1440 if (new->mb_flags & MAC_BIBA_FLAG_RANGE &&
1441 !mac_biba_range_in_range(new, subj))
1442 return (EPERM);
1443
1444 /*
1445 * To have EQUAL in any component of the new credential
1446 * Biba label, the subject must already have EQUAL in
1447 * their label.
1448 */
1449 if (mac_biba_contains_equal(new)) {
1450 error = mac_biba_subject_privileged(subj);
1451 if (error)
1452 return (error);
1453 }
1454 }
1455
1456 return (0);
1457}
1458
1459static int
1460mac_biba_check_cred_visible(struct ucred *u1, struct ucred *u2)
1461{
1462 struct mac_biba *subj, *obj;
1463
1464 if (!mac_biba_enabled)
1465 return (0);
1466
1467 subj = SLOT(u1->cr_label);
1468 obj = SLOT(u2->cr_label);
1469
1470 /* XXX: range */
1471 if (!mac_biba_dominate_single(obj, subj))
1472 return (ESRCH);
1473
1474 return (0);
1475}
1476
1477static int
1478mac_biba_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet,
1479 struct label *ifnetlabel, struct label *newlabel)
1480{
1481 struct mac_biba *subj, *new;
1482 int error;
1483
1484 subj = SLOT(cred->cr_label);
1485 new = SLOT(newlabel);
1486
1487 /*
1488 * If there is a Biba label update for the interface, it may
1489 * be an update of the single, range, or both.
1490 */
1491 error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
1492 if (error)
1493 return (error);
1494
1495 /*
1496 * Relabling network interfaces requires Biba privilege.
1497 */
1498 error = mac_biba_subject_privileged(subj);
1499 if (error)
1500 return (error);
1501
1502 return (0);
1503}
1504
1505static int
1506mac_biba_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel,
1507 struct mbuf *m, struct label *mbuflabel)
1508{
1509 struct mac_biba *p, *i;
1510
1511 if (!mac_biba_enabled)
1512 return (0);
1513
1514 p = SLOT(mbuflabel);
1515 i = SLOT(ifnetlabel);
1516
1517 return (mac_biba_single_in_range(p, i) ? 0 : EACCES);
1518}
1519
1520static int
1521mac_biba_check_inpcb_deliver(struct inpcb *inp, struct label *inplabel,
1522 struct mbuf *m, struct label *mlabel)
1523{
1524 struct mac_biba *p, *i;
1525
1526 if (!mac_biba_enabled)
1527 return (0);
1528
1529 p = SLOT(mlabel);
1530 i = SLOT(inplabel);
1531
1532 return (mac_biba_equal_single(p, i) ? 0 : EACCES);
1533}
1534
1535static int
1536mac_biba_check_kld_load(struct ucred *cred, struct vnode *vp,
1537 struct label *label)
1538{
1539 struct mac_biba *subj, *obj;
1540 int error;
1541
1542 if (!mac_biba_enabled)
1543 return (0);
1544
1545 subj = SLOT(cred->cr_label);
1546
1547 error = mac_biba_subject_privileged(subj);
1548 if (error)
1549 return (error);
1550
1551 obj = SLOT(label);
1552 if (!mac_biba_high_single(obj))
1553 return (EACCES);
1554
1555 return (0);
1556}
1557
1558
1559static int
1560mac_biba_check_kld_unload(struct ucred *cred)
1561{
1562 struct mac_biba *subj;
1563
1564 if (!mac_biba_enabled)
1565 return (0);
1566
1567 subj = SLOT(cred->cr_label);
1568
1569 return (mac_biba_subject_privileged(subj));
1570}
1571
1572static int
1573mac_biba_check_mount_stat(struct ucred *cred, struct mount *mp,
1574 struct label *mntlabel)
1575{
1576 struct mac_biba *subj, *obj;
1577
1578 if (!mac_biba_enabled)
1579 return (0);
1580
1581 subj = SLOT(cred->cr_label);
1582 obj = SLOT(mntlabel);
1583
1584 if (!mac_biba_dominate_single(obj, subj))
1585 return (EACCES);
1586
1587 return (0);
1588}
1589
1590static int
1591mac_biba_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe,
1592 struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data)
1593{
1594
1595 if(!mac_biba_enabled)
1596 return (0);
1597
1598 /* XXX: This will be implemented soon... */
1599
1600 return (0);
1601}
1602
1603static int
1604mac_biba_check_pipe_poll(struct ucred *cred, struct pipe *pipe,
1605 struct label *pipelabel)
1606{
1607 struct mac_biba *subj, *obj;
1608
1609 if (!mac_biba_enabled)
1610 return (0);
1611
1612 subj = SLOT(cred->cr_label);
1613 obj = SLOT((pipelabel));
1614
1615 if (!mac_biba_dominate_single(obj, subj))
1616 return (EACCES);
1617
1618 return (0);
1619}
1620
1621static int
1622mac_biba_check_pipe_read(struct ucred *cred, struct pipe *pipe,
1623 struct label *pipelabel)
1624{
1625 struct mac_biba *subj, *obj;
1626
1627 if (!mac_biba_enabled)
1628 return (0);
1629
1630 subj = SLOT(cred->cr_label);
1631 obj = SLOT((pipelabel));
1632
1633 if (!mac_biba_dominate_single(obj, subj))
1634 return (EACCES);
1635
1636 return (0);
1637}
1638
1639static int
1640mac_biba_check_pipe_relabel(struct ucred *cred, struct pipe *pipe,
1641 struct label *pipelabel, struct label *newlabel)
1642{
1643 struct mac_biba *subj, *obj, *new;
1644 int error;
1645
1646 new = SLOT(newlabel);
1647 subj = SLOT(cred->cr_label);
1648 obj = SLOT(pipelabel);
1649
1650 /*
1651 * If there is a Biba label update for a pipe, it must be a
1652 * single update.
1653 */
1654 error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE);
1655 if (error)
1656 return (error);
1657
1658 /*
1659 * To perform a relabel of a pipe (Biba label or not), Biba must
1660 * authorize the relabel.
1661 */
1662 if (!mac_biba_single_in_range(obj, subj))
1663 return (EPERM);
1664
1665 /*
1666 * If the Biba label is to be changed, authorize as appropriate.
1667 */
1668 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) {
1669 /*
1670 * To change the Biba label on a pipe, the new pipe label
1671 * must be in the subject range.
1672 */
1673 if (!mac_biba_single_in_range(new, subj))
1674 return (EPERM);
1675
1676 /*
1677 * To change the Biba label on a pipe to be EQUAL, the
1678 * subject must have appropriate privilege.
1679 */
1680 if (mac_biba_contains_equal(new)) {
1681 error = mac_biba_subject_privileged(subj);
1682 if (error)
1683 return (error);
1684 }
1685 }
1686
1687 return (0);
1688}
1689
1690static int
1691mac_biba_check_pipe_stat(struct ucred *cred, struct pipe *pipe,
1692 struct label *pipelabel)
1693{
1694 struct mac_biba *subj, *obj;
1695
1696 if (!mac_biba_enabled)
1697 return (0);
1698
1699 subj = SLOT(cred->cr_label);
1700 obj = SLOT((pipelabel));
1701
1702 if (!mac_biba_dominate_single(obj, subj))
1703 return (EACCES);
1704
1705 return (0);
1706}
1707
1708static int
1709mac_biba_check_pipe_write(struct ucred *cred, struct pipe *pipe,
1710 struct label *pipelabel)
1711{
1712 struct mac_biba *subj, *obj;
1713
1714 if (!mac_biba_enabled)
1715 return (0);
1716
1717 subj = SLOT(cred->cr_label);
1718 obj = SLOT((pipelabel));
1719
1720 if (!mac_biba_dominate_single(subj, obj))
1721 return (EACCES);
1722
1723 return (0);
1724}
1725
1726static int
1727mac_biba_check_proc_debug(struct ucred *cred, struct proc *proc)
1728{
1729 struct mac_biba *subj, *obj;
1730
1731 if (!mac_biba_enabled)
1732 return (0);
1733
1734 subj = SLOT(cred->cr_label);
1735 obj = SLOT(proc->p_ucred->cr_label);
1736
1737 /* XXX: range checks */
1738 if (!mac_biba_dominate_single(obj, subj))
1739 return (ESRCH);
1740 if (!mac_biba_dominate_single(subj, obj))
1741 return (EACCES);
1742
1743 return (0);
1744}
1745
1746static int
1747mac_biba_check_proc_sched(struct ucred *cred, struct proc *proc)
1748{
1749 struct mac_biba *subj, *obj;
1750
1751 if (!mac_biba_enabled)
1752 return (0);
1753
1754 subj = SLOT(cred->cr_label);
1755 obj = SLOT(proc->p_ucred->cr_label);
1756
1757 /* XXX: range checks */
1758 if (!mac_biba_dominate_single(obj, subj))
1759 return (ESRCH);
1760 if (!mac_biba_dominate_single(subj, obj))
1761 return (EACCES);
1762
1763 return (0);
1764}
1765
1766static int
1767mac_biba_check_proc_signal(struct ucred *cred, struct proc *proc, int signum)
1768{
1769 struct mac_biba *subj, *obj;
1770
1771 if (!mac_biba_enabled)
1772 return (0);
1773
1774 subj = SLOT(cred->cr_label);
1775 obj = SLOT(proc->p_ucred->cr_label);
1776
1777 /* XXX: range checks */
1778 if (!mac_biba_dominate_single(obj, subj))
1779 return (ESRCH);
1780 if (!mac_biba_dominate_single(subj, obj))
1781 return (EACCES);
1782
1783 return (0);
1784}
1785
1786static int
1787mac_biba_check_socket_deliver(struct socket *so, struct label *socketlabel,
1788 struct mbuf *m, struct label *mbuflabel)
1789{
1790 struct mac_biba *p, *s;
1791
1792 if (!mac_biba_enabled)
1793 return (0);
1794
1795 p = SLOT(mbuflabel);
1796 s = SLOT(socketlabel);
1797
1798 return (mac_biba_equal_single(p, s) ? 0 : EACCES);
1799}
1800
1801static int
1802mac_biba_check_socket_relabel(struct ucred *cred, struct socket *so,
1803 struct label *socketlabel, struct label *newlabel)
1804{
1805 struct mac_biba *subj, *obj, *new;
1806 int error;
1807
1808 new = SLOT(newlabel);
1809 subj = SLOT(cred->cr_label);
1810 obj = SLOT(socketlabel);
1811
1812 /*
1813 * If there is a Biba label update for the socket, it may be
1814 * an update of single.
1815 */
1816 error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE);
1817 if (error)
1818 return (error);
1819
1820 /*
1821 * To relabel a socket, the old socket single must be in the subject
1822 * range.
1823 */
1824 if (!mac_biba_single_in_range(obj, subj))
1825 return (EPERM);
1826
1827 /*
1828 * If the Biba label is to be changed, authorize as appropriate.
1829 */
1830 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) {
1831 /*
1832 * To relabel a socket, the new socket single must be in
1833 * the subject range.
1834 */
1835 if (!mac_biba_single_in_range(new, subj))
1836 return (EPERM);
1837
1838 /*
1839 * To change the Biba label on the socket to contain EQUAL,
1840 * the subject must have appropriate privilege.
1841 */
1842 if (mac_biba_contains_equal(new)) {
1843 error = mac_biba_subject_privileged(subj);
1844 if (error)
1845 return (error);
1846 }
1847 }
1848
1849 return (0);
1850}
1851
1852static int
1853mac_biba_check_socket_visible(struct ucred *cred, struct socket *socket,
1854 struct label *socketlabel)
1855{
1856 struct mac_biba *subj, *obj;
1857
1858 if (!mac_biba_enabled)
1859 return (0);
1860
1861 subj = SLOT(cred->cr_label);
1862 obj = SLOT(socketlabel);
1863
1864 if (!mac_biba_dominate_single(obj, subj))
1865 return (ENOENT);
1866
1867 return (0);
1868}
1869
1870static int
1871mac_biba_check_sysarch_ioperm(struct ucred *cred)
1872{
1873 struct mac_biba *subj;
1874 int error;
1875
1876 if (!mac_biba_enabled)
1877 return (0);
1878
1879 subj = SLOT(cred->cr_label);
1880
1881 error = mac_biba_subject_privileged(subj);
1882 if (error)
1883 return (error);
1884
1885 return (0);
1886}
1887
1888static int
1889mac_biba_check_system_acct(struct ucred *cred, struct vnode *vp,
1890 struct label *label)
1891{
1892 struct mac_biba *subj, *obj;
1893 int error;
1894
1895 if (!mac_biba_enabled)
1896 return (0);
1897
1898 subj = SLOT(cred->cr_label);
1899
1900 error = mac_biba_subject_privileged(subj);
1901 if (error)
1902 return (error);
1903
1904 if (label == NULL)
1905 return (0);
1906
1907 obj = SLOT(label);
1908 if (!mac_biba_high_single(obj))
1909 return (EACCES);
1910
1911 return (0);
1912}
1913
1914static int
1915mac_biba_check_system_settime(struct ucred *cred)
1916{
1917 struct mac_biba *subj;
1918 int error;
1919
1920 if (!mac_biba_enabled)
1921 return (0);
1922
1923 subj = SLOT(cred->cr_label);
1924
1925 error = mac_biba_subject_privileged(subj);
1926 if (error)
1927 return (error);
1928
1929 return (0);
1930}
1931
1932static int
1933mac_biba_check_system_swapon(struct ucred *cred, struct vnode *vp,
1934 struct label *label)
1935{
1936 struct mac_biba *subj, *obj;
1937 int error;
1938
1939 if (!mac_biba_enabled)
1940 return (0);
1941
1942 subj = SLOT(cred->cr_label);
1943 obj = SLOT(label);
1944
1945 error = mac_biba_subject_privileged(subj);
1946 if (error)
1947 return (error);
1948
1949 if (!mac_biba_high_single(obj))
1950 return (EACCES);
1951
1952 return (0);
1953}
1954
1955static int
1956mac_biba_check_system_swapoff(struct ucred *cred, struct vnode *vp,
1957 struct label *label)
1958{
1959 struct mac_biba *subj, *obj;
1960 int error;
1961
1962 if (!mac_biba_enabled)
1963 return (0);
1964
1965 subj = SLOT(cred->cr_label);
1966 obj = SLOT(label);
1967
1968 error = mac_biba_subject_privileged(subj);
1969 if (error)
1970 return (error);
1971
1972 return (0);
1973}
1974
1975static int
1976mac_biba_check_system_sysctl(struct ucred *cred, int *name, u_int namelen,
1977 void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen)
1978{
1979 struct mac_biba *subj;
1980 int error;
1981
1982 if (!mac_biba_enabled)
1983 return (0);
1984
1985 subj = SLOT(cred->cr_label);
1986
1987 /*
1988 * In general, treat sysctl variables as biba/high, but also
1989 * require privilege to change them, since they are a
1990 * communications channel between grades. Exempt MIB
1991 * queries from this due to undocmented sysctl magic.
1992 * XXXMAC: This probably requires some more review.
1993 */
1994 if (new != NULL) {
1995 if (namelen > 0 && name[0] == 0)
1996 return (0);
1997
1998 if (!mac_biba_subject_dominate_high(subj))
1999 return (EACCES);
2000
2001 error = mac_biba_subject_privileged(subj);
2002 if (error)
2003 return (error);
2004 }
2005
2006 return (0);
2007}
2008
2009static int
2010mac_biba_check_vnode_chdir(struct ucred *cred, struct vnode *dvp,
2011 struct label *dlabel)
2012{
2013 struct mac_biba *subj, *obj;
2014
2015 if (!mac_biba_enabled)
2016 return (0);
2017
2018 subj = SLOT(cred->cr_label);
2019 obj = SLOT(dlabel);
2020
2021 if (!mac_biba_dominate_single(obj, subj))
2022 return (EACCES);
2023
2024 return (0);
2025}
2026
2027static int
2028mac_biba_check_vnode_chroot(struct ucred *cred, struct vnode *dvp,
2029 struct label *dlabel)
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(dlabel);
2038
2039 if (!mac_biba_dominate_single(obj, subj))
2040 return (EACCES);
2041
2042 return (0);
2043}
2044
2045static int
2046mac_biba_check_vnode_create(struct ucred *cred, struct vnode *dvp,
2047 struct label *dlabel, struct componentname *cnp, struct vattr *vap)
2048{
2049 struct mac_biba *subj, *obj;
2050
2051 if (!mac_biba_enabled)
2052 return (0);
2053
2054 subj = SLOT(cred->cr_label);
2055 obj = SLOT(dlabel);
2056
2057 if (!mac_biba_dominate_single(subj, obj))
2058 return (EACCES);
2059
2060 return (0);
2061}
2062
2063static int
2064mac_biba_check_vnode_delete(struct ucred *cred, struct vnode *dvp,
2065 struct label *dlabel, struct vnode *vp, struct label *label,
2066 struct componentname *cnp)
2067{
2068 struct mac_biba *subj, *obj;
2069
2070 if (!mac_biba_enabled)
2071 return (0);
2072
2073 subj = SLOT(cred->cr_label);
2074 obj = SLOT(dlabel);
2075
2076 if (!mac_biba_dominate_single(subj, obj))
2077 return (EACCES);
2078
2079 obj = SLOT(label);
2080
2081 if (!mac_biba_dominate_single(subj, obj))
2082 return (EACCES);
2083
2084 return (0);
2085}
2086
2087static int
2088mac_biba_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
2089 struct label *label, acl_type_t type)
2090{
2091 struct mac_biba *subj, *obj;
2092
2093 if (!mac_biba_enabled)
2094 return (0);
2095
2096 subj = SLOT(cred->cr_label);
2097 obj = SLOT(label);
2098
2099 if (!mac_biba_dominate_single(subj, obj))
2100 return (EACCES);
2101
2102 return (0);
2103}
2104
2105static int
2106mac_biba_check_vnode_deleteextattr(struct ucred *cred, struct vnode *vp,
2107 struct label *label, int attrnamespace, const char *name)
2108{
2109 struct mac_biba *subj, *obj;
2110
2111 if (!mac_biba_enabled)
2112 return (0);
2113
2114 subj = SLOT(cred->cr_label);
2115 obj = SLOT(label);
2116
2117 if (!mac_biba_dominate_single(subj, obj))
2118 return (EACCES);
2119
2120 return (0);
2121}
2122
2123static int
2124mac_biba_check_vnode_exec(struct ucred *cred, struct vnode *vp,
2125 struct label *label, struct image_params *imgp,
2126 struct label *execlabel)
2127{
2128 struct mac_biba *subj, *obj, *exec;
2129 int error;
2130
2131 if (execlabel != NULL) {
2132 /*
2133 * We currently don't permit labels to be changed at
2134 * exec-time as part of Biba, so disallow non-NULL
2135 * Biba label elements in the execlabel.
2136 */
2137 exec = SLOT(execlabel);
2138 error = biba_atmostflags(exec, 0);
2139 if (error)
2140 return (error);
2141 }
2142
2143 if (!mac_biba_enabled)
2144 return (0);
2145
2146 subj = SLOT(cred->cr_label);
2147 obj = SLOT(label);
2148
2149 if (!mac_biba_dominate_single(obj, subj))
2150 return (EACCES);
2151
2152 return (0);
2153}
2154
2155static int
2156mac_biba_check_vnode_getacl(struct ucred *cred, struct vnode *vp,
2157 struct label *label, acl_type_t type)
2158{
2159 struct mac_biba *subj, *obj;
2160
2161 if (!mac_biba_enabled)
2162 return (0);
2163
2164 subj = SLOT(cred->cr_label);
2165 obj = SLOT(label);
2166
2167 if (!mac_biba_dominate_single(obj, subj))
2168 return (EACCES);
2169
2170 return (0);
2171}
2172
2173static int
2174mac_biba_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
2175 struct label *label, int attrnamespace, const char *name, struct uio *uio)
2176{
2177 struct mac_biba *subj, *obj;
2178
2179 if (!mac_biba_enabled)
2180 return (0);
2181
2182 subj = SLOT(cred->cr_label);
2183 obj = SLOT(label);
2184
2185 if (!mac_biba_dominate_single(obj, subj))
2186 return (EACCES);
2187
2188 return (0);
2189}
2190
2191static int
2192mac_biba_check_vnode_link(struct ucred *cred, struct vnode *dvp,
2193 struct label *dlabel, struct vnode *vp, struct label *label,
2194 struct componentname *cnp)
2195{
2196 struct mac_biba *subj, *obj;
2197
2198 if (!mac_biba_enabled)
2199 return (0);
2200
2201 subj = SLOT(cred->cr_label);
2202 obj = SLOT(dlabel);
2203
2204 if (!mac_biba_dominate_single(subj, obj))
2205 return (EACCES);
2206
2207 obj = SLOT(label);
2208
2209 if (!mac_biba_dominate_single(subj, obj))
2210 return (EACCES);
2211
2212 return (0);
2213}
2214
2215static int
2216mac_biba_check_vnode_listextattr(struct ucred *cred, struct vnode *vp,
2217 struct label *label, int attrnamespace)
2218{
2219 struct mac_biba *subj, *obj;
2220
2221 if (!mac_biba_enabled)
2222 return (0);
2223
2224 subj = SLOT(cred->cr_label);
2225 obj = SLOT(label);
2226
2227 if (!mac_biba_dominate_single(obj, subj))
2228 return (EACCES);
2229
2230 return (0);
2231}
2232
2233static int
2234mac_biba_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
2235 struct label *dlabel, struct componentname *cnp)
2236{
2237 struct mac_biba *subj, *obj;
2238
2239 if (!mac_biba_enabled)
2240 return (0);
2241
2242 subj = SLOT(cred->cr_label);
2243 obj = SLOT(dlabel);
2244
2245 if (!mac_biba_dominate_single(obj, subj))
2246 return (EACCES);
2247
2248 return (0);
2249}
2250
2251static int
2252mac_biba_check_vnode_mmap(struct ucred *cred, struct vnode *vp,
2253 struct label *label, int prot)
2254{
2255 struct mac_biba *subj, *obj;
2256
2257 /*
2258 * Rely on the use of open()-time protections to handle
2259 * non-revocation cases.
2260 */
2261 if (!mac_biba_enabled || !revocation_enabled)
2262 return (0);
2263
2264 subj = SLOT(cred->cr_label);
2265 obj = SLOT(label);
2266
2267 if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
2268 if (!mac_biba_dominate_single(obj, subj))
2269 return (EACCES);
2270 }
2271 if (prot & VM_PROT_WRITE) {
2272 if (!mac_biba_dominate_single(subj, obj))
2273 return (EACCES);
2274 }
2275
2276 return (0);
2277}
2278
2279static int
2280mac_biba_check_vnode_open(struct ucred *cred, struct vnode *vp,
2281 struct label *vnodelabel, int acc_mode)
2282{
2283 struct mac_biba *subj, *obj;
2284
2285 if (!mac_biba_enabled)
2286 return (0);
2287
2288 subj = SLOT(cred->cr_label);
2289 obj = SLOT(vnodelabel);
2290
2291 /* XXX privilege override for admin? */
2292 if (acc_mode & (VREAD | VEXEC | VSTAT)) {
2293 if (!mac_biba_dominate_single(obj, subj))
2294 return (EACCES);
2295 }
2296 if (acc_mode & (VWRITE | VAPPEND | VADMIN)) {
2297 if (!mac_biba_dominate_single(subj, obj))
2298 return (EACCES);
2299 }
2300
2301 return (0);
2302}
2303
2304static int
2305mac_biba_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred,
2306 struct vnode *vp, struct label *label)
2307{
2308 struct mac_biba *subj, *obj;
2309
2310 if (!mac_biba_enabled || !revocation_enabled)
2311 return (0);
2312
2313 subj = SLOT(active_cred->cr_label);
2314 obj = SLOT(label);
2315
2316 if (!mac_biba_dominate_single(obj, subj))
2317 return (EACCES);
2318
2319 return (0);
2320}
2321
2322static int
2323mac_biba_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
2324 struct vnode *vp, struct label *label)
2325{
2326 struct mac_biba *subj, *obj;
2327
2328 if (!mac_biba_enabled || !revocation_enabled)
2329 return (0);
2330
2331 subj = SLOT(active_cred->cr_label);
2332 obj = SLOT(label);
2333
2334 if (!mac_biba_dominate_single(obj, subj))
2335 return (EACCES);
2336
2337 return (0);
2338}
2339
2340static int
2341mac_biba_check_vnode_readdir(struct ucred *cred, struct vnode *dvp,
2342 struct label *dlabel)
2343{
2344 struct mac_biba *subj, *obj;
2345
2346 if (!mac_biba_enabled)
2347 return (0);
2348
2349 subj = SLOT(cred->cr_label);
2350 obj = SLOT(dlabel);
2351
2352 if (!mac_biba_dominate_single(obj, subj))
2353 return (EACCES);
2354
2355 return (0);
2356}
2357
2358static int
2359mac_biba_check_vnode_readlink(struct ucred *cred, struct vnode *vp,
2360 struct label *label)
2361{
2362 struct mac_biba *subj, *obj;
2363
2364 if (!mac_biba_enabled)
2365 return (0);
2366
2367 subj = SLOT(cred->cr_label);
2368 obj = SLOT(label);
2369
2370 if (!mac_biba_dominate_single(obj, subj))
2371 return (EACCES);
2372
2373 return (0);
2374}
2375
2376static int
2377mac_biba_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
2378 struct label *vnodelabel, struct label *newlabel)
2379{
2380 struct mac_biba *old, *new, *subj;
2381 int error;
2382
2383 old = SLOT(vnodelabel);
2384 new = SLOT(newlabel);
2385 subj = SLOT(cred->cr_label);
2386
2387 /*
2388 * If there is a Biba label update for the vnode, it must be a
2389 * single label.
2390 */
2391 error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE);
2392 if (error)
2393 return (error);
2394
2395 /*
2396 * To perform a relabel of the vnode (Biba label or not), Biba must
2397 * authorize the relabel.
2398 */
2399 if (!mac_biba_single_in_range(old, subj))
2400 return (EPERM);
2401
2402 /*
2403 * If the Biba label is to be changed, authorize as appropriate.
2404 */
2405 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) {
2406 /*
2407 * To change the Biba label on a vnode, the new vnode label
2408 * must be in the subject range.
2409 */
2410 if (!mac_biba_single_in_range(new, subj))
2411 return (EPERM);
2412
2413 /*
2414 * To change the Biba label on the vnode to be EQUAL,
2415 * the subject must have appropriate privilege.
2416 */
2417 if (mac_biba_contains_equal(new)) {
2418 error = mac_biba_subject_privileged(subj);
2419 if (error)
2420 return (error);
2421 }
2422 }
2423
2424 return (0);
2425}
2426
2427static int
2428mac_biba_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
2429 struct label *dlabel, struct vnode *vp, struct label *label,
2430 struct componentname *cnp)
2431{
2432 struct mac_biba *subj, *obj;
2433
2434 if (!mac_biba_enabled)
2435 return (0);
2436
2437 subj = SLOT(cred->cr_label);
2438 obj = SLOT(dlabel);
2439
2440 if (!mac_biba_dominate_single(subj, obj))
2441 return (EACCES);
2442
2443 obj = SLOT(label);
2444
2445 if (!mac_biba_dominate_single(subj, obj))
2446 return (EACCES);
2447
2448 return (0);
2449}
2450
2451static int
2452mac_biba_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
2453 struct label *dlabel, struct vnode *vp, struct label *label, int samedir,
2454 struct componentname *cnp)
2455{
2456 struct mac_biba *subj, *obj;
2457
2458 if (!mac_biba_enabled)
2459 return (0);
2460
2461 subj = SLOT(cred->cr_label);
2462 obj = SLOT(dlabel);
2463
2464 if (!mac_biba_dominate_single(subj, obj))
2465 return (EACCES);
2466
2467 if (vp != NULL) {
2468 obj = SLOT(label);
2469
2470 if (!mac_biba_dominate_single(subj, obj))
2471 return (EACCES);
2472 }
2473
2474 return (0);
2475}
2476
2477static int
2478mac_biba_check_vnode_revoke(struct ucred *cred, struct vnode *vp,
2479 struct label *label)
2480{
2481 struct mac_biba *subj, *obj;
2482
2483 if (!mac_biba_enabled)
2484 return (0);
2485
2486 subj = SLOT(cred->cr_label);
2487 obj = SLOT(label);
2488
2489 if (!mac_biba_dominate_single(subj, obj))
2490 return (EACCES);
2491
2492 return (0);
2493}
2494
2495static int
2496mac_biba_check_vnode_setacl(struct ucred *cred, struct vnode *vp,
2497 struct label *label, acl_type_t type, struct acl *acl)
2498{
2499 struct mac_biba *subj, *obj;
2500
2501 if (!mac_biba_enabled)
2502 return (0);
2503
2504 subj = SLOT(cred->cr_label);
2505 obj = SLOT(label);
2506
2507 if (!mac_biba_dominate_single(subj, obj))
2508 return (EACCES);
2509
2510 return (0);
2511}
2512
2513static int
2514mac_biba_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
2515 struct label *vnodelabel, int attrnamespace, const char *name,
2516 struct uio *uio)
2517{
2518 struct mac_biba *subj, *obj;
2519
2520 if (!mac_biba_enabled)
2521 return (0);
2522
2523 subj = SLOT(cred->cr_label);
2524 obj = SLOT(vnodelabel);
2525
2526 if (!mac_biba_dominate_single(subj, obj))
2527 return (EACCES);
2528
2529 /* XXX: protect the MAC EA in a special way? */
2530
2531 return (0);
2532}
2533
2534static int
2535mac_biba_check_vnode_setflags(struct ucred *cred, struct vnode *vp,
2536 struct label *vnodelabel, u_long flags)
2537{
2538 struct mac_biba *subj, *obj;
2539
2540 if (!mac_biba_enabled)
2541 return (0);
2542
2543 subj = SLOT(cred->cr_label);
2544 obj = SLOT(vnodelabel);
2545
2546 if (!mac_biba_dominate_single(subj, obj))
2547 return (EACCES);
2548
2549 return (0);
2550}
2551
2552static int
2553mac_biba_check_vnode_setmode(struct ucred *cred, struct vnode *vp,
2554 struct label *vnodelabel, mode_t mode)
2555{
2556 struct mac_biba *subj, *obj;
2557
2558 if (!mac_biba_enabled)
2559 return (0);
2560
2561 subj = SLOT(cred->cr_label);
2562 obj = SLOT(vnodelabel);
2563
2564 if (!mac_biba_dominate_single(subj, obj))
2565 return (EACCES);
2566
2567 return (0);
2568}
2569
2570static int
2571mac_biba_check_vnode_setowner(struct ucred *cred, struct vnode *vp,
2572 struct label *vnodelabel, uid_t uid, gid_t gid)
2573{
2574 struct mac_biba *subj, *obj;
2575
2576 if (!mac_biba_enabled)
2577 return (0);
2578
2579 subj = SLOT(cred->cr_label);
2580 obj = SLOT(vnodelabel);
2581
2582 if (!mac_biba_dominate_single(subj, obj))
2583 return (EACCES);
2584
2585 return (0);
2586}
2587
2588static int
2589mac_biba_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
2590 struct label *vnodelabel, struct timespec atime, struct timespec mtime)
2591{
2592 struct mac_biba *subj, *obj;
2593
2594 if (!mac_biba_enabled)
2595 return (0);
2596
2597 subj = SLOT(cred->cr_label);
2598 obj = SLOT(vnodelabel);
2599
2600 if (!mac_biba_dominate_single(subj, obj))
2601 return (EACCES);
2602
2603 return (0);
2604}
2605
2606static int
2607mac_biba_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
2608 struct vnode *vp, struct label *vnodelabel)
2609{
2610 struct mac_biba *subj, *obj;
2611
2612 if (!mac_biba_enabled)
2613 return (0);
2614
2615 subj = SLOT(active_cred->cr_label);
2616 obj = SLOT(vnodelabel);
2617
2618 if (!mac_biba_dominate_single(obj, subj))
2619 return (EACCES);
2620
2621 return (0);
2622}
2623
2624static int
2625mac_biba_check_vnode_write(struct ucred *active_cred,
2626 struct ucred *file_cred, struct vnode *vp, struct label *label)
2627{
2628 struct mac_biba *subj, *obj;
2629
2630 if (!mac_biba_enabled || !revocation_enabled)
2631 return (0);
2632
2633 subj = SLOT(active_cred->cr_label);
2634 obj = SLOT(label);
2635
2636 if (!mac_biba_dominate_single(subj, obj))
2637 return (EACCES);
2638
2639 return (0);
2640}
2641
2642static struct mac_policy_ops mac_biba_ops =
2643{
2644 .mpo_init = mac_biba_init,
2645 .mpo_init_bpfdesc_label = mac_biba_init_label,
2646 .mpo_init_cred_label = mac_biba_init_label,
2647 .mpo_init_devfsdirent_label = mac_biba_init_label,
2648 .mpo_init_ifnet_label = mac_biba_init_label,
2649 .mpo_init_inpcb_label = mac_biba_init_label_waitcheck,
2650 .mpo_init_ipq_label = mac_biba_init_label_waitcheck,
2651 .mpo_init_mbuf_label = mac_biba_init_label_waitcheck,
2652 .mpo_init_mount_label = mac_biba_init_label,
2653 .mpo_init_mount_fs_label = mac_biba_init_label,
2654 .mpo_init_pipe_label = mac_biba_init_label,
2655 .mpo_init_socket_label = mac_biba_init_label_waitcheck,
2656 .mpo_init_socket_peer_label = mac_biba_init_label_waitcheck,
2657 .mpo_init_vnode_label = mac_biba_init_label,
2658 .mpo_destroy_bpfdesc_label = mac_biba_destroy_label,
2659 .mpo_destroy_cred_label = mac_biba_destroy_label,
2660 .mpo_destroy_devfsdirent_label = mac_biba_destroy_label,
2661 .mpo_destroy_ifnet_label = mac_biba_destroy_label,
2662 .mpo_destroy_inpcb_label = mac_biba_destroy_label,
2663 .mpo_destroy_ipq_label = mac_biba_destroy_label,
2664 .mpo_destroy_mbuf_label = mac_biba_destroy_label,
2665 .mpo_destroy_mount_label = mac_biba_destroy_label,
2666 .mpo_destroy_mount_fs_label = mac_biba_destroy_label,
2667 .mpo_destroy_pipe_label = mac_biba_destroy_label,
2668 .mpo_destroy_socket_label = mac_biba_destroy_label,
2669 .mpo_destroy_socket_peer_label = mac_biba_destroy_label,
2670 .mpo_destroy_vnode_label = mac_biba_destroy_label,
2671 .mpo_copy_mbuf_label = mac_biba_copy_label,
2672 .mpo_copy_pipe_label = mac_biba_copy_label,
2673 .mpo_copy_socket_label = mac_biba_copy_label,
2674 .mpo_copy_vnode_label = mac_biba_copy_label,
2675 .mpo_externalize_cred_label = mac_biba_externalize_label,
2676 .mpo_externalize_ifnet_label = mac_biba_externalize_label,
2677 .mpo_externalize_pipe_label = mac_biba_externalize_label,
2678 .mpo_externalize_socket_label = mac_biba_externalize_label,
2679 .mpo_externalize_socket_peer_label = mac_biba_externalize_label,
2680 .mpo_externalize_vnode_label = mac_biba_externalize_label,
2681 .mpo_internalize_cred_label = mac_biba_internalize_label,
2682 .mpo_internalize_ifnet_label = mac_biba_internalize_label,
2683 .mpo_internalize_pipe_label = mac_biba_internalize_label,
2684 .mpo_internalize_socket_label = mac_biba_internalize_label,
2685 .mpo_internalize_vnode_label = mac_biba_internalize_label,
2686 .mpo_create_devfs_device = mac_biba_create_devfs_device,
2687 .mpo_create_devfs_directory = mac_biba_create_devfs_directory,
2688 .mpo_create_devfs_symlink = mac_biba_create_devfs_symlink,
2689 .mpo_create_mount = mac_biba_create_mount,
2690 .mpo_create_root_mount = mac_biba_create_root_mount,
2691 .mpo_relabel_vnode = mac_biba_relabel_vnode,
2692 .mpo_update_devfsdirent = mac_biba_update_devfsdirent,
2693 .mpo_associate_vnode_devfs = mac_biba_associate_vnode_devfs,
2694 .mpo_associate_vnode_extattr = mac_biba_associate_vnode_extattr,
2695 .mpo_associate_vnode_singlelabel = mac_biba_associate_vnode_singlelabel,
2696 .mpo_create_vnode_extattr = mac_biba_create_vnode_extattr,
2697 .mpo_setlabel_vnode_extattr = mac_biba_setlabel_vnode_extattr,
2698 .mpo_create_mbuf_from_socket = mac_biba_create_mbuf_from_socket,
2699 .mpo_create_pipe = mac_biba_create_pipe,
2700 .mpo_create_socket = mac_biba_create_socket,
2701 .mpo_create_socket_from_socket = mac_biba_create_socket_from_socket,
2702 .mpo_relabel_pipe = mac_biba_relabel_pipe,
2703 .mpo_relabel_socket = mac_biba_relabel_socket,
2704 .mpo_set_socket_peer_from_mbuf = mac_biba_set_socket_peer_from_mbuf,
2705 .mpo_set_socket_peer_from_socket = mac_biba_set_socket_peer_from_socket,
2706 .mpo_create_bpfdesc = mac_biba_create_bpfdesc,
2707 .mpo_create_datagram_from_ipq = mac_biba_create_datagram_from_ipq,
2708 .mpo_create_fragment = mac_biba_create_fragment,
2709 .mpo_create_ifnet = mac_biba_create_ifnet,
2710 .mpo_create_inpcb_from_socket = mac_biba_create_inpcb_from_socket,
2711 .mpo_create_ipq = mac_biba_create_ipq,
2712 .mpo_create_mbuf_from_mbuf = mac_biba_create_mbuf_from_mbuf,
2713 .mpo_create_mbuf_linklayer = mac_biba_create_mbuf_linklayer,
2714 .mpo_create_mbuf_from_bpfdesc = mac_biba_create_mbuf_from_bpfdesc,
2715 .mpo_create_mbuf_from_ifnet = mac_biba_create_mbuf_from_ifnet,
2716 .mpo_create_mbuf_multicast_encap = mac_biba_create_mbuf_multicast_encap,
2717 .mpo_create_mbuf_netlayer = mac_biba_create_mbuf_netlayer,
2718 .mpo_fragment_match = mac_biba_fragment_match,
2719 .mpo_relabel_ifnet = mac_biba_relabel_ifnet,
2720 .mpo_update_ipq = mac_biba_update_ipq,
2721 .mpo_inpcb_sosetlabel = mac_biba_inpcb_sosetlabel,
2722 .mpo_create_cred = mac_biba_create_cred,
2723 .mpo_create_proc0 = mac_biba_create_proc0,
2724 .mpo_create_proc1 = mac_biba_create_proc1,
2725 .mpo_relabel_cred = mac_biba_relabel_cred,
2726 .mpo_check_bpfdesc_receive = mac_biba_check_bpfdesc_receive,
2727 .mpo_check_cred_relabel = mac_biba_check_cred_relabel,
2728 .mpo_check_cred_visible = mac_biba_check_cred_visible,
2729 .mpo_check_ifnet_relabel = mac_biba_check_ifnet_relabel,
2730 .mpo_check_ifnet_transmit = mac_biba_check_ifnet_transmit,
2731 .mpo_check_inpcb_deliver = mac_biba_check_inpcb_deliver,
2732 .mpo_check_kld_load = mac_biba_check_kld_load,
2733 .mpo_check_kld_unload = mac_biba_check_kld_unload,
2734 .mpo_check_mount_stat = mac_biba_check_mount_stat,
2735 .mpo_check_pipe_ioctl = mac_biba_check_pipe_ioctl,
2736 .mpo_check_pipe_poll = mac_biba_check_pipe_poll,
2737 .mpo_check_pipe_read = mac_biba_check_pipe_read,
2738 .mpo_check_pipe_relabel = mac_biba_check_pipe_relabel,
2739 .mpo_check_pipe_stat = mac_biba_check_pipe_stat,
2740 .mpo_check_pipe_write = mac_biba_check_pipe_write,
2741 .mpo_check_proc_debug = mac_biba_check_proc_debug,
2742 .mpo_check_proc_sched = mac_biba_check_proc_sched,
2743 .mpo_check_proc_signal = mac_biba_check_proc_signal,
2744 .mpo_check_socket_deliver = mac_biba_check_socket_deliver,
2745 .mpo_check_socket_relabel = mac_biba_check_socket_relabel,
2746 .mpo_check_socket_visible = mac_biba_check_socket_visible,
2747 .mpo_check_sysarch_ioperm = mac_biba_check_sysarch_ioperm,
2748 .mpo_check_system_acct = mac_biba_check_system_acct,
2749 .mpo_check_system_settime = mac_biba_check_system_settime,
2750 .mpo_check_system_swapon = mac_biba_check_system_swapon,
2751 .mpo_check_system_swapoff = mac_biba_check_system_swapoff,
2752 .mpo_check_system_sysctl = mac_biba_check_system_sysctl,
2753 .mpo_check_vnode_access = mac_biba_check_vnode_open,
2754 .mpo_check_vnode_chdir = mac_biba_check_vnode_chdir,
2755 .mpo_check_vnode_chroot = mac_biba_check_vnode_chroot,
2756 .mpo_check_vnode_create = mac_biba_check_vnode_create,
2757 .mpo_check_vnode_delete = mac_biba_check_vnode_delete,
2758 .mpo_check_vnode_deleteacl = mac_biba_check_vnode_deleteacl,
2759 .mpo_check_vnode_deleteextattr = mac_biba_check_vnode_deleteextattr,
2760 .mpo_check_vnode_exec = mac_biba_check_vnode_exec,
2761 .mpo_check_vnode_getacl = mac_biba_check_vnode_getacl,
2762 .mpo_check_vnode_getextattr = mac_biba_check_vnode_getextattr,
2763 .mpo_check_vnode_link = mac_biba_check_vnode_link,
2764 .mpo_check_vnode_listextattr = mac_biba_check_vnode_listextattr,
2765 .mpo_check_vnode_lookup = mac_biba_check_vnode_lookup,
2766 .mpo_check_vnode_mmap = mac_biba_check_vnode_mmap,
2767 .mpo_check_vnode_mprotect = mac_biba_check_vnode_mmap,
2768 .mpo_check_vnode_open = mac_biba_check_vnode_open,
2769 .mpo_check_vnode_poll = mac_biba_check_vnode_poll,
2770 .mpo_check_vnode_read = mac_biba_check_vnode_read,
2771 .mpo_check_vnode_readdir = mac_biba_check_vnode_readdir,
2772 .mpo_check_vnode_readlink = mac_biba_check_vnode_readlink,
2773 .mpo_check_vnode_relabel = mac_biba_check_vnode_relabel,
2774 .mpo_check_vnode_rename_from = mac_biba_check_vnode_rename_from,
2775 .mpo_check_vnode_rename_to = mac_biba_check_vnode_rename_to,
2776 .mpo_check_vnode_revoke = mac_biba_check_vnode_revoke,
2777 .mpo_check_vnode_setacl = mac_biba_check_vnode_setacl,
2778 .mpo_check_vnode_setextattr = mac_biba_check_vnode_setextattr,
2779 .mpo_check_vnode_setflags = mac_biba_check_vnode_setflags,
2780 .mpo_check_vnode_setmode = mac_biba_check_vnode_setmode,
2781 .mpo_check_vnode_setowner = mac_biba_check_vnode_setowner,
2782 .mpo_check_vnode_setutimes = mac_biba_check_vnode_setutimes,
2783 .mpo_check_vnode_stat = mac_biba_check_vnode_stat,
2784 .mpo_check_vnode_write = mac_biba_check_vnode_write,
2785};
2786
2787MAC_POLICY_SET(&mac_biba_ops, mac_biba, "TrustedBSD MAC/Biba",
2788 MPC_LOADTIME_FLAG_NOTLATE | MPC_LOADTIME_FLAG_LABELMBUFS, &mac_biba_slot);