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