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