mac_biba.c revision 112574
1101099Srwatson/*-
2101099Srwatson * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson
3101099Srwatson * Copyright (c) 2001, 2002 Networks Associates Technology, Inc.
4101099Srwatson * All rights reserved.
5101099Srwatson *
6101099Srwatson * This software was developed by Robert Watson for the TrustedBSD Project.
7101099Srwatson *
8106393Srwatson * This software was developed for the FreeBSD Project in part by Network
9106393Srwatson * Associates Laboratories, the Security Research Division of Network
10106393Srwatson * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"),
11106393Srwatson * as part of the DARPA CHATS research program.
12101099Srwatson *
13101099Srwatson * Redistribution and use in source and binary forms, with or without
14101099Srwatson * modification, are permitted provided that the following conditions
15101099Srwatson * are met:
16101099Srwatson * 1. Redistributions of source code must retain the above copyright
17101099Srwatson *    notice, this list of conditions and the following disclaimer.
18101099Srwatson * 2. Redistributions in binary form must reproduce the above copyright
19101099Srwatson *    notice, this list of conditions and the following disclaimer in the
20101099Srwatson *    documentation and/or other materials provided with the distribution.
21101099Srwatson *
22101099Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
23101099Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24101099Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25101099Srwatson * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
26101099Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27101099Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28101099Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29101099Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30101099Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31101099Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32101099Srwatson * SUCH DAMAGE.
33101099Srwatson *
34101099Srwatson * $FreeBSD: head/sys/security/mac_biba/mac_biba.c 112574 2003-03-25 01:10:54Z rwatson $
35101099Srwatson */
36101099Srwatson
37101099Srwatson/*
38101099Srwatson * Developed by the TrustedBSD Project.
39101099Srwatson * Biba fixed label mandatory integrity policy.
40101099Srwatson */
41101099Srwatson
42101099Srwatson#include <sys/types.h>
43101099Srwatson#include <sys/param.h>
44101099Srwatson#include <sys/acl.h>
45101099Srwatson#include <sys/conf.h>
46105988Srwatson#include <sys/extattr.h>
47101099Srwatson#include <sys/kernel.h>
48101099Srwatson#include <sys/mac.h>
49103183Sbde#include <sys/malloc.h>
50101099Srwatson#include <sys/mount.h>
51101099Srwatson#include <sys/proc.h>
52101099Srwatson#include <sys/systm.h>
53101099Srwatson#include <sys/sysproto.h>
54101099Srwatson#include <sys/sysent.h>
55105696Srwatson#include <sys/systm.h>
56101099Srwatson#include <sys/vnode.h>
57101099Srwatson#include <sys/file.h>
58101099Srwatson#include <sys/socket.h>
59101099Srwatson#include <sys/socketvar.h>
60101099Srwatson#include <sys/pipe.h>
61101099Srwatson#include <sys/sysctl.h>
62101099Srwatson
63101099Srwatson#include <fs/devfs/devfs.h>
64101099Srwatson
65101099Srwatson#include <net/bpfdesc.h>
66101099Srwatson#include <net/if.h>
67101099Srwatson#include <net/if_types.h>
68101099Srwatson#include <net/if_var.h>
69101099Srwatson
70101099Srwatson#include <netinet/in.h>
71101099Srwatson#include <netinet/ip_var.h>
72101099Srwatson
73101099Srwatson#include <vm/vm.h>
74101099Srwatson
75101099Srwatson#include <sys/mac_policy.h>
76101099Srwatson
77101099Srwatson#include <security/mac_biba/mac_biba.h>
78101099Srwatson
79101099SrwatsonSYSCTL_DECL(_security_mac);
80101099Srwatson
81101099SrwatsonSYSCTL_NODE(_security_mac, OID_AUTO, biba, CTLFLAG_RW, 0,
82101099Srwatson    "TrustedBSD mac_biba policy controls");
83101099Srwatson
84105988Srwatsonstatic int	mac_biba_label_size = sizeof(struct mac_biba);
85105988SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, label_size, CTLFLAG_RD,
86105988Srwatson    &mac_biba_label_size, 0, "Size of struct mac_biba");
87105988Srwatson
88107731Srwatsonstatic int	mac_biba_enabled = 1;
89101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, enabled, CTLFLAG_RW,
90101099Srwatson    &mac_biba_enabled, 0, "Enforce MAC/Biba policy");
91102980SrwatsonTUNABLE_INT("security.mac.biba.enabled", &mac_biba_enabled);
92101099Srwatson
93101099Srwatsonstatic int	destroyed_not_inited;
94101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, destroyed_not_inited, CTLFLAG_RD,
95101099Srwatson    &destroyed_not_inited, 0, "Count of labels destroyed but not inited");
96101099Srwatson
97101099Srwatsonstatic int	trust_all_interfaces = 0;
98101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, trust_all_interfaces, CTLFLAG_RD,
99101099Srwatson    &trust_all_interfaces, 0, "Consider all interfaces 'trusted' by MAC/Biba");
100101099SrwatsonTUNABLE_INT("security.mac.biba.trust_all_interfaces", &trust_all_interfaces);
101101099Srwatson
102101099Srwatsonstatic char	trusted_interfaces[128];
103101099SrwatsonSYSCTL_STRING(_security_mac_biba, OID_AUTO, trusted_interfaces, CTLFLAG_RD,
104101099Srwatson    trusted_interfaces, 0, "Interfaces considered 'trusted' by MAC/Biba");
105101099SrwatsonTUNABLE_STR("security.mac.biba.trusted_interfaces", trusted_interfaces,
106101099Srwatson    sizeof(trusted_interfaces));
107101099Srwatson
108105643Srwatsonstatic int	max_compartments = MAC_BIBA_MAX_COMPARTMENTS;
109105643SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, max_compartments, CTLFLAG_RD,
110105643Srwatson    &max_compartments, 0, "Maximum supported compartments");
111105643Srwatson
112105606Srwatsonstatic int	ptys_equal = 0;
113105606SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, ptys_equal, CTLFLAG_RW,
114105606Srwatson    &ptys_equal, 0, "Label pty devices as biba/equal on create");
115105606SrwatsonTUNABLE_INT("security.mac.biba.ptys_equal", &ptys_equal);
116105606Srwatson
117105637Srwatsonstatic int	revocation_enabled = 0;
118101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, revocation_enabled, CTLFLAG_RW,
119105637Srwatson    &revocation_enabled, 0, "Revoke access to objects on relabel");
120105637SrwatsonTUNABLE_INT("security.mac.biba.revocation_enabled", &revocation_enabled);
121101099Srwatson
122101099Srwatsonstatic int	mac_biba_slot;
123101099Srwatson#define	SLOT(l)	((struct mac_biba *)LABEL_TO_SLOT((l), mac_biba_slot).l_ptr)
124101099Srwatson
125101099SrwatsonMALLOC_DEFINE(M_MACBIBA, "biba label", "MAC/Biba labels");
126101099Srwatson
127105643Srwatsonstatic __inline int
128105643Srwatsonbiba_bit_set_empty(u_char *set) {
129105643Srwatson	int i;
130105643Srwatson
131105643Srwatson	for (i = 0; i < MAC_BIBA_MAX_COMPARTMENTS >> 3; i++)
132105643Srwatson		if (set[i] != 0)
133105643Srwatson			return (0);
134105643Srwatson	return (1);
135105643Srwatson}
136105643Srwatson
137101099Srwatsonstatic struct mac_biba *
138104514Srwatsonbiba_alloc(int flag)
139101099Srwatson{
140101099Srwatson	struct mac_biba *mac_biba;
141101099Srwatson
142104514Srwatson	mac_biba = malloc(sizeof(struct mac_biba), M_MACBIBA, M_ZERO | flag);
143101099Srwatson
144101099Srwatson	return (mac_biba);
145101099Srwatson}
146101099Srwatson
147101099Srwatsonstatic void
148101099Srwatsonbiba_free(struct mac_biba *mac_biba)
149101099Srwatson{
150101099Srwatson
151101099Srwatson	if (mac_biba != NULL)
152101099Srwatson		free(mac_biba, M_MACBIBA);
153101099Srwatson	else
154101099Srwatson		atomic_add_int(&destroyed_not_inited, 1);
155101099Srwatson}
156101099Srwatson
157101099Srwatsonstatic int
158105634Srwatsonbiba_atmostflags(struct mac_biba *mac_biba, int flags)
159105634Srwatson{
160105634Srwatson
161105634Srwatson	if ((mac_biba->mb_flags & flags) != mac_biba->mb_flags)
162105634Srwatson		return (EINVAL);
163105634Srwatson	return (0);
164105634Srwatson}
165105634Srwatson
166105634Srwatsonstatic int
167101099Srwatsonmac_biba_dominate_element(struct mac_biba_element *a,
168101099Srwatson    struct mac_biba_element *b)
169101099Srwatson{
170105643Srwatson	int bit;
171101099Srwatson
172105736Srwatson	switch (a->mbe_type) {
173101099Srwatson	case MAC_BIBA_TYPE_EQUAL:
174101099Srwatson	case MAC_BIBA_TYPE_HIGH:
175101099Srwatson		return (1);
176101099Srwatson
177101099Srwatson	case MAC_BIBA_TYPE_LOW:
178101099Srwatson		switch (b->mbe_type) {
179101099Srwatson		case MAC_BIBA_TYPE_GRADE:
180101099Srwatson		case MAC_BIBA_TYPE_HIGH:
181101099Srwatson			return (0);
182101099Srwatson
183101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
184101099Srwatson		case MAC_BIBA_TYPE_LOW:
185101099Srwatson			return (1);
186101099Srwatson
187101099Srwatson		default:
188101099Srwatson			panic("mac_biba_dominate_element: b->mbe_type invalid");
189101099Srwatson		}
190101099Srwatson
191101099Srwatson	case MAC_BIBA_TYPE_GRADE:
192101099Srwatson		switch (b->mbe_type) {
193101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
194101099Srwatson		case MAC_BIBA_TYPE_LOW:
195101099Srwatson			return (1);
196101099Srwatson
197101099Srwatson		case MAC_BIBA_TYPE_HIGH:
198101099Srwatson			return (0);
199101099Srwatson
200101099Srwatson		case MAC_BIBA_TYPE_GRADE:
201105643Srwatson			for (bit = 1; bit <= MAC_BIBA_MAX_COMPARTMENTS; bit++)
202105643Srwatson				if (!MAC_BIBA_BIT_TEST(bit,
203105643Srwatson				    a->mbe_compartments) &&
204105643Srwatson				    MAC_BIBA_BIT_TEST(bit, b->mbe_compartments))
205105643Srwatson					return (0);
206101099Srwatson			return (a->mbe_grade >= b->mbe_grade);
207101099Srwatson
208101099Srwatson		default:
209101099Srwatson			panic("mac_biba_dominate_element: b->mbe_type invalid");
210101099Srwatson		}
211101099Srwatson
212101099Srwatson	default:
213101099Srwatson		panic("mac_biba_dominate_element: a->mbe_type invalid");
214101099Srwatson	}
215101099Srwatson
216101099Srwatson	return (0);
217101099Srwatson}
218101099Srwatson
219101099Srwatsonstatic int
220105988Srwatsonmac_biba_subject_dominate_high(struct mac_biba *mac_biba)
221105988Srwatson{
222105988Srwatson	struct mac_biba_element *element;
223105988Srwatson
224106174Srwatson	KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
225105988Srwatson	    ("mac_biba_single_in_range: mac_biba not single"));
226105988Srwatson	element = &mac_biba->mb_single;
227105988Srwatson
228105988Srwatson	return (element->mbe_type == MAC_BIBA_TYPE_EQUAL ||
229105988Srwatson	    element->mbe_type == MAC_BIBA_TYPE_HIGH);
230105988Srwatson}
231105988Srwatson
232105988Srwatsonstatic int
233101099Srwatsonmac_biba_range_in_range(struct mac_biba *rangea, struct mac_biba *rangeb)
234101099Srwatson{
235101099Srwatson
236101099Srwatson	return (mac_biba_dominate_element(&rangeb->mb_rangehigh,
237101099Srwatson	    &rangea->mb_rangehigh) &&
238101099Srwatson	    mac_biba_dominate_element(&rangea->mb_rangelow,
239101099Srwatson	    &rangeb->mb_rangelow));
240101099Srwatson}
241101099Srwatson
242101099Srwatsonstatic int
243101099Srwatsonmac_biba_single_in_range(struct mac_biba *single, struct mac_biba *range)
244101099Srwatson{
245101099Srwatson
246103750Srwatson	KASSERT((single->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
247101099Srwatson	    ("mac_biba_single_in_range: a not single"));
248103750Srwatson	KASSERT((range->mb_flags & MAC_BIBA_FLAG_RANGE) != 0,
249101099Srwatson	    ("mac_biba_single_in_range: b not range"));
250101099Srwatson
251101099Srwatson	return (mac_biba_dominate_element(&range->mb_rangehigh,
252101099Srwatson	    &single->mb_single) &&
253101099Srwatson	    mac_biba_dominate_element(&single->mb_single,
254101099Srwatson	    &range->mb_rangelow));
255101099Srwatson
256101099Srwatson	return (1);
257101099Srwatson}
258101099Srwatson
259101099Srwatsonstatic int
260101099Srwatsonmac_biba_dominate_single(struct mac_biba *a, struct mac_biba *b)
261101099Srwatson{
262101099Srwatson	KASSERT((a->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
263101099Srwatson	    ("mac_biba_dominate_single: a not single"));
264101099Srwatson	KASSERT((b->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
265101099Srwatson	    ("mac_biba_dominate_single: b not single"));
266101099Srwatson
267101099Srwatson	return (mac_biba_dominate_element(&a->mb_single, &b->mb_single));
268101099Srwatson}
269101099Srwatson
270101099Srwatsonstatic int
271101099Srwatsonmac_biba_equal_element(struct mac_biba_element *a, struct mac_biba_element *b)
272101099Srwatson{
273101099Srwatson
274101099Srwatson	if (a->mbe_type == MAC_BIBA_TYPE_EQUAL ||
275101099Srwatson	    b->mbe_type == MAC_BIBA_TYPE_EQUAL)
276101099Srwatson		return (1);
277101099Srwatson
278101099Srwatson	return (a->mbe_type == b->mbe_type && a->mbe_grade == b->mbe_grade);
279101099Srwatson}
280101099Srwatson
281101099Srwatsonstatic int
282101099Srwatsonmac_biba_equal_single(struct mac_biba *a, struct mac_biba *b)
283101099Srwatson{
284101099Srwatson
285101099Srwatson	KASSERT((a->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
286101099Srwatson	    ("mac_biba_equal_single: a not single"));
287101099Srwatson	KASSERT((b->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
288101099Srwatson	    ("mac_biba_equal_single: b not single"));
289101099Srwatson
290101099Srwatson	return (mac_biba_equal_element(&a->mb_single, &b->mb_single));
291101099Srwatson}
292101099Srwatson
293101099Srwatsonstatic int
294105634Srwatsonmac_biba_contains_equal(struct mac_biba *mac_biba)
295105634Srwatson{
296105634Srwatson
297105634Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE)
298105634Srwatson		if (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_EQUAL)
299105634Srwatson			return (1);
300105634Srwatson
301105634Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
302105634Srwatson		if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL)
303105634Srwatson			return (1);
304105634Srwatson		if (mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL)
305105637Srwatson			return (1);
306105634Srwatson	}
307105634Srwatson
308105634Srwatson	return (0);
309105634Srwatson}
310105634Srwatson
311105634Srwatsonstatic int
312106090Srwatsonmac_biba_subject_privileged(struct mac_biba *mac_biba)
313105634Srwatson{
314105634Srwatson
315105634Srwatson	KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAGS_BOTH) ==
316105634Srwatson	    MAC_BIBA_FLAGS_BOTH,
317106090Srwatson	    ("mac_biba_subject_privileged: subject doesn't have both labels"));
318105634Srwatson
319105634Srwatson	/* If the single is EQUAL, it's ok. */
320105634Srwatson	if (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_EQUAL)
321105634Srwatson		return (0);
322105634Srwatson
323105634Srwatson	/* If either range endpoint is EQUAL, it's ok. */
324105634Srwatson	if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL ||
325105634Srwatson	    mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL)
326105634Srwatson		return (0);
327105634Srwatson
328105634Srwatson	/* If the range is low-high, it's ok. */
329105634Srwatson	if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_LOW &&
330105634Srwatson	    mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_HIGH)
331105634Srwatson		return (0);
332105634Srwatson
333105634Srwatson	/* It's not ok. */
334105634Srwatson	return (EPERM);
335105634Srwatson}
336105634Srwatson
337106091Srwatsonstatic int
338105988Srwatsonmac_biba_high_single(struct mac_biba *mac_biba)
339105988Srwatson{
340105988Srwatson
341105988Srwatson	KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
342105988Srwatson	    ("mac_biba_equal_single: mac_biba not single"));
343105988Srwatson
344105988Srwatson	return (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_HIGH);
345105988Srwatson}
346105988Srwatson
347105634Srwatsonstatic int
348101099Srwatsonmac_biba_valid(struct mac_biba *mac_biba)
349101099Srwatson{
350101099Srwatson
351101099Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) {
352101099Srwatson		switch (mac_biba->mb_single.mbe_type) {
353101099Srwatson		case MAC_BIBA_TYPE_GRADE:
354101099Srwatson			break;
355101099Srwatson
356101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
357101099Srwatson		case MAC_BIBA_TYPE_HIGH:
358101099Srwatson		case MAC_BIBA_TYPE_LOW:
359105643Srwatson			if (mac_biba->mb_single.mbe_grade != 0 ||
360105643Srwatson			    !MAC_BIBA_BIT_SET_EMPTY(
361105643Srwatson			    mac_biba->mb_single.mbe_compartments))
362101099Srwatson				return (EINVAL);
363101099Srwatson			break;
364101099Srwatson
365101099Srwatson		default:
366101099Srwatson			return (EINVAL);
367101099Srwatson		}
368101099Srwatson	} else {
369101099Srwatson		if (mac_biba->mb_single.mbe_type != MAC_BIBA_TYPE_UNDEF)
370101099Srwatson			return (EINVAL);
371101099Srwatson	}
372101099Srwatson
373101099Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
374101099Srwatson		switch (mac_biba->mb_rangelow.mbe_type) {
375101099Srwatson		case MAC_BIBA_TYPE_GRADE:
376101099Srwatson			break;
377101099Srwatson
378101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
379101099Srwatson		case MAC_BIBA_TYPE_HIGH:
380101099Srwatson		case MAC_BIBA_TYPE_LOW:
381105643Srwatson			if (mac_biba->mb_rangelow.mbe_grade != 0 ||
382105643Srwatson			    !MAC_BIBA_BIT_SET_EMPTY(
383105643Srwatson			    mac_biba->mb_rangelow.mbe_compartments))
384101099Srwatson				return (EINVAL);
385101099Srwatson			break;
386101099Srwatson
387101099Srwatson		default:
388101099Srwatson			return (EINVAL);
389101099Srwatson		}
390101099Srwatson
391101099Srwatson		switch (mac_biba->mb_rangehigh.mbe_type) {
392101099Srwatson		case MAC_BIBA_TYPE_GRADE:
393101099Srwatson			break;
394101099Srwatson
395101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
396101099Srwatson		case MAC_BIBA_TYPE_HIGH:
397101099Srwatson		case MAC_BIBA_TYPE_LOW:
398105643Srwatson			if (mac_biba->mb_rangehigh.mbe_grade != 0 ||
399105643Srwatson			    !MAC_BIBA_BIT_SET_EMPTY(
400105643Srwatson			    mac_biba->mb_rangehigh.mbe_compartments))
401101099Srwatson				return (EINVAL);
402101099Srwatson			break;
403101099Srwatson
404101099Srwatson		default:
405101099Srwatson			return (EINVAL);
406101099Srwatson		}
407101099Srwatson		if (!mac_biba_dominate_element(&mac_biba->mb_rangehigh,
408101099Srwatson		    &mac_biba->mb_rangelow))
409101099Srwatson			return (EINVAL);
410101099Srwatson	} else {
411101099Srwatson		if (mac_biba->mb_rangelow.mbe_type != MAC_BIBA_TYPE_UNDEF ||
412101099Srwatson		    mac_biba->mb_rangehigh.mbe_type != MAC_BIBA_TYPE_UNDEF)
413101099Srwatson			return (EINVAL);
414101099Srwatson	}
415101099Srwatson
416101099Srwatson	return (0);
417101099Srwatson}
418101099Srwatson
419101099Srwatsonstatic void
420101099Srwatsonmac_biba_set_range(struct mac_biba *mac_biba, u_short typelow,
421105643Srwatson    u_short gradelow, u_char *compartmentslow, u_short typehigh,
422105643Srwatson    u_short gradehigh, u_char *compartmentshigh)
423101099Srwatson{
424101099Srwatson
425101099Srwatson	mac_biba->mb_rangelow.mbe_type = typelow;
426101099Srwatson	mac_biba->mb_rangelow.mbe_grade = gradelow;
427105643Srwatson	if (compartmentslow != NULL)
428105643Srwatson		memcpy(mac_biba->mb_rangelow.mbe_compartments,
429105643Srwatson		    compartmentslow,
430105643Srwatson		    sizeof(mac_biba->mb_rangelow.mbe_compartments));
431101099Srwatson	mac_biba->mb_rangehigh.mbe_type = typehigh;
432101099Srwatson	mac_biba->mb_rangehigh.mbe_grade = gradehigh;
433105643Srwatson	if (compartmentshigh != NULL)
434105643Srwatson		memcpy(mac_biba->mb_rangehigh.mbe_compartments,
435105643Srwatson		    compartmentshigh,
436105643Srwatson		    sizeof(mac_biba->mb_rangehigh.mbe_compartments));
437101099Srwatson	mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE;
438101099Srwatson}
439101099Srwatson
440101099Srwatsonstatic void
441105643Srwatsonmac_biba_set_single(struct mac_biba *mac_biba, u_short type, u_short grade,
442105643Srwatson    u_char *compartments)
443101099Srwatson{
444101099Srwatson
445101099Srwatson	mac_biba->mb_single.mbe_type = type;
446101099Srwatson	mac_biba->mb_single.mbe_grade = grade;
447105643Srwatson	if (compartments != NULL)
448105643Srwatson		memcpy(mac_biba->mb_single.mbe_compartments, compartments,
449105643Srwatson		    sizeof(mac_biba->mb_single.mbe_compartments));
450101099Srwatson	mac_biba->mb_flags |= MAC_BIBA_FLAG_SINGLE;
451101099Srwatson}
452101099Srwatson
453101099Srwatsonstatic void
454101099Srwatsonmac_biba_copy_range(struct mac_biba *labelfrom, struct mac_biba *labelto)
455101099Srwatson{
456105643Srwatson
457101099Srwatson	KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_RANGE) != 0,
458101099Srwatson	    ("mac_biba_copy_range: labelfrom not range"));
459101099Srwatson
460101099Srwatson	labelto->mb_rangelow = labelfrom->mb_rangelow;
461101099Srwatson	labelto->mb_rangehigh = labelfrom->mb_rangehigh;
462101099Srwatson	labelto->mb_flags |= MAC_BIBA_FLAG_RANGE;
463101099Srwatson}
464101099Srwatson
465101099Srwatsonstatic void
466101099Srwatsonmac_biba_copy_single(struct mac_biba *labelfrom, struct mac_biba *labelto)
467101099Srwatson{
468101099Srwatson
469101099Srwatson	KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
470101099Srwatson	    ("mac_biba_copy_single: labelfrom not single"));
471101099Srwatson
472101099Srwatson	labelto->mb_single = labelfrom->mb_single;
473101099Srwatson	labelto->mb_flags |= MAC_BIBA_FLAG_SINGLE;
474101099Srwatson}
475101099Srwatson
476105656Srwatsonstatic void
477105656Srwatsonmac_biba_copy(struct mac_biba *source, struct mac_biba *dest)
478105656Srwatson{
479105656Srwatson
480105656Srwatson	if (source->mb_flags & MAC_BIBA_FLAG_SINGLE)
481105656Srwatson		mac_biba_copy_single(source, dest);
482105656Srwatson	if (source->mb_flags & MAC_BIBA_FLAG_RANGE)
483105656Srwatson		mac_biba_copy_range(source, dest);
484105656Srwatson}
485105656Srwatson
486101099Srwatson/*
487101099Srwatson * Policy module operations.
488101099Srwatson */
489101099Srwatsonstatic void
490101099Srwatsonmac_biba_destroy(struct mac_policy_conf *conf)
491101099Srwatson{
492101099Srwatson
493101099Srwatson}
494101099Srwatson
495101099Srwatsonstatic void
496101099Srwatsonmac_biba_init(struct mac_policy_conf *conf)
497101099Srwatson{
498101099Srwatson
499101099Srwatson}
500101099Srwatson
501101099Srwatson/*
502101099Srwatson * Label operations.
503101099Srwatson */
504101099Srwatsonstatic void
505104514Srwatsonmac_biba_init_label(struct label *label)
506101099Srwatson{
507101099Srwatson
508111119Simp	SLOT(label) = biba_alloc(M_WAITOK);
509101099Srwatson}
510101099Srwatson
511101099Srwatsonstatic int
512104514Srwatsonmac_biba_init_label_waitcheck(struct label *label, int flag)
513101099Srwatson{
514101099Srwatson
515104514Srwatson	SLOT(label) = biba_alloc(flag);
516101099Srwatson	if (SLOT(label) == NULL)
517101099Srwatson		return (ENOMEM);
518101099Srwatson
519101099Srwatson	return (0);
520101099Srwatson}
521101099Srwatson
522101099Srwatsonstatic void
523104514Srwatsonmac_biba_destroy_label(struct label *label)
524101099Srwatson{
525101099Srwatson
526101099Srwatson	biba_free(SLOT(label));
527101099Srwatson	SLOT(label) = NULL;
528101099Srwatson}
529101099Srwatson
530105696Srwatson/*
531105696Srwatson * mac_biba_element_to_string() is basically an snprintf wrapper with
532105696Srwatson * the same properties as snprintf().  It returns the length it would
533105696Srwatson * have added to the string in the event the string is too short.
534105696Srwatson */
535105696Srwatsonstatic size_t
536105696Srwatsonmac_biba_element_to_string(char *string, size_t size,
537105696Srwatson    struct mac_biba_element *element)
538105696Srwatson{
539105696Srwatson	int pos, bit = 1;
540105696Srwatson
541105696Srwatson	switch (element->mbe_type) {
542105696Srwatson	case MAC_BIBA_TYPE_HIGH:
543105696Srwatson		return (snprintf(string, size, "high"));
544105696Srwatson
545105696Srwatson	case MAC_BIBA_TYPE_LOW:
546105696Srwatson		return (snprintf(string, size, "low"));
547105696Srwatson
548105696Srwatson	case MAC_BIBA_TYPE_EQUAL:
549105696Srwatson		return (snprintf(string, size, "equal"));
550105696Srwatson
551105696Srwatson	case MAC_BIBA_TYPE_GRADE:
552105696Srwatson		pos = snprintf(string, size, "%d:", element->mbe_grade);
553105696Srwatson		for (bit = 1; bit <= MAC_BIBA_MAX_COMPARTMENTS; bit++) {
554105696Srwatson			if (MAC_BIBA_BIT_TEST(bit, element->mbe_compartments))
555105696Srwatson				pos += snprintf(string + pos, size - pos,
556105696Srwatson				    "%d+", bit);
557105696Srwatson		}
558105696Srwatson		if (string[pos - 1] == '+' || string[pos - 1] == ':')
559106214Srwatson			string[--pos] = '\0';
560105696Srwatson		return (pos);
561105696Srwatson
562105696Srwatson	default:
563105696Srwatson		panic("mac_biba_element_to_string: invalid type (%d)",
564105696Srwatson		    element->mbe_type);
565105696Srwatson	}
566105696Srwatson}
567105696Srwatson
568101099Srwatsonstatic int
569105696Srwatsonmac_biba_to_string(char *string, size_t size, size_t *caller_len,
570105696Srwatson    struct mac_biba *mac_biba)
571101099Srwatson{
572105696Srwatson	size_t left, len;
573105696Srwatson	char *curptr;
574105696Srwatson
575105696Srwatson	bzero(string, size);
576105696Srwatson	curptr = string;
577105696Srwatson	left = size;
578105696Srwatson
579105696Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) {
580105696Srwatson		len = mac_biba_element_to_string(curptr, left,
581105696Srwatson		    &mac_biba->mb_single);
582105696Srwatson		if (len >= left)
583105696Srwatson			return (EINVAL);
584105696Srwatson		left -= len;
585105696Srwatson		curptr += len;
586105696Srwatson	}
587105696Srwatson
588105696Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
589105696Srwatson		len = snprintf(curptr, left, "(");
590105696Srwatson		if (len >= left)
591105696Srwatson			return (EINVAL);
592105696Srwatson		left -= len;
593105696Srwatson		curptr += len;
594105696Srwatson
595105696Srwatson		len = mac_biba_element_to_string(curptr, left,
596105696Srwatson		    &mac_biba->mb_rangelow);
597105696Srwatson		if (len >= left)
598105696Srwatson			return (EINVAL);
599105696Srwatson		left -= len;
600105696Srwatson		curptr += len;
601105696Srwatson
602105696Srwatson		len = snprintf(curptr, left, "-");
603105696Srwatson		if (len >= left)
604105696Srwatson			return (EINVAL);
605105696Srwatson		left -= len;
606105696Srwatson		curptr += len;
607105696Srwatson
608105696Srwatson		len = mac_biba_element_to_string(curptr, left,
609105696Srwatson		    &mac_biba->mb_rangehigh);
610105696Srwatson		if (len >= left)
611105696Srwatson			return (EINVAL);
612105696Srwatson		left -= len;
613105696Srwatson		curptr += len;
614105696Srwatson
615105696Srwatson		len = snprintf(curptr, left, ")");
616105696Srwatson		if (len >= left)
617105696Srwatson			return (EINVAL);
618105696Srwatson		left -= len;
619105696Srwatson		curptr += len;
620105696Srwatson	}
621105696Srwatson
622105696Srwatson	*caller_len = strlen(string);
623105696Srwatson	return (0);
624105696Srwatson}
625105696Srwatson
626105696Srwatsonstatic int
627105696Srwatsonmac_biba_externalize_label(struct label *label, char *element_name,
628105696Srwatson    char *element_data, size_t size, size_t *len, int *claimed)
629105696Srwatson{
630101099Srwatson	struct mac_biba *mac_biba;
631105696Srwatson	int error;
632101099Srwatson
633105696Srwatson	if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0)
634105696Srwatson		return (0);
635105696Srwatson
636105696Srwatson	(*claimed)++;
637105696Srwatson
638101099Srwatson	mac_biba = SLOT(label);
639105696Srwatson	error = mac_biba_to_string(element_data, size, len, mac_biba);
640105696Srwatson	if (error)
641105696Srwatson		return (error);
642101099Srwatson
643105696Srwatson	*len = strlen(element_data);
644105696Srwatson	return (0);
645105696Srwatson}
646105696Srwatson
647105696Srwatsonstatic int
648105696Srwatsonmac_biba_parse_element(struct mac_biba_element *element, char *string)
649101099Srwatson{
650105696Srwatson
651105696Srwatson	if (strcmp(string, "high") == 0 ||
652105696Srwatson	    strcmp(string, "hi") == 0) {
653105696Srwatson		element->mbe_type = MAC_BIBA_TYPE_HIGH;
654105696Srwatson		element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
655105696Srwatson	} else if (strcmp(string, "low") == 0 ||
656105696Srwatson	    strcmp(string, "lo") == 0) {
657105696Srwatson		element->mbe_type = MAC_BIBA_TYPE_LOW;
658105696Srwatson		element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
659105696Srwatson	} else if (strcmp(string, "equal") == 0 ||
660105696Srwatson	    strcmp(string, "eq") == 0) {
661105696Srwatson		element->mbe_type = MAC_BIBA_TYPE_EQUAL;
662105696Srwatson		element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
663105696Srwatson	} else {
664105696Srwatson		char *p0, *p1;
665105696Srwatson		int d;
666105696Srwatson
667105696Srwatson		p0 = string;
668105696Srwatson		d = strtol(p0, &p1, 10);
669105696Srwatson
670105696Srwatson		if (d < 0 || d > 65535)
671105696Srwatson			return (EINVAL);
672105696Srwatson		element->mbe_type = MAC_BIBA_TYPE_GRADE;
673105696Srwatson		element->mbe_grade = d;
674105696Srwatson
675105696Srwatson		if (*p1 != ':')  {
676105696Srwatson			if (p1 == p0 || *p1 != '\0')
677105696Srwatson				return (EINVAL);
678105696Srwatson			else
679105696Srwatson				return (0);
680105696Srwatson		}
681105696Srwatson		else
682105696Srwatson			if (*(p1 + 1) == '\0')
683105696Srwatson				return (0);
684105696Srwatson
685105696Srwatson		while ((p0 = ++p1)) {
686105696Srwatson			d = strtol(p0, &p1, 10);
687105696Srwatson			if (d < 1 || d > MAC_BIBA_MAX_COMPARTMENTS)
688105696Srwatson				return (EINVAL);
689105696Srwatson
690105696Srwatson			MAC_BIBA_BIT_SET(d, element->mbe_compartments);
691105696Srwatson
692105696Srwatson			if (*p1 == '\0')
693105696Srwatson				break;
694105696Srwatson			if (p1 == p0 || *p1 != '+')
695105696Srwatson				return (EINVAL);
696105696Srwatson		}
697105696Srwatson	}
698105696Srwatson
699105696Srwatson	return (0);
700105696Srwatson}
701105696Srwatson
702105696Srwatson/*
703105696Srwatson * Note: destructively consumes the string, make a local copy before
704105696Srwatson * calling if that's a problem.
705105696Srwatson */
706105696Srwatsonstatic int
707105696Srwatsonmac_biba_parse(struct mac_biba *mac_biba, char *string)
708105696Srwatson{
709105696Srwatson	char *range, *rangeend, *rangehigh, *rangelow, *single;
710101099Srwatson	int error;
711101099Srwatson
712105696Srwatson	/* Do we have a range? */
713105696Srwatson	single = string;
714105696Srwatson	range = index(string, '(');
715105696Srwatson	if (range == single)
716105696Srwatson		single = NULL;
717105696Srwatson	rangelow = rangehigh = NULL;
718105696Srwatson	if (range != NULL) {
719105696Srwatson		/* Nul terminate the end of the single string. */
720105696Srwatson		*range = '\0';
721105696Srwatson		range++;
722105696Srwatson		rangelow = range;
723105696Srwatson		rangehigh = index(rangelow, '-');
724105696Srwatson		if (rangehigh == NULL)
725105696Srwatson			return (EINVAL);
726105696Srwatson		rangehigh++;
727105696Srwatson		if (*rangelow == '\0' || *rangehigh == '\0')
728105696Srwatson			return (EINVAL);
729105696Srwatson		rangeend = index(rangehigh, ')');
730105696Srwatson		if (rangeend == NULL)
731105696Srwatson			return (EINVAL);
732105696Srwatson		if (*(rangeend + 1) != '\0')
733105696Srwatson			return (EINVAL);
734105696Srwatson		/* Nul terminate the ends of the ranges. */
735105696Srwatson		*(rangehigh - 1) = '\0';
736105696Srwatson		*rangeend = '\0';
737105696Srwatson	}
738105696Srwatson	KASSERT((rangelow != NULL && rangehigh != NULL) ||
739105696Srwatson	    (rangelow == NULL && rangehigh == NULL),
740105696Srwatson	    ("mac_biba_internalize_label: range mismatch"));
741101099Srwatson
742105696Srwatson	bzero(mac_biba, sizeof(*mac_biba));
743105696Srwatson	if (single != NULL) {
744105696Srwatson		error = mac_biba_parse_element(&mac_biba->mb_single, single);
745105696Srwatson		if (error)
746105696Srwatson			return (error);
747105696Srwatson		mac_biba->mb_flags |= MAC_BIBA_FLAG_SINGLE;
748105696Srwatson	}
749105696Srwatson
750105696Srwatson	if (rangelow != NULL) {
751105696Srwatson		error = mac_biba_parse_element(&mac_biba->mb_rangelow,
752105696Srwatson		    rangelow);
753105696Srwatson		if (error)
754105696Srwatson			return (error);
755105696Srwatson		error = mac_biba_parse_element(&mac_biba->mb_rangehigh,
756105696Srwatson		    rangehigh);
757105696Srwatson		if (error)
758105696Srwatson			return (error);
759105696Srwatson		mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE;
760105696Srwatson	}
761105696Srwatson
762101099Srwatson	error = mac_biba_valid(mac_biba);
763101099Srwatson	if (error)
764101099Srwatson		return (error);
765101099Srwatson
766105696Srwatson	return (0);
767105696Srwatson}
768101099Srwatson
769105696Srwatsonstatic int
770105696Srwatsonmac_biba_internalize_label(struct label *label, char *element_name,
771105696Srwatson    char *element_data, int *claimed)
772105696Srwatson{
773105696Srwatson	struct mac_biba *mac_biba, mac_biba_temp;
774105696Srwatson	int error;
775105696Srwatson
776105696Srwatson	if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0)
777105696Srwatson		return (0);
778105696Srwatson
779105696Srwatson	(*claimed)++;
780105696Srwatson
781105696Srwatson	error = mac_biba_parse(&mac_biba_temp, element_data);
782105696Srwatson	if (error)
783105696Srwatson		return (error);
784105696Srwatson
785105696Srwatson	mac_biba = SLOT(label);
786105696Srwatson	*mac_biba = mac_biba_temp;
787105696Srwatson
788101099Srwatson	return (0);
789101099Srwatson}
790101099Srwatson
791105696Srwatsonstatic void
792105696Srwatsonmac_biba_copy_label(struct label *src, struct label *dest)
793105696Srwatson{
794105696Srwatson
795105696Srwatson	*SLOT(dest) = *SLOT(src);
796105696Srwatson}
797105696Srwatson
798101099Srwatson/*
799101099Srwatson * Labeling event operations: file system objects, and things that look
800101099Srwatson * a lot like file system objects.
801101099Srwatson */
802101099Srwatsonstatic void
803107698Srwatsonmac_biba_create_devfs_device(struct mount *mp, dev_t dev,
804107698Srwatson    struct devfs_dirent *devfs_dirent, struct label *label)
805101099Srwatson{
806101099Srwatson	struct mac_biba *mac_biba;
807101099Srwatson	int biba_type;
808101099Srwatson
809101099Srwatson	mac_biba = SLOT(label);
810101099Srwatson	if (strcmp(dev->si_name, "null") == 0 ||
811101099Srwatson	    strcmp(dev->si_name, "zero") == 0 ||
812101099Srwatson	    strcmp(dev->si_name, "random") == 0 ||
813101099Srwatson	    strncmp(dev->si_name, "fd/", strlen("fd/")) == 0)
814101099Srwatson		biba_type = MAC_BIBA_TYPE_EQUAL;
815105606Srwatson	else if (ptys_equal &&
816105606Srwatson	    (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 ||
817105606Srwatson	    strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0))
818105606Srwatson		biba_type = MAC_BIBA_TYPE_EQUAL;
819101099Srwatson	else
820101099Srwatson		biba_type = MAC_BIBA_TYPE_HIGH;
821105643Srwatson	mac_biba_set_single(mac_biba, biba_type, 0, NULL);
822101099Srwatson}
823101099Srwatson
824101099Srwatsonstatic void
825107698Srwatsonmac_biba_create_devfs_directory(struct mount *mp, char *dirname,
826107698Srwatson    int dirnamelen, struct devfs_dirent *devfs_dirent, struct label *label)
827101099Srwatson{
828101099Srwatson	struct mac_biba *mac_biba;
829101099Srwatson
830101099Srwatson	mac_biba = SLOT(label);
831105643Srwatson	mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
832101099Srwatson}
833101099Srwatson
834101099Srwatsonstatic void
835107698Srwatsonmac_biba_create_devfs_symlink(struct ucred *cred, struct mount *mp,
836107698Srwatson    struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de,
837107698Srwatson    struct label *delabel)
838104535Srwatson{
839104535Srwatson	struct mac_biba *source, *dest;
840104535Srwatson
841104535Srwatson	source = SLOT(&cred->cr_label);
842104535Srwatson	dest = SLOT(delabel);
843104535Srwatson
844104535Srwatson	mac_biba_copy_single(source, dest);
845104535Srwatson}
846104535Srwatson
847104535Srwatsonstatic void
848101099Srwatsonmac_biba_create_mount(struct ucred *cred, struct mount *mp,
849101099Srwatson    struct label *mntlabel, struct label *fslabel)
850101099Srwatson{
851101099Srwatson	struct mac_biba *source, *dest;
852101099Srwatson
853101099Srwatson	source = SLOT(&cred->cr_label);
854101099Srwatson	dest = SLOT(mntlabel);
855101099Srwatson	mac_biba_copy_single(source, dest);
856101099Srwatson	dest = SLOT(fslabel);
857101099Srwatson	mac_biba_copy_single(source, dest);
858101099Srwatson}
859101099Srwatson
860101099Srwatsonstatic void
861101099Srwatsonmac_biba_create_root_mount(struct ucred *cred, struct mount *mp,
862101099Srwatson    struct label *mntlabel, struct label *fslabel)
863101099Srwatson{
864101099Srwatson	struct mac_biba *mac_biba;
865101099Srwatson
866101099Srwatson	/* Always mount root as high integrity. */
867101099Srwatson	mac_biba = SLOT(fslabel);
868105643Srwatson	mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
869101099Srwatson	mac_biba = SLOT(mntlabel);
870105643Srwatson	mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
871101099Srwatson}
872101099Srwatson
873101099Srwatsonstatic void
874101099Srwatsonmac_biba_relabel_vnode(struct ucred *cred, struct vnode *vp,
875101099Srwatson    struct label *vnodelabel, struct label *label)
876101099Srwatson{
877101099Srwatson	struct mac_biba *source, *dest;
878101099Srwatson
879101099Srwatson	source = SLOT(label);
880101099Srwatson	dest = SLOT(vnodelabel);
881101099Srwatson
882105656Srwatson	mac_biba_copy(source, dest);
883101099Srwatson}
884101099Srwatson
885101099Srwatsonstatic void
886107698Srwatsonmac_biba_update_devfsdirent(struct mount *mp,
887107698Srwatson    struct devfs_dirent *devfs_dirent, struct label *direntlabel,
888107698Srwatson    struct vnode *vp, struct label *vnodelabel)
889101099Srwatson{
890101099Srwatson	struct mac_biba *source, *dest;
891101099Srwatson
892101099Srwatson	source = SLOT(vnodelabel);
893101099Srwatson	dest = SLOT(direntlabel);
894101099Srwatson
895105656Srwatson	mac_biba_copy(source, dest);
896101099Srwatson}
897101099Srwatson
898101099Srwatsonstatic void
899105988Srwatsonmac_biba_associate_vnode_devfs(struct mount *mp, struct label *fslabel,
900105988Srwatson    struct devfs_dirent *de, struct label *delabel, struct vnode *vp,
901105988Srwatson    struct label *vlabel)
902101099Srwatson{
903101099Srwatson	struct mac_biba *source, *dest;
904101099Srwatson
905105988Srwatson	source = SLOT(delabel);
906105988Srwatson	dest = SLOT(vlabel);
907101099Srwatson
908101099Srwatson	mac_biba_copy_single(source, dest);
909101099Srwatson}
910101099Srwatson
911101099Srwatsonstatic int
912105988Srwatsonmac_biba_associate_vnode_extattr(struct mount *mp, struct label *fslabel,
913105988Srwatson    struct vnode *vp, struct label *vlabel)
914101099Srwatson{
915105988Srwatson	struct mac_biba temp, *source, *dest;
916106354Smux	int buflen, error;
917101099Srwatson
918105988Srwatson	source = SLOT(fslabel);
919105988Srwatson	dest = SLOT(vlabel);
920101099Srwatson
921105988Srwatson	buflen = sizeof(temp);
922105988Srwatson	bzero(&temp, buflen);
923105988Srwatson
924105988Srwatson	error = vn_extattr_get(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
925105988Srwatson	    MAC_BIBA_EXTATTR_NAME, &buflen, (char *) &temp, curthread);
926105988Srwatson	if (error == ENOATTR || error == EOPNOTSUPP) {
927105988Srwatson		/* Fall back to the fslabel. */
928105988Srwatson		mac_biba_copy_single(source, dest);
929105988Srwatson		return (0);
930105988Srwatson	} else if (error)
931101099Srwatson		return (error);
932101099Srwatson
933105988Srwatson	if (buflen != sizeof(temp)) {
934105988Srwatson		printf("mac_biba_associate_vnode_extattr: bad size %d\n",
935105988Srwatson		    buflen);
936105988Srwatson		return (EPERM);
937105988Srwatson	}
938105988Srwatson	if (mac_biba_valid(&temp) != 0) {
939105988Srwatson		printf("mac_biba_associate_vnode_extattr: invalid\n");
940105988Srwatson		return (EPERM);
941105988Srwatson	}
942105988Srwatson	if ((temp.mb_flags & MAC_BIBA_FLAGS_BOTH) != MAC_BIBA_FLAG_SINGLE) {
943105988Srwatson		printf("mac_biba_associate_vnode_extattr: not single\n");
944105988Srwatson		return (EPERM);
945105988Srwatson	}
946101099Srwatson
947105988Srwatson	mac_biba_copy_single(&temp, dest);
948101099Srwatson	return (0);
949101099Srwatson}
950101099Srwatson
951101099Srwatsonstatic void
952105988Srwatsonmac_biba_associate_vnode_singlelabel(struct mount *mp,
953105988Srwatson    struct label *fslabel, struct vnode *vp, struct label *vlabel)
954101099Srwatson{
955101099Srwatson	struct mac_biba *source, *dest;
956101099Srwatson
957101099Srwatson	source = SLOT(fslabel);
958105988Srwatson	dest = SLOT(vlabel);
959101099Srwatson
960101099Srwatson	mac_biba_copy_single(source, dest);
961101099Srwatson}
962101099Srwatson
963105988Srwatsonstatic int
964105988Srwatsonmac_biba_create_vnode_extattr(struct ucred *cred, struct mount *mp,
965105988Srwatson    struct label *fslabel, struct vnode *dvp, struct label *dlabel,
966105988Srwatson    struct vnode *vp, struct label *vlabel, struct componentname *cnp)
967105988Srwatson{
968105988Srwatson	struct mac_biba *source, *dest, temp;
969105988Srwatson	size_t buflen;
970105988Srwatson	int error;
971105988Srwatson
972105988Srwatson	buflen = sizeof(temp);
973105988Srwatson	bzero(&temp, buflen);
974105988Srwatson
975105988Srwatson	source = SLOT(&cred->cr_label);
976105988Srwatson	dest = SLOT(vlabel);
977105988Srwatson	mac_biba_copy_single(source, &temp);
978105988Srwatson
979105988Srwatson	error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
980105988Srwatson	    MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread);
981105988Srwatson	if (error == 0)
982105988Srwatson		mac_biba_copy_single(source, dest);
983105988Srwatson	return (error);
984105988Srwatson}
985105988Srwatson
986105988Srwatsonstatic int
987105988Srwatsonmac_biba_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp,
988105988Srwatson    struct label *vlabel, struct label *intlabel)
989105988Srwatson{
990105988Srwatson	struct mac_biba *source, temp;
991105988Srwatson	size_t buflen;
992105988Srwatson	int error;
993105988Srwatson
994105988Srwatson	buflen = sizeof(temp);
995105988Srwatson	bzero(&temp, buflen);
996105988Srwatson
997105988Srwatson	source = SLOT(intlabel);
998105988Srwatson	if ((source->mb_flags & MAC_BIBA_FLAG_SINGLE) == 0)
999105988Srwatson		return (0);
1000105988Srwatson
1001105988Srwatson	mac_biba_copy_single(source, &temp);
1002105988Srwatson
1003105988Srwatson	error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
1004105988Srwatson	    MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread);
1005105988Srwatson	return (error);
1006105988Srwatson}
1007105988Srwatson
1008101099Srwatson/*
1009101099Srwatson * Labeling event operations: IPC object.
1010101099Srwatson */
1011101099Srwatsonstatic void
1012101099Srwatsonmac_biba_create_mbuf_from_socket(struct socket *so, struct label *socketlabel,
1013101099Srwatson    struct mbuf *m, struct label *mbuflabel)
1014101099Srwatson{
1015101099Srwatson	struct mac_biba *source, *dest;
1016101099Srwatson
1017101099Srwatson	source = SLOT(socketlabel);
1018101099Srwatson	dest = SLOT(mbuflabel);
1019101099Srwatson
1020101099Srwatson	mac_biba_copy_single(source, dest);
1021101099Srwatson}
1022101099Srwatson
1023101099Srwatsonstatic void
1024101099Srwatsonmac_biba_create_socket(struct ucred *cred, struct socket *socket,
1025101099Srwatson    struct label *socketlabel)
1026101099Srwatson{
1027101099Srwatson	struct mac_biba *source, *dest;
1028101099Srwatson
1029101099Srwatson	source = SLOT(&cred->cr_label);
1030101099Srwatson	dest = SLOT(socketlabel);
1031101099Srwatson
1032101099Srwatson	mac_biba_copy_single(source, dest);
1033101099Srwatson}
1034101099Srwatson
1035101099Srwatsonstatic void
1036101099Srwatsonmac_biba_create_pipe(struct ucred *cred, struct pipe *pipe,
1037101099Srwatson    struct label *pipelabel)
1038101099Srwatson{
1039101099Srwatson	struct mac_biba *source, *dest;
1040101099Srwatson
1041101099Srwatson	source = SLOT(&cred->cr_label);
1042101099Srwatson	dest = SLOT(pipelabel);
1043101099Srwatson
1044101099Srwatson	mac_biba_copy_single(source, dest);
1045101099Srwatson}
1046101099Srwatson
1047101099Srwatsonstatic void
1048101099Srwatsonmac_biba_create_socket_from_socket(struct socket *oldsocket,
1049101099Srwatson    struct label *oldsocketlabel, struct socket *newsocket,
1050101099Srwatson    struct label *newsocketlabel)
1051101099Srwatson{
1052101099Srwatson	struct mac_biba *source, *dest;
1053101099Srwatson
1054101099Srwatson	source = SLOT(oldsocketlabel);
1055101099Srwatson	dest = SLOT(newsocketlabel);
1056101099Srwatson
1057101099Srwatson	mac_biba_copy_single(source, dest);
1058101099Srwatson}
1059101099Srwatson
1060101099Srwatsonstatic void
1061101099Srwatsonmac_biba_relabel_socket(struct ucred *cred, struct socket *socket,
1062101099Srwatson    struct label *socketlabel, struct label *newlabel)
1063101099Srwatson{
1064101099Srwatson	struct mac_biba *source, *dest;
1065101099Srwatson
1066101099Srwatson	source = SLOT(newlabel);
1067101099Srwatson	dest = SLOT(socketlabel);
1068101099Srwatson
1069105656Srwatson	mac_biba_copy(source, dest);
1070101099Srwatson}
1071101099Srwatson
1072101099Srwatsonstatic void
1073101099Srwatsonmac_biba_relabel_pipe(struct ucred *cred, struct pipe *pipe,
1074101099Srwatson    struct label *pipelabel, struct label *newlabel)
1075101099Srwatson{
1076101099Srwatson	struct mac_biba *source, *dest;
1077101099Srwatson
1078101099Srwatson	source = SLOT(newlabel);
1079101099Srwatson	dest = SLOT(pipelabel);
1080101099Srwatson
1081105656Srwatson	mac_biba_copy(source, dest);
1082101099Srwatson}
1083101099Srwatson
1084101099Srwatsonstatic void
1085101099Srwatsonmac_biba_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel,
1086101099Srwatson    struct socket *socket, struct label *socketpeerlabel)
1087101099Srwatson{
1088101099Srwatson	struct mac_biba *source, *dest;
1089101099Srwatson
1090101099Srwatson	source = SLOT(mbuflabel);
1091101099Srwatson	dest = SLOT(socketpeerlabel);
1092101099Srwatson
1093101099Srwatson	mac_biba_copy_single(source, dest);
1094101099Srwatson}
1095101099Srwatson
1096101099Srwatson/*
1097101099Srwatson * Labeling event operations: network objects.
1098101099Srwatson */
1099101099Srwatsonstatic void
1100101099Srwatsonmac_biba_set_socket_peer_from_socket(struct socket *oldsocket,
1101101099Srwatson    struct label *oldsocketlabel, struct socket *newsocket,
1102101099Srwatson    struct label *newsocketpeerlabel)
1103101099Srwatson{
1104101099Srwatson	struct mac_biba *source, *dest;
1105101099Srwatson
1106101099Srwatson	source = SLOT(oldsocketlabel);
1107101099Srwatson	dest = SLOT(newsocketpeerlabel);
1108101099Srwatson
1109101099Srwatson	mac_biba_copy_single(source, dest);
1110101099Srwatson}
1111101099Srwatson
1112101099Srwatsonstatic void
1113101099Srwatsonmac_biba_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d,
1114101099Srwatson    struct label *bpflabel)
1115101099Srwatson{
1116101099Srwatson	struct mac_biba *source, *dest;
1117101099Srwatson
1118101099Srwatson	source = SLOT(&cred->cr_label);
1119101099Srwatson	dest = SLOT(bpflabel);
1120101099Srwatson
1121101099Srwatson	mac_biba_copy_single(source, dest);
1122101099Srwatson}
1123101099Srwatson
1124101099Srwatsonstatic void
1125101099Srwatsonmac_biba_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel)
1126101099Srwatson{
1127101099Srwatson	char tifname[IFNAMSIZ], ifname[IFNAMSIZ], *p, *q;
1128101099Srwatson	char tiflist[sizeof(trusted_interfaces)];
1129101099Srwatson	struct mac_biba *dest;
1130110350Srwatson	int len, type;
1131101099Srwatson
1132101099Srwatson	dest = SLOT(ifnetlabel);
1133101099Srwatson
1134101099Srwatson	if (ifnet->if_type == IFT_LOOP) {
1135110350Srwatson		type = MAC_BIBA_TYPE_EQUAL;
1136101099Srwatson		goto set;
1137101099Srwatson	}
1138101099Srwatson
1139101099Srwatson	if (trust_all_interfaces) {
1140110350Srwatson		type = MAC_BIBA_TYPE_HIGH;
1141101099Srwatson		goto set;
1142101099Srwatson	}
1143101099Srwatson
1144110350Srwatson	type = MAC_BIBA_TYPE_LOW;
1145101099Srwatson
1146101099Srwatson	if (trusted_interfaces[0] == '\0' ||
1147101099Srwatson	    !strvalid(trusted_interfaces, sizeof(trusted_interfaces)))
1148101099Srwatson		goto set;
1149101099Srwatson
1150106089Srwatson	bzero(tiflist, sizeof(tiflist));
1151101099Srwatson	for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++)
1152101099Srwatson		if(*p != ' ' && *p != '\t')
1153101099Srwatson			*q = *p;
1154101099Srwatson
1155101099Srwatson	snprintf(ifname, IFNAMSIZ, "%s%d", ifnet->if_name, ifnet->if_unit);
1156101099Srwatson
1157101099Srwatson	for (p = q = tiflist;; p++) {
1158101099Srwatson		if (*p == ',' || *p == '\0') {
1159101099Srwatson			len = p - q;
1160101099Srwatson			if (len < IFNAMSIZ) {
1161101099Srwatson				bzero(tifname, sizeof(tifname));
1162101099Srwatson				bcopy(q, tifname, len);
1163101099Srwatson				if (strcmp(tifname, ifname) == 0) {
1164110350Srwatson					type = MAC_BIBA_TYPE_HIGH;
1165101099Srwatson					break;
1166101099Srwatson				}
1167106089Srwatson			} else {
1168106089Srwatson				*p = '\0';
1169106089Srwatson				printf("mac_biba warning: interface name "
1170106089Srwatson				    "\"%s\" is too long (must be < %d)\n",
1171106089Srwatson				    q, IFNAMSIZ);
1172101099Srwatson			}
1173101099Srwatson			if (*p == '\0')
1174101099Srwatson				break;
1175101099Srwatson			q = p + 1;
1176101099Srwatson		}
1177101099Srwatson	}
1178101099Srwatsonset:
1179110350Srwatson	mac_biba_set_single(dest, type, 0, NULL);
1180110350Srwatson	mac_biba_set_range(dest, type, 0, NULL, type, 0, NULL);
1181101099Srwatson}
1182101099Srwatson
1183101099Srwatsonstatic void
1184101099Srwatsonmac_biba_create_ipq(struct mbuf *fragment, struct label *fragmentlabel,
1185101099Srwatson    struct ipq *ipq, struct label *ipqlabel)
1186101099Srwatson{
1187101099Srwatson	struct mac_biba *source, *dest;
1188101099Srwatson
1189101099Srwatson	source = SLOT(fragmentlabel);
1190101099Srwatson	dest = SLOT(ipqlabel);
1191101099Srwatson
1192101099Srwatson	mac_biba_copy_single(source, dest);
1193101099Srwatson}
1194101099Srwatson
1195101099Srwatsonstatic void
1196101099Srwatsonmac_biba_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel,
1197101099Srwatson    struct mbuf *datagram, struct label *datagramlabel)
1198101099Srwatson{
1199101099Srwatson	struct mac_biba *source, *dest;
1200101099Srwatson
1201101099Srwatson	source = SLOT(ipqlabel);
1202101099Srwatson	dest = SLOT(datagramlabel);
1203101099Srwatson
1204101099Srwatson	/* Just use the head, since we require them all to match. */
1205101099Srwatson	mac_biba_copy_single(source, dest);
1206101099Srwatson}
1207101099Srwatson
1208101099Srwatsonstatic void
1209101099Srwatsonmac_biba_create_fragment(struct mbuf *datagram, struct label *datagramlabel,
1210101099Srwatson    struct mbuf *fragment, struct label *fragmentlabel)
1211101099Srwatson{
1212101099Srwatson	struct mac_biba *source, *dest;
1213101099Srwatson
1214101099Srwatson	source = SLOT(datagramlabel);
1215101099Srwatson	dest = SLOT(fragmentlabel);
1216101099Srwatson
1217101099Srwatson	mac_biba_copy_single(source, dest);
1218101099Srwatson}
1219101099Srwatson
1220101099Srwatsonstatic void
1221101099Srwatsonmac_biba_create_mbuf_from_mbuf(struct mbuf *oldmbuf,
1222101099Srwatson    struct label *oldmbuflabel, struct mbuf *newmbuf,
1223101099Srwatson    struct label *newmbuflabel)
1224101099Srwatson{
1225101099Srwatson	struct mac_biba *source, *dest;
1226101099Srwatson
1227101099Srwatson	source = SLOT(oldmbuflabel);
1228101099Srwatson	dest = SLOT(newmbuflabel);
1229101099Srwatson
1230105656Srwatson	/*
1231105656Srwatson	 * Because the source mbuf may not yet have been "created",
1232105696Srwatson	 * just initialized, we do a conditional copy.  Since we don't
1233105656Srwatson	 * allow mbufs to have ranges, do a KASSERT to make sure that
1234105656Srwatson	 * doesn't happen.
1235105656Srwatson	 */
1236105656Srwatson	KASSERT((source->mb_flags & MAC_BIBA_FLAG_RANGE) == 0,
1237105656Srwatson	    ("mac_biba_create_mbuf_from_mbuf: source mbuf has range"));
1238105656Srwatson	mac_biba_copy(source, dest);
1239101099Srwatson}
1240101099Srwatson
1241101099Srwatsonstatic void
1242101099Srwatsonmac_biba_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel,
1243101099Srwatson    struct mbuf *mbuf, struct label *mbuflabel)
1244101099Srwatson{
1245101099Srwatson	struct mac_biba *dest;
1246101099Srwatson
1247101099Srwatson	dest = SLOT(mbuflabel);
1248101099Srwatson
1249105643Srwatson	mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1250101099Srwatson}
1251101099Srwatson
1252101099Srwatsonstatic void
1253101099Srwatsonmac_biba_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel,
1254101099Srwatson    struct mbuf *mbuf, struct label *mbuflabel)
1255101099Srwatson{
1256101099Srwatson	struct mac_biba *source, *dest;
1257101099Srwatson
1258101099Srwatson	source = SLOT(bpflabel);
1259101099Srwatson	dest = SLOT(mbuflabel);
1260101099Srwatson
1261101099Srwatson	mac_biba_copy_single(source, dest);
1262101099Srwatson}
1263101099Srwatson
1264101099Srwatsonstatic void
1265101099Srwatsonmac_biba_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel,
1266101099Srwatson    struct mbuf *m, struct label *mbuflabel)
1267101099Srwatson{
1268101099Srwatson	struct mac_biba *source, *dest;
1269101099Srwatson
1270101099Srwatson	source = SLOT(ifnetlabel);
1271101099Srwatson	dest = SLOT(mbuflabel);
1272101099Srwatson
1273101099Srwatson	mac_biba_copy_single(source, dest);
1274101099Srwatson}
1275101099Srwatson
1276101099Srwatsonstatic void
1277101099Srwatsonmac_biba_create_mbuf_multicast_encap(struct mbuf *oldmbuf,
1278101099Srwatson    struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel,
1279101099Srwatson    struct mbuf *newmbuf, struct label *newmbuflabel)
1280101099Srwatson{
1281101099Srwatson	struct mac_biba *source, *dest;
1282101099Srwatson
1283101099Srwatson	source = SLOT(oldmbuflabel);
1284101099Srwatson	dest = SLOT(newmbuflabel);
1285101099Srwatson
1286101099Srwatson	mac_biba_copy_single(source, dest);
1287101099Srwatson}
1288101099Srwatson
1289101099Srwatsonstatic void
1290101099Srwatsonmac_biba_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel,
1291101099Srwatson    struct mbuf *newmbuf, struct label *newmbuflabel)
1292101099Srwatson{
1293101099Srwatson	struct mac_biba *source, *dest;
1294101099Srwatson
1295101099Srwatson	source = SLOT(oldmbuflabel);
1296101099Srwatson	dest = SLOT(newmbuflabel);
1297101099Srwatson
1298101099Srwatson	mac_biba_copy_single(source, dest);
1299101099Srwatson}
1300101099Srwatson
1301101099Srwatsonstatic int
1302101099Srwatsonmac_biba_fragment_match(struct mbuf *fragment, struct label *fragmentlabel,
1303101099Srwatson    struct ipq *ipq, struct label *ipqlabel)
1304101099Srwatson{
1305101099Srwatson	struct mac_biba *a, *b;
1306101099Srwatson
1307101099Srwatson	a = SLOT(ipqlabel);
1308101099Srwatson	b = SLOT(fragmentlabel);
1309101099Srwatson
1310101099Srwatson	return (mac_biba_equal_single(a, b));
1311101099Srwatson}
1312101099Srwatson
1313101099Srwatsonstatic void
1314101099Srwatsonmac_biba_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet,
1315101099Srwatson    struct label *ifnetlabel, struct label *newlabel)
1316101099Srwatson{
1317101099Srwatson	struct mac_biba *source, *dest;
1318101099Srwatson
1319101099Srwatson	source = SLOT(newlabel);
1320101099Srwatson	dest = SLOT(ifnetlabel);
1321101099Srwatson
1322105656Srwatson	mac_biba_copy(source, dest);
1323101099Srwatson}
1324101099Srwatson
1325101099Srwatsonstatic void
1326101099Srwatsonmac_biba_update_ipq(struct mbuf *fragment, struct label *fragmentlabel,
1327101099Srwatson    struct ipq *ipq, struct label *ipqlabel)
1328101099Srwatson{
1329101099Srwatson
1330101099Srwatson	/* NOOP: we only accept matching labels, so no need to update */
1331101099Srwatson}
1332101099Srwatson
1333101099Srwatson/*
1334101099Srwatson * Labeling event operations: processes.
1335101099Srwatson */
1336101099Srwatsonstatic void
1337101099Srwatsonmac_biba_create_cred(struct ucred *cred_parent, struct ucred *cred_child)
1338101099Srwatson{
1339101099Srwatson	struct mac_biba *source, *dest;
1340101099Srwatson
1341101099Srwatson	source = SLOT(&cred_parent->cr_label);
1342101099Srwatson	dest = SLOT(&cred_child->cr_label);
1343101099Srwatson
1344101099Srwatson	mac_biba_copy_single(source, dest);
1345101099Srwatson	mac_biba_copy_range(source, dest);
1346101099Srwatson}
1347101099Srwatson
1348101099Srwatsonstatic void
1349101099Srwatsonmac_biba_create_proc0(struct ucred *cred)
1350101099Srwatson{
1351101099Srwatson	struct mac_biba *dest;
1352101099Srwatson
1353101099Srwatson	dest = SLOT(&cred->cr_label);
1354101099Srwatson
1355105643Srwatson	mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1356105643Srwatson	mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL,
1357105643Srwatson	    MAC_BIBA_TYPE_HIGH, 0, NULL);
1358101099Srwatson}
1359101099Srwatson
1360101099Srwatsonstatic void
1361101099Srwatsonmac_biba_create_proc1(struct ucred *cred)
1362101099Srwatson{
1363101099Srwatson	struct mac_biba *dest;
1364101099Srwatson
1365101099Srwatson	dest = SLOT(&cred->cr_label);
1366101099Srwatson
1367105643Srwatson	mac_biba_set_single(dest, MAC_BIBA_TYPE_HIGH, 0, NULL);
1368105643Srwatson	mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL,
1369105643Srwatson	    MAC_BIBA_TYPE_HIGH, 0, NULL);
1370101099Srwatson}
1371101099Srwatson
1372101099Srwatsonstatic void
1373101099Srwatsonmac_biba_relabel_cred(struct ucred *cred, struct label *newlabel)
1374101099Srwatson{
1375101099Srwatson	struct mac_biba *source, *dest;
1376101099Srwatson
1377101099Srwatson	source = SLOT(newlabel);
1378101099Srwatson	dest = SLOT(&cred->cr_label);
1379101099Srwatson
1380105656Srwatson	mac_biba_copy(source, dest);
1381101099Srwatson}
1382101099Srwatson
1383101099Srwatson/*
1384101099Srwatson * Access control checks.
1385101099Srwatson */
1386101099Srwatsonstatic int
1387101099Srwatsonmac_biba_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel,
1388101099Srwatson    struct ifnet *ifnet, struct label *ifnetlabel)
1389101099Srwatson{
1390101099Srwatson	struct mac_biba *a, *b;
1391101099Srwatson
1392101099Srwatson	if (!mac_biba_enabled)
1393101099Srwatson		return (0);
1394101099Srwatson
1395101099Srwatson	a = SLOT(bpflabel);
1396101099Srwatson	b = SLOT(ifnetlabel);
1397101099Srwatson
1398101099Srwatson	if (mac_biba_equal_single(a, b))
1399101099Srwatson		return (0);
1400101099Srwatson	return (EACCES);
1401101099Srwatson}
1402101099Srwatson
1403101099Srwatsonstatic int
1404101099Srwatsonmac_biba_check_cred_relabel(struct ucred *cred, struct label *newlabel)
1405101099Srwatson{
1406101099Srwatson	struct mac_biba *subj, *new;
1407105634Srwatson	int error;
1408101099Srwatson
1409101099Srwatson	subj = SLOT(&cred->cr_label);
1410101099Srwatson	new = SLOT(newlabel);
1411101099Srwatson
1412101099Srwatson	/*
1413105634Srwatson	 * If there is a Biba label update for the credential, it may
1414105634Srwatson	 * be an update of the single, range, or both.
1415101099Srwatson	 */
1416105634Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
1417105634Srwatson	if (error)
1418105634Srwatson		return (error);
1419101099Srwatson
1420101099Srwatson	/*
1421105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
1422101099Srwatson	 */
1423105634Srwatson	if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) {
1424105634Srwatson		/*
1425110351Srwatson		 * If the change request modifies both the Biba label
1426110351Srwatson		 * single and range, check that the new single will be
1427110351Srwatson		 * in the new range.
1428110351Srwatson		 */
1429110351Srwatson		if ((new->mb_flags & MAC_BIBA_FLAGS_BOTH) ==
1430110351Srwatson		    MAC_BIBA_FLAGS_BOTH &&
1431110351Srwatson		    !mac_biba_single_in_range(new, new))
1432110351Srwatson			return (EINVAL);
1433110351Srwatson
1434110351Srwatson		/*
1435105634Srwatson		 * To change the Biba single label on a credential, the
1436105634Srwatson		 * new single label must be in the current range.
1437105634Srwatson		 */
1438105634Srwatson		if (new->mb_flags & MAC_BIBA_FLAG_SINGLE &&
1439105634Srwatson		    !mac_biba_single_in_range(new, subj))
1440105634Srwatson			return (EPERM);
1441101099Srwatson
1442105634Srwatson		/*
1443105634Srwatson		 * To change the Biba range on a credential, the new
1444105634Srwatson		 * range label must be in the current range.
1445105634Srwatson		 */
1446105634Srwatson		if (new->mb_flags & MAC_BIBA_FLAG_RANGE &&
1447105634Srwatson		    !mac_biba_range_in_range(new, subj))
1448105634Srwatson			return (EPERM);
1449101099Srwatson
1450105634Srwatson		/*
1451105634Srwatson		 * To have EQUAL in any component of the new credential
1452105634Srwatson		 * Biba label, the subject must already have EQUAL in
1453105634Srwatson		 * their label.
1454105634Srwatson		 */
1455105634Srwatson		if (mac_biba_contains_equal(new)) {
1456106090Srwatson			error = mac_biba_subject_privileged(subj);
1457105634Srwatson			if (error)
1458105634Srwatson				return (error);
1459105634Srwatson		}
1460105634Srwatson	}
1461105634Srwatson
1462101099Srwatson	return (0);
1463101099Srwatson}
1464101099Srwatson
1465101099Srwatsonstatic int
1466101099Srwatsonmac_biba_check_cred_visible(struct ucred *u1, struct ucred *u2)
1467101099Srwatson{
1468101099Srwatson	struct mac_biba *subj, *obj;
1469101099Srwatson
1470101099Srwatson	if (!mac_biba_enabled)
1471101099Srwatson		return (0);
1472101099Srwatson
1473101099Srwatson	subj = SLOT(&u1->cr_label);
1474101099Srwatson	obj = SLOT(&u2->cr_label);
1475101099Srwatson
1476101099Srwatson	/* XXX: range */
1477101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1478101099Srwatson		return (ESRCH);
1479101099Srwatson
1480101099Srwatson	return (0);
1481101099Srwatson}
1482101099Srwatson
1483101099Srwatsonstatic int
1484101099Srwatsonmac_biba_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet,
1485101099Srwatson    struct label *ifnetlabel, struct label *newlabel)
1486101099Srwatson{
1487101099Srwatson	struct mac_biba *subj, *new;
1488105634Srwatson	int error;
1489101099Srwatson
1490101099Srwatson	subj = SLOT(&cred->cr_label);
1491101099Srwatson	new = SLOT(newlabel);
1492101099Srwatson
1493105634Srwatson	/*
1494105634Srwatson	 * If there is a Biba label update for the interface, it may
1495105634Srwatson	 * be an update of the single, range, or both.
1496105634Srwatson	 */
1497105634Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
1498105634Srwatson	if (error)
1499105634Srwatson		return (error);
1500101099Srwatson
1501105634Srwatson	/*
1502106160Srwatson	 * Relabling network interfaces requires Biba privilege.
1503106160Srwatson	 */
1504106160Srwatson	error = mac_biba_subject_privileged(subj);
1505106160Srwatson	if (error)
1506106160Srwatson		return (error);
1507106160Srwatson
1508106160Srwatson	/*
1509105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
1510105634Srwatson	 */
1511105634Srwatson	if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) {
1512105634Srwatson		/*
1513105634Srwatson		 * Rely on the traditional superuser status for the Biba
1514105634Srwatson		 * interface relabel requirements.  XXXMAC: This will go
1515105634Srwatson		 * away.
1516105634Srwatson		 */
1517105634Srwatson		error = suser_cred(cred, 0);
1518105634Srwatson		if (error)
1519105634Srwatson			return (EPERM);
1520105634Srwatson
1521105634Srwatson		/*
1522105634Srwatson		 * XXXMAC: Additional consistency tests regarding the single
1523105634Srwatson		 * and the range of the new label might be performed here.
1524105634Srwatson		 */
1525105634Srwatson	}
1526105634Srwatson
1527105634Srwatson	return (0);
1528101099Srwatson}
1529101099Srwatson
1530103759Srwatsonstatic int
1531101099Srwatsonmac_biba_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel,
1532101099Srwatson    struct mbuf *m, struct label *mbuflabel)
1533101099Srwatson{
1534101099Srwatson	struct mac_biba *p, *i;
1535103761Srwatson
1536101099Srwatson	if (!mac_biba_enabled)
1537101099Srwatson		return (0);
1538101099Srwatson
1539101099Srwatson	p = SLOT(mbuflabel);
1540101099Srwatson	i = SLOT(ifnetlabel);
1541103759Srwatson
1542101099Srwatson	return (mac_biba_single_in_range(p, i) ? 0 : EACCES);
1543101099Srwatson}
1544101099Srwatson
1545101099Srwatsonstatic int
1546110354Srwatsonmac_biba_check_kld_load(struct ucred *cred, struct vnode *vp,
1547110354Srwatson    struct label *label)
1548110354Srwatson{
1549110354Srwatson	struct mac_biba *subj, *obj;
1550110354Srwatson	int error;
1551110354Srwatson
1552110354Srwatson	if (!mac_biba_enabled)
1553110354Srwatson		return (0);
1554110354Srwatson
1555110354Srwatson	subj = SLOT(&cred->cr_label);
1556110354Srwatson
1557110354Srwatson	error = mac_biba_subject_privileged(subj);
1558110354Srwatson	if (error)
1559110354Srwatson		return (error);
1560110354Srwatson
1561110354Srwatson	obj = SLOT(label);
1562110354Srwatson	if (!mac_biba_high_single(obj))
1563110354Srwatson		return (EACCES);
1564110354Srwatson
1565110354Srwatson	return (0);
1566110354Srwatson}
1567110354Srwatson
1568110354Srwatson
1569110354Srwatsonstatic int
1570110354Srwatsonmac_biba_check_kld_unload(struct ucred *cred)
1571110354Srwatson{
1572110354Srwatson	struct mac_biba *subj;
1573110354Srwatson
1574110354Srwatson	if (!mac_biba_enabled)
1575110354Srwatson		return (0);
1576110354Srwatson
1577110354Srwatson	subj = SLOT(&cred->cr_label);
1578110354Srwatson
1579110354Srwatson	return (mac_biba_subject_privileged(subj));
1580110354Srwatson}
1581110354Srwatson
1582110354Srwatsonstatic int
1583101099Srwatsonmac_biba_check_mount_stat(struct ucred *cred, struct mount *mp,
1584101099Srwatson    struct label *mntlabel)
1585101099Srwatson{
1586101099Srwatson	struct mac_biba *subj, *obj;
1587101099Srwatson
1588101099Srwatson	if (!mac_biba_enabled)
1589101099Srwatson		return (0);
1590101099Srwatson
1591101099Srwatson	subj = SLOT(&cred->cr_label);
1592101099Srwatson	obj = SLOT(mntlabel);
1593101099Srwatson
1594101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1595101099Srwatson		return (EACCES);
1596101099Srwatson
1597101099Srwatson	return (0);
1598101099Srwatson}
1599101099Srwatson
1600101099Srwatsonstatic int
1601101099Srwatsonmac_biba_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe,
1602101099Srwatson    struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data)
1603101099Srwatson{
1604103759Srwatson
1605101099Srwatson	if(!mac_biba_enabled)
1606101099Srwatson		return (0);
1607101099Srwatson
1608101099Srwatson	/* XXX: This will be implemented soon... */
1609101099Srwatson
1610101099Srwatson	return (0);
1611101099Srwatson}
1612101099Srwatson
1613101099Srwatsonstatic int
1614102115Srwatsonmac_biba_check_pipe_poll(struct ucred *cred, struct pipe *pipe,
1615102115Srwatson    struct label *pipelabel)
1616101099Srwatson{
1617101099Srwatson	struct mac_biba *subj, *obj;
1618101099Srwatson
1619101099Srwatson	if (!mac_biba_enabled)
1620101099Srwatson		return (0);
1621101099Srwatson
1622101099Srwatson	subj = SLOT(&cred->cr_label);
1623101099Srwatson	obj = SLOT((pipelabel));
1624101099Srwatson
1625102115Srwatson	if (!mac_biba_dominate_single(obj, subj))
1626102115Srwatson		return (EACCES);
1627101099Srwatson
1628101099Srwatson	return (0);
1629101099Srwatson}
1630101099Srwatson
1631101099Srwatsonstatic int
1632102115Srwatsonmac_biba_check_pipe_read(struct ucred *cred, struct pipe *pipe,
1633102115Srwatson    struct label *pipelabel)
1634102115Srwatson{
1635102115Srwatson	struct mac_biba *subj, *obj;
1636102115Srwatson
1637102115Srwatson	if (!mac_biba_enabled)
1638102115Srwatson		return (0);
1639102115Srwatson
1640102115Srwatson	subj = SLOT(&cred->cr_label);
1641102115Srwatson	obj = SLOT((pipelabel));
1642102115Srwatson
1643102115Srwatson	if (!mac_biba_dominate_single(obj, subj))
1644102115Srwatson		return (EACCES);
1645102115Srwatson
1646102115Srwatson	return (0);
1647102115Srwatson}
1648102115Srwatson
1649102115Srwatsonstatic int
1650101099Srwatsonmac_biba_check_pipe_relabel(struct ucred *cred, struct pipe *pipe,
1651101099Srwatson    struct label *pipelabel, struct label *newlabel)
1652101099Srwatson{
1653101099Srwatson	struct mac_biba *subj, *obj, *new;
1654105634Srwatson	int error;
1655101099Srwatson
1656101099Srwatson	new = SLOT(newlabel);
1657101099Srwatson	subj = SLOT(&cred->cr_label);
1658101099Srwatson	obj = SLOT(pipelabel);
1659101099Srwatson
1660101099Srwatson	/*
1661105634Srwatson	 * If there is a Biba label update for a pipe, it must be a
1662105634Srwatson	 * single update.
1663101099Srwatson	 */
1664105634Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE);
1665105634Srwatson	if (error)
1666105634Srwatson		return (error);
1667101099Srwatson
1668101099Srwatson	/*
1669105634Srwatson	 * To perform a relabel of a pipe (Biba label or not), Biba must
1670105634Srwatson	 * authorize the relabel.
1671101099Srwatson	 */
1672105634Srwatson	if (!mac_biba_single_in_range(obj, subj))
1673101099Srwatson		return (EPERM);
1674101099Srwatson
1675101099Srwatson	/*
1676105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
1677101099Srwatson	 */
1678105634Srwatson	if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) {
1679105634Srwatson		/*
1680105634Srwatson		 * To change the Biba label on a pipe, the new pipe label
1681105634Srwatson		 * must be in the subject range.
1682105634Srwatson		 */
1683105634Srwatson		if (!mac_biba_single_in_range(new, subj))
1684105634Srwatson			return (EPERM);
1685101099Srwatson
1686105634Srwatson		/*
1687105634Srwatson		 * To change the Biba label on a pipe to be EQUAL, the
1688105634Srwatson		 * subject must have appropriate privilege.
1689105634Srwatson		 */
1690105634Srwatson		if (mac_biba_contains_equal(new)) {
1691106090Srwatson			error = mac_biba_subject_privileged(subj);
1692105634Srwatson			if (error)
1693105634Srwatson				return (error);
1694105634Srwatson		}
1695105634Srwatson	}
1696105634Srwatson
1697101099Srwatson	return (0);
1698101099Srwatson}
1699101099Srwatson
1700101099Srwatsonstatic int
1701102115Srwatsonmac_biba_check_pipe_stat(struct ucred *cred, struct pipe *pipe,
1702102115Srwatson    struct label *pipelabel)
1703102115Srwatson{
1704102115Srwatson	struct mac_biba *subj, *obj;
1705102115Srwatson
1706102115Srwatson	if (!mac_biba_enabled)
1707102115Srwatson		return (0);
1708102115Srwatson
1709102115Srwatson	subj = SLOT(&cred->cr_label);
1710102115Srwatson	obj = SLOT((pipelabel));
1711102115Srwatson
1712102115Srwatson	if (!mac_biba_dominate_single(obj, subj))
1713102115Srwatson		return (EACCES);
1714102115Srwatson
1715102115Srwatson	return (0);
1716102115Srwatson}
1717102115Srwatson
1718102115Srwatsonstatic int
1719102115Srwatsonmac_biba_check_pipe_write(struct ucred *cred, struct pipe *pipe,
1720102115Srwatson    struct label *pipelabel)
1721102115Srwatson{
1722102115Srwatson	struct mac_biba *subj, *obj;
1723102115Srwatson
1724102115Srwatson	if (!mac_biba_enabled)
1725102115Srwatson		return (0);
1726102115Srwatson
1727102115Srwatson	subj = SLOT(&cred->cr_label);
1728102115Srwatson	obj = SLOT((pipelabel));
1729102115Srwatson
1730102115Srwatson	if (!mac_biba_dominate_single(subj, obj))
1731102115Srwatson		return (EACCES);
1732102115Srwatson
1733102115Srwatson	return (0);
1734102115Srwatson}
1735102115Srwatson
1736102115Srwatsonstatic int
1737101099Srwatsonmac_biba_check_proc_debug(struct ucred *cred, struct proc *proc)
1738101099Srwatson{
1739101099Srwatson	struct mac_biba *subj, *obj;
1740101099Srwatson
1741101099Srwatson	if (!mac_biba_enabled)
1742101099Srwatson		return (0);
1743101099Srwatson
1744101099Srwatson	subj = SLOT(&cred->cr_label);
1745101099Srwatson	obj = SLOT(&proc->p_ucred->cr_label);
1746101099Srwatson
1747101099Srwatson	/* XXX: range checks */
1748101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1749101099Srwatson		return (ESRCH);
1750101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1751101099Srwatson		return (EACCES);
1752101099Srwatson
1753101099Srwatson	return (0);
1754101099Srwatson}
1755101099Srwatson
1756101099Srwatsonstatic int
1757101099Srwatsonmac_biba_check_proc_sched(struct ucred *cred, struct proc *proc)
1758101099Srwatson{
1759101099Srwatson	struct mac_biba *subj, *obj;
1760103759Srwatson
1761101099Srwatson	if (!mac_biba_enabled)
1762101099Srwatson		return (0);
1763101099Srwatson
1764101099Srwatson	subj = SLOT(&cred->cr_label);
1765101099Srwatson	obj = SLOT(&proc->p_ucred->cr_label);
1766103759Srwatson
1767101099Srwatson	/* XXX: range checks */
1768101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1769101099Srwatson		return (ESRCH);
1770101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1771101099Srwatson		return (EACCES);
1772101099Srwatson
1773101099Srwatson	return (0);
1774101099Srwatson}
1775101099Srwatson
1776101099Srwatsonstatic int
1777101099Srwatsonmac_biba_check_proc_signal(struct ucred *cred, struct proc *proc, int signum)
1778101099Srwatson{
1779101099Srwatson	struct mac_biba *subj, *obj;
1780103759Srwatson
1781101099Srwatson	if (!mac_biba_enabled)
1782101099Srwatson		return (0);
1783101099Srwatson
1784101099Srwatson	subj = SLOT(&cred->cr_label);
1785101099Srwatson	obj = SLOT(&proc->p_ucred->cr_label);
1786103759Srwatson
1787101099Srwatson	/* XXX: range checks */
1788101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1789101099Srwatson		return (ESRCH);
1790101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1791101099Srwatson		return (EACCES);
1792101099Srwatson
1793101099Srwatson	return (0);
1794101099Srwatson}
1795101099Srwatson
1796101099Srwatsonstatic int
1797101934Srwatsonmac_biba_check_socket_deliver(struct socket *so, struct label *socketlabel,
1798101099Srwatson    struct mbuf *m, struct label *mbuflabel)
1799101099Srwatson{
1800101099Srwatson	struct mac_biba *p, *s;
1801101099Srwatson
1802101099Srwatson	if (!mac_biba_enabled)
1803101099Srwatson		return (0);
1804101099Srwatson
1805101099Srwatson	p = SLOT(mbuflabel);
1806101099Srwatson	s = SLOT(socketlabel);
1807101099Srwatson
1808101099Srwatson	return (mac_biba_equal_single(p, s) ? 0 : EACCES);
1809101099Srwatson}
1810101099Srwatson
1811101099Srwatsonstatic int
1812106214Srwatsonmac_biba_check_socket_relabel(struct ucred *cred, struct socket *so,
1813101099Srwatson    struct label *socketlabel, struct label *newlabel)
1814101099Srwatson{
1815101099Srwatson	struct mac_biba *subj, *obj, *new;
1816105634Srwatson	int error;
1817101099Srwatson
1818101099Srwatson	new = SLOT(newlabel);
1819101099Srwatson	subj = SLOT(&cred->cr_label);
1820101099Srwatson	obj = SLOT(socketlabel);
1821101099Srwatson
1822101099Srwatson	/*
1823105634Srwatson	 * If there is a Biba label update for the socket, it may be
1824105634Srwatson	 * an update of single.
1825101099Srwatson	 */
1826105634Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE);
1827105634Srwatson	if (error)
1828105634Srwatson		return (error);
1829101099Srwatson
1830101099Srwatson	/*
1831105634Srwatson	 * To relabel a socket, the old socket single must be in the subject
1832101099Srwatson	 * range.
1833101099Srwatson	 */
1834105634Srwatson	if (!mac_biba_single_in_range(obj, subj))
1835101099Srwatson		return (EPERM);
1836101099Srwatson
1837101099Srwatson	/*
1838105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
1839101099Srwatson	 */
1840105634Srwatson	if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) {
1841105634Srwatson		/*
1842105634Srwatson		 * To relabel a socket, the new socket single must be in
1843105634Srwatson		 * the subject range.
1844105634Srwatson		 */
1845105634Srwatson		if (!mac_biba_single_in_range(new, subj))
1846105634Srwatson			return (EPERM);
1847101099Srwatson
1848105634Srwatson		/*
1849105634Srwatson		 * To change the Biba label on the socket to contain EQUAL,
1850105634Srwatson		 * the subject must have appropriate privilege.
1851105634Srwatson		 */
1852105634Srwatson		if (mac_biba_contains_equal(new)) {
1853106090Srwatson			error = mac_biba_subject_privileged(subj);
1854105634Srwatson			if (error)
1855105634Srwatson				return (error);
1856105634Srwatson		}
1857105634Srwatson	}
1858105634Srwatson
1859101099Srwatson	return (0);
1860101099Srwatson}
1861101099Srwatson
1862101099Srwatsonstatic int
1863101099Srwatsonmac_biba_check_socket_visible(struct ucred *cred, struct socket *socket,
1864101099Srwatson    struct label *socketlabel)
1865101099Srwatson{
1866101099Srwatson	struct mac_biba *subj, *obj;
1867101099Srwatson
1868105722Srwatson	if (!mac_biba_enabled)
1869105722Srwatson		return (0);
1870105722Srwatson
1871101099Srwatson	subj = SLOT(&cred->cr_label);
1872101099Srwatson	obj = SLOT(socketlabel);
1873101099Srwatson
1874101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1875101099Srwatson		return (ENOENT);
1876101099Srwatson
1877101099Srwatson	return (0);
1878101099Srwatson}
1879101099Srwatson
1880101099Srwatsonstatic int
1881112574Srwatsonmac_biba_check_sysarch_ioperm(struct ucred *cred)
1882112574Srwatson{
1883112574Srwatson	struct mac_biba *subj;
1884112574Srwatson	int error;
1885112574Srwatson
1886112574Srwatson	if (!mac_biba_enabled)
1887112574Srwatson		return (0);
1888112574Srwatson
1889112574Srwatson	subj = SLOT(&cred->cr_label);
1890112574Srwatson
1891112574Srwatson	error = mac_biba_subject_privileged(subj);
1892112574Srwatson	if (error)
1893112574Srwatson		return (error);
1894112574Srwatson
1895112574Srwatson	return (0);
1896112574Srwatson}
1897112574Srwatson
1898112574Srwatsonstatic int
1899106418Srwatsonmac_biba_check_system_acct(struct ucred *cred, struct vnode *vp,
1900106418Srwatson    struct label *label)
1901106418Srwatson{
1902106418Srwatson	struct mac_biba *subj, *obj;
1903106418Srwatson	int error;
1904106418Srwatson
1905106418Srwatson	if (!mac_biba_enabled)
1906106418Srwatson		return (0);
1907106418Srwatson
1908106418Srwatson	subj = SLOT(&cred->cr_label);
1909106418Srwatson
1910106418Srwatson	error = mac_biba_subject_privileged(subj);
1911106418Srwatson	if (error)
1912106418Srwatson		return (error);
1913106418Srwatson
1914106418Srwatson	if (label == NULL)
1915106418Srwatson		return (0);
1916106418Srwatson
1917106418Srwatson	obj = SLOT(label);
1918106418Srwatson	if (!mac_biba_high_single(obj))
1919106418Srwatson		return (EACCES);
1920106418Srwatson
1921106418Srwatson	return (0);
1922106418Srwatson}
1923106418Srwatson
1924106418Srwatsonstatic int
1925106418Srwatsonmac_biba_check_system_settime(struct ucred *cred)
1926106418Srwatson{
1927106418Srwatson	struct mac_biba *subj;
1928106418Srwatson	int error;
1929106418Srwatson
1930106418Srwatson	if (!mac_biba_enabled)
1931106418Srwatson		return (0);
1932106418Srwatson
1933106418Srwatson	subj = SLOT(&cred->cr_label);
1934106418Srwatson
1935106418Srwatson	error = mac_biba_subject_privileged(subj);
1936106418Srwatson	if (error)
1937106418Srwatson		return (error);
1938106418Srwatson
1939106418Srwatson	return (0);
1940106418Srwatson}
1941106418Srwatson
1942106418Srwatsonstatic int
1943106161Srwatsonmac_biba_check_system_swapon(struct ucred *cred, struct vnode *vp,
1944106161Srwatson    struct label *label)
1945106161Srwatson{
1946106161Srwatson	struct mac_biba *subj, *obj;
1947106416Srwatson	int error;
1948106161Srwatson
1949106161Srwatson	if (!mac_biba_enabled)
1950106161Srwatson		return (0);
1951106161Srwatson
1952106161Srwatson	subj = SLOT(&cred->cr_label);
1953106161Srwatson	obj = SLOT(label);
1954106161Srwatson
1955106416Srwatson	error = mac_biba_subject_privileged(subj);
1956106416Srwatson	if (error)
1957106416Srwatson		return (error);
1958106161Srwatson
1959106161Srwatson	if (!mac_biba_high_single(obj))
1960106161Srwatson		return (EACCES);
1961106161Srwatson
1962106161Srwatson	return (0);
1963106161Srwatson}
1964106161Srwatson
1965106161Srwatsonstatic int
1966112574Srwatsonmac_biba_check_system_swapoff(struct ucred *cred, struct vnode *vp,
1967112574Srwatson    struct label *label)
1968112574Srwatson{
1969112574Srwatson	struct mac_biba *subj, *obj;
1970112574Srwatson	int error;
1971112574Srwatson
1972112574Srwatson	if (!mac_biba_enabled)
1973112574Srwatson		return (0);
1974112574Srwatson
1975112574Srwatson	subj = SLOT(&cred->cr_label);
1976112574Srwatson	obj = SLOT(label);
1977112574Srwatson
1978112574Srwatson	error = mac_biba_subject_privileged(subj);
1979112574Srwatson	if (error)
1980112574Srwatson		return (error);
1981112574Srwatson
1982112574Srwatson	return (0);
1983112574Srwatson}
1984112574Srwatson
1985112574Srwatsonstatic int
1986106161Srwatsonmac_biba_check_system_sysctl(struct ucred *cred, int *name, u_int namelen,
1987106161Srwatson    void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen)
1988106161Srwatson{
1989106161Srwatson	struct mac_biba *subj;
1990106161Srwatson	int error;
1991106161Srwatson
1992106161Srwatson	if (!mac_biba_enabled)
1993106161Srwatson		return (0);
1994106161Srwatson
1995106161Srwatson	subj = SLOT(&cred->cr_label);
1996106161Srwatson
1997106161Srwatson	/*
1998106161Srwatson	 * In general, treat sysctl variables as biba/high, but also
1999106161Srwatson	 * require privilege to change them, since they are a
2000106161Srwatson	 * communications channel between grades.  Exempt MIB
2001106161Srwatson	 * queries from this due to undocmented sysctl magic.
2002106161Srwatson	 * XXXMAC: This probably requires some more review.
2003106161Srwatson	 */
2004106161Srwatson	if (new != NULL) {
2005106161Srwatson		if (namelen > 0 && name[0] == 0)
2006106161Srwatson			return (0);
2007106161Srwatson
2008106161Srwatson		if (!mac_biba_subject_dominate_high(subj))
2009106161Srwatson			return (EACCES);
2010106161Srwatson
2011106161Srwatson		error = mac_biba_subject_privileged(subj);
2012106161Srwatson		if (error)
2013106161Srwatson			return (error);
2014106161Srwatson	}
2015106161Srwatson
2016106161Srwatson	return (0);
2017106161Srwatson}
2018106161Srwatson
2019106161Srwatsonstatic int
2020101099Srwatsonmac_biba_check_vnode_chdir(struct ucred *cred, struct vnode *dvp,
2021101099Srwatson    struct label *dlabel)
2022101099Srwatson{
2023101099Srwatson	struct mac_biba *subj, *obj;
2024101099Srwatson
2025101099Srwatson	if (!mac_biba_enabled)
2026101099Srwatson		return (0);
2027101099Srwatson
2028101099Srwatson	subj = SLOT(&cred->cr_label);
2029101099Srwatson	obj = SLOT(dlabel);
2030101099Srwatson
2031101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
2032101099Srwatson		return (EACCES);
2033101099Srwatson
2034101099Srwatson	return (0);
2035101099Srwatson}
2036101099Srwatson
2037101099Srwatsonstatic int
2038101099Srwatsonmac_biba_check_vnode_chroot(struct ucred *cred, struct vnode *dvp,
2039101099Srwatson    struct label *dlabel)
2040101099Srwatson{
2041101099Srwatson	struct mac_biba *subj, *obj;
2042101099Srwatson
2043101099Srwatson	if (!mac_biba_enabled)
2044101099Srwatson		return (0);
2045101099Srwatson
2046101099Srwatson	subj = SLOT(&cred->cr_label);
2047101099Srwatson	obj = SLOT(dlabel);
2048101099Srwatson
2049101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
2050101099Srwatson		return (EACCES);
2051101099Srwatson
2052101099Srwatson	return (0);
2053101099Srwatson}
2054101099Srwatson
2055101099Srwatsonstatic int
2056101099Srwatsonmac_biba_check_vnode_create(struct ucred *cred, struct vnode *dvp,
2057101099Srwatson    struct label *dlabel, struct componentname *cnp, struct vattr *vap)
2058101099Srwatson{
2059101099Srwatson	struct mac_biba *subj, *obj;
2060101099Srwatson
2061101099Srwatson	if (!mac_biba_enabled)
2062101099Srwatson		return (0);
2063101099Srwatson
2064101099Srwatson	subj = SLOT(&cred->cr_label);
2065101099Srwatson	obj = SLOT(dlabel);
2066101099Srwatson
2067101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2068101099Srwatson		return (EACCES);
2069101099Srwatson
2070101099Srwatson	return (0);
2071101099Srwatson}
2072101099Srwatson
2073101099Srwatsonstatic int
2074101099Srwatsonmac_biba_check_vnode_delete(struct ucred *cred, struct vnode *dvp,
2075101099Srwatson    struct label *dlabel, struct vnode *vp, struct label *label,
2076101099Srwatson    struct componentname *cnp)
2077101099Srwatson{
2078101099Srwatson	struct mac_biba *subj, *obj;
2079101099Srwatson
2080101099Srwatson	if (!mac_biba_enabled)
2081101099Srwatson		return (0);
2082101099Srwatson
2083101099Srwatson	subj = SLOT(&cred->cr_label);
2084101099Srwatson	obj = SLOT(dlabel);
2085101099Srwatson
2086101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2087101099Srwatson		return (EACCES);
2088101099Srwatson
2089101099Srwatson	obj = SLOT(label);
2090101099Srwatson
2091101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2092101099Srwatson		return (EACCES);
2093101099Srwatson
2094101099Srwatson	return (0);
2095101099Srwatson}
2096101099Srwatson
2097101099Srwatsonstatic int
2098101099Srwatsonmac_biba_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
2099101099Srwatson    struct label *label, acl_type_t type)
2100101099Srwatson{
2101101099Srwatson	struct mac_biba *subj, *obj;
2102101099Srwatson
2103101099Srwatson	if (!mac_biba_enabled)
2104101099Srwatson		return (0);
2105101099Srwatson
2106101099Srwatson	subj = SLOT(&cred->cr_label);
2107101099Srwatson	obj = SLOT(label);
2108101099Srwatson
2109101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2110101099Srwatson		return (EACCES);
2111101099Srwatson
2112101099Srwatson	return (0);
2113101099Srwatson}
2114101099Srwatson
2115101099Srwatsonstatic int
2116101099Srwatsonmac_biba_check_vnode_exec(struct ucred *cred, struct vnode *vp,
2117106648Srwatson    struct label *label, struct image_params *imgp,
2118106648Srwatson    struct label *execlabel)
2119101099Srwatson{
2120106648Srwatson	struct mac_biba *subj, *obj, *exec;
2121106648Srwatson	int error;
2122101099Srwatson
2123106648Srwatson	if (execlabel != NULL) {
2124106648Srwatson		/*
2125106648Srwatson		 * We currently don't permit labels to be changed at
2126106648Srwatson		 * exec-time as part of Biba, so disallow non-NULL
2127106648Srwatson		 * Biba label elements in the execlabel.
2128106648Srwatson		 */
2129106648Srwatson		exec = SLOT(execlabel);
2130106648Srwatson		error = biba_atmostflags(exec, 0);
2131106648Srwatson		if (error)
2132106648Srwatson			return (error);
2133106648Srwatson	}
2134106648Srwatson
2135101099Srwatson	if (!mac_biba_enabled)
2136101099Srwatson		return (0);
2137101099Srwatson
2138101099Srwatson	subj = SLOT(&cred->cr_label);
2139101099Srwatson	obj = SLOT(label);
2140101099Srwatson
2141101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
2142101099Srwatson		return (EACCES);
2143101099Srwatson
2144101099Srwatson	return (0);
2145101099Srwatson}
2146101099Srwatson
2147101099Srwatsonstatic int
2148101099Srwatsonmac_biba_check_vnode_getacl(struct ucred *cred, struct vnode *vp,
2149101099Srwatson    struct label *label, acl_type_t type)
2150101099Srwatson{
2151101099Srwatson	struct mac_biba *subj, *obj;
2152101099Srwatson
2153101099Srwatson	if (!mac_biba_enabled)
2154101099Srwatson		return (0);
2155101099Srwatson
2156101099Srwatson	subj = SLOT(&cred->cr_label);
2157101099Srwatson	obj = SLOT(label);
2158101099Srwatson
2159101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
2160101099Srwatson		return (EACCES);
2161101099Srwatson
2162101099Srwatson	return (0);
2163101099Srwatson}
2164101099Srwatson
2165101099Srwatsonstatic int
2166101099Srwatsonmac_biba_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
2167101099Srwatson    struct label *label, int attrnamespace, const char *name, struct uio *uio)
2168101099Srwatson{
2169101099Srwatson	struct mac_biba *subj, *obj;
2170101099Srwatson
2171101099Srwatson	if (!mac_biba_enabled)
2172101099Srwatson		return (0);
2173101099Srwatson
2174101099Srwatson	subj = SLOT(&cred->cr_label);
2175101099Srwatson	obj = SLOT(label);
2176101099Srwatson
2177101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
2178101099Srwatson		return (EACCES);
2179101099Srwatson
2180101099Srwatson	return (0);
2181101099Srwatson}
2182101099Srwatson
2183101099Srwatsonstatic int
2184104530Srwatsonmac_biba_check_vnode_link(struct ucred *cred, struct vnode *dvp,
2185104530Srwatson    struct label *dlabel, struct vnode *vp, struct label *label,
2186104530Srwatson    struct componentname *cnp)
2187104530Srwatson{
2188104530Srwatson	struct mac_biba *subj, *obj;
2189104530Srwatson
2190104530Srwatson	if (!mac_biba_enabled)
2191104530Srwatson		return (0);
2192104530Srwatson
2193104530Srwatson	subj = SLOT(&cred->cr_label);
2194104530Srwatson	obj = SLOT(dlabel);
2195104530Srwatson
2196104530Srwatson	if (!mac_biba_dominate_single(subj, obj))
2197104530Srwatson		return (EACCES);
2198104530Srwatson
2199104530Srwatson	obj = SLOT(label);
2200104530Srwatson
2201104530Srwatson	if (!mac_biba_dominate_single(subj, obj))
2202104530Srwatson		return (EACCES);
2203104530Srwatson
2204104530Srwatson	return (0);
2205104530Srwatson}
2206104530Srwatson
2207104530Srwatsonstatic int
2208103759Srwatsonmac_biba_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
2209101099Srwatson    struct label *dlabel, struct componentname *cnp)
2210101099Srwatson{
2211101099Srwatson	struct mac_biba *subj, *obj;
2212103759Srwatson
2213101099Srwatson	if (!mac_biba_enabled)
2214101099Srwatson		return (0);
2215103759Srwatson
2216101099Srwatson	subj = SLOT(&cred->cr_label);
2217101099Srwatson	obj = SLOT(dlabel);
2218103759Srwatson
2219101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
2220101099Srwatson		return (EACCES);
2221101099Srwatson
2222103759Srwatson	return (0);
2223101099Srwatson}
2224101099Srwatson
2225101099Srwatsonstatic int
2226104546Srwatsonmac_biba_check_vnode_mmap(struct ucred *cred, struct vnode *vp,
2227104546Srwatson    struct label *label, int prot)
2228104546Srwatson{
2229104546Srwatson	struct mac_biba *subj, *obj;
2230104546Srwatson
2231104546Srwatson	/*
2232104546Srwatson	 * Rely on the use of open()-time protections to handle
2233104546Srwatson	 * non-revocation cases.
2234104546Srwatson	 */
2235105637Srwatson	if (!mac_biba_enabled || !revocation_enabled)
2236104546Srwatson		return (0);
2237104546Srwatson
2238104546Srwatson	subj = SLOT(&cred->cr_label);
2239104546Srwatson	obj = SLOT(label);
2240104546Srwatson
2241104546Srwatson	if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
2242104546Srwatson		if (!mac_biba_dominate_single(obj, subj))
2243104546Srwatson			return (EACCES);
2244104546Srwatson	}
2245104546Srwatson	if (prot & VM_PROT_WRITE) {
2246104546Srwatson		if (!mac_biba_dominate_single(subj, obj))
2247104546Srwatson			return (EACCES);
2248104546Srwatson	}
2249104546Srwatson
2250104569Srwatson	return (0);
2251104546Srwatson}
2252104546Srwatson
2253104546Srwatsonstatic int
2254101099Srwatsonmac_biba_check_vnode_open(struct ucred *cred, struct vnode *vp,
2255106212Srwatson    struct label *vnodelabel, int acc_mode)
2256101099Srwatson{
2257101099Srwatson	struct mac_biba *subj, *obj;
2258101099Srwatson
2259101099Srwatson	if (!mac_biba_enabled)
2260101099Srwatson		return (0);
2261101099Srwatson
2262101099Srwatson	subj = SLOT(&cred->cr_label);
2263101099Srwatson	obj = SLOT(vnodelabel);
2264101099Srwatson
2265101099Srwatson	/* XXX privilege override for admin? */
2266101099Srwatson	if (acc_mode & (VREAD | VEXEC | VSTAT)) {
2267101099Srwatson		if (!mac_biba_dominate_single(obj, subj))
2268101099Srwatson			return (EACCES);
2269101099Srwatson	}
2270101099Srwatson	if (acc_mode & (VWRITE | VAPPEND | VADMIN)) {
2271101099Srwatson		if (!mac_biba_dominate_single(subj, obj))
2272101099Srwatson			return (EACCES);
2273101099Srwatson	}
2274101099Srwatson
2275101099Srwatson	return (0);
2276101099Srwatson}
2277101099Srwatson
2278101099Srwatsonstatic int
2279102129Srwatsonmac_biba_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred,
2280102129Srwatson    struct vnode *vp, struct label *label)
2281102112Srwatson{
2282102112Srwatson	struct mac_biba *subj, *obj;
2283102112Srwatson
2284105637Srwatson	if (!mac_biba_enabled || !revocation_enabled)
2285102112Srwatson		return (0);
2286102112Srwatson
2287102129Srwatson	subj = SLOT(&active_cred->cr_label);
2288102112Srwatson	obj = SLOT(label);
2289102112Srwatson
2290102112Srwatson	if (!mac_biba_dominate_single(obj, subj))
2291102112Srwatson		return (EACCES);
2292102112Srwatson
2293102112Srwatson	return (0);
2294102112Srwatson}
2295102112Srwatson
2296102112Srwatsonstatic int
2297102129Srwatsonmac_biba_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
2298102129Srwatson    struct vnode *vp, struct label *label)
2299102112Srwatson{
2300102112Srwatson	struct mac_biba *subj, *obj;
2301102112Srwatson
2302105637Srwatson	if (!mac_biba_enabled || !revocation_enabled)
2303102112Srwatson		return (0);
2304102112Srwatson
2305102129Srwatson	subj = SLOT(&active_cred->cr_label);
2306102112Srwatson	obj = SLOT(label);
2307102112Srwatson
2308102112Srwatson	if (!mac_biba_dominate_single(obj, subj))
2309102112Srwatson		return (EACCES);
2310102112Srwatson
2311102112Srwatson	return (0);
2312102112Srwatson}
2313102112Srwatson
2314102112Srwatsonstatic int
2315101099Srwatsonmac_biba_check_vnode_readdir(struct ucred *cred, struct vnode *dvp,
2316101099Srwatson    struct label *dlabel)
2317101099Srwatson{
2318101099Srwatson	struct mac_biba *subj, *obj;
2319101099Srwatson
2320101099Srwatson	if (!mac_biba_enabled)
2321101099Srwatson		return (0);
2322101099Srwatson
2323101099Srwatson	subj = SLOT(&cred->cr_label);
2324101099Srwatson	obj = SLOT(dlabel);
2325101099Srwatson
2326101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
2327101099Srwatson		return (EACCES);
2328101099Srwatson
2329101099Srwatson	return (0);
2330101099Srwatson}
2331101099Srwatson
2332101099Srwatsonstatic int
2333101099Srwatsonmac_biba_check_vnode_readlink(struct ucred *cred, struct vnode *vp,
2334101099Srwatson    struct label *label)
2335101099Srwatson{
2336101099Srwatson	struct mac_biba *subj, *obj;
2337101099Srwatson
2338101099Srwatson	if (!mac_biba_enabled)
2339101099Srwatson		return (0);
2340101099Srwatson
2341101099Srwatson	subj = SLOT(&cred->cr_label);
2342101099Srwatson	obj = SLOT(label);
2343101099Srwatson
2344101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
2345101099Srwatson		return (EACCES);
2346101099Srwatson
2347101099Srwatson	return (0);
2348101099Srwatson}
2349101099Srwatson
2350101099Srwatsonstatic int
2351101099Srwatsonmac_biba_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
2352101099Srwatson    struct label *vnodelabel, struct label *newlabel)
2353101099Srwatson{
2354101099Srwatson	struct mac_biba *old, *new, *subj;
2355105634Srwatson	int error;
2356101099Srwatson
2357101099Srwatson	old = SLOT(vnodelabel);
2358101099Srwatson	new = SLOT(newlabel);
2359101099Srwatson	subj = SLOT(&cred->cr_label);
2360101099Srwatson
2361101099Srwatson	/*
2362105634Srwatson	 * If there is a Biba label update for the vnode, it must be a
2363105634Srwatson	 * single label.
2364101099Srwatson	 */
2365105634Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE);
2366105634Srwatson	if (error)
2367105634Srwatson		return (error);
2368101099Srwatson
2369101099Srwatson	/*
2370105634Srwatson	 * To perform a relabel of the vnode (Biba label or not), Biba must
2371105634Srwatson	 * authorize the relabel.
2372101099Srwatson	 */
2373105634Srwatson	if (!mac_biba_single_in_range(old, subj))
2374101099Srwatson		return (EPERM);
2375101099Srwatson
2376101099Srwatson	/*
2377105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
2378101099Srwatson	 */
2379105634Srwatson	if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) {
2380105634Srwatson		/*
2381105634Srwatson		 * To change the Biba label on a vnode, the new vnode label
2382105634Srwatson		 * must be in the subject range.
2383105634Srwatson		 */
2384105634Srwatson		if (!mac_biba_single_in_range(new, subj))
2385105634Srwatson			return (EPERM);
2386101099Srwatson
2387105634Srwatson		/*
2388105634Srwatson		 * To change the Biba label on the vnode to be EQUAL,
2389105634Srwatson		 * the subject must have appropriate privilege.
2390105634Srwatson		 */
2391105634Srwatson		if (mac_biba_contains_equal(new)) {
2392106090Srwatson			error = mac_biba_subject_privileged(subj);
2393105634Srwatson			if (error)
2394105634Srwatson				return (error);
2395105634Srwatson		}
2396105634Srwatson	}
2397105634Srwatson
2398105634Srwatson	return (0);
2399101099Srwatson}
2400101099Srwatson
2401101099Srwatsonstatic int
2402101099Srwatsonmac_biba_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
2403101099Srwatson    struct label *dlabel, struct vnode *vp, struct label *label,
2404101099Srwatson    struct componentname *cnp)
2405101099Srwatson{
2406101099Srwatson	struct mac_biba *subj, *obj;
2407101099Srwatson
2408101099Srwatson	if (!mac_biba_enabled)
2409101099Srwatson		return (0);
2410101099Srwatson
2411101099Srwatson	subj = SLOT(&cred->cr_label);
2412101099Srwatson	obj = SLOT(dlabel);
2413101099Srwatson
2414101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2415101099Srwatson		return (EACCES);
2416101099Srwatson
2417101099Srwatson	obj = SLOT(label);
2418101099Srwatson
2419101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2420101099Srwatson		return (EACCES);
2421101099Srwatson
2422101099Srwatson	return (0);
2423101099Srwatson}
2424101099Srwatson
2425101099Srwatsonstatic int
2426101099Srwatsonmac_biba_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
2427101099Srwatson    struct label *dlabel, struct vnode *vp, struct label *label, int samedir,
2428101099Srwatson    struct componentname *cnp)
2429101099Srwatson{
2430101099Srwatson	struct mac_biba *subj, *obj;
2431101099Srwatson
2432101099Srwatson	if (!mac_biba_enabled)
2433101099Srwatson		return (0);
2434101099Srwatson
2435101099Srwatson	subj = SLOT(&cred->cr_label);
2436101099Srwatson	obj = SLOT(dlabel);
2437101099Srwatson
2438101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2439101099Srwatson		return (EACCES);
2440101099Srwatson
2441101099Srwatson	if (vp != NULL) {
2442101099Srwatson		obj = SLOT(label);
2443101099Srwatson
2444101099Srwatson		if (!mac_biba_dominate_single(subj, obj))
2445101099Srwatson			return (EACCES);
2446101099Srwatson	}
2447101099Srwatson
2448101099Srwatson	return (0);
2449101099Srwatson}
2450101099Srwatson
2451101099Srwatsonstatic int
2452101099Srwatsonmac_biba_check_vnode_revoke(struct ucred *cred, struct vnode *vp,
2453101099Srwatson    struct label *label)
2454101099Srwatson{
2455101099Srwatson	struct mac_biba *subj, *obj;
2456101099Srwatson
2457101099Srwatson	if (!mac_biba_enabled)
2458101099Srwatson		return (0);
2459101099Srwatson
2460101099Srwatson	subj = SLOT(&cred->cr_label);
2461101099Srwatson	obj = SLOT(label);
2462101099Srwatson
2463101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2464101099Srwatson		return (EACCES);
2465101099Srwatson
2466101099Srwatson	return (0);
2467101099Srwatson}
2468101099Srwatson
2469101099Srwatsonstatic int
2470101099Srwatsonmac_biba_check_vnode_setacl(struct ucred *cred, struct vnode *vp,
2471101099Srwatson    struct label *label, acl_type_t type, struct acl *acl)
2472101099Srwatson{
2473101099Srwatson	struct mac_biba *subj, *obj;
2474101099Srwatson
2475101099Srwatson	if (!mac_biba_enabled)
2476101099Srwatson		return (0);
2477101099Srwatson
2478101099Srwatson	subj = SLOT(&cred->cr_label);
2479101099Srwatson	obj = SLOT(label);
2480101099Srwatson
2481101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2482101099Srwatson		return (EACCES);
2483101099Srwatson
2484101099Srwatson	return (0);
2485101099Srwatson}
2486101099Srwatson
2487101099Srwatsonstatic int
2488101099Srwatsonmac_biba_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
2489101099Srwatson    struct label *vnodelabel, int attrnamespace, const char *name,
2490101099Srwatson    struct uio *uio)
2491101099Srwatson{
2492101099Srwatson	struct mac_biba *subj, *obj;
2493101099Srwatson
2494101099Srwatson	if (!mac_biba_enabled)
2495101099Srwatson		return (0);
2496101099Srwatson
2497101099Srwatson	subj = SLOT(&cred->cr_label);
2498101099Srwatson	obj = SLOT(vnodelabel);
2499101099Srwatson
2500101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2501101099Srwatson		return (EACCES);
2502101099Srwatson
2503101099Srwatson	/* XXX: protect the MAC EA in a special way? */
2504101099Srwatson
2505101099Srwatson	return (0);
2506101099Srwatson}
2507101099Srwatson
2508101099Srwatsonstatic int
2509101099Srwatsonmac_biba_check_vnode_setflags(struct ucred *cred, struct vnode *vp,
2510101099Srwatson    struct label *vnodelabel, u_long flags)
2511101099Srwatson{
2512101099Srwatson	struct mac_biba *subj, *obj;
2513101099Srwatson
2514101099Srwatson	if (!mac_biba_enabled)
2515101099Srwatson		return (0);
2516101099Srwatson
2517101099Srwatson	subj = SLOT(&cred->cr_label);
2518101099Srwatson	obj = SLOT(vnodelabel);
2519101099Srwatson
2520101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2521101099Srwatson		return (EACCES);
2522101099Srwatson
2523101099Srwatson	return (0);
2524101099Srwatson}
2525101099Srwatson
2526101099Srwatsonstatic int
2527101099Srwatsonmac_biba_check_vnode_setmode(struct ucred *cred, struct vnode *vp,
2528101099Srwatson    struct label *vnodelabel, mode_t mode)
2529101099Srwatson{
2530101099Srwatson	struct mac_biba *subj, *obj;
2531101099Srwatson
2532101099Srwatson	if (!mac_biba_enabled)
2533101099Srwatson		return (0);
2534101099Srwatson
2535101099Srwatson	subj = SLOT(&cred->cr_label);
2536101099Srwatson	obj = SLOT(vnodelabel);
2537101099Srwatson
2538101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2539101099Srwatson		return (EACCES);
2540101099Srwatson
2541101099Srwatson	return (0);
2542101099Srwatson}
2543101099Srwatson
2544101099Srwatsonstatic int
2545101099Srwatsonmac_biba_check_vnode_setowner(struct ucred *cred, struct vnode *vp,
2546101099Srwatson    struct label *vnodelabel, uid_t uid, gid_t gid)
2547101099Srwatson{
2548101099Srwatson	struct mac_biba *subj, *obj;
2549101099Srwatson
2550101099Srwatson	if (!mac_biba_enabled)
2551101099Srwatson		return (0);
2552101099Srwatson
2553101099Srwatson	subj = SLOT(&cred->cr_label);
2554101099Srwatson	obj = SLOT(vnodelabel);
2555101099Srwatson
2556101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2557101099Srwatson		return (EACCES);
2558101099Srwatson
2559101099Srwatson	return (0);
2560101099Srwatson}
2561101099Srwatson
2562101099Srwatsonstatic int
2563101099Srwatsonmac_biba_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
2564101099Srwatson    struct label *vnodelabel, struct timespec atime, struct timespec mtime)
2565101099Srwatson{
2566101099Srwatson	struct mac_biba *subj, *obj;
2567101099Srwatson
2568101099Srwatson	if (!mac_biba_enabled)
2569101099Srwatson		return (0);
2570101099Srwatson
2571101099Srwatson	subj = SLOT(&cred->cr_label);
2572101099Srwatson	obj = SLOT(vnodelabel);
2573101099Srwatson
2574101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2575101099Srwatson		return (EACCES);
2576101099Srwatson
2577101099Srwatson	return (0);
2578101099Srwatson}
2579101099Srwatson
2580101099Srwatsonstatic int
2581102129Srwatsonmac_biba_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
2582102129Srwatson    struct vnode *vp, struct label *vnodelabel)
2583101099Srwatson{
2584101099Srwatson	struct mac_biba *subj, *obj;
2585101099Srwatson
2586101099Srwatson	if (!mac_biba_enabled)
2587101099Srwatson		return (0);
2588101099Srwatson
2589102129Srwatson	subj = SLOT(&active_cred->cr_label);
2590101099Srwatson	obj = SLOT(vnodelabel);
2591101099Srwatson
2592101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
2593101099Srwatson		return (EACCES);
2594101099Srwatson
2595101099Srwatson	return (0);
2596101099Srwatson}
2597101099Srwatson
2598102112Srwatsonstatic int
2599102129Srwatsonmac_biba_check_vnode_write(struct ucred *active_cred,
2600102129Srwatson    struct ucred *file_cred, struct vnode *vp, struct label *label)
2601102112Srwatson{
2602102112Srwatson	struct mac_biba *subj, *obj;
2603102112Srwatson
2604105637Srwatson	if (!mac_biba_enabled || !revocation_enabled)
2605102112Srwatson		return (0);
2606102112Srwatson
2607102129Srwatson	subj = SLOT(&active_cred->cr_label);
2608102112Srwatson	obj = SLOT(label);
2609102112Srwatson
2610102112Srwatson	if (!mac_biba_dominate_single(subj, obj))
2611102112Srwatson		return (EACCES);
2612102112Srwatson
2613102112Srwatson	return (0);
2614102112Srwatson}
2615102112Srwatson
2616106217Srwatsonstatic struct mac_policy_ops mac_biba_ops =
2617101099Srwatson{
2618106217Srwatson	.mpo_destroy = mac_biba_destroy,
2619106217Srwatson	.mpo_init = mac_biba_init,
2620106217Srwatson	.mpo_init_bpfdesc_label = mac_biba_init_label,
2621106217Srwatson	.mpo_init_cred_label = mac_biba_init_label,
2622106217Srwatson	.mpo_init_devfsdirent_label = mac_biba_init_label,
2623106217Srwatson	.mpo_init_ifnet_label = mac_biba_init_label,
2624106217Srwatson	.mpo_init_ipq_label = mac_biba_init_label,
2625106217Srwatson	.mpo_init_mbuf_label = mac_biba_init_label_waitcheck,
2626106217Srwatson	.mpo_init_mount_label = mac_biba_init_label,
2627106217Srwatson	.mpo_init_mount_fs_label = mac_biba_init_label,
2628106217Srwatson	.mpo_init_pipe_label = mac_biba_init_label,
2629106217Srwatson	.mpo_init_socket_label = mac_biba_init_label_waitcheck,
2630106217Srwatson	.mpo_init_socket_peer_label = mac_biba_init_label_waitcheck,
2631106217Srwatson	.mpo_init_vnode_label = mac_biba_init_label,
2632106217Srwatson	.mpo_destroy_bpfdesc_label = mac_biba_destroy_label,
2633106217Srwatson	.mpo_destroy_cred_label = mac_biba_destroy_label,
2634106217Srwatson	.mpo_destroy_devfsdirent_label = mac_biba_destroy_label,
2635106217Srwatson	.mpo_destroy_ifnet_label = mac_biba_destroy_label,
2636106217Srwatson	.mpo_destroy_ipq_label = mac_biba_destroy_label,
2637106217Srwatson	.mpo_destroy_mbuf_label = mac_biba_destroy_label,
2638106217Srwatson	.mpo_destroy_mount_label = mac_biba_destroy_label,
2639106217Srwatson	.mpo_destroy_mount_fs_label = mac_biba_destroy_label,
2640106217Srwatson	.mpo_destroy_pipe_label = mac_biba_destroy_label,
2641106217Srwatson	.mpo_destroy_socket_label = mac_biba_destroy_label,
2642106217Srwatson	.mpo_destroy_socket_peer_label = mac_biba_destroy_label,
2643106217Srwatson	.mpo_destroy_vnode_label = mac_biba_destroy_label,
2644106217Srwatson	.mpo_copy_pipe_label = mac_biba_copy_label,
2645106217Srwatson	.mpo_copy_vnode_label = mac_biba_copy_label,
2646106217Srwatson	.mpo_externalize_cred_label = mac_biba_externalize_label,
2647106217Srwatson	.mpo_externalize_ifnet_label = mac_biba_externalize_label,
2648106217Srwatson	.mpo_externalize_pipe_label = mac_biba_externalize_label,
2649106217Srwatson	.mpo_externalize_socket_label = mac_biba_externalize_label,
2650106217Srwatson	.mpo_externalize_socket_peer_label = mac_biba_externalize_label,
2651106217Srwatson	.mpo_externalize_vnode_label = mac_biba_externalize_label,
2652106217Srwatson	.mpo_internalize_cred_label = mac_biba_internalize_label,
2653106217Srwatson	.mpo_internalize_ifnet_label = mac_biba_internalize_label,
2654106217Srwatson	.mpo_internalize_pipe_label = mac_biba_internalize_label,
2655106217Srwatson	.mpo_internalize_socket_label = mac_biba_internalize_label,
2656106217Srwatson	.mpo_internalize_vnode_label = mac_biba_internalize_label,
2657106217Srwatson	.mpo_create_devfs_device = mac_biba_create_devfs_device,
2658106217Srwatson	.mpo_create_devfs_directory = mac_biba_create_devfs_directory,
2659106217Srwatson	.mpo_create_devfs_symlink = mac_biba_create_devfs_symlink,
2660106217Srwatson	.mpo_create_mount = mac_biba_create_mount,
2661106217Srwatson	.mpo_create_root_mount = mac_biba_create_root_mount,
2662106217Srwatson	.mpo_relabel_vnode = mac_biba_relabel_vnode,
2663106217Srwatson	.mpo_update_devfsdirent = mac_biba_update_devfsdirent,
2664106217Srwatson	.mpo_associate_vnode_devfs = mac_biba_associate_vnode_devfs,
2665106217Srwatson	.mpo_associate_vnode_extattr = mac_biba_associate_vnode_extattr,
2666106217Srwatson	.mpo_associate_vnode_singlelabel = mac_biba_associate_vnode_singlelabel,
2667106217Srwatson	.mpo_create_vnode_extattr = mac_biba_create_vnode_extattr,
2668106217Srwatson	.mpo_setlabel_vnode_extattr = mac_biba_setlabel_vnode_extattr,
2669106217Srwatson	.mpo_create_mbuf_from_socket = mac_biba_create_mbuf_from_socket,
2670106217Srwatson	.mpo_create_pipe = mac_biba_create_pipe,
2671106217Srwatson	.mpo_create_socket = mac_biba_create_socket,
2672106217Srwatson	.mpo_create_socket_from_socket = mac_biba_create_socket_from_socket,
2673106217Srwatson	.mpo_relabel_pipe = mac_biba_relabel_pipe,
2674106217Srwatson	.mpo_relabel_socket = mac_biba_relabel_socket,
2675106217Srwatson	.mpo_set_socket_peer_from_mbuf = mac_biba_set_socket_peer_from_mbuf,
2676106217Srwatson	.mpo_set_socket_peer_from_socket = mac_biba_set_socket_peer_from_socket,
2677106217Srwatson	.mpo_create_bpfdesc = mac_biba_create_bpfdesc,
2678106217Srwatson	.mpo_create_datagram_from_ipq = mac_biba_create_datagram_from_ipq,
2679106217Srwatson	.mpo_create_fragment = mac_biba_create_fragment,
2680106217Srwatson	.mpo_create_ifnet = mac_biba_create_ifnet,
2681106217Srwatson	.mpo_create_ipq = mac_biba_create_ipq,
2682106217Srwatson	.mpo_create_mbuf_from_mbuf = mac_biba_create_mbuf_from_mbuf,
2683106217Srwatson	.mpo_create_mbuf_linklayer = mac_biba_create_mbuf_linklayer,
2684106217Srwatson	.mpo_create_mbuf_from_bpfdesc = mac_biba_create_mbuf_from_bpfdesc,
2685106217Srwatson	.mpo_create_mbuf_from_ifnet = mac_biba_create_mbuf_from_ifnet,
2686106217Srwatson	.mpo_create_mbuf_multicast_encap = mac_biba_create_mbuf_multicast_encap,
2687106217Srwatson	.mpo_create_mbuf_netlayer = mac_biba_create_mbuf_netlayer,
2688106217Srwatson	.mpo_fragment_match = mac_biba_fragment_match,
2689106217Srwatson	.mpo_relabel_ifnet = mac_biba_relabel_ifnet,
2690106217Srwatson	.mpo_update_ipq = mac_biba_update_ipq,
2691106217Srwatson	.mpo_create_cred = mac_biba_create_cred,
2692106217Srwatson	.mpo_create_proc0 = mac_biba_create_proc0,
2693106217Srwatson	.mpo_create_proc1 = mac_biba_create_proc1,
2694106217Srwatson	.mpo_relabel_cred = mac_biba_relabel_cred,
2695106217Srwatson	.mpo_check_bpfdesc_receive = mac_biba_check_bpfdesc_receive,
2696106217Srwatson	.mpo_check_cred_relabel = mac_biba_check_cred_relabel,
2697106217Srwatson	.mpo_check_cred_visible = mac_biba_check_cred_visible,
2698106217Srwatson	.mpo_check_ifnet_relabel = mac_biba_check_ifnet_relabel,
2699106217Srwatson	.mpo_check_ifnet_transmit = mac_biba_check_ifnet_transmit,
2700110354Srwatson	.mpo_check_kld_load = mac_biba_check_kld_load,
2701110354Srwatson	.mpo_check_kld_unload = mac_biba_check_kld_unload,
2702106217Srwatson	.mpo_check_mount_stat = mac_biba_check_mount_stat,
2703106217Srwatson	.mpo_check_pipe_ioctl = mac_biba_check_pipe_ioctl,
2704106217Srwatson	.mpo_check_pipe_poll = mac_biba_check_pipe_poll,
2705106217Srwatson	.mpo_check_pipe_read = mac_biba_check_pipe_read,
2706106217Srwatson	.mpo_check_pipe_relabel = mac_biba_check_pipe_relabel,
2707106217Srwatson	.mpo_check_pipe_stat = mac_biba_check_pipe_stat,
2708106217Srwatson	.mpo_check_pipe_write = mac_biba_check_pipe_write,
2709106217Srwatson	.mpo_check_proc_debug = mac_biba_check_proc_debug,
2710106217Srwatson	.mpo_check_proc_sched = mac_biba_check_proc_sched,
2711106217Srwatson	.mpo_check_proc_signal = mac_biba_check_proc_signal,
2712106217Srwatson	.mpo_check_socket_deliver = mac_biba_check_socket_deliver,
2713106217Srwatson	.mpo_check_socket_relabel = mac_biba_check_socket_relabel,
2714106217Srwatson	.mpo_check_socket_visible = mac_biba_check_socket_visible,
2715112574Srwatson	.mpo_check_sysarch_ioperm = mac_biba_check_sysarch_ioperm,
2716106418Srwatson	.mpo_check_system_acct = mac_biba_check_system_acct,
2717106418Srwatson	.mpo_check_system_settime = mac_biba_check_system_settime,
2718106217Srwatson	.mpo_check_system_swapon = mac_biba_check_system_swapon,
2719112574Srwatson	.mpo_check_system_swapoff = mac_biba_check_system_swapoff,
2720106217Srwatson	.mpo_check_system_sysctl = mac_biba_check_system_sysctl,
2721106217Srwatson	.mpo_check_vnode_access = mac_biba_check_vnode_open,
2722106217Srwatson	.mpo_check_vnode_chdir = mac_biba_check_vnode_chdir,
2723106217Srwatson	.mpo_check_vnode_chroot = mac_biba_check_vnode_chroot,
2724106217Srwatson	.mpo_check_vnode_create = mac_biba_check_vnode_create,
2725106217Srwatson	.mpo_check_vnode_delete = mac_biba_check_vnode_delete,
2726106217Srwatson	.mpo_check_vnode_deleteacl = mac_biba_check_vnode_deleteacl,
2727106217Srwatson	.mpo_check_vnode_exec = mac_biba_check_vnode_exec,
2728106217Srwatson	.mpo_check_vnode_getacl = mac_biba_check_vnode_getacl,
2729106217Srwatson	.mpo_check_vnode_getextattr = mac_biba_check_vnode_getextattr,
2730106217Srwatson	.mpo_check_vnode_link = mac_biba_check_vnode_link,
2731106217Srwatson	.mpo_check_vnode_lookup = mac_biba_check_vnode_lookup,
2732106217Srwatson	.mpo_check_vnode_mmap = mac_biba_check_vnode_mmap,
2733106217Srwatson	.mpo_check_vnode_mprotect = mac_biba_check_vnode_mmap,
2734106217Srwatson	.mpo_check_vnode_open = mac_biba_check_vnode_open,
2735106217Srwatson	.mpo_check_vnode_poll = mac_biba_check_vnode_poll,
2736106217Srwatson	.mpo_check_vnode_read = mac_biba_check_vnode_read,
2737106217Srwatson	.mpo_check_vnode_readdir = mac_biba_check_vnode_readdir,
2738106217Srwatson	.mpo_check_vnode_readlink = mac_biba_check_vnode_readlink,
2739106217Srwatson	.mpo_check_vnode_relabel = mac_biba_check_vnode_relabel,
2740106217Srwatson	.mpo_check_vnode_rename_from = mac_biba_check_vnode_rename_from,
2741106217Srwatson	.mpo_check_vnode_rename_to = mac_biba_check_vnode_rename_to,
2742106217Srwatson	.mpo_check_vnode_revoke = mac_biba_check_vnode_revoke,
2743106217Srwatson	.mpo_check_vnode_setacl = mac_biba_check_vnode_setacl,
2744106217Srwatson	.mpo_check_vnode_setextattr = mac_biba_check_vnode_setextattr,
2745106217Srwatson	.mpo_check_vnode_setflags = mac_biba_check_vnode_setflags,
2746106217Srwatson	.mpo_check_vnode_setmode = mac_biba_check_vnode_setmode,
2747106217Srwatson	.mpo_check_vnode_setowner = mac_biba_check_vnode_setowner,
2748106217Srwatson	.mpo_check_vnode_setutimes = mac_biba_check_vnode_setutimes,
2749106217Srwatson	.mpo_check_vnode_stat = mac_biba_check_vnode_stat,
2750106217Srwatson	.mpo_check_vnode_write = mac_biba_check_vnode_write,
2751101099Srwatson};
2752101099Srwatson
2753106217SrwatsonMAC_POLICY_SET(&mac_biba_ops, trustedbsd_mac_biba, "TrustedBSD MAC/Biba",
2754101099Srwatson    MPC_LOADTIME_FLAG_NOTLATE, &mac_biba_slot);
2755