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