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