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