mac_biba.c revision 105736
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 *
8101099Srwatson * This software was developed for the FreeBSD Project in part by NAI Labs,
9101099Srwatson * the Security Research Division of Network Associates, Inc. under
10101099Srwatson * DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA
11101099Srwatson * 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 * 3. The names of the authors may not be used to endorse or promote
22101099Srwatson *    products derived from this software without specific prior written
23101099Srwatson *    permission.
24101099Srwatson *
25101099Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
26101099Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27101099Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28101099Srwatson * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
29101099Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30101099Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31101099Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32101099Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33101099Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34101099Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35101099Srwatson * SUCH DAMAGE.
36101099Srwatson *
37101099Srwatson * $FreeBSD: head/sys/security/mac_biba/mac_biba.c 105736 2002-10-22 19:01:49Z rwatson $
38101099Srwatson */
39101099Srwatson
40101099Srwatson/*
41101099Srwatson * Developed by the TrustedBSD Project.
42101099Srwatson * Biba fixed label mandatory integrity policy.
43101099Srwatson */
44101099Srwatson
45101099Srwatson#include <sys/types.h>
46101099Srwatson#include <sys/param.h>
47101099Srwatson#include <sys/acl.h>
48101099Srwatson#include <sys/conf.h>
49101099Srwatson#include <sys/kernel.h>
50101099Srwatson#include <sys/mac.h>
51103183Sbde#include <sys/malloc.h>
52101099Srwatson#include <sys/mount.h>
53101099Srwatson#include <sys/proc.h>
54101099Srwatson#include <sys/systm.h>
55101099Srwatson#include <sys/sysproto.h>
56101099Srwatson#include <sys/sysent.h>
57105696Srwatson#include <sys/systm.h>
58101099Srwatson#include <sys/vnode.h>
59101099Srwatson#include <sys/file.h>
60101099Srwatson#include <sys/socket.h>
61101099Srwatson#include <sys/socketvar.h>
62101099Srwatson#include <sys/pipe.h>
63101099Srwatson#include <sys/sysctl.h>
64101099Srwatson
65101099Srwatson#include <fs/devfs/devfs.h>
66101099Srwatson
67101099Srwatson#include <net/bpfdesc.h>
68101099Srwatson#include <net/if.h>
69101099Srwatson#include <net/if_types.h>
70101099Srwatson#include <net/if_var.h>
71101099Srwatson
72101099Srwatson#include <netinet/in.h>
73101099Srwatson#include <netinet/ip_var.h>
74101099Srwatson
75101099Srwatson#include <vm/vm.h>
76101099Srwatson
77101099Srwatson#include <sys/mac_policy.h>
78101099Srwatson
79101099Srwatson#include <security/mac_biba/mac_biba.h>
80101099Srwatson
81101099SrwatsonSYSCTL_DECL(_security_mac);
82101099Srwatson
83101099SrwatsonSYSCTL_NODE(_security_mac, OID_AUTO, biba, CTLFLAG_RW, 0,
84101099Srwatson    "TrustedBSD mac_biba policy controls");
85101099Srwatson
86101099Srwatsonstatic int	mac_biba_enabled = 0;
87101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, enabled, CTLFLAG_RW,
88101099Srwatson    &mac_biba_enabled, 0, "Enforce MAC/Biba policy");
89102980SrwatsonTUNABLE_INT("security.mac.biba.enabled", &mac_biba_enabled);
90101099Srwatson
91101099Srwatsonstatic int	destroyed_not_inited;
92101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, destroyed_not_inited, CTLFLAG_RD,
93101099Srwatson    &destroyed_not_inited, 0, "Count of labels destroyed but not inited");
94101099Srwatson
95101099Srwatsonstatic int	trust_all_interfaces = 0;
96101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, trust_all_interfaces, CTLFLAG_RD,
97101099Srwatson    &trust_all_interfaces, 0, "Consider all interfaces 'trusted' by MAC/Biba");
98101099SrwatsonTUNABLE_INT("security.mac.biba.trust_all_interfaces", &trust_all_interfaces);
99101099Srwatson
100101099Srwatsonstatic char	trusted_interfaces[128];
101101099SrwatsonSYSCTL_STRING(_security_mac_biba, OID_AUTO, trusted_interfaces, CTLFLAG_RD,
102101099Srwatson    trusted_interfaces, 0, "Interfaces considered 'trusted' by MAC/Biba");
103101099SrwatsonTUNABLE_STR("security.mac.biba.trusted_interfaces", trusted_interfaces,
104101099Srwatson    sizeof(trusted_interfaces));
105101099Srwatson
106105643Srwatsonstatic int	max_compartments = MAC_BIBA_MAX_COMPARTMENTS;
107105643SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, max_compartments, CTLFLAG_RD,
108105643Srwatson    &max_compartments, 0, "Maximum supported compartments");
109105643Srwatson
110105606Srwatsonstatic int	ptys_equal = 0;
111105606SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, ptys_equal, CTLFLAG_RW,
112105606Srwatson    &ptys_equal, 0, "Label pty devices as biba/equal on create");
113105606SrwatsonTUNABLE_INT("security.mac.biba.ptys_equal", &ptys_equal);
114105606Srwatson
115105637Srwatsonstatic int	revocation_enabled = 0;
116101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, revocation_enabled, CTLFLAG_RW,
117105637Srwatson    &revocation_enabled, 0, "Revoke access to objects on relabel");
118105637SrwatsonTUNABLE_INT("security.mac.biba.revocation_enabled", &revocation_enabled);
119101099Srwatson
120101099Srwatsonstatic int	mac_biba_slot;
121101099Srwatson#define	SLOT(l)	((struct mac_biba *)LABEL_TO_SLOT((l), mac_biba_slot).l_ptr)
122101099Srwatson
123101099SrwatsonMALLOC_DEFINE(M_MACBIBA, "biba label", "MAC/Biba labels");
124101099Srwatson
125105643Srwatsonstatic __inline int
126105643Srwatsonbiba_bit_set_empty(u_char *set) {
127105643Srwatson	int i;
128105643Srwatson
129105643Srwatson	for (i = 0; i < MAC_BIBA_MAX_COMPARTMENTS >> 3; i++)
130105643Srwatson		if (set[i] != 0)
131105643Srwatson			return (0);
132105643Srwatson	return (1);
133105643Srwatson}
134105643Srwatson
135101099Srwatsonstatic struct mac_biba *
136104514Srwatsonbiba_alloc(int flag)
137101099Srwatson{
138101099Srwatson	struct mac_biba *mac_biba;
139101099Srwatson
140104514Srwatson	mac_biba = malloc(sizeof(struct mac_biba), M_MACBIBA, M_ZERO | flag);
141101099Srwatson
142101099Srwatson	return (mac_biba);
143101099Srwatson}
144101099Srwatson
145101099Srwatsonstatic void
146101099Srwatsonbiba_free(struct mac_biba *mac_biba)
147101099Srwatson{
148101099Srwatson
149101099Srwatson	if (mac_biba != NULL)
150101099Srwatson		free(mac_biba, M_MACBIBA);
151101099Srwatson	else
152101099Srwatson		atomic_add_int(&destroyed_not_inited, 1);
153101099Srwatson}
154101099Srwatson
155101099Srwatsonstatic int
156105634Srwatsonbiba_atmostflags(struct mac_biba *mac_biba, int flags)
157105634Srwatson{
158105634Srwatson
159105634Srwatson	if ((mac_biba->mb_flags & flags) != mac_biba->mb_flags)
160105634Srwatson		return (EINVAL);
161105634Srwatson	return (0);
162105634Srwatson}
163105634Srwatson
164105634Srwatsonstatic int
165101099Srwatsonmac_biba_dominate_element(struct mac_biba_element *a,
166101099Srwatson    struct mac_biba_element *b)
167101099Srwatson{
168105643Srwatson	int bit;
169101099Srwatson
170105736Srwatson	switch (a->mbe_type) {
171101099Srwatson	case MAC_BIBA_TYPE_EQUAL:
172101099Srwatson	case MAC_BIBA_TYPE_HIGH:
173101099Srwatson		return (1);
174101099Srwatson
175101099Srwatson	case MAC_BIBA_TYPE_LOW:
176101099Srwatson		switch (b->mbe_type) {
177101099Srwatson		case MAC_BIBA_TYPE_GRADE:
178101099Srwatson		case MAC_BIBA_TYPE_HIGH:
179101099Srwatson			return (0);
180101099Srwatson
181101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
182101099Srwatson		case MAC_BIBA_TYPE_LOW:
183101099Srwatson			return (1);
184101099Srwatson
185101099Srwatson		default:
186101099Srwatson			panic("mac_biba_dominate_element: b->mbe_type invalid");
187101099Srwatson		}
188101099Srwatson
189101099Srwatson	case MAC_BIBA_TYPE_GRADE:
190101099Srwatson		switch (b->mbe_type) {
191101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
192101099Srwatson		case MAC_BIBA_TYPE_LOW:
193101099Srwatson			return (1);
194101099Srwatson
195101099Srwatson		case MAC_BIBA_TYPE_HIGH:
196101099Srwatson			return (0);
197101099Srwatson
198101099Srwatson		case MAC_BIBA_TYPE_GRADE:
199105643Srwatson			for (bit = 1; bit <= MAC_BIBA_MAX_COMPARTMENTS; bit++)
200105643Srwatson				if (!MAC_BIBA_BIT_TEST(bit,
201105643Srwatson				    a->mbe_compartments) &&
202105643Srwatson				    MAC_BIBA_BIT_TEST(bit, b->mbe_compartments))
203105643Srwatson					return (0);
204101099Srwatson			return (a->mbe_grade >= b->mbe_grade);
205101099Srwatson
206101099Srwatson		default:
207101099Srwatson			panic("mac_biba_dominate_element: b->mbe_type invalid");
208101099Srwatson		}
209101099Srwatson
210101099Srwatson	default:
211101099Srwatson		panic("mac_biba_dominate_element: a->mbe_type invalid");
212101099Srwatson	}
213101099Srwatson
214101099Srwatson	return (0);
215101099Srwatson}
216101099Srwatson
217101099Srwatsonstatic int
218101099Srwatsonmac_biba_range_in_range(struct mac_biba *rangea, struct mac_biba *rangeb)
219101099Srwatson{
220101099Srwatson
221101099Srwatson	return (mac_biba_dominate_element(&rangeb->mb_rangehigh,
222101099Srwatson	    &rangea->mb_rangehigh) &&
223101099Srwatson	    mac_biba_dominate_element(&rangea->mb_rangelow,
224101099Srwatson	    &rangeb->mb_rangelow));
225101099Srwatson}
226101099Srwatson
227101099Srwatsonstatic int
228101099Srwatsonmac_biba_single_in_range(struct mac_biba *single, struct mac_biba *range)
229101099Srwatson{
230101099Srwatson
231103750Srwatson	KASSERT((single->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
232101099Srwatson	    ("mac_biba_single_in_range: a not single"));
233103750Srwatson	KASSERT((range->mb_flags & MAC_BIBA_FLAG_RANGE) != 0,
234101099Srwatson	    ("mac_biba_single_in_range: b not range"));
235101099Srwatson
236101099Srwatson	return (mac_biba_dominate_element(&range->mb_rangehigh,
237101099Srwatson	    &single->mb_single) &&
238101099Srwatson	    mac_biba_dominate_element(&single->mb_single,
239101099Srwatson	    &range->mb_rangelow));
240101099Srwatson
241101099Srwatson	return (1);
242101099Srwatson}
243101099Srwatson
244101099Srwatsonstatic int
245101099Srwatsonmac_biba_dominate_single(struct mac_biba *a, struct mac_biba *b)
246101099Srwatson{
247101099Srwatson	KASSERT((a->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
248101099Srwatson	    ("mac_biba_dominate_single: a not single"));
249101099Srwatson	KASSERT((b->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
250101099Srwatson	    ("mac_biba_dominate_single: b not single"));
251101099Srwatson
252101099Srwatson	return (mac_biba_dominate_element(&a->mb_single, &b->mb_single));
253101099Srwatson}
254101099Srwatson
255101099Srwatsonstatic int
256101099Srwatsonmac_biba_equal_element(struct mac_biba_element *a, struct mac_biba_element *b)
257101099Srwatson{
258101099Srwatson
259101099Srwatson	if (a->mbe_type == MAC_BIBA_TYPE_EQUAL ||
260101099Srwatson	    b->mbe_type == MAC_BIBA_TYPE_EQUAL)
261101099Srwatson		return (1);
262101099Srwatson
263101099Srwatson	return (a->mbe_type == b->mbe_type && a->mbe_grade == b->mbe_grade);
264101099Srwatson}
265101099Srwatson
266101099Srwatsonstatic int
267101099Srwatsonmac_biba_equal_single(struct mac_biba *a, struct mac_biba *b)
268101099Srwatson{
269101099Srwatson
270101099Srwatson	KASSERT((a->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
271101099Srwatson	    ("mac_biba_equal_single: a not single"));
272101099Srwatson	KASSERT((b->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
273101099Srwatson	    ("mac_biba_equal_single: b not single"));
274101099Srwatson
275101099Srwatson	return (mac_biba_equal_element(&a->mb_single, &b->mb_single));
276101099Srwatson}
277101099Srwatson
278101099Srwatsonstatic int
279105634Srwatsonmac_biba_contains_equal(struct mac_biba *mac_biba)
280105634Srwatson{
281105634Srwatson
282105634Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE)
283105634Srwatson		if (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_EQUAL)
284105634Srwatson			return (1);
285105634Srwatson
286105634Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
287105634Srwatson		if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL)
288105634Srwatson			return (1);
289105634Srwatson		if (mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL)
290105637Srwatson			return (1);
291105634Srwatson	}
292105634Srwatson
293105634Srwatson	return (0);
294105634Srwatson}
295105634Srwatson
296105634Srwatsonstatic int
297105634Srwatsonmac_biba_subject_equal_ok(struct mac_biba *mac_biba)
298105634Srwatson{
299105634Srwatson
300105634Srwatson	KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAGS_BOTH) ==
301105634Srwatson	    MAC_BIBA_FLAGS_BOTH,
302105634Srwatson	    ("mac_biba_subject_equal_ok: subject doesn't have both labels"));
303105634Srwatson
304105634Srwatson	/* If the single is EQUAL, it's ok. */
305105634Srwatson	if (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_EQUAL)
306105634Srwatson		return (0);
307105634Srwatson
308105634Srwatson	/* If either range endpoint is EQUAL, it's ok. */
309105634Srwatson	if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL ||
310105634Srwatson	    mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL)
311105634Srwatson		return (0);
312105634Srwatson
313105634Srwatson	/* If the range is low-high, it's ok. */
314105634Srwatson	if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_LOW &&
315105634Srwatson	    mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_HIGH)
316105634Srwatson		return (0);
317105634Srwatson
318105634Srwatson	/* It's not ok. */
319105634Srwatson	return (EPERM);
320105634Srwatson}
321105634Srwatson
322105634Srwatsonstatic int
323101099Srwatsonmac_biba_valid(struct mac_biba *mac_biba)
324101099Srwatson{
325101099Srwatson
326101099Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) {
327101099Srwatson		switch (mac_biba->mb_single.mbe_type) {
328101099Srwatson		case MAC_BIBA_TYPE_GRADE:
329101099Srwatson			break;
330101099Srwatson
331101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
332101099Srwatson		case MAC_BIBA_TYPE_HIGH:
333101099Srwatson		case MAC_BIBA_TYPE_LOW:
334105643Srwatson			if (mac_biba->mb_single.mbe_grade != 0 ||
335105643Srwatson			    !MAC_BIBA_BIT_SET_EMPTY(
336105643Srwatson			    mac_biba->mb_single.mbe_compartments))
337101099Srwatson				return (EINVAL);
338101099Srwatson			break;
339101099Srwatson
340101099Srwatson		default:
341101099Srwatson			return (EINVAL);
342101099Srwatson		}
343101099Srwatson	} else {
344101099Srwatson		if (mac_biba->mb_single.mbe_type != MAC_BIBA_TYPE_UNDEF)
345101099Srwatson			return (EINVAL);
346101099Srwatson	}
347101099Srwatson
348101099Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
349101099Srwatson		switch (mac_biba->mb_rangelow.mbe_type) {
350101099Srwatson		case MAC_BIBA_TYPE_GRADE:
351101099Srwatson			break;
352101099Srwatson
353101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
354101099Srwatson		case MAC_BIBA_TYPE_HIGH:
355101099Srwatson		case MAC_BIBA_TYPE_LOW:
356105643Srwatson			if (mac_biba->mb_rangelow.mbe_grade != 0 ||
357105643Srwatson			    !MAC_BIBA_BIT_SET_EMPTY(
358105643Srwatson			    mac_biba->mb_rangelow.mbe_compartments))
359101099Srwatson				return (EINVAL);
360101099Srwatson			break;
361101099Srwatson
362101099Srwatson		default:
363101099Srwatson			return (EINVAL);
364101099Srwatson		}
365101099Srwatson
366101099Srwatson		switch (mac_biba->mb_rangehigh.mbe_type) {
367101099Srwatson		case MAC_BIBA_TYPE_GRADE:
368101099Srwatson			break;
369101099Srwatson
370101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
371101099Srwatson		case MAC_BIBA_TYPE_HIGH:
372101099Srwatson		case MAC_BIBA_TYPE_LOW:
373105643Srwatson			if (mac_biba->mb_rangehigh.mbe_grade != 0 ||
374105643Srwatson			    !MAC_BIBA_BIT_SET_EMPTY(
375105643Srwatson			    mac_biba->mb_rangehigh.mbe_compartments))
376101099Srwatson				return (EINVAL);
377101099Srwatson			break;
378101099Srwatson
379101099Srwatson		default:
380101099Srwatson			return (EINVAL);
381101099Srwatson		}
382101099Srwatson		if (!mac_biba_dominate_element(&mac_biba->mb_rangehigh,
383101099Srwatson		    &mac_biba->mb_rangelow))
384101099Srwatson			return (EINVAL);
385101099Srwatson	} else {
386101099Srwatson		if (mac_biba->mb_rangelow.mbe_type != MAC_BIBA_TYPE_UNDEF ||
387101099Srwatson		    mac_biba->mb_rangehigh.mbe_type != MAC_BIBA_TYPE_UNDEF)
388101099Srwatson			return (EINVAL);
389101099Srwatson	}
390101099Srwatson
391101099Srwatson	return (0);
392101099Srwatson}
393101099Srwatson
394101099Srwatsonstatic void
395101099Srwatsonmac_biba_set_range(struct mac_biba *mac_biba, u_short typelow,
396105643Srwatson    u_short gradelow, u_char *compartmentslow, u_short typehigh,
397105643Srwatson    u_short gradehigh, u_char *compartmentshigh)
398101099Srwatson{
399101099Srwatson
400101099Srwatson	mac_biba->mb_rangelow.mbe_type = typelow;
401101099Srwatson	mac_biba->mb_rangelow.mbe_grade = gradelow;
402105643Srwatson	if (compartmentslow != NULL)
403105643Srwatson		memcpy(mac_biba->mb_rangelow.mbe_compartments,
404105643Srwatson		    compartmentslow,
405105643Srwatson		    sizeof(mac_biba->mb_rangelow.mbe_compartments));
406101099Srwatson	mac_biba->mb_rangehigh.mbe_type = typehigh;
407101099Srwatson	mac_biba->mb_rangehigh.mbe_grade = gradehigh;
408105643Srwatson	if (compartmentshigh != NULL)
409105643Srwatson		memcpy(mac_biba->mb_rangehigh.mbe_compartments,
410105643Srwatson		    compartmentshigh,
411105643Srwatson		    sizeof(mac_biba->mb_rangehigh.mbe_compartments));
412101099Srwatson	mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE;
413101099Srwatson}
414101099Srwatson
415101099Srwatsonstatic void
416105643Srwatsonmac_biba_set_single(struct mac_biba *mac_biba, u_short type, u_short grade,
417105643Srwatson    u_char *compartments)
418101099Srwatson{
419101099Srwatson
420101099Srwatson	mac_biba->mb_single.mbe_type = type;
421101099Srwatson	mac_biba->mb_single.mbe_grade = grade;
422105643Srwatson	if (compartments != NULL)
423105643Srwatson		memcpy(mac_biba->mb_single.mbe_compartments, compartments,
424105643Srwatson		    sizeof(mac_biba->mb_single.mbe_compartments));
425101099Srwatson	mac_biba->mb_flags |= MAC_BIBA_FLAG_SINGLE;
426101099Srwatson}
427101099Srwatson
428101099Srwatsonstatic void
429101099Srwatsonmac_biba_copy_range(struct mac_biba *labelfrom, struct mac_biba *labelto)
430101099Srwatson{
431105643Srwatson
432101099Srwatson	KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_RANGE) != 0,
433101099Srwatson	    ("mac_biba_copy_range: labelfrom not range"));
434101099Srwatson
435101099Srwatson	labelto->mb_rangelow = labelfrom->mb_rangelow;
436101099Srwatson	labelto->mb_rangehigh = labelfrom->mb_rangehigh;
437101099Srwatson	labelto->mb_flags |= MAC_BIBA_FLAG_RANGE;
438101099Srwatson}
439101099Srwatson
440101099Srwatsonstatic void
441101099Srwatsonmac_biba_copy_single(struct mac_biba *labelfrom, struct mac_biba *labelto)
442101099Srwatson{
443101099Srwatson
444101099Srwatson	KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
445101099Srwatson	    ("mac_biba_copy_single: labelfrom not single"));
446101099Srwatson
447101099Srwatson	labelto->mb_single = labelfrom->mb_single;
448101099Srwatson	labelto->mb_flags |= MAC_BIBA_FLAG_SINGLE;
449101099Srwatson}
450101099Srwatson
451105656Srwatsonstatic void
452105656Srwatsonmac_biba_copy(struct mac_biba *source, struct mac_biba *dest)
453105656Srwatson{
454105656Srwatson
455105656Srwatson	if (source->mb_flags & MAC_BIBA_FLAG_SINGLE)
456105656Srwatson		mac_biba_copy_single(source, dest);
457105656Srwatson	if (source->mb_flags & MAC_BIBA_FLAG_RANGE)
458105656Srwatson		mac_biba_copy_range(source, dest);
459105656Srwatson}
460105656Srwatson
461101099Srwatson/*
462101099Srwatson * Policy module operations.
463101099Srwatson */
464101099Srwatsonstatic void
465101099Srwatsonmac_biba_destroy(struct mac_policy_conf *conf)
466101099Srwatson{
467101099Srwatson
468101099Srwatson}
469101099Srwatson
470101099Srwatsonstatic void
471101099Srwatsonmac_biba_init(struct mac_policy_conf *conf)
472101099Srwatson{
473101099Srwatson
474101099Srwatson}
475101099Srwatson
476101099Srwatson/*
477101099Srwatson * Label operations.
478101099Srwatson */
479101099Srwatsonstatic void
480104514Srwatsonmac_biba_init_label(struct label *label)
481101099Srwatson{
482101099Srwatson
483101099Srwatson	SLOT(label) = biba_alloc(M_WAITOK);
484101099Srwatson}
485101099Srwatson
486101099Srwatsonstatic int
487104514Srwatsonmac_biba_init_label_waitcheck(struct label *label, int flag)
488101099Srwatson{
489101099Srwatson
490104514Srwatson	SLOT(label) = biba_alloc(flag);
491101099Srwatson	if (SLOT(label) == NULL)
492101099Srwatson		return (ENOMEM);
493101099Srwatson
494101099Srwatson	return (0);
495101099Srwatson}
496101099Srwatson
497101099Srwatsonstatic void
498104514Srwatsonmac_biba_destroy_label(struct label *label)
499101099Srwatson{
500101099Srwatson
501101099Srwatson	biba_free(SLOT(label));
502101099Srwatson	SLOT(label) = NULL;
503101099Srwatson}
504101099Srwatson
505105696Srwatson/*
506105696Srwatson * mac_biba_element_to_string() is basically an snprintf wrapper with
507105696Srwatson * the same properties as snprintf().  It returns the length it would
508105696Srwatson * have added to the string in the event the string is too short.
509105696Srwatson */
510105696Srwatsonstatic size_t
511105696Srwatsonmac_biba_element_to_string(char *string, size_t size,
512105696Srwatson    struct mac_biba_element *element)
513105696Srwatson{
514105696Srwatson	int pos, bit = 1;
515105696Srwatson
516105696Srwatson	switch (element->mbe_type) {
517105696Srwatson	case MAC_BIBA_TYPE_HIGH:
518105696Srwatson		return (snprintf(string, size, "high"));
519105696Srwatson
520105696Srwatson	case MAC_BIBA_TYPE_LOW:
521105696Srwatson		return (snprintf(string, size, "low"));
522105696Srwatson
523105696Srwatson	case MAC_BIBA_TYPE_EQUAL:
524105696Srwatson		return (snprintf(string, size, "equal"));
525105696Srwatson
526105696Srwatson	case MAC_BIBA_TYPE_GRADE:
527105696Srwatson		pos = snprintf(string, size, "%d:", element->mbe_grade);
528105696Srwatson		for (bit = 1; bit <= MAC_BIBA_MAX_COMPARTMENTS; bit++) {
529105696Srwatson			if (MAC_BIBA_BIT_TEST(bit, element->mbe_compartments))
530105696Srwatson				pos += snprintf(string + pos, size - pos,
531105696Srwatson				    "%d+", bit);
532105696Srwatson		}
533105696Srwatson		if (string[pos - 1] == '+' || string[pos - 1] == ':')
534105696Srwatson			string[--pos] = NULL;
535105696Srwatson		return (pos);
536105696Srwatson
537105696Srwatson	default:
538105696Srwatson		panic("mac_biba_element_to_string: invalid type (%d)",
539105696Srwatson		    element->mbe_type);
540105696Srwatson	}
541105696Srwatson}
542105696Srwatson
543101099Srwatsonstatic int
544105696Srwatsonmac_biba_to_string(char *string, size_t size, size_t *caller_len,
545105696Srwatson    struct mac_biba *mac_biba)
546101099Srwatson{
547105696Srwatson	size_t left, len;
548105696Srwatson	char *curptr;
549105696Srwatson
550105696Srwatson	bzero(string, size);
551105696Srwatson	curptr = string;
552105696Srwatson	left = size;
553105696Srwatson
554105696Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) {
555105696Srwatson		len = mac_biba_element_to_string(curptr, left,
556105696Srwatson		    &mac_biba->mb_single);
557105696Srwatson		if (len >= left)
558105696Srwatson			return (EINVAL);
559105696Srwatson		left -= len;
560105696Srwatson		curptr += len;
561105696Srwatson	}
562105696Srwatson
563105696Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
564105696Srwatson		len = snprintf(curptr, left, "(");
565105696Srwatson		if (len >= left)
566105696Srwatson			return (EINVAL);
567105696Srwatson		left -= len;
568105696Srwatson		curptr += len;
569105696Srwatson
570105696Srwatson		len = mac_biba_element_to_string(curptr, left,
571105696Srwatson		    &mac_biba->mb_rangelow);
572105696Srwatson		if (len >= left)
573105696Srwatson			return (EINVAL);
574105696Srwatson		left -= len;
575105696Srwatson		curptr += len;
576105696Srwatson
577105696Srwatson		len = snprintf(curptr, left, "-");
578105696Srwatson		if (len >= left)
579105696Srwatson			return (EINVAL);
580105696Srwatson		left -= len;
581105696Srwatson		curptr += len;
582105696Srwatson
583105696Srwatson		len = mac_biba_element_to_string(curptr, left,
584105696Srwatson		    &mac_biba->mb_rangehigh);
585105696Srwatson		if (len >= left)
586105696Srwatson			return (EINVAL);
587105696Srwatson		left -= len;
588105696Srwatson		curptr += len;
589105696Srwatson
590105696Srwatson		len = snprintf(curptr, left, ")");
591105696Srwatson		if (len >= left)
592105696Srwatson			return (EINVAL);
593105696Srwatson		left -= len;
594105696Srwatson		curptr += len;
595105696Srwatson	}
596105696Srwatson
597105696Srwatson	*caller_len = strlen(string);
598105696Srwatson	return (0);
599105696Srwatson}
600105696Srwatson
601105696Srwatsonstatic int
602105696Srwatsonmac_biba_externalize_label(struct label *label, char *element_name,
603105696Srwatson    char *element_data, size_t size, size_t *len, int *claimed)
604105696Srwatson{
605101099Srwatson	struct mac_biba *mac_biba;
606105696Srwatson	int error;
607101099Srwatson
608105696Srwatson	if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0)
609105696Srwatson		return (0);
610105696Srwatson
611105696Srwatson	(*claimed)++;
612105696Srwatson
613101099Srwatson	mac_biba = SLOT(label);
614105696Srwatson	error = mac_biba_to_string(element_data, size, len, mac_biba);
615105696Srwatson	if (error)
616105696Srwatson		return (error);
617101099Srwatson
618105696Srwatson	*len = strlen(element_data);
619105696Srwatson	return (0);
620105696Srwatson}
621105696Srwatson
622105696Srwatsonstatic int
623105696Srwatsonmac_biba_externalize_vnode_oldmac(struct label *label, struct oldmac *extmac)
624105696Srwatson{
625105696Srwatson	struct mac_biba *mac_biba;
626105696Srwatson
627105696Srwatson	mac_biba = SLOT(label);
628105696Srwatson
629101099Srwatson	if (mac_biba == NULL) {
630105696Srwatson		printf("mac_biba_externalize_vnode_oldmac: NULL pointer\n");
631101099Srwatson		return (0);
632101099Srwatson	}
633101099Srwatson
634101099Srwatson	extmac->m_biba = *mac_biba;
635101099Srwatson
636101099Srwatson	return (0);
637101099Srwatson}
638101099Srwatson
639101099Srwatsonstatic int
640105696Srwatsonmac_biba_parse_element(struct mac_biba_element *element, char *string)
641101099Srwatson{
642105696Srwatson
643105696Srwatson	if (strcmp(string, "high") == 0 ||
644105696Srwatson	    strcmp(string, "hi") == 0) {
645105696Srwatson		element->mbe_type = MAC_BIBA_TYPE_HIGH;
646105696Srwatson		element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
647105696Srwatson	} else if (strcmp(string, "low") == 0 ||
648105696Srwatson	    strcmp(string, "lo") == 0) {
649105696Srwatson		element->mbe_type = MAC_BIBA_TYPE_LOW;
650105696Srwatson		element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
651105696Srwatson	} else if (strcmp(string, "equal") == 0 ||
652105696Srwatson	    strcmp(string, "eq") == 0) {
653105696Srwatson		element->mbe_type = MAC_BIBA_TYPE_EQUAL;
654105696Srwatson		element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
655105696Srwatson	} else {
656105696Srwatson		char *p0, *p1;
657105696Srwatson		int d;
658105696Srwatson
659105696Srwatson		p0 = string;
660105696Srwatson		d = strtol(p0, &p1, 10);
661105696Srwatson
662105696Srwatson		if (d < 0 || d > 65535)
663105696Srwatson			return (EINVAL);
664105696Srwatson		element->mbe_type = MAC_BIBA_TYPE_GRADE;
665105696Srwatson		element->mbe_grade = d;
666105696Srwatson
667105696Srwatson		if (*p1 != ':')  {
668105696Srwatson			if (p1 == p0 || *p1 != '\0')
669105696Srwatson				return (EINVAL);
670105696Srwatson			else
671105696Srwatson				return (0);
672105696Srwatson		}
673105696Srwatson		else
674105696Srwatson			if (*(p1 + 1) == '\0')
675105696Srwatson				return (0);
676105696Srwatson
677105696Srwatson		while ((p0 = ++p1)) {
678105696Srwatson			d = strtol(p0, &p1, 10);
679105696Srwatson			if (d < 1 || d > MAC_BIBA_MAX_COMPARTMENTS)
680105696Srwatson				return (EINVAL);
681105696Srwatson
682105696Srwatson			MAC_BIBA_BIT_SET(d, element->mbe_compartments);
683105696Srwatson
684105696Srwatson			if (*p1 == '\0')
685105696Srwatson				break;
686105696Srwatson			if (p1 == p0 || *p1 != '+')
687105696Srwatson				return (EINVAL);
688105696Srwatson		}
689105696Srwatson	}
690105696Srwatson
691105696Srwatson	return (0);
692105696Srwatson}
693105696Srwatson
694105696Srwatson/*
695105696Srwatson * Note: destructively consumes the string, make a local copy before
696105696Srwatson * calling if that's a problem.
697105696Srwatson */
698105696Srwatsonstatic int
699105696Srwatsonmac_biba_parse(struct mac_biba *mac_biba, char *string)
700105696Srwatson{
701105696Srwatson	char *range, *rangeend, *rangehigh, *rangelow, *single;
702101099Srwatson	int error;
703101099Srwatson
704105696Srwatson	/* Do we have a range? */
705105696Srwatson	single = string;
706105696Srwatson	range = index(string, '(');
707105696Srwatson	if (range == single)
708105696Srwatson		single = NULL;
709105696Srwatson	rangelow = rangehigh = NULL;
710105696Srwatson	if (range != NULL) {
711105696Srwatson		/* Nul terminate the end of the single string. */
712105696Srwatson		*range = '\0';
713105696Srwatson		range++;
714105696Srwatson		rangelow = range;
715105696Srwatson		rangehigh = index(rangelow, '-');
716105696Srwatson		if (rangehigh == NULL)
717105696Srwatson			return (EINVAL);
718105696Srwatson		rangehigh++;
719105696Srwatson		if (*rangelow == '\0' || *rangehigh == '\0')
720105696Srwatson			return (EINVAL);
721105696Srwatson		rangeend = index(rangehigh, ')');
722105696Srwatson		if (rangeend == NULL)
723105696Srwatson			return (EINVAL);
724105696Srwatson		if (*(rangeend + 1) != '\0')
725105696Srwatson			return (EINVAL);
726105696Srwatson		/* Nul terminate the ends of the ranges. */
727105696Srwatson		*(rangehigh - 1) = '\0';
728105696Srwatson		*rangeend = '\0';
729105696Srwatson	}
730105696Srwatson	KASSERT((rangelow != NULL && rangehigh != NULL) ||
731105696Srwatson	    (rangelow == NULL && rangehigh == NULL),
732105696Srwatson	    ("mac_biba_internalize_label: range mismatch"));
733101099Srwatson
734105696Srwatson	bzero(mac_biba, sizeof(*mac_biba));
735105696Srwatson	if (single != NULL) {
736105696Srwatson		error = mac_biba_parse_element(&mac_biba->mb_single, single);
737105696Srwatson		if (error)
738105696Srwatson			return (error);
739105696Srwatson		mac_biba->mb_flags |= MAC_BIBA_FLAG_SINGLE;
740105696Srwatson	}
741105696Srwatson
742105696Srwatson	if (rangelow != NULL) {
743105696Srwatson		error = mac_biba_parse_element(&mac_biba->mb_rangelow,
744105696Srwatson		    rangelow);
745105696Srwatson		if (error)
746105696Srwatson			return (error);
747105696Srwatson		error = mac_biba_parse_element(&mac_biba->mb_rangehigh,
748105696Srwatson		    rangehigh);
749105696Srwatson		if (error)
750105696Srwatson			return (error);
751105696Srwatson		mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE;
752105696Srwatson	}
753105696Srwatson
754101099Srwatson	error = mac_biba_valid(mac_biba);
755101099Srwatson	if (error)
756101099Srwatson		return (error);
757101099Srwatson
758105696Srwatson	return (0);
759105696Srwatson}
760101099Srwatson
761105696Srwatsonstatic int
762105696Srwatsonmac_biba_internalize_label(struct label *label, char *element_name,
763105696Srwatson    char *element_data, int *claimed)
764105696Srwatson{
765105696Srwatson	struct mac_biba *mac_biba, mac_biba_temp;
766105696Srwatson	int error;
767105696Srwatson
768105696Srwatson	if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0)
769105696Srwatson		return (0);
770105696Srwatson
771105696Srwatson	(*claimed)++;
772105696Srwatson
773105696Srwatson	error = mac_biba_parse(&mac_biba_temp, element_data);
774105696Srwatson	if (error)
775105696Srwatson		return (error);
776105696Srwatson
777105696Srwatson	mac_biba = SLOT(label);
778105696Srwatson	*mac_biba = mac_biba_temp;
779105696Srwatson
780101099Srwatson	return (0);
781101099Srwatson}
782101099Srwatson
783105696Srwatsonstatic void
784105696Srwatsonmac_biba_copy_label(struct label *src, struct label *dest)
785105696Srwatson{
786105696Srwatson
787105696Srwatson	*SLOT(dest) = *SLOT(src);
788105696Srwatson}
789105696Srwatson
790101099Srwatson/*
791101099Srwatson * Labeling event operations: file system objects, and things that look
792101099Srwatson * a lot like file system objects.
793101099Srwatson */
794101099Srwatsonstatic void
795101099Srwatsonmac_biba_create_devfs_device(dev_t dev, struct devfs_dirent *devfs_dirent,
796101099Srwatson    struct label *label)
797101099Srwatson{
798101099Srwatson	struct mac_biba *mac_biba;
799101099Srwatson	int biba_type;
800101099Srwatson
801101099Srwatson	mac_biba = SLOT(label);
802101099Srwatson	if (strcmp(dev->si_name, "null") == 0 ||
803101099Srwatson	    strcmp(dev->si_name, "zero") == 0 ||
804101099Srwatson	    strcmp(dev->si_name, "random") == 0 ||
805101099Srwatson	    strncmp(dev->si_name, "fd/", strlen("fd/")) == 0)
806101099Srwatson		biba_type = MAC_BIBA_TYPE_EQUAL;
807105606Srwatson	else if (ptys_equal &&
808105606Srwatson	    (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 ||
809105606Srwatson	    strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0))
810105606Srwatson		biba_type = MAC_BIBA_TYPE_EQUAL;
811101099Srwatson	else
812101099Srwatson		biba_type = MAC_BIBA_TYPE_HIGH;
813105643Srwatson	mac_biba_set_single(mac_biba, biba_type, 0, NULL);
814101099Srwatson}
815101099Srwatson
816101099Srwatsonstatic void
817101099Srwatsonmac_biba_create_devfs_directory(char *dirname, int dirnamelen,
818101099Srwatson    struct devfs_dirent *devfs_dirent, struct label *label)
819101099Srwatson{
820101099Srwatson	struct mac_biba *mac_biba;
821101099Srwatson
822101099Srwatson	mac_biba = SLOT(label);
823105643Srwatson	mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
824101099Srwatson}
825101099Srwatson
826101099Srwatsonstatic void
827104535Srwatsonmac_biba_create_devfs_symlink(struct ucred *cred, struct devfs_dirent *dd,
828104535Srwatson    struct label *ddlabel, struct devfs_dirent *de, struct label *delabel)
829104535Srwatson{
830104535Srwatson	struct mac_biba *source, *dest;
831104535Srwatson
832104535Srwatson	source = SLOT(&cred->cr_label);
833104535Srwatson	dest = SLOT(delabel);
834104535Srwatson
835104535Srwatson	mac_biba_copy_single(source, dest);
836104535Srwatson}
837104535Srwatson
838104535Srwatsonstatic void
839101099Srwatsonmac_biba_create_devfs_vnode(struct devfs_dirent *devfs_dirent,
840101099Srwatson    struct label *direntlabel, struct vnode *vp, struct label *vnodelabel)
841101099Srwatson{
842101099Srwatson	struct mac_biba *source, *dest;
843101099Srwatson
844101099Srwatson	source = SLOT(direntlabel);
845101099Srwatson	dest = SLOT(vnodelabel);
846101099Srwatson	mac_biba_copy_single(source, dest);
847101099Srwatson}
848101099Srwatson
849101099Srwatsonstatic void
850101099Srwatsonmac_biba_create_vnode(struct ucred *cred, struct vnode *parent,
851101099Srwatson    struct label *parentlabel, struct vnode *child, struct label *childlabel)
852101099Srwatson{
853101099Srwatson	struct mac_biba *source, *dest;
854101099Srwatson
855101099Srwatson	source = SLOT(&cred->cr_label);
856101099Srwatson	dest = SLOT(childlabel);
857101099Srwatson
858101099Srwatson	mac_biba_copy_single(source, dest);
859101099Srwatson}
860101099Srwatson
861101099Srwatsonstatic void
862101099Srwatsonmac_biba_create_mount(struct ucred *cred, struct mount *mp,
863101099Srwatson    struct label *mntlabel, struct label *fslabel)
864101099Srwatson{
865101099Srwatson	struct mac_biba *source, *dest;
866101099Srwatson
867101099Srwatson	source = SLOT(&cred->cr_label);
868101099Srwatson	dest = SLOT(mntlabel);
869101099Srwatson	mac_biba_copy_single(source, dest);
870101099Srwatson	dest = SLOT(fslabel);
871101099Srwatson	mac_biba_copy_single(source, dest);
872101099Srwatson}
873101099Srwatson
874101099Srwatsonstatic void
875101099Srwatsonmac_biba_create_root_mount(struct ucred *cred, struct mount *mp,
876101099Srwatson    struct label *mntlabel, struct label *fslabel)
877101099Srwatson{
878101099Srwatson	struct mac_biba *mac_biba;
879101099Srwatson
880101099Srwatson	/* Always mount root as high integrity. */
881101099Srwatson	mac_biba = SLOT(fslabel);
882105643Srwatson	mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
883101099Srwatson	mac_biba = SLOT(mntlabel);
884105643Srwatson	mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
885101099Srwatson}
886101099Srwatson
887101099Srwatsonstatic void
888101099Srwatsonmac_biba_relabel_vnode(struct ucred *cred, struct vnode *vp,
889101099Srwatson    struct label *vnodelabel, struct label *label)
890101099Srwatson{
891101099Srwatson	struct mac_biba *source, *dest;
892101099Srwatson
893101099Srwatson	source = SLOT(label);
894101099Srwatson	dest = SLOT(vnodelabel);
895101099Srwatson
896105656Srwatson	mac_biba_copy(source, dest);
897101099Srwatson}
898101099Srwatson
899101099Srwatsonstatic void
900101099Srwatsonmac_biba_update_devfsdirent(struct devfs_dirent *devfs_dirent,
901101099Srwatson    struct label *direntlabel, struct vnode *vp, struct label *vnodelabel)
902101099Srwatson{
903101099Srwatson	struct mac_biba *source, *dest;
904101099Srwatson
905101099Srwatson	source = SLOT(vnodelabel);
906101099Srwatson	dest = SLOT(direntlabel);
907101099Srwatson
908105656Srwatson	mac_biba_copy(source, dest);
909101099Srwatson}
910101099Srwatson
911101099Srwatsonstatic void
912101099Srwatsonmac_biba_update_procfsvnode(struct vnode *vp, struct label *vnodelabel,
913101099Srwatson    struct ucred *cred)
914101099Srwatson{
915101099Srwatson	struct mac_biba *source, *dest;
916101099Srwatson
917101099Srwatson	source = SLOT(&cred->cr_label);
918101099Srwatson	dest = SLOT(vnodelabel);
919101099Srwatson
920101099Srwatson	/*
921101099Srwatson	 * Only copy the single, not the range, since vnodes only have
922101099Srwatson	 * a single.
923101099Srwatson	 */
924101099Srwatson	mac_biba_copy_single(source, dest);
925101099Srwatson}
926101099Srwatson
927101099Srwatsonstatic int
928101099Srwatsonmac_biba_update_vnode_from_externalized(struct vnode *vp,
929105696Srwatson    struct label *vnodelabel, struct oldmac *extmac)
930101099Srwatson{
931101099Srwatson	struct mac_biba *source, *dest;
932101099Srwatson	int error;
933101099Srwatson
934101099Srwatson	source = &extmac->m_biba;
935101099Srwatson	dest = SLOT(vnodelabel);
936101099Srwatson
937101099Srwatson	error = mac_biba_valid(source);
938101099Srwatson	if (error)
939101099Srwatson		return (error);
940101099Srwatson
941101099Srwatson	if ((source->mb_flags & MAC_BIBA_FLAGS_BOTH) != MAC_BIBA_FLAG_SINGLE)
942101099Srwatson		return (EINVAL);
943101099Srwatson
944101099Srwatson	mac_biba_copy_single(source, dest);
945101099Srwatson
946101099Srwatson	return (0);
947101099Srwatson}
948101099Srwatson
949101099Srwatsonstatic void
950101099Srwatsonmac_biba_update_vnode_from_mount(struct vnode *vp, struct label *vnodelabel,
951101099Srwatson    struct mount *mp, struct label *fslabel)
952101099Srwatson{
953101099Srwatson	struct mac_biba *source, *dest;
954101099Srwatson
955101099Srwatson	source = SLOT(fslabel);
956101099Srwatson	dest = SLOT(vnodelabel);
957101099Srwatson
958101099Srwatson	mac_biba_copy_single(source, dest);
959101099Srwatson}
960101099Srwatson
961101099Srwatson/*
962101099Srwatson * Labeling event operations: IPC object.
963101099Srwatson */
964101099Srwatsonstatic void
965101099Srwatsonmac_biba_create_mbuf_from_socket(struct socket *so, struct label *socketlabel,
966101099Srwatson    struct mbuf *m, struct label *mbuflabel)
967101099Srwatson{
968101099Srwatson	struct mac_biba *source, *dest;
969101099Srwatson
970101099Srwatson	source = SLOT(socketlabel);
971101099Srwatson	dest = SLOT(mbuflabel);
972101099Srwatson
973101099Srwatson	mac_biba_copy_single(source, dest);
974101099Srwatson}
975101099Srwatson
976101099Srwatsonstatic void
977101099Srwatsonmac_biba_create_socket(struct ucred *cred, struct socket *socket,
978101099Srwatson    struct label *socketlabel)
979101099Srwatson{
980101099Srwatson	struct mac_biba *source, *dest;
981101099Srwatson
982101099Srwatson	source = SLOT(&cred->cr_label);
983101099Srwatson	dest = SLOT(socketlabel);
984101099Srwatson
985101099Srwatson	mac_biba_copy_single(source, dest);
986101099Srwatson}
987101099Srwatson
988101099Srwatsonstatic void
989101099Srwatsonmac_biba_create_pipe(struct ucred *cred, struct pipe *pipe,
990101099Srwatson    struct label *pipelabel)
991101099Srwatson{
992101099Srwatson	struct mac_biba *source, *dest;
993101099Srwatson
994101099Srwatson	source = SLOT(&cred->cr_label);
995101099Srwatson	dest = SLOT(pipelabel);
996101099Srwatson
997101099Srwatson	mac_biba_copy_single(source, dest);
998101099Srwatson}
999101099Srwatson
1000101099Srwatsonstatic void
1001101099Srwatsonmac_biba_create_socket_from_socket(struct socket *oldsocket,
1002101099Srwatson    struct label *oldsocketlabel, struct socket *newsocket,
1003101099Srwatson    struct label *newsocketlabel)
1004101099Srwatson{
1005101099Srwatson	struct mac_biba *source, *dest;
1006101099Srwatson
1007101099Srwatson	source = SLOT(oldsocketlabel);
1008101099Srwatson	dest = SLOT(newsocketlabel);
1009101099Srwatson
1010101099Srwatson	mac_biba_copy_single(source, dest);
1011101099Srwatson}
1012101099Srwatson
1013101099Srwatsonstatic void
1014101099Srwatsonmac_biba_relabel_socket(struct ucred *cred, struct socket *socket,
1015101099Srwatson    struct label *socketlabel, struct label *newlabel)
1016101099Srwatson{
1017101099Srwatson	struct mac_biba *source, *dest;
1018101099Srwatson
1019101099Srwatson	source = SLOT(newlabel);
1020101099Srwatson	dest = SLOT(socketlabel);
1021101099Srwatson
1022105656Srwatson	mac_biba_copy(source, dest);
1023101099Srwatson}
1024101099Srwatson
1025101099Srwatsonstatic void
1026101099Srwatsonmac_biba_relabel_pipe(struct ucred *cred, struct pipe *pipe,
1027101099Srwatson    struct label *pipelabel, struct label *newlabel)
1028101099Srwatson{
1029101099Srwatson	struct mac_biba *source, *dest;
1030101099Srwatson
1031101099Srwatson	source = SLOT(newlabel);
1032101099Srwatson	dest = SLOT(pipelabel);
1033101099Srwatson
1034105656Srwatson	mac_biba_copy(source, dest);
1035101099Srwatson}
1036101099Srwatson
1037101099Srwatsonstatic void
1038101099Srwatsonmac_biba_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel,
1039101099Srwatson    struct socket *socket, struct label *socketpeerlabel)
1040101099Srwatson{
1041101099Srwatson	struct mac_biba *source, *dest;
1042101099Srwatson
1043101099Srwatson	source = SLOT(mbuflabel);
1044101099Srwatson	dest = SLOT(socketpeerlabel);
1045101099Srwatson
1046101099Srwatson	mac_biba_copy_single(source, dest);
1047101099Srwatson}
1048101099Srwatson
1049101099Srwatson/*
1050101099Srwatson * Labeling event operations: network objects.
1051101099Srwatson */
1052101099Srwatsonstatic void
1053101099Srwatsonmac_biba_set_socket_peer_from_socket(struct socket *oldsocket,
1054101099Srwatson    struct label *oldsocketlabel, struct socket *newsocket,
1055101099Srwatson    struct label *newsocketpeerlabel)
1056101099Srwatson{
1057101099Srwatson	struct mac_biba *source, *dest;
1058101099Srwatson
1059101099Srwatson	source = SLOT(oldsocketlabel);
1060101099Srwatson	dest = SLOT(newsocketpeerlabel);
1061101099Srwatson
1062101099Srwatson	mac_biba_copy_single(source, dest);
1063101099Srwatson}
1064101099Srwatson
1065101099Srwatsonstatic void
1066101099Srwatsonmac_biba_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d,
1067101099Srwatson    struct label *bpflabel)
1068101099Srwatson{
1069101099Srwatson	struct mac_biba *source, *dest;
1070101099Srwatson
1071101099Srwatson	source = SLOT(&cred->cr_label);
1072101099Srwatson	dest = SLOT(bpflabel);
1073101099Srwatson
1074101099Srwatson	mac_biba_copy_single(source, dest);
1075101099Srwatson}
1076101099Srwatson
1077101099Srwatsonstatic void
1078101099Srwatsonmac_biba_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel)
1079101099Srwatson{
1080101099Srwatson	char tifname[IFNAMSIZ], ifname[IFNAMSIZ], *p, *q;
1081101099Srwatson	char tiflist[sizeof(trusted_interfaces)];
1082101099Srwatson	struct mac_biba *dest;
1083101099Srwatson	int len, grade;
1084101099Srwatson
1085101099Srwatson	dest = SLOT(ifnetlabel);
1086101099Srwatson
1087101099Srwatson	if (ifnet->if_type == IFT_LOOP) {
1088101099Srwatson		grade = MAC_BIBA_TYPE_EQUAL;
1089101099Srwatson		goto set;
1090101099Srwatson	}
1091101099Srwatson
1092101099Srwatson	if (trust_all_interfaces) {
1093101099Srwatson		grade = MAC_BIBA_TYPE_HIGH;
1094101099Srwatson		goto set;
1095101099Srwatson	}
1096101099Srwatson
1097101099Srwatson	grade = MAC_BIBA_TYPE_LOW;
1098101099Srwatson
1099101099Srwatson	if (trusted_interfaces[0] == '\0' ||
1100101099Srwatson	    !strvalid(trusted_interfaces, sizeof(trusted_interfaces)))
1101101099Srwatson		goto set;
1102101099Srwatson
1103101099Srwatson	for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++)
1104101099Srwatson		if(*p != ' ' && *p != '\t')
1105101099Srwatson			*q = *p;
1106101099Srwatson
1107101099Srwatson	snprintf(ifname, IFNAMSIZ, "%s%d", ifnet->if_name, ifnet->if_unit);
1108101099Srwatson
1109101099Srwatson	for (p = q = tiflist;; p++) {
1110101099Srwatson		if (*p == ',' || *p == '\0') {
1111101099Srwatson			len = p - q;
1112101099Srwatson			if (len < IFNAMSIZ) {
1113101099Srwatson				bzero(tifname, sizeof(tifname));
1114101099Srwatson				bcopy(q, tifname, len);
1115101099Srwatson				if (strcmp(tifname, ifname) == 0) {
1116101099Srwatson					grade = MAC_BIBA_TYPE_HIGH;
1117101099Srwatson					break;
1118101099Srwatson				}
1119101099Srwatson			}
1120101099Srwatson			if (*p == '\0')
1121101099Srwatson				break;
1122101099Srwatson			q = p + 1;
1123101099Srwatson		}
1124101099Srwatson	}
1125101099Srwatsonset:
1126105643Srwatson	mac_biba_set_single(dest, grade, 0, NULL);
1127105643Srwatson	mac_biba_set_range(dest, grade, 0, NULL, grade, 0, NULL);
1128101099Srwatson}
1129101099Srwatson
1130101099Srwatsonstatic void
1131101099Srwatsonmac_biba_create_ipq(struct mbuf *fragment, struct label *fragmentlabel,
1132101099Srwatson    struct ipq *ipq, struct label *ipqlabel)
1133101099Srwatson{
1134101099Srwatson	struct mac_biba *source, *dest;
1135101099Srwatson
1136101099Srwatson	source = SLOT(fragmentlabel);
1137101099Srwatson	dest = SLOT(ipqlabel);
1138101099Srwatson
1139101099Srwatson	mac_biba_copy_single(source, dest);
1140101099Srwatson}
1141101099Srwatson
1142101099Srwatsonstatic void
1143101099Srwatsonmac_biba_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel,
1144101099Srwatson    struct mbuf *datagram, struct label *datagramlabel)
1145101099Srwatson{
1146101099Srwatson	struct mac_biba *source, *dest;
1147101099Srwatson
1148101099Srwatson	source = SLOT(ipqlabel);
1149101099Srwatson	dest = SLOT(datagramlabel);
1150101099Srwatson
1151101099Srwatson	/* Just use the head, since we require them all to match. */
1152101099Srwatson	mac_biba_copy_single(source, dest);
1153101099Srwatson}
1154101099Srwatson
1155101099Srwatsonstatic void
1156101099Srwatsonmac_biba_create_fragment(struct mbuf *datagram, struct label *datagramlabel,
1157101099Srwatson    struct mbuf *fragment, struct label *fragmentlabel)
1158101099Srwatson{
1159101099Srwatson	struct mac_biba *source, *dest;
1160101099Srwatson
1161101099Srwatson	source = SLOT(datagramlabel);
1162101099Srwatson	dest = SLOT(fragmentlabel);
1163101099Srwatson
1164101099Srwatson	mac_biba_copy_single(source, dest);
1165101099Srwatson}
1166101099Srwatson
1167101099Srwatsonstatic void
1168101099Srwatsonmac_biba_create_mbuf_from_mbuf(struct mbuf *oldmbuf,
1169101099Srwatson    struct label *oldmbuflabel, struct mbuf *newmbuf,
1170101099Srwatson    struct label *newmbuflabel)
1171101099Srwatson{
1172101099Srwatson	struct mac_biba *source, *dest;
1173101099Srwatson
1174101099Srwatson	source = SLOT(oldmbuflabel);
1175101099Srwatson	dest = SLOT(newmbuflabel);
1176101099Srwatson
1177105656Srwatson	/*
1178105656Srwatson	 * Because the source mbuf may not yet have been "created",
1179105696Srwatson	 * just initialized, we do a conditional copy.  Since we don't
1180105656Srwatson	 * allow mbufs to have ranges, do a KASSERT to make sure that
1181105656Srwatson	 * doesn't happen.
1182105656Srwatson	 */
1183105656Srwatson	KASSERT((source->mb_flags & MAC_BIBA_FLAG_RANGE) == 0,
1184105656Srwatson	    ("mac_biba_create_mbuf_from_mbuf: source mbuf has range"));
1185105656Srwatson	mac_biba_copy(source, dest);
1186101099Srwatson}
1187101099Srwatson
1188101099Srwatsonstatic void
1189101099Srwatsonmac_biba_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel,
1190101099Srwatson    struct mbuf *mbuf, struct label *mbuflabel)
1191101099Srwatson{
1192101099Srwatson	struct mac_biba *dest;
1193101099Srwatson
1194101099Srwatson	dest = SLOT(mbuflabel);
1195101099Srwatson
1196105643Srwatson	mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1197101099Srwatson}
1198101099Srwatson
1199101099Srwatsonstatic void
1200101099Srwatsonmac_biba_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel,
1201101099Srwatson    struct mbuf *mbuf, struct label *mbuflabel)
1202101099Srwatson{
1203101099Srwatson	struct mac_biba *source, *dest;
1204101099Srwatson
1205101099Srwatson	source = SLOT(bpflabel);
1206101099Srwatson	dest = SLOT(mbuflabel);
1207101099Srwatson
1208101099Srwatson	mac_biba_copy_single(source, dest);
1209101099Srwatson}
1210101099Srwatson
1211101099Srwatsonstatic void
1212101099Srwatsonmac_biba_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel,
1213101099Srwatson    struct mbuf *m, struct label *mbuflabel)
1214101099Srwatson{
1215101099Srwatson	struct mac_biba *source, *dest;
1216101099Srwatson
1217101099Srwatson	source = SLOT(ifnetlabel);
1218101099Srwatson	dest = SLOT(mbuflabel);
1219101099Srwatson
1220101099Srwatson	mac_biba_copy_single(source, dest);
1221101099Srwatson}
1222101099Srwatson
1223101099Srwatsonstatic void
1224101099Srwatsonmac_biba_create_mbuf_multicast_encap(struct mbuf *oldmbuf,
1225101099Srwatson    struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel,
1226101099Srwatson    struct mbuf *newmbuf, struct label *newmbuflabel)
1227101099Srwatson{
1228101099Srwatson	struct mac_biba *source, *dest;
1229101099Srwatson
1230101099Srwatson	source = SLOT(oldmbuflabel);
1231101099Srwatson	dest = SLOT(newmbuflabel);
1232101099Srwatson
1233101099Srwatson	mac_biba_copy_single(source, dest);
1234101099Srwatson}
1235101099Srwatson
1236101099Srwatsonstatic void
1237101099Srwatsonmac_biba_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel,
1238101099Srwatson    struct mbuf *newmbuf, struct label *newmbuflabel)
1239101099Srwatson{
1240101099Srwatson	struct mac_biba *source, *dest;
1241101099Srwatson
1242101099Srwatson	source = SLOT(oldmbuflabel);
1243101099Srwatson	dest = SLOT(newmbuflabel);
1244101099Srwatson
1245101099Srwatson	mac_biba_copy_single(source, dest);
1246101099Srwatson}
1247101099Srwatson
1248101099Srwatsonstatic int
1249101099Srwatsonmac_biba_fragment_match(struct mbuf *fragment, struct label *fragmentlabel,
1250101099Srwatson    struct ipq *ipq, struct label *ipqlabel)
1251101099Srwatson{
1252101099Srwatson	struct mac_biba *a, *b;
1253101099Srwatson
1254101099Srwatson	a = SLOT(ipqlabel);
1255101099Srwatson	b = SLOT(fragmentlabel);
1256101099Srwatson
1257101099Srwatson	return (mac_biba_equal_single(a, b));
1258101099Srwatson}
1259101099Srwatson
1260101099Srwatsonstatic void
1261101099Srwatsonmac_biba_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet,
1262101099Srwatson    struct label *ifnetlabel, struct label *newlabel)
1263101099Srwatson{
1264101099Srwatson	struct mac_biba *source, *dest;
1265101099Srwatson
1266101099Srwatson	source = SLOT(newlabel);
1267101099Srwatson	dest = SLOT(ifnetlabel);
1268101099Srwatson
1269105656Srwatson	mac_biba_copy(source, dest);
1270101099Srwatson}
1271101099Srwatson
1272101099Srwatsonstatic void
1273101099Srwatsonmac_biba_update_ipq(struct mbuf *fragment, struct label *fragmentlabel,
1274101099Srwatson    struct ipq *ipq, struct label *ipqlabel)
1275101099Srwatson{
1276101099Srwatson
1277101099Srwatson	/* NOOP: we only accept matching labels, so no need to update */
1278101099Srwatson}
1279101099Srwatson
1280101099Srwatson/*
1281101099Srwatson * Labeling event operations: processes.
1282101099Srwatson */
1283101099Srwatsonstatic void
1284101099Srwatsonmac_biba_create_cred(struct ucred *cred_parent, struct ucred *cred_child)
1285101099Srwatson{
1286101099Srwatson	struct mac_biba *source, *dest;
1287101099Srwatson
1288101099Srwatson	source = SLOT(&cred_parent->cr_label);
1289101099Srwatson	dest = SLOT(&cred_child->cr_label);
1290101099Srwatson
1291101099Srwatson	mac_biba_copy_single(source, dest);
1292101099Srwatson	mac_biba_copy_range(source, dest);
1293101099Srwatson}
1294101099Srwatson
1295101099Srwatsonstatic void
1296101099Srwatsonmac_biba_execve_transition(struct ucred *old, struct ucred *new,
1297101099Srwatson    struct vnode *vp, struct mac *vnodelabel)
1298101099Srwatson{
1299101099Srwatson	struct mac_biba *source, *dest;
1300101099Srwatson
1301101099Srwatson	source = SLOT(&old->cr_label);
1302101099Srwatson	dest = SLOT(&new->cr_label);
1303101099Srwatson
1304101099Srwatson	mac_biba_copy_single(source, dest);
1305101099Srwatson	mac_biba_copy_range(source, dest);
1306101099Srwatson}
1307101099Srwatson
1308101099Srwatsonstatic int
1309101099Srwatsonmac_biba_execve_will_transition(struct ucred *old, struct vnode *vp,
1310101099Srwatson    struct mac *vnodelabel)
1311101099Srwatson{
1312101099Srwatson
1313101099Srwatson	return (0);
1314101099Srwatson}
1315101099Srwatson
1316101099Srwatsonstatic void
1317101099Srwatsonmac_biba_create_proc0(struct ucred *cred)
1318101099Srwatson{
1319101099Srwatson	struct mac_biba *dest;
1320101099Srwatson
1321101099Srwatson	dest = SLOT(&cred->cr_label);
1322101099Srwatson
1323105643Srwatson	mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1324105643Srwatson	mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL,
1325105643Srwatson	    MAC_BIBA_TYPE_HIGH, 0, NULL);
1326101099Srwatson}
1327101099Srwatson
1328101099Srwatsonstatic void
1329101099Srwatsonmac_biba_create_proc1(struct ucred *cred)
1330101099Srwatson{
1331101099Srwatson	struct mac_biba *dest;
1332101099Srwatson
1333101099Srwatson	dest = SLOT(&cred->cr_label);
1334101099Srwatson
1335105643Srwatson	mac_biba_set_single(dest, MAC_BIBA_TYPE_HIGH, 0, NULL);
1336105643Srwatson	mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL,
1337105643Srwatson	    MAC_BIBA_TYPE_HIGH, 0, NULL);
1338101099Srwatson}
1339101099Srwatson
1340101099Srwatsonstatic void
1341101099Srwatsonmac_biba_relabel_cred(struct ucred *cred, struct label *newlabel)
1342101099Srwatson{
1343101099Srwatson	struct mac_biba *source, *dest;
1344101099Srwatson
1345101099Srwatson	source = SLOT(newlabel);
1346101099Srwatson	dest = SLOT(&cred->cr_label);
1347101099Srwatson
1348105656Srwatson	mac_biba_copy(source, dest);
1349101099Srwatson}
1350101099Srwatson
1351101099Srwatson/*
1352101099Srwatson * Access control checks.
1353101099Srwatson */
1354101099Srwatsonstatic int
1355101099Srwatsonmac_biba_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel,
1356101099Srwatson    struct ifnet *ifnet, struct label *ifnetlabel)
1357101099Srwatson{
1358101099Srwatson	struct mac_biba *a, *b;
1359101099Srwatson
1360101099Srwatson	if (!mac_biba_enabled)
1361101099Srwatson		return (0);
1362101099Srwatson
1363101099Srwatson	a = SLOT(bpflabel);
1364101099Srwatson	b = SLOT(ifnetlabel);
1365101099Srwatson
1366101099Srwatson	if (mac_biba_equal_single(a, b))
1367101099Srwatson		return (0);
1368101099Srwatson	return (EACCES);
1369101099Srwatson}
1370101099Srwatson
1371101099Srwatsonstatic int
1372101099Srwatsonmac_biba_check_cred_relabel(struct ucred *cred, struct label *newlabel)
1373101099Srwatson{
1374101099Srwatson	struct mac_biba *subj, *new;
1375105634Srwatson	int error;
1376101099Srwatson
1377101099Srwatson	subj = SLOT(&cred->cr_label);
1378101099Srwatson	new = SLOT(newlabel);
1379101099Srwatson
1380101099Srwatson	/*
1381105634Srwatson	 * If there is a Biba label update for the credential, it may
1382105634Srwatson	 * be an update of the single, range, or both.
1383101099Srwatson	 */
1384105634Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
1385105634Srwatson	if (error)
1386105634Srwatson		return (error);
1387101099Srwatson
1388101099Srwatson	/*
1389105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
1390101099Srwatson	 */
1391105634Srwatson	if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) {
1392105634Srwatson		/*
1393105634Srwatson		 * To change the Biba single label on a credential, the
1394105634Srwatson		 * new single label must be in the current range.
1395105634Srwatson		 */
1396105634Srwatson		if (new->mb_flags & MAC_BIBA_FLAG_SINGLE &&
1397105634Srwatson		    !mac_biba_single_in_range(new, subj))
1398105634Srwatson			return (EPERM);
1399101099Srwatson
1400105634Srwatson		/*
1401105634Srwatson		 * To change the Biba range on a credential, the new
1402105634Srwatson		 * range label must be in the current range.
1403105634Srwatson		 */
1404105634Srwatson		if (new->mb_flags & MAC_BIBA_FLAG_RANGE &&
1405105634Srwatson		    !mac_biba_range_in_range(new, subj))
1406105634Srwatson			return (EPERM);
1407101099Srwatson
1408105634Srwatson		/*
1409105634Srwatson		 * To have EQUAL in any component of the new credential
1410105634Srwatson		 * Biba label, the subject must already have EQUAL in
1411105634Srwatson		 * their label.
1412105634Srwatson		 */
1413105634Srwatson		if (mac_biba_contains_equal(new)) {
1414105634Srwatson			error = mac_biba_subject_equal_ok(subj);
1415105634Srwatson			if (error)
1416105634Srwatson				return (error);
1417105634Srwatson		}
1418101099Srwatson
1419105634Srwatson		/*
1420105634Srwatson		 * XXXMAC: Additional consistency tests regarding the
1421105634Srwatson		 * single and range of the new label might be performed
1422105634Srwatson		 * here.
1423105634Srwatson		 */
1424105634Srwatson	}
1425105634Srwatson
1426101099Srwatson	return (0);
1427101099Srwatson}
1428101099Srwatson
1429101099Srwatsonstatic int
1430101099Srwatsonmac_biba_check_cred_visible(struct ucred *u1, struct ucred *u2)
1431101099Srwatson{
1432101099Srwatson	struct mac_biba *subj, *obj;
1433101099Srwatson
1434101099Srwatson	if (!mac_biba_enabled)
1435101099Srwatson		return (0);
1436101099Srwatson
1437101099Srwatson	subj = SLOT(&u1->cr_label);
1438101099Srwatson	obj = SLOT(&u2->cr_label);
1439101099Srwatson
1440101099Srwatson	/* XXX: range */
1441101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1442101099Srwatson		return (ESRCH);
1443101099Srwatson
1444101099Srwatson	return (0);
1445101099Srwatson}
1446101099Srwatson
1447101099Srwatsonstatic int
1448101099Srwatsonmac_biba_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet,
1449101099Srwatson    struct label *ifnetlabel, struct label *newlabel)
1450101099Srwatson{
1451101099Srwatson	struct mac_biba *subj, *new;
1452105634Srwatson	int error;
1453101099Srwatson
1454101099Srwatson	subj = SLOT(&cred->cr_label);
1455101099Srwatson	new = SLOT(newlabel);
1456101099Srwatson
1457105634Srwatson	/*
1458105634Srwatson	 * If there is a Biba label update for the interface, it may
1459105634Srwatson	 * be an update of the single, range, or both.
1460105634Srwatson	 */
1461105634Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
1462105634Srwatson	if (error)
1463105634Srwatson		return (error);
1464101099Srwatson
1465105634Srwatson	/*
1466105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
1467105634Srwatson	 */
1468105634Srwatson	if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) {
1469105634Srwatson		/*
1470105634Srwatson		 * Rely on the traditional superuser status for the Biba
1471105634Srwatson		 * interface relabel requirements.  XXXMAC: This will go
1472105634Srwatson		 * away.
1473105634Srwatson		 */
1474105634Srwatson		error = suser_cred(cred, 0);
1475105634Srwatson		if (error)
1476105634Srwatson			return (EPERM);
1477105634Srwatson
1478105634Srwatson		/*
1479105634Srwatson		 * XXXMAC: Additional consistency tests regarding the single
1480105634Srwatson		 * and the range of the new label might be performed here.
1481105634Srwatson		 */
1482105634Srwatson	}
1483105634Srwatson
1484105634Srwatson	return (0);
1485101099Srwatson}
1486101099Srwatson
1487103759Srwatsonstatic int
1488101099Srwatsonmac_biba_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel,
1489101099Srwatson    struct mbuf *m, struct label *mbuflabel)
1490101099Srwatson{
1491101099Srwatson	struct mac_biba *p, *i;
1492103761Srwatson
1493101099Srwatson	if (!mac_biba_enabled)
1494101099Srwatson		return (0);
1495101099Srwatson
1496101099Srwatson	p = SLOT(mbuflabel);
1497101099Srwatson	i = SLOT(ifnetlabel);
1498103759Srwatson
1499101099Srwatson	return (mac_biba_single_in_range(p, i) ? 0 : EACCES);
1500101099Srwatson}
1501101099Srwatson
1502101099Srwatsonstatic int
1503101099Srwatsonmac_biba_check_mount_stat(struct ucred *cred, struct mount *mp,
1504101099Srwatson    struct label *mntlabel)
1505101099Srwatson{
1506101099Srwatson	struct mac_biba *subj, *obj;
1507101099Srwatson
1508101099Srwatson	if (!mac_biba_enabled)
1509101099Srwatson		return (0);
1510101099Srwatson
1511101099Srwatson	subj = SLOT(&cred->cr_label);
1512101099Srwatson	obj = SLOT(mntlabel);
1513101099Srwatson
1514101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1515101099Srwatson		return (EACCES);
1516101099Srwatson
1517101099Srwatson	return (0);
1518101099Srwatson}
1519101099Srwatson
1520101099Srwatsonstatic int
1521101099Srwatsonmac_biba_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe,
1522101099Srwatson    struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data)
1523101099Srwatson{
1524103759Srwatson
1525101099Srwatson	if(!mac_biba_enabled)
1526101099Srwatson		return (0);
1527101099Srwatson
1528101099Srwatson	/* XXX: This will be implemented soon... */
1529101099Srwatson
1530101099Srwatson	return (0);
1531101099Srwatson}
1532101099Srwatson
1533101099Srwatsonstatic int
1534102115Srwatsonmac_biba_check_pipe_poll(struct ucred *cred, struct pipe *pipe,
1535102115Srwatson    struct label *pipelabel)
1536101099Srwatson{
1537101099Srwatson	struct mac_biba *subj, *obj;
1538101099Srwatson
1539101099Srwatson	if (!mac_biba_enabled)
1540101099Srwatson		return (0);
1541101099Srwatson
1542101099Srwatson	subj = SLOT(&cred->cr_label);
1543101099Srwatson	obj = SLOT((pipelabel));
1544101099Srwatson
1545102115Srwatson	if (!mac_biba_dominate_single(obj, subj))
1546102115Srwatson		return (EACCES);
1547101099Srwatson
1548101099Srwatson	return (0);
1549101099Srwatson}
1550101099Srwatson
1551101099Srwatsonstatic int
1552102115Srwatsonmac_biba_check_pipe_read(struct ucred *cred, struct pipe *pipe,
1553102115Srwatson    struct label *pipelabel)
1554102115Srwatson{
1555102115Srwatson	struct mac_biba *subj, *obj;
1556102115Srwatson
1557102115Srwatson	if (!mac_biba_enabled)
1558102115Srwatson		return (0);
1559102115Srwatson
1560102115Srwatson	subj = SLOT(&cred->cr_label);
1561102115Srwatson	obj = SLOT((pipelabel));
1562102115Srwatson
1563102115Srwatson	if (!mac_biba_dominate_single(obj, subj))
1564102115Srwatson		return (EACCES);
1565102115Srwatson
1566102115Srwatson	return (0);
1567102115Srwatson}
1568102115Srwatson
1569102115Srwatsonstatic int
1570101099Srwatsonmac_biba_check_pipe_relabel(struct ucred *cred, struct pipe *pipe,
1571101099Srwatson    struct label *pipelabel, struct label *newlabel)
1572101099Srwatson{
1573101099Srwatson	struct mac_biba *subj, *obj, *new;
1574105634Srwatson	int error;
1575101099Srwatson
1576101099Srwatson	new = SLOT(newlabel);
1577101099Srwatson	subj = SLOT(&cred->cr_label);
1578101099Srwatson	obj = SLOT(pipelabel);
1579101099Srwatson
1580101099Srwatson	/*
1581105634Srwatson	 * If there is a Biba label update for a pipe, it must be a
1582105634Srwatson	 * single update.
1583101099Srwatson	 */
1584105634Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE);
1585105634Srwatson	if (error)
1586105634Srwatson		return (error);
1587101099Srwatson
1588101099Srwatson	/*
1589105634Srwatson	 * To perform a relabel of a pipe (Biba label or not), Biba must
1590105634Srwatson	 * authorize the relabel.
1591101099Srwatson	 */
1592105634Srwatson	if (!mac_biba_single_in_range(obj, subj))
1593101099Srwatson		return (EPERM);
1594101099Srwatson
1595101099Srwatson	/*
1596105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
1597101099Srwatson	 */
1598105634Srwatson	if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) {
1599105634Srwatson		/*
1600105634Srwatson		 * To change the Biba label on a pipe, the new pipe label
1601105634Srwatson		 * must be in the subject range.
1602105634Srwatson		 */
1603105634Srwatson		if (!mac_biba_single_in_range(new, subj))
1604105634Srwatson			return (EPERM);
1605101099Srwatson
1606105634Srwatson		/*
1607105634Srwatson		 * To change the Biba label on a pipe to be EQUAL, the
1608105634Srwatson		 * subject must have appropriate privilege.
1609105634Srwatson		 */
1610105634Srwatson		if (mac_biba_contains_equal(new)) {
1611105634Srwatson			error = mac_biba_subject_equal_ok(subj);
1612105634Srwatson			if (error)
1613105634Srwatson				return (error);
1614105634Srwatson		}
1615105634Srwatson	}
1616105634Srwatson
1617101099Srwatson	return (0);
1618101099Srwatson}
1619101099Srwatson
1620101099Srwatsonstatic int
1621102115Srwatsonmac_biba_check_pipe_stat(struct ucred *cred, struct pipe *pipe,
1622102115Srwatson    struct label *pipelabel)
1623102115Srwatson{
1624102115Srwatson	struct mac_biba *subj, *obj;
1625102115Srwatson
1626102115Srwatson	if (!mac_biba_enabled)
1627102115Srwatson		return (0);
1628102115Srwatson
1629102115Srwatson	subj = SLOT(&cred->cr_label);
1630102115Srwatson	obj = SLOT((pipelabel));
1631102115Srwatson
1632102115Srwatson	if (!mac_biba_dominate_single(obj, subj))
1633102115Srwatson		return (EACCES);
1634102115Srwatson
1635102115Srwatson	return (0);
1636102115Srwatson}
1637102115Srwatson
1638102115Srwatsonstatic int
1639102115Srwatsonmac_biba_check_pipe_write(struct ucred *cred, struct pipe *pipe,
1640102115Srwatson    struct label *pipelabel)
1641102115Srwatson{
1642102115Srwatson	struct mac_biba *subj, *obj;
1643102115Srwatson
1644102115Srwatson	if (!mac_biba_enabled)
1645102115Srwatson		return (0);
1646102115Srwatson
1647102115Srwatson	subj = SLOT(&cred->cr_label);
1648102115Srwatson	obj = SLOT((pipelabel));
1649102115Srwatson
1650102115Srwatson	if (!mac_biba_dominate_single(subj, obj))
1651102115Srwatson		return (EACCES);
1652102115Srwatson
1653102115Srwatson	return (0);
1654102115Srwatson}
1655102115Srwatson
1656102115Srwatsonstatic int
1657101099Srwatsonmac_biba_check_proc_debug(struct ucred *cred, struct proc *proc)
1658101099Srwatson{
1659101099Srwatson	struct mac_biba *subj, *obj;
1660101099Srwatson
1661101099Srwatson	if (!mac_biba_enabled)
1662101099Srwatson		return (0);
1663101099Srwatson
1664101099Srwatson	subj = SLOT(&cred->cr_label);
1665101099Srwatson	obj = SLOT(&proc->p_ucred->cr_label);
1666101099Srwatson
1667101099Srwatson	/* XXX: range checks */
1668101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1669101099Srwatson		return (ESRCH);
1670101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1671101099Srwatson		return (EACCES);
1672101099Srwatson
1673101099Srwatson	return (0);
1674101099Srwatson}
1675101099Srwatson
1676101099Srwatsonstatic int
1677101099Srwatsonmac_biba_check_proc_sched(struct ucred *cred, struct proc *proc)
1678101099Srwatson{
1679101099Srwatson	struct mac_biba *subj, *obj;
1680103759Srwatson
1681101099Srwatson	if (!mac_biba_enabled)
1682101099Srwatson		return (0);
1683101099Srwatson
1684101099Srwatson	subj = SLOT(&cred->cr_label);
1685101099Srwatson	obj = SLOT(&proc->p_ucred->cr_label);
1686103759Srwatson
1687101099Srwatson	/* XXX: range checks */
1688101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1689101099Srwatson		return (ESRCH);
1690101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1691101099Srwatson		return (EACCES);
1692101099Srwatson
1693101099Srwatson	return (0);
1694101099Srwatson}
1695101099Srwatson
1696101099Srwatsonstatic int
1697101099Srwatsonmac_biba_check_proc_signal(struct ucred *cred, struct proc *proc, int signum)
1698101099Srwatson{
1699101099Srwatson	struct mac_biba *subj, *obj;
1700103759Srwatson
1701101099Srwatson	if (!mac_biba_enabled)
1702101099Srwatson		return (0);
1703101099Srwatson
1704101099Srwatson	subj = SLOT(&cred->cr_label);
1705101099Srwatson	obj = SLOT(&proc->p_ucred->cr_label);
1706103759Srwatson
1707101099Srwatson	/* XXX: range checks */
1708101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1709101099Srwatson		return (ESRCH);
1710101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1711101099Srwatson		return (EACCES);
1712101099Srwatson
1713101099Srwatson	return (0);
1714101099Srwatson}
1715101099Srwatson
1716101099Srwatsonstatic int
1717101934Srwatsonmac_biba_check_socket_deliver(struct socket *so, struct label *socketlabel,
1718101099Srwatson    struct mbuf *m, struct label *mbuflabel)
1719101099Srwatson{
1720101099Srwatson	struct mac_biba *p, *s;
1721101099Srwatson
1722101099Srwatson	if (!mac_biba_enabled)
1723101099Srwatson		return (0);
1724101099Srwatson
1725101099Srwatson	p = SLOT(mbuflabel);
1726101099Srwatson	s = SLOT(socketlabel);
1727101099Srwatson
1728101099Srwatson	return (mac_biba_equal_single(p, s) ? 0 : EACCES);
1729101099Srwatson}
1730101099Srwatson
1731101099Srwatsonstatic int
1732101099Srwatsonmac_biba_check_socket_relabel(struct ucred *cred, struct socket *socket,
1733101099Srwatson    struct label *socketlabel, struct label *newlabel)
1734101099Srwatson{
1735101099Srwatson	struct mac_biba *subj, *obj, *new;
1736105634Srwatson	int error;
1737101099Srwatson
1738101099Srwatson	new = SLOT(newlabel);
1739101099Srwatson	subj = SLOT(&cred->cr_label);
1740101099Srwatson	obj = SLOT(socketlabel);
1741101099Srwatson
1742101099Srwatson	/*
1743105634Srwatson	 * If there is a Biba label update for the socket, it may be
1744105634Srwatson	 * an update of single.
1745101099Srwatson	 */
1746105634Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE);
1747105634Srwatson	if (error)
1748105634Srwatson		return (error);
1749101099Srwatson
1750101099Srwatson	/*
1751105634Srwatson	 * To relabel a socket, the old socket single must be in the subject
1752101099Srwatson	 * range.
1753101099Srwatson	 */
1754105634Srwatson	if (!mac_biba_single_in_range(obj, subj))
1755101099Srwatson		return (EPERM);
1756101099Srwatson
1757101099Srwatson	/*
1758105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
1759101099Srwatson	 */
1760105634Srwatson	if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) {
1761105634Srwatson		/*
1762105634Srwatson		 * To relabel a socket, the new socket single must be in
1763105634Srwatson		 * the subject range.
1764105634Srwatson		 */
1765105634Srwatson		if (!mac_biba_single_in_range(new, subj))
1766105634Srwatson			return (EPERM);
1767101099Srwatson
1768105634Srwatson		/*
1769105634Srwatson		 * To change the Biba label on the socket to contain EQUAL,
1770105634Srwatson		 * the subject must have appropriate privilege.
1771105634Srwatson		 */
1772105634Srwatson		if (mac_biba_contains_equal(new)) {
1773105634Srwatson			error = mac_biba_subject_equal_ok(subj);
1774105634Srwatson			if (error)
1775105634Srwatson				return (error);
1776105634Srwatson		}
1777105634Srwatson	}
1778105634Srwatson
1779101099Srwatson	return (0);
1780101099Srwatson}
1781101099Srwatson
1782101099Srwatsonstatic int
1783101099Srwatsonmac_biba_check_socket_visible(struct ucred *cred, struct socket *socket,
1784101099Srwatson    struct label *socketlabel)
1785101099Srwatson{
1786101099Srwatson	struct mac_biba *subj, *obj;
1787101099Srwatson
1788105722Srwatson	if (!mac_biba_enabled)
1789105722Srwatson		return (0);
1790105722Srwatson
1791101099Srwatson	subj = SLOT(&cred->cr_label);
1792101099Srwatson	obj = SLOT(socketlabel);
1793101099Srwatson
1794101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1795101099Srwatson		return (ENOENT);
1796101099Srwatson
1797101099Srwatson	return (0);
1798101099Srwatson}
1799101099Srwatson
1800101099Srwatsonstatic int
1801101099Srwatsonmac_biba_check_vnode_chdir(struct ucred *cred, struct vnode *dvp,
1802101099Srwatson    struct label *dlabel)
1803101099Srwatson{
1804101099Srwatson	struct mac_biba *subj, *obj;
1805101099Srwatson
1806101099Srwatson	if (!mac_biba_enabled)
1807101099Srwatson		return (0);
1808101099Srwatson
1809101099Srwatson	subj = SLOT(&cred->cr_label);
1810101099Srwatson	obj = SLOT(dlabel);
1811101099Srwatson
1812101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1813101099Srwatson		return (EACCES);
1814101099Srwatson
1815101099Srwatson	return (0);
1816101099Srwatson}
1817101099Srwatson
1818101099Srwatsonstatic int
1819101099Srwatsonmac_biba_check_vnode_chroot(struct ucred *cred, struct vnode *dvp,
1820101099Srwatson    struct label *dlabel)
1821101099Srwatson{
1822101099Srwatson	struct mac_biba *subj, *obj;
1823101099Srwatson
1824101099Srwatson	if (!mac_biba_enabled)
1825101099Srwatson		return (0);
1826101099Srwatson
1827101099Srwatson	subj = SLOT(&cred->cr_label);
1828101099Srwatson	obj = SLOT(dlabel);
1829101099Srwatson
1830101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1831101099Srwatson		return (EACCES);
1832101099Srwatson
1833101099Srwatson	return (0);
1834101099Srwatson}
1835101099Srwatson
1836101099Srwatsonstatic int
1837101099Srwatsonmac_biba_check_vnode_create(struct ucred *cred, struct vnode *dvp,
1838101099Srwatson    struct label *dlabel, struct componentname *cnp, struct vattr *vap)
1839101099Srwatson{
1840101099Srwatson	struct mac_biba *subj, *obj;
1841101099Srwatson
1842101099Srwatson	if (!mac_biba_enabled)
1843101099Srwatson		return (0);
1844101099Srwatson
1845101099Srwatson	subj = SLOT(&cred->cr_label);
1846101099Srwatson	obj = SLOT(dlabel);
1847101099Srwatson
1848101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1849101099Srwatson		return (EACCES);
1850101099Srwatson
1851101099Srwatson	return (0);
1852101099Srwatson}
1853101099Srwatson
1854101099Srwatsonstatic int
1855101099Srwatsonmac_biba_check_vnode_delete(struct ucred *cred, struct vnode *dvp,
1856101099Srwatson    struct label *dlabel, struct vnode *vp, struct label *label,
1857101099Srwatson    struct componentname *cnp)
1858101099Srwatson{
1859101099Srwatson	struct mac_biba *subj, *obj;
1860101099Srwatson
1861101099Srwatson	if (!mac_biba_enabled)
1862101099Srwatson		return (0);
1863101099Srwatson
1864101099Srwatson	subj = SLOT(&cred->cr_label);
1865101099Srwatson	obj = SLOT(dlabel);
1866101099Srwatson
1867101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1868101099Srwatson		return (EACCES);
1869101099Srwatson
1870101099Srwatson	obj = SLOT(label);
1871101099Srwatson
1872101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1873101099Srwatson		return (EACCES);
1874101099Srwatson
1875101099Srwatson	return (0);
1876101099Srwatson}
1877101099Srwatson
1878101099Srwatsonstatic int
1879101099Srwatsonmac_biba_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
1880101099Srwatson    struct label *label, acl_type_t type)
1881101099Srwatson{
1882101099Srwatson	struct mac_biba *subj, *obj;
1883101099Srwatson
1884101099Srwatson	if (!mac_biba_enabled)
1885101099Srwatson		return (0);
1886101099Srwatson
1887101099Srwatson	subj = SLOT(&cred->cr_label);
1888101099Srwatson	obj = SLOT(label);
1889101099Srwatson
1890101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1891101099Srwatson		return (EACCES);
1892101099Srwatson
1893101099Srwatson	return (0);
1894101099Srwatson}
1895101099Srwatson
1896101099Srwatsonstatic int
1897101099Srwatsonmac_biba_check_vnode_exec(struct ucred *cred, struct vnode *vp,
1898101099Srwatson    struct label *label)
1899101099Srwatson{
1900101099Srwatson	struct mac_biba *subj, *obj;
1901101099Srwatson
1902101099Srwatson	if (!mac_biba_enabled)
1903101099Srwatson		return (0);
1904101099Srwatson
1905101099Srwatson	subj = SLOT(&cred->cr_label);
1906101099Srwatson	obj = SLOT(label);
1907101099Srwatson
1908101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1909101099Srwatson		return (EACCES);
1910101099Srwatson
1911101099Srwatson	return (0);
1912101099Srwatson}
1913101099Srwatson
1914101099Srwatsonstatic int
1915101099Srwatsonmac_biba_check_vnode_getacl(struct ucred *cred, struct vnode *vp,
1916101099Srwatson    struct label *label, acl_type_t type)
1917101099Srwatson{
1918101099Srwatson	struct mac_biba *subj, *obj;
1919101099Srwatson
1920101099Srwatson	if (!mac_biba_enabled)
1921101099Srwatson		return (0);
1922101099Srwatson
1923101099Srwatson	subj = SLOT(&cred->cr_label);
1924101099Srwatson	obj = SLOT(label);
1925101099Srwatson
1926101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1927101099Srwatson		return (EACCES);
1928101099Srwatson
1929101099Srwatson	return (0);
1930101099Srwatson}
1931101099Srwatson
1932101099Srwatsonstatic int
1933101099Srwatsonmac_biba_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
1934101099Srwatson    struct label *label, int attrnamespace, const char *name, struct uio *uio)
1935101099Srwatson{
1936101099Srwatson	struct mac_biba *subj, *obj;
1937101099Srwatson
1938101099Srwatson	if (!mac_biba_enabled)
1939101099Srwatson		return (0);
1940101099Srwatson
1941101099Srwatson	subj = SLOT(&cred->cr_label);
1942101099Srwatson	obj = SLOT(label);
1943101099Srwatson
1944101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1945101099Srwatson		return (EACCES);
1946101099Srwatson
1947101099Srwatson	return (0);
1948101099Srwatson}
1949101099Srwatson
1950101099Srwatsonstatic int
1951104530Srwatsonmac_biba_check_vnode_link(struct ucred *cred, struct vnode *dvp,
1952104530Srwatson    struct label *dlabel, struct vnode *vp, struct label *label,
1953104530Srwatson    struct componentname *cnp)
1954104530Srwatson{
1955104530Srwatson	struct mac_biba *subj, *obj;
1956104530Srwatson
1957104530Srwatson	if (!mac_biba_enabled)
1958104530Srwatson		return (0);
1959104530Srwatson
1960104530Srwatson	subj = SLOT(&cred->cr_label);
1961104530Srwatson	obj = SLOT(dlabel);
1962104530Srwatson
1963104530Srwatson	if (!mac_biba_dominate_single(subj, obj))
1964104530Srwatson		return (EACCES);
1965104530Srwatson
1966104530Srwatson	obj = SLOT(label);
1967104530Srwatson
1968104530Srwatson	if (!mac_biba_dominate_single(subj, obj))
1969104530Srwatson		return (EACCES);
1970104530Srwatson
1971104530Srwatson	return (0);
1972104530Srwatson}
1973104530Srwatson
1974104530Srwatsonstatic int
1975103759Srwatsonmac_biba_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
1976101099Srwatson    struct label *dlabel, struct componentname *cnp)
1977101099Srwatson{
1978101099Srwatson	struct mac_biba *subj, *obj;
1979103759Srwatson
1980101099Srwatson	if (!mac_biba_enabled)
1981101099Srwatson		return (0);
1982103759Srwatson
1983101099Srwatson	subj = SLOT(&cred->cr_label);
1984101099Srwatson	obj = SLOT(dlabel);
1985103759Srwatson
1986101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1987101099Srwatson		return (EACCES);
1988101099Srwatson
1989103759Srwatson	return (0);
1990101099Srwatson}
1991101099Srwatson
1992101099Srwatsonstatic int
1993104546Srwatsonmac_biba_check_vnode_mmap(struct ucred *cred, struct vnode *vp,
1994104546Srwatson    struct label *label, int prot)
1995104546Srwatson{
1996104546Srwatson	struct mac_biba *subj, *obj;
1997104546Srwatson
1998104546Srwatson	/*
1999104546Srwatson	 * Rely on the use of open()-time protections to handle
2000104546Srwatson	 * non-revocation cases.
2001104546Srwatson	 */
2002105637Srwatson	if (!mac_biba_enabled || !revocation_enabled)
2003104546Srwatson		return (0);
2004104546Srwatson
2005104546Srwatson	subj = SLOT(&cred->cr_label);
2006104546Srwatson	obj = SLOT(label);
2007104546Srwatson
2008104546Srwatson	if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
2009104546Srwatson		if (!mac_biba_dominate_single(obj, subj))
2010104546Srwatson			return (EACCES);
2011104546Srwatson	}
2012104546Srwatson	if (prot & VM_PROT_WRITE) {
2013104546Srwatson		if (!mac_biba_dominate_single(subj, obj))
2014104546Srwatson			return (EACCES);
2015104546Srwatson	}
2016104546Srwatson
2017104569Srwatson	return (0);
2018104546Srwatson}
2019104546Srwatson
2020104546Srwatsonstatic int
2021101099Srwatsonmac_biba_check_vnode_open(struct ucred *cred, struct vnode *vp,
2022101099Srwatson    struct label *vnodelabel, mode_t acc_mode)
2023101099Srwatson{
2024101099Srwatson	struct mac_biba *subj, *obj;
2025101099Srwatson
2026101099Srwatson	if (!mac_biba_enabled)
2027101099Srwatson		return (0);
2028101099Srwatson
2029101099Srwatson	subj = SLOT(&cred->cr_label);
2030101099Srwatson	obj = SLOT(vnodelabel);
2031101099Srwatson
2032101099Srwatson	/* XXX privilege override for admin? */
2033101099Srwatson	if (acc_mode & (VREAD | VEXEC | VSTAT)) {
2034101099Srwatson		if (!mac_biba_dominate_single(obj, subj))
2035101099Srwatson			return (EACCES);
2036101099Srwatson	}
2037101099Srwatson	if (acc_mode & (VWRITE | VAPPEND | VADMIN)) {
2038101099Srwatson		if (!mac_biba_dominate_single(subj, obj))
2039101099Srwatson			return (EACCES);
2040101099Srwatson	}
2041101099Srwatson
2042101099Srwatson	return (0);
2043101099Srwatson}
2044101099Srwatson
2045101099Srwatsonstatic int
2046102129Srwatsonmac_biba_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred,
2047102129Srwatson    struct vnode *vp, struct label *label)
2048102112Srwatson{
2049102112Srwatson	struct mac_biba *subj, *obj;
2050102112Srwatson
2051105637Srwatson	if (!mac_biba_enabled || !revocation_enabled)
2052102112Srwatson		return (0);
2053102112Srwatson
2054102129Srwatson	subj = SLOT(&active_cred->cr_label);
2055102112Srwatson	obj = SLOT(label);
2056102112Srwatson
2057102112Srwatson	if (!mac_biba_dominate_single(obj, subj))
2058102112Srwatson		return (EACCES);
2059102112Srwatson
2060102112Srwatson	return (0);
2061102112Srwatson}
2062102112Srwatson
2063102112Srwatsonstatic int
2064102129Srwatsonmac_biba_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
2065102129Srwatson    struct vnode *vp, struct label *label)
2066102112Srwatson{
2067102112Srwatson	struct mac_biba *subj, *obj;
2068102112Srwatson
2069105637Srwatson	if (!mac_biba_enabled || !revocation_enabled)
2070102112Srwatson		return (0);
2071102112Srwatson
2072102129Srwatson	subj = SLOT(&active_cred->cr_label);
2073102112Srwatson	obj = SLOT(label);
2074102112Srwatson
2075102112Srwatson	if (!mac_biba_dominate_single(obj, subj))
2076102112Srwatson		return (EACCES);
2077102112Srwatson
2078102112Srwatson	return (0);
2079102112Srwatson}
2080102112Srwatson
2081102112Srwatsonstatic int
2082101099Srwatsonmac_biba_check_vnode_readdir(struct ucred *cred, struct vnode *dvp,
2083101099Srwatson    struct label *dlabel)
2084101099Srwatson{
2085101099Srwatson	struct mac_biba *subj, *obj;
2086101099Srwatson
2087101099Srwatson	if (!mac_biba_enabled)
2088101099Srwatson		return (0);
2089101099Srwatson
2090101099Srwatson	subj = SLOT(&cred->cr_label);
2091101099Srwatson	obj = SLOT(dlabel);
2092101099Srwatson
2093101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
2094101099Srwatson		return (EACCES);
2095101099Srwatson
2096101099Srwatson	return (0);
2097101099Srwatson}
2098101099Srwatson
2099101099Srwatsonstatic int
2100101099Srwatsonmac_biba_check_vnode_readlink(struct ucred *cred, struct vnode *vp,
2101101099Srwatson    struct label *label)
2102101099Srwatson{
2103101099Srwatson	struct mac_biba *subj, *obj;
2104101099Srwatson
2105101099Srwatson	if (!mac_biba_enabled)
2106101099Srwatson		return (0);
2107101099Srwatson
2108101099Srwatson	subj = SLOT(&cred->cr_label);
2109101099Srwatson	obj = SLOT(label);
2110101099Srwatson
2111101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
2112101099Srwatson		return (EACCES);
2113101099Srwatson
2114101099Srwatson	return (0);
2115101099Srwatson}
2116101099Srwatson
2117101099Srwatsonstatic int
2118101099Srwatsonmac_biba_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
2119101099Srwatson    struct label *vnodelabel, struct label *newlabel)
2120101099Srwatson{
2121101099Srwatson	struct mac_biba *old, *new, *subj;
2122105634Srwatson	int error;
2123101099Srwatson
2124101099Srwatson	old = SLOT(vnodelabel);
2125101099Srwatson	new = SLOT(newlabel);
2126101099Srwatson	subj = SLOT(&cred->cr_label);
2127101099Srwatson
2128101099Srwatson	/*
2129105634Srwatson	 * If there is a Biba label update for the vnode, it must be a
2130105634Srwatson	 * single label.
2131101099Srwatson	 */
2132105634Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE);
2133105634Srwatson	if (error)
2134105634Srwatson		return (error);
2135101099Srwatson
2136101099Srwatson	/*
2137105634Srwatson	 * To perform a relabel of the vnode (Biba label or not), Biba must
2138105634Srwatson	 * authorize the relabel.
2139101099Srwatson	 */
2140105634Srwatson	if (!mac_biba_single_in_range(old, subj))
2141101099Srwatson		return (EPERM);
2142101099Srwatson
2143101099Srwatson	/*
2144105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
2145101099Srwatson	 */
2146105634Srwatson	if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) {
2147105634Srwatson		/*
2148105634Srwatson		 * To change the Biba label on a vnode, the new vnode label
2149105634Srwatson		 * must be in the subject range.
2150105634Srwatson		 */
2151105634Srwatson		if (!mac_biba_single_in_range(new, subj))
2152105634Srwatson			return (EPERM);
2153101099Srwatson
2154105634Srwatson		/*
2155105634Srwatson		 * To change the Biba label on the vnode to be EQUAL,
2156105634Srwatson		 * the subject must have appropriate privilege.
2157105634Srwatson		 */
2158105634Srwatson		if (mac_biba_contains_equal(new)) {
2159105634Srwatson			error = mac_biba_subject_equal_ok(subj);
2160105634Srwatson			if (error)
2161105634Srwatson				return (error);
2162105634Srwatson		}
2163105634Srwatson	}
2164105634Srwatson
2165105634Srwatson	return (0);
2166101099Srwatson}
2167101099Srwatson
2168101099Srwatsonstatic int
2169101099Srwatsonmac_biba_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
2170101099Srwatson    struct label *dlabel, struct vnode *vp, struct label *label,
2171101099Srwatson    struct componentname *cnp)
2172101099Srwatson{
2173101099Srwatson	struct mac_biba *subj, *obj;
2174101099Srwatson
2175101099Srwatson	if (!mac_biba_enabled)
2176101099Srwatson		return (0);
2177101099Srwatson
2178101099Srwatson	subj = SLOT(&cred->cr_label);
2179101099Srwatson	obj = SLOT(dlabel);
2180101099Srwatson
2181101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2182101099Srwatson		return (EACCES);
2183101099Srwatson
2184101099Srwatson	obj = SLOT(label);
2185101099Srwatson
2186101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2187101099Srwatson		return (EACCES);
2188101099Srwatson
2189101099Srwatson	return (0);
2190101099Srwatson}
2191101099Srwatson
2192101099Srwatsonstatic int
2193101099Srwatsonmac_biba_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
2194101099Srwatson    struct label *dlabel, struct vnode *vp, struct label *label, int samedir,
2195101099Srwatson    struct componentname *cnp)
2196101099Srwatson{
2197101099Srwatson	struct mac_biba *subj, *obj;
2198101099Srwatson
2199101099Srwatson	if (!mac_biba_enabled)
2200101099Srwatson		return (0);
2201101099Srwatson
2202101099Srwatson	subj = SLOT(&cred->cr_label);
2203101099Srwatson	obj = SLOT(dlabel);
2204101099Srwatson
2205101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2206101099Srwatson		return (EACCES);
2207101099Srwatson
2208101099Srwatson	if (vp != NULL) {
2209101099Srwatson		obj = SLOT(label);
2210101099Srwatson
2211101099Srwatson		if (!mac_biba_dominate_single(subj, obj))
2212101099Srwatson			return (EACCES);
2213101099Srwatson	}
2214101099Srwatson
2215101099Srwatson	return (0);
2216101099Srwatson}
2217101099Srwatson
2218101099Srwatsonstatic int
2219101099Srwatsonmac_biba_check_vnode_revoke(struct ucred *cred, struct vnode *vp,
2220101099Srwatson    struct label *label)
2221101099Srwatson{
2222101099Srwatson	struct mac_biba *subj, *obj;
2223101099Srwatson
2224101099Srwatson	if (!mac_biba_enabled)
2225101099Srwatson		return (0);
2226101099Srwatson
2227101099Srwatson	subj = SLOT(&cred->cr_label);
2228101099Srwatson	obj = SLOT(label);
2229101099Srwatson
2230101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2231101099Srwatson		return (EACCES);
2232101099Srwatson
2233101099Srwatson	return (0);
2234101099Srwatson}
2235101099Srwatson
2236101099Srwatsonstatic int
2237101099Srwatsonmac_biba_check_vnode_setacl(struct ucred *cred, struct vnode *vp,
2238101099Srwatson    struct label *label, acl_type_t type, struct acl *acl)
2239101099Srwatson{
2240101099Srwatson	struct mac_biba *subj, *obj;
2241101099Srwatson
2242101099Srwatson	if (!mac_biba_enabled)
2243101099Srwatson		return (0);
2244101099Srwatson
2245101099Srwatson	subj = SLOT(&cred->cr_label);
2246101099Srwatson	obj = SLOT(label);
2247101099Srwatson
2248101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2249101099Srwatson		return (EACCES);
2250101099Srwatson
2251101099Srwatson	return (0);
2252101099Srwatson}
2253101099Srwatson
2254101099Srwatsonstatic int
2255101099Srwatsonmac_biba_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
2256101099Srwatson    struct label *vnodelabel, int attrnamespace, const char *name,
2257101099Srwatson    struct uio *uio)
2258101099Srwatson{
2259101099Srwatson	struct mac_biba *subj, *obj;
2260101099Srwatson
2261101099Srwatson	if (!mac_biba_enabled)
2262101099Srwatson		return (0);
2263101099Srwatson
2264101099Srwatson	subj = SLOT(&cred->cr_label);
2265101099Srwatson	obj = SLOT(vnodelabel);
2266101099Srwatson
2267101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2268101099Srwatson		return (EACCES);
2269101099Srwatson
2270101099Srwatson	/* XXX: protect the MAC EA in a special way? */
2271101099Srwatson
2272101099Srwatson	return (0);
2273101099Srwatson}
2274101099Srwatson
2275101099Srwatsonstatic int
2276101099Srwatsonmac_biba_check_vnode_setflags(struct ucred *cred, struct vnode *vp,
2277101099Srwatson    struct label *vnodelabel, u_long flags)
2278101099Srwatson{
2279101099Srwatson	struct mac_biba *subj, *obj;
2280101099Srwatson
2281101099Srwatson	if (!mac_biba_enabled)
2282101099Srwatson		return (0);
2283101099Srwatson
2284101099Srwatson	subj = SLOT(&cred->cr_label);
2285101099Srwatson	obj = SLOT(vnodelabel);
2286101099Srwatson
2287101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2288101099Srwatson		return (EACCES);
2289101099Srwatson
2290101099Srwatson	return (0);
2291101099Srwatson}
2292101099Srwatson
2293101099Srwatsonstatic int
2294101099Srwatsonmac_biba_check_vnode_setmode(struct ucred *cred, struct vnode *vp,
2295101099Srwatson    struct label *vnodelabel, mode_t mode)
2296101099Srwatson{
2297101099Srwatson	struct mac_biba *subj, *obj;
2298101099Srwatson
2299101099Srwatson	if (!mac_biba_enabled)
2300101099Srwatson		return (0);
2301101099Srwatson
2302101099Srwatson	subj = SLOT(&cred->cr_label);
2303101099Srwatson	obj = SLOT(vnodelabel);
2304101099Srwatson
2305101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2306101099Srwatson		return (EACCES);
2307101099Srwatson
2308101099Srwatson	return (0);
2309101099Srwatson}
2310101099Srwatson
2311101099Srwatsonstatic int
2312101099Srwatsonmac_biba_check_vnode_setowner(struct ucred *cred, struct vnode *vp,
2313101099Srwatson    struct label *vnodelabel, uid_t uid, gid_t gid)
2314101099Srwatson{
2315101099Srwatson	struct mac_biba *subj, *obj;
2316101099Srwatson
2317101099Srwatson	if (!mac_biba_enabled)
2318101099Srwatson		return (0);
2319101099Srwatson
2320101099Srwatson	subj = SLOT(&cred->cr_label);
2321101099Srwatson	obj = SLOT(vnodelabel);
2322101099Srwatson
2323101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2324101099Srwatson		return (EACCES);
2325101099Srwatson
2326101099Srwatson	return (0);
2327101099Srwatson}
2328101099Srwatson
2329101099Srwatsonstatic int
2330101099Srwatsonmac_biba_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
2331101099Srwatson    struct label *vnodelabel, struct timespec atime, struct timespec mtime)
2332101099Srwatson{
2333101099Srwatson	struct mac_biba *subj, *obj;
2334101099Srwatson
2335101099Srwatson	if (!mac_biba_enabled)
2336101099Srwatson		return (0);
2337101099Srwatson
2338101099Srwatson	subj = SLOT(&cred->cr_label);
2339101099Srwatson	obj = SLOT(vnodelabel);
2340101099Srwatson
2341101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2342101099Srwatson		return (EACCES);
2343101099Srwatson
2344101099Srwatson	return (0);
2345101099Srwatson}
2346101099Srwatson
2347101099Srwatsonstatic int
2348102129Srwatsonmac_biba_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
2349102129Srwatson    struct vnode *vp, struct label *vnodelabel)
2350101099Srwatson{
2351101099Srwatson	struct mac_biba *subj, *obj;
2352101099Srwatson
2353101099Srwatson	if (!mac_biba_enabled)
2354101099Srwatson		return (0);
2355101099Srwatson
2356102129Srwatson	subj = SLOT(&active_cred->cr_label);
2357101099Srwatson	obj = SLOT(vnodelabel);
2358101099Srwatson
2359101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
2360101099Srwatson		return (EACCES);
2361101099Srwatson
2362101099Srwatson	return (0);
2363101099Srwatson}
2364101099Srwatson
2365102112Srwatsonstatic int
2366102129Srwatsonmac_biba_check_vnode_write(struct ucred *active_cred,
2367102129Srwatson    struct ucred *file_cred, struct vnode *vp, struct label *label)
2368102112Srwatson{
2369102112Srwatson	struct mac_biba *subj, *obj;
2370102112Srwatson
2371105637Srwatson	if (!mac_biba_enabled || !revocation_enabled)
2372102112Srwatson		return (0);
2373102112Srwatson
2374102129Srwatson	subj = SLOT(&active_cred->cr_label);
2375102112Srwatson	obj = SLOT(label);
2376102112Srwatson
2377102112Srwatson	if (!mac_biba_dominate_single(subj, obj))
2378102112Srwatson		return (EACCES);
2379102112Srwatson
2380102112Srwatson	return (0);
2381102112Srwatson}
2382102112Srwatson
2383101099Srwatsonstatic struct mac_policy_op_entry mac_biba_ops[] =
2384101099Srwatson{
2385101099Srwatson	{ MAC_DESTROY,
2386101099Srwatson	    (macop_t)mac_biba_destroy },
2387101099Srwatson	{ MAC_INIT,
2388101099Srwatson	    (macop_t)mac_biba_init },
2389104514Srwatson	{ MAC_INIT_BPFDESC_LABEL,
2390104514Srwatson	    (macop_t)mac_biba_init_label },
2391104514Srwatson	{ MAC_INIT_CRED_LABEL,
2392104514Srwatson	    (macop_t)mac_biba_init_label },
2393104514Srwatson	{ MAC_INIT_DEVFSDIRENT_LABEL,
2394104514Srwatson	    (macop_t)mac_biba_init_label },
2395104514Srwatson	{ MAC_INIT_IFNET_LABEL,
2396104514Srwatson	    (macop_t)mac_biba_init_label },
2397104514Srwatson	{ MAC_INIT_IPQ_LABEL,
2398104514Srwatson	    (macop_t)mac_biba_init_label },
2399104514Srwatson	{ MAC_INIT_MBUF_LABEL,
2400104514Srwatson	    (macop_t)mac_biba_init_label_waitcheck },
2401104514Srwatson	{ MAC_INIT_MOUNT_LABEL,
2402104514Srwatson	    (macop_t)mac_biba_init_label },
2403104514Srwatson	{ MAC_INIT_MOUNT_FS_LABEL,
2404104514Srwatson	    (macop_t)mac_biba_init_label },
2405104514Srwatson	{ MAC_INIT_PIPE_LABEL,
2406104514Srwatson	    (macop_t)mac_biba_init_label },
2407104514Srwatson	{ MAC_INIT_SOCKET_LABEL,
2408104541Srwatson	    (macop_t)mac_biba_init_label_waitcheck },
2409104514Srwatson	{ MAC_INIT_SOCKET_PEER_LABEL,
2410104541Srwatson	    (macop_t)mac_biba_init_label_waitcheck },
2411104514Srwatson	{ MAC_INIT_VNODE_LABEL,
2412104514Srwatson	    (macop_t)mac_biba_init_label },
2413104514Srwatson	{ MAC_DESTROY_BPFDESC_LABEL,
2414104514Srwatson	    (macop_t)mac_biba_destroy_label },
2415104514Srwatson	{ MAC_DESTROY_CRED_LABEL,
2416104514Srwatson	    (macop_t)mac_biba_destroy_label },
2417104514Srwatson	{ MAC_DESTROY_DEVFSDIRENT_LABEL,
2418104514Srwatson	    (macop_t)mac_biba_destroy_label },
2419104514Srwatson	{ MAC_DESTROY_IFNET_LABEL,
2420104514Srwatson	    (macop_t)mac_biba_destroy_label },
2421104514Srwatson	{ MAC_DESTROY_IPQ_LABEL,
2422104514Srwatson	    (macop_t)mac_biba_destroy_label },
2423104514Srwatson	{ MAC_DESTROY_MBUF_LABEL,
2424104514Srwatson	    (macop_t)mac_biba_destroy_label },
2425104514Srwatson	{ MAC_DESTROY_MOUNT_LABEL,
2426104514Srwatson	    (macop_t)mac_biba_destroy_label },
2427104514Srwatson	{ MAC_DESTROY_MOUNT_FS_LABEL,
2428104514Srwatson	    (macop_t)mac_biba_destroy_label },
2429104514Srwatson	{ MAC_DESTROY_PIPE_LABEL,
2430104514Srwatson	    (macop_t)mac_biba_destroy_label },
2431104514Srwatson	{ MAC_DESTROY_SOCKET_LABEL,
2432104514Srwatson	    (macop_t)mac_biba_destroy_label },
2433104514Srwatson	{ MAC_DESTROY_SOCKET_PEER_LABEL,
2434104514Srwatson	    (macop_t)mac_biba_destroy_label },
2435104514Srwatson	{ MAC_DESTROY_VNODE_LABEL,
2436104514Srwatson	    (macop_t)mac_biba_destroy_label },
2437105696Srwatson	{ MAC_COPY_PIPE_LABEL,
2438105696Srwatson	    (macop_t)mac_biba_copy_label },
2439105696Srwatson	{ MAC_COPY_VNODE_LABEL,
2440105696Srwatson	    (macop_t)mac_biba_copy_label },
2441105696Srwatson	{ MAC_EXTERNALIZE_CRED_LABEL,
2442105696Srwatson	    (macop_t)mac_biba_externalize_label },
2443105696Srwatson	{ MAC_EXTERNALIZE_IFNET_LABEL,
2444105696Srwatson	    (macop_t)mac_biba_externalize_label },
2445105696Srwatson	{ MAC_EXTERNALIZE_PIPE_LABEL,
2446105696Srwatson	    (macop_t)mac_biba_externalize_label },
2447105696Srwatson	{ MAC_EXTERNALIZE_SOCKET_LABEL,
2448105696Srwatson	    (macop_t)mac_biba_externalize_label },
2449105696Srwatson	{ MAC_EXTERNALIZE_SOCKET_PEER_LABEL,
2450105696Srwatson	    (macop_t)mac_biba_externalize_label },
2451105696Srwatson	{ MAC_EXTERNALIZE_VNODE_LABEL,
2452105696Srwatson	    (macop_t)mac_biba_externalize_label },
2453105696Srwatson	{ MAC_EXTERNALIZE_VNODE_OLDMAC,
2454105696Srwatson	    (macop_t)mac_biba_externalize_vnode_oldmac },
2455105696Srwatson	{ MAC_INTERNALIZE_CRED_LABEL,
2456105696Srwatson	    (macop_t)mac_biba_internalize_label },
2457105696Srwatson	{ MAC_INTERNALIZE_IFNET_LABEL,
2458105696Srwatson	    (macop_t)mac_biba_internalize_label },
2459105696Srwatson	{ MAC_INTERNALIZE_PIPE_LABEL,
2460105696Srwatson	    (macop_t)mac_biba_internalize_label },
2461105696Srwatson	{ MAC_INTERNALIZE_SOCKET_LABEL,
2462105696Srwatson	    (macop_t)mac_biba_internalize_label },
2463105696Srwatson	{ MAC_INTERNALIZE_VNODE_LABEL,
2464105696Srwatson	    (macop_t)mac_biba_internalize_label },
2465101099Srwatson	{ MAC_CREATE_DEVFS_DEVICE,
2466101099Srwatson	    (macop_t)mac_biba_create_devfs_device },
2467101099Srwatson	{ MAC_CREATE_DEVFS_DIRECTORY,
2468101099Srwatson	    (macop_t)mac_biba_create_devfs_directory },
2469104535Srwatson	{ MAC_CREATE_DEVFS_SYMLINK,
2470104535Srwatson	    (macop_t)mac_biba_create_devfs_symlink },
2471101099Srwatson	{ MAC_CREATE_DEVFS_VNODE,
2472101099Srwatson	    (macop_t)mac_biba_create_devfs_vnode },
2473101099Srwatson	{ MAC_CREATE_VNODE,
2474101099Srwatson	    (macop_t)mac_biba_create_vnode },
2475101099Srwatson	{ MAC_CREATE_MOUNT,
2476101099Srwatson	    (macop_t)mac_biba_create_mount },
2477101099Srwatson	{ MAC_CREATE_ROOT_MOUNT,
2478101099Srwatson	    (macop_t)mac_biba_create_root_mount },
2479101099Srwatson	{ MAC_RELABEL_VNODE,
2480101099Srwatson	    (macop_t)mac_biba_relabel_vnode },
2481101099Srwatson	{ MAC_UPDATE_DEVFSDIRENT,
2482101099Srwatson	    (macop_t)mac_biba_update_devfsdirent },
2483101099Srwatson	{ MAC_UPDATE_PROCFSVNODE,
2484101099Srwatson	    (macop_t)mac_biba_update_procfsvnode },
2485101099Srwatson	{ MAC_UPDATE_VNODE_FROM_EXTERNALIZED,
2486101099Srwatson	    (macop_t)mac_biba_update_vnode_from_externalized },
2487101099Srwatson	{ MAC_UPDATE_VNODE_FROM_MOUNT,
2488101099Srwatson	    (macop_t)mac_biba_update_vnode_from_mount },
2489101099Srwatson	{ MAC_CREATE_MBUF_FROM_SOCKET,
2490101099Srwatson	    (macop_t)mac_biba_create_mbuf_from_socket },
2491101099Srwatson	{ MAC_CREATE_PIPE,
2492101099Srwatson	    (macop_t)mac_biba_create_pipe },
2493101099Srwatson	{ MAC_CREATE_SOCKET,
2494101099Srwatson	    (macop_t)mac_biba_create_socket },
2495101099Srwatson	{ MAC_CREATE_SOCKET_FROM_SOCKET,
2496101099Srwatson	    (macop_t)mac_biba_create_socket_from_socket },
2497101099Srwatson	{ MAC_RELABEL_PIPE,
2498101099Srwatson	    (macop_t)mac_biba_relabel_pipe },
2499101099Srwatson	{ MAC_RELABEL_SOCKET,
2500101099Srwatson	    (macop_t)mac_biba_relabel_socket },
2501101099Srwatson	{ MAC_SET_SOCKET_PEER_FROM_MBUF,
2502101099Srwatson	    (macop_t)mac_biba_set_socket_peer_from_mbuf },
2503101099Srwatson	{ MAC_SET_SOCKET_PEER_FROM_SOCKET,
2504101099Srwatson	    (macop_t)mac_biba_set_socket_peer_from_socket },
2505101099Srwatson	{ MAC_CREATE_BPFDESC,
2506101099Srwatson	    (macop_t)mac_biba_create_bpfdesc },
2507101099Srwatson	{ MAC_CREATE_DATAGRAM_FROM_IPQ,
2508101099Srwatson	    (macop_t)mac_biba_create_datagram_from_ipq },
2509101099Srwatson	{ MAC_CREATE_FRAGMENT,
2510101099Srwatson	    (macop_t)mac_biba_create_fragment },
2511101099Srwatson	{ MAC_CREATE_IFNET,
2512101099Srwatson	    (macop_t)mac_biba_create_ifnet },
2513101099Srwatson	{ MAC_CREATE_IPQ,
2514101099Srwatson	    (macop_t)mac_biba_create_ipq },
2515101099Srwatson	{ MAC_CREATE_MBUF_FROM_MBUF,
2516101099Srwatson	    (macop_t)mac_biba_create_mbuf_from_mbuf },
2517101099Srwatson	{ MAC_CREATE_MBUF_LINKLAYER,
2518101099Srwatson	    (macop_t)mac_biba_create_mbuf_linklayer },
2519101099Srwatson	{ MAC_CREATE_MBUF_FROM_BPFDESC,
2520101099Srwatson	    (macop_t)mac_biba_create_mbuf_from_bpfdesc },
2521101099Srwatson	{ MAC_CREATE_MBUF_FROM_IFNET,
2522101099Srwatson	    (macop_t)mac_biba_create_mbuf_from_ifnet },
2523101099Srwatson	{ MAC_CREATE_MBUF_MULTICAST_ENCAP,
2524101099Srwatson	    (macop_t)mac_biba_create_mbuf_multicast_encap },
2525101099Srwatson	{ MAC_CREATE_MBUF_NETLAYER,
2526101099Srwatson	    (macop_t)mac_biba_create_mbuf_netlayer },
2527101099Srwatson	{ MAC_FRAGMENT_MATCH,
2528101099Srwatson	    (macop_t)mac_biba_fragment_match },
2529101099Srwatson	{ MAC_RELABEL_IFNET,
2530101099Srwatson	    (macop_t)mac_biba_relabel_ifnet },
2531101099Srwatson	{ MAC_UPDATE_IPQ,
2532101099Srwatson	    (macop_t)mac_biba_update_ipq },
2533101099Srwatson	{ MAC_CREATE_CRED,
2534101099Srwatson	    (macop_t)mac_biba_create_cred },
2535101099Srwatson	{ MAC_EXECVE_TRANSITION,
2536101099Srwatson	    (macop_t)mac_biba_execve_transition },
2537101099Srwatson	{ MAC_EXECVE_WILL_TRANSITION,
2538101099Srwatson	    (macop_t)mac_biba_execve_will_transition },
2539101099Srwatson	{ MAC_CREATE_PROC0,
2540101099Srwatson	    (macop_t)mac_biba_create_proc0 },
2541101099Srwatson	{ MAC_CREATE_PROC1,
2542101099Srwatson	    (macop_t)mac_biba_create_proc1 },
2543101099Srwatson	{ MAC_RELABEL_CRED,
2544101099Srwatson	    (macop_t)mac_biba_relabel_cred },
2545101099Srwatson	{ MAC_CHECK_BPFDESC_RECEIVE,
2546101099Srwatson	    (macop_t)mac_biba_check_bpfdesc_receive },
2547101099Srwatson	{ MAC_CHECK_CRED_RELABEL,
2548101099Srwatson	    (macop_t)mac_biba_check_cred_relabel },
2549101099Srwatson	{ MAC_CHECK_CRED_VISIBLE,
2550101099Srwatson	    (macop_t)mac_biba_check_cred_visible },
2551101099Srwatson	{ MAC_CHECK_IFNET_RELABEL,
2552101099Srwatson	    (macop_t)mac_biba_check_ifnet_relabel },
2553101099Srwatson	{ MAC_CHECK_IFNET_TRANSMIT,
2554101099Srwatson	    (macop_t)mac_biba_check_ifnet_transmit },
2555101099Srwatson	{ MAC_CHECK_MOUNT_STAT,
2556101099Srwatson	    (macop_t)mac_biba_check_mount_stat },
2557101099Srwatson	{ MAC_CHECK_PIPE_IOCTL,
2558101099Srwatson	    (macop_t)mac_biba_check_pipe_ioctl },
2559102115Srwatson	{ MAC_CHECK_PIPE_POLL,
2560102115Srwatson	    (macop_t)mac_biba_check_pipe_poll },
2561102115Srwatson	{ MAC_CHECK_PIPE_READ,
2562102115Srwatson	    (macop_t)mac_biba_check_pipe_read },
2563101099Srwatson	{ MAC_CHECK_PIPE_RELABEL,
2564101099Srwatson	    (macop_t)mac_biba_check_pipe_relabel },
2565102115Srwatson	{ MAC_CHECK_PIPE_STAT,
2566102115Srwatson	    (macop_t)mac_biba_check_pipe_stat },
2567102115Srwatson	{ MAC_CHECK_PIPE_WRITE,
2568102115Srwatson	    (macop_t)mac_biba_check_pipe_write },
2569101099Srwatson	{ MAC_CHECK_PROC_DEBUG,
2570101099Srwatson	    (macop_t)mac_biba_check_proc_debug },
2571101099Srwatson	{ MAC_CHECK_PROC_SCHED,
2572101099Srwatson	    (macop_t)mac_biba_check_proc_sched },
2573101099Srwatson	{ MAC_CHECK_PROC_SIGNAL,
2574101099Srwatson	    (macop_t)mac_biba_check_proc_signal },
2575101934Srwatson	{ MAC_CHECK_SOCKET_DELIVER,
2576101934Srwatson	    (macop_t)mac_biba_check_socket_deliver },
2577101099Srwatson	{ MAC_CHECK_SOCKET_RELABEL,
2578101099Srwatson	    (macop_t)mac_biba_check_socket_relabel },
2579101099Srwatson	{ MAC_CHECK_SOCKET_VISIBLE,
2580101099Srwatson	    (macop_t)mac_biba_check_socket_visible },
2581101099Srwatson	{ MAC_CHECK_VNODE_ACCESS,
2582105635Srwatson	    (macop_t)mac_biba_check_vnode_open },
2583101099Srwatson	{ MAC_CHECK_VNODE_CHDIR,
2584101099Srwatson	    (macop_t)mac_biba_check_vnode_chdir },
2585101099Srwatson	{ MAC_CHECK_VNODE_CHROOT,
2586101099Srwatson	    (macop_t)mac_biba_check_vnode_chroot },
2587101099Srwatson	{ MAC_CHECK_VNODE_CREATE,
2588101099Srwatson	    (macop_t)mac_biba_check_vnode_create },
2589101099Srwatson	{ MAC_CHECK_VNODE_DELETE,
2590101099Srwatson	    (macop_t)mac_biba_check_vnode_delete },
2591101099Srwatson	{ MAC_CHECK_VNODE_DELETEACL,
2592101099Srwatson	    (macop_t)mac_biba_check_vnode_deleteacl },
2593101099Srwatson	{ MAC_CHECK_VNODE_EXEC,
2594101099Srwatson	    (macop_t)mac_biba_check_vnode_exec },
2595101099Srwatson	{ MAC_CHECK_VNODE_GETACL,
2596101099Srwatson	    (macop_t)mac_biba_check_vnode_getacl },
2597101099Srwatson	{ MAC_CHECK_VNODE_GETEXTATTR,
2598101099Srwatson	    (macop_t)mac_biba_check_vnode_getextattr },
2599104530Srwatson	{ MAC_CHECK_VNODE_LINK,
2600104530Srwatson	    (macop_t)mac_biba_check_vnode_link },
2601101099Srwatson	{ MAC_CHECK_VNODE_LOOKUP,
2602101099Srwatson	    (macop_t)mac_biba_check_vnode_lookup },
2603104546Srwatson	{ MAC_CHECK_VNODE_MMAP,
2604104546Srwatson	    (macop_t)mac_biba_check_vnode_mmap },
2605104546Srwatson	{ MAC_CHECK_VNODE_MPROTECT,
2606104546Srwatson	    (macop_t)mac_biba_check_vnode_mmap },
2607101099Srwatson	{ MAC_CHECK_VNODE_OPEN,
2608101099Srwatson	    (macop_t)mac_biba_check_vnode_open },
2609102112Srwatson	{ MAC_CHECK_VNODE_POLL,
2610102112Srwatson	    (macop_t)mac_biba_check_vnode_poll },
2611102112Srwatson	{ MAC_CHECK_VNODE_READ,
2612102112Srwatson	    (macop_t)mac_biba_check_vnode_read },
2613101099Srwatson	{ MAC_CHECK_VNODE_READDIR,
2614101099Srwatson	    (macop_t)mac_biba_check_vnode_readdir },
2615101099Srwatson	{ MAC_CHECK_VNODE_READLINK,
2616101099Srwatson	    (macop_t)mac_biba_check_vnode_readlink },
2617101099Srwatson	{ MAC_CHECK_VNODE_RELABEL,
2618101099Srwatson	    (macop_t)mac_biba_check_vnode_relabel },
2619101099Srwatson	{ MAC_CHECK_VNODE_RENAME_FROM,
2620101099Srwatson	    (macop_t)mac_biba_check_vnode_rename_from },
2621101099Srwatson	{ MAC_CHECK_VNODE_RENAME_TO,
2622101099Srwatson	    (macop_t)mac_biba_check_vnode_rename_to },
2623101099Srwatson	{ MAC_CHECK_VNODE_REVOKE,
2624101099Srwatson	    (macop_t)mac_biba_check_vnode_revoke },
2625101099Srwatson	{ MAC_CHECK_VNODE_SETACL,
2626101099Srwatson	    (macop_t)mac_biba_check_vnode_setacl },
2627101099Srwatson	{ MAC_CHECK_VNODE_SETEXTATTR,
2628101099Srwatson	    (macop_t)mac_biba_check_vnode_setextattr },
2629101099Srwatson	{ MAC_CHECK_VNODE_SETFLAGS,
2630101099Srwatson	    (macop_t)mac_biba_check_vnode_setflags },
2631101099Srwatson	{ MAC_CHECK_VNODE_SETMODE,
2632101099Srwatson	    (macop_t)mac_biba_check_vnode_setmode },
2633101099Srwatson	{ MAC_CHECK_VNODE_SETOWNER,
2634101099Srwatson	    (macop_t)mac_biba_check_vnode_setowner },
2635101099Srwatson	{ MAC_CHECK_VNODE_SETUTIMES,
2636101099Srwatson	    (macop_t)mac_biba_check_vnode_setutimes },
2637101099Srwatson	{ MAC_CHECK_VNODE_STAT,
2638101099Srwatson	    (macop_t)mac_biba_check_vnode_stat },
2639102112Srwatson	{ MAC_CHECK_VNODE_WRITE,
2640102112Srwatson	    (macop_t)mac_biba_check_vnode_write },
2641101099Srwatson	{ MAC_OP_LAST, NULL }
2642101099Srwatson};
2643101099Srwatson
2644101099SrwatsonMAC_POLICY_SET(mac_biba_ops, trustedbsd_mac_biba, "TrustedBSD MAC/Biba",
2645101099Srwatson    MPC_LOADTIME_FLAG_NOTLATE, &mac_biba_slot);
2646