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