Deleted Added
full compact
mac_biba.c (106217) mac_biba.c (106354)
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 106217 2002-10-30 18:48:51Z rwatson $
37 * $FreeBSD: head/sys/security/mac_biba/mac_biba.c 106354 2002-11-02 20:16:35Z mux $
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_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_privileged(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_privileged: 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
340static int
341mac_biba_high_single(struct mac_biba *mac_biba)
342{
343
344 KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
345 ("mac_biba_equal_single: mac_biba not single"));
346
347 return (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_HIGH);
348}
349
350static int
351mac_biba_valid(struct mac_biba *mac_biba)
352{
353
354 if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) {
355 switch (mac_biba->mb_single.mbe_type) {
356 case MAC_BIBA_TYPE_GRADE:
357 break;
358
359 case MAC_BIBA_TYPE_EQUAL:
360 case MAC_BIBA_TYPE_HIGH:
361 case MAC_BIBA_TYPE_LOW:
362 if (mac_biba->mb_single.mbe_grade != 0 ||
363 !MAC_BIBA_BIT_SET_EMPTY(
364 mac_biba->mb_single.mbe_compartments))
365 return (EINVAL);
366 break;
367
368 default:
369 return (EINVAL);
370 }
371 } else {
372 if (mac_biba->mb_single.mbe_type != MAC_BIBA_TYPE_UNDEF)
373 return (EINVAL);
374 }
375
376 if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
377 switch (mac_biba->mb_rangelow.mbe_type) {
378 case MAC_BIBA_TYPE_GRADE:
379 break;
380
381 case MAC_BIBA_TYPE_EQUAL:
382 case MAC_BIBA_TYPE_HIGH:
383 case MAC_BIBA_TYPE_LOW:
384 if (mac_biba->mb_rangelow.mbe_grade != 0 ||
385 !MAC_BIBA_BIT_SET_EMPTY(
386 mac_biba->mb_rangelow.mbe_compartments))
387 return (EINVAL);
388 break;
389
390 default:
391 return (EINVAL);
392 }
393
394 switch (mac_biba->mb_rangehigh.mbe_type) {
395 case MAC_BIBA_TYPE_GRADE:
396 break;
397
398 case MAC_BIBA_TYPE_EQUAL:
399 case MAC_BIBA_TYPE_HIGH:
400 case MAC_BIBA_TYPE_LOW:
401 if (mac_biba->mb_rangehigh.mbe_grade != 0 ||
402 !MAC_BIBA_BIT_SET_EMPTY(
403 mac_biba->mb_rangehigh.mbe_compartments))
404 return (EINVAL);
405 break;
406
407 default:
408 return (EINVAL);
409 }
410 if (!mac_biba_dominate_element(&mac_biba->mb_rangehigh,
411 &mac_biba->mb_rangelow))
412 return (EINVAL);
413 } else {
414 if (mac_biba->mb_rangelow.mbe_type != MAC_BIBA_TYPE_UNDEF ||
415 mac_biba->mb_rangehigh.mbe_type != MAC_BIBA_TYPE_UNDEF)
416 return (EINVAL);
417 }
418
419 return (0);
420}
421
422static void
423mac_biba_set_range(struct mac_biba *mac_biba, u_short typelow,
424 u_short gradelow, u_char *compartmentslow, u_short typehigh,
425 u_short gradehigh, u_char *compartmentshigh)
426{
427
428 mac_biba->mb_rangelow.mbe_type = typelow;
429 mac_biba->mb_rangelow.mbe_grade = gradelow;
430 if (compartmentslow != NULL)
431 memcpy(mac_biba->mb_rangelow.mbe_compartments,
432 compartmentslow,
433 sizeof(mac_biba->mb_rangelow.mbe_compartments));
434 mac_biba->mb_rangehigh.mbe_type = typehigh;
435 mac_biba->mb_rangehigh.mbe_grade = gradehigh;
436 if (compartmentshigh != NULL)
437 memcpy(mac_biba->mb_rangehigh.mbe_compartments,
438 compartmentshigh,
439 sizeof(mac_biba->mb_rangehigh.mbe_compartments));
440 mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE;
441}
442
443static void
444mac_biba_set_single(struct mac_biba *mac_biba, u_short type, u_short grade,
445 u_char *compartments)
446{
447
448 mac_biba->mb_single.mbe_type = type;
449 mac_biba->mb_single.mbe_grade = grade;
450 if (compartments != NULL)
451 memcpy(mac_biba->mb_single.mbe_compartments, compartments,
452 sizeof(mac_biba->mb_single.mbe_compartments));
453 mac_biba->mb_flags |= MAC_BIBA_FLAG_SINGLE;
454}
455
456static void
457mac_biba_copy_range(struct mac_biba *labelfrom, struct mac_biba *labelto)
458{
459
460 KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_RANGE) != 0,
461 ("mac_biba_copy_range: labelfrom not range"));
462
463 labelto->mb_rangelow = labelfrom->mb_rangelow;
464 labelto->mb_rangehigh = labelfrom->mb_rangehigh;
465 labelto->mb_flags |= MAC_BIBA_FLAG_RANGE;
466}
467
468static void
469mac_biba_copy_single(struct mac_biba *labelfrom, struct mac_biba *labelto)
470{
471
472 KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
473 ("mac_biba_copy_single: labelfrom not single"));
474
475 labelto->mb_single = labelfrom->mb_single;
476 labelto->mb_flags |= MAC_BIBA_FLAG_SINGLE;
477}
478
479static void
480mac_biba_copy(struct mac_biba *source, struct mac_biba *dest)
481{
482
483 if (source->mb_flags & MAC_BIBA_FLAG_SINGLE)
484 mac_biba_copy_single(source, dest);
485 if (source->mb_flags & MAC_BIBA_FLAG_RANGE)
486 mac_biba_copy_range(source, dest);
487}
488
489/*
490 * Policy module operations.
491 */
492static void
493mac_biba_destroy(struct mac_policy_conf *conf)
494{
495
496}
497
498static void
499mac_biba_init(struct mac_policy_conf *conf)
500{
501
502}
503
504/*
505 * Label operations.
506 */
507static void
508mac_biba_init_label(struct label *label)
509{
510
511 SLOT(label) = biba_alloc(M_WAITOK);
512}
513
514static int
515mac_biba_init_label_waitcheck(struct label *label, int flag)
516{
517
518 SLOT(label) = biba_alloc(flag);
519 if (SLOT(label) == NULL)
520 return (ENOMEM);
521
522 return (0);
523}
524
525static void
526mac_biba_destroy_label(struct label *label)
527{
528
529 biba_free(SLOT(label));
530 SLOT(label) = NULL;
531}
532
533/*
534 * mac_biba_element_to_string() is basically an snprintf wrapper with
535 * the same properties as snprintf(). It returns the length it would
536 * have added to the string in the event the string is too short.
537 */
538static size_t
539mac_biba_element_to_string(char *string, size_t size,
540 struct mac_biba_element *element)
541{
542 int pos, bit = 1;
543
544 switch (element->mbe_type) {
545 case MAC_BIBA_TYPE_HIGH:
546 return (snprintf(string, size, "high"));
547
548 case MAC_BIBA_TYPE_LOW:
549 return (snprintf(string, size, "low"));
550
551 case MAC_BIBA_TYPE_EQUAL:
552 return (snprintf(string, size, "equal"));
553
554 case MAC_BIBA_TYPE_GRADE:
555 pos = snprintf(string, size, "%d:", element->mbe_grade);
556 for (bit = 1; bit <= MAC_BIBA_MAX_COMPARTMENTS; bit++) {
557 if (MAC_BIBA_BIT_TEST(bit, element->mbe_compartments))
558 pos += snprintf(string + pos, size - pos,
559 "%d+", bit);
560 }
561 if (string[pos - 1] == '+' || string[pos - 1] == ':')
562 string[--pos] = '\0';
563 return (pos);
564
565 default:
566 panic("mac_biba_element_to_string: invalid type (%d)",
567 element->mbe_type);
568 }
569}
570
571static int
572mac_biba_to_string(char *string, size_t size, size_t *caller_len,
573 struct mac_biba *mac_biba)
574{
575 size_t left, len;
576 char *curptr;
577
578 bzero(string, size);
579 curptr = string;
580 left = size;
581
582 if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) {
583 len = mac_biba_element_to_string(curptr, left,
584 &mac_biba->mb_single);
585 if (len >= left)
586 return (EINVAL);
587 left -= len;
588 curptr += len;
589 }
590
591 if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
592 len = snprintf(curptr, left, "(");
593 if (len >= left)
594 return (EINVAL);
595 left -= len;
596 curptr += len;
597
598 len = mac_biba_element_to_string(curptr, left,
599 &mac_biba->mb_rangelow);
600 if (len >= left)
601 return (EINVAL);
602 left -= len;
603 curptr += len;
604
605 len = snprintf(curptr, left, "-");
606 if (len >= left)
607 return (EINVAL);
608 left -= len;
609 curptr += len;
610
611 len = mac_biba_element_to_string(curptr, left,
612 &mac_biba->mb_rangehigh);
613 if (len >= left)
614 return (EINVAL);
615 left -= len;
616 curptr += len;
617
618 len = snprintf(curptr, left, ")");
619 if (len >= left)
620 return (EINVAL);
621 left -= len;
622 curptr += len;
623 }
624
625 *caller_len = strlen(string);
626 return (0);
627}
628
629static int
630mac_biba_externalize_label(struct label *label, char *element_name,
631 char *element_data, size_t size, size_t *len, int *claimed)
632{
633 struct mac_biba *mac_biba;
634 int error;
635
636 if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0)
637 return (0);
638
639 (*claimed)++;
640
641 mac_biba = SLOT(label);
642 error = mac_biba_to_string(element_data, size, len, mac_biba);
643 if (error)
644 return (error);
645
646 *len = strlen(element_data);
647 return (0);
648}
649
650static int
651mac_biba_parse_element(struct mac_biba_element *element, char *string)
652{
653
654 if (strcmp(string, "high") == 0 ||
655 strcmp(string, "hi") == 0) {
656 element->mbe_type = MAC_BIBA_TYPE_HIGH;
657 element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
658 } else if (strcmp(string, "low") == 0 ||
659 strcmp(string, "lo") == 0) {
660 element->mbe_type = MAC_BIBA_TYPE_LOW;
661 element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
662 } else if (strcmp(string, "equal") == 0 ||
663 strcmp(string, "eq") == 0) {
664 element->mbe_type = MAC_BIBA_TYPE_EQUAL;
665 element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
666 } else {
667 char *p0, *p1;
668 int d;
669
670 p0 = string;
671 d = strtol(p0, &p1, 10);
672
673 if (d < 0 || d > 65535)
674 return (EINVAL);
675 element->mbe_type = MAC_BIBA_TYPE_GRADE;
676 element->mbe_grade = d;
677
678 if (*p1 != ':') {
679 if (p1 == p0 || *p1 != '\0')
680 return (EINVAL);
681 else
682 return (0);
683 }
684 else
685 if (*(p1 + 1) == '\0')
686 return (0);
687
688 while ((p0 = ++p1)) {
689 d = strtol(p0, &p1, 10);
690 if (d < 1 || d > MAC_BIBA_MAX_COMPARTMENTS)
691 return (EINVAL);
692
693 MAC_BIBA_BIT_SET(d, element->mbe_compartments);
694
695 if (*p1 == '\0')
696 break;
697 if (p1 == p0 || *p1 != '+')
698 return (EINVAL);
699 }
700 }
701
702 return (0);
703}
704
705/*
706 * Note: destructively consumes the string, make a local copy before
707 * calling if that's a problem.
708 */
709static int
710mac_biba_parse(struct mac_biba *mac_biba, char *string)
711{
712 char *range, *rangeend, *rangehigh, *rangelow, *single;
713 int error;
714
715 /* Do we have a range? */
716 single = string;
717 range = index(string, '(');
718 if (range == single)
719 single = NULL;
720 rangelow = rangehigh = NULL;
721 if (range != NULL) {
722 /* Nul terminate the end of the single string. */
723 *range = '\0';
724 range++;
725 rangelow = range;
726 rangehigh = index(rangelow, '-');
727 if (rangehigh == NULL)
728 return (EINVAL);
729 rangehigh++;
730 if (*rangelow == '\0' || *rangehigh == '\0')
731 return (EINVAL);
732 rangeend = index(rangehigh, ')');
733 if (rangeend == NULL)
734 return (EINVAL);
735 if (*(rangeend + 1) != '\0')
736 return (EINVAL);
737 /* Nul terminate the ends of the ranges. */
738 *(rangehigh - 1) = '\0';
739 *rangeend = '\0';
740 }
741 KASSERT((rangelow != NULL && rangehigh != NULL) ||
742 (rangelow == NULL && rangehigh == NULL),
743 ("mac_biba_internalize_label: range mismatch"));
744
745 bzero(mac_biba, sizeof(*mac_biba));
746 if (single != NULL) {
747 error = mac_biba_parse_element(&mac_biba->mb_single, single);
748 if (error)
749 return (error);
750 mac_biba->mb_flags |= MAC_BIBA_FLAG_SINGLE;
751 }
752
753 if (rangelow != NULL) {
754 error = mac_biba_parse_element(&mac_biba->mb_rangelow,
755 rangelow);
756 if (error)
757 return (error);
758 error = mac_biba_parse_element(&mac_biba->mb_rangehigh,
759 rangehigh);
760 if (error)
761 return (error);
762 mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE;
763 }
764
765 error = mac_biba_valid(mac_biba);
766 if (error)
767 return (error);
768
769 return (0);
770}
771
772static int
773mac_biba_internalize_label(struct label *label, char *element_name,
774 char *element_data, int *claimed)
775{
776 struct mac_biba *mac_biba, mac_biba_temp;
777 int error;
778
779 if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0)
780 return (0);
781
782 (*claimed)++;
783
784 error = mac_biba_parse(&mac_biba_temp, element_data);
785 if (error)
786 return (error);
787
788 mac_biba = SLOT(label);
789 *mac_biba = mac_biba_temp;
790
791 return (0);
792}
793
794static void
795mac_biba_copy_label(struct label *src, struct label *dest)
796{
797
798 *SLOT(dest) = *SLOT(src);
799}
800
801/*
802 * Labeling event operations: file system objects, and things that look
803 * a lot like file system objects.
804 */
805static void
806mac_biba_create_devfs_device(dev_t dev, struct devfs_dirent *devfs_dirent,
807 struct label *label)
808{
809 struct mac_biba *mac_biba;
810 int biba_type;
811
812 mac_biba = SLOT(label);
813 if (strcmp(dev->si_name, "null") == 0 ||
814 strcmp(dev->si_name, "zero") == 0 ||
815 strcmp(dev->si_name, "random") == 0 ||
816 strncmp(dev->si_name, "fd/", strlen("fd/")) == 0)
817 biba_type = MAC_BIBA_TYPE_EQUAL;
818 else if (ptys_equal &&
819 (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 ||
820 strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0))
821 biba_type = MAC_BIBA_TYPE_EQUAL;
822 else
823 biba_type = MAC_BIBA_TYPE_HIGH;
824 mac_biba_set_single(mac_biba, biba_type, 0, NULL);
825}
826
827static void
828mac_biba_create_devfs_directory(char *dirname, int dirnamelen,
829 struct devfs_dirent *devfs_dirent, struct label *label)
830{
831 struct mac_biba *mac_biba;
832
833 mac_biba = SLOT(label);
834 mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
835}
836
837static void
838mac_biba_create_devfs_symlink(struct ucred *cred, struct devfs_dirent *dd,
839 struct label *ddlabel, struct devfs_dirent *de, struct label *delabel)
840{
841 struct mac_biba *source, *dest;
842
843 source = SLOT(&cred->cr_label);
844 dest = SLOT(delabel);
845
846 mac_biba_copy_single(source, dest);
847}
848
849static void
850mac_biba_create_devfs_vnode(struct devfs_dirent *devfs_dirent,
851 struct label *direntlabel, struct vnode *vp, struct label *vnodelabel)
852{
853 struct mac_biba *source, *dest;
854
855 source = SLOT(direntlabel);
856 dest = SLOT(vnodelabel);
857 mac_biba_copy_single(source, dest);
858}
859
860static void
861mac_biba_create_mount(struct ucred *cred, struct mount *mp,
862 struct label *mntlabel, struct label *fslabel)
863{
864 struct mac_biba *source, *dest;
865
866 source = SLOT(&cred->cr_label);
867 dest = SLOT(mntlabel);
868 mac_biba_copy_single(source, dest);
869 dest = SLOT(fslabel);
870 mac_biba_copy_single(source, dest);
871}
872
873static void
874mac_biba_create_root_mount(struct ucred *cred, struct mount *mp,
875 struct label *mntlabel, struct label *fslabel)
876{
877 struct mac_biba *mac_biba;
878
879 /* Always mount root as high integrity. */
880 mac_biba = SLOT(fslabel);
881 mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
882 mac_biba = SLOT(mntlabel);
883 mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
884}
885
886static void
887mac_biba_relabel_vnode(struct ucred *cred, struct vnode *vp,
888 struct label *vnodelabel, struct label *label)
889{
890 struct mac_biba *source, *dest;
891
892 source = SLOT(label);
893 dest = SLOT(vnodelabel);
894
895 mac_biba_copy(source, dest);
896}
897
898static void
899mac_biba_update_devfsdirent(struct devfs_dirent *devfs_dirent,
900 struct label *direntlabel, struct vnode *vp, struct label *vnodelabel)
901{
902 struct mac_biba *source, *dest;
903
904 source = SLOT(vnodelabel);
905 dest = SLOT(direntlabel);
906
907 mac_biba_copy(source, dest);
908}
909
910static void
911mac_biba_associate_vnode_devfs(struct mount *mp, struct label *fslabel,
912 struct devfs_dirent *de, struct label *delabel, struct vnode *vp,
913 struct label *vlabel)
914{
915 struct mac_biba *source, *dest;
916
917 source = SLOT(delabel);
918 dest = SLOT(vlabel);
919
920 mac_biba_copy_single(source, dest);
921}
922
923static int
924mac_biba_associate_vnode_extattr(struct mount *mp, struct label *fslabel,
925 struct vnode *vp, struct label *vlabel)
926{
927 struct mac_biba temp, *source, *dest;
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_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_privileged(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_privileged: 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
340static int
341mac_biba_high_single(struct mac_biba *mac_biba)
342{
343
344 KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
345 ("mac_biba_equal_single: mac_biba not single"));
346
347 return (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_HIGH);
348}
349
350static int
351mac_biba_valid(struct mac_biba *mac_biba)
352{
353
354 if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) {
355 switch (mac_biba->mb_single.mbe_type) {
356 case MAC_BIBA_TYPE_GRADE:
357 break;
358
359 case MAC_BIBA_TYPE_EQUAL:
360 case MAC_BIBA_TYPE_HIGH:
361 case MAC_BIBA_TYPE_LOW:
362 if (mac_biba->mb_single.mbe_grade != 0 ||
363 !MAC_BIBA_BIT_SET_EMPTY(
364 mac_biba->mb_single.mbe_compartments))
365 return (EINVAL);
366 break;
367
368 default:
369 return (EINVAL);
370 }
371 } else {
372 if (mac_biba->mb_single.mbe_type != MAC_BIBA_TYPE_UNDEF)
373 return (EINVAL);
374 }
375
376 if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
377 switch (mac_biba->mb_rangelow.mbe_type) {
378 case MAC_BIBA_TYPE_GRADE:
379 break;
380
381 case MAC_BIBA_TYPE_EQUAL:
382 case MAC_BIBA_TYPE_HIGH:
383 case MAC_BIBA_TYPE_LOW:
384 if (mac_biba->mb_rangelow.mbe_grade != 0 ||
385 !MAC_BIBA_BIT_SET_EMPTY(
386 mac_biba->mb_rangelow.mbe_compartments))
387 return (EINVAL);
388 break;
389
390 default:
391 return (EINVAL);
392 }
393
394 switch (mac_biba->mb_rangehigh.mbe_type) {
395 case MAC_BIBA_TYPE_GRADE:
396 break;
397
398 case MAC_BIBA_TYPE_EQUAL:
399 case MAC_BIBA_TYPE_HIGH:
400 case MAC_BIBA_TYPE_LOW:
401 if (mac_biba->mb_rangehigh.mbe_grade != 0 ||
402 !MAC_BIBA_BIT_SET_EMPTY(
403 mac_biba->mb_rangehigh.mbe_compartments))
404 return (EINVAL);
405 break;
406
407 default:
408 return (EINVAL);
409 }
410 if (!mac_biba_dominate_element(&mac_biba->mb_rangehigh,
411 &mac_biba->mb_rangelow))
412 return (EINVAL);
413 } else {
414 if (mac_biba->mb_rangelow.mbe_type != MAC_BIBA_TYPE_UNDEF ||
415 mac_biba->mb_rangehigh.mbe_type != MAC_BIBA_TYPE_UNDEF)
416 return (EINVAL);
417 }
418
419 return (0);
420}
421
422static void
423mac_biba_set_range(struct mac_biba *mac_biba, u_short typelow,
424 u_short gradelow, u_char *compartmentslow, u_short typehigh,
425 u_short gradehigh, u_char *compartmentshigh)
426{
427
428 mac_biba->mb_rangelow.mbe_type = typelow;
429 mac_biba->mb_rangelow.mbe_grade = gradelow;
430 if (compartmentslow != NULL)
431 memcpy(mac_biba->mb_rangelow.mbe_compartments,
432 compartmentslow,
433 sizeof(mac_biba->mb_rangelow.mbe_compartments));
434 mac_biba->mb_rangehigh.mbe_type = typehigh;
435 mac_biba->mb_rangehigh.mbe_grade = gradehigh;
436 if (compartmentshigh != NULL)
437 memcpy(mac_biba->mb_rangehigh.mbe_compartments,
438 compartmentshigh,
439 sizeof(mac_biba->mb_rangehigh.mbe_compartments));
440 mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE;
441}
442
443static void
444mac_biba_set_single(struct mac_biba *mac_biba, u_short type, u_short grade,
445 u_char *compartments)
446{
447
448 mac_biba->mb_single.mbe_type = type;
449 mac_biba->mb_single.mbe_grade = grade;
450 if (compartments != NULL)
451 memcpy(mac_biba->mb_single.mbe_compartments, compartments,
452 sizeof(mac_biba->mb_single.mbe_compartments));
453 mac_biba->mb_flags |= MAC_BIBA_FLAG_SINGLE;
454}
455
456static void
457mac_biba_copy_range(struct mac_biba *labelfrom, struct mac_biba *labelto)
458{
459
460 KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_RANGE) != 0,
461 ("mac_biba_copy_range: labelfrom not range"));
462
463 labelto->mb_rangelow = labelfrom->mb_rangelow;
464 labelto->mb_rangehigh = labelfrom->mb_rangehigh;
465 labelto->mb_flags |= MAC_BIBA_FLAG_RANGE;
466}
467
468static void
469mac_biba_copy_single(struct mac_biba *labelfrom, struct mac_biba *labelto)
470{
471
472 KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
473 ("mac_biba_copy_single: labelfrom not single"));
474
475 labelto->mb_single = labelfrom->mb_single;
476 labelto->mb_flags |= MAC_BIBA_FLAG_SINGLE;
477}
478
479static void
480mac_biba_copy(struct mac_biba *source, struct mac_biba *dest)
481{
482
483 if (source->mb_flags & MAC_BIBA_FLAG_SINGLE)
484 mac_biba_copy_single(source, dest);
485 if (source->mb_flags & MAC_BIBA_FLAG_RANGE)
486 mac_biba_copy_range(source, dest);
487}
488
489/*
490 * Policy module operations.
491 */
492static void
493mac_biba_destroy(struct mac_policy_conf *conf)
494{
495
496}
497
498static void
499mac_biba_init(struct mac_policy_conf *conf)
500{
501
502}
503
504/*
505 * Label operations.
506 */
507static void
508mac_biba_init_label(struct label *label)
509{
510
511 SLOT(label) = biba_alloc(M_WAITOK);
512}
513
514static int
515mac_biba_init_label_waitcheck(struct label *label, int flag)
516{
517
518 SLOT(label) = biba_alloc(flag);
519 if (SLOT(label) == NULL)
520 return (ENOMEM);
521
522 return (0);
523}
524
525static void
526mac_biba_destroy_label(struct label *label)
527{
528
529 biba_free(SLOT(label));
530 SLOT(label) = NULL;
531}
532
533/*
534 * mac_biba_element_to_string() is basically an snprintf wrapper with
535 * the same properties as snprintf(). It returns the length it would
536 * have added to the string in the event the string is too short.
537 */
538static size_t
539mac_biba_element_to_string(char *string, size_t size,
540 struct mac_biba_element *element)
541{
542 int pos, bit = 1;
543
544 switch (element->mbe_type) {
545 case MAC_BIBA_TYPE_HIGH:
546 return (snprintf(string, size, "high"));
547
548 case MAC_BIBA_TYPE_LOW:
549 return (snprintf(string, size, "low"));
550
551 case MAC_BIBA_TYPE_EQUAL:
552 return (snprintf(string, size, "equal"));
553
554 case MAC_BIBA_TYPE_GRADE:
555 pos = snprintf(string, size, "%d:", element->mbe_grade);
556 for (bit = 1; bit <= MAC_BIBA_MAX_COMPARTMENTS; bit++) {
557 if (MAC_BIBA_BIT_TEST(bit, element->mbe_compartments))
558 pos += snprintf(string + pos, size - pos,
559 "%d+", bit);
560 }
561 if (string[pos - 1] == '+' || string[pos - 1] == ':')
562 string[--pos] = '\0';
563 return (pos);
564
565 default:
566 panic("mac_biba_element_to_string: invalid type (%d)",
567 element->mbe_type);
568 }
569}
570
571static int
572mac_biba_to_string(char *string, size_t size, size_t *caller_len,
573 struct mac_biba *mac_biba)
574{
575 size_t left, len;
576 char *curptr;
577
578 bzero(string, size);
579 curptr = string;
580 left = size;
581
582 if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) {
583 len = mac_biba_element_to_string(curptr, left,
584 &mac_biba->mb_single);
585 if (len >= left)
586 return (EINVAL);
587 left -= len;
588 curptr += len;
589 }
590
591 if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
592 len = snprintf(curptr, left, "(");
593 if (len >= left)
594 return (EINVAL);
595 left -= len;
596 curptr += len;
597
598 len = mac_biba_element_to_string(curptr, left,
599 &mac_biba->mb_rangelow);
600 if (len >= left)
601 return (EINVAL);
602 left -= len;
603 curptr += len;
604
605 len = snprintf(curptr, left, "-");
606 if (len >= left)
607 return (EINVAL);
608 left -= len;
609 curptr += len;
610
611 len = mac_biba_element_to_string(curptr, left,
612 &mac_biba->mb_rangehigh);
613 if (len >= left)
614 return (EINVAL);
615 left -= len;
616 curptr += len;
617
618 len = snprintf(curptr, left, ")");
619 if (len >= left)
620 return (EINVAL);
621 left -= len;
622 curptr += len;
623 }
624
625 *caller_len = strlen(string);
626 return (0);
627}
628
629static int
630mac_biba_externalize_label(struct label *label, char *element_name,
631 char *element_data, size_t size, size_t *len, int *claimed)
632{
633 struct mac_biba *mac_biba;
634 int error;
635
636 if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0)
637 return (0);
638
639 (*claimed)++;
640
641 mac_biba = SLOT(label);
642 error = mac_biba_to_string(element_data, size, len, mac_biba);
643 if (error)
644 return (error);
645
646 *len = strlen(element_data);
647 return (0);
648}
649
650static int
651mac_biba_parse_element(struct mac_biba_element *element, char *string)
652{
653
654 if (strcmp(string, "high") == 0 ||
655 strcmp(string, "hi") == 0) {
656 element->mbe_type = MAC_BIBA_TYPE_HIGH;
657 element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
658 } else if (strcmp(string, "low") == 0 ||
659 strcmp(string, "lo") == 0) {
660 element->mbe_type = MAC_BIBA_TYPE_LOW;
661 element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
662 } else if (strcmp(string, "equal") == 0 ||
663 strcmp(string, "eq") == 0) {
664 element->mbe_type = MAC_BIBA_TYPE_EQUAL;
665 element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
666 } else {
667 char *p0, *p1;
668 int d;
669
670 p0 = string;
671 d = strtol(p0, &p1, 10);
672
673 if (d < 0 || d > 65535)
674 return (EINVAL);
675 element->mbe_type = MAC_BIBA_TYPE_GRADE;
676 element->mbe_grade = d;
677
678 if (*p1 != ':') {
679 if (p1 == p0 || *p1 != '\0')
680 return (EINVAL);
681 else
682 return (0);
683 }
684 else
685 if (*(p1 + 1) == '\0')
686 return (0);
687
688 while ((p0 = ++p1)) {
689 d = strtol(p0, &p1, 10);
690 if (d < 1 || d > MAC_BIBA_MAX_COMPARTMENTS)
691 return (EINVAL);
692
693 MAC_BIBA_BIT_SET(d, element->mbe_compartments);
694
695 if (*p1 == '\0')
696 break;
697 if (p1 == p0 || *p1 != '+')
698 return (EINVAL);
699 }
700 }
701
702 return (0);
703}
704
705/*
706 * Note: destructively consumes the string, make a local copy before
707 * calling if that's a problem.
708 */
709static int
710mac_biba_parse(struct mac_biba *mac_biba, char *string)
711{
712 char *range, *rangeend, *rangehigh, *rangelow, *single;
713 int error;
714
715 /* Do we have a range? */
716 single = string;
717 range = index(string, '(');
718 if (range == single)
719 single = NULL;
720 rangelow = rangehigh = NULL;
721 if (range != NULL) {
722 /* Nul terminate the end of the single string. */
723 *range = '\0';
724 range++;
725 rangelow = range;
726 rangehigh = index(rangelow, '-');
727 if (rangehigh == NULL)
728 return (EINVAL);
729 rangehigh++;
730 if (*rangelow == '\0' || *rangehigh == '\0')
731 return (EINVAL);
732 rangeend = index(rangehigh, ')');
733 if (rangeend == NULL)
734 return (EINVAL);
735 if (*(rangeend + 1) != '\0')
736 return (EINVAL);
737 /* Nul terminate the ends of the ranges. */
738 *(rangehigh - 1) = '\0';
739 *rangeend = '\0';
740 }
741 KASSERT((rangelow != NULL && rangehigh != NULL) ||
742 (rangelow == NULL && rangehigh == NULL),
743 ("mac_biba_internalize_label: range mismatch"));
744
745 bzero(mac_biba, sizeof(*mac_biba));
746 if (single != NULL) {
747 error = mac_biba_parse_element(&mac_biba->mb_single, single);
748 if (error)
749 return (error);
750 mac_biba->mb_flags |= MAC_BIBA_FLAG_SINGLE;
751 }
752
753 if (rangelow != NULL) {
754 error = mac_biba_parse_element(&mac_biba->mb_rangelow,
755 rangelow);
756 if (error)
757 return (error);
758 error = mac_biba_parse_element(&mac_biba->mb_rangehigh,
759 rangehigh);
760 if (error)
761 return (error);
762 mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE;
763 }
764
765 error = mac_biba_valid(mac_biba);
766 if (error)
767 return (error);
768
769 return (0);
770}
771
772static int
773mac_biba_internalize_label(struct label *label, char *element_name,
774 char *element_data, int *claimed)
775{
776 struct mac_biba *mac_biba, mac_biba_temp;
777 int error;
778
779 if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0)
780 return (0);
781
782 (*claimed)++;
783
784 error = mac_biba_parse(&mac_biba_temp, element_data);
785 if (error)
786 return (error);
787
788 mac_biba = SLOT(label);
789 *mac_biba = mac_biba_temp;
790
791 return (0);
792}
793
794static void
795mac_biba_copy_label(struct label *src, struct label *dest)
796{
797
798 *SLOT(dest) = *SLOT(src);
799}
800
801/*
802 * Labeling event operations: file system objects, and things that look
803 * a lot like file system objects.
804 */
805static void
806mac_biba_create_devfs_device(dev_t dev, struct devfs_dirent *devfs_dirent,
807 struct label *label)
808{
809 struct mac_biba *mac_biba;
810 int biba_type;
811
812 mac_biba = SLOT(label);
813 if (strcmp(dev->si_name, "null") == 0 ||
814 strcmp(dev->si_name, "zero") == 0 ||
815 strcmp(dev->si_name, "random") == 0 ||
816 strncmp(dev->si_name, "fd/", strlen("fd/")) == 0)
817 biba_type = MAC_BIBA_TYPE_EQUAL;
818 else if (ptys_equal &&
819 (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 ||
820 strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0))
821 biba_type = MAC_BIBA_TYPE_EQUAL;
822 else
823 biba_type = MAC_BIBA_TYPE_HIGH;
824 mac_biba_set_single(mac_biba, biba_type, 0, NULL);
825}
826
827static void
828mac_biba_create_devfs_directory(char *dirname, int dirnamelen,
829 struct devfs_dirent *devfs_dirent, struct label *label)
830{
831 struct mac_biba *mac_biba;
832
833 mac_biba = SLOT(label);
834 mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
835}
836
837static void
838mac_biba_create_devfs_symlink(struct ucred *cred, struct devfs_dirent *dd,
839 struct label *ddlabel, struct devfs_dirent *de, struct label *delabel)
840{
841 struct mac_biba *source, *dest;
842
843 source = SLOT(&cred->cr_label);
844 dest = SLOT(delabel);
845
846 mac_biba_copy_single(source, dest);
847}
848
849static void
850mac_biba_create_devfs_vnode(struct devfs_dirent *devfs_dirent,
851 struct label *direntlabel, struct vnode *vp, struct label *vnodelabel)
852{
853 struct mac_biba *source, *dest;
854
855 source = SLOT(direntlabel);
856 dest = SLOT(vnodelabel);
857 mac_biba_copy_single(source, dest);
858}
859
860static void
861mac_biba_create_mount(struct ucred *cred, struct mount *mp,
862 struct label *mntlabel, struct label *fslabel)
863{
864 struct mac_biba *source, *dest;
865
866 source = SLOT(&cred->cr_label);
867 dest = SLOT(mntlabel);
868 mac_biba_copy_single(source, dest);
869 dest = SLOT(fslabel);
870 mac_biba_copy_single(source, dest);
871}
872
873static void
874mac_biba_create_root_mount(struct ucred *cred, struct mount *mp,
875 struct label *mntlabel, struct label *fslabel)
876{
877 struct mac_biba *mac_biba;
878
879 /* Always mount root as high integrity. */
880 mac_biba = SLOT(fslabel);
881 mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
882 mac_biba = SLOT(mntlabel);
883 mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
884}
885
886static void
887mac_biba_relabel_vnode(struct ucred *cred, struct vnode *vp,
888 struct label *vnodelabel, struct label *label)
889{
890 struct mac_biba *source, *dest;
891
892 source = SLOT(label);
893 dest = SLOT(vnodelabel);
894
895 mac_biba_copy(source, dest);
896}
897
898static void
899mac_biba_update_devfsdirent(struct devfs_dirent *devfs_dirent,
900 struct label *direntlabel, struct vnode *vp, struct label *vnodelabel)
901{
902 struct mac_biba *source, *dest;
903
904 source = SLOT(vnodelabel);
905 dest = SLOT(direntlabel);
906
907 mac_biba_copy(source, dest);
908}
909
910static void
911mac_biba_associate_vnode_devfs(struct mount *mp, struct label *fslabel,
912 struct devfs_dirent *de, struct label *delabel, struct vnode *vp,
913 struct label *vlabel)
914{
915 struct mac_biba *source, *dest;
916
917 source = SLOT(delabel);
918 dest = SLOT(vlabel);
919
920 mac_biba_copy_single(source, dest);
921}
922
923static int
924mac_biba_associate_vnode_extattr(struct mount *mp, struct label *fslabel,
925 struct vnode *vp, struct label *vlabel)
926{
927 struct mac_biba temp, *source, *dest;
928 size_t buflen;
929 int error;
928 int buflen, error;
930
931 source = SLOT(fslabel);
932 dest = SLOT(vlabel);
933
934 buflen = sizeof(temp);
935 bzero(&temp, buflen);
936
937 error = vn_extattr_get(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
938 MAC_BIBA_EXTATTR_NAME, &buflen, (char *) &temp, curthread);
939 if (error == ENOATTR || error == EOPNOTSUPP) {
940 /* Fall back to the fslabel. */
941 mac_biba_copy_single(source, dest);
942 return (0);
943 } else if (error)
944 return (error);
945
946 if (buflen != sizeof(temp)) {
947 printf("mac_biba_associate_vnode_extattr: bad size %d\n",
948 buflen);
949 return (EPERM);
950 }
951 if (mac_biba_valid(&temp) != 0) {
952 printf("mac_biba_associate_vnode_extattr: invalid\n");
953 return (EPERM);
954 }
955 if ((temp.mb_flags & MAC_BIBA_FLAGS_BOTH) != MAC_BIBA_FLAG_SINGLE) {
956 printf("mac_biba_associate_vnode_extattr: not single\n");
957 return (EPERM);
958 }
959
960 mac_biba_copy_single(&temp, dest);
961 return (0);
962}
963
964static void
965mac_biba_associate_vnode_singlelabel(struct mount *mp,
966 struct label *fslabel, struct vnode *vp, struct label *vlabel)
967{
968 struct mac_biba *source, *dest;
969
970 source = SLOT(fslabel);
971 dest = SLOT(vlabel);
972
973 mac_biba_copy_single(source, dest);
974}
975
976static int
977mac_biba_create_vnode_extattr(struct ucred *cred, struct mount *mp,
978 struct label *fslabel, struct vnode *dvp, struct label *dlabel,
979 struct vnode *vp, struct label *vlabel, struct componentname *cnp)
980{
981 struct mac_biba *source, *dest, temp;
982 size_t buflen;
983 int error;
984
985 buflen = sizeof(temp);
986 bzero(&temp, buflen);
987
988 source = SLOT(&cred->cr_label);
989 dest = SLOT(vlabel);
990 mac_biba_copy_single(source, &temp);
991
992 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
993 MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread);
994 if (error == 0)
995 mac_biba_copy_single(source, dest);
996 return (error);
997}
998
999static int
1000mac_biba_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp,
1001 struct label *vlabel, struct label *intlabel)
1002{
1003 struct mac_biba *source, temp;
1004 size_t buflen;
1005 int error;
1006
1007 buflen = sizeof(temp);
1008 bzero(&temp, buflen);
1009
1010 source = SLOT(intlabel);
1011 if ((source->mb_flags & MAC_BIBA_FLAG_SINGLE) == 0)
1012 return (0);
1013
1014 mac_biba_copy_single(source, &temp);
1015
1016 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
1017 MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread);
1018 return (error);
1019}
1020
1021/*
1022 * Labeling event operations: IPC object.
1023 */
1024static void
1025mac_biba_create_mbuf_from_socket(struct socket *so, struct label *socketlabel,
1026 struct mbuf *m, struct label *mbuflabel)
1027{
1028 struct mac_biba *source, *dest;
1029
1030 source = SLOT(socketlabel);
1031 dest = SLOT(mbuflabel);
1032
1033 mac_biba_copy_single(source, dest);
1034}
1035
1036static void
1037mac_biba_create_socket(struct ucred *cred, struct socket *socket,
1038 struct label *socketlabel)
1039{
1040 struct mac_biba *source, *dest;
1041
1042 source = SLOT(&cred->cr_label);
1043 dest = SLOT(socketlabel);
1044
1045 mac_biba_copy_single(source, dest);
1046}
1047
1048static void
1049mac_biba_create_pipe(struct ucred *cred, struct pipe *pipe,
1050 struct label *pipelabel)
1051{
1052 struct mac_biba *source, *dest;
1053
1054 source = SLOT(&cred->cr_label);
1055 dest = SLOT(pipelabel);
1056
1057 mac_biba_copy_single(source, dest);
1058}
1059
1060static void
1061mac_biba_create_socket_from_socket(struct socket *oldsocket,
1062 struct label *oldsocketlabel, struct socket *newsocket,
1063 struct label *newsocketlabel)
1064{
1065 struct mac_biba *source, *dest;
1066
1067 source = SLOT(oldsocketlabel);
1068 dest = SLOT(newsocketlabel);
1069
1070 mac_biba_copy_single(source, dest);
1071}
1072
1073static void
1074mac_biba_relabel_socket(struct ucred *cred, struct socket *socket,
1075 struct label *socketlabel, struct label *newlabel)
1076{
1077 struct mac_biba *source, *dest;
1078
1079 source = SLOT(newlabel);
1080 dest = SLOT(socketlabel);
1081
1082 mac_biba_copy(source, dest);
1083}
1084
1085static void
1086mac_biba_relabel_pipe(struct ucred *cred, struct pipe *pipe,
1087 struct label *pipelabel, struct label *newlabel)
1088{
1089 struct mac_biba *source, *dest;
1090
1091 source = SLOT(newlabel);
1092 dest = SLOT(pipelabel);
1093
1094 mac_biba_copy(source, dest);
1095}
1096
1097static void
1098mac_biba_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel,
1099 struct socket *socket, struct label *socketpeerlabel)
1100{
1101 struct mac_biba *source, *dest;
1102
1103 source = SLOT(mbuflabel);
1104 dest = SLOT(socketpeerlabel);
1105
1106 mac_biba_copy_single(source, dest);
1107}
1108
1109/*
1110 * Labeling event operations: network objects.
1111 */
1112static void
1113mac_biba_set_socket_peer_from_socket(struct socket *oldsocket,
1114 struct label *oldsocketlabel, struct socket *newsocket,
1115 struct label *newsocketpeerlabel)
1116{
1117 struct mac_biba *source, *dest;
1118
1119 source = SLOT(oldsocketlabel);
1120 dest = SLOT(newsocketpeerlabel);
1121
1122 mac_biba_copy_single(source, dest);
1123}
1124
1125static void
1126mac_biba_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d,
1127 struct label *bpflabel)
1128{
1129 struct mac_biba *source, *dest;
1130
1131 source = SLOT(&cred->cr_label);
1132 dest = SLOT(bpflabel);
1133
1134 mac_biba_copy_single(source, dest);
1135}
1136
1137static void
1138mac_biba_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel)
1139{
1140 char tifname[IFNAMSIZ], ifname[IFNAMSIZ], *p, *q;
1141 char tiflist[sizeof(trusted_interfaces)];
1142 struct mac_biba *dest;
1143 int len, grade;
1144
1145 dest = SLOT(ifnetlabel);
1146
1147 if (ifnet->if_type == IFT_LOOP) {
1148 grade = MAC_BIBA_TYPE_EQUAL;
1149 goto set;
1150 }
1151
1152 if (trust_all_interfaces) {
1153 grade = MAC_BIBA_TYPE_HIGH;
1154 goto set;
1155 }
1156
1157 grade = MAC_BIBA_TYPE_LOW;
1158
1159 if (trusted_interfaces[0] == '\0' ||
1160 !strvalid(trusted_interfaces, sizeof(trusted_interfaces)))
1161 goto set;
1162
1163 bzero(tiflist, sizeof(tiflist));
1164 for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++)
1165 if(*p != ' ' && *p != '\t')
1166 *q = *p;
1167
1168 snprintf(ifname, IFNAMSIZ, "%s%d", ifnet->if_name, ifnet->if_unit);
1169
1170 for (p = q = tiflist;; p++) {
1171 if (*p == ',' || *p == '\0') {
1172 len = p - q;
1173 if (len < IFNAMSIZ) {
1174 bzero(tifname, sizeof(tifname));
1175 bcopy(q, tifname, len);
1176 if (strcmp(tifname, ifname) == 0) {
1177 grade = MAC_BIBA_TYPE_HIGH;
1178 break;
1179 }
1180 } else {
1181 *p = '\0';
1182 printf("mac_biba warning: interface name "
1183 "\"%s\" is too long (must be < %d)\n",
1184 q, IFNAMSIZ);
1185 }
1186 if (*p == '\0')
1187 break;
1188 q = p + 1;
1189 }
1190 }
1191set:
1192 mac_biba_set_single(dest, grade, 0, NULL);
1193 mac_biba_set_range(dest, grade, 0, NULL, grade, 0, NULL);
1194}
1195
1196static void
1197mac_biba_create_ipq(struct mbuf *fragment, struct label *fragmentlabel,
1198 struct ipq *ipq, struct label *ipqlabel)
1199{
1200 struct mac_biba *source, *dest;
1201
1202 source = SLOT(fragmentlabel);
1203 dest = SLOT(ipqlabel);
1204
1205 mac_biba_copy_single(source, dest);
1206}
1207
1208static void
1209mac_biba_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel,
1210 struct mbuf *datagram, struct label *datagramlabel)
1211{
1212 struct mac_biba *source, *dest;
1213
1214 source = SLOT(ipqlabel);
1215 dest = SLOT(datagramlabel);
1216
1217 /* Just use the head, since we require them all to match. */
1218 mac_biba_copy_single(source, dest);
1219}
1220
1221static void
1222mac_biba_create_fragment(struct mbuf *datagram, struct label *datagramlabel,
1223 struct mbuf *fragment, struct label *fragmentlabel)
1224{
1225 struct mac_biba *source, *dest;
1226
1227 source = SLOT(datagramlabel);
1228 dest = SLOT(fragmentlabel);
1229
1230 mac_biba_copy_single(source, dest);
1231}
1232
1233static void
1234mac_biba_create_mbuf_from_mbuf(struct mbuf *oldmbuf,
1235 struct label *oldmbuflabel, struct mbuf *newmbuf,
1236 struct label *newmbuflabel)
1237{
1238 struct mac_biba *source, *dest;
1239
1240 source = SLOT(oldmbuflabel);
1241 dest = SLOT(newmbuflabel);
1242
1243 /*
1244 * Because the source mbuf may not yet have been "created",
1245 * just initialized, we do a conditional copy. Since we don't
1246 * allow mbufs to have ranges, do a KASSERT to make sure that
1247 * doesn't happen.
1248 */
1249 KASSERT((source->mb_flags & MAC_BIBA_FLAG_RANGE) == 0,
1250 ("mac_biba_create_mbuf_from_mbuf: source mbuf has range"));
1251 mac_biba_copy(source, dest);
1252}
1253
1254static void
1255mac_biba_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel,
1256 struct mbuf *mbuf, struct label *mbuflabel)
1257{
1258 struct mac_biba *dest;
1259
1260 dest = SLOT(mbuflabel);
1261
1262 mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1263}
1264
1265static void
1266mac_biba_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel,
1267 struct mbuf *mbuf, struct label *mbuflabel)
1268{
1269 struct mac_biba *source, *dest;
1270
1271 source = SLOT(bpflabel);
1272 dest = SLOT(mbuflabel);
1273
1274 mac_biba_copy_single(source, dest);
1275}
1276
1277static void
1278mac_biba_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel,
1279 struct mbuf *m, struct label *mbuflabel)
1280{
1281 struct mac_biba *source, *dest;
1282
1283 source = SLOT(ifnetlabel);
1284 dest = SLOT(mbuflabel);
1285
1286 mac_biba_copy_single(source, dest);
1287}
1288
1289static void
1290mac_biba_create_mbuf_multicast_encap(struct mbuf *oldmbuf,
1291 struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel,
1292 struct mbuf *newmbuf, struct label *newmbuflabel)
1293{
1294 struct mac_biba *source, *dest;
1295
1296 source = SLOT(oldmbuflabel);
1297 dest = SLOT(newmbuflabel);
1298
1299 mac_biba_copy_single(source, dest);
1300}
1301
1302static void
1303mac_biba_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel,
1304 struct mbuf *newmbuf, struct label *newmbuflabel)
1305{
1306 struct mac_biba *source, *dest;
1307
1308 source = SLOT(oldmbuflabel);
1309 dest = SLOT(newmbuflabel);
1310
1311 mac_biba_copy_single(source, dest);
1312}
1313
1314static int
1315mac_biba_fragment_match(struct mbuf *fragment, struct label *fragmentlabel,
1316 struct ipq *ipq, struct label *ipqlabel)
1317{
1318 struct mac_biba *a, *b;
1319
1320 a = SLOT(ipqlabel);
1321 b = SLOT(fragmentlabel);
1322
1323 return (mac_biba_equal_single(a, b));
1324}
1325
1326static void
1327mac_biba_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet,
1328 struct label *ifnetlabel, struct label *newlabel)
1329{
1330 struct mac_biba *source, *dest;
1331
1332 source = SLOT(newlabel);
1333 dest = SLOT(ifnetlabel);
1334
1335 mac_biba_copy(source, dest);
1336}
1337
1338static void
1339mac_biba_update_ipq(struct mbuf *fragment, struct label *fragmentlabel,
1340 struct ipq *ipq, struct label *ipqlabel)
1341{
1342
1343 /* NOOP: we only accept matching labels, so no need to update */
1344}
1345
1346/*
1347 * Labeling event operations: processes.
1348 */
1349static void
1350mac_biba_create_cred(struct ucred *cred_parent, struct ucred *cred_child)
1351{
1352 struct mac_biba *source, *dest;
1353
1354 source = SLOT(&cred_parent->cr_label);
1355 dest = SLOT(&cred_child->cr_label);
1356
1357 mac_biba_copy_single(source, dest);
1358 mac_biba_copy_range(source, dest);
1359}
1360
1361static void
1362mac_biba_execve_transition(struct ucred *old, struct ucred *new,
1363 struct vnode *vp, struct label *vnodelabel)
1364{
1365 struct mac_biba *source, *dest;
1366
1367 source = SLOT(&old->cr_label);
1368 dest = SLOT(&new->cr_label);
1369
1370 mac_biba_copy_single(source, dest);
1371 mac_biba_copy_range(source, dest);
1372}
1373
1374static int
1375mac_biba_execve_will_transition(struct ucred *old, struct vnode *vp,
1376 struct label *vnodelabel)
1377{
1378
1379 return (0);
1380}
1381
1382static void
1383mac_biba_create_proc0(struct ucred *cred)
1384{
1385 struct mac_biba *dest;
1386
1387 dest = SLOT(&cred->cr_label);
1388
1389 mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1390 mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL,
1391 MAC_BIBA_TYPE_HIGH, 0, NULL);
1392}
1393
1394static void
1395mac_biba_create_proc1(struct ucred *cred)
1396{
1397 struct mac_biba *dest;
1398
1399 dest = SLOT(&cred->cr_label);
1400
1401 mac_biba_set_single(dest, MAC_BIBA_TYPE_HIGH, 0, NULL);
1402 mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL,
1403 MAC_BIBA_TYPE_HIGH, 0, NULL);
1404}
1405
1406static void
1407mac_biba_relabel_cred(struct ucred *cred, struct label *newlabel)
1408{
1409 struct mac_biba *source, *dest;
1410
1411 source = SLOT(newlabel);
1412 dest = SLOT(&cred->cr_label);
1413
1414 mac_biba_copy(source, dest);
1415}
1416
1417/*
1418 * Access control checks.
1419 */
1420static int
1421mac_biba_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel,
1422 struct ifnet *ifnet, struct label *ifnetlabel)
1423{
1424 struct mac_biba *a, *b;
1425
1426 if (!mac_biba_enabled)
1427 return (0);
1428
1429 a = SLOT(bpflabel);
1430 b = SLOT(ifnetlabel);
1431
1432 if (mac_biba_equal_single(a, b))
1433 return (0);
1434 return (EACCES);
1435}
1436
1437static int
1438mac_biba_check_cred_relabel(struct ucred *cred, struct label *newlabel)
1439{
1440 struct mac_biba *subj, *new;
1441 int error;
1442
1443 subj = SLOT(&cred->cr_label);
1444 new = SLOT(newlabel);
1445
1446 /*
1447 * If there is a Biba label update for the credential, it may
1448 * be an update of the single, range, or both.
1449 */
1450 error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
1451 if (error)
1452 return (error);
1453
1454 /*
1455 * If the Biba label is to be changed, authorize as appropriate.
1456 */
1457 if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) {
1458 /*
1459 * To change the Biba single label on a credential, the
1460 * new single label must be in the current range.
1461 */
1462 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE &&
1463 !mac_biba_single_in_range(new, subj))
1464 return (EPERM);
1465
1466 /*
1467 * To change the Biba range on a credential, the new
1468 * range label must be in the current range.
1469 */
1470 if (new->mb_flags & MAC_BIBA_FLAG_RANGE &&
1471 !mac_biba_range_in_range(new, subj))
1472 return (EPERM);
1473
1474 /*
1475 * To have EQUAL in any component of the new credential
1476 * Biba label, the subject must already have EQUAL in
1477 * their label.
1478 */
1479 if (mac_biba_contains_equal(new)) {
1480 error = mac_biba_subject_privileged(subj);
1481 if (error)
1482 return (error);
1483 }
1484
1485 /*
1486 * XXXMAC: Additional consistency tests regarding the
1487 * single and range of the new label might be performed
1488 * here.
1489 */
1490 }
1491
1492 return (0);
1493}
1494
1495static int
1496mac_biba_check_cred_visible(struct ucred *u1, struct ucred *u2)
1497{
1498 struct mac_biba *subj, *obj;
1499
1500 if (!mac_biba_enabled)
1501 return (0);
1502
1503 subj = SLOT(&u1->cr_label);
1504 obj = SLOT(&u2->cr_label);
1505
1506 /* XXX: range */
1507 if (!mac_biba_dominate_single(obj, subj))
1508 return (ESRCH);
1509
1510 return (0);
1511}
1512
1513static int
1514mac_biba_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet,
1515 struct label *ifnetlabel, struct label *newlabel)
1516{
1517 struct mac_biba *subj, *new;
1518 int error;
1519
1520 subj = SLOT(&cred->cr_label);
1521 new = SLOT(newlabel);
1522
1523 /*
1524 * If there is a Biba label update for the interface, it may
1525 * be an update of the single, range, or both.
1526 */
1527 error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
1528 if (error)
1529 return (error);
1530
1531 /*
1532 * Relabling network interfaces requires Biba privilege.
1533 */
1534 error = mac_biba_subject_privileged(subj);
1535 if (error)
1536 return (error);
1537
1538 /*
1539 * If the Biba label is to be changed, authorize as appropriate.
1540 */
1541 if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) {
1542 /*
1543 * Rely on the traditional superuser status for the Biba
1544 * interface relabel requirements. XXXMAC: This will go
1545 * away.
1546 */
1547 error = suser_cred(cred, 0);
1548 if (error)
1549 return (EPERM);
1550
1551 /*
1552 * XXXMAC: Additional consistency tests regarding the single
1553 * and the range of the new label might be performed here.
1554 */
1555 }
1556
1557 return (0);
1558}
1559
1560static int
1561mac_biba_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel,
1562 struct mbuf *m, struct label *mbuflabel)
1563{
1564 struct mac_biba *p, *i;
1565
1566 if (!mac_biba_enabled)
1567 return (0);
1568
1569 p = SLOT(mbuflabel);
1570 i = SLOT(ifnetlabel);
1571
1572 return (mac_biba_single_in_range(p, i) ? 0 : EACCES);
1573}
1574
1575static int
1576mac_biba_check_mount_stat(struct ucred *cred, struct mount *mp,
1577 struct label *mntlabel)
1578{
1579 struct mac_biba *subj, *obj;
1580
1581 if (!mac_biba_enabled)
1582 return (0);
1583
1584 subj = SLOT(&cred->cr_label);
1585 obj = SLOT(mntlabel);
1586
1587 if (!mac_biba_dominate_single(obj, subj))
1588 return (EACCES);
1589
1590 return (0);
1591}
1592
1593static int
1594mac_biba_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe,
1595 struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data)
1596{
1597
1598 if(!mac_biba_enabled)
1599 return (0);
1600
1601 /* XXX: This will be implemented soon... */
1602
1603 return (0);
1604}
1605
1606static int
1607mac_biba_check_pipe_poll(struct ucred *cred, struct pipe *pipe,
1608 struct label *pipelabel)
1609{
1610 struct mac_biba *subj, *obj;
1611
1612 if (!mac_biba_enabled)
1613 return (0);
1614
1615 subj = SLOT(&cred->cr_label);
1616 obj = SLOT((pipelabel));
1617
1618 if (!mac_biba_dominate_single(obj, subj))
1619 return (EACCES);
1620
1621 return (0);
1622}
1623
1624static int
1625mac_biba_check_pipe_read(struct ucred *cred, struct pipe *pipe,
1626 struct label *pipelabel)
1627{
1628 struct mac_biba *subj, *obj;
1629
1630 if (!mac_biba_enabled)
1631 return (0);
1632
1633 subj = SLOT(&cred->cr_label);
1634 obj = SLOT((pipelabel));
1635
1636 if (!mac_biba_dominate_single(obj, subj))
1637 return (EACCES);
1638
1639 return (0);
1640}
1641
1642static int
1643mac_biba_check_pipe_relabel(struct ucred *cred, struct pipe *pipe,
1644 struct label *pipelabel, struct label *newlabel)
1645{
1646 struct mac_biba *subj, *obj, *new;
1647 int error;
1648
1649 new = SLOT(newlabel);
1650 subj = SLOT(&cred->cr_label);
1651 obj = SLOT(pipelabel);
1652
1653 /*
1654 * If there is a Biba label update for a pipe, it must be a
1655 * single update.
1656 */
1657 error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE);
1658 if (error)
1659 return (error);
1660
1661 /*
1662 * To perform a relabel of a pipe (Biba label or not), Biba must
1663 * authorize the relabel.
1664 */
1665 if (!mac_biba_single_in_range(obj, subj))
1666 return (EPERM);
1667
1668 /*
1669 * If the Biba label is to be changed, authorize as appropriate.
1670 */
1671 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) {
1672 /*
1673 * To change the Biba label on a pipe, the new pipe label
1674 * must be in the subject range.
1675 */
1676 if (!mac_biba_single_in_range(new, subj))
1677 return (EPERM);
1678
1679 /*
1680 * To change the Biba label on a pipe to be EQUAL, the
1681 * subject must have appropriate privilege.
1682 */
1683 if (mac_biba_contains_equal(new)) {
1684 error = mac_biba_subject_privileged(subj);
1685 if (error)
1686 return (error);
1687 }
1688 }
1689
1690 return (0);
1691}
1692
1693static int
1694mac_biba_check_pipe_stat(struct ucred *cred, struct pipe *pipe,
1695 struct label *pipelabel)
1696{
1697 struct mac_biba *subj, *obj;
1698
1699 if (!mac_biba_enabled)
1700 return (0);
1701
1702 subj = SLOT(&cred->cr_label);
1703 obj = SLOT((pipelabel));
1704
1705 if (!mac_biba_dominate_single(obj, subj))
1706 return (EACCES);
1707
1708 return (0);
1709}
1710
1711static int
1712mac_biba_check_pipe_write(struct ucred *cred, struct pipe *pipe,
1713 struct label *pipelabel)
1714{
1715 struct mac_biba *subj, *obj;
1716
1717 if (!mac_biba_enabled)
1718 return (0);
1719
1720 subj = SLOT(&cred->cr_label);
1721 obj = SLOT((pipelabel));
1722
1723 if (!mac_biba_dominate_single(subj, obj))
1724 return (EACCES);
1725
1726 return (0);
1727}
1728
1729static int
1730mac_biba_check_proc_debug(struct ucred *cred, struct proc *proc)
1731{
1732 struct mac_biba *subj, *obj;
1733
1734 if (!mac_biba_enabled)
1735 return (0);
1736
1737 subj = SLOT(&cred->cr_label);
1738 obj = SLOT(&proc->p_ucred->cr_label);
1739
1740 /* XXX: range checks */
1741 if (!mac_biba_dominate_single(obj, subj))
1742 return (ESRCH);
1743 if (!mac_biba_dominate_single(subj, obj))
1744 return (EACCES);
1745
1746 return (0);
1747}
1748
1749static int
1750mac_biba_check_proc_sched(struct ucred *cred, struct proc *proc)
1751{
1752 struct mac_biba *subj, *obj;
1753
1754 if (!mac_biba_enabled)
1755 return (0);
1756
1757 subj = SLOT(&cred->cr_label);
1758 obj = SLOT(&proc->p_ucred->cr_label);
1759
1760 /* XXX: range checks */
1761 if (!mac_biba_dominate_single(obj, subj))
1762 return (ESRCH);
1763 if (!mac_biba_dominate_single(subj, obj))
1764 return (EACCES);
1765
1766 return (0);
1767}
1768
1769static int
1770mac_biba_check_proc_signal(struct ucred *cred, struct proc *proc, int signum)
1771{
1772 struct mac_biba *subj, *obj;
1773
1774 if (!mac_biba_enabled)
1775 return (0);
1776
1777 subj = SLOT(&cred->cr_label);
1778 obj = SLOT(&proc->p_ucred->cr_label);
1779
1780 /* XXX: range checks */
1781 if (!mac_biba_dominate_single(obj, subj))
1782 return (ESRCH);
1783 if (!mac_biba_dominate_single(subj, obj))
1784 return (EACCES);
1785
1786 return (0);
1787}
1788
1789static int
1790mac_biba_check_socket_deliver(struct socket *so, struct label *socketlabel,
1791 struct mbuf *m, struct label *mbuflabel)
1792{
1793 struct mac_biba *p, *s;
1794
1795 if (!mac_biba_enabled)
1796 return (0);
1797
1798 p = SLOT(mbuflabel);
1799 s = SLOT(socketlabel);
1800
1801 return (mac_biba_equal_single(p, s) ? 0 : EACCES);
1802}
1803
1804static int
1805mac_biba_check_socket_relabel(struct ucred *cred, struct socket *so,
1806 struct label *socketlabel, struct label *newlabel)
1807{
1808 struct mac_biba *subj, *obj, *new;
1809 int error;
1810
1811 new = SLOT(newlabel);
1812 subj = SLOT(&cred->cr_label);
1813 obj = SLOT(socketlabel);
1814
1815 /*
1816 * If there is a Biba label update for the socket, it may be
1817 * an update of single.
1818 */
1819 error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE);
1820 if (error)
1821 return (error);
1822
1823 /*
1824 * To relabel a socket, the old socket single must be in the subject
1825 * range.
1826 */
1827 if (!mac_biba_single_in_range(obj, subj))
1828 return (EPERM);
1829
1830 /*
1831 * If the Biba label is to be changed, authorize as appropriate.
1832 */
1833 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) {
1834 /*
1835 * To relabel a socket, the new socket single must be in
1836 * the subject range.
1837 */
1838 if (!mac_biba_single_in_range(new, subj))
1839 return (EPERM);
1840
1841 /*
1842 * To change the Biba label on the socket to contain EQUAL,
1843 * the subject must have appropriate privilege.
1844 */
1845 if (mac_biba_contains_equal(new)) {
1846 error = mac_biba_subject_privileged(subj);
1847 if (error)
1848 return (error);
1849 }
1850 }
1851
1852 return (0);
1853}
1854
1855static int
1856mac_biba_check_socket_visible(struct ucred *cred, struct socket *socket,
1857 struct label *socketlabel)
1858{
1859 struct mac_biba *subj, *obj;
1860
1861 if (!mac_biba_enabled)
1862 return (0);
1863
1864 subj = SLOT(&cred->cr_label);
1865 obj = SLOT(socketlabel);
1866
1867 if (!mac_biba_dominate_single(obj, subj))
1868 return (ENOENT);
1869
1870 return (0);
1871}
1872
1873static int
1874mac_biba_check_system_swapon(struct ucred *cred, struct vnode *vp,
1875 struct label *label)
1876{
1877 struct mac_biba *subj, *obj;
1878
1879 if (!mac_biba_enabled)
1880 return (0);
1881
1882 subj = SLOT(&cred->cr_label);
1883 obj = SLOT(label);
1884
1885 if (!mac_biba_subject_privileged(subj))
1886 return (EPERM);
1887
1888 if (!mac_biba_high_single(obj))
1889 return (EACCES);
1890
1891 return (0);
1892}
1893
1894static int
1895mac_biba_check_system_sysctl(struct ucred *cred, int *name, u_int namelen,
1896 void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen)
1897{
1898 struct mac_biba *subj;
1899 int error;
1900
1901 if (!mac_biba_enabled)
1902 return (0);
1903
1904 subj = SLOT(&cred->cr_label);
1905
1906 /*
1907 * In general, treat sysctl variables as biba/high, but also
1908 * require privilege to change them, since they are a
1909 * communications channel between grades. Exempt MIB
1910 * queries from this due to undocmented sysctl magic.
1911 * XXXMAC: This probably requires some more review.
1912 */
1913 if (new != NULL) {
1914 if (namelen > 0 && name[0] == 0)
1915 return (0);
1916
1917 if (!mac_biba_subject_dominate_high(subj))
1918 return (EACCES);
1919
1920 error = mac_biba_subject_privileged(subj);
1921 if (error)
1922 return (error);
1923 }
1924
1925 return (0);
1926}
1927
1928static int
1929mac_biba_check_vnode_chdir(struct ucred *cred, struct vnode *dvp,
1930 struct label *dlabel)
1931{
1932 struct mac_biba *subj, *obj;
1933
1934 if (!mac_biba_enabled)
1935 return (0);
1936
1937 subj = SLOT(&cred->cr_label);
1938 obj = SLOT(dlabel);
1939
1940 if (!mac_biba_dominate_single(obj, subj))
1941 return (EACCES);
1942
1943 return (0);
1944}
1945
1946static int
1947mac_biba_check_vnode_chroot(struct ucred *cred, struct vnode *dvp,
1948 struct label *dlabel)
1949{
1950 struct mac_biba *subj, *obj;
1951
1952 if (!mac_biba_enabled)
1953 return (0);
1954
1955 subj = SLOT(&cred->cr_label);
1956 obj = SLOT(dlabel);
1957
1958 if (!mac_biba_dominate_single(obj, subj))
1959 return (EACCES);
1960
1961 return (0);
1962}
1963
1964static int
1965mac_biba_check_vnode_create(struct ucred *cred, struct vnode *dvp,
1966 struct label *dlabel, struct componentname *cnp, struct vattr *vap)
1967{
1968 struct mac_biba *subj, *obj;
1969
1970 if (!mac_biba_enabled)
1971 return (0);
1972
1973 subj = SLOT(&cred->cr_label);
1974 obj = SLOT(dlabel);
1975
1976 if (!mac_biba_dominate_single(subj, obj))
1977 return (EACCES);
1978
1979 return (0);
1980}
1981
1982static int
1983mac_biba_check_vnode_delete(struct ucred *cred, struct vnode *dvp,
1984 struct label *dlabel, struct vnode *vp, struct label *label,
1985 struct componentname *cnp)
1986{
1987 struct mac_biba *subj, *obj;
1988
1989 if (!mac_biba_enabled)
1990 return (0);
1991
1992 subj = SLOT(&cred->cr_label);
1993 obj = SLOT(dlabel);
1994
1995 if (!mac_biba_dominate_single(subj, obj))
1996 return (EACCES);
1997
1998 obj = SLOT(label);
1999
2000 if (!mac_biba_dominate_single(subj, obj))
2001 return (EACCES);
2002
2003 return (0);
2004}
2005
2006static int
2007mac_biba_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
2008 struct label *label, acl_type_t type)
2009{
2010 struct mac_biba *subj, *obj;
2011
2012 if (!mac_biba_enabled)
2013 return (0);
2014
2015 subj = SLOT(&cred->cr_label);
2016 obj = SLOT(label);
2017
2018 if (!mac_biba_dominate_single(subj, obj))
2019 return (EACCES);
2020
2021 return (0);
2022}
2023
2024static int
2025mac_biba_check_vnode_exec(struct ucred *cred, struct vnode *vp,
2026 struct label *label)
2027{
2028 struct mac_biba *subj, *obj;
2029
2030 if (!mac_biba_enabled)
2031 return (0);
2032
2033 subj = SLOT(&cred->cr_label);
2034 obj = SLOT(label);
2035
2036 if (!mac_biba_dominate_single(obj, subj))
2037 return (EACCES);
2038
2039 return (0);
2040}
2041
2042static int
2043mac_biba_check_vnode_getacl(struct ucred *cred, struct vnode *vp,
2044 struct label *label, acl_type_t type)
2045{
2046 struct mac_biba *subj, *obj;
2047
2048 if (!mac_biba_enabled)
2049 return (0);
2050
2051 subj = SLOT(&cred->cr_label);
2052 obj = SLOT(label);
2053
2054 if (!mac_biba_dominate_single(obj, subj))
2055 return (EACCES);
2056
2057 return (0);
2058}
2059
2060static int
2061mac_biba_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
2062 struct label *label, int attrnamespace, const char *name, struct uio *uio)
2063{
2064 struct mac_biba *subj, *obj;
2065
2066 if (!mac_biba_enabled)
2067 return (0);
2068
2069 subj = SLOT(&cred->cr_label);
2070 obj = SLOT(label);
2071
2072 if (!mac_biba_dominate_single(obj, subj))
2073 return (EACCES);
2074
2075 return (0);
2076}
2077
2078static int
2079mac_biba_check_vnode_link(struct ucred *cred, struct vnode *dvp,
2080 struct label *dlabel, struct vnode *vp, struct label *label,
2081 struct componentname *cnp)
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(dlabel);
2090
2091 if (!mac_biba_dominate_single(subj, obj))
2092 return (EACCES);
2093
2094 obj = SLOT(label);
2095
2096 if (!mac_biba_dominate_single(subj, obj))
2097 return (EACCES);
2098
2099 return (0);
2100}
2101
2102static int
2103mac_biba_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
2104 struct label *dlabel, struct componentname *cnp)
2105{
2106 struct mac_biba *subj, *obj;
2107
2108 if (!mac_biba_enabled)
2109 return (0);
2110
2111 subj = SLOT(&cred->cr_label);
2112 obj = SLOT(dlabel);
2113
2114 if (!mac_biba_dominate_single(obj, subj))
2115 return (EACCES);
2116
2117 return (0);
2118}
2119
2120static int
2121mac_biba_check_vnode_mmap(struct ucred *cred, struct vnode *vp,
2122 struct label *label, int prot)
2123{
2124 struct mac_biba *subj, *obj;
2125
2126 /*
2127 * Rely on the use of open()-time protections to handle
2128 * non-revocation cases.
2129 */
2130 if (!mac_biba_enabled || !revocation_enabled)
2131 return (0);
2132
2133 subj = SLOT(&cred->cr_label);
2134 obj = SLOT(label);
2135
2136 if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
2137 if (!mac_biba_dominate_single(obj, subj))
2138 return (EACCES);
2139 }
2140 if (prot & VM_PROT_WRITE) {
2141 if (!mac_biba_dominate_single(subj, obj))
2142 return (EACCES);
2143 }
2144
2145 return (0);
2146}
2147
2148static int
2149mac_biba_check_vnode_open(struct ucred *cred, struct vnode *vp,
2150 struct label *vnodelabel, int acc_mode)
2151{
2152 struct mac_biba *subj, *obj;
2153
2154 if (!mac_biba_enabled)
2155 return (0);
2156
2157 subj = SLOT(&cred->cr_label);
2158 obj = SLOT(vnodelabel);
2159
2160 /* XXX privilege override for admin? */
2161 if (acc_mode & (VREAD | VEXEC | VSTAT)) {
2162 if (!mac_biba_dominate_single(obj, subj))
2163 return (EACCES);
2164 }
2165 if (acc_mode & (VWRITE | VAPPEND | VADMIN)) {
2166 if (!mac_biba_dominate_single(subj, obj))
2167 return (EACCES);
2168 }
2169
2170 return (0);
2171}
2172
2173static int
2174mac_biba_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred,
2175 struct vnode *vp, struct label *label)
2176{
2177 struct mac_biba *subj, *obj;
2178
2179 if (!mac_biba_enabled || !revocation_enabled)
2180 return (0);
2181
2182 subj = SLOT(&active_cred->cr_label);
2183 obj = SLOT(label);
2184
2185 if (!mac_biba_dominate_single(obj, subj))
2186 return (EACCES);
2187
2188 return (0);
2189}
2190
2191static int
2192mac_biba_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
2193 struct vnode *vp, struct label *label)
2194{
2195 struct mac_biba *subj, *obj;
2196
2197 if (!mac_biba_enabled || !revocation_enabled)
2198 return (0);
2199
2200 subj = SLOT(&active_cred->cr_label);
2201 obj = SLOT(label);
2202
2203 if (!mac_biba_dominate_single(obj, subj))
2204 return (EACCES);
2205
2206 return (0);
2207}
2208
2209static int
2210mac_biba_check_vnode_readdir(struct ucred *cred, struct vnode *dvp,
2211 struct label *dlabel)
2212{
2213 struct mac_biba *subj, *obj;
2214
2215 if (!mac_biba_enabled)
2216 return (0);
2217
2218 subj = SLOT(&cred->cr_label);
2219 obj = SLOT(dlabel);
2220
2221 if (!mac_biba_dominate_single(obj, subj))
2222 return (EACCES);
2223
2224 return (0);
2225}
2226
2227static int
2228mac_biba_check_vnode_readlink(struct ucred *cred, struct vnode *vp,
2229 struct label *label)
2230{
2231 struct mac_biba *subj, *obj;
2232
2233 if (!mac_biba_enabled)
2234 return (0);
2235
2236 subj = SLOT(&cred->cr_label);
2237 obj = SLOT(label);
2238
2239 if (!mac_biba_dominate_single(obj, subj))
2240 return (EACCES);
2241
2242 return (0);
2243}
2244
2245static int
2246mac_biba_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
2247 struct label *vnodelabel, struct label *newlabel)
2248{
2249 struct mac_biba *old, *new, *subj;
2250 int error;
2251
2252 old = SLOT(vnodelabel);
2253 new = SLOT(newlabel);
2254 subj = SLOT(&cred->cr_label);
2255
2256 /*
2257 * If there is a Biba label update for the vnode, it must be a
2258 * single label.
2259 */
2260 error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE);
2261 if (error)
2262 return (error);
2263
2264 /*
2265 * To perform a relabel of the vnode (Biba label or not), Biba must
2266 * authorize the relabel.
2267 */
2268 if (!mac_biba_single_in_range(old, subj))
2269 return (EPERM);
2270
2271 /*
2272 * If the Biba label is to be changed, authorize as appropriate.
2273 */
2274 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) {
2275 /*
2276 * To change the Biba label on a vnode, the new vnode label
2277 * must be in the subject range.
2278 */
2279 if (!mac_biba_single_in_range(new, subj))
2280 return (EPERM);
2281
2282 /*
2283 * To change the Biba label on the vnode to be EQUAL,
2284 * the subject must have appropriate privilege.
2285 */
2286 if (mac_biba_contains_equal(new)) {
2287 error = mac_biba_subject_privileged(subj);
2288 if (error)
2289 return (error);
2290 }
2291 }
2292
2293 return (0);
2294}
2295
2296static int
2297mac_biba_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
2298 struct label *dlabel, struct vnode *vp, struct label *label,
2299 struct componentname *cnp)
2300{
2301 struct mac_biba *subj, *obj;
2302
2303 if (!mac_biba_enabled)
2304 return (0);
2305
2306 subj = SLOT(&cred->cr_label);
2307 obj = SLOT(dlabel);
2308
2309 if (!mac_biba_dominate_single(subj, obj))
2310 return (EACCES);
2311
2312 obj = SLOT(label);
2313
2314 if (!mac_biba_dominate_single(subj, obj))
2315 return (EACCES);
2316
2317 return (0);
2318}
2319
2320static int
2321mac_biba_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
2322 struct label *dlabel, struct vnode *vp, struct label *label, int samedir,
2323 struct componentname *cnp)
2324{
2325 struct mac_biba *subj, *obj;
2326
2327 if (!mac_biba_enabled)
2328 return (0);
2329
2330 subj = SLOT(&cred->cr_label);
2331 obj = SLOT(dlabel);
2332
2333 if (!mac_biba_dominate_single(subj, obj))
2334 return (EACCES);
2335
2336 if (vp != NULL) {
2337 obj = SLOT(label);
2338
2339 if (!mac_biba_dominate_single(subj, obj))
2340 return (EACCES);
2341 }
2342
2343 return (0);
2344}
2345
2346static int
2347mac_biba_check_vnode_revoke(struct ucred *cred, struct vnode *vp,
2348 struct label *label)
2349{
2350 struct mac_biba *subj, *obj;
2351
2352 if (!mac_biba_enabled)
2353 return (0);
2354
2355 subj = SLOT(&cred->cr_label);
2356 obj = SLOT(label);
2357
2358 if (!mac_biba_dominate_single(subj, obj))
2359 return (EACCES);
2360
2361 return (0);
2362}
2363
2364static int
2365mac_biba_check_vnode_setacl(struct ucred *cred, struct vnode *vp,
2366 struct label *label, acl_type_t type, struct acl *acl)
2367{
2368 struct mac_biba *subj, *obj;
2369
2370 if (!mac_biba_enabled)
2371 return (0);
2372
2373 subj = SLOT(&cred->cr_label);
2374 obj = SLOT(label);
2375
2376 if (!mac_biba_dominate_single(subj, obj))
2377 return (EACCES);
2378
2379 return (0);
2380}
2381
2382static int
2383mac_biba_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
2384 struct label *vnodelabel, int attrnamespace, const char *name,
2385 struct uio *uio)
2386{
2387 struct mac_biba *subj, *obj;
2388
2389 if (!mac_biba_enabled)
2390 return (0);
2391
2392 subj = SLOT(&cred->cr_label);
2393 obj = SLOT(vnodelabel);
2394
2395 if (!mac_biba_dominate_single(subj, obj))
2396 return (EACCES);
2397
2398 /* XXX: protect the MAC EA in a special way? */
2399
2400 return (0);
2401}
2402
2403static int
2404mac_biba_check_vnode_setflags(struct ucred *cred, struct vnode *vp,
2405 struct label *vnodelabel, u_long flags)
2406{
2407 struct mac_biba *subj, *obj;
2408
2409 if (!mac_biba_enabled)
2410 return (0);
2411
2412 subj = SLOT(&cred->cr_label);
2413 obj = SLOT(vnodelabel);
2414
2415 if (!mac_biba_dominate_single(subj, obj))
2416 return (EACCES);
2417
2418 return (0);
2419}
2420
2421static int
2422mac_biba_check_vnode_setmode(struct ucred *cred, struct vnode *vp,
2423 struct label *vnodelabel, mode_t mode)
2424{
2425 struct mac_biba *subj, *obj;
2426
2427 if (!mac_biba_enabled)
2428 return (0);
2429
2430 subj = SLOT(&cred->cr_label);
2431 obj = SLOT(vnodelabel);
2432
2433 if (!mac_biba_dominate_single(subj, obj))
2434 return (EACCES);
2435
2436 return (0);
2437}
2438
2439static int
2440mac_biba_check_vnode_setowner(struct ucred *cred, struct vnode *vp,
2441 struct label *vnodelabel, uid_t uid, gid_t gid)
2442{
2443 struct mac_biba *subj, *obj;
2444
2445 if (!mac_biba_enabled)
2446 return (0);
2447
2448 subj = SLOT(&cred->cr_label);
2449 obj = SLOT(vnodelabel);
2450
2451 if (!mac_biba_dominate_single(subj, obj))
2452 return (EACCES);
2453
2454 return (0);
2455}
2456
2457static int
2458mac_biba_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
2459 struct label *vnodelabel, struct timespec atime, struct timespec mtime)
2460{
2461 struct mac_biba *subj, *obj;
2462
2463 if (!mac_biba_enabled)
2464 return (0);
2465
2466 subj = SLOT(&cred->cr_label);
2467 obj = SLOT(vnodelabel);
2468
2469 if (!mac_biba_dominate_single(subj, obj))
2470 return (EACCES);
2471
2472 return (0);
2473}
2474
2475static int
2476mac_biba_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
2477 struct vnode *vp, struct label *vnodelabel)
2478{
2479 struct mac_biba *subj, *obj;
2480
2481 if (!mac_biba_enabled)
2482 return (0);
2483
2484 subj = SLOT(&active_cred->cr_label);
2485 obj = SLOT(vnodelabel);
2486
2487 if (!mac_biba_dominate_single(obj, subj))
2488 return (EACCES);
2489
2490 return (0);
2491}
2492
2493static int
2494mac_biba_check_vnode_write(struct ucred *active_cred,
2495 struct ucred *file_cred, struct vnode *vp, struct label *label)
2496{
2497 struct mac_biba *subj, *obj;
2498
2499 if (!mac_biba_enabled || !revocation_enabled)
2500 return (0);
2501
2502 subj = SLOT(&active_cred->cr_label);
2503 obj = SLOT(label);
2504
2505 if (!mac_biba_dominate_single(subj, obj))
2506 return (EACCES);
2507
2508 return (0);
2509}
2510
2511static struct mac_policy_ops mac_biba_ops =
2512{
2513 .mpo_destroy = mac_biba_destroy,
2514 .mpo_init = mac_biba_init,
2515 .mpo_init_bpfdesc_label = mac_biba_init_label,
2516 .mpo_init_cred_label = mac_biba_init_label,
2517 .mpo_init_devfsdirent_label = mac_biba_init_label,
2518 .mpo_init_ifnet_label = mac_biba_init_label,
2519 .mpo_init_ipq_label = mac_biba_init_label,
2520 .mpo_init_mbuf_label = mac_biba_init_label_waitcheck,
2521 .mpo_init_mount_label = mac_biba_init_label,
2522 .mpo_init_mount_fs_label = mac_biba_init_label,
2523 .mpo_init_pipe_label = mac_biba_init_label,
2524 .mpo_init_socket_label = mac_biba_init_label_waitcheck,
2525 .mpo_init_socket_peer_label = mac_biba_init_label_waitcheck,
2526 .mpo_init_vnode_label = mac_biba_init_label,
2527 .mpo_destroy_bpfdesc_label = mac_biba_destroy_label,
2528 .mpo_destroy_cred_label = mac_biba_destroy_label,
2529 .mpo_destroy_devfsdirent_label = mac_biba_destroy_label,
2530 .mpo_destroy_ifnet_label = mac_biba_destroy_label,
2531 .mpo_destroy_ipq_label = mac_biba_destroy_label,
2532 .mpo_destroy_mbuf_label = mac_biba_destroy_label,
2533 .mpo_destroy_mount_label = mac_biba_destroy_label,
2534 .mpo_destroy_mount_fs_label = mac_biba_destroy_label,
2535 .mpo_destroy_pipe_label = mac_biba_destroy_label,
2536 .mpo_destroy_socket_label = mac_biba_destroy_label,
2537 .mpo_destroy_socket_peer_label = mac_biba_destroy_label,
2538 .mpo_destroy_vnode_label = mac_biba_destroy_label,
2539 .mpo_copy_pipe_label = mac_biba_copy_label,
2540 .mpo_copy_vnode_label = mac_biba_copy_label,
2541 .mpo_externalize_cred_label = mac_biba_externalize_label,
2542 .mpo_externalize_ifnet_label = mac_biba_externalize_label,
2543 .mpo_externalize_pipe_label = mac_biba_externalize_label,
2544 .mpo_externalize_socket_label = mac_biba_externalize_label,
2545 .mpo_externalize_socket_peer_label = mac_biba_externalize_label,
2546 .mpo_externalize_vnode_label = mac_biba_externalize_label,
2547 .mpo_internalize_cred_label = mac_biba_internalize_label,
2548 .mpo_internalize_ifnet_label = mac_biba_internalize_label,
2549 .mpo_internalize_pipe_label = mac_biba_internalize_label,
2550 .mpo_internalize_socket_label = mac_biba_internalize_label,
2551 .mpo_internalize_vnode_label = mac_biba_internalize_label,
2552 .mpo_create_devfs_device = mac_biba_create_devfs_device,
2553 .mpo_create_devfs_directory = mac_biba_create_devfs_directory,
2554 .mpo_create_devfs_symlink = mac_biba_create_devfs_symlink,
2555 .mpo_create_devfs_vnode = mac_biba_create_devfs_vnode,
2556 .mpo_create_mount = mac_biba_create_mount,
2557 .mpo_create_root_mount = mac_biba_create_root_mount,
2558 .mpo_relabel_vnode = mac_biba_relabel_vnode,
2559 .mpo_update_devfsdirent = mac_biba_update_devfsdirent,
2560 .mpo_associate_vnode_devfs = mac_biba_associate_vnode_devfs,
2561 .mpo_associate_vnode_extattr = mac_biba_associate_vnode_extattr,
2562 .mpo_associate_vnode_singlelabel = mac_biba_associate_vnode_singlelabel,
2563 .mpo_create_vnode_extattr = mac_biba_create_vnode_extattr,
2564 .mpo_setlabel_vnode_extattr = mac_biba_setlabel_vnode_extattr,
2565 .mpo_create_mbuf_from_socket = mac_biba_create_mbuf_from_socket,
2566 .mpo_create_pipe = mac_biba_create_pipe,
2567 .mpo_create_socket = mac_biba_create_socket,
2568 .mpo_create_socket_from_socket = mac_biba_create_socket_from_socket,
2569 .mpo_relabel_pipe = mac_biba_relabel_pipe,
2570 .mpo_relabel_socket = mac_biba_relabel_socket,
2571 .mpo_set_socket_peer_from_mbuf = mac_biba_set_socket_peer_from_mbuf,
2572 .mpo_set_socket_peer_from_socket = mac_biba_set_socket_peer_from_socket,
2573 .mpo_create_bpfdesc = mac_biba_create_bpfdesc,
2574 .mpo_create_datagram_from_ipq = mac_biba_create_datagram_from_ipq,
2575 .mpo_create_fragment = mac_biba_create_fragment,
2576 .mpo_create_ifnet = mac_biba_create_ifnet,
2577 .mpo_create_ipq = mac_biba_create_ipq,
2578 .mpo_create_mbuf_from_mbuf = mac_biba_create_mbuf_from_mbuf,
2579 .mpo_create_mbuf_linklayer = mac_biba_create_mbuf_linklayer,
2580 .mpo_create_mbuf_from_bpfdesc = mac_biba_create_mbuf_from_bpfdesc,
2581 .mpo_create_mbuf_from_ifnet = mac_biba_create_mbuf_from_ifnet,
2582 .mpo_create_mbuf_multicast_encap = mac_biba_create_mbuf_multicast_encap,
2583 .mpo_create_mbuf_netlayer = mac_biba_create_mbuf_netlayer,
2584 .mpo_fragment_match = mac_biba_fragment_match,
2585 .mpo_relabel_ifnet = mac_biba_relabel_ifnet,
2586 .mpo_update_ipq = mac_biba_update_ipq,
2587 .mpo_create_cred = mac_biba_create_cred,
2588 .mpo_execve_transition = mac_biba_execve_transition,
2589 .mpo_execve_will_transition = mac_biba_execve_will_transition,
2590 .mpo_create_proc0 = mac_biba_create_proc0,
2591 .mpo_create_proc1 = mac_biba_create_proc1,
2592 .mpo_relabel_cred = mac_biba_relabel_cred,
2593 .mpo_check_bpfdesc_receive = mac_biba_check_bpfdesc_receive,
2594 .mpo_check_cred_relabel = mac_biba_check_cred_relabel,
2595 .mpo_check_cred_visible = mac_biba_check_cred_visible,
2596 .mpo_check_ifnet_relabel = mac_biba_check_ifnet_relabel,
2597 .mpo_check_ifnet_transmit = mac_biba_check_ifnet_transmit,
2598 .mpo_check_mount_stat = mac_biba_check_mount_stat,
2599 .mpo_check_pipe_ioctl = mac_biba_check_pipe_ioctl,
2600 .mpo_check_pipe_poll = mac_biba_check_pipe_poll,
2601 .mpo_check_pipe_read = mac_biba_check_pipe_read,
2602 .mpo_check_pipe_relabel = mac_biba_check_pipe_relabel,
2603 .mpo_check_pipe_stat = mac_biba_check_pipe_stat,
2604 .mpo_check_pipe_write = mac_biba_check_pipe_write,
2605 .mpo_check_proc_debug = mac_biba_check_proc_debug,
2606 .mpo_check_proc_sched = mac_biba_check_proc_sched,
2607 .mpo_check_proc_signal = mac_biba_check_proc_signal,
2608 .mpo_check_socket_deliver = mac_biba_check_socket_deliver,
2609 .mpo_check_socket_relabel = mac_biba_check_socket_relabel,
2610 .mpo_check_socket_visible = mac_biba_check_socket_visible,
2611 .mpo_check_system_swapon = mac_biba_check_system_swapon,
2612 .mpo_check_system_sysctl = mac_biba_check_system_sysctl,
2613 .mpo_check_vnode_access = mac_biba_check_vnode_open,
2614 .mpo_check_vnode_chdir = mac_biba_check_vnode_chdir,
2615 .mpo_check_vnode_chroot = mac_biba_check_vnode_chroot,
2616 .mpo_check_vnode_create = mac_biba_check_vnode_create,
2617 .mpo_check_vnode_delete = mac_biba_check_vnode_delete,
2618 .mpo_check_vnode_deleteacl = mac_biba_check_vnode_deleteacl,
2619 .mpo_check_vnode_exec = mac_biba_check_vnode_exec,
2620 .mpo_check_vnode_getacl = mac_biba_check_vnode_getacl,
2621 .mpo_check_vnode_getextattr = mac_biba_check_vnode_getextattr,
2622 .mpo_check_vnode_link = mac_biba_check_vnode_link,
2623 .mpo_check_vnode_lookup = mac_biba_check_vnode_lookup,
2624 .mpo_check_vnode_mmap = mac_biba_check_vnode_mmap,
2625 .mpo_check_vnode_mprotect = mac_biba_check_vnode_mmap,
2626 .mpo_check_vnode_open = mac_biba_check_vnode_open,
2627 .mpo_check_vnode_poll = mac_biba_check_vnode_poll,
2628 .mpo_check_vnode_read = mac_biba_check_vnode_read,
2629 .mpo_check_vnode_readdir = mac_biba_check_vnode_readdir,
2630 .mpo_check_vnode_readlink = mac_biba_check_vnode_readlink,
2631 .mpo_check_vnode_relabel = mac_biba_check_vnode_relabel,
2632 .mpo_check_vnode_rename_from = mac_biba_check_vnode_rename_from,
2633 .mpo_check_vnode_rename_to = mac_biba_check_vnode_rename_to,
2634 .mpo_check_vnode_revoke = mac_biba_check_vnode_revoke,
2635 .mpo_check_vnode_setacl = mac_biba_check_vnode_setacl,
2636 .mpo_check_vnode_setextattr = mac_biba_check_vnode_setextattr,
2637 .mpo_check_vnode_setflags = mac_biba_check_vnode_setflags,
2638 .mpo_check_vnode_setmode = mac_biba_check_vnode_setmode,
2639 .mpo_check_vnode_setowner = mac_biba_check_vnode_setowner,
2640 .mpo_check_vnode_setutimes = mac_biba_check_vnode_setutimes,
2641 .mpo_check_vnode_stat = mac_biba_check_vnode_stat,
2642 .mpo_check_vnode_write = mac_biba_check_vnode_write,
2643};
2644
2645MAC_POLICY_SET(&mac_biba_ops, trustedbsd_mac_biba, "TrustedBSD MAC/Biba",
2646 MPC_LOADTIME_FLAG_NOTLATE, &mac_biba_slot);
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));
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);
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 label *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 label *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_privileged(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 * Relabling network interfaces requires Biba privilege.
1532 */
1533 error = mac_biba_subject_privileged(subj);
1534 if (error)
1535 return (error);
1536
1537 /*
1538 * If the Biba label is to be changed, authorize as appropriate.
1539 */
1540 if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) {
1541 /*
1542 * Rely on the traditional superuser status for the Biba
1543 * interface relabel requirements. XXXMAC: This will go
1544 * away.
1545 */
1546 error = suser_cred(cred, 0);
1547 if (error)
1548 return (EPERM);
1549
1550 /*
1551 * XXXMAC: Additional consistency tests regarding the single
1552 * and the range of the new label might be performed here.
1553 */
1554 }
1555
1556 return (0);
1557}
1558
1559static int
1560mac_biba_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel,
1561 struct mbuf *m, struct label *mbuflabel)
1562{
1563 struct mac_biba *p, *i;
1564
1565 if (!mac_biba_enabled)
1566 return (0);
1567
1568 p = SLOT(mbuflabel);
1569 i = SLOT(ifnetlabel);
1570
1571 return (mac_biba_single_in_range(p, i) ? 0 : EACCES);
1572}
1573
1574static int
1575mac_biba_check_mount_stat(struct ucred *cred, struct mount *mp,
1576 struct label *mntlabel)
1577{
1578 struct mac_biba *subj, *obj;
1579
1580 if (!mac_biba_enabled)
1581 return (0);
1582
1583 subj = SLOT(&cred->cr_label);
1584 obj = SLOT(mntlabel);
1585
1586 if (!mac_biba_dominate_single(obj, subj))
1587 return (EACCES);
1588
1589 return (0);
1590}
1591
1592static int
1593mac_biba_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe,
1594 struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data)
1595{
1596
1597 if(!mac_biba_enabled)
1598 return (0);
1599
1600 /* XXX: This will be implemented soon... */
1601
1602 return (0);
1603}
1604
1605static int
1606mac_biba_check_pipe_poll(struct ucred *cred, struct pipe *pipe,
1607 struct label *pipelabel)
1608{
1609 struct mac_biba *subj, *obj;
1610
1611 if (!mac_biba_enabled)
1612 return (0);
1613
1614 subj = SLOT(&cred->cr_label);
1615 obj = SLOT((pipelabel));
1616
1617 if (!mac_biba_dominate_single(obj, subj))
1618 return (EACCES);
1619
1620 return (0);
1621}
1622
1623static int
1624mac_biba_check_pipe_read(struct ucred *cred, struct pipe *pipe,
1625 struct label *pipelabel)
1626{
1627 struct mac_biba *subj, *obj;
1628
1629 if (!mac_biba_enabled)
1630 return (0);
1631
1632 subj = SLOT(&cred->cr_label);
1633 obj = SLOT((pipelabel));
1634
1635 if (!mac_biba_dominate_single(obj, subj))
1636 return (EACCES);
1637
1638 return (0);
1639}
1640
1641static int
1642mac_biba_check_pipe_relabel(struct ucred *cred, struct pipe *pipe,
1643 struct label *pipelabel, struct label *newlabel)
1644{
1645 struct mac_biba *subj, *obj, *new;
1646 int error;
1647
1648 new = SLOT(newlabel);
1649 subj = SLOT(&cred->cr_label);
1650 obj = SLOT(pipelabel);
1651
1652 /*
1653 * If there is a Biba label update for a pipe, it must be a
1654 * single update.
1655 */
1656 error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE);
1657 if (error)
1658 return (error);
1659
1660 /*
1661 * To perform a relabel of a pipe (Biba label or not), Biba must
1662 * authorize the relabel.
1663 */
1664 if (!mac_biba_single_in_range(obj, subj))
1665 return (EPERM);
1666
1667 /*
1668 * If the Biba label is to be changed, authorize as appropriate.
1669 */
1670 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) {
1671 /*
1672 * To change the Biba label on a pipe, the new pipe label
1673 * must be in the subject range.
1674 */
1675 if (!mac_biba_single_in_range(new, subj))
1676 return (EPERM);
1677
1678 /*
1679 * To change the Biba label on a pipe to be EQUAL, the
1680 * subject must have appropriate privilege.
1681 */
1682 if (mac_biba_contains_equal(new)) {
1683 error = mac_biba_subject_privileged(subj);
1684 if (error)
1685 return (error);
1686 }
1687 }
1688
1689 return (0);
1690}
1691
1692static int
1693mac_biba_check_pipe_stat(struct ucred *cred, struct pipe *pipe,
1694 struct label *pipelabel)
1695{
1696 struct mac_biba *subj, *obj;
1697
1698 if (!mac_biba_enabled)
1699 return (0);
1700
1701 subj = SLOT(&cred->cr_label);
1702 obj = SLOT((pipelabel));
1703
1704 if (!mac_biba_dominate_single(obj, subj))
1705 return (EACCES);
1706
1707 return (0);
1708}
1709
1710static int
1711mac_biba_check_pipe_write(struct ucred *cred, struct pipe *pipe,
1712 struct label *pipelabel)
1713{
1714 struct mac_biba *subj, *obj;
1715
1716 if (!mac_biba_enabled)
1717 return (0);
1718
1719 subj = SLOT(&cred->cr_label);
1720 obj = SLOT((pipelabel));
1721
1722 if (!mac_biba_dominate_single(subj, obj))
1723 return (EACCES);
1724
1725 return (0);
1726}
1727
1728static int
1729mac_biba_check_proc_debug(struct ucred *cred, struct proc *proc)
1730{
1731 struct mac_biba *subj, *obj;
1732
1733 if (!mac_biba_enabled)
1734 return (0);
1735
1736 subj = SLOT(&cred->cr_label);
1737 obj = SLOT(&proc->p_ucred->cr_label);
1738
1739 /* XXX: range checks */
1740 if (!mac_biba_dominate_single(obj, subj))
1741 return (ESRCH);
1742 if (!mac_biba_dominate_single(subj, obj))
1743 return (EACCES);
1744
1745 return (0);
1746}
1747
1748static int
1749mac_biba_check_proc_sched(struct ucred *cred, struct proc *proc)
1750{
1751 struct mac_biba *subj, *obj;
1752
1753 if (!mac_biba_enabled)
1754 return (0);
1755
1756 subj = SLOT(&cred->cr_label);
1757 obj = SLOT(&proc->p_ucred->cr_label);
1758
1759 /* XXX: range checks */
1760 if (!mac_biba_dominate_single(obj, subj))
1761 return (ESRCH);
1762 if (!mac_biba_dominate_single(subj, obj))
1763 return (EACCES);
1764
1765 return (0);
1766}
1767
1768static int
1769mac_biba_check_proc_signal(struct ucred *cred, struct proc *proc, int signum)
1770{
1771 struct mac_biba *subj, *obj;
1772
1773 if (!mac_biba_enabled)
1774 return (0);
1775
1776 subj = SLOT(&cred->cr_label);
1777 obj = SLOT(&proc->p_ucred->cr_label);
1778
1779 /* XXX: range checks */
1780 if (!mac_biba_dominate_single(obj, subj))
1781 return (ESRCH);
1782 if (!mac_biba_dominate_single(subj, obj))
1783 return (EACCES);
1784
1785 return (0);
1786}
1787
1788static int
1789mac_biba_check_socket_deliver(struct socket *so, struct label *socketlabel,
1790 struct mbuf *m, struct label *mbuflabel)
1791{
1792 struct mac_biba *p, *s;
1793
1794 if (!mac_biba_enabled)
1795 return (0);
1796
1797 p = SLOT(mbuflabel);
1798 s = SLOT(socketlabel);
1799
1800 return (mac_biba_equal_single(p, s) ? 0 : EACCES);
1801}
1802
1803static int
1804mac_biba_check_socket_relabel(struct ucred *cred, struct socket *so,
1805 struct label *socketlabel, struct label *newlabel)
1806{
1807 struct mac_biba *subj, *obj, *new;
1808 int error;
1809
1810 new = SLOT(newlabel);
1811 subj = SLOT(&cred->cr_label);
1812 obj = SLOT(socketlabel);
1813
1814 /*
1815 * If there is a Biba label update for the socket, it may be
1816 * an update of single.
1817 */
1818 error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE);
1819 if (error)
1820 return (error);
1821
1822 /*
1823 * To relabel a socket, the old socket single must be in the subject
1824 * range.
1825 */
1826 if (!mac_biba_single_in_range(obj, subj))
1827 return (EPERM);
1828
1829 /*
1830 * If the Biba label is to be changed, authorize as appropriate.
1831 */
1832 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) {
1833 /*
1834 * To relabel a socket, the new socket single must be in
1835 * the subject range.
1836 */
1837 if (!mac_biba_single_in_range(new, subj))
1838 return (EPERM);
1839
1840 /*
1841 * To change the Biba label on the socket to contain EQUAL,
1842 * the subject must have appropriate privilege.
1843 */
1844 if (mac_biba_contains_equal(new)) {
1845 error = mac_biba_subject_privileged(subj);
1846 if (error)
1847 return (error);
1848 }
1849 }
1850
1851 return (0);
1852}
1853
1854static int
1855mac_biba_check_socket_visible(struct ucred *cred, struct socket *socket,
1856 struct label *socketlabel)
1857{
1858 struct mac_biba *subj, *obj;
1859
1860 if (!mac_biba_enabled)
1861 return (0);
1862
1863 subj = SLOT(&cred->cr_label);
1864 obj = SLOT(socketlabel);
1865
1866 if (!mac_biba_dominate_single(obj, subj))
1867 return (ENOENT);
1868
1869 return (0);
1870}
1871
1872static int
1873mac_biba_check_system_swapon(struct ucred *cred, struct vnode *vp,
1874 struct label *label)
1875{
1876 struct mac_biba *subj, *obj;
1877
1878 if (!mac_biba_enabled)
1879 return (0);
1880
1881 subj = SLOT(&cred->cr_label);
1882 obj = SLOT(label);
1883
1884 if (!mac_biba_subject_privileged(subj))
1885 return (EPERM);
1886
1887 if (!mac_biba_high_single(obj))
1888 return (EACCES);
1889
1890 return (0);
1891}
1892
1893static int
1894mac_biba_check_system_sysctl(struct ucred *cred, int *name, u_int namelen,
1895 void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen)
1896{
1897 struct mac_biba *subj;
1898 int error;
1899
1900 if (!mac_biba_enabled)
1901 return (0);
1902
1903 subj = SLOT(&cred->cr_label);
1904
1905 /*
1906 * In general, treat sysctl variables as biba/high, but also
1907 * require privilege to change them, since they are a
1908 * communications channel between grades. Exempt MIB
1909 * queries from this due to undocmented sysctl magic.
1910 * XXXMAC: This probably requires some more review.
1911 */
1912 if (new != NULL) {
1913 if (namelen > 0 && name[0] == 0)
1914 return (0);
1915
1916 if (!mac_biba_subject_dominate_high(subj))
1917 return (EACCES);
1918
1919 error = mac_biba_subject_privileged(subj);
1920 if (error)
1921 return (error);
1922 }
1923
1924 return (0);
1925}
1926
1927static int
1928mac_biba_check_vnode_chdir(struct ucred *cred, struct vnode *dvp,
1929 struct label *dlabel)
1930{
1931 struct mac_biba *subj, *obj;
1932
1933 if (!mac_biba_enabled)
1934 return (0);
1935
1936 subj = SLOT(&cred->cr_label);
1937 obj = SLOT(dlabel);
1938
1939 if (!mac_biba_dominate_single(obj, subj))
1940 return (EACCES);
1941
1942 return (0);
1943}
1944
1945static int
1946mac_biba_check_vnode_chroot(struct ucred *cred, struct vnode *dvp,
1947 struct label *dlabel)
1948{
1949 struct mac_biba *subj, *obj;
1950
1951 if (!mac_biba_enabled)
1952 return (0);
1953
1954 subj = SLOT(&cred->cr_label);
1955 obj = SLOT(dlabel);
1956
1957 if (!mac_biba_dominate_single(obj, subj))
1958 return (EACCES);
1959
1960 return (0);
1961}
1962
1963static int
1964mac_biba_check_vnode_create(struct ucred *cred, struct vnode *dvp,
1965 struct label *dlabel, struct componentname *cnp, struct vattr *vap)
1966{
1967 struct mac_biba *subj, *obj;
1968
1969 if (!mac_biba_enabled)
1970 return (0);
1971
1972 subj = SLOT(&cred->cr_label);
1973 obj = SLOT(dlabel);
1974
1975 if (!mac_biba_dominate_single(subj, obj))
1976 return (EACCES);
1977
1978 return (0);
1979}
1980
1981static int
1982mac_biba_check_vnode_delete(struct ucred *cred, struct vnode *dvp,
1983 struct label *dlabel, struct vnode *vp, struct label *label,
1984 struct componentname *cnp)
1985{
1986 struct mac_biba *subj, *obj;
1987
1988 if (!mac_biba_enabled)
1989 return (0);
1990
1991 subj = SLOT(&cred->cr_label);
1992 obj = SLOT(dlabel);
1993
1994 if (!mac_biba_dominate_single(subj, obj))
1995 return (EACCES);
1996
1997 obj = SLOT(label);
1998
1999 if (!mac_biba_dominate_single(subj, obj))
2000 return (EACCES);
2001
2002 return (0);
2003}
2004
2005static int
2006mac_biba_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
2007 struct label *label, acl_type_t type)
2008{
2009 struct mac_biba *subj, *obj;
2010
2011 if (!mac_biba_enabled)
2012 return (0);
2013
2014 subj = SLOT(&cred->cr_label);
2015 obj = SLOT(label);
2016
2017 if (!mac_biba_dominate_single(subj, obj))
2018 return (EACCES);
2019
2020 return (0);
2021}
2022
2023static int
2024mac_biba_check_vnode_exec(struct ucred *cred, struct vnode *vp,
2025 struct label *label)
2026{
2027 struct mac_biba *subj, *obj;
2028
2029 if (!mac_biba_enabled)
2030 return (0);
2031
2032 subj = SLOT(&cred->cr_label);
2033 obj = SLOT(label);
2034
2035 if (!mac_biba_dominate_single(obj, subj))
2036 return (EACCES);
2037
2038 return (0);
2039}
2040
2041static int
2042mac_biba_check_vnode_getacl(struct ucred *cred, struct vnode *vp,
2043 struct label *label, acl_type_t type)
2044{
2045 struct mac_biba *subj, *obj;
2046
2047 if (!mac_biba_enabled)
2048 return (0);
2049
2050 subj = SLOT(&cred->cr_label);
2051 obj = SLOT(label);
2052
2053 if (!mac_biba_dominate_single(obj, subj))
2054 return (EACCES);
2055
2056 return (0);
2057}
2058
2059static int
2060mac_biba_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
2061 struct label *label, int attrnamespace, const char *name, struct uio *uio)
2062{
2063 struct mac_biba *subj, *obj;
2064
2065 if (!mac_biba_enabled)
2066 return (0);
2067
2068 subj = SLOT(&cred->cr_label);
2069 obj = SLOT(label);
2070
2071 if (!mac_biba_dominate_single(obj, subj))
2072 return (EACCES);
2073
2074 return (0);
2075}
2076
2077static int
2078mac_biba_check_vnode_link(struct ucred *cred, struct vnode *dvp,
2079 struct label *dlabel, struct vnode *vp, struct label *label,
2080 struct componentname *cnp)
2081{
2082 struct mac_biba *subj, *obj;
2083
2084 if (!mac_biba_enabled)
2085 return (0);
2086
2087 subj = SLOT(&cred->cr_label);
2088 obj = SLOT(dlabel);
2089
2090 if (!mac_biba_dominate_single(subj, obj))
2091 return (EACCES);
2092
2093 obj = SLOT(label);
2094
2095 if (!mac_biba_dominate_single(subj, obj))
2096 return (EACCES);
2097
2098 return (0);
2099}
2100
2101static int
2102mac_biba_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
2103 struct label *dlabel, struct componentname *cnp)
2104{
2105 struct mac_biba *subj, *obj;
2106
2107 if (!mac_biba_enabled)
2108 return (0);
2109
2110 subj = SLOT(&cred->cr_label);
2111 obj = SLOT(dlabel);
2112
2113 if (!mac_biba_dominate_single(obj, subj))
2114 return (EACCES);
2115
2116 return (0);
2117}
2118
2119static int
2120mac_biba_check_vnode_mmap(struct ucred *cred, struct vnode *vp,
2121 struct label *label, int prot)
2122{
2123 struct mac_biba *subj, *obj;
2124
2125 /*
2126 * Rely on the use of open()-time protections to handle
2127 * non-revocation cases.
2128 */
2129 if (!mac_biba_enabled || !revocation_enabled)
2130 return (0);
2131
2132 subj = SLOT(&cred->cr_label);
2133 obj = SLOT(label);
2134
2135 if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
2136 if (!mac_biba_dominate_single(obj, subj))
2137 return (EACCES);
2138 }
2139 if (prot & VM_PROT_WRITE) {
2140 if (!mac_biba_dominate_single(subj, obj))
2141 return (EACCES);
2142 }
2143
2144 return (0);
2145}
2146
2147static int
2148mac_biba_check_vnode_open(struct ucred *cred, struct vnode *vp,
2149 struct label *vnodelabel, int acc_mode)
2150{
2151 struct mac_biba *subj, *obj;
2152
2153 if (!mac_biba_enabled)
2154 return (0);
2155
2156 subj = SLOT(&cred->cr_label);
2157 obj = SLOT(vnodelabel);
2158
2159 /* XXX privilege override for admin? */
2160 if (acc_mode & (VREAD | VEXEC | VSTAT)) {
2161 if (!mac_biba_dominate_single(obj, subj))
2162 return (EACCES);
2163 }
2164 if (acc_mode & (VWRITE | VAPPEND | VADMIN)) {
2165 if (!mac_biba_dominate_single(subj, obj))
2166 return (EACCES);
2167 }
2168
2169 return (0);
2170}
2171
2172static int
2173mac_biba_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred,
2174 struct vnode *vp, struct label *label)
2175{
2176 struct mac_biba *subj, *obj;
2177
2178 if (!mac_biba_enabled || !revocation_enabled)
2179 return (0);
2180
2181 subj = SLOT(&active_cred->cr_label);
2182 obj = SLOT(label);
2183
2184 if (!mac_biba_dominate_single(obj, subj))
2185 return (EACCES);
2186
2187 return (0);
2188}
2189
2190static int
2191mac_biba_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
2192 struct vnode *vp, struct label *label)
2193{
2194 struct mac_biba *subj, *obj;
2195
2196 if (!mac_biba_enabled || !revocation_enabled)
2197 return (0);
2198
2199 subj = SLOT(&active_cred->cr_label);
2200 obj = SLOT(label);
2201
2202 if (!mac_biba_dominate_single(obj, subj))
2203 return (EACCES);
2204
2205 return (0);
2206}
2207
2208static int
2209mac_biba_check_vnode_readdir(struct ucred *cred, struct vnode *dvp,
2210 struct label *dlabel)
2211{
2212 struct mac_biba *subj, *obj;
2213
2214 if (!mac_biba_enabled)
2215 return (0);
2216
2217 subj = SLOT(&cred->cr_label);
2218 obj = SLOT(dlabel);
2219
2220 if (!mac_biba_dominate_single(obj, subj))
2221 return (EACCES);
2222
2223 return (0);
2224}
2225
2226static int
2227mac_biba_check_vnode_readlink(struct ucred *cred, struct vnode *vp,
2228 struct label *label)
2229{
2230 struct mac_biba *subj, *obj;
2231
2232 if (!mac_biba_enabled)
2233 return (0);
2234
2235 subj = SLOT(&cred->cr_label);
2236 obj = SLOT(label);
2237
2238 if (!mac_biba_dominate_single(obj, subj))
2239 return (EACCES);
2240
2241 return (0);
2242}
2243
2244static int
2245mac_biba_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
2246 struct label *vnodelabel, struct label *newlabel)
2247{
2248 struct mac_biba *old, *new, *subj;
2249 int error;
2250
2251 old = SLOT(vnodelabel);
2252 new = SLOT(newlabel);
2253 subj = SLOT(&cred->cr_label);
2254
2255 /*
2256 * If there is a Biba label update for the vnode, it must be a
2257 * single label.
2258 */
2259 error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE);
2260 if (error)
2261 return (error);
2262
2263 /*
2264 * To perform a relabel of the vnode (Biba label or not), Biba must
2265 * authorize the relabel.
2266 */
2267 if (!mac_biba_single_in_range(old, subj))
2268 return (EPERM);
2269
2270 /*
2271 * If the Biba label is to be changed, authorize as appropriate.
2272 */
2273 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) {
2274 /*
2275 * To change the Biba label on a vnode, the new vnode label
2276 * must be in the subject range.
2277 */
2278 if (!mac_biba_single_in_range(new, subj))
2279 return (EPERM);
2280
2281 /*
2282 * To change the Biba label on the vnode to be EQUAL,
2283 * the subject must have appropriate privilege.
2284 */
2285 if (mac_biba_contains_equal(new)) {
2286 error = mac_biba_subject_privileged(subj);
2287 if (error)
2288 return (error);
2289 }
2290 }
2291
2292 return (0);
2293}
2294
2295static int
2296mac_biba_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
2297 struct label *dlabel, struct vnode *vp, struct label *label,
2298 struct componentname *cnp)
2299{
2300 struct mac_biba *subj, *obj;
2301
2302 if (!mac_biba_enabled)
2303 return (0);
2304
2305 subj = SLOT(&cred->cr_label);
2306 obj = SLOT(dlabel);
2307
2308 if (!mac_biba_dominate_single(subj, obj))
2309 return (EACCES);
2310
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_rename_to(struct ucred *cred, struct vnode *dvp,
2321 struct label *dlabel, struct vnode *vp, struct label *label, int samedir,
2322 struct componentname *cnp)
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(dlabel);
2331
2332 if (!mac_biba_dominate_single(subj, obj))
2333 return (EACCES);
2334
2335 if (vp != NULL) {
2336 obj = SLOT(label);
2337
2338 if (!mac_biba_dominate_single(subj, obj))
2339 return (EACCES);
2340 }
2341
2342 return (0);
2343}
2344
2345static int
2346mac_biba_check_vnode_revoke(struct ucred *cred, struct vnode *vp,
2347 struct label *label)
2348{
2349 struct mac_biba *subj, *obj;
2350
2351 if (!mac_biba_enabled)
2352 return (0);
2353
2354 subj = SLOT(&cred->cr_label);
2355 obj = SLOT(label);
2356
2357 if (!mac_biba_dominate_single(subj, obj))
2358 return (EACCES);
2359
2360 return (0);
2361}
2362
2363static int
2364mac_biba_check_vnode_setacl(struct ucred *cred, struct vnode *vp,
2365 struct label *label, acl_type_t type, struct acl *acl)
2366{
2367 struct mac_biba *subj, *obj;
2368
2369 if (!mac_biba_enabled)
2370 return (0);
2371
2372 subj = SLOT(&cred->cr_label);
2373 obj = SLOT(label);
2374
2375 if (!mac_biba_dominate_single(subj, obj))
2376 return (EACCES);
2377
2378 return (0);
2379}
2380
2381static int
2382mac_biba_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
2383 struct label *vnodelabel, int attrnamespace, const char *name,
2384 struct uio *uio)
2385{
2386 struct mac_biba *subj, *obj;
2387
2388 if (!mac_biba_enabled)
2389 return (0);
2390
2391 subj = SLOT(&cred->cr_label);
2392 obj = SLOT(vnodelabel);
2393
2394 if (!mac_biba_dominate_single(subj, obj))
2395 return (EACCES);
2396
2397 /* XXX: protect the MAC EA in a special way? */
2398
2399 return (0);
2400}
2401
2402static int
2403mac_biba_check_vnode_setflags(struct ucred *cred, struct vnode *vp,
2404 struct label *vnodelabel, u_long flags)
2405{
2406 struct mac_biba *subj, *obj;
2407
2408 if (!mac_biba_enabled)
2409 return (0);
2410
2411 subj = SLOT(&cred->cr_label);
2412 obj = SLOT(vnodelabel);
2413
2414 if (!mac_biba_dominate_single(subj, obj))
2415 return (EACCES);
2416
2417 return (0);
2418}
2419
2420static int
2421mac_biba_check_vnode_setmode(struct ucred *cred, struct vnode *vp,
2422 struct label *vnodelabel, mode_t mode)
2423{
2424 struct mac_biba *subj, *obj;
2425
2426 if (!mac_biba_enabled)
2427 return (0);
2428
2429 subj = SLOT(&cred->cr_label);
2430 obj = SLOT(vnodelabel);
2431
2432 if (!mac_biba_dominate_single(subj, obj))
2433 return (EACCES);
2434
2435 return (0);
2436}
2437
2438static int
2439mac_biba_check_vnode_setowner(struct ucred *cred, struct vnode *vp,
2440 struct label *vnodelabel, uid_t uid, gid_t gid)
2441{
2442 struct mac_biba *subj, *obj;
2443
2444 if (!mac_biba_enabled)
2445 return (0);
2446
2447 subj = SLOT(&cred->cr_label);
2448 obj = SLOT(vnodelabel);
2449
2450 if (!mac_biba_dominate_single(subj, obj))
2451 return (EACCES);
2452
2453 return (0);
2454}
2455
2456static int
2457mac_biba_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
2458 struct label *vnodelabel, struct timespec atime, struct timespec mtime)
2459{
2460 struct mac_biba *subj, *obj;
2461
2462 if (!mac_biba_enabled)
2463 return (0);
2464
2465 subj = SLOT(&cred->cr_label);
2466 obj = SLOT(vnodelabel);
2467
2468 if (!mac_biba_dominate_single(subj, obj))
2469 return (EACCES);
2470
2471 return (0);
2472}
2473
2474static int
2475mac_biba_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
2476 struct vnode *vp, struct label *vnodelabel)
2477{
2478 struct mac_biba *subj, *obj;
2479
2480 if (!mac_biba_enabled)
2481 return (0);
2482
2483 subj = SLOT(&active_cred->cr_label);
2484 obj = SLOT(vnodelabel);
2485
2486 if (!mac_biba_dominate_single(obj, subj))
2487 return (EACCES);
2488
2489 return (0);
2490}
2491
2492static int
2493mac_biba_check_vnode_write(struct ucred *active_cred,
2494 struct ucred *file_cred, struct vnode *vp, struct label *label)
2495{
2496 struct mac_biba *subj, *obj;
2497
2498 if (!mac_biba_enabled || !revocation_enabled)
2499 return (0);
2500
2501 subj = SLOT(&active_cred->cr_label);
2502 obj = SLOT(label);
2503
2504 if (!mac_biba_dominate_single(subj, obj))
2505 return (EACCES);
2506
2507 return (0);
2508}
2509
2510static struct mac_policy_ops mac_biba_ops =
2511{
2512 .mpo_destroy = mac_biba_destroy,
2513 .mpo_init = mac_biba_init,
2514 .mpo_init_bpfdesc_label = mac_biba_init_label,
2515 .mpo_init_cred_label = mac_biba_init_label,
2516 .mpo_init_devfsdirent_label = mac_biba_init_label,
2517 .mpo_init_ifnet_label = mac_biba_init_label,
2518 .mpo_init_ipq_label = mac_biba_init_label,
2519 .mpo_init_mbuf_label = mac_biba_init_label_waitcheck,
2520 .mpo_init_mount_label = mac_biba_init_label,
2521 .mpo_init_mount_fs_label = mac_biba_init_label,
2522 .mpo_init_pipe_label = mac_biba_init_label,
2523 .mpo_init_socket_label = mac_biba_init_label_waitcheck,
2524 .mpo_init_socket_peer_label = mac_biba_init_label_waitcheck,
2525 .mpo_init_vnode_label = mac_biba_init_label,
2526 .mpo_destroy_bpfdesc_label = mac_biba_destroy_label,
2527 .mpo_destroy_cred_label = mac_biba_destroy_label,
2528 .mpo_destroy_devfsdirent_label = mac_biba_destroy_label,
2529 .mpo_destroy_ifnet_label = mac_biba_destroy_label,
2530 .mpo_destroy_ipq_label = mac_biba_destroy_label,
2531 .mpo_destroy_mbuf_label = mac_biba_destroy_label,
2532 .mpo_destroy_mount_label = mac_biba_destroy_label,
2533 .mpo_destroy_mount_fs_label = mac_biba_destroy_label,
2534 .mpo_destroy_pipe_label = mac_biba_destroy_label,
2535 .mpo_destroy_socket_label = mac_biba_destroy_label,
2536 .mpo_destroy_socket_peer_label = mac_biba_destroy_label,
2537 .mpo_destroy_vnode_label = mac_biba_destroy_label,
2538 .mpo_copy_pipe_label = mac_biba_copy_label,
2539 .mpo_copy_vnode_label = mac_biba_copy_label,
2540 .mpo_externalize_cred_label = mac_biba_externalize_label,
2541 .mpo_externalize_ifnet_label = mac_biba_externalize_label,
2542 .mpo_externalize_pipe_label = mac_biba_externalize_label,
2543 .mpo_externalize_socket_label = mac_biba_externalize_label,
2544 .mpo_externalize_socket_peer_label = mac_biba_externalize_label,
2545 .mpo_externalize_vnode_label = mac_biba_externalize_label,
2546 .mpo_internalize_cred_label = mac_biba_internalize_label,
2547 .mpo_internalize_ifnet_label = mac_biba_internalize_label,
2548 .mpo_internalize_pipe_label = mac_biba_internalize_label,
2549 .mpo_internalize_socket_label = mac_biba_internalize_label,
2550 .mpo_internalize_vnode_label = mac_biba_internalize_label,
2551 .mpo_create_devfs_device = mac_biba_create_devfs_device,
2552 .mpo_create_devfs_directory = mac_biba_create_devfs_directory,
2553 .mpo_create_devfs_symlink = mac_biba_create_devfs_symlink,
2554 .mpo_create_devfs_vnode = mac_biba_create_devfs_vnode,
2555 .mpo_create_mount = mac_biba_create_mount,
2556 .mpo_create_root_mount = mac_biba_create_root_mount,
2557 .mpo_relabel_vnode = mac_biba_relabel_vnode,
2558 .mpo_update_devfsdirent = mac_biba_update_devfsdirent,
2559 .mpo_associate_vnode_devfs = mac_biba_associate_vnode_devfs,
2560 .mpo_associate_vnode_extattr = mac_biba_associate_vnode_extattr,
2561 .mpo_associate_vnode_singlelabel = mac_biba_associate_vnode_singlelabel,
2562 .mpo_create_vnode_extattr = mac_biba_create_vnode_extattr,
2563 .mpo_setlabel_vnode_extattr = mac_biba_setlabel_vnode_extattr,
2564 .mpo_create_mbuf_from_socket = mac_biba_create_mbuf_from_socket,
2565 .mpo_create_pipe = mac_biba_create_pipe,
2566 .mpo_create_socket = mac_biba_create_socket,
2567 .mpo_create_socket_from_socket = mac_biba_create_socket_from_socket,
2568 .mpo_relabel_pipe = mac_biba_relabel_pipe,
2569 .mpo_relabel_socket = mac_biba_relabel_socket,
2570 .mpo_set_socket_peer_from_mbuf = mac_biba_set_socket_peer_from_mbuf,
2571 .mpo_set_socket_peer_from_socket = mac_biba_set_socket_peer_from_socket,
2572 .mpo_create_bpfdesc = mac_biba_create_bpfdesc,
2573 .mpo_create_datagram_from_ipq = mac_biba_create_datagram_from_ipq,
2574 .mpo_create_fragment = mac_biba_create_fragment,
2575 .mpo_create_ifnet = mac_biba_create_ifnet,
2576 .mpo_create_ipq = mac_biba_create_ipq,
2577 .mpo_create_mbuf_from_mbuf = mac_biba_create_mbuf_from_mbuf,
2578 .mpo_create_mbuf_linklayer = mac_biba_create_mbuf_linklayer,
2579 .mpo_create_mbuf_from_bpfdesc = mac_biba_create_mbuf_from_bpfdesc,
2580 .mpo_create_mbuf_from_ifnet = mac_biba_create_mbuf_from_ifnet,
2581 .mpo_create_mbuf_multicast_encap = mac_biba_create_mbuf_multicast_encap,
2582 .mpo_create_mbuf_netlayer = mac_biba_create_mbuf_netlayer,
2583 .mpo_fragment_match = mac_biba_fragment_match,
2584 .mpo_relabel_ifnet = mac_biba_relabel_ifnet,
2585 .mpo_update_ipq = mac_biba_update_ipq,
2586 .mpo_create_cred = mac_biba_create_cred,
2587 .mpo_execve_transition = mac_biba_execve_transition,
2588 .mpo_execve_will_transition = mac_biba_execve_will_transition,
2589 .mpo_create_proc0 = mac_biba_create_proc0,
2590 .mpo_create_proc1 = mac_biba_create_proc1,
2591 .mpo_relabel_cred = mac_biba_relabel_cred,
2592 .mpo_check_bpfdesc_receive = mac_biba_check_bpfdesc_receive,
2593 .mpo_check_cred_relabel = mac_biba_check_cred_relabel,
2594 .mpo_check_cred_visible = mac_biba_check_cred_visible,
2595 .mpo_check_ifnet_relabel = mac_biba_check_ifnet_relabel,
2596 .mpo_check_ifnet_transmit = mac_biba_check_ifnet_transmit,
2597 .mpo_check_mount_stat = mac_biba_check_mount_stat,
2598 .mpo_check_pipe_ioctl = mac_biba_check_pipe_ioctl,
2599 .mpo_check_pipe_poll = mac_biba_check_pipe_poll,
2600 .mpo_check_pipe_read = mac_biba_check_pipe_read,
2601 .mpo_check_pipe_relabel = mac_biba_check_pipe_relabel,
2602 .mpo_check_pipe_stat = mac_biba_check_pipe_stat,
2603 .mpo_check_pipe_write = mac_biba_check_pipe_write,
2604 .mpo_check_proc_debug = mac_biba_check_proc_debug,
2605 .mpo_check_proc_sched = mac_biba_check_proc_sched,
2606 .mpo_check_proc_signal = mac_biba_check_proc_signal,
2607 .mpo_check_socket_deliver = mac_biba_check_socket_deliver,
2608 .mpo_check_socket_relabel = mac_biba_check_socket_relabel,
2609 .mpo_check_socket_visible = mac_biba_check_socket_visible,
2610 .mpo_check_system_swapon = mac_biba_check_system_swapon,
2611 .mpo_check_system_sysctl = mac_biba_check_system_sysctl,
2612 .mpo_check_vnode_access = mac_biba_check_vnode_open,
2613 .mpo_check_vnode_chdir = mac_biba_check_vnode_chdir,
2614 .mpo_check_vnode_chroot = mac_biba_check_vnode_chroot,
2615 .mpo_check_vnode_create = mac_biba_check_vnode_create,
2616 .mpo_check_vnode_delete = mac_biba_check_vnode_delete,
2617 .mpo_check_vnode_deleteacl = mac_biba_check_vnode_deleteacl,
2618 .mpo_check_vnode_exec = mac_biba_check_vnode_exec,
2619 .mpo_check_vnode_getacl = mac_biba_check_vnode_getacl,
2620 .mpo_check_vnode_getextattr = mac_biba_check_vnode_getextattr,
2621 .mpo_check_vnode_link = mac_biba_check_vnode_link,
2622 .mpo_check_vnode_lookup = mac_biba_check_vnode_lookup,
2623 .mpo_check_vnode_mmap = mac_biba_check_vnode_mmap,
2624 .mpo_check_vnode_mprotect = mac_biba_check_vnode_mmap,
2625 .mpo_check_vnode_open = mac_biba_check_vnode_open,
2626 .mpo_check_vnode_poll = mac_biba_check_vnode_poll,
2627 .mpo_check_vnode_read = mac_biba_check_vnode_read,
2628 .mpo_check_vnode_readdir = mac_biba_check_vnode_readdir,
2629 .mpo_check_vnode_readlink = mac_biba_check_vnode_readlink,
2630 .mpo_check_vnode_relabel = mac_biba_check_vnode_relabel,
2631 .mpo_check_vnode_rename_from = mac_biba_check_vnode_rename_from,
2632 .mpo_check_vnode_rename_to = mac_biba_check_vnode_rename_to,
2633 .mpo_check_vnode_revoke = mac_biba_check_vnode_revoke,
2634 .mpo_check_vnode_setacl = mac_biba_check_vnode_setacl,
2635 .mpo_check_vnode_setextattr = mac_biba_check_vnode_setextattr,
2636 .mpo_check_vnode_setflags = mac_biba_check_vnode_setflags,
2637 .mpo_check_vnode_setmode = mac_biba_check_vnode_setmode,
2638 .mpo_check_vnode_setowner = mac_biba_check_vnode_setowner,
2639 .mpo_check_vnode_setutimes = mac_biba_check_vnode_setutimes,
2640 .mpo_check_vnode_stat = mac_biba_check_vnode_stat,
2641 .mpo_check_vnode_write = mac_biba_check_vnode_write,
2642};
2643
2644MAC_POLICY_SET(&mac_biba_ops, trustedbsd_mac_biba, "TrustedBSD MAC/Biba",
2645 MPC_LOADTIME_FLAG_NOTLATE, &mac_biba_slot);