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