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