mac_biba.c revision 106090
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 106090 2002-10-28 19:17:39Z 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>
49105988Srwatson#include <sys/extattr.h>
50101099Srwatson#include <sys/kernel.h>
51101099Srwatson#include <sys/mac.h>
52103183Sbde#include <sys/malloc.h>
53101099Srwatson#include <sys/mount.h>
54101099Srwatson#include <sys/proc.h>
55101099Srwatson#include <sys/systm.h>
56101099Srwatson#include <sys/sysproto.h>
57101099Srwatson#include <sys/sysent.h>
58105696Srwatson#include <sys/systm.h>
59101099Srwatson#include <sys/vnode.h>
60101099Srwatson#include <sys/file.h>
61101099Srwatson#include <sys/socket.h>
62101099Srwatson#include <sys/socketvar.h>
63101099Srwatson#include <sys/pipe.h>
64101099Srwatson#include <sys/sysctl.h>
65101099Srwatson
66101099Srwatson#include <fs/devfs/devfs.h>
67101099Srwatson
68101099Srwatson#include <net/bpfdesc.h>
69101099Srwatson#include <net/if.h>
70101099Srwatson#include <net/if_types.h>
71101099Srwatson#include <net/if_var.h>
72101099Srwatson
73101099Srwatson#include <netinet/in.h>
74101099Srwatson#include <netinet/ip_var.h>
75101099Srwatson
76101099Srwatson#include <vm/vm.h>
77101099Srwatson
78101099Srwatson#include <sys/mac_policy.h>
79101099Srwatson
80101099Srwatson#include <security/mac_biba/mac_biba.h>
81101099Srwatson
82101099SrwatsonSYSCTL_DECL(_security_mac);
83101099Srwatson
84101099SrwatsonSYSCTL_NODE(_security_mac, OID_AUTO, biba, CTLFLAG_RW, 0,
85101099Srwatson    "TrustedBSD mac_biba policy controls");
86101099Srwatson
87105988Srwatsonstatic int	mac_biba_label_size = sizeof(struct mac_biba);
88105988SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, label_size, CTLFLAG_RD,
89105988Srwatson    &mac_biba_label_size, 0, "Size of struct mac_biba");
90105988Srwatson
91101099Srwatsonstatic int	mac_biba_enabled = 0;
92101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, enabled, CTLFLAG_RW,
93101099Srwatson    &mac_biba_enabled, 0, "Enforce MAC/Biba policy");
94102980SrwatsonTUNABLE_INT("security.mac.biba.enabled", &mac_biba_enabled);
95101099Srwatson
96101099Srwatsonstatic int	destroyed_not_inited;
97101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, destroyed_not_inited, CTLFLAG_RD,
98101099Srwatson    &destroyed_not_inited, 0, "Count of labels destroyed but not inited");
99101099Srwatson
100101099Srwatsonstatic int	trust_all_interfaces = 0;
101101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, trust_all_interfaces, CTLFLAG_RD,
102101099Srwatson    &trust_all_interfaces, 0, "Consider all interfaces 'trusted' by MAC/Biba");
103101099SrwatsonTUNABLE_INT("security.mac.biba.trust_all_interfaces", &trust_all_interfaces);
104101099Srwatson
105101099Srwatsonstatic char	trusted_interfaces[128];
106101099SrwatsonSYSCTL_STRING(_security_mac_biba, OID_AUTO, trusted_interfaces, CTLFLAG_RD,
107101099Srwatson    trusted_interfaces, 0, "Interfaces considered 'trusted' by MAC/Biba");
108101099SrwatsonTUNABLE_STR("security.mac.biba.trusted_interfaces", trusted_interfaces,
109101099Srwatson    sizeof(trusted_interfaces));
110101099Srwatson
111105643Srwatsonstatic int	max_compartments = MAC_BIBA_MAX_COMPARTMENTS;
112105643SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, max_compartments, CTLFLAG_RD,
113105643Srwatson    &max_compartments, 0, "Maximum supported compartments");
114105643Srwatson
115105606Srwatsonstatic int	ptys_equal = 0;
116105606SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, ptys_equal, CTLFLAG_RW,
117105606Srwatson    &ptys_equal, 0, "Label pty devices as biba/equal on create");
118105606SrwatsonTUNABLE_INT("security.mac.biba.ptys_equal", &ptys_equal);
119105606Srwatson
120105637Srwatsonstatic int	revocation_enabled = 0;
121101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, revocation_enabled, CTLFLAG_RW,
122105637Srwatson    &revocation_enabled, 0, "Revoke access to objects on relabel");
123105637SrwatsonTUNABLE_INT("security.mac.biba.revocation_enabled", &revocation_enabled);
124101099Srwatson
125101099Srwatsonstatic int	mac_biba_slot;
126101099Srwatson#define	SLOT(l)	((struct mac_biba *)LABEL_TO_SLOT((l), mac_biba_slot).l_ptr)
127101099Srwatson
128101099SrwatsonMALLOC_DEFINE(M_MACBIBA, "biba label", "MAC/Biba labels");
129101099Srwatson
130105643Srwatsonstatic __inline int
131105643Srwatsonbiba_bit_set_empty(u_char *set) {
132105643Srwatson	int i;
133105643Srwatson
134105643Srwatson	for (i = 0; i < MAC_BIBA_MAX_COMPARTMENTS >> 3; i++)
135105643Srwatson		if (set[i] != 0)
136105643Srwatson			return (0);
137105643Srwatson	return (1);
138105643Srwatson}
139105643Srwatson
140101099Srwatsonstatic struct mac_biba *
141104514Srwatsonbiba_alloc(int flag)
142101099Srwatson{
143101099Srwatson	struct mac_biba *mac_biba;
144101099Srwatson
145104514Srwatson	mac_biba = malloc(sizeof(struct mac_biba), M_MACBIBA, M_ZERO | flag);
146101099Srwatson
147101099Srwatson	return (mac_biba);
148101099Srwatson}
149101099Srwatson
150101099Srwatsonstatic void
151101099Srwatsonbiba_free(struct mac_biba *mac_biba)
152101099Srwatson{
153101099Srwatson
154101099Srwatson	if (mac_biba != NULL)
155101099Srwatson		free(mac_biba, M_MACBIBA);
156101099Srwatson	else
157101099Srwatson		atomic_add_int(&destroyed_not_inited, 1);
158101099Srwatson}
159101099Srwatson
160101099Srwatsonstatic int
161105634Srwatsonbiba_atmostflags(struct mac_biba *mac_biba, int flags)
162105634Srwatson{
163105634Srwatson
164105634Srwatson	if ((mac_biba->mb_flags & flags) != mac_biba->mb_flags)
165105634Srwatson		return (EINVAL);
166105634Srwatson	return (0);
167105634Srwatson}
168105634Srwatson
169105634Srwatsonstatic int
170101099Srwatsonmac_biba_dominate_element(struct mac_biba_element *a,
171101099Srwatson    struct mac_biba_element *b)
172101099Srwatson{
173105643Srwatson	int bit;
174101099Srwatson
175105736Srwatson	switch (a->mbe_type) {
176101099Srwatson	case MAC_BIBA_TYPE_EQUAL:
177101099Srwatson	case MAC_BIBA_TYPE_HIGH:
178101099Srwatson		return (1);
179101099Srwatson
180101099Srwatson	case MAC_BIBA_TYPE_LOW:
181101099Srwatson		switch (b->mbe_type) {
182101099Srwatson		case MAC_BIBA_TYPE_GRADE:
183101099Srwatson		case MAC_BIBA_TYPE_HIGH:
184101099Srwatson			return (0);
185101099Srwatson
186101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
187101099Srwatson		case MAC_BIBA_TYPE_LOW:
188101099Srwatson			return (1);
189101099Srwatson
190101099Srwatson		default:
191101099Srwatson			panic("mac_biba_dominate_element: b->mbe_type invalid");
192101099Srwatson		}
193101099Srwatson
194101099Srwatson	case MAC_BIBA_TYPE_GRADE:
195101099Srwatson		switch (b->mbe_type) {
196101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
197101099Srwatson		case MAC_BIBA_TYPE_LOW:
198101099Srwatson			return (1);
199101099Srwatson
200101099Srwatson		case MAC_BIBA_TYPE_HIGH:
201101099Srwatson			return (0);
202101099Srwatson
203101099Srwatson		case MAC_BIBA_TYPE_GRADE:
204105643Srwatson			for (bit = 1; bit <= MAC_BIBA_MAX_COMPARTMENTS; bit++)
205105643Srwatson				if (!MAC_BIBA_BIT_TEST(bit,
206105643Srwatson				    a->mbe_compartments) &&
207105643Srwatson				    MAC_BIBA_BIT_TEST(bit, b->mbe_compartments))
208105643Srwatson					return (0);
209101099Srwatson			return (a->mbe_grade >= b->mbe_grade);
210101099Srwatson
211101099Srwatson		default:
212101099Srwatson			panic("mac_biba_dominate_element: b->mbe_type invalid");
213101099Srwatson		}
214101099Srwatson
215101099Srwatson	default:
216101099Srwatson		panic("mac_biba_dominate_element: a->mbe_type invalid");
217101099Srwatson	}
218101099Srwatson
219101099Srwatson	return (0);
220101099Srwatson}
221101099Srwatson
222101099Srwatsonstatic int
223105988Srwatsonmac_biba_subject_dominate_high(struct mac_biba *mac_biba)
224105988Srwatson{
225105988Srwatson	struct mac_biba_element *element;
226105988Srwatson
227105988Srwatson	KASSERT((mac_biba->mb_single->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
228105988Srwatson	    ("mac_biba_single_in_range: mac_biba not single"));
229105988Srwatson	element = &mac_biba->mb_single;
230105988Srwatson
231105988Srwatson	return (element->mbe_type == MAC_BIBA_TYPE_EQUAL ||
232105988Srwatson	    element->mbe_type == MAC_BIBA_TYPE_HIGH);
233105988Srwatson}
234105988Srwatson
235105988Srwatsonstatic int
236101099Srwatsonmac_biba_range_in_range(struct mac_biba *rangea, struct mac_biba *rangeb)
237101099Srwatson{
238101099Srwatson
239101099Srwatson	return (mac_biba_dominate_element(&rangeb->mb_rangehigh,
240101099Srwatson	    &rangea->mb_rangehigh) &&
241101099Srwatson	    mac_biba_dominate_element(&rangea->mb_rangelow,
242101099Srwatson	    &rangeb->mb_rangelow));
243101099Srwatson}
244101099Srwatson
245101099Srwatsonstatic int
246101099Srwatsonmac_biba_single_in_range(struct mac_biba *single, struct mac_biba *range)
247101099Srwatson{
248101099Srwatson
249103750Srwatson	KASSERT((single->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
250101099Srwatson	    ("mac_biba_single_in_range: a not single"));
251103750Srwatson	KASSERT((range->mb_flags & MAC_BIBA_FLAG_RANGE) != 0,
252101099Srwatson	    ("mac_biba_single_in_range: b not range"));
253101099Srwatson
254101099Srwatson	return (mac_biba_dominate_element(&range->mb_rangehigh,
255101099Srwatson	    &single->mb_single) &&
256101099Srwatson	    mac_biba_dominate_element(&single->mb_single,
257101099Srwatson	    &range->mb_rangelow));
258101099Srwatson
259101099Srwatson	return (1);
260101099Srwatson}
261101099Srwatson
262101099Srwatsonstatic int
263101099Srwatsonmac_biba_dominate_single(struct mac_biba *a, struct mac_biba *b)
264101099Srwatson{
265101099Srwatson	KASSERT((a->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
266101099Srwatson	    ("mac_biba_dominate_single: a not single"));
267101099Srwatson	KASSERT((b->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
268101099Srwatson	    ("mac_biba_dominate_single: b not single"));
269101099Srwatson
270101099Srwatson	return (mac_biba_dominate_element(&a->mb_single, &b->mb_single));
271101099Srwatson}
272101099Srwatson
273101099Srwatsonstatic int
274101099Srwatsonmac_biba_equal_element(struct mac_biba_element *a, struct mac_biba_element *b)
275101099Srwatson{
276101099Srwatson
277101099Srwatson	if (a->mbe_type == MAC_BIBA_TYPE_EQUAL ||
278101099Srwatson	    b->mbe_type == MAC_BIBA_TYPE_EQUAL)
279101099Srwatson		return (1);
280101099Srwatson
281101099Srwatson	return (a->mbe_type == b->mbe_type && a->mbe_grade == b->mbe_grade);
282101099Srwatson}
283101099Srwatson
284101099Srwatsonstatic int
285101099Srwatsonmac_biba_equal_single(struct mac_biba *a, struct mac_biba *b)
286101099Srwatson{
287101099Srwatson
288101099Srwatson	KASSERT((a->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
289101099Srwatson	    ("mac_biba_equal_single: a not single"));
290101099Srwatson	KASSERT((b->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
291101099Srwatson	    ("mac_biba_equal_single: b not single"));
292101099Srwatson
293101099Srwatson	return (mac_biba_equal_element(&a->mb_single, &b->mb_single));
294101099Srwatson}
295101099Srwatson
296101099Srwatsonstatic int
297105634Srwatsonmac_biba_contains_equal(struct mac_biba *mac_biba)
298105634Srwatson{
299105634Srwatson
300105634Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE)
301105634Srwatson		if (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_EQUAL)
302105634Srwatson			return (1);
303105634Srwatson
304105634Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
305105634Srwatson		if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL)
306105634Srwatson			return (1);
307105634Srwatson		if (mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL)
308105637Srwatson			return (1);
309105634Srwatson	}
310105634Srwatson
311105634Srwatson	return (0);
312105634Srwatson}
313105634Srwatson
314105634Srwatsonstatic int
315106090Srwatsonmac_biba_subject_privileged(struct mac_biba *mac_biba)
316105634Srwatson{
317105634Srwatson
318105634Srwatson	KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAGS_BOTH) ==
319105634Srwatson	    MAC_BIBA_FLAGS_BOTH,
320106090Srwatson	    ("mac_biba_subject_privileged: subject doesn't have both labels"));
321105634Srwatson
322105634Srwatson	/* If the single is EQUAL, it's ok. */
323105634Srwatson	if (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_EQUAL)
324105634Srwatson		return (0);
325105634Srwatson
326105634Srwatson	/* If either range endpoint is EQUAL, it's ok. */
327105634Srwatson	if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL ||
328105634Srwatson	    mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL)
329105634Srwatson		return (0);
330105634Srwatson
331105634Srwatson	/* If the range is low-high, it's ok. */
332105634Srwatson	if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_LOW &&
333105634Srwatson	    mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_HIGH)
334105634Srwatson		return (0);
335105634Srwatson
336105634Srwatson	/* It's not ok. */
337105634Srwatson	return (EPERM);
338105634Srwatson}
339105634Srwatson
340105988Srwatsonmac_biba_high_single(struct mac_biba *mac_biba)
341105988Srwatson{
342105988Srwatson
343105988Srwatson	KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
344105988Srwatson	    ("mac_biba_equal_single: mac_biba not single"));
345105988Srwatson
346105988Srwatson	return (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_HIGH);
347105988Srwatson}
348105988Srwatson
349105634Srwatsonstatic int
350101099Srwatsonmac_biba_valid(struct mac_biba *mac_biba)
351101099Srwatson{
352101099Srwatson
353101099Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) {
354101099Srwatson		switch (mac_biba->mb_single.mbe_type) {
355101099Srwatson		case MAC_BIBA_TYPE_GRADE:
356101099Srwatson			break;
357101099Srwatson
358101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
359101099Srwatson		case MAC_BIBA_TYPE_HIGH:
360101099Srwatson		case MAC_BIBA_TYPE_LOW:
361105643Srwatson			if (mac_biba->mb_single.mbe_grade != 0 ||
362105643Srwatson			    !MAC_BIBA_BIT_SET_EMPTY(
363105643Srwatson			    mac_biba->mb_single.mbe_compartments))
364101099Srwatson				return (EINVAL);
365101099Srwatson			break;
366101099Srwatson
367101099Srwatson		default:
368101099Srwatson			return (EINVAL);
369101099Srwatson		}
370101099Srwatson	} else {
371101099Srwatson		if (mac_biba->mb_single.mbe_type != MAC_BIBA_TYPE_UNDEF)
372101099Srwatson			return (EINVAL);
373101099Srwatson	}
374101099Srwatson
375101099Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
376101099Srwatson		switch (mac_biba->mb_rangelow.mbe_type) {
377101099Srwatson		case MAC_BIBA_TYPE_GRADE:
378101099Srwatson			break;
379101099Srwatson
380101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
381101099Srwatson		case MAC_BIBA_TYPE_HIGH:
382101099Srwatson		case MAC_BIBA_TYPE_LOW:
383105643Srwatson			if (mac_biba->mb_rangelow.mbe_grade != 0 ||
384105643Srwatson			    !MAC_BIBA_BIT_SET_EMPTY(
385105643Srwatson			    mac_biba->mb_rangelow.mbe_compartments))
386101099Srwatson				return (EINVAL);
387101099Srwatson			break;
388101099Srwatson
389101099Srwatson		default:
390101099Srwatson			return (EINVAL);
391101099Srwatson		}
392101099Srwatson
393101099Srwatson		switch (mac_biba->mb_rangehigh.mbe_type) {
394101099Srwatson		case MAC_BIBA_TYPE_GRADE:
395101099Srwatson			break;
396101099Srwatson
397101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
398101099Srwatson		case MAC_BIBA_TYPE_HIGH:
399101099Srwatson		case MAC_BIBA_TYPE_LOW:
400105643Srwatson			if (mac_biba->mb_rangehigh.mbe_grade != 0 ||
401105643Srwatson			    !MAC_BIBA_BIT_SET_EMPTY(
402105643Srwatson			    mac_biba->mb_rangehigh.mbe_compartments))
403101099Srwatson				return (EINVAL);
404101099Srwatson			break;
405101099Srwatson
406101099Srwatson		default:
407101099Srwatson			return (EINVAL);
408101099Srwatson		}
409101099Srwatson		if (!mac_biba_dominate_element(&mac_biba->mb_rangehigh,
410101099Srwatson		    &mac_biba->mb_rangelow))
411101099Srwatson			return (EINVAL);
412101099Srwatson	} else {
413101099Srwatson		if (mac_biba->mb_rangelow.mbe_type != MAC_BIBA_TYPE_UNDEF ||
414101099Srwatson		    mac_biba->mb_rangehigh.mbe_type != MAC_BIBA_TYPE_UNDEF)
415101099Srwatson			return (EINVAL);
416101099Srwatson	}
417101099Srwatson
418101099Srwatson	return (0);
419101099Srwatson}
420101099Srwatson
421101099Srwatsonstatic void
422101099Srwatsonmac_biba_set_range(struct mac_biba *mac_biba, u_short typelow,
423105643Srwatson    u_short gradelow, u_char *compartmentslow, u_short typehigh,
424105643Srwatson    u_short gradehigh, u_char *compartmentshigh)
425101099Srwatson{
426101099Srwatson
427101099Srwatson	mac_biba->mb_rangelow.mbe_type = typelow;
428101099Srwatson	mac_biba->mb_rangelow.mbe_grade = gradelow;
429105643Srwatson	if (compartmentslow != NULL)
430105643Srwatson		memcpy(mac_biba->mb_rangelow.mbe_compartments,
431105643Srwatson		    compartmentslow,
432105643Srwatson		    sizeof(mac_biba->mb_rangelow.mbe_compartments));
433101099Srwatson	mac_biba->mb_rangehigh.mbe_type = typehigh;
434101099Srwatson	mac_biba->mb_rangehigh.mbe_grade = gradehigh;
435105643Srwatson	if (compartmentshigh != NULL)
436105643Srwatson		memcpy(mac_biba->mb_rangehigh.mbe_compartments,
437105643Srwatson		    compartmentshigh,
438105643Srwatson		    sizeof(mac_biba->mb_rangehigh.mbe_compartments));
439101099Srwatson	mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE;
440101099Srwatson}
441101099Srwatson
442101099Srwatsonstatic void
443105643Srwatsonmac_biba_set_single(struct mac_biba *mac_biba, u_short type, u_short grade,
444105643Srwatson    u_char *compartments)
445101099Srwatson{
446101099Srwatson
447101099Srwatson	mac_biba->mb_single.mbe_type = type;
448101099Srwatson	mac_biba->mb_single.mbe_grade = grade;
449105643Srwatson	if (compartments != NULL)
450105643Srwatson		memcpy(mac_biba->mb_single.mbe_compartments, compartments,
451105643Srwatson		    sizeof(mac_biba->mb_single.mbe_compartments));
452101099Srwatson	mac_biba->mb_flags |= MAC_BIBA_FLAG_SINGLE;
453101099Srwatson}
454101099Srwatson
455101099Srwatsonstatic void
456101099Srwatsonmac_biba_copy_range(struct mac_biba *labelfrom, struct mac_biba *labelto)
457101099Srwatson{
458105643Srwatson
459101099Srwatson	KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_RANGE) != 0,
460101099Srwatson	    ("mac_biba_copy_range: labelfrom not range"));
461101099Srwatson
462101099Srwatson	labelto->mb_rangelow = labelfrom->mb_rangelow;
463101099Srwatson	labelto->mb_rangehigh = labelfrom->mb_rangehigh;
464101099Srwatson	labelto->mb_flags |= MAC_BIBA_FLAG_RANGE;
465101099Srwatson}
466101099Srwatson
467101099Srwatsonstatic void
468101099Srwatsonmac_biba_copy_single(struct mac_biba *labelfrom, struct mac_biba *labelto)
469101099Srwatson{
470101099Srwatson
471101099Srwatson	KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
472101099Srwatson	    ("mac_biba_copy_single: labelfrom not single"));
473101099Srwatson
474101099Srwatson	labelto->mb_single = labelfrom->mb_single;
475101099Srwatson	labelto->mb_flags |= MAC_BIBA_FLAG_SINGLE;
476101099Srwatson}
477101099Srwatson
478105656Srwatsonstatic void
479105656Srwatsonmac_biba_copy(struct mac_biba *source, struct mac_biba *dest)
480105656Srwatson{
481105656Srwatson
482105656Srwatson	if (source->mb_flags & MAC_BIBA_FLAG_SINGLE)
483105656Srwatson		mac_biba_copy_single(source, dest);
484105656Srwatson	if (source->mb_flags & MAC_BIBA_FLAG_RANGE)
485105656Srwatson		mac_biba_copy_range(source, dest);
486105656Srwatson}
487105656Srwatson
488101099Srwatson/*
489101099Srwatson * Policy module operations.
490101099Srwatson */
491101099Srwatsonstatic void
492101099Srwatsonmac_biba_destroy(struct mac_policy_conf *conf)
493101099Srwatson{
494101099Srwatson
495101099Srwatson}
496101099Srwatson
497101099Srwatsonstatic void
498101099Srwatsonmac_biba_init(struct mac_policy_conf *conf)
499101099Srwatson{
500101099Srwatson
501101099Srwatson}
502101099Srwatson
503101099Srwatson/*
504101099Srwatson * Label operations.
505101099Srwatson */
506101099Srwatsonstatic void
507104514Srwatsonmac_biba_init_label(struct label *label)
508101099Srwatson{
509101099Srwatson
510101099Srwatson	SLOT(label) = biba_alloc(M_WAITOK);
511101099Srwatson}
512101099Srwatson
513101099Srwatsonstatic int
514104514Srwatsonmac_biba_init_label_waitcheck(struct label *label, int flag)
515101099Srwatson{
516101099Srwatson
517104514Srwatson	SLOT(label) = biba_alloc(flag);
518101099Srwatson	if (SLOT(label) == NULL)
519101099Srwatson		return (ENOMEM);
520101099Srwatson
521101099Srwatson	return (0);
522101099Srwatson}
523101099Srwatson
524101099Srwatsonstatic void
525104514Srwatsonmac_biba_destroy_label(struct label *label)
526101099Srwatson{
527101099Srwatson
528101099Srwatson	biba_free(SLOT(label));
529101099Srwatson	SLOT(label) = NULL;
530101099Srwatson}
531101099Srwatson
532105696Srwatson/*
533105696Srwatson * mac_biba_element_to_string() is basically an snprintf wrapper with
534105696Srwatson * the same properties as snprintf().  It returns the length it would
535105696Srwatson * have added to the string in the event the string is too short.
536105696Srwatson */
537105696Srwatsonstatic size_t
538105696Srwatsonmac_biba_element_to_string(char *string, size_t size,
539105696Srwatson    struct mac_biba_element *element)
540105696Srwatson{
541105696Srwatson	int pos, bit = 1;
542105696Srwatson
543105696Srwatson	switch (element->mbe_type) {
544105696Srwatson	case MAC_BIBA_TYPE_HIGH:
545105696Srwatson		return (snprintf(string, size, "high"));
546105696Srwatson
547105696Srwatson	case MAC_BIBA_TYPE_LOW:
548105696Srwatson		return (snprintf(string, size, "low"));
549105696Srwatson
550105696Srwatson	case MAC_BIBA_TYPE_EQUAL:
551105696Srwatson		return (snprintf(string, size, "equal"));
552105696Srwatson
553105696Srwatson	case MAC_BIBA_TYPE_GRADE:
554105696Srwatson		pos = snprintf(string, size, "%d:", element->mbe_grade);
555105696Srwatson		for (bit = 1; bit <= MAC_BIBA_MAX_COMPARTMENTS; bit++) {
556105696Srwatson			if (MAC_BIBA_BIT_TEST(bit, element->mbe_compartments))
557105696Srwatson				pos += snprintf(string + pos, size - pos,
558105696Srwatson				    "%d+", bit);
559105696Srwatson		}
560105696Srwatson		if (string[pos - 1] == '+' || string[pos - 1] == ':')
561105696Srwatson			string[--pos] = NULL;
562105696Srwatson		return (pos);
563105696Srwatson
564105696Srwatson	default:
565105696Srwatson		panic("mac_biba_element_to_string: invalid type (%d)",
566105696Srwatson		    element->mbe_type);
567105696Srwatson	}
568105696Srwatson}
569105696Srwatson
570101099Srwatsonstatic int
571105696Srwatsonmac_biba_to_string(char *string, size_t size, size_t *caller_len,
572105696Srwatson    struct mac_biba *mac_biba)
573101099Srwatson{
574105696Srwatson	size_t left, len;
575105696Srwatson	char *curptr;
576105696Srwatson
577105696Srwatson	bzero(string, size);
578105696Srwatson	curptr = string;
579105696Srwatson	left = size;
580105696Srwatson
581105696Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) {
582105696Srwatson		len = mac_biba_element_to_string(curptr, left,
583105696Srwatson		    &mac_biba->mb_single);
584105696Srwatson		if (len >= left)
585105696Srwatson			return (EINVAL);
586105696Srwatson		left -= len;
587105696Srwatson		curptr += len;
588105696Srwatson	}
589105696Srwatson
590105696Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
591105696Srwatson		len = snprintf(curptr, left, "(");
592105696Srwatson		if (len >= left)
593105696Srwatson			return (EINVAL);
594105696Srwatson		left -= len;
595105696Srwatson		curptr += len;
596105696Srwatson
597105696Srwatson		len = mac_biba_element_to_string(curptr, left,
598105696Srwatson		    &mac_biba->mb_rangelow);
599105696Srwatson		if (len >= left)
600105696Srwatson			return (EINVAL);
601105696Srwatson		left -= len;
602105696Srwatson		curptr += len;
603105696Srwatson
604105696Srwatson		len = snprintf(curptr, left, "-");
605105696Srwatson		if (len >= left)
606105696Srwatson			return (EINVAL);
607105696Srwatson		left -= len;
608105696Srwatson		curptr += len;
609105696Srwatson
610105696Srwatson		len = mac_biba_element_to_string(curptr, left,
611105696Srwatson		    &mac_biba->mb_rangehigh);
612105696Srwatson		if (len >= left)
613105696Srwatson			return (EINVAL);
614105696Srwatson		left -= len;
615105696Srwatson		curptr += len;
616105696Srwatson
617105696Srwatson		len = snprintf(curptr, left, ")");
618105696Srwatson		if (len >= left)
619105696Srwatson			return (EINVAL);
620105696Srwatson		left -= len;
621105696Srwatson		curptr += len;
622105696Srwatson	}
623105696Srwatson
624105696Srwatson	*caller_len = strlen(string);
625105696Srwatson	return (0);
626105696Srwatson}
627105696Srwatson
628105696Srwatsonstatic int
629105696Srwatsonmac_biba_externalize_label(struct label *label, char *element_name,
630105696Srwatson    char *element_data, size_t size, size_t *len, int *claimed)
631105696Srwatson{
632101099Srwatson	struct mac_biba *mac_biba;
633105696Srwatson	int error;
634101099Srwatson
635105696Srwatson	if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0)
636105696Srwatson		return (0);
637105696Srwatson
638105696Srwatson	(*claimed)++;
639105696Srwatson
640101099Srwatson	mac_biba = SLOT(label);
641105696Srwatson	error = mac_biba_to_string(element_data, size, len, mac_biba);
642105696Srwatson	if (error)
643105696Srwatson		return (error);
644101099Srwatson
645105696Srwatson	*len = strlen(element_data);
646105696Srwatson	return (0);
647105696Srwatson}
648105696Srwatson
649105696Srwatsonstatic int
650105696Srwatsonmac_biba_parse_element(struct mac_biba_element *element, char *string)
651101099Srwatson{
652105696Srwatson
653105696Srwatson	if (strcmp(string, "high") == 0 ||
654105696Srwatson	    strcmp(string, "hi") == 0) {
655105696Srwatson		element->mbe_type = MAC_BIBA_TYPE_HIGH;
656105696Srwatson		element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
657105696Srwatson	} else if (strcmp(string, "low") == 0 ||
658105696Srwatson	    strcmp(string, "lo") == 0) {
659105696Srwatson		element->mbe_type = MAC_BIBA_TYPE_LOW;
660105696Srwatson		element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
661105696Srwatson	} else if (strcmp(string, "equal") == 0 ||
662105696Srwatson	    strcmp(string, "eq") == 0) {
663105696Srwatson		element->mbe_type = MAC_BIBA_TYPE_EQUAL;
664105696Srwatson		element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
665105696Srwatson	} else {
666105696Srwatson		char *p0, *p1;
667105696Srwatson		int d;
668105696Srwatson
669105696Srwatson		p0 = string;
670105696Srwatson		d = strtol(p0, &p1, 10);
671105696Srwatson
672105696Srwatson		if (d < 0 || d > 65535)
673105696Srwatson			return (EINVAL);
674105696Srwatson		element->mbe_type = MAC_BIBA_TYPE_GRADE;
675105696Srwatson		element->mbe_grade = d;
676105696Srwatson
677105696Srwatson		if (*p1 != ':')  {
678105696Srwatson			if (p1 == p0 || *p1 != '\0')
679105696Srwatson				return (EINVAL);
680105696Srwatson			else
681105696Srwatson				return (0);
682105696Srwatson		}
683105696Srwatson		else
684105696Srwatson			if (*(p1 + 1) == '\0')
685105696Srwatson				return (0);
686105696Srwatson
687105696Srwatson		while ((p0 = ++p1)) {
688105696Srwatson			d = strtol(p0, &p1, 10);
689105696Srwatson			if (d < 1 || d > MAC_BIBA_MAX_COMPARTMENTS)
690105696Srwatson				return (EINVAL);
691105696Srwatson
692105696Srwatson			MAC_BIBA_BIT_SET(d, element->mbe_compartments);
693105696Srwatson
694105696Srwatson			if (*p1 == '\0')
695105696Srwatson				break;
696105696Srwatson			if (p1 == p0 || *p1 != '+')
697105696Srwatson				return (EINVAL);
698105696Srwatson		}
699105696Srwatson	}
700105696Srwatson
701105696Srwatson	return (0);
702105696Srwatson}
703105696Srwatson
704105696Srwatson/*
705105696Srwatson * Note: destructively consumes the string, make a local copy before
706105696Srwatson * calling if that's a problem.
707105696Srwatson */
708105696Srwatsonstatic int
709105696Srwatsonmac_biba_parse(struct mac_biba *mac_biba, char *string)
710105696Srwatson{
711105696Srwatson	char *range, *rangeend, *rangehigh, *rangelow, *single;
712101099Srwatson	int error;
713101099Srwatson
714105696Srwatson	/* Do we have a range? */
715105696Srwatson	single = string;
716105696Srwatson	range = index(string, '(');
717105696Srwatson	if (range == single)
718105696Srwatson		single = NULL;
719105696Srwatson	rangelow = rangehigh = NULL;
720105696Srwatson	if (range != NULL) {
721105696Srwatson		/* Nul terminate the end of the single string. */
722105696Srwatson		*range = '\0';
723105696Srwatson		range++;
724105696Srwatson		rangelow = range;
725105696Srwatson		rangehigh = index(rangelow, '-');
726105696Srwatson		if (rangehigh == NULL)
727105696Srwatson			return (EINVAL);
728105696Srwatson		rangehigh++;
729105696Srwatson		if (*rangelow == '\0' || *rangehigh == '\0')
730105696Srwatson			return (EINVAL);
731105696Srwatson		rangeend = index(rangehigh, ')');
732105696Srwatson		if (rangeend == NULL)
733105696Srwatson			return (EINVAL);
734105696Srwatson		if (*(rangeend + 1) != '\0')
735105696Srwatson			return (EINVAL);
736105696Srwatson		/* Nul terminate the ends of the ranges. */
737105696Srwatson		*(rangehigh - 1) = '\0';
738105696Srwatson		*rangeend = '\0';
739105696Srwatson	}
740105696Srwatson	KASSERT((rangelow != NULL && rangehigh != NULL) ||
741105696Srwatson	    (rangelow == NULL && rangehigh == NULL),
742105696Srwatson	    ("mac_biba_internalize_label: range mismatch"));
743101099Srwatson
744105696Srwatson	bzero(mac_biba, sizeof(*mac_biba));
745105696Srwatson	if (single != NULL) {
746105696Srwatson		error = mac_biba_parse_element(&mac_biba->mb_single, single);
747105696Srwatson		if (error)
748105696Srwatson			return (error);
749105696Srwatson		mac_biba->mb_flags |= MAC_BIBA_FLAG_SINGLE;
750105696Srwatson	}
751105696Srwatson
752105696Srwatson	if (rangelow != NULL) {
753105696Srwatson		error = mac_biba_parse_element(&mac_biba->mb_rangelow,
754105696Srwatson		    rangelow);
755105696Srwatson		if (error)
756105696Srwatson			return (error);
757105696Srwatson		error = mac_biba_parse_element(&mac_biba->mb_rangehigh,
758105696Srwatson		    rangehigh);
759105696Srwatson		if (error)
760105696Srwatson			return (error);
761105696Srwatson		mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE;
762105696Srwatson	}
763105696Srwatson
764101099Srwatson	error = mac_biba_valid(mac_biba);
765101099Srwatson	if (error)
766101099Srwatson		return (error);
767101099Srwatson
768105696Srwatson	return (0);
769105696Srwatson}
770101099Srwatson
771105696Srwatsonstatic int
772105696Srwatsonmac_biba_internalize_label(struct label *label, char *element_name,
773105696Srwatson    char *element_data, int *claimed)
774105696Srwatson{
775105696Srwatson	struct mac_biba *mac_biba, mac_biba_temp;
776105696Srwatson	int error;
777105696Srwatson
778105696Srwatson	if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0)
779105696Srwatson		return (0);
780105696Srwatson
781105696Srwatson	(*claimed)++;
782105696Srwatson
783105696Srwatson	error = mac_biba_parse(&mac_biba_temp, element_data);
784105696Srwatson	if (error)
785105696Srwatson		return (error);
786105696Srwatson
787105696Srwatson	mac_biba = SLOT(label);
788105696Srwatson	*mac_biba = mac_biba_temp;
789105696Srwatson
790101099Srwatson	return (0);
791101099Srwatson}
792101099Srwatson
793105696Srwatsonstatic void
794105696Srwatsonmac_biba_copy_label(struct label *src, struct label *dest)
795105696Srwatson{
796105696Srwatson
797105696Srwatson	*SLOT(dest) = *SLOT(src);
798105696Srwatson}
799105696Srwatson
800101099Srwatson/*
801101099Srwatson * Labeling event operations: file system objects, and things that look
802101099Srwatson * a lot like file system objects.
803101099Srwatson */
804101099Srwatsonstatic void
805101099Srwatsonmac_biba_create_devfs_device(dev_t dev, struct devfs_dirent *devfs_dirent,
806101099Srwatson    struct label *label)
807101099Srwatson{
808101099Srwatson	struct mac_biba *mac_biba;
809101099Srwatson	int biba_type;
810101099Srwatson
811101099Srwatson	mac_biba = SLOT(label);
812101099Srwatson	if (strcmp(dev->si_name, "null") == 0 ||
813101099Srwatson	    strcmp(dev->si_name, "zero") == 0 ||
814101099Srwatson	    strcmp(dev->si_name, "random") == 0 ||
815101099Srwatson	    strncmp(dev->si_name, "fd/", strlen("fd/")) == 0)
816101099Srwatson		biba_type = MAC_BIBA_TYPE_EQUAL;
817105606Srwatson	else if (ptys_equal &&
818105606Srwatson	    (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 ||
819105606Srwatson	    strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0))
820105606Srwatson		biba_type = MAC_BIBA_TYPE_EQUAL;
821101099Srwatson	else
822101099Srwatson		biba_type = MAC_BIBA_TYPE_HIGH;
823105643Srwatson	mac_biba_set_single(mac_biba, biba_type, 0, NULL);
824101099Srwatson}
825101099Srwatson
826101099Srwatsonstatic void
827101099Srwatsonmac_biba_create_devfs_directory(char *dirname, int dirnamelen,
828101099Srwatson    struct devfs_dirent *devfs_dirent, struct label *label)
829101099Srwatson{
830101099Srwatson	struct mac_biba *mac_biba;
831101099Srwatson
832101099Srwatson	mac_biba = SLOT(label);
833105643Srwatson	mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
834101099Srwatson}
835101099Srwatson
836101099Srwatsonstatic void
837104535Srwatsonmac_biba_create_devfs_symlink(struct ucred *cred, struct devfs_dirent *dd,
838104535Srwatson    struct label *ddlabel, struct devfs_dirent *de, struct label *delabel)
839104535Srwatson{
840104535Srwatson	struct mac_biba *source, *dest;
841104535Srwatson
842104535Srwatson	source = SLOT(&cred->cr_label);
843104535Srwatson	dest = SLOT(delabel);
844104535Srwatson
845104535Srwatson	mac_biba_copy_single(source, dest);
846104535Srwatson}
847104535Srwatson
848104535Srwatsonstatic void
849101099Srwatsonmac_biba_create_devfs_vnode(struct devfs_dirent *devfs_dirent,
850101099Srwatson    struct label *direntlabel, struct vnode *vp, struct label *vnodelabel)
851101099Srwatson{
852101099Srwatson	struct mac_biba *source, *dest;
853101099Srwatson
854101099Srwatson	source = SLOT(direntlabel);
855101099Srwatson	dest = SLOT(vnodelabel);
856101099Srwatson	mac_biba_copy_single(source, dest);
857101099Srwatson}
858101099Srwatson
859101099Srwatsonstatic void
860101099Srwatsonmac_biba_create_mount(struct ucred *cred, struct mount *mp,
861101099Srwatson    struct label *mntlabel, struct label *fslabel)
862101099Srwatson{
863101099Srwatson	struct mac_biba *source, *dest;
864101099Srwatson
865101099Srwatson	source = SLOT(&cred->cr_label);
866101099Srwatson	dest = SLOT(mntlabel);
867101099Srwatson	mac_biba_copy_single(source, dest);
868101099Srwatson	dest = SLOT(fslabel);
869101099Srwatson	mac_biba_copy_single(source, dest);
870101099Srwatson}
871101099Srwatson
872101099Srwatsonstatic void
873101099Srwatsonmac_biba_create_root_mount(struct ucred *cred, struct mount *mp,
874101099Srwatson    struct label *mntlabel, struct label *fslabel)
875101099Srwatson{
876101099Srwatson	struct mac_biba *mac_biba;
877101099Srwatson
878101099Srwatson	/* Always mount root as high integrity. */
879101099Srwatson	mac_biba = SLOT(fslabel);
880105643Srwatson	mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
881101099Srwatson	mac_biba = SLOT(mntlabel);
882105643Srwatson	mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
883101099Srwatson}
884101099Srwatson
885101099Srwatsonstatic void
886101099Srwatsonmac_biba_relabel_vnode(struct ucred *cred, struct vnode *vp,
887101099Srwatson    struct label *vnodelabel, struct label *label)
888101099Srwatson{
889101099Srwatson	struct mac_biba *source, *dest;
890101099Srwatson
891101099Srwatson	source = SLOT(label);
892101099Srwatson	dest = SLOT(vnodelabel);
893101099Srwatson
894105656Srwatson	mac_biba_copy(source, dest);
895101099Srwatson}
896101099Srwatson
897101099Srwatsonstatic void
898101099Srwatsonmac_biba_update_devfsdirent(struct devfs_dirent *devfs_dirent,
899101099Srwatson    struct label *direntlabel, struct vnode *vp, struct label *vnodelabel)
900101099Srwatson{
901101099Srwatson	struct mac_biba *source, *dest;
902101099Srwatson
903101099Srwatson	source = SLOT(vnodelabel);
904101099Srwatson	dest = SLOT(direntlabel);
905101099Srwatson
906105656Srwatson	mac_biba_copy(source, dest);
907101099Srwatson}
908101099Srwatson
909101099Srwatsonstatic void
910105988Srwatsonmac_biba_associate_vnode_devfs(struct mount *mp, struct label *fslabel,
911105988Srwatson    struct devfs_dirent *de, struct label *delabel, struct vnode *vp,
912105988Srwatson    struct label *vlabel)
913101099Srwatson{
914101099Srwatson	struct mac_biba *source, *dest;
915101099Srwatson
916105988Srwatson	source = SLOT(delabel);
917105988Srwatson	dest = SLOT(vlabel);
918101099Srwatson
919101099Srwatson	mac_biba_copy_single(source, dest);
920101099Srwatson}
921101099Srwatson
922101099Srwatsonstatic int
923105988Srwatsonmac_biba_associate_vnode_extattr(struct mount *mp, struct label *fslabel,
924105988Srwatson    struct vnode *vp, struct label *vlabel)
925101099Srwatson{
926105988Srwatson	struct mac_biba temp, *source, *dest;
927105988Srwatson	size_t buflen;
928101099Srwatson	int error;
929101099Srwatson
930105988Srwatson	source = SLOT(fslabel);
931105988Srwatson	dest = SLOT(vlabel);
932101099Srwatson
933105988Srwatson	buflen = sizeof(temp);
934105988Srwatson	bzero(&temp, buflen);
935105988Srwatson
936105988Srwatson	error = vn_extattr_get(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
937105988Srwatson	    MAC_BIBA_EXTATTR_NAME, &buflen, (char *) &temp, curthread);
938105988Srwatson	if (error == ENOATTR || error == EOPNOTSUPP) {
939105988Srwatson		/* Fall back to the fslabel. */
940105988Srwatson		mac_biba_copy_single(source, dest);
941105988Srwatson		return (0);
942105988Srwatson	} else if (error)
943101099Srwatson		return (error);
944101099Srwatson
945105988Srwatson	if (buflen != sizeof(temp)) {
946105988Srwatson		printf("mac_biba_associate_vnode_extattr: bad size %d\n",
947105988Srwatson		    buflen);
948105988Srwatson		return (EPERM);
949105988Srwatson	}
950105988Srwatson	if (mac_biba_valid(&temp) != 0) {
951105988Srwatson		printf("mac_biba_associate_vnode_extattr: invalid\n");
952105988Srwatson		return (EPERM);
953105988Srwatson	}
954105988Srwatson	if ((temp.mb_flags & MAC_BIBA_FLAGS_BOTH) != MAC_BIBA_FLAG_SINGLE) {
955105988Srwatson		printf("mac_biba_associate_vnode_extattr: not single\n");
956105988Srwatson		return (EPERM);
957105988Srwatson	}
958101099Srwatson
959105988Srwatson	mac_biba_copy_single(&temp, dest);
960101099Srwatson	return (0);
961101099Srwatson}
962101099Srwatson
963101099Srwatsonstatic void
964105988Srwatsonmac_biba_associate_vnode_singlelabel(struct mount *mp,
965105988Srwatson    struct label *fslabel, struct vnode *vp, struct label *vlabel)
966101099Srwatson{
967101099Srwatson	struct mac_biba *source, *dest;
968101099Srwatson
969101099Srwatson	source = SLOT(fslabel);
970105988Srwatson	dest = SLOT(vlabel);
971101099Srwatson
972101099Srwatson	mac_biba_copy_single(source, dest);
973101099Srwatson}
974101099Srwatson
975105988Srwatsonstatic int
976105988Srwatsonmac_biba_create_vnode_extattr(struct ucred *cred, struct mount *mp,
977105988Srwatson    struct label *fslabel, struct vnode *dvp, struct label *dlabel,
978105988Srwatson    struct vnode *vp, struct label *vlabel, struct componentname *cnp)
979105988Srwatson{
980105988Srwatson	struct mac_biba *source, *dest, temp;
981105988Srwatson	size_t buflen;
982105988Srwatson	int error;
983105988Srwatson
984105988Srwatson	buflen = sizeof(temp);
985105988Srwatson	bzero(&temp, buflen);
986105988Srwatson
987105988Srwatson	source = SLOT(&cred->cr_label);
988105988Srwatson	dest = SLOT(vlabel);
989105988Srwatson	mac_biba_copy_single(source, &temp);
990105988Srwatson
991105988Srwatson	error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
992105988Srwatson	    MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread);
993105988Srwatson	if (error == 0)
994105988Srwatson		mac_biba_copy_single(source, dest);
995105988Srwatson	return (error);
996105988Srwatson}
997105988Srwatson
998105988Srwatsonstatic int
999105988Srwatsonmac_biba_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp,
1000105988Srwatson    struct label *vlabel, struct label *intlabel)
1001105988Srwatson{
1002105988Srwatson	struct mac_biba *source, temp;
1003105988Srwatson	size_t buflen;
1004105988Srwatson	int error;
1005105988Srwatson
1006105988Srwatson	buflen = sizeof(temp);
1007105988Srwatson	bzero(&temp, buflen);
1008105988Srwatson
1009105988Srwatson	source = SLOT(intlabel);
1010105988Srwatson	if ((source->mb_flags & MAC_BIBA_FLAG_SINGLE) == 0)
1011105988Srwatson		return (0);
1012105988Srwatson
1013105988Srwatson	mac_biba_copy_single(source, &temp);
1014105988Srwatson
1015105988Srwatson	error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
1016105988Srwatson	    MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread);
1017105988Srwatson	return (error);
1018105988Srwatson}
1019105988Srwatson
1020101099Srwatson/*
1021101099Srwatson * Labeling event operations: IPC object.
1022101099Srwatson */
1023101099Srwatsonstatic void
1024101099Srwatsonmac_biba_create_mbuf_from_socket(struct socket *so, struct label *socketlabel,
1025101099Srwatson    struct mbuf *m, struct label *mbuflabel)
1026101099Srwatson{
1027101099Srwatson	struct mac_biba *source, *dest;
1028101099Srwatson
1029101099Srwatson	source = SLOT(socketlabel);
1030101099Srwatson	dest = SLOT(mbuflabel);
1031101099Srwatson
1032101099Srwatson	mac_biba_copy_single(source, dest);
1033101099Srwatson}
1034101099Srwatson
1035101099Srwatsonstatic void
1036101099Srwatsonmac_biba_create_socket(struct ucred *cred, struct socket *socket,
1037101099Srwatson    struct label *socketlabel)
1038101099Srwatson{
1039101099Srwatson	struct mac_biba *source, *dest;
1040101099Srwatson
1041101099Srwatson	source = SLOT(&cred->cr_label);
1042101099Srwatson	dest = SLOT(socketlabel);
1043101099Srwatson
1044101099Srwatson	mac_biba_copy_single(source, dest);
1045101099Srwatson}
1046101099Srwatson
1047101099Srwatsonstatic void
1048101099Srwatsonmac_biba_create_pipe(struct ucred *cred, struct pipe *pipe,
1049101099Srwatson    struct label *pipelabel)
1050101099Srwatson{
1051101099Srwatson	struct mac_biba *source, *dest;
1052101099Srwatson
1053101099Srwatson	source = SLOT(&cred->cr_label);
1054101099Srwatson	dest = SLOT(pipelabel);
1055101099Srwatson
1056101099Srwatson	mac_biba_copy_single(source, dest);
1057101099Srwatson}
1058101099Srwatson
1059101099Srwatsonstatic void
1060101099Srwatsonmac_biba_create_socket_from_socket(struct socket *oldsocket,
1061101099Srwatson    struct label *oldsocketlabel, struct socket *newsocket,
1062101099Srwatson    struct label *newsocketlabel)
1063101099Srwatson{
1064101099Srwatson	struct mac_biba *source, *dest;
1065101099Srwatson
1066101099Srwatson	source = SLOT(oldsocketlabel);
1067101099Srwatson	dest = SLOT(newsocketlabel);
1068101099Srwatson
1069101099Srwatson	mac_biba_copy_single(source, dest);
1070101099Srwatson}
1071101099Srwatson
1072101099Srwatsonstatic void
1073101099Srwatsonmac_biba_relabel_socket(struct ucred *cred, struct socket *socket,
1074101099Srwatson    struct label *socketlabel, struct label *newlabel)
1075101099Srwatson{
1076101099Srwatson	struct mac_biba *source, *dest;
1077101099Srwatson
1078101099Srwatson	source = SLOT(newlabel);
1079101099Srwatson	dest = SLOT(socketlabel);
1080101099Srwatson
1081105656Srwatson	mac_biba_copy(source, dest);
1082101099Srwatson}
1083101099Srwatson
1084101099Srwatsonstatic void
1085101099Srwatsonmac_biba_relabel_pipe(struct ucred *cred, struct pipe *pipe,
1086101099Srwatson    struct label *pipelabel, struct label *newlabel)
1087101099Srwatson{
1088101099Srwatson	struct mac_biba *source, *dest;
1089101099Srwatson
1090101099Srwatson	source = SLOT(newlabel);
1091101099Srwatson	dest = SLOT(pipelabel);
1092101099Srwatson
1093105656Srwatson	mac_biba_copy(source, dest);
1094101099Srwatson}
1095101099Srwatson
1096101099Srwatsonstatic void
1097101099Srwatsonmac_biba_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel,
1098101099Srwatson    struct socket *socket, struct label *socketpeerlabel)
1099101099Srwatson{
1100101099Srwatson	struct mac_biba *source, *dest;
1101101099Srwatson
1102101099Srwatson	source = SLOT(mbuflabel);
1103101099Srwatson	dest = SLOT(socketpeerlabel);
1104101099Srwatson
1105101099Srwatson	mac_biba_copy_single(source, dest);
1106101099Srwatson}
1107101099Srwatson
1108101099Srwatson/*
1109101099Srwatson * Labeling event operations: network objects.
1110101099Srwatson */
1111101099Srwatsonstatic void
1112101099Srwatsonmac_biba_set_socket_peer_from_socket(struct socket *oldsocket,
1113101099Srwatson    struct label *oldsocketlabel, struct socket *newsocket,
1114101099Srwatson    struct label *newsocketpeerlabel)
1115101099Srwatson{
1116101099Srwatson	struct mac_biba *source, *dest;
1117101099Srwatson
1118101099Srwatson	source = SLOT(oldsocketlabel);
1119101099Srwatson	dest = SLOT(newsocketpeerlabel);
1120101099Srwatson
1121101099Srwatson	mac_biba_copy_single(source, dest);
1122101099Srwatson}
1123101099Srwatson
1124101099Srwatsonstatic void
1125101099Srwatsonmac_biba_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d,
1126101099Srwatson    struct label *bpflabel)
1127101099Srwatson{
1128101099Srwatson	struct mac_biba *source, *dest;
1129101099Srwatson
1130101099Srwatson	source = SLOT(&cred->cr_label);
1131101099Srwatson	dest = SLOT(bpflabel);
1132101099Srwatson
1133101099Srwatson	mac_biba_copy_single(source, dest);
1134101099Srwatson}
1135101099Srwatson
1136101099Srwatsonstatic void
1137101099Srwatsonmac_biba_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel)
1138101099Srwatson{
1139101099Srwatson	char tifname[IFNAMSIZ], ifname[IFNAMSIZ], *p, *q;
1140101099Srwatson	char tiflist[sizeof(trusted_interfaces)];
1141101099Srwatson	struct mac_biba *dest;
1142101099Srwatson	int len, grade;
1143101099Srwatson
1144101099Srwatson	dest = SLOT(ifnetlabel);
1145101099Srwatson
1146101099Srwatson	if (ifnet->if_type == IFT_LOOP) {
1147101099Srwatson		grade = MAC_BIBA_TYPE_EQUAL;
1148101099Srwatson		goto set;
1149101099Srwatson	}
1150101099Srwatson
1151101099Srwatson	if (trust_all_interfaces) {
1152101099Srwatson		grade = MAC_BIBA_TYPE_HIGH;
1153101099Srwatson		goto set;
1154101099Srwatson	}
1155101099Srwatson
1156101099Srwatson	grade = MAC_BIBA_TYPE_LOW;
1157101099Srwatson
1158101099Srwatson	if (trusted_interfaces[0] == '\0' ||
1159101099Srwatson	    !strvalid(trusted_interfaces, sizeof(trusted_interfaces)))
1160101099Srwatson		goto set;
1161101099Srwatson
1162106089Srwatson	bzero(tiflist, sizeof(tiflist));
1163101099Srwatson	for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++)
1164101099Srwatson		if(*p != ' ' && *p != '\t')
1165101099Srwatson			*q = *p;
1166101099Srwatson
1167101099Srwatson	snprintf(ifname, IFNAMSIZ, "%s%d", ifnet->if_name, ifnet->if_unit);
1168101099Srwatson
1169101099Srwatson	for (p = q = tiflist;; p++) {
1170101099Srwatson		if (*p == ',' || *p == '\0') {
1171101099Srwatson			len = p - q;
1172101099Srwatson			if (len < IFNAMSIZ) {
1173101099Srwatson				bzero(tifname, sizeof(tifname));
1174101099Srwatson				bcopy(q, tifname, len);
1175101099Srwatson				if (strcmp(tifname, ifname) == 0) {
1176101099Srwatson					grade = MAC_BIBA_TYPE_HIGH;
1177101099Srwatson					break;
1178101099Srwatson				}
1179106089Srwatson			} else {
1180106089Srwatson				*p = '\0';
1181106089Srwatson				printf("mac_biba warning: interface name "
1182106089Srwatson				    "\"%s\" is too long (must be < %d)\n",
1183106089Srwatson				    q, IFNAMSIZ);
1184101099Srwatson			}
1185101099Srwatson			if (*p == '\0')
1186101099Srwatson				break;
1187101099Srwatson			q = p + 1;
1188101099Srwatson		}
1189101099Srwatson	}
1190101099Srwatsonset:
1191105643Srwatson	mac_biba_set_single(dest, grade, 0, NULL);
1192105643Srwatson	mac_biba_set_range(dest, grade, 0, NULL, grade, 0, NULL);
1193101099Srwatson}
1194101099Srwatson
1195101099Srwatsonstatic void
1196101099Srwatsonmac_biba_create_ipq(struct mbuf *fragment, struct label *fragmentlabel,
1197101099Srwatson    struct ipq *ipq, struct label *ipqlabel)
1198101099Srwatson{
1199101099Srwatson	struct mac_biba *source, *dest;
1200101099Srwatson
1201101099Srwatson	source = SLOT(fragmentlabel);
1202101099Srwatson	dest = SLOT(ipqlabel);
1203101099Srwatson
1204101099Srwatson	mac_biba_copy_single(source, dest);
1205101099Srwatson}
1206101099Srwatson
1207101099Srwatsonstatic void
1208101099Srwatsonmac_biba_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel,
1209101099Srwatson    struct mbuf *datagram, struct label *datagramlabel)
1210101099Srwatson{
1211101099Srwatson	struct mac_biba *source, *dest;
1212101099Srwatson
1213101099Srwatson	source = SLOT(ipqlabel);
1214101099Srwatson	dest = SLOT(datagramlabel);
1215101099Srwatson
1216101099Srwatson	/* Just use the head, since we require them all to match. */
1217101099Srwatson	mac_biba_copy_single(source, dest);
1218101099Srwatson}
1219101099Srwatson
1220101099Srwatsonstatic void
1221101099Srwatsonmac_biba_create_fragment(struct mbuf *datagram, struct label *datagramlabel,
1222101099Srwatson    struct mbuf *fragment, struct label *fragmentlabel)
1223101099Srwatson{
1224101099Srwatson	struct mac_biba *source, *dest;
1225101099Srwatson
1226101099Srwatson	source = SLOT(datagramlabel);
1227101099Srwatson	dest = SLOT(fragmentlabel);
1228101099Srwatson
1229101099Srwatson	mac_biba_copy_single(source, dest);
1230101099Srwatson}
1231101099Srwatson
1232101099Srwatsonstatic void
1233101099Srwatsonmac_biba_create_mbuf_from_mbuf(struct mbuf *oldmbuf,
1234101099Srwatson    struct label *oldmbuflabel, struct mbuf *newmbuf,
1235101099Srwatson    struct label *newmbuflabel)
1236101099Srwatson{
1237101099Srwatson	struct mac_biba *source, *dest;
1238101099Srwatson
1239101099Srwatson	source = SLOT(oldmbuflabel);
1240101099Srwatson	dest = SLOT(newmbuflabel);
1241101099Srwatson
1242105656Srwatson	/*
1243105656Srwatson	 * Because the source mbuf may not yet have been "created",
1244105696Srwatson	 * just initialized, we do a conditional copy.  Since we don't
1245105656Srwatson	 * allow mbufs to have ranges, do a KASSERT to make sure that
1246105656Srwatson	 * doesn't happen.
1247105656Srwatson	 */
1248105656Srwatson	KASSERT((source->mb_flags & MAC_BIBA_FLAG_RANGE) == 0,
1249105656Srwatson	    ("mac_biba_create_mbuf_from_mbuf: source mbuf has range"));
1250105656Srwatson	mac_biba_copy(source, dest);
1251101099Srwatson}
1252101099Srwatson
1253101099Srwatsonstatic void
1254101099Srwatsonmac_biba_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel,
1255101099Srwatson    struct mbuf *mbuf, struct label *mbuflabel)
1256101099Srwatson{
1257101099Srwatson	struct mac_biba *dest;
1258101099Srwatson
1259101099Srwatson	dest = SLOT(mbuflabel);
1260101099Srwatson
1261105643Srwatson	mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1262101099Srwatson}
1263101099Srwatson
1264101099Srwatsonstatic void
1265101099Srwatsonmac_biba_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel,
1266101099Srwatson    struct mbuf *mbuf, struct label *mbuflabel)
1267101099Srwatson{
1268101099Srwatson	struct mac_biba *source, *dest;
1269101099Srwatson
1270101099Srwatson	source = SLOT(bpflabel);
1271101099Srwatson	dest = SLOT(mbuflabel);
1272101099Srwatson
1273101099Srwatson	mac_biba_copy_single(source, dest);
1274101099Srwatson}
1275101099Srwatson
1276101099Srwatsonstatic void
1277101099Srwatsonmac_biba_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel,
1278101099Srwatson    struct mbuf *m, struct label *mbuflabel)
1279101099Srwatson{
1280101099Srwatson	struct mac_biba *source, *dest;
1281101099Srwatson
1282101099Srwatson	source = SLOT(ifnetlabel);
1283101099Srwatson	dest = SLOT(mbuflabel);
1284101099Srwatson
1285101099Srwatson	mac_biba_copy_single(source, dest);
1286101099Srwatson}
1287101099Srwatson
1288101099Srwatsonstatic void
1289101099Srwatsonmac_biba_create_mbuf_multicast_encap(struct mbuf *oldmbuf,
1290101099Srwatson    struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel,
1291101099Srwatson    struct mbuf *newmbuf, struct label *newmbuflabel)
1292101099Srwatson{
1293101099Srwatson	struct mac_biba *source, *dest;
1294101099Srwatson
1295101099Srwatson	source = SLOT(oldmbuflabel);
1296101099Srwatson	dest = SLOT(newmbuflabel);
1297101099Srwatson
1298101099Srwatson	mac_biba_copy_single(source, dest);
1299101099Srwatson}
1300101099Srwatson
1301101099Srwatsonstatic void
1302101099Srwatsonmac_biba_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel,
1303101099Srwatson    struct mbuf *newmbuf, struct label *newmbuflabel)
1304101099Srwatson{
1305101099Srwatson	struct mac_biba *source, *dest;
1306101099Srwatson
1307101099Srwatson	source = SLOT(oldmbuflabel);
1308101099Srwatson	dest = SLOT(newmbuflabel);
1309101099Srwatson
1310101099Srwatson	mac_biba_copy_single(source, dest);
1311101099Srwatson}
1312101099Srwatson
1313101099Srwatsonstatic int
1314101099Srwatsonmac_biba_fragment_match(struct mbuf *fragment, struct label *fragmentlabel,
1315101099Srwatson    struct ipq *ipq, struct label *ipqlabel)
1316101099Srwatson{
1317101099Srwatson	struct mac_biba *a, *b;
1318101099Srwatson
1319101099Srwatson	a = SLOT(ipqlabel);
1320101099Srwatson	b = SLOT(fragmentlabel);
1321101099Srwatson
1322101099Srwatson	return (mac_biba_equal_single(a, b));
1323101099Srwatson}
1324101099Srwatson
1325101099Srwatsonstatic void
1326101099Srwatsonmac_biba_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet,
1327101099Srwatson    struct label *ifnetlabel, struct label *newlabel)
1328101099Srwatson{
1329101099Srwatson	struct mac_biba *source, *dest;
1330101099Srwatson
1331101099Srwatson	source = SLOT(newlabel);
1332101099Srwatson	dest = SLOT(ifnetlabel);
1333101099Srwatson
1334105656Srwatson	mac_biba_copy(source, dest);
1335101099Srwatson}
1336101099Srwatson
1337101099Srwatsonstatic void
1338101099Srwatsonmac_biba_update_ipq(struct mbuf *fragment, struct label *fragmentlabel,
1339101099Srwatson    struct ipq *ipq, struct label *ipqlabel)
1340101099Srwatson{
1341101099Srwatson
1342101099Srwatson	/* NOOP: we only accept matching labels, so no need to update */
1343101099Srwatson}
1344101099Srwatson
1345101099Srwatson/*
1346101099Srwatson * Labeling event operations: processes.
1347101099Srwatson */
1348101099Srwatsonstatic void
1349101099Srwatsonmac_biba_create_cred(struct ucred *cred_parent, struct ucred *cred_child)
1350101099Srwatson{
1351101099Srwatson	struct mac_biba *source, *dest;
1352101099Srwatson
1353101099Srwatson	source = SLOT(&cred_parent->cr_label);
1354101099Srwatson	dest = SLOT(&cred_child->cr_label);
1355101099Srwatson
1356101099Srwatson	mac_biba_copy_single(source, dest);
1357101099Srwatson	mac_biba_copy_range(source, dest);
1358101099Srwatson}
1359101099Srwatson
1360101099Srwatsonstatic void
1361101099Srwatsonmac_biba_execve_transition(struct ucred *old, struct ucred *new,
1362101099Srwatson    struct vnode *vp, struct mac *vnodelabel)
1363101099Srwatson{
1364101099Srwatson	struct mac_biba *source, *dest;
1365101099Srwatson
1366101099Srwatson	source = SLOT(&old->cr_label);
1367101099Srwatson	dest = SLOT(&new->cr_label);
1368101099Srwatson
1369101099Srwatson	mac_biba_copy_single(source, dest);
1370101099Srwatson	mac_biba_copy_range(source, dest);
1371101099Srwatson}
1372101099Srwatson
1373101099Srwatsonstatic int
1374101099Srwatsonmac_biba_execve_will_transition(struct ucred *old, struct vnode *vp,
1375101099Srwatson    struct mac *vnodelabel)
1376101099Srwatson{
1377101099Srwatson
1378101099Srwatson	return (0);
1379101099Srwatson}
1380101099Srwatson
1381101099Srwatsonstatic void
1382101099Srwatsonmac_biba_create_proc0(struct ucred *cred)
1383101099Srwatson{
1384101099Srwatson	struct mac_biba *dest;
1385101099Srwatson
1386101099Srwatson	dest = SLOT(&cred->cr_label);
1387101099Srwatson
1388105643Srwatson	mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1389105643Srwatson	mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL,
1390105643Srwatson	    MAC_BIBA_TYPE_HIGH, 0, NULL);
1391101099Srwatson}
1392101099Srwatson
1393101099Srwatsonstatic void
1394101099Srwatsonmac_biba_create_proc1(struct ucred *cred)
1395101099Srwatson{
1396101099Srwatson	struct mac_biba *dest;
1397101099Srwatson
1398101099Srwatson	dest = SLOT(&cred->cr_label);
1399101099Srwatson
1400105643Srwatson	mac_biba_set_single(dest, MAC_BIBA_TYPE_HIGH, 0, NULL);
1401105643Srwatson	mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL,
1402105643Srwatson	    MAC_BIBA_TYPE_HIGH, 0, NULL);
1403101099Srwatson}
1404101099Srwatson
1405101099Srwatsonstatic void
1406101099Srwatsonmac_biba_relabel_cred(struct ucred *cred, struct label *newlabel)
1407101099Srwatson{
1408101099Srwatson	struct mac_biba *source, *dest;
1409101099Srwatson
1410101099Srwatson	source = SLOT(newlabel);
1411101099Srwatson	dest = SLOT(&cred->cr_label);
1412101099Srwatson
1413105656Srwatson	mac_biba_copy(source, dest);
1414101099Srwatson}
1415101099Srwatson
1416101099Srwatson/*
1417101099Srwatson * Access control checks.
1418101099Srwatson */
1419101099Srwatsonstatic int
1420101099Srwatsonmac_biba_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel,
1421101099Srwatson    struct ifnet *ifnet, struct label *ifnetlabel)
1422101099Srwatson{
1423101099Srwatson	struct mac_biba *a, *b;
1424101099Srwatson
1425101099Srwatson	if (!mac_biba_enabled)
1426101099Srwatson		return (0);
1427101099Srwatson
1428101099Srwatson	a = SLOT(bpflabel);
1429101099Srwatson	b = SLOT(ifnetlabel);
1430101099Srwatson
1431101099Srwatson	if (mac_biba_equal_single(a, b))
1432101099Srwatson		return (0);
1433101099Srwatson	return (EACCES);
1434101099Srwatson}
1435101099Srwatson
1436101099Srwatsonstatic int
1437101099Srwatsonmac_biba_check_cred_relabel(struct ucred *cred, struct label *newlabel)
1438101099Srwatson{
1439101099Srwatson	struct mac_biba *subj, *new;
1440105634Srwatson	int error;
1441101099Srwatson
1442101099Srwatson	subj = SLOT(&cred->cr_label);
1443101099Srwatson	new = SLOT(newlabel);
1444101099Srwatson
1445101099Srwatson	/*
1446105634Srwatson	 * If there is a Biba label update for the credential, it may
1447105634Srwatson	 * be an update of the single, range, or both.
1448101099Srwatson	 */
1449105634Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
1450105634Srwatson	if (error)
1451105634Srwatson		return (error);
1452101099Srwatson
1453101099Srwatson	/*
1454105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
1455101099Srwatson	 */
1456105634Srwatson	if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) {
1457105634Srwatson		/*
1458105634Srwatson		 * To change the Biba single label on a credential, the
1459105634Srwatson		 * new single label must be in the current range.
1460105634Srwatson		 */
1461105634Srwatson		if (new->mb_flags & MAC_BIBA_FLAG_SINGLE &&
1462105634Srwatson		    !mac_biba_single_in_range(new, subj))
1463105634Srwatson			return (EPERM);
1464101099Srwatson
1465105634Srwatson		/*
1466105634Srwatson		 * To change the Biba range on a credential, the new
1467105634Srwatson		 * range label must be in the current range.
1468105634Srwatson		 */
1469105634Srwatson		if (new->mb_flags & MAC_BIBA_FLAG_RANGE &&
1470105634Srwatson		    !mac_biba_range_in_range(new, subj))
1471105634Srwatson			return (EPERM);
1472101099Srwatson
1473105634Srwatson		/*
1474105634Srwatson		 * To have EQUAL in any component of the new credential
1475105634Srwatson		 * Biba label, the subject must already have EQUAL in
1476105634Srwatson		 * their label.
1477105634Srwatson		 */
1478105634Srwatson		if (mac_biba_contains_equal(new)) {
1479106090Srwatson			error = mac_biba_subject_privileged(subj);
1480105634Srwatson			if (error)
1481105634Srwatson				return (error);
1482105634Srwatson		}
1483101099Srwatson
1484105634Srwatson		/*
1485105634Srwatson		 * XXXMAC: Additional consistency tests regarding the
1486105634Srwatson		 * single and range of the new label might be performed
1487105634Srwatson		 * here.
1488105634Srwatson		 */
1489105634Srwatson	}
1490105634Srwatson
1491101099Srwatson	return (0);
1492101099Srwatson}
1493101099Srwatson
1494101099Srwatsonstatic int
1495101099Srwatsonmac_biba_check_cred_visible(struct ucred *u1, struct ucred *u2)
1496101099Srwatson{
1497101099Srwatson	struct mac_biba *subj, *obj;
1498101099Srwatson
1499101099Srwatson	if (!mac_biba_enabled)
1500101099Srwatson		return (0);
1501101099Srwatson
1502101099Srwatson	subj = SLOT(&u1->cr_label);
1503101099Srwatson	obj = SLOT(&u2->cr_label);
1504101099Srwatson
1505101099Srwatson	/* XXX: range */
1506101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1507101099Srwatson		return (ESRCH);
1508101099Srwatson
1509101099Srwatson	return (0);
1510101099Srwatson}
1511101099Srwatson
1512101099Srwatsonstatic int
1513101099Srwatsonmac_biba_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet,
1514101099Srwatson    struct label *ifnetlabel, struct label *newlabel)
1515101099Srwatson{
1516101099Srwatson	struct mac_biba *subj, *new;
1517105634Srwatson	int error;
1518101099Srwatson
1519101099Srwatson	subj = SLOT(&cred->cr_label);
1520101099Srwatson	new = SLOT(newlabel);
1521101099Srwatson
1522105634Srwatson	/*
1523105634Srwatson	 * If there is a Biba label update for the interface, it may
1524105634Srwatson	 * be an update of the single, range, or both.
1525105634Srwatson	 */
1526105634Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
1527105634Srwatson	if (error)
1528105634Srwatson		return (error);
1529101099Srwatson
1530105634Srwatson	/*
1531105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
1532105634Srwatson	 */
1533105634Srwatson	if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) {
1534105634Srwatson		/*
1535105634Srwatson		 * Rely on the traditional superuser status for the Biba
1536105634Srwatson		 * interface relabel requirements.  XXXMAC: This will go
1537105634Srwatson		 * away.
1538105634Srwatson		 */
1539105634Srwatson		error = suser_cred(cred, 0);
1540105634Srwatson		if (error)
1541105634Srwatson			return (EPERM);
1542105634Srwatson
1543105634Srwatson		/*
1544105634Srwatson		 * XXXMAC: Additional consistency tests regarding the single
1545105634Srwatson		 * and the range of the new label might be performed here.
1546105634Srwatson		 */
1547105634Srwatson	}
1548105634Srwatson
1549105634Srwatson	return (0);
1550101099Srwatson}
1551101099Srwatson
1552103759Srwatsonstatic int
1553101099Srwatsonmac_biba_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel,
1554101099Srwatson    struct mbuf *m, struct label *mbuflabel)
1555101099Srwatson{
1556101099Srwatson	struct mac_biba *p, *i;
1557103761Srwatson
1558101099Srwatson	if (!mac_biba_enabled)
1559101099Srwatson		return (0);
1560101099Srwatson
1561101099Srwatson	p = SLOT(mbuflabel);
1562101099Srwatson	i = SLOT(ifnetlabel);
1563103759Srwatson
1564101099Srwatson	return (mac_biba_single_in_range(p, i) ? 0 : EACCES);
1565101099Srwatson}
1566101099Srwatson
1567101099Srwatsonstatic int
1568101099Srwatsonmac_biba_check_mount_stat(struct ucred *cred, struct mount *mp,
1569101099Srwatson    struct label *mntlabel)
1570101099Srwatson{
1571101099Srwatson	struct mac_biba *subj, *obj;
1572101099Srwatson
1573101099Srwatson	if (!mac_biba_enabled)
1574101099Srwatson		return (0);
1575101099Srwatson
1576101099Srwatson	subj = SLOT(&cred->cr_label);
1577101099Srwatson	obj = SLOT(mntlabel);
1578101099Srwatson
1579101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1580101099Srwatson		return (EACCES);
1581101099Srwatson
1582101099Srwatson	return (0);
1583101099Srwatson}
1584101099Srwatson
1585101099Srwatsonstatic int
1586101099Srwatsonmac_biba_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe,
1587101099Srwatson    struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data)
1588101099Srwatson{
1589103759Srwatson
1590101099Srwatson	if(!mac_biba_enabled)
1591101099Srwatson		return (0);
1592101099Srwatson
1593101099Srwatson	/* XXX: This will be implemented soon... */
1594101099Srwatson
1595101099Srwatson	return (0);
1596101099Srwatson}
1597101099Srwatson
1598101099Srwatsonstatic int
1599102115Srwatsonmac_biba_check_pipe_poll(struct ucred *cred, struct pipe *pipe,
1600102115Srwatson    struct label *pipelabel)
1601101099Srwatson{
1602101099Srwatson	struct mac_biba *subj, *obj;
1603101099Srwatson
1604101099Srwatson	if (!mac_biba_enabled)
1605101099Srwatson		return (0);
1606101099Srwatson
1607101099Srwatson	subj = SLOT(&cred->cr_label);
1608101099Srwatson	obj = SLOT((pipelabel));
1609101099Srwatson
1610102115Srwatson	if (!mac_biba_dominate_single(obj, subj))
1611102115Srwatson		return (EACCES);
1612101099Srwatson
1613101099Srwatson	return (0);
1614101099Srwatson}
1615101099Srwatson
1616101099Srwatsonstatic int
1617102115Srwatsonmac_biba_check_pipe_read(struct ucred *cred, struct pipe *pipe,
1618102115Srwatson    struct label *pipelabel)
1619102115Srwatson{
1620102115Srwatson	struct mac_biba *subj, *obj;
1621102115Srwatson
1622102115Srwatson	if (!mac_biba_enabled)
1623102115Srwatson		return (0);
1624102115Srwatson
1625102115Srwatson	subj = SLOT(&cred->cr_label);
1626102115Srwatson	obj = SLOT((pipelabel));
1627102115Srwatson
1628102115Srwatson	if (!mac_biba_dominate_single(obj, subj))
1629102115Srwatson		return (EACCES);
1630102115Srwatson
1631102115Srwatson	return (0);
1632102115Srwatson}
1633102115Srwatson
1634102115Srwatsonstatic int
1635101099Srwatsonmac_biba_check_pipe_relabel(struct ucred *cred, struct pipe *pipe,
1636101099Srwatson    struct label *pipelabel, struct label *newlabel)
1637101099Srwatson{
1638101099Srwatson	struct mac_biba *subj, *obj, *new;
1639105634Srwatson	int error;
1640101099Srwatson
1641101099Srwatson	new = SLOT(newlabel);
1642101099Srwatson	subj = SLOT(&cred->cr_label);
1643101099Srwatson	obj = SLOT(pipelabel);
1644101099Srwatson
1645101099Srwatson	/*
1646105634Srwatson	 * If there is a Biba label update for a pipe, it must be a
1647105634Srwatson	 * single update.
1648101099Srwatson	 */
1649105634Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE);
1650105634Srwatson	if (error)
1651105634Srwatson		return (error);
1652101099Srwatson
1653101099Srwatson	/*
1654105634Srwatson	 * To perform a relabel of a pipe (Biba label or not), Biba must
1655105634Srwatson	 * authorize the relabel.
1656101099Srwatson	 */
1657105634Srwatson	if (!mac_biba_single_in_range(obj, subj))
1658101099Srwatson		return (EPERM);
1659101099Srwatson
1660101099Srwatson	/*
1661105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
1662101099Srwatson	 */
1663105634Srwatson	if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) {
1664105634Srwatson		/*
1665105634Srwatson		 * To change the Biba label on a pipe, the new pipe label
1666105634Srwatson		 * must be in the subject range.
1667105634Srwatson		 */
1668105634Srwatson		if (!mac_biba_single_in_range(new, subj))
1669105634Srwatson			return (EPERM);
1670101099Srwatson
1671105634Srwatson		/*
1672105634Srwatson		 * To change the Biba label on a pipe to be EQUAL, the
1673105634Srwatson		 * subject must have appropriate privilege.
1674105634Srwatson		 */
1675105634Srwatson		if (mac_biba_contains_equal(new)) {
1676106090Srwatson			error = mac_biba_subject_privileged(subj);
1677105634Srwatson			if (error)
1678105634Srwatson				return (error);
1679105634Srwatson		}
1680105634Srwatson	}
1681105634Srwatson
1682101099Srwatson	return (0);
1683101099Srwatson}
1684101099Srwatson
1685101099Srwatsonstatic int
1686102115Srwatsonmac_biba_check_pipe_stat(struct ucred *cred, struct pipe *pipe,
1687102115Srwatson    struct label *pipelabel)
1688102115Srwatson{
1689102115Srwatson	struct mac_biba *subj, *obj;
1690102115Srwatson
1691102115Srwatson	if (!mac_biba_enabled)
1692102115Srwatson		return (0);
1693102115Srwatson
1694102115Srwatson	subj = SLOT(&cred->cr_label);
1695102115Srwatson	obj = SLOT((pipelabel));
1696102115Srwatson
1697102115Srwatson	if (!mac_biba_dominate_single(obj, subj))
1698102115Srwatson		return (EACCES);
1699102115Srwatson
1700102115Srwatson	return (0);
1701102115Srwatson}
1702102115Srwatson
1703102115Srwatsonstatic int
1704102115Srwatsonmac_biba_check_pipe_write(struct ucred *cred, struct pipe *pipe,
1705102115Srwatson    struct label *pipelabel)
1706102115Srwatson{
1707102115Srwatson	struct mac_biba *subj, *obj;
1708102115Srwatson
1709102115Srwatson	if (!mac_biba_enabled)
1710102115Srwatson		return (0);
1711102115Srwatson
1712102115Srwatson	subj = SLOT(&cred->cr_label);
1713102115Srwatson	obj = SLOT((pipelabel));
1714102115Srwatson
1715102115Srwatson	if (!mac_biba_dominate_single(subj, obj))
1716102115Srwatson		return (EACCES);
1717102115Srwatson
1718102115Srwatson	return (0);
1719102115Srwatson}
1720102115Srwatson
1721102115Srwatsonstatic int
1722101099Srwatsonmac_biba_check_proc_debug(struct ucred *cred, struct proc *proc)
1723101099Srwatson{
1724101099Srwatson	struct mac_biba *subj, *obj;
1725101099Srwatson
1726101099Srwatson	if (!mac_biba_enabled)
1727101099Srwatson		return (0);
1728101099Srwatson
1729101099Srwatson	subj = SLOT(&cred->cr_label);
1730101099Srwatson	obj = SLOT(&proc->p_ucred->cr_label);
1731101099Srwatson
1732101099Srwatson	/* XXX: range checks */
1733101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1734101099Srwatson		return (ESRCH);
1735101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1736101099Srwatson		return (EACCES);
1737101099Srwatson
1738101099Srwatson	return (0);
1739101099Srwatson}
1740101099Srwatson
1741101099Srwatsonstatic int
1742101099Srwatsonmac_biba_check_proc_sched(struct ucred *cred, struct proc *proc)
1743101099Srwatson{
1744101099Srwatson	struct mac_biba *subj, *obj;
1745103759Srwatson
1746101099Srwatson	if (!mac_biba_enabled)
1747101099Srwatson		return (0);
1748101099Srwatson
1749101099Srwatson	subj = SLOT(&cred->cr_label);
1750101099Srwatson	obj = SLOT(&proc->p_ucred->cr_label);
1751103759Srwatson
1752101099Srwatson	/* XXX: range checks */
1753101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1754101099Srwatson		return (ESRCH);
1755101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1756101099Srwatson		return (EACCES);
1757101099Srwatson
1758101099Srwatson	return (0);
1759101099Srwatson}
1760101099Srwatson
1761101099Srwatsonstatic int
1762101099Srwatsonmac_biba_check_proc_signal(struct ucred *cred, struct proc *proc, int signum)
1763101099Srwatson{
1764101099Srwatson	struct mac_biba *subj, *obj;
1765103759Srwatson
1766101099Srwatson	if (!mac_biba_enabled)
1767101099Srwatson		return (0);
1768101099Srwatson
1769101099Srwatson	subj = SLOT(&cred->cr_label);
1770101099Srwatson	obj = SLOT(&proc->p_ucred->cr_label);
1771103759Srwatson
1772101099Srwatson	/* XXX: range checks */
1773101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1774101099Srwatson		return (ESRCH);
1775101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1776101099Srwatson		return (EACCES);
1777101099Srwatson
1778101099Srwatson	return (0);
1779101099Srwatson}
1780101099Srwatson
1781101099Srwatsonstatic int
1782101934Srwatsonmac_biba_check_socket_deliver(struct socket *so, struct label *socketlabel,
1783101099Srwatson    struct mbuf *m, struct label *mbuflabel)
1784101099Srwatson{
1785101099Srwatson	struct mac_biba *p, *s;
1786101099Srwatson
1787101099Srwatson	if (!mac_biba_enabled)
1788101099Srwatson		return (0);
1789101099Srwatson
1790101099Srwatson	p = SLOT(mbuflabel);
1791101099Srwatson	s = SLOT(socketlabel);
1792101099Srwatson
1793101099Srwatson	return (mac_biba_equal_single(p, s) ? 0 : EACCES);
1794101099Srwatson}
1795101099Srwatson
1796101099Srwatsonstatic int
1797101099Srwatsonmac_biba_check_socket_relabel(struct ucred *cred, struct socket *socket,
1798101099Srwatson    struct label *socketlabel, struct label *newlabel)
1799101099Srwatson{
1800101099Srwatson	struct mac_biba *subj, *obj, *new;
1801105634Srwatson	int error;
1802101099Srwatson
1803101099Srwatson	new = SLOT(newlabel);
1804101099Srwatson	subj = SLOT(&cred->cr_label);
1805101099Srwatson	obj = SLOT(socketlabel);
1806101099Srwatson
1807101099Srwatson	/*
1808105634Srwatson	 * If there is a Biba label update for the socket, it may be
1809105634Srwatson	 * an update of single.
1810101099Srwatson	 */
1811105634Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE);
1812105634Srwatson	if (error)
1813105634Srwatson		return (error);
1814101099Srwatson
1815101099Srwatson	/*
1816105634Srwatson	 * To relabel a socket, the old socket single must be in the subject
1817101099Srwatson	 * range.
1818101099Srwatson	 */
1819105634Srwatson	if (!mac_biba_single_in_range(obj, subj))
1820101099Srwatson		return (EPERM);
1821101099Srwatson
1822101099Srwatson	/*
1823105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
1824101099Srwatson	 */
1825105634Srwatson	if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) {
1826105634Srwatson		/*
1827105634Srwatson		 * To relabel a socket, the new socket single must be in
1828105634Srwatson		 * the subject range.
1829105634Srwatson		 */
1830105634Srwatson		if (!mac_biba_single_in_range(new, subj))
1831105634Srwatson			return (EPERM);
1832101099Srwatson
1833105634Srwatson		/*
1834105634Srwatson		 * To change the Biba label on the socket to contain EQUAL,
1835105634Srwatson		 * the subject must have appropriate privilege.
1836105634Srwatson		 */
1837105634Srwatson		if (mac_biba_contains_equal(new)) {
1838106090Srwatson			error = mac_biba_subject_privileged(subj);
1839105634Srwatson			if (error)
1840105634Srwatson				return (error);
1841105634Srwatson		}
1842105634Srwatson	}
1843105634Srwatson
1844101099Srwatson	return (0);
1845101099Srwatson}
1846101099Srwatson
1847101099Srwatsonstatic int
1848101099Srwatsonmac_biba_check_socket_visible(struct ucred *cred, struct socket *socket,
1849101099Srwatson    struct label *socketlabel)
1850101099Srwatson{
1851101099Srwatson	struct mac_biba *subj, *obj;
1852101099Srwatson
1853105722Srwatson	if (!mac_biba_enabled)
1854105722Srwatson		return (0);
1855105722Srwatson
1856101099Srwatson	subj = SLOT(&cred->cr_label);
1857101099Srwatson	obj = SLOT(socketlabel);
1858101099Srwatson
1859101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1860101099Srwatson		return (ENOENT);
1861101099Srwatson
1862101099Srwatson	return (0);
1863101099Srwatson}
1864101099Srwatson
1865101099Srwatsonstatic int
1866101099Srwatsonmac_biba_check_vnode_chdir(struct ucred *cred, struct vnode *dvp,
1867101099Srwatson    struct label *dlabel)
1868101099Srwatson{
1869101099Srwatson	struct mac_biba *subj, *obj;
1870101099Srwatson
1871101099Srwatson	if (!mac_biba_enabled)
1872101099Srwatson		return (0);
1873101099Srwatson
1874101099Srwatson	subj = SLOT(&cred->cr_label);
1875101099Srwatson	obj = SLOT(dlabel);
1876101099Srwatson
1877101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1878101099Srwatson		return (EACCES);
1879101099Srwatson
1880101099Srwatson	return (0);
1881101099Srwatson}
1882101099Srwatson
1883101099Srwatsonstatic int
1884101099Srwatsonmac_biba_check_vnode_chroot(struct ucred *cred, struct vnode *dvp,
1885101099Srwatson    struct label *dlabel)
1886101099Srwatson{
1887101099Srwatson	struct mac_biba *subj, *obj;
1888101099Srwatson
1889101099Srwatson	if (!mac_biba_enabled)
1890101099Srwatson		return (0);
1891101099Srwatson
1892101099Srwatson	subj = SLOT(&cred->cr_label);
1893101099Srwatson	obj = SLOT(dlabel);
1894101099Srwatson
1895101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1896101099Srwatson		return (EACCES);
1897101099Srwatson
1898101099Srwatson	return (0);
1899101099Srwatson}
1900101099Srwatson
1901101099Srwatsonstatic int
1902101099Srwatsonmac_biba_check_vnode_create(struct ucred *cred, struct vnode *dvp,
1903101099Srwatson    struct label *dlabel, struct componentname *cnp, struct vattr *vap)
1904101099Srwatson{
1905101099Srwatson	struct mac_biba *subj, *obj;
1906101099Srwatson
1907101099Srwatson	if (!mac_biba_enabled)
1908101099Srwatson		return (0);
1909101099Srwatson
1910101099Srwatson	subj = SLOT(&cred->cr_label);
1911101099Srwatson	obj = SLOT(dlabel);
1912101099Srwatson
1913101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1914101099Srwatson		return (EACCES);
1915101099Srwatson
1916101099Srwatson	return (0);
1917101099Srwatson}
1918101099Srwatson
1919101099Srwatsonstatic int
1920101099Srwatsonmac_biba_check_vnode_delete(struct ucred *cred, struct vnode *dvp,
1921101099Srwatson    struct label *dlabel, struct vnode *vp, struct label *label,
1922101099Srwatson    struct componentname *cnp)
1923101099Srwatson{
1924101099Srwatson	struct mac_biba *subj, *obj;
1925101099Srwatson
1926101099Srwatson	if (!mac_biba_enabled)
1927101099Srwatson		return (0);
1928101099Srwatson
1929101099Srwatson	subj = SLOT(&cred->cr_label);
1930101099Srwatson	obj = SLOT(dlabel);
1931101099Srwatson
1932101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1933101099Srwatson		return (EACCES);
1934101099Srwatson
1935101099Srwatson	obj = SLOT(label);
1936101099Srwatson
1937101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1938101099Srwatson		return (EACCES);
1939101099Srwatson
1940101099Srwatson	return (0);
1941101099Srwatson}
1942101099Srwatson
1943101099Srwatsonstatic int
1944101099Srwatsonmac_biba_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
1945101099Srwatson    struct label *label, acl_type_t type)
1946101099Srwatson{
1947101099Srwatson	struct mac_biba *subj, *obj;
1948101099Srwatson
1949101099Srwatson	if (!mac_biba_enabled)
1950101099Srwatson		return (0);
1951101099Srwatson
1952101099Srwatson	subj = SLOT(&cred->cr_label);
1953101099Srwatson	obj = SLOT(label);
1954101099Srwatson
1955101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1956101099Srwatson		return (EACCES);
1957101099Srwatson
1958101099Srwatson	return (0);
1959101099Srwatson}
1960101099Srwatson
1961101099Srwatsonstatic int
1962101099Srwatsonmac_biba_check_vnode_exec(struct ucred *cred, struct vnode *vp,
1963101099Srwatson    struct label *label)
1964101099Srwatson{
1965101099Srwatson	struct mac_biba *subj, *obj;
1966101099Srwatson
1967101099Srwatson	if (!mac_biba_enabled)
1968101099Srwatson		return (0);
1969101099Srwatson
1970101099Srwatson	subj = SLOT(&cred->cr_label);
1971101099Srwatson	obj = SLOT(label);
1972101099Srwatson
1973101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1974101099Srwatson		return (EACCES);
1975101099Srwatson
1976101099Srwatson	return (0);
1977101099Srwatson}
1978101099Srwatson
1979101099Srwatsonstatic int
1980101099Srwatsonmac_biba_check_vnode_getacl(struct ucred *cred, struct vnode *vp,
1981101099Srwatson    struct label *label, acl_type_t type)
1982101099Srwatson{
1983101099Srwatson	struct mac_biba *subj, *obj;
1984101099Srwatson
1985101099Srwatson	if (!mac_biba_enabled)
1986101099Srwatson		return (0);
1987101099Srwatson
1988101099Srwatson	subj = SLOT(&cred->cr_label);
1989101099Srwatson	obj = SLOT(label);
1990101099Srwatson
1991101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1992101099Srwatson		return (EACCES);
1993101099Srwatson
1994101099Srwatson	return (0);
1995101099Srwatson}
1996101099Srwatson
1997101099Srwatsonstatic int
1998101099Srwatsonmac_biba_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
1999101099Srwatson    struct label *label, int attrnamespace, const char *name, struct uio *uio)
2000101099Srwatson{
2001101099Srwatson	struct mac_biba *subj, *obj;
2002101099Srwatson
2003101099Srwatson	if (!mac_biba_enabled)
2004101099Srwatson		return (0);
2005101099Srwatson
2006101099Srwatson	subj = SLOT(&cred->cr_label);
2007101099Srwatson	obj = SLOT(label);
2008101099Srwatson
2009101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
2010101099Srwatson		return (EACCES);
2011101099Srwatson
2012101099Srwatson	return (0);
2013101099Srwatson}
2014101099Srwatson
2015101099Srwatsonstatic int
2016104530Srwatsonmac_biba_check_vnode_link(struct ucred *cred, struct vnode *dvp,
2017104530Srwatson    struct label *dlabel, struct vnode *vp, struct label *label,
2018104530Srwatson    struct componentname *cnp)
2019104530Srwatson{
2020104530Srwatson	struct mac_biba *subj, *obj;
2021104530Srwatson
2022104530Srwatson	if (!mac_biba_enabled)
2023104530Srwatson		return (0);
2024104530Srwatson
2025104530Srwatson	subj = SLOT(&cred->cr_label);
2026104530Srwatson	obj = SLOT(dlabel);
2027104530Srwatson
2028104530Srwatson	if (!mac_biba_dominate_single(subj, obj))
2029104530Srwatson		return (EACCES);
2030104530Srwatson
2031104530Srwatson	obj = SLOT(label);
2032104530Srwatson
2033104530Srwatson	if (!mac_biba_dominate_single(subj, obj))
2034104530Srwatson		return (EACCES);
2035104530Srwatson
2036104530Srwatson	return (0);
2037104530Srwatson}
2038104530Srwatson
2039104530Srwatsonstatic int
2040103759Srwatsonmac_biba_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
2041101099Srwatson    struct label *dlabel, struct componentname *cnp)
2042101099Srwatson{
2043101099Srwatson	struct mac_biba *subj, *obj;
2044103759Srwatson
2045101099Srwatson	if (!mac_biba_enabled)
2046101099Srwatson		return (0);
2047103759Srwatson
2048101099Srwatson	subj = SLOT(&cred->cr_label);
2049101099Srwatson	obj = SLOT(dlabel);
2050103759Srwatson
2051101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
2052101099Srwatson		return (EACCES);
2053101099Srwatson
2054103759Srwatson	return (0);
2055101099Srwatson}
2056101099Srwatson
2057101099Srwatsonstatic int
2058104546Srwatsonmac_biba_check_vnode_mmap(struct ucred *cred, struct vnode *vp,
2059104546Srwatson    struct label *label, int prot)
2060104546Srwatson{
2061104546Srwatson	struct mac_biba *subj, *obj;
2062104546Srwatson
2063104546Srwatson	/*
2064104546Srwatson	 * Rely on the use of open()-time protections to handle
2065104546Srwatson	 * non-revocation cases.
2066104546Srwatson	 */
2067105637Srwatson	if (!mac_biba_enabled || !revocation_enabled)
2068104546Srwatson		return (0);
2069104546Srwatson
2070104546Srwatson	subj = SLOT(&cred->cr_label);
2071104546Srwatson	obj = SLOT(label);
2072104546Srwatson
2073104546Srwatson	if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
2074104546Srwatson		if (!mac_biba_dominate_single(obj, subj))
2075104546Srwatson			return (EACCES);
2076104546Srwatson	}
2077104546Srwatson	if (prot & VM_PROT_WRITE) {
2078104546Srwatson		if (!mac_biba_dominate_single(subj, obj))
2079104546Srwatson			return (EACCES);
2080104546Srwatson	}
2081104546Srwatson
2082104569Srwatson	return (0);
2083104546Srwatson}
2084104546Srwatson
2085104546Srwatsonstatic int
2086101099Srwatsonmac_biba_check_vnode_open(struct ucred *cred, struct vnode *vp,
2087101099Srwatson    struct label *vnodelabel, mode_t acc_mode)
2088101099Srwatson{
2089101099Srwatson	struct mac_biba *subj, *obj;
2090101099Srwatson
2091101099Srwatson	if (!mac_biba_enabled)
2092101099Srwatson		return (0);
2093101099Srwatson
2094101099Srwatson	subj = SLOT(&cred->cr_label);
2095101099Srwatson	obj = SLOT(vnodelabel);
2096101099Srwatson
2097101099Srwatson	/* XXX privilege override for admin? */
2098101099Srwatson	if (acc_mode & (VREAD | VEXEC | VSTAT)) {
2099101099Srwatson		if (!mac_biba_dominate_single(obj, subj))
2100101099Srwatson			return (EACCES);
2101101099Srwatson	}
2102101099Srwatson	if (acc_mode & (VWRITE | VAPPEND | VADMIN)) {
2103101099Srwatson		if (!mac_biba_dominate_single(subj, obj))
2104101099Srwatson			return (EACCES);
2105101099Srwatson	}
2106101099Srwatson
2107101099Srwatson	return (0);
2108101099Srwatson}
2109101099Srwatson
2110101099Srwatsonstatic int
2111102129Srwatsonmac_biba_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred,
2112102129Srwatson    struct vnode *vp, struct label *label)
2113102112Srwatson{
2114102112Srwatson	struct mac_biba *subj, *obj;
2115102112Srwatson
2116105637Srwatson	if (!mac_biba_enabled || !revocation_enabled)
2117102112Srwatson		return (0);
2118102112Srwatson
2119102129Srwatson	subj = SLOT(&active_cred->cr_label);
2120102112Srwatson	obj = SLOT(label);
2121102112Srwatson
2122102112Srwatson	if (!mac_biba_dominate_single(obj, subj))
2123102112Srwatson		return (EACCES);
2124102112Srwatson
2125102112Srwatson	return (0);
2126102112Srwatson}
2127102112Srwatson
2128102112Srwatsonstatic int
2129102129Srwatsonmac_biba_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
2130102129Srwatson    struct vnode *vp, struct label *label)
2131102112Srwatson{
2132102112Srwatson	struct mac_biba *subj, *obj;
2133102112Srwatson
2134105637Srwatson	if (!mac_biba_enabled || !revocation_enabled)
2135102112Srwatson		return (0);
2136102112Srwatson
2137102129Srwatson	subj = SLOT(&active_cred->cr_label);
2138102112Srwatson	obj = SLOT(label);
2139102112Srwatson
2140102112Srwatson	if (!mac_biba_dominate_single(obj, subj))
2141102112Srwatson		return (EACCES);
2142102112Srwatson
2143102112Srwatson	return (0);
2144102112Srwatson}
2145102112Srwatson
2146102112Srwatsonstatic int
2147101099Srwatsonmac_biba_check_vnode_readdir(struct ucred *cred, struct vnode *dvp,
2148101099Srwatson    struct label *dlabel)
2149101099Srwatson{
2150101099Srwatson	struct mac_biba *subj, *obj;
2151101099Srwatson
2152101099Srwatson	if (!mac_biba_enabled)
2153101099Srwatson		return (0);
2154101099Srwatson
2155101099Srwatson	subj = SLOT(&cred->cr_label);
2156101099Srwatson	obj = SLOT(dlabel);
2157101099Srwatson
2158101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
2159101099Srwatson		return (EACCES);
2160101099Srwatson
2161101099Srwatson	return (0);
2162101099Srwatson}
2163101099Srwatson
2164101099Srwatsonstatic int
2165101099Srwatsonmac_biba_check_vnode_readlink(struct ucred *cred, struct vnode *vp,
2166101099Srwatson    struct label *label)
2167101099Srwatson{
2168101099Srwatson	struct mac_biba *subj, *obj;
2169101099Srwatson
2170101099Srwatson	if (!mac_biba_enabled)
2171101099Srwatson		return (0);
2172101099Srwatson
2173101099Srwatson	subj = SLOT(&cred->cr_label);
2174101099Srwatson	obj = SLOT(label);
2175101099Srwatson
2176101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
2177101099Srwatson		return (EACCES);
2178101099Srwatson
2179101099Srwatson	return (0);
2180101099Srwatson}
2181101099Srwatson
2182101099Srwatsonstatic int
2183101099Srwatsonmac_biba_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
2184101099Srwatson    struct label *vnodelabel, struct label *newlabel)
2185101099Srwatson{
2186101099Srwatson	struct mac_biba *old, *new, *subj;
2187105634Srwatson	int error;
2188101099Srwatson
2189101099Srwatson	old = SLOT(vnodelabel);
2190101099Srwatson	new = SLOT(newlabel);
2191101099Srwatson	subj = SLOT(&cred->cr_label);
2192101099Srwatson
2193101099Srwatson	/*
2194105634Srwatson	 * If there is a Biba label update for the vnode, it must be a
2195105634Srwatson	 * single label.
2196101099Srwatson	 */
2197105634Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE);
2198105634Srwatson	if (error)
2199105634Srwatson		return (error);
2200101099Srwatson
2201101099Srwatson	/*
2202105634Srwatson	 * To perform a relabel of the vnode (Biba label or not), Biba must
2203105634Srwatson	 * authorize the relabel.
2204101099Srwatson	 */
2205105634Srwatson	if (!mac_biba_single_in_range(old, subj))
2206101099Srwatson		return (EPERM);
2207101099Srwatson
2208101099Srwatson	/*
2209105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
2210101099Srwatson	 */
2211105634Srwatson	if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) {
2212105634Srwatson		/*
2213105634Srwatson		 * To change the Biba label on a vnode, the new vnode label
2214105634Srwatson		 * must be in the subject range.
2215105634Srwatson		 */
2216105634Srwatson		if (!mac_biba_single_in_range(new, subj))
2217105634Srwatson			return (EPERM);
2218101099Srwatson
2219105634Srwatson		/*
2220105634Srwatson		 * To change the Biba label on the vnode to be EQUAL,
2221105634Srwatson		 * the subject must have appropriate privilege.
2222105634Srwatson		 */
2223105634Srwatson		if (mac_biba_contains_equal(new)) {
2224106090Srwatson			error = mac_biba_subject_privileged(subj);
2225105634Srwatson			if (error)
2226105634Srwatson				return (error);
2227105634Srwatson		}
2228105634Srwatson	}
2229105634Srwatson
2230105634Srwatson	return (0);
2231101099Srwatson}
2232101099Srwatson
2233101099Srwatsonstatic int
2234101099Srwatsonmac_biba_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
2235101099Srwatson    struct label *dlabel, struct vnode *vp, struct label *label,
2236101099Srwatson    struct componentname *cnp)
2237101099Srwatson{
2238101099Srwatson	struct mac_biba *subj, *obj;
2239101099Srwatson
2240101099Srwatson	if (!mac_biba_enabled)
2241101099Srwatson		return (0);
2242101099Srwatson
2243101099Srwatson	subj = SLOT(&cred->cr_label);
2244101099Srwatson	obj = SLOT(dlabel);
2245101099Srwatson
2246101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2247101099Srwatson		return (EACCES);
2248101099Srwatson
2249101099Srwatson	obj = SLOT(label);
2250101099Srwatson
2251101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2252101099Srwatson		return (EACCES);
2253101099Srwatson
2254101099Srwatson	return (0);
2255101099Srwatson}
2256101099Srwatson
2257101099Srwatsonstatic int
2258101099Srwatsonmac_biba_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
2259101099Srwatson    struct label *dlabel, struct vnode *vp, struct label *label, int samedir,
2260101099Srwatson    struct componentname *cnp)
2261101099Srwatson{
2262101099Srwatson	struct mac_biba *subj, *obj;
2263101099Srwatson
2264101099Srwatson	if (!mac_biba_enabled)
2265101099Srwatson		return (0);
2266101099Srwatson
2267101099Srwatson	subj = SLOT(&cred->cr_label);
2268101099Srwatson	obj = SLOT(dlabel);
2269101099Srwatson
2270101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2271101099Srwatson		return (EACCES);
2272101099Srwatson
2273101099Srwatson	if (vp != NULL) {
2274101099Srwatson		obj = SLOT(label);
2275101099Srwatson
2276101099Srwatson		if (!mac_biba_dominate_single(subj, obj))
2277101099Srwatson			return (EACCES);
2278101099Srwatson	}
2279101099Srwatson
2280101099Srwatson	return (0);
2281101099Srwatson}
2282101099Srwatson
2283101099Srwatsonstatic int
2284101099Srwatsonmac_biba_check_vnode_revoke(struct ucred *cred, struct vnode *vp,
2285101099Srwatson    struct label *label)
2286101099Srwatson{
2287101099Srwatson	struct mac_biba *subj, *obj;
2288101099Srwatson
2289101099Srwatson	if (!mac_biba_enabled)
2290101099Srwatson		return (0);
2291101099Srwatson
2292101099Srwatson	subj = SLOT(&cred->cr_label);
2293101099Srwatson	obj = SLOT(label);
2294101099Srwatson
2295101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2296101099Srwatson		return (EACCES);
2297101099Srwatson
2298101099Srwatson	return (0);
2299101099Srwatson}
2300101099Srwatson
2301101099Srwatsonstatic int
2302101099Srwatsonmac_biba_check_vnode_setacl(struct ucred *cred, struct vnode *vp,
2303101099Srwatson    struct label *label, acl_type_t type, struct acl *acl)
2304101099Srwatson{
2305101099Srwatson	struct mac_biba *subj, *obj;
2306101099Srwatson
2307101099Srwatson	if (!mac_biba_enabled)
2308101099Srwatson		return (0);
2309101099Srwatson
2310101099Srwatson	subj = SLOT(&cred->cr_label);
2311101099Srwatson	obj = SLOT(label);
2312101099Srwatson
2313101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2314101099Srwatson		return (EACCES);
2315101099Srwatson
2316101099Srwatson	return (0);
2317101099Srwatson}
2318101099Srwatson
2319101099Srwatsonstatic int
2320101099Srwatsonmac_biba_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
2321101099Srwatson    struct label *vnodelabel, int attrnamespace, const char *name,
2322101099Srwatson    struct uio *uio)
2323101099Srwatson{
2324101099Srwatson	struct mac_biba *subj, *obj;
2325101099Srwatson
2326101099Srwatson	if (!mac_biba_enabled)
2327101099Srwatson		return (0);
2328101099Srwatson
2329101099Srwatson	subj = SLOT(&cred->cr_label);
2330101099Srwatson	obj = SLOT(vnodelabel);
2331101099Srwatson
2332101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2333101099Srwatson		return (EACCES);
2334101099Srwatson
2335101099Srwatson	/* XXX: protect the MAC EA in a special way? */
2336101099Srwatson
2337101099Srwatson	return (0);
2338101099Srwatson}
2339101099Srwatson
2340101099Srwatsonstatic int
2341101099Srwatsonmac_biba_check_vnode_setflags(struct ucred *cred, struct vnode *vp,
2342101099Srwatson    struct label *vnodelabel, u_long flags)
2343101099Srwatson{
2344101099Srwatson	struct mac_biba *subj, *obj;
2345101099Srwatson
2346101099Srwatson	if (!mac_biba_enabled)
2347101099Srwatson		return (0);
2348101099Srwatson
2349101099Srwatson	subj = SLOT(&cred->cr_label);
2350101099Srwatson	obj = SLOT(vnodelabel);
2351101099Srwatson
2352101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2353101099Srwatson		return (EACCES);
2354101099Srwatson
2355101099Srwatson	return (0);
2356101099Srwatson}
2357101099Srwatson
2358101099Srwatsonstatic int
2359101099Srwatsonmac_biba_check_vnode_setmode(struct ucred *cred, struct vnode *vp,
2360101099Srwatson    struct label *vnodelabel, mode_t mode)
2361101099Srwatson{
2362101099Srwatson	struct mac_biba *subj, *obj;
2363101099Srwatson
2364101099Srwatson	if (!mac_biba_enabled)
2365101099Srwatson		return (0);
2366101099Srwatson
2367101099Srwatson	subj = SLOT(&cred->cr_label);
2368101099Srwatson	obj = SLOT(vnodelabel);
2369101099Srwatson
2370101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2371101099Srwatson		return (EACCES);
2372101099Srwatson
2373101099Srwatson	return (0);
2374101099Srwatson}
2375101099Srwatson
2376101099Srwatsonstatic int
2377101099Srwatsonmac_biba_check_vnode_setowner(struct ucred *cred, struct vnode *vp,
2378101099Srwatson    struct label *vnodelabel, uid_t uid, gid_t gid)
2379101099Srwatson{
2380101099Srwatson	struct mac_biba *subj, *obj;
2381101099Srwatson
2382101099Srwatson	if (!mac_biba_enabled)
2383101099Srwatson		return (0);
2384101099Srwatson
2385101099Srwatson	subj = SLOT(&cred->cr_label);
2386101099Srwatson	obj = SLOT(vnodelabel);
2387101099Srwatson
2388101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2389101099Srwatson		return (EACCES);
2390101099Srwatson
2391101099Srwatson	return (0);
2392101099Srwatson}
2393101099Srwatson
2394101099Srwatsonstatic int
2395101099Srwatsonmac_biba_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
2396101099Srwatson    struct label *vnodelabel, struct timespec atime, struct timespec mtime)
2397101099Srwatson{
2398101099Srwatson	struct mac_biba *subj, *obj;
2399101099Srwatson
2400101099Srwatson	if (!mac_biba_enabled)
2401101099Srwatson		return (0);
2402101099Srwatson
2403101099Srwatson	subj = SLOT(&cred->cr_label);
2404101099Srwatson	obj = SLOT(vnodelabel);
2405101099Srwatson
2406101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2407101099Srwatson		return (EACCES);
2408101099Srwatson
2409101099Srwatson	return (0);
2410101099Srwatson}
2411101099Srwatson
2412101099Srwatsonstatic int
2413102129Srwatsonmac_biba_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
2414102129Srwatson    struct vnode *vp, struct label *vnodelabel)
2415101099Srwatson{
2416101099Srwatson	struct mac_biba *subj, *obj;
2417101099Srwatson
2418101099Srwatson	if (!mac_biba_enabled)
2419101099Srwatson		return (0);
2420101099Srwatson
2421102129Srwatson	subj = SLOT(&active_cred->cr_label);
2422101099Srwatson	obj = SLOT(vnodelabel);
2423101099Srwatson
2424101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
2425101099Srwatson		return (EACCES);
2426101099Srwatson
2427101099Srwatson	return (0);
2428101099Srwatson}
2429101099Srwatson
2430102112Srwatsonstatic int
2431102129Srwatsonmac_biba_check_vnode_write(struct ucred *active_cred,
2432102129Srwatson    struct ucred *file_cred, struct vnode *vp, struct label *label)
2433102112Srwatson{
2434102112Srwatson	struct mac_biba *subj, *obj;
2435102112Srwatson
2436105637Srwatson	if (!mac_biba_enabled || !revocation_enabled)
2437102112Srwatson		return (0);
2438102112Srwatson
2439102129Srwatson	subj = SLOT(&active_cred->cr_label);
2440102112Srwatson	obj = SLOT(label);
2441102112Srwatson
2442102112Srwatson	if (!mac_biba_dominate_single(subj, obj))
2443102112Srwatson		return (EACCES);
2444102112Srwatson
2445102112Srwatson	return (0);
2446102112Srwatson}
2447102112Srwatson
2448101099Srwatsonstatic struct mac_policy_op_entry mac_biba_ops[] =
2449101099Srwatson{
2450101099Srwatson	{ MAC_DESTROY,
2451101099Srwatson	    (macop_t)mac_biba_destroy },
2452101099Srwatson	{ MAC_INIT,
2453101099Srwatson	    (macop_t)mac_biba_init },
2454104514Srwatson	{ MAC_INIT_BPFDESC_LABEL,
2455104514Srwatson	    (macop_t)mac_biba_init_label },
2456104514Srwatson	{ MAC_INIT_CRED_LABEL,
2457104514Srwatson	    (macop_t)mac_biba_init_label },
2458104514Srwatson	{ MAC_INIT_DEVFSDIRENT_LABEL,
2459104514Srwatson	    (macop_t)mac_biba_init_label },
2460104514Srwatson	{ MAC_INIT_IFNET_LABEL,
2461104514Srwatson	    (macop_t)mac_biba_init_label },
2462104514Srwatson	{ MAC_INIT_IPQ_LABEL,
2463104514Srwatson	    (macop_t)mac_biba_init_label },
2464104514Srwatson	{ MAC_INIT_MBUF_LABEL,
2465104514Srwatson	    (macop_t)mac_biba_init_label_waitcheck },
2466104514Srwatson	{ MAC_INIT_MOUNT_LABEL,
2467104514Srwatson	    (macop_t)mac_biba_init_label },
2468104514Srwatson	{ MAC_INIT_MOUNT_FS_LABEL,
2469104514Srwatson	    (macop_t)mac_biba_init_label },
2470104514Srwatson	{ MAC_INIT_PIPE_LABEL,
2471104514Srwatson	    (macop_t)mac_biba_init_label },
2472104514Srwatson	{ MAC_INIT_SOCKET_LABEL,
2473104541Srwatson	    (macop_t)mac_biba_init_label_waitcheck },
2474104514Srwatson	{ MAC_INIT_SOCKET_PEER_LABEL,
2475104541Srwatson	    (macop_t)mac_biba_init_label_waitcheck },
2476104514Srwatson	{ MAC_INIT_VNODE_LABEL,
2477104514Srwatson	    (macop_t)mac_biba_init_label },
2478104514Srwatson	{ MAC_DESTROY_BPFDESC_LABEL,
2479104514Srwatson	    (macop_t)mac_biba_destroy_label },
2480104514Srwatson	{ MAC_DESTROY_CRED_LABEL,
2481104514Srwatson	    (macop_t)mac_biba_destroy_label },
2482104514Srwatson	{ MAC_DESTROY_DEVFSDIRENT_LABEL,
2483104514Srwatson	    (macop_t)mac_biba_destroy_label },
2484104514Srwatson	{ MAC_DESTROY_IFNET_LABEL,
2485104514Srwatson	    (macop_t)mac_biba_destroy_label },
2486104514Srwatson	{ MAC_DESTROY_IPQ_LABEL,
2487104514Srwatson	    (macop_t)mac_biba_destroy_label },
2488104514Srwatson	{ MAC_DESTROY_MBUF_LABEL,
2489104514Srwatson	    (macop_t)mac_biba_destroy_label },
2490104514Srwatson	{ MAC_DESTROY_MOUNT_LABEL,
2491104514Srwatson	    (macop_t)mac_biba_destroy_label },
2492104514Srwatson	{ MAC_DESTROY_MOUNT_FS_LABEL,
2493104514Srwatson	    (macop_t)mac_biba_destroy_label },
2494104514Srwatson	{ MAC_DESTROY_PIPE_LABEL,
2495104514Srwatson	    (macop_t)mac_biba_destroy_label },
2496104514Srwatson	{ MAC_DESTROY_SOCKET_LABEL,
2497104514Srwatson	    (macop_t)mac_biba_destroy_label },
2498104514Srwatson	{ MAC_DESTROY_SOCKET_PEER_LABEL,
2499104514Srwatson	    (macop_t)mac_biba_destroy_label },
2500104514Srwatson	{ MAC_DESTROY_VNODE_LABEL,
2501104514Srwatson	    (macop_t)mac_biba_destroy_label },
2502105696Srwatson	{ MAC_COPY_PIPE_LABEL,
2503105696Srwatson	    (macop_t)mac_biba_copy_label },
2504105696Srwatson	{ MAC_COPY_VNODE_LABEL,
2505105696Srwatson	    (macop_t)mac_biba_copy_label },
2506105696Srwatson	{ MAC_EXTERNALIZE_CRED_LABEL,
2507105696Srwatson	    (macop_t)mac_biba_externalize_label },
2508105696Srwatson	{ MAC_EXTERNALIZE_IFNET_LABEL,
2509105696Srwatson	    (macop_t)mac_biba_externalize_label },
2510105696Srwatson	{ MAC_EXTERNALIZE_PIPE_LABEL,
2511105696Srwatson	    (macop_t)mac_biba_externalize_label },
2512105696Srwatson	{ MAC_EXTERNALIZE_SOCKET_LABEL,
2513105696Srwatson	    (macop_t)mac_biba_externalize_label },
2514105696Srwatson	{ MAC_EXTERNALIZE_SOCKET_PEER_LABEL,
2515105696Srwatson	    (macop_t)mac_biba_externalize_label },
2516105696Srwatson	{ MAC_EXTERNALIZE_VNODE_LABEL,
2517105696Srwatson	    (macop_t)mac_biba_externalize_label },
2518105696Srwatson	{ MAC_INTERNALIZE_CRED_LABEL,
2519105696Srwatson	    (macop_t)mac_biba_internalize_label },
2520105696Srwatson	{ MAC_INTERNALIZE_IFNET_LABEL,
2521105696Srwatson	    (macop_t)mac_biba_internalize_label },
2522105696Srwatson	{ MAC_INTERNALIZE_PIPE_LABEL,
2523105696Srwatson	    (macop_t)mac_biba_internalize_label },
2524105696Srwatson	{ MAC_INTERNALIZE_SOCKET_LABEL,
2525105696Srwatson	    (macop_t)mac_biba_internalize_label },
2526105696Srwatson	{ MAC_INTERNALIZE_VNODE_LABEL,
2527105696Srwatson	    (macop_t)mac_biba_internalize_label },
2528101099Srwatson	{ MAC_CREATE_DEVFS_DEVICE,
2529101099Srwatson	    (macop_t)mac_biba_create_devfs_device },
2530101099Srwatson	{ MAC_CREATE_DEVFS_DIRECTORY,
2531101099Srwatson	    (macop_t)mac_biba_create_devfs_directory },
2532104535Srwatson	{ MAC_CREATE_DEVFS_SYMLINK,
2533104535Srwatson	    (macop_t)mac_biba_create_devfs_symlink },
2534101099Srwatson	{ MAC_CREATE_DEVFS_VNODE,
2535101099Srwatson	    (macop_t)mac_biba_create_devfs_vnode },
2536101099Srwatson	{ MAC_CREATE_MOUNT,
2537101099Srwatson	    (macop_t)mac_biba_create_mount },
2538101099Srwatson	{ MAC_CREATE_ROOT_MOUNT,
2539101099Srwatson	    (macop_t)mac_biba_create_root_mount },
2540101099Srwatson	{ MAC_RELABEL_VNODE,
2541101099Srwatson	    (macop_t)mac_biba_relabel_vnode },
2542101099Srwatson	{ MAC_UPDATE_DEVFSDIRENT,
2543101099Srwatson	    (macop_t)mac_biba_update_devfsdirent },
2544105988Srwatson	{ MAC_ASSOCIATE_VNODE_DEVFS,
2545105988Srwatson	    (macop_t)mac_biba_associate_vnode_devfs },
2546105988Srwatson	{ MAC_ASSOCIATE_VNODE_EXTATTR,
2547105988Srwatson	    (macop_t)mac_biba_associate_vnode_extattr },
2548105988Srwatson	{ MAC_ASSOCIATE_VNODE_SINGLELABEL,
2549105988Srwatson	    (macop_t)mac_biba_associate_vnode_singlelabel },
2550105988Srwatson	{ MAC_CREATE_VNODE_EXTATTR,
2551105988Srwatson	    (macop_t)mac_biba_create_vnode_extattr },
2552105988Srwatson	{ MAC_SETLABEL_VNODE_EXTATTR,
2553105988Srwatson	    (macop_t)mac_biba_setlabel_vnode_extattr },
2554101099Srwatson	{ MAC_CREATE_MBUF_FROM_SOCKET,
2555101099Srwatson	    (macop_t)mac_biba_create_mbuf_from_socket },
2556101099Srwatson	{ MAC_CREATE_PIPE,
2557101099Srwatson	    (macop_t)mac_biba_create_pipe },
2558101099Srwatson	{ MAC_CREATE_SOCKET,
2559101099Srwatson	    (macop_t)mac_biba_create_socket },
2560101099Srwatson	{ MAC_CREATE_SOCKET_FROM_SOCKET,
2561101099Srwatson	    (macop_t)mac_biba_create_socket_from_socket },
2562101099Srwatson	{ MAC_RELABEL_PIPE,
2563101099Srwatson	    (macop_t)mac_biba_relabel_pipe },
2564101099Srwatson	{ MAC_RELABEL_SOCKET,
2565101099Srwatson	    (macop_t)mac_biba_relabel_socket },
2566101099Srwatson	{ MAC_SET_SOCKET_PEER_FROM_MBUF,
2567101099Srwatson	    (macop_t)mac_biba_set_socket_peer_from_mbuf },
2568101099Srwatson	{ MAC_SET_SOCKET_PEER_FROM_SOCKET,
2569101099Srwatson	    (macop_t)mac_biba_set_socket_peer_from_socket },
2570101099Srwatson	{ MAC_CREATE_BPFDESC,
2571101099Srwatson	    (macop_t)mac_biba_create_bpfdesc },
2572101099Srwatson	{ MAC_CREATE_DATAGRAM_FROM_IPQ,
2573101099Srwatson	    (macop_t)mac_biba_create_datagram_from_ipq },
2574101099Srwatson	{ MAC_CREATE_FRAGMENT,
2575101099Srwatson	    (macop_t)mac_biba_create_fragment },
2576101099Srwatson	{ MAC_CREATE_IFNET,
2577101099Srwatson	    (macop_t)mac_biba_create_ifnet },
2578101099Srwatson	{ MAC_CREATE_IPQ,
2579101099Srwatson	    (macop_t)mac_biba_create_ipq },
2580101099Srwatson	{ MAC_CREATE_MBUF_FROM_MBUF,
2581101099Srwatson	    (macop_t)mac_biba_create_mbuf_from_mbuf },
2582101099Srwatson	{ MAC_CREATE_MBUF_LINKLAYER,
2583101099Srwatson	    (macop_t)mac_biba_create_mbuf_linklayer },
2584101099Srwatson	{ MAC_CREATE_MBUF_FROM_BPFDESC,
2585101099Srwatson	    (macop_t)mac_biba_create_mbuf_from_bpfdesc },
2586101099Srwatson	{ MAC_CREATE_MBUF_FROM_IFNET,
2587101099Srwatson	    (macop_t)mac_biba_create_mbuf_from_ifnet },
2588101099Srwatson	{ MAC_CREATE_MBUF_MULTICAST_ENCAP,
2589101099Srwatson	    (macop_t)mac_biba_create_mbuf_multicast_encap },
2590101099Srwatson	{ MAC_CREATE_MBUF_NETLAYER,
2591101099Srwatson	    (macop_t)mac_biba_create_mbuf_netlayer },
2592101099Srwatson	{ MAC_FRAGMENT_MATCH,
2593101099Srwatson	    (macop_t)mac_biba_fragment_match },
2594101099Srwatson	{ MAC_RELABEL_IFNET,
2595101099Srwatson	    (macop_t)mac_biba_relabel_ifnet },
2596101099Srwatson	{ MAC_UPDATE_IPQ,
2597101099Srwatson	    (macop_t)mac_biba_update_ipq },
2598101099Srwatson	{ MAC_CREATE_CRED,
2599101099Srwatson	    (macop_t)mac_biba_create_cred },
2600101099Srwatson	{ MAC_EXECVE_TRANSITION,
2601101099Srwatson	    (macop_t)mac_biba_execve_transition },
2602101099Srwatson	{ MAC_EXECVE_WILL_TRANSITION,
2603101099Srwatson	    (macop_t)mac_biba_execve_will_transition },
2604101099Srwatson	{ MAC_CREATE_PROC0,
2605101099Srwatson	    (macop_t)mac_biba_create_proc0 },
2606101099Srwatson	{ MAC_CREATE_PROC1,
2607101099Srwatson	    (macop_t)mac_biba_create_proc1 },
2608101099Srwatson	{ MAC_RELABEL_CRED,
2609101099Srwatson	    (macop_t)mac_biba_relabel_cred },
2610101099Srwatson	{ MAC_CHECK_BPFDESC_RECEIVE,
2611101099Srwatson	    (macop_t)mac_biba_check_bpfdesc_receive },
2612101099Srwatson	{ MAC_CHECK_CRED_RELABEL,
2613101099Srwatson	    (macop_t)mac_biba_check_cred_relabel },
2614101099Srwatson	{ MAC_CHECK_CRED_VISIBLE,
2615101099Srwatson	    (macop_t)mac_biba_check_cred_visible },
2616101099Srwatson	{ MAC_CHECK_IFNET_RELABEL,
2617101099Srwatson	    (macop_t)mac_biba_check_ifnet_relabel },
2618101099Srwatson	{ MAC_CHECK_IFNET_TRANSMIT,
2619101099Srwatson	    (macop_t)mac_biba_check_ifnet_transmit },
2620101099Srwatson	{ MAC_CHECK_MOUNT_STAT,
2621101099Srwatson	    (macop_t)mac_biba_check_mount_stat },
2622101099Srwatson	{ MAC_CHECK_PIPE_IOCTL,
2623101099Srwatson	    (macop_t)mac_biba_check_pipe_ioctl },
2624102115Srwatson	{ MAC_CHECK_PIPE_POLL,
2625102115Srwatson	    (macop_t)mac_biba_check_pipe_poll },
2626102115Srwatson	{ MAC_CHECK_PIPE_READ,
2627102115Srwatson	    (macop_t)mac_biba_check_pipe_read },
2628101099Srwatson	{ MAC_CHECK_PIPE_RELABEL,
2629101099Srwatson	    (macop_t)mac_biba_check_pipe_relabel },
2630102115Srwatson	{ MAC_CHECK_PIPE_STAT,
2631102115Srwatson	    (macop_t)mac_biba_check_pipe_stat },
2632102115Srwatson	{ MAC_CHECK_PIPE_WRITE,
2633102115Srwatson	    (macop_t)mac_biba_check_pipe_write },
2634101099Srwatson	{ MAC_CHECK_PROC_DEBUG,
2635101099Srwatson	    (macop_t)mac_biba_check_proc_debug },
2636101099Srwatson	{ MAC_CHECK_PROC_SCHED,
2637101099Srwatson	    (macop_t)mac_biba_check_proc_sched },
2638101099Srwatson	{ MAC_CHECK_PROC_SIGNAL,
2639101099Srwatson	    (macop_t)mac_biba_check_proc_signal },
2640101934Srwatson	{ MAC_CHECK_SOCKET_DELIVER,
2641101934Srwatson	    (macop_t)mac_biba_check_socket_deliver },
2642101099Srwatson	{ MAC_CHECK_SOCKET_RELABEL,
2643101099Srwatson	    (macop_t)mac_biba_check_socket_relabel },
2644101099Srwatson	{ MAC_CHECK_SOCKET_VISIBLE,
2645101099Srwatson	    (macop_t)mac_biba_check_socket_visible },
2646101099Srwatson	{ MAC_CHECK_VNODE_ACCESS,
2647105635Srwatson	    (macop_t)mac_biba_check_vnode_open },
2648101099Srwatson	{ MAC_CHECK_VNODE_CHDIR,
2649101099Srwatson	    (macop_t)mac_biba_check_vnode_chdir },
2650101099Srwatson	{ MAC_CHECK_VNODE_CHROOT,
2651101099Srwatson	    (macop_t)mac_biba_check_vnode_chroot },
2652101099Srwatson	{ MAC_CHECK_VNODE_CREATE,
2653101099Srwatson	    (macop_t)mac_biba_check_vnode_create },
2654101099Srwatson	{ MAC_CHECK_VNODE_DELETE,
2655101099Srwatson	    (macop_t)mac_biba_check_vnode_delete },
2656101099Srwatson	{ MAC_CHECK_VNODE_DELETEACL,
2657101099Srwatson	    (macop_t)mac_biba_check_vnode_deleteacl },
2658101099Srwatson	{ MAC_CHECK_VNODE_EXEC,
2659101099Srwatson	    (macop_t)mac_biba_check_vnode_exec },
2660101099Srwatson	{ MAC_CHECK_VNODE_GETACL,
2661101099Srwatson	    (macop_t)mac_biba_check_vnode_getacl },
2662101099Srwatson	{ MAC_CHECK_VNODE_GETEXTATTR,
2663101099Srwatson	    (macop_t)mac_biba_check_vnode_getextattr },
2664104530Srwatson	{ MAC_CHECK_VNODE_LINK,
2665104530Srwatson	    (macop_t)mac_biba_check_vnode_link },
2666101099Srwatson	{ MAC_CHECK_VNODE_LOOKUP,
2667101099Srwatson	    (macop_t)mac_biba_check_vnode_lookup },
2668104546Srwatson	{ MAC_CHECK_VNODE_MMAP,
2669104546Srwatson	    (macop_t)mac_biba_check_vnode_mmap },
2670104546Srwatson	{ MAC_CHECK_VNODE_MPROTECT,
2671104546Srwatson	    (macop_t)mac_biba_check_vnode_mmap },
2672101099Srwatson	{ MAC_CHECK_VNODE_OPEN,
2673101099Srwatson	    (macop_t)mac_biba_check_vnode_open },
2674102112Srwatson	{ MAC_CHECK_VNODE_POLL,
2675102112Srwatson	    (macop_t)mac_biba_check_vnode_poll },
2676102112Srwatson	{ MAC_CHECK_VNODE_READ,
2677102112Srwatson	    (macop_t)mac_biba_check_vnode_read },
2678101099Srwatson	{ MAC_CHECK_VNODE_READDIR,
2679101099Srwatson	    (macop_t)mac_biba_check_vnode_readdir },
2680101099Srwatson	{ MAC_CHECK_VNODE_READLINK,
2681101099Srwatson	    (macop_t)mac_biba_check_vnode_readlink },
2682101099Srwatson	{ MAC_CHECK_VNODE_RELABEL,
2683101099Srwatson	    (macop_t)mac_biba_check_vnode_relabel },
2684101099Srwatson	{ MAC_CHECK_VNODE_RENAME_FROM,
2685101099Srwatson	    (macop_t)mac_biba_check_vnode_rename_from },
2686101099Srwatson	{ MAC_CHECK_VNODE_RENAME_TO,
2687101099Srwatson	    (macop_t)mac_biba_check_vnode_rename_to },
2688101099Srwatson	{ MAC_CHECK_VNODE_REVOKE,
2689101099Srwatson	    (macop_t)mac_biba_check_vnode_revoke },
2690101099Srwatson	{ MAC_CHECK_VNODE_SETACL,
2691101099Srwatson	    (macop_t)mac_biba_check_vnode_setacl },
2692101099Srwatson	{ MAC_CHECK_VNODE_SETEXTATTR,
2693101099Srwatson	    (macop_t)mac_biba_check_vnode_setextattr },
2694101099Srwatson	{ MAC_CHECK_VNODE_SETFLAGS,
2695101099Srwatson	    (macop_t)mac_biba_check_vnode_setflags },
2696101099Srwatson	{ MAC_CHECK_VNODE_SETMODE,
2697101099Srwatson	    (macop_t)mac_biba_check_vnode_setmode },
2698101099Srwatson	{ MAC_CHECK_VNODE_SETOWNER,
2699101099Srwatson	    (macop_t)mac_biba_check_vnode_setowner },
2700101099Srwatson	{ MAC_CHECK_VNODE_SETUTIMES,
2701101099Srwatson	    (macop_t)mac_biba_check_vnode_setutimes },
2702101099Srwatson	{ MAC_CHECK_VNODE_STAT,
2703101099Srwatson	    (macop_t)mac_biba_check_vnode_stat },
2704102112Srwatson	{ MAC_CHECK_VNODE_WRITE,
2705102112Srwatson	    (macop_t)mac_biba_check_vnode_write },
2706101099Srwatson	{ MAC_OP_LAST, NULL }
2707101099Srwatson};
2708101099Srwatson
2709101099SrwatsonMAC_POLICY_SET(mac_biba_ops, trustedbsd_mac_biba, "TrustedBSD MAC/Biba",
2710101099Srwatson    MPC_LOADTIME_FLAG_NOTLATE, &mac_biba_slot);
2711