mac_biba.c revision 106212
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 106212 2002-10-30 17:56:57Z 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
227106174Srwatson	KASSERT((mac_biba->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
340106091Srwatsonstatic int
341105988Srwatsonmac_biba_high_single(struct mac_biba *mac_biba)
342105988Srwatson{
343105988Srwatson
344105988Srwatson	KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
345105988Srwatson	    ("mac_biba_equal_single: mac_biba not single"));
346105988Srwatson
347105988Srwatson	return (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_HIGH);
348105988Srwatson}
349105988Srwatson
350105634Srwatsonstatic int
351101099Srwatsonmac_biba_valid(struct mac_biba *mac_biba)
352101099Srwatson{
353101099Srwatson
354101099Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) {
355101099Srwatson		switch (mac_biba->mb_single.mbe_type) {
356101099Srwatson		case MAC_BIBA_TYPE_GRADE:
357101099Srwatson			break;
358101099Srwatson
359101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
360101099Srwatson		case MAC_BIBA_TYPE_HIGH:
361101099Srwatson		case MAC_BIBA_TYPE_LOW:
362105643Srwatson			if (mac_biba->mb_single.mbe_grade != 0 ||
363105643Srwatson			    !MAC_BIBA_BIT_SET_EMPTY(
364105643Srwatson			    mac_biba->mb_single.mbe_compartments))
365101099Srwatson				return (EINVAL);
366101099Srwatson			break;
367101099Srwatson
368101099Srwatson		default:
369101099Srwatson			return (EINVAL);
370101099Srwatson		}
371101099Srwatson	} else {
372101099Srwatson		if (mac_biba->mb_single.mbe_type != MAC_BIBA_TYPE_UNDEF)
373101099Srwatson			return (EINVAL);
374101099Srwatson	}
375101099Srwatson
376101099Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
377101099Srwatson		switch (mac_biba->mb_rangelow.mbe_type) {
378101099Srwatson		case MAC_BIBA_TYPE_GRADE:
379101099Srwatson			break;
380101099Srwatson
381101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
382101099Srwatson		case MAC_BIBA_TYPE_HIGH:
383101099Srwatson		case MAC_BIBA_TYPE_LOW:
384105643Srwatson			if (mac_biba->mb_rangelow.mbe_grade != 0 ||
385105643Srwatson			    !MAC_BIBA_BIT_SET_EMPTY(
386105643Srwatson			    mac_biba->mb_rangelow.mbe_compartments))
387101099Srwatson				return (EINVAL);
388101099Srwatson			break;
389101099Srwatson
390101099Srwatson		default:
391101099Srwatson			return (EINVAL);
392101099Srwatson		}
393101099Srwatson
394101099Srwatson		switch (mac_biba->mb_rangehigh.mbe_type) {
395101099Srwatson		case MAC_BIBA_TYPE_GRADE:
396101099Srwatson			break;
397101099Srwatson
398101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
399101099Srwatson		case MAC_BIBA_TYPE_HIGH:
400101099Srwatson		case MAC_BIBA_TYPE_LOW:
401105643Srwatson			if (mac_biba->mb_rangehigh.mbe_grade != 0 ||
402105643Srwatson			    !MAC_BIBA_BIT_SET_EMPTY(
403105643Srwatson			    mac_biba->mb_rangehigh.mbe_compartments))
404101099Srwatson				return (EINVAL);
405101099Srwatson			break;
406101099Srwatson
407101099Srwatson		default:
408101099Srwatson			return (EINVAL);
409101099Srwatson		}
410101099Srwatson		if (!mac_biba_dominate_element(&mac_biba->mb_rangehigh,
411101099Srwatson		    &mac_biba->mb_rangelow))
412101099Srwatson			return (EINVAL);
413101099Srwatson	} else {
414101099Srwatson		if (mac_biba->mb_rangelow.mbe_type != MAC_BIBA_TYPE_UNDEF ||
415101099Srwatson		    mac_biba->mb_rangehigh.mbe_type != MAC_BIBA_TYPE_UNDEF)
416101099Srwatson			return (EINVAL);
417101099Srwatson	}
418101099Srwatson
419101099Srwatson	return (0);
420101099Srwatson}
421101099Srwatson
422101099Srwatsonstatic void
423101099Srwatsonmac_biba_set_range(struct mac_biba *mac_biba, u_short typelow,
424105643Srwatson    u_short gradelow, u_char *compartmentslow, u_short typehigh,
425105643Srwatson    u_short gradehigh, u_char *compartmentshigh)
426101099Srwatson{
427101099Srwatson
428101099Srwatson	mac_biba->mb_rangelow.mbe_type = typelow;
429101099Srwatson	mac_biba->mb_rangelow.mbe_grade = gradelow;
430105643Srwatson	if (compartmentslow != NULL)
431105643Srwatson		memcpy(mac_biba->mb_rangelow.mbe_compartments,
432105643Srwatson		    compartmentslow,
433105643Srwatson		    sizeof(mac_biba->mb_rangelow.mbe_compartments));
434101099Srwatson	mac_biba->mb_rangehigh.mbe_type = typehigh;
435101099Srwatson	mac_biba->mb_rangehigh.mbe_grade = gradehigh;
436105643Srwatson	if (compartmentshigh != NULL)
437105643Srwatson		memcpy(mac_biba->mb_rangehigh.mbe_compartments,
438105643Srwatson		    compartmentshigh,
439105643Srwatson		    sizeof(mac_biba->mb_rangehigh.mbe_compartments));
440101099Srwatson	mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE;
441101099Srwatson}
442101099Srwatson
443101099Srwatsonstatic void
444105643Srwatsonmac_biba_set_single(struct mac_biba *mac_biba, u_short type, u_short grade,
445105643Srwatson    u_char *compartments)
446101099Srwatson{
447101099Srwatson
448101099Srwatson	mac_biba->mb_single.mbe_type = type;
449101099Srwatson	mac_biba->mb_single.mbe_grade = grade;
450105643Srwatson	if (compartments != NULL)
451105643Srwatson		memcpy(mac_biba->mb_single.mbe_compartments, compartments,
452105643Srwatson		    sizeof(mac_biba->mb_single.mbe_compartments));
453101099Srwatson	mac_biba->mb_flags |= MAC_BIBA_FLAG_SINGLE;
454101099Srwatson}
455101099Srwatson
456101099Srwatsonstatic void
457101099Srwatsonmac_biba_copy_range(struct mac_biba *labelfrom, struct mac_biba *labelto)
458101099Srwatson{
459105643Srwatson
460101099Srwatson	KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_RANGE) != 0,
461101099Srwatson	    ("mac_biba_copy_range: labelfrom not range"));
462101099Srwatson
463101099Srwatson	labelto->mb_rangelow = labelfrom->mb_rangelow;
464101099Srwatson	labelto->mb_rangehigh = labelfrom->mb_rangehigh;
465101099Srwatson	labelto->mb_flags |= MAC_BIBA_FLAG_RANGE;
466101099Srwatson}
467101099Srwatson
468101099Srwatsonstatic void
469101099Srwatsonmac_biba_copy_single(struct mac_biba *labelfrom, struct mac_biba *labelto)
470101099Srwatson{
471101099Srwatson
472101099Srwatson	KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
473101099Srwatson	    ("mac_biba_copy_single: labelfrom not single"));
474101099Srwatson
475101099Srwatson	labelto->mb_single = labelfrom->mb_single;
476101099Srwatson	labelto->mb_flags |= MAC_BIBA_FLAG_SINGLE;
477101099Srwatson}
478101099Srwatson
479105656Srwatsonstatic void
480105656Srwatsonmac_biba_copy(struct mac_biba *source, struct mac_biba *dest)
481105656Srwatson{
482105656Srwatson
483105656Srwatson	if (source->mb_flags & MAC_BIBA_FLAG_SINGLE)
484105656Srwatson		mac_biba_copy_single(source, dest);
485105656Srwatson	if (source->mb_flags & MAC_BIBA_FLAG_RANGE)
486105656Srwatson		mac_biba_copy_range(source, dest);
487105656Srwatson}
488105656Srwatson
489101099Srwatson/*
490101099Srwatson * Policy module operations.
491101099Srwatson */
492101099Srwatsonstatic void
493101099Srwatsonmac_biba_destroy(struct mac_policy_conf *conf)
494101099Srwatson{
495101099Srwatson
496101099Srwatson}
497101099Srwatson
498101099Srwatsonstatic void
499101099Srwatsonmac_biba_init(struct mac_policy_conf *conf)
500101099Srwatson{
501101099Srwatson
502101099Srwatson}
503101099Srwatson
504101099Srwatson/*
505101099Srwatson * Label operations.
506101099Srwatson */
507101099Srwatsonstatic void
508104514Srwatsonmac_biba_init_label(struct label *label)
509101099Srwatson{
510101099Srwatson
511101099Srwatson	SLOT(label) = biba_alloc(M_WAITOK);
512101099Srwatson}
513101099Srwatson
514101099Srwatsonstatic int
515104514Srwatsonmac_biba_init_label_waitcheck(struct label *label, int flag)
516101099Srwatson{
517101099Srwatson
518104514Srwatson	SLOT(label) = biba_alloc(flag);
519101099Srwatson	if (SLOT(label) == NULL)
520101099Srwatson		return (ENOMEM);
521101099Srwatson
522101099Srwatson	return (0);
523101099Srwatson}
524101099Srwatson
525101099Srwatsonstatic void
526104514Srwatsonmac_biba_destroy_label(struct label *label)
527101099Srwatson{
528101099Srwatson
529101099Srwatson	biba_free(SLOT(label));
530101099Srwatson	SLOT(label) = NULL;
531101099Srwatson}
532101099Srwatson
533105696Srwatson/*
534105696Srwatson * mac_biba_element_to_string() is basically an snprintf wrapper with
535105696Srwatson * the same properties as snprintf().  It returns the length it would
536105696Srwatson * have added to the string in the event the string is too short.
537105696Srwatson */
538105696Srwatsonstatic size_t
539105696Srwatsonmac_biba_element_to_string(char *string, size_t size,
540105696Srwatson    struct mac_biba_element *element)
541105696Srwatson{
542105696Srwatson	int pos, bit = 1;
543105696Srwatson
544105696Srwatson	switch (element->mbe_type) {
545105696Srwatson	case MAC_BIBA_TYPE_HIGH:
546105696Srwatson		return (snprintf(string, size, "high"));
547105696Srwatson
548105696Srwatson	case MAC_BIBA_TYPE_LOW:
549105696Srwatson		return (snprintf(string, size, "low"));
550105696Srwatson
551105696Srwatson	case MAC_BIBA_TYPE_EQUAL:
552105696Srwatson		return (snprintf(string, size, "equal"));
553105696Srwatson
554105696Srwatson	case MAC_BIBA_TYPE_GRADE:
555105696Srwatson		pos = snprintf(string, size, "%d:", element->mbe_grade);
556105696Srwatson		for (bit = 1; bit <= MAC_BIBA_MAX_COMPARTMENTS; bit++) {
557105696Srwatson			if (MAC_BIBA_BIT_TEST(bit, element->mbe_compartments))
558105696Srwatson				pos += snprintf(string + pos, size - pos,
559105696Srwatson				    "%d+", bit);
560105696Srwatson		}
561105696Srwatson		if (string[pos - 1] == '+' || string[pos - 1] == ':')
562105696Srwatson			string[--pos] = NULL;
563105696Srwatson		return (pos);
564105696Srwatson
565105696Srwatson	default:
566105696Srwatson		panic("mac_biba_element_to_string: invalid type (%d)",
567105696Srwatson		    element->mbe_type);
568105696Srwatson	}
569105696Srwatson}
570105696Srwatson
571101099Srwatsonstatic int
572105696Srwatsonmac_biba_to_string(char *string, size_t size, size_t *caller_len,
573105696Srwatson    struct mac_biba *mac_biba)
574101099Srwatson{
575105696Srwatson	size_t left, len;
576105696Srwatson	char *curptr;
577105696Srwatson
578105696Srwatson	bzero(string, size);
579105696Srwatson	curptr = string;
580105696Srwatson	left = size;
581105696Srwatson
582105696Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) {
583105696Srwatson		len = mac_biba_element_to_string(curptr, left,
584105696Srwatson		    &mac_biba->mb_single);
585105696Srwatson		if (len >= left)
586105696Srwatson			return (EINVAL);
587105696Srwatson		left -= len;
588105696Srwatson		curptr += len;
589105696Srwatson	}
590105696Srwatson
591105696Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
592105696Srwatson		len = snprintf(curptr, left, "(");
593105696Srwatson		if (len >= left)
594105696Srwatson			return (EINVAL);
595105696Srwatson		left -= len;
596105696Srwatson		curptr += len;
597105696Srwatson
598105696Srwatson		len = mac_biba_element_to_string(curptr, left,
599105696Srwatson		    &mac_biba->mb_rangelow);
600105696Srwatson		if (len >= left)
601105696Srwatson			return (EINVAL);
602105696Srwatson		left -= len;
603105696Srwatson		curptr += len;
604105696Srwatson
605105696Srwatson		len = snprintf(curptr, left, "-");
606105696Srwatson		if (len >= left)
607105696Srwatson			return (EINVAL);
608105696Srwatson		left -= len;
609105696Srwatson		curptr += len;
610105696Srwatson
611105696Srwatson		len = mac_biba_element_to_string(curptr, left,
612105696Srwatson		    &mac_biba->mb_rangehigh);
613105696Srwatson		if (len >= left)
614105696Srwatson			return (EINVAL);
615105696Srwatson		left -= len;
616105696Srwatson		curptr += len;
617105696Srwatson
618105696Srwatson		len = snprintf(curptr, left, ")");
619105696Srwatson		if (len >= left)
620105696Srwatson			return (EINVAL);
621105696Srwatson		left -= len;
622105696Srwatson		curptr += len;
623105696Srwatson	}
624105696Srwatson
625105696Srwatson	*caller_len = strlen(string);
626105696Srwatson	return (0);
627105696Srwatson}
628105696Srwatson
629105696Srwatsonstatic int
630105696Srwatsonmac_biba_externalize_label(struct label *label, char *element_name,
631105696Srwatson    char *element_data, size_t size, size_t *len, int *claimed)
632105696Srwatson{
633101099Srwatson	struct mac_biba *mac_biba;
634105696Srwatson	int error;
635101099Srwatson
636105696Srwatson	if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0)
637105696Srwatson		return (0);
638105696Srwatson
639105696Srwatson	(*claimed)++;
640105696Srwatson
641101099Srwatson	mac_biba = SLOT(label);
642105696Srwatson	error = mac_biba_to_string(element_data, size, len, mac_biba);
643105696Srwatson	if (error)
644105696Srwatson		return (error);
645101099Srwatson
646105696Srwatson	*len = strlen(element_data);
647105696Srwatson	return (0);
648105696Srwatson}
649105696Srwatson
650105696Srwatsonstatic int
651105696Srwatsonmac_biba_parse_element(struct mac_biba_element *element, char *string)
652101099Srwatson{
653105696Srwatson
654105696Srwatson	if (strcmp(string, "high") == 0 ||
655105696Srwatson	    strcmp(string, "hi") == 0) {
656105696Srwatson		element->mbe_type = MAC_BIBA_TYPE_HIGH;
657105696Srwatson		element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
658105696Srwatson	} else if (strcmp(string, "low") == 0 ||
659105696Srwatson	    strcmp(string, "lo") == 0) {
660105696Srwatson		element->mbe_type = MAC_BIBA_TYPE_LOW;
661105696Srwatson		element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
662105696Srwatson	} else if (strcmp(string, "equal") == 0 ||
663105696Srwatson	    strcmp(string, "eq") == 0) {
664105696Srwatson		element->mbe_type = MAC_BIBA_TYPE_EQUAL;
665105696Srwatson		element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
666105696Srwatson	} else {
667105696Srwatson		char *p0, *p1;
668105696Srwatson		int d;
669105696Srwatson
670105696Srwatson		p0 = string;
671105696Srwatson		d = strtol(p0, &p1, 10);
672105696Srwatson
673105696Srwatson		if (d < 0 || d > 65535)
674105696Srwatson			return (EINVAL);
675105696Srwatson		element->mbe_type = MAC_BIBA_TYPE_GRADE;
676105696Srwatson		element->mbe_grade = d;
677105696Srwatson
678105696Srwatson		if (*p1 != ':')  {
679105696Srwatson			if (p1 == p0 || *p1 != '\0')
680105696Srwatson				return (EINVAL);
681105696Srwatson			else
682105696Srwatson				return (0);
683105696Srwatson		}
684105696Srwatson		else
685105696Srwatson			if (*(p1 + 1) == '\0')
686105696Srwatson				return (0);
687105696Srwatson
688105696Srwatson		while ((p0 = ++p1)) {
689105696Srwatson			d = strtol(p0, &p1, 10);
690105696Srwatson			if (d < 1 || d > MAC_BIBA_MAX_COMPARTMENTS)
691105696Srwatson				return (EINVAL);
692105696Srwatson
693105696Srwatson			MAC_BIBA_BIT_SET(d, element->mbe_compartments);
694105696Srwatson
695105696Srwatson			if (*p1 == '\0')
696105696Srwatson				break;
697105696Srwatson			if (p1 == p0 || *p1 != '+')
698105696Srwatson				return (EINVAL);
699105696Srwatson		}
700105696Srwatson	}
701105696Srwatson
702105696Srwatson	return (0);
703105696Srwatson}
704105696Srwatson
705105696Srwatson/*
706105696Srwatson * Note: destructively consumes the string, make a local copy before
707105696Srwatson * calling if that's a problem.
708105696Srwatson */
709105696Srwatsonstatic int
710105696Srwatsonmac_biba_parse(struct mac_biba *mac_biba, char *string)
711105696Srwatson{
712105696Srwatson	char *range, *rangeend, *rangehigh, *rangelow, *single;
713101099Srwatson	int error;
714101099Srwatson
715105696Srwatson	/* Do we have a range? */
716105696Srwatson	single = string;
717105696Srwatson	range = index(string, '(');
718105696Srwatson	if (range == single)
719105696Srwatson		single = NULL;
720105696Srwatson	rangelow = rangehigh = NULL;
721105696Srwatson	if (range != NULL) {
722105696Srwatson		/* Nul terminate the end of the single string. */
723105696Srwatson		*range = '\0';
724105696Srwatson		range++;
725105696Srwatson		rangelow = range;
726105696Srwatson		rangehigh = index(rangelow, '-');
727105696Srwatson		if (rangehigh == NULL)
728105696Srwatson			return (EINVAL);
729105696Srwatson		rangehigh++;
730105696Srwatson		if (*rangelow == '\0' || *rangehigh == '\0')
731105696Srwatson			return (EINVAL);
732105696Srwatson		rangeend = index(rangehigh, ')');
733105696Srwatson		if (rangeend == NULL)
734105696Srwatson			return (EINVAL);
735105696Srwatson		if (*(rangeend + 1) != '\0')
736105696Srwatson			return (EINVAL);
737105696Srwatson		/* Nul terminate the ends of the ranges. */
738105696Srwatson		*(rangehigh - 1) = '\0';
739105696Srwatson		*rangeend = '\0';
740105696Srwatson	}
741105696Srwatson	KASSERT((rangelow != NULL && rangehigh != NULL) ||
742105696Srwatson	    (rangelow == NULL && rangehigh == NULL),
743105696Srwatson	    ("mac_biba_internalize_label: range mismatch"));
744101099Srwatson
745105696Srwatson	bzero(mac_biba, sizeof(*mac_biba));
746105696Srwatson	if (single != NULL) {
747105696Srwatson		error = mac_biba_parse_element(&mac_biba->mb_single, single);
748105696Srwatson		if (error)
749105696Srwatson			return (error);
750105696Srwatson		mac_biba->mb_flags |= MAC_BIBA_FLAG_SINGLE;
751105696Srwatson	}
752105696Srwatson
753105696Srwatson	if (rangelow != NULL) {
754105696Srwatson		error = mac_biba_parse_element(&mac_biba->mb_rangelow,
755105696Srwatson		    rangelow);
756105696Srwatson		if (error)
757105696Srwatson			return (error);
758105696Srwatson		error = mac_biba_parse_element(&mac_biba->mb_rangehigh,
759105696Srwatson		    rangehigh);
760105696Srwatson		if (error)
761105696Srwatson			return (error);
762105696Srwatson		mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE;
763105696Srwatson	}
764105696Srwatson
765101099Srwatson	error = mac_biba_valid(mac_biba);
766101099Srwatson	if (error)
767101099Srwatson		return (error);
768101099Srwatson
769105696Srwatson	return (0);
770105696Srwatson}
771101099Srwatson
772105696Srwatsonstatic int
773105696Srwatsonmac_biba_internalize_label(struct label *label, char *element_name,
774105696Srwatson    char *element_data, int *claimed)
775105696Srwatson{
776105696Srwatson	struct mac_biba *mac_biba, mac_biba_temp;
777105696Srwatson	int error;
778105696Srwatson
779105696Srwatson	if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0)
780105696Srwatson		return (0);
781105696Srwatson
782105696Srwatson	(*claimed)++;
783105696Srwatson
784105696Srwatson	error = mac_biba_parse(&mac_biba_temp, element_data);
785105696Srwatson	if (error)
786105696Srwatson		return (error);
787105696Srwatson
788105696Srwatson	mac_biba = SLOT(label);
789105696Srwatson	*mac_biba = mac_biba_temp;
790105696Srwatson
791101099Srwatson	return (0);
792101099Srwatson}
793101099Srwatson
794105696Srwatsonstatic void
795105696Srwatsonmac_biba_copy_label(struct label *src, struct label *dest)
796105696Srwatson{
797105696Srwatson
798105696Srwatson	*SLOT(dest) = *SLOT(src);
799105696Srwatson}
800105696Srwatson
801101099Srwatson/*
802101099Srwatson * Labeling event operations: file system objects, and things that look
803101099Srwatson * a lot like file system objects.
804101099Srwatson */
805101099Srwatsonstatic void
806101099Srwatsonmac_biba_create_devfs_device(dev_t dev, struct devfs_dirent *devfs_dirent,
807101099Srwatson    struct label *label)
808101099Srwatson{
809101099Srwatson	struct mac_biba *mac_biba;
810101099Srwatson	int biba_type;
811101099Srwatson
812101099Srwatson	mac_biba = SLOT(label);
813101099Srwatson	if (strcmp(dev->si_name, "null") == 0 ||
814101099Srwatson	    strcmp(dev->si_name, "zero") == 0 ||
815101099Srwatson	    strcmp(dev->si_name, "random") == 0 ||
816101099Srwatson	    strncmp(dev->si_name, "fd/", strlen("fd/")) == 0)
817101099Srwatson		biba_type = MAC_BIBA_TYPE_EQUAL;
818105606Srwatson	else if (ptys_equal &&
819105606Srwatson	    (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 ||
820105606Srwatson	    strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0))
821105606Srwatson		biba_type = MAC_BIBA_TYPE_EQUAL;
822101099Srwatson	else
823101099Srwatson		biba_type = MAC_BIBA_TYPE_HIGH;
824105643Srwatson	mac_biba_set_single(mac_biba, biba_type, 0, NULL);
825101099Srwatson}
826101099Srwatson
827101099Srwatsonstatic void
828101099Srwatsonmac_biba_create_devfs_directory(char *dirname, int dirnamelen,
829101099Srwatson    struct devfs_dirent *devfs_dirent, struct label *label)
830101099Srwatson{
831101099Srwatson	struct mac_biba *mac_biba;
832101099Srwatson
833101099Srwatson	mac_biba = SLOT(label);
834105643Srwatson	mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
835101099Srwatson}
836101099Srwatson
837101099Srwatsonstatic void
838104535Srwatsonmac_biba_create_devfs_symlink(struct ucred *cred, struct devfs_dirent *dd,
839104535Srwatson    struct label *ddlabel, struct devfs_dirent *de, struct label *delabel)
840104535Srwatson{
841104535Srwatson	struct mac_biba *source, *dest;
842104535Srwatson
843104535Srwatson	source = SLOT(&cred->cr_label);
844104535Srwatson	dest = SLOT(delabel);
845104535Srwatson
846104535Srwatson	mac_biba_copy_single(source, dest);
847104535Srwatson}
848104535Srwatson
849104535Srwatsonstatic void
850101099Srwatsonmac_biba_create_devfs_vnode(struct devfs_dirent *devfs_dirent,
851101099Srwatson    struct label *direntlabel, struct vnode *vp, struct label *vnodelabel)
852101099Srwatson{
853101099Srwatson	struct mac_biba *source, *dest;
854101099Srwatson
855101099Srwatson	source = SLOT(direntlabel);
856101099Srwatson	dest = SLOT(vnodelabel);
857101099Srwatson	mac_biba_copy_single(source, dest);
858101099Srwatson}
859101099Srwatson
860101099Srwatsonstatic void
861101099Srwatsonmac_biba_create_mount(struct ucred *cred, struct mount *mp,
862101099Srwatson    struct label *mntlabel, struct label *fslabel)
863101099Srwatson{
864101099Srwatson	struct mac_biba *source, *dest;
865101099Srwatson
866101099Srwatson	source = SLOT(&cred->cr_label);
867101099Srwatson	dest = SLOT(mntlabel);
868101099Srwatson	mac_biba_copy_single(source, dest);
869101099Srwatson	dest = SLOT(fslabel);
870101099Srwatson	mac_biba_copy_single(source, dest);
871101099Srwatson}
872101099Srwatson
873101099Srwatsonstatic void
874101099Srwatsonmac_biba_create_root_mount(struct ucred *cred, struct mount *mp,
875101099Srwatson    struct label *mntlabel, struct label *fslabel)
876101099Srwatson{
877101099Srwatson	struct mac_biba *mac_biba;
878101099Srwatson
879101099Srwatson	/* Always mount root as high integrity. */
880101099Srwatson	mac_biba = SLOT(fslabel);
881105643Srwatson	mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
882101099Srwatson	mac_biba = SLOT(mntlabel);
883105643Srwatson	mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
884101099Srwatson}
885101099Srwatson
886101099Srwatsonstatic void
887101099Srwatsonmac_biba_relabel_vnode(struct ucred *cred, struct vnode *vp,
888101099Srwatson    struct label *vnodelabel, struct label *label)
889101099Srwatson{
890101099Srwatson	struct mac_biba *source, *dest;
891101099Srwatson
892101099Srwatson	source = SLOT(label);
893101099Srwatson	dest = SLOT(vnodelabel);
894101099Srwatson
895105656Srwatson	mac_biba_copy(source, dest);
896101099Srwatson}
897101099Srwatson
898101099Srwatsonstatic void
899101099Srwatsonmac_biba_update_devfsdirent(struct devfs_dirent *devfs_dirent,
900101099Srwatson    struct label *direntlabel, struct vnode *vp, struct label *vnodelabel)
901101099Srwatson{
902101099Srwatson	struct mac_biba *source, *dest;
903101099Srwatson
904101099Srwatson	source = SLOT(vnodelabel);
905101099Srwatson	dest = SLOT(direntlabel);
906101099Srwatson
907105656Srwatson	mac_biba_copy(source, dest);
908101099Srwatson}
909101099Srwatson
910101099Srwatsonstatic void
911105988Srwatsonmac_biba_associate_vnode_devfs(struct mount *mp, struct label *fslabel,
912105988Srwatson    struct devfs_dirent *de, struct label *delabel, struct vnode *vp,
913105988Srwatson    struct label *vlabel)
914101099Srwatson{
915101099Srwatson	struct mac_biba *source, *dest;
916101099Srwatson
917105988Srwatson	source = SLOT(delabel);
918105988Srwatson	dest = SLOT(vlabel);
919101099Srwatson
920101099Srwatson	mac_biba_copy_single(source, dest);
921101099Srwatson}
922101099Srwatson
923101099Srwatsonstatic int
924105988Srwatsonmac_biba_associate_vnode_extattr(struct mount *mp, struct label *fslabel,
925105988Srwatson    struct vnode *vp, struct label *vlabel)
926101099Srwatson{
927105988Srwatson	struct mac_biba temp, *source, *dest;
928105988Srwatson	size_t buflen;
929101099Srwatson	int error;
930101099Srwatson
931105988Srwatson	source = SLOT(fslabel);
932105988Srwatson	dest = SLOT(vlabel);
933101099Srwatson
934105988Srwatson	buflen = sizeof(temp);
935105988Srwatson	bzero(&temp, buflen);
936105988Srwatson
937105988Srwatson	error = vn_extattr_get(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
938105988Srwatson	    MAC_BIBA_EXTATTR_NAME, &buflen, (char *) &temp, curthread);
939105988Srwatson	if (error == ENOATTR || error == EOPNOTSUPP) {
940105988Srwatson		/* Fall back to the fslabel. */
941105988Srwatson		mac_biba_copy_single(source, dest);
942105988Srwatson		return (0);
943105988Srwatson	} else if (error)
944101099Srwatson		return (error);
945101099Srwatson
946105988Srwatson	if (buflen != sizeof(temp)) {
947105988Srwatson		printf("mac_biba_associate_vnode_extattr: bad size %d\n",
948105988Srwatson		    buflen);
949105988Srwatson		return (EPERM);
950105988Srwatson	}
951105988Srwatson	if (mac_biba_valid(&temp) != 0) {
952105988Srwatson		printf("mac_biba_associate_vnode_extattr: invalid\n");
953105988Srwatson		return (EPERM);
954105988Srwatson	}
955105988Srwatson	if ((temp.mb_flags & MAC_BIBA_FLAGS_BOTH) != MAC_BIBA_FLAG_SINGLE) {
956105988Srwatson		printf("mac_biba_associate_vnode_extattr: not single\n");
957105988Srwatson		return (EPERM);
958105988Srwatson	}
959101099Srwatson
960105988Srwatson	mac_biba_copy_single(&temp, dest);
961101099Srwatson	return (0);
962101099Srwatson}
963101099Srwatson
964101099Srwatsonstatic void
965105988Srwatsonmac_biba_associate_vnode_singlelabel(struct mount *mp,
966105988Srwatson    struct label *fslabel, struct vnode *vp, struct label *vlabel)
967101099Srwatson{
968101099Srwatson	struct mac_biba *source, *dest;
969101099Srwatson
970101099Srwatson	source = SLOT(fslabel);
971105988Srwatson	dest = SLOT(vlabel);
972101099Srwatson
973101099Srwatson	mac_biba_copy_single(source, dest);
974101099Srwatson}
975101099Srwatson
976105988Srwatsonstatic int
977105988Srwatsonmac_biba_create_vnode_extattr(struct ucred *cred, struct mount *mp,
978105988Srwatson    struct label *fslabel, struct vnode *dvp, struct label *dlabel,
979105988Srwatson    struct vnode *vp, struct label *vlabel, struct componentname *cnp)
980105988Srwatson{
981105988Srwatson	struct mac_biba *source, *dest, temp;
982105988Srwatson	size_t buflen;
983105988Srwatson	int error;
984105988Srwatson
985105988Srwatson	buflen = sizeof(temp);
986105988Srwatson	bzero(&temp, buflen);
987105988Srwatson
988105988Srwatson	source = SLOT(&cred->cr_label);
989105988Srwatson	dest = SLOT(vlabel);
990105988Srwatson	mac_biba_copy_single(source, &temp);
991105988Srwatson
992105988Srwatson	error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
993105988Srwatson	    MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread);
994105988Srwatson	if (error == 0)
995105988Srwatson		mac_biba_copy_single(source, dest);
996105988Srwatson	return (error);
997105988Srwatson}
998105988Srwatson
999105988Srwatsonstatic int
1000105988Srwatsonmac_biba_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp,
1001105988Srwatson    struct label *vlabel, struct label *intlabel)
1002105988Srwatson{
1003105988Srwatson	struct mac_biba *source, temp;
1004105988Srwatson	size_t buflen;
1005105988Srwatson	int error;
1006105988Srwatson
1007105988Srwatson	buflen = sizeof(temp);
1008105988Srwatson	bzero(&temp, buflen);
1009105988Srwatson
1010105988Srwatson	source = SLOT(intlabel);
1011105988Srwatson	if ((source->mb_flags & MAC_BIBA_FLAG_SINGLE) == 0)
1012105988Srwatson		return (0);
1013105988Srwatson
1014105988Srwatson	mac_biba_copy_single(source, &temp);
1015105988Srwatson
1016105988Srwatson	error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
1017105988Srwatson	    MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread);
1018105988Srwatson	return (error);
1019105988Srwatson}
1020105988Srwatson
1021101099Srwatson/*
1022101099Srwatson * Labeling event operations: IPC object.
1023101099Srwatson */
1024101099Srwatsonstatic void
1025101099Srwatsonmac_biba_create_mbuf_from_socket(struct socket *so, struct label *socketlabel,
1026101099Srwatson    struct mbuf *m, struct label *mbuflabel)
1027101099Srwatson{
1028101099Srwatson	struct mac_biba *source, *dest;
1029101099Srwatson
1030101099Srwatson	source = SLOT(socketlabel);
1031101099Srwatson	dest = SLOT(mbuflabel);
1032101099Srwatson
1033101099Srwatson	mac_biba_copy_single(source, dest);
1034101099Srwatson}
1035101099Srwatson
1036101099Srwatsonstatic void
1037101099Srwatsonmac_biba_create_socket(struct ucred *cred, struct socket *socket,
1038101099Srwatson    struct label *socketlabel)
1039101099Srwatson{
1040101099Srwatson	struct mac_biba *source, *dest;
1041101099Srwatson
1042101099Srwatson	source = SLOT(&cred->cr_label);
1043101099Srwatson	dest = SLOT(socketlabel);
1044101099Srwatson
1045101099Srwatson	mac_biba_copy_single(source, dest);
1046101099Srwatson}
1047101099Srwatson
1048101099Srwatsonstatic void
1049101099Srwatsonmac_biba_create_pipe(struct ucred *cred, struct pipe *pipe,
1050101099Srwatson    struct label *pipelabel)
1051101099Srwatson{
1052101099Srwatson	struct mac_biba *source, *dest;
1053101099Srwatson
1054101099Srwatson	source = SLOT(&cred->cr_label);
1055101099Srwatson	dest = SLOT(pipelabel);
1056101099Srwatson
1057101099Srwatson	mac_biba_copy_single(source, dest);
1058101099Srwatson}
1059101099Srwatson
1060101099Srwatsonstatic void
1061101099Srwatsonmac_biba_create_socket_from_socket(struct socket *oldsocket,
1062101099Srwatson    struct label *oldsocketlabel, struct socket *newsocket,
1063101099Srwatson    struct label *newsocketlabel)
1064101099Srwatson{
1065101099Srwatson	struct mac_biba *source, *dest;
1066101099Srwatson
1067101099Srwatson	source = SLOT(oldsocketlabel);
1068101099Srwatson	dest = SLOT(newsocketlabel);
1069101099Srwatson
1070101099Srwatson	mac_biba_copy_single(source, dest);
1071101099Srwatson}
1072101099Srwatson
1073101099Srwatsonstatic void
1074101099Srwatsonmac_biba_relabel_socket(struct ucred *cred, struct socket *socket,
1075101099Srwatson    struct label *socketlabel, struct label *newlabel)
1076101099Srwatson{
1077101099Srwatson	struct mac_biba *source, *dest;
1078101099Srwatson
1079101099Srwatson	source = SLOT(newlabel);
1080101099Srwatson	dest = SLOT(socketlabel);
1081101099Srwatson
1082105656Srwatson	mac_biba_copy(source, dest);
1083101099Srwatson}
1084101099Srwatson
1085101099Srwatsonstatic void
1086101099Srwatsonmac_biba_relabel_pipe(struct ucred *cred, struct pipe *pipe,
1087101099Srwatson    struct label *pipelabel, struct label *newlabel)
1088101099Srwatson{
1089101099Srwatson	struct mac_biba *source, *dest;
1090101099Srwatson
1091101099Srwatson	source = SLOT(newlabel);
1092101099Srwatson	dest = SLOT(pipelabel);
1093101099Srwatson
1094105656Srwatson	mac_biba_copy(source, dest);
1095101099Srwatson}
1096101099Srwatson
1097101099Srwatsonstatic void
1098101099Srwatsonmac_biba_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel,
1099101099Srwatson    struct socket *socket, struct label *socketpeerlabel)
1100101099Srwatson{
1101101099Srwatson	struct mac_biba *source, *dest;
1102101099Srwatson
1103101099Srwatson	source = SLOT(mbuflabel);
1104101099Srwatson	dest = SLOT(socketpeerlabel);
1105101099Srwatson
1106101099Srwatson	mac_biba_copy_single(source, dest);
1107101099Srwatson}
1108101099Srwatson
1109101099Srwatson/*
1110101099Srwatson * Labeling event operations: network objects.
1111101099Srwatson */
1112101099Srwatsonstatic void
1113101099Srwatsonmac_biba_set_socket_peer_from_socket(struct socket *oldsocket,
1114101099Srwatson    struct label *oldsocketlabel, struct socket *newsocket,
1115101099Srwatson    struct label *newsocketpeerlabel)
1116101099Srwatson{
1117101099Srwatson	struct mac_biba *source, *dest;
1118101099Srwatson
1119101099Srwatson	source = SLOT(oldsocketlabel);
1120101099Srwatson	dest = SLOT(newsocketpeerlabel);
1121101099Srwatson
1122101099Srwatson	mac_biba_copy_single(source, dest);
1123101099Srwatson}
1124101099Srwatson
1125101099Srwatsonstatic void
1126101099Srwatsonmac_biba_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d,
1127101099Srwatson    struct label *bpflabel)
1128101099Srwatson{
1129101099Srwatson	struct mac_biba *source, *dest;
1130101099Srwatson
1131101099Srwatson	source = SLOT(&cred->cr_label);
1132101099Srwatson	dest = SLOT(bpflabel);
1133101099Srwatson
1134101099Srwatson	mac_biba_copy_single(source, dest);
1135101099Srwatson}
1136101099Srwatson
1137101099Srwatsonstatic void
1138101099Srwatsonmac_biba_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel)
1139101099Srwatson{
1140101099Srwatson	char tifname[IFNAMSIZ], ifname[IFNAMSIZ], *p, *q;
1141101099Srwatson	char tiflist[sizeof(trusted_interfaces)];
1142101099Srwatson	struct mac_biba *dest;
1143101099Srwatson	int len, grade;
1144101099Srwatson
1145101099Srwatson	dest = SLOT(ifnetlabel);
1146101099Srwatson
1147101099Srwatson	if (ifnet->if_type == IFT_LOOP) {
1148101099Srwatson		grade = MAC_BIBA_TYPE_EQUAL;
1149101099Srwatson		goto set;
1150101099Srwatson	}
1151101099Srwatson
1152101099Srwatson	if (trust_all_interfaces) {
1153101099Srwatson		grade = MAC_BIBA_TYPE_HIGH;
1154101099Srwatson		goto set;
1155101099Srwatson	}
1156101099Srwatson
1157101099Srwatson	grade = MAC_BIBA_TYPE_LOW;
1158101099Srwatson
1159101099Srwatson	if (trusted_interfaces[0] == '\0' ||
1160101099Srwatson	    !strvalid(trusted_interfaces, sizeof(trusted_interfaces)))
1161101099Srwatson		goto set;
1162101099Srwatson
1163106089Srwatson	bzero(tiflist, sizeof(tiflist));
1164101099Srwatson	for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++)
1165101099Srwatson		if(*p != ' ' && *p != '\t')
1166101099Srwatson			*q = *p;
1167101099Srwatson
1168101099Srwatson	snprintf(ifname, IFNAMSIZ, "%s%d", ifnet->if_name, ifnet->if_unit);
1169101099Srwatson
1170101099Srwatson	for (p = q = tiflist;; p++) {
1171101099Srwatson		if (*p == ',' || *p == '\0') {
1172101099Srwatson			len = p - q;
1173101099Srwatson			if (len < IFNAMSIZ) {
1174101099Srwatson				bzero(tifname, sizeof(tifname));
1175101099Srwatson				bcopy(q, tifname, len);
1176101099Srwatson				if (strcmp(tifname, ifname) == 0) {
1177101099Srwatson					grade = MAC_BIBA_TYPE_HIGH;
1178101099Srwatson					break;
1179101099Srwatson				}
1180106089Srwatson			} else {
1181106089Srwatson				*p = '\0';
1182106089Srwatson				printf("mac_biba warning: interface name "
1183106089Srwatson				    "\"%s\" is too long (must be < %d)\n",
1184106089Srwatson				    q, IFNAMSIZ);
1185101099Srwatson			}
1186101099Srwatson			if (*p == '\0')
1187101099Srwatson				break;
1188101099Srwatson			q = p + 1;
1189101099Srwatson		}
1190101099Srwatson	}
1191101099Srwatsonset:
1192105643Srwatson	mac_biba_set_single(dest, grade, 0, NULL);
1193105643Srwatson	mac_biba_set_range(dest, grade, 0, NULL, grade, 0, NULL);
1194101099Srwatson}
1195101099Srwatson
1196101099Srwatsonstatic void
1197101099Srwatsonmac_biba_create_ipq(struct mbuf *fragment, struct label *fragmentlabel,
1198101099Srwatson    struct ipq *ipq, struct label *ipqlabel)
1199101099Srwatson{
1200101099Srwatson	struct mac_biba *source, *dest;
1201101099Srwatson
1202101099Srwatson	source = SLOT(fragmentlabel);
1203101099Srwatson	dest = SLOT(ipqlabel);
1204101099Srwatson
1205101099Srwatson	mac_biba_copy_single(source, dest);
1206101099Srwatson}
1207101099Srwatson
1208101099Srwatsonstatic void
1209101099Srwatsonmac_biba_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel,
1210101099Srwatson    struct mbuf *datagram, struct label *datagramlabel)
1211101099Srwatson{
1212101099Srwatson	struct mac_biba *source, *dest;
1213101099Srwatson
1214101099Srwatson	source = SLOT(ipqlabel);
1215101099Srwatson	dest = SLOT(datagramlabel);
1216101099Srwatson
1217101099Srwatson	/* Just use the head, since we require them all to match. */
1218101099Srwatson	mac_biba_copy_single(source, dest);
1219101099Srwatson}
1220101099Srwatson
1221101099Srwatsonstatic void
1222101099Srwatsonmac_biba_create_fragment(struct mbuf *datagram, struct label *datagramlabel,
1223101099Srwatson    struct mbuf *fragment, struct label *fragmentlabel)
1224101099Srwatson{
1225101099Srwatson	struct mac_biba *source, *dest;
1226101099Srwatson
1227101099Srwatson	source = SLOT(datagramlabel);
1228101099Srwatson	dest = SLOT(fragmentlabel);
1229101099Srwatson
1230101099Srwatson	mac_biba_copy_single(source, dest);
1231101099Srwatson}
1232101099Srwatson
1233101099Srwatsonstatic void
1234101099Srwatsonmac_biba_create_mbuf_from_mbuf(struct mbuf *oldmbuf,
1235101099Srwatson    struct label *oldmbuflabel, struct mbuf *newmbuf,
1236101099Srwatson    struct label *newmbuflabel)
1237101099Srwatson{
1238101099Srwatson	struct mac_biba *source, *dest;
1239101099Srwatson
1240101099Srwatson	source = SLOT(oldmbuflabel);
1241101099Srwatson	dest = SLOT(newmbuflabel);
1242101099Srwatson
1243105656Srwatson	/*
1244105656Srwatson	 * Because the source mbuf may not yet have been "created",
1245105696Srwatson	 * just initialized, we do a conditional copy.  Since we don't
1246105656Srwatson	 * allow mbufs to have ranges, do a KASSERT to make sure that
1247105656Srwatson	 * doesn't happen.
1248105656Srwatson	 */
1249105656Srwatson	KASSERT((source->mb_flags & MAC_BIBA_FLAG_RANGE) == 0,
1250105656Srwatson	    ("mac_biba_create_mbuf_from_mbuf: source mbuf has range"));
1251105656Srwatson	mac_biba_copy(source, dest);
1252101099Srwatson}
1253101099Srwatson
1254101099Srwatsonstatic void
1255101099Srwatsonmac_biba_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel,
1256101099Srwatson    struct mbuf *mbuf, struct label *mbuflabel)
1257101099Srwatson{
1258101099Srwatson	struct mac_biba *dest;
1259101099Srwatson
1260101099Srwatson	dest = SLOT(mbuflabel);
1261101099Srwatson
1262105643Srwatson	mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1263101099Srwatson}
1264101099Srwatson
1265101099Srwatsonstatic void
1266101099Srwatsonmac_biba_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel,
1267101099Srwatson    struct mbuf *mbuf, struct label *mbuflabel)
1268101099Srwatson{
1269101099Srwatson	struct mac_biba *source, *dest;
1270101099Srwatson
1271101099Srwatson	source = SLOT(bpflabel);
1272101099Srwatson	dest = SLOT(mbuflabel);
1273101099Srwatson
1274101099Srwatson	mac_biba_copy_single(source, dest);
1275101099Srwatson}
1276101099Srwatson
1277101099Srwatsonstatic void
1278101099Srwatsonmac_biba_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel,
1279101099Srwatson    struct mbuf *m, struct label *mbuflabel)
1280101099Srwatson{
1281101099Srwatson	struct mac_biba *source, *dest;
1282101099Srwatson
1283101099Srwatson	source = SLOT(ifnetlabel);
1284101099Srwatson	dest = SLOT(mbuflabel);
1285101099Srwatson
1286101099Srwatson	mac_biba_copy_single(source, dest);
1287101099Srwatson}
1288101099Srwatson
1289101099Srwatsonstatic void
1290101099Srwatsonmac_biba_create_mbuf_multicast_encap(struct mbuf *oldmbuf,
1291101099Srwatson    struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel,
1292101099Srwatson    struct mbuf *newmbuf, struct label *newmbuflabel)
1293101099Srwatson{
1294101099Srwatson	struct mac_biba *source, *dest;
1295101099Srwatson
1296101099Srwatson	source = SLOT(oldmbuflabel);
1297101099Srwatson	dest = SLOT(newmbuflabel);
1298101099Srwatson
1299101099Srwatson	mac_biba_copy_single(source, dest);
1300101099Srwatson}
1301101099Srwatson
1302101099Srwatsonstatic void
1303101099Srwatsonmac_biba_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel,
1304101099Srwatson    struct mbuf *newmbuf, struct label *newmbuflabel)
1305101099Srwatson{
1306101099Srwatson	struct mac_biba *source, *dest;
1307101099Srwatson
1308101099Srwatson	source = SLOT(oldmbuflabel);
1309101099Srwatson	dest = SLOT(newmbuflabel);
1310101099Srwatson
1311101099Srwatson	mac_biba_copy_single(source, dest);
1312101099Srwatson}
1313101099Srwatson
1314101099Srwatsonstatic int
1315101099Srwatsonmac_biba_fragment_match(struct mbuf *fragment, struct label *fragmentlabel,
1316101099Srwatson    struct ipq *ipq, struct label *ipqlabel)
1317101099Srwatson{
1318101099Srwatson	struct mac_biba *a, *b;
1319101099Srwatson
1320101099Srwatson	a = SLOT(ipqlabel);
1321101099Srwatson	b = SLOT(fragmentlabel);
1322101099Srwatson
1323101099Srwatson	return (mac_biba_equal_single(a, b));
1324101099Srwatson}
1325101099Srwatson
1326101099Srwatsonstatic void
1327101099Srwatsonmac_biba_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet,
1328101099Srwatson    struct label *ifnetlabel, struct label *newlabel)
1329101099Srwatson{
1330101099Srwatson	struct mac_biba *source, *dest;
1331101099Srwatson
1332101099Srwatson	source = SLOT(newlabel);
1333101099Srwatson	dest = SLOT(ifnetlabel);
1334101099Srwatson
1335105656Srwatson	mac_biba_copy(source, dest);
1336101099Srwatson}
1337101099Srwatson
1338101099Srwatsonstatic void
1339101099Srwatsonmac_biba_update_ipq(struct mbuf *fragment, struct label *fragmentlabel,
1340101099Srwatson    struct ipq *ipq, struct label *ipqlabel)
1341101099Srwatson{
1342101099Srwatson
1343101099Srwatson	/* NOOP: we only accept matching labels, so no need to update */
1344101099Srwatson}
1345101099Srwatson
1346101099Srwatson/*
1347101099Srwatson * Labeling event operations: processes.
1348101099Srwatson */
1349101099Srwatsonstatic void
1350101099Srwatsonmac_biba_create_cred(struct ucred *cred_parent, struct ucred *cred_child)
1351101099Srwatson{
1352101099Srwatson	struct mac_biba *source, *dest;
1353101099Srwatson
1354101099Srwatson	source = SLOT(&cred_parent->cr_label);
1355101099Srwatson	dest = SLOT(&cred_child->cr_label);
1356101099Srwatson
1357101099Srwatson	mac_biba_copy_single(source, dest);
1358101099Srwatson	mac_biba_copy_range(source, dest);
1359101099Srwatson}
1360101099Srwatson
1361101099Srwatsonstatic void
1362101099Srwatsonmac_biba_execve_transition(struct ucred *old, struct ucred *new,
1363101099Srwatson    struct vnode *vp, struct mac *vnodelabel)
1364101099Srwatson{
1365101099Srwatson	struct mac_biba *source, *dest;
1366101099Srwatson
1367101099Srwatson	source = SLOT(&old->cr_label);
1368101099Srwatson	dest = SLOT(&new->cr_label);
1369101099Srwatson
1370101099Srwatson	mac_biba_copy_single(source, dest);
1371101099Srwatson	mac_biba_copy_range(source, dest);
1372101099Srwatson}
1373101099Srwatson
1374101099Srwatsonstatic int
1375101099Srwatsonmac_biba_execve_will_transition(struct ucred *old, struct vnode *vp,
1376101099Srwatson    struct mac *vnodelabel)
1377101099Srwatson{
1378101099Srwatson
1379101099Srwatson	return (0);
1380101099Srwatson}
1381101099Srwatson
1382101099Srwatsonstatic void
1383101099Srwatsonmac_biba_create_proc0(struct ucred *cred)
1384101099Srwatson{
1385101099Srwatson	struct mac_biba *dest;
1386101099Srwatson
1387101099Srwatson	dest = SLOT(&cred->cr_label);
1388101099Srwatson
1389105643Srwatson	mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1390105643Srwatson	mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL,
1391105643Srwatson	    MAC_BIBA_TYPE_HIGH, 0, NULL);
1392101099Srwatson}
1393101099Srwatson
1394101099Srwatsonstatic void
1395101099Srwatsonmac_biba_create_proc1(struct ucred *cred)
1396101099Srwatson{
1397101099Srwatson	struct mac_biba *dest;
1398101099Srwatson
1399101099Srwatson	dest = SLOT(&cred->cr_label);
1400101099Srwatson
1401105643Srwatson	mac_biba_set_single(dest, MAC_BIBA_TYPE_HIGH, 0, NULL);
1402105643Srwatson	mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL,
1403105643Srwatson	    MAC_BIBA_TYPE_HIGH, 0, NULL);
1404101099Srwatson}
1405101099Srwatson
1406101099Srwatsonstatic void
1407101099Srwatsonmac_biba_relabel_cred(struct ucred *cred, struct label *newlabel)
1408101099Srwatson{
1409101099Srwatson	struct mac_biba *source, *dest;
1410101099Srwatson
1411101099Srwatson	source = SLOT(newlabel);
1412101099Srwatson	dest = SLOT(&cred->cr_label);
1413101099Srwatson
1414105656Srwatson	mac_biba_copy(source, dest);
1415101099Srwatson}
1416101099Srwatson
1417101099Srwatson/*
1418101099Srwatson * Access control checks.
1419101099Srwatson */
1420101099Srwatsonstatic int
1421101099Srwatsonmac_biba_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel,
1422101099Srwatson    struct ifnet *ifnet, struct label *ifnetlabel)
1423101099Srwatson{
1424101099Srwatson	struct mac_biba *a, *b;
1425101099Srwatson
1426101099Srwatson	if (!mac_biba_enabled)
1427101099Srwatson		return (0);
1428101099Srwatson
1429101099Srwatson	a = SLOT(bpflabel);
1430101099Srwatson	b = SLOT(ifnetlabel);
1431101099Srwatson
1432101099Srwatson	if (mac_biba_equal_single(a, b))
1433101099Srwatson		return (0);
1434101099Srwatson	return (EACCES);
1435101099Srwatson}
1436101099Srwatson
1437101099Srwatsonstatic int
1438101099Srwatsonmac_biba_check_cred_relabel(struct ucred *cred, struct label *newlabel)
1439101099Srwatson{
1440101099Srwatson	struct mac_biba *subj, *new;
1441105634Srwatson	int error;
1442101099Srwatson
1443101099Srwatson	subj = SLOT(&cred->cr_label);
1444101099Srwatson	new = SLOT(newlabel);
1445101099Srwatson
1446101099Srwatson	/*
1447105634Srwatson	 * If there is a Biba label update for the credential, it may
1448105634Srwatson	 * be an update of the single, range, or both.
1449101099Srwatson	 */
1450105634Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
1451105634Srwatson	if (error)
1452105634Srwatson		return (error);
1453101099Srwatson
1454101099Srwatson	/*
1455105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
1456101099Srwatson	 */
1457105634Srwatson	if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) {
1458105634Srwatson		/*
1459105634Srwatson		 * To change the Biba single label on a credential, the
1460105634Srwatson		 * new single label must be in the current range.
1461105634Srwatson		 */
1462105634Srwatson		if (new->mb_flags & MAC_BIBA_FLAG_SINGLE &&
1463105634Srwatson		    !mac_biba_single_in_range(new, subj))
1464105634Srwatson			return (EPERM);
1465101099Srwatson
1466105634Srwatson		/*
1467105634Srwatson		 * To change the Biba range on a credential, the new
1468105634Srwatson		 * range label must be in the current range.
1469105634Srwatson		 */
1470105634Srwatson		if (new->mb_flags & MAC_BIBA_FLAG_RANGE &&
1471105634Srwatson		    !mac_biba_range_in_range(new, subj))
1472105634Srwatson			return (EPERM);
1473101099Srwatson
1474105634Srwatson		/*
1475105634Srwatson		 * To have EQUAL in any component of the new credential
1476105634Srwatson		 * Biba label, the subject must already have EQUAL in
1477105634Srwatson		 * their label.
1478105634Srwatson		 */
1479105634Srwatson		if (mac_biba_contains_equal(new)) {
1480106090Srwatson			error = mac_biba_subject_privileged(subj);
1481105634Srwatson			if (error)
1482105634Srwatson				return (error);
1483105634Srwatson		}
1484101099Srwatson
1485105634Srwatson		/*
1486105634Srwatson		 * XXXMAC: Additional consistency tests regarding the
1487105634Srwatson		 * single and range of the new label might be performed
1488105634Srwatson		 * here.
1489105634Srwatson		 */
1490105634Srwatson	}
1491105634Srwatson
1492101099Srwatson	return (0);
1493101099Srwatson}
1494101099Srwatson
1495101099Srwatsonstatic int
1496101099Srwatsonmac_biba_check_cred_visible(struct ucred *u1, struct ucred *u2)
1497101099Srwatson{
1498101099Srwatson	struct mac_biba *subj, *obj;
1499101099Srwatson
1500101099Srwatson	if (!mac_biba_enabled)
1501101099Srwatson		return (0);
1502101099Srwatson
1503101099Srwatson	subj = SLOT(&u1->cr_label);
1504101099Srwatson	obj = SLOT(&u2->cr_label);
1505101099Srwatson
1506101099Srwatson	/* XXX: range */
1507101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1508101099Srwatson		return (ESRCH);
1509101099Srwatson
1510101099Srwatson	return (0);
1511101099Srwatson}
1512101099Srwatson
1513101099Srwatsonstatic int
1514101099Srwatsonmac_biba_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet,
1515101099Srwatson    struct label *ifnetlabel, struct label *newlabel)
1516101099Srwatson{
1517101099Srwatson	struct mac_biba *subj, *new;
1518105634Srwatson	int error;
1519101099Srwatson
1520101099Srwatson	subj = SLOT(&cred->cr_label);
1521101099Srwatson	new = SLOT(newlabel);
1522101099Srwatson
1523105634Srwatson	/*
1524105634Srwatson	 * If there is a Biba label update for the interface, it may
1525105634Srwatson	 * be an update of the single, range, or both.
1526105634Srwatson	 */
1527105634Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
1528105634Srwatson	if (error)
1529105634Srwatson		return (error);
1530101099Srwatson
1531105634Srwatson	/*
1532106160Srwatson	 * Relabling network interfaces requires Biba privilege.
1533106160Srwatson	 */
1534106160Srwatson	error = mac_biba_subject_privileged(subj);
1535106160Srwatson	if (error)
1536106160Srwatson		return (error);
1537106160Srwatson
1538106160Srwatson	/*
1539105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
1540105634Srwatson	 */
1541105634Srwatson	if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) {
1542105634Srwatson		/*
1543105634Srwatson		 * Rely on the traditional superuser status for the Biba
1544105634Srwatson		 * interface relabel requirements.  XXXMAC: This will go
1545105634Srwatson		 * away.
1546105634Srwatson		 */
1547105634Srwatson		error = suser_cred(cred, 0);
1548105634Srwatson		if (error)
1549105634Srwatson			return (EPERM);
1550105634Srwatson
1551105634Srwatson		/*
1552105634Srwatson		 * XXXMAC: Additional consistency tests regarding the single
1553105634Srwatson		 * and the range of the new label might be performed here.
1554105634Srwatson		 */
1555105634Srwatson	}
1556105634Srwatson
1557105634Srwatson	return (0);
1558101099Srwatson}
1559101099Srwatson
1560103759Srwatsonstatic int
1561101099Srwatsonmac_biba_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel,
1562101099Srwatson    struct mbuf *m, struct label *mbuflabel)
1563101099Srwatson{
1564101099Srwatson	struct mac_biba *p, *i;
1565103761Srwatson
1566101099Srwatson	if (!mac_biba_enabled)
1567101099Srwatson		return (0);
1568101099Srwatson
1569101099Srwatson	p = SLOT(mbuflabel);
1570101099Srwatson	i = SLOT(ifnetlabel);
1571103759Srwatson
1572101099Srwatson	return (mac_biba_single_in_range(p, i) ? 0 : EACCES);
1573101099Srwatson}
1574101099Srwatson
1575101099Srwatsonstatic int
1576101099Srwatsonmac_biba_check_mount_stat(struct ucred *cred, struct mount *mp,
1577101099Srwatson    struct label *mntlabel)
1578101099Srwatson{
1579101099Srwatson	struct mac_biba *subj, *obj;
1580101099Srwatson
1581101099Srwatson	if (!mac_biba_enabled)
1582101099Srwatson		return (0);
1583101099Srwatson
1584101099Srwatson	subj = SLOT(&cred->cr_label);
1585101099Srwatson	obj = SLOT(mntlabel);
1586101099Srwatson
1587101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1588101099Srwatson		return (EACCES);
1589101099Srwatson
1590101099Srwatson	return (0);
1591101099Srwatson}
1592101099Srwatson
1593101099Srwatsonstatic int
1594101099Srwatsonmac_biba_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe,
1595101099Srwatson    struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data)
1596101099Srwatson{
1597103759Srwatson
1598101099Srwatson	if(!mac_biba_enabled)
1599101099Srwatson		return (0);
1600101099Srwatson
1601101099Srwatson	/* XXX: This will be implemented soon... */
1602101099Srwatson
1603101099Srwatson	return (0);
1604101099Srwatson}
1605101099Srwatson
1606101099Srwatsonstatic int
1607102115Srwatsonmac_biba_check_pipe_poll(struct ucred *cred, struct pipe *pipe,
1608102115Srwatson    struct label *pipelabel)
1609101099Srwatson{
1610101099Srwatson	struct mac_biba *subj, *obj;
1611101099Srwatson
1612101099Srwatson	if (!mac_biba_enabled)
1613101099Srwatson		return (0);
1614101099Srwatson
1615101099Srwatson	subj = SLOT(&cred->cr_label);
1616101099Srwatson	obj = SLOT((pipelabel));
1617101099Srwatson
1618102115Srwatson	if (!mac_biba_dominate_single(obj, subj))
1619102115Srwatson		return (EACCES);
1620101099Srwatson
1621101099Srwatson	return (0);
1622101099Srwatson}
1623101099Srwatson
1624101099Srwatsonstatic int
1625102115Srwatsonmac_biba_check_pipe_read(struct ucred *cred, struct pipe *pipe,
1626102115Srwatson    struct label *pipelabel)
1627102115Srwatson{
1628102115Srwatson	struct mac_biba *subj, *obj;
1629102115Srwatson
1630102115Srwatson	if (!mac_biba_enabled)
1631102115Srwatson		return (0);
1632102115Srwatson
1633102115Srwatson	subj = SLOT(&cred->cr_label);
1634102115Srwatson	obj = SLOT((pipelabel));
1635102115Srwatson
1636102115Srwatson	if (!mac_biba_dominate_single(obj, subj))
1637102115Srwatson		return (EACCES);
1638102115Srwatson
1639102115Srwatson	return (0);
1640102115Srwatson}
1641102115Srwatson
1642102115Srwatsonstatic int
1643101099Srwatsonmac_biba_check_pipe_relabel(struct ucred *cred, struct pipe *pipe,
1644101099Srwatson    struct label *pipelabel, struct label *newlabel)
1645101099Srwatson{
1646101099Srwatson	struct mac_biba *subj, *obj, *new;
1647105634Srwatson	int error;
1648101099Srwatson
1649101099Srwatson	new = SLOT(newlabel);
1650101099Srwatson	subj = SLOT(&cred->cr_label);
1651101099Srwatson	obj = SLOT(pipelabel);
1652101099Srwatson
1653101099Srwatson	/*
1654105634Srwatson	 * If there is a Biba label update for a pipe, it must be a
1655105634Srwatson	 * single update.
1656101099Srwatson	 */
1657105634Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE);
1658105634Srwatson	if (error)
1659105634Srwatson		return (error);
1660101099Srwatson
1661101099Srwatson	/*
1662105634Srwatson	 * To perform a relabel of a pipe (Biba label or not), Biba must
1663105634Srwatson	 * authorize the relabel.
1664101099Srwatson	 */
1665105634Srwatson	if (!mac_biba_single_in_range(obj, subj))
1666101099Srwatson		return (EPERM);
1667101099Srwatson
1668101099Srwatson	/*
1669105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
1670101099Srwatson	 */
1671105634Srwatson	if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) {
1672105634Srwatson		/*
1673105634Srwatson		 * To change the Biba label on a pipe, the new pipe label
1674105634Srwatson		 * must be in the subject range.
1675105634Srwatson		 */
1676105634Srwatson		if (!mac_biba_single_in_range(new, subj))
1677105634Srwatson			return (EPERM);
1678101099Srwatson
1679105634Srwatson		/*
1680105634Srwatson		 * To change the Biba label on a pipe to be EQUAL, the
1681105634Srwatson		 * subject must have appropriate privilege.
1682105634Srwatson		 */
1683105634Srwatson		if (mac_biba_contains_equal(new)) {
1684106090Srwatson			error = mac_biba_subject_privileged(subj);
1685105634Srwatson			if (error)
1686105634Srwatson				return (error);
1687105634Srwatson		}
1688105634Srwatson	}
1689105634Srwatson
1690101099Srwatson	return (0);
1691101099Srwatson}
1692101099Srwatson
1693101099Srwatsonstatic int
1694102115Srwatsonmac_biba_check_pipe_stat(struct ucred *cred, struct pipe *pipe,
1695102115Srwatson    struct label *pipelabel)
1696102115Srwatson{
1697102115Srwatson	struct mac_biba *subj, *obj;
1698102115Srwatson
1699102115Srwatson	if (!mac_biba_enabled)
1700102115Srwatson		return (0);
1701102115Srwatson
1702102115Srwatson	subj = SLOT(&cred->cr_label);
1703102115Srwatson	obj = SLOT((pipelabel));
1704102115Srwatson
1705102115Srwatson	if (!mac_biba_dominate_single(obj, subj))
1706102115Srwatson		return (EACCES);
1707102115Srwatson
1708102115Srwatson	return (0);
1709102115Srwatson}
1710102115Srwatson
1711102115Srwatsonstatic int
1712102115Srwatsonmac_biba_check_pipe_write(struct ucred *cred, struct pipe *pipe,
1713102115Srwatson    struct label *pipelabel)
1714102115Srwatson{
1715102115Srwatson	struct mac_biba *subj, *obj;
1716102115Srwatson
1717102115Srwatson	if (!mac_biba_enabled)
1718102115Srwatson		return (0);
1719102115Srwatson
1720102115Srwatson	subj = SLOT(&cred->cr_label);
1721102115Srwatson	obj = SLOT((pipelabel));
1722102115Srwatson
1723102115Srwatson	if (!mac_biba_dominate_single(subj, obj))
1724102115Srwatson		return (EACCES);
1725102115Srwatson
1726102115Srwatson	return (0);
1727102115Srwatson}
1728102115Srwatson
1729102115Srwatsonstatic int
1730101099Srwatsonmac_biba_check_proc_debug(struct ucred *cred, struct proc *proc)
1731101099Srwatson{
1732101099Srwatson	struct mac_biba *subj, *obj;
1733101099Srwatson
1734101099Srwatson	if (!mac_biba_enabled)
1735101099Srwatson		return (0);
1736101099Srwatson
1737101099Srwatson	subj = SLOT(&cred->cr_label);
1738101099Srwatson	obj = SLOT(&proc->p_ucred->cr_label);
1739101099Srwatson
1740101099Srwatson	/* XXX: range checks */
1741101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1742101099Srwatson		return (ESRCH);
1743101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1744101099Srwatson		return (EACCES);
1745101099Srwatson
1746101099Srwatson	return (0);
1747101099Srwatson}
1748101099Srwatson
1749101099Srwatsonstatic int
1750101099Srwatsonmac_biba_check_proc_sched(struct ucred *cred, struct proc *proc)
1751101099Srwatson{
1752101099Srwatson	struct mac_biba *subj, *obj;
1753103759Srwatson
1754101099Srwatson	if (!mac_biba_enabled)
1755101099Srwatson		return (0);
1756101099Srwatson
1757101099Srwatson	subj = SLOT(&cred->cr_label);
1758101099Srwatson	obj = SLOT(&proc->p_ucred->cr_label);
1759103759Srwatson
1760101099Srwatson	/* XXX: range checks */
1761101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1762101099Srwatson		return (ESRCH);
1763101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1764101099Srwatson		return (EACCES);
1765101099Srwatson
1766101099Srwatson	return (0);
1767101099Srwatson}
1768101099Srwatson
1769101099Srwatsonstatic int
1770101099Srwatsonmac_biba_check_proc_signal(struct ucred *cred, struct proc *proc, int signum)
1771101099Srwatson{
1772101099Srwatson	struct mac_biba *subj, *obj;
1773103759Srwatson
1774101099Srwatson	if (!mac_biba_enabled)
1775101099Srwatson		return (0);
1776101099Srwatson
1777101099Srwatson	subj = SLOT(&cred->cr_label);
1778101099Srwatson	obj = SLOT(&proc->p_ucred->cr_label);
1779103759Srwatson
1780101099Srwatson	/* XXX: range checks */
1781101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1782101099Srwatson		return (ESRCH);
1783101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1784101099Srwatson		return (EACCES);
1785101099Srwatson
1786101099Srwatson	return (0);
1787101099Srwatson}
1788101099Srwatson
1789101099Srwatsonstatic int
1790101934Srwatsonmac_biba_check_socket_deliver(struct socket *so, struct label *socketlabel,
1791101099Srwatson    struct mbuf *m, struct label *mbuflabel)
1792101099Srwatson{
1793101099Srwatson	struct mac_biba *p, *s;
1794101099Srwatson
1795101099Srwatson	if (!mac_biba_enabled)
1796101099Srwatson		return (0);
1797101099Srwatson
1798101099Srwatson	p = SLOT(mbuflabel);
1799101099Srwatson	s = SLOT(socketlabel);
1800101099Srwatson
1801101099Srwatson	return (mac_biba_equal_single(p, s) ? 0 : EACCES);
1802101099Srwatson}
1803101099Srwatson
1804101099Srwatsonstatic int
1805101099Srwatsonmac_biba_check_socket_relabel(struct ucred *cred, struct socket *socket,
1806101099Srwatson    struct label *socketlabel, struct label *newlabel)
1807101099Srwatson{
1808101099Srwatson	struct mac_biba *subj, *obj, *new;
1809105634Srwatson	int error;
1810101099Srwatson
1811101099Srwatson	new = SLOT(newlabel);
1812101099Srwatson	subj = SLOT(&cred->cr_label);
1813101099Srwatson	obj = SLOT(socketlabel);
1814101099Srwatson
1815101099Srwatson	/*
1816105634Srwatson	 * If there is a Biba label update for the socket, it may be
1817105634Srwatson	 * an update of single.
1818101099Srwatson	 */
1819105634Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE);
1820105634Srwatson	if (error)
1821105634Srwatson		return (error);
1822101099Srwatson
1823101099Srwatson	/*
1824105634Srwatson	 * To relabel a socket, the old socket single must be in the subject
1825101099Srwatson	 * range.
1826101099Srwatson	 */
1827105634Srwatson	if (!mac_biba_single_in_range(obj, subj))
1828101099Srwatson		return (EPERM);
1829101099Srwatson
1830101099Srwatson	/*
1831105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
1832101099Srwatson	 */
1833105634Srwatson	if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) {
1834105634Srwatson		/*
1835105634Srwatson		 * To relabel a socket, the new socket single must be in
1836105634Srwatson		 * the subject range.
1837105634Srwatson		 */
1838105634Srwatson		if (!mac_biba_single_in_range(new, subj))
1839105634Srwatson			return (EPERM);
1840101099Srwatson
1841105634Srwatson		/*
1842105634Srwatson		 * To change the Biba label on the socket to contain EQUAL,
1843105634Srwatson		 * the subject must have appropriate privilege.
1844105634Srwatson		 */
1845105634Srwatson		if (mac_biba_contains_equal(new)) {
1846106090Srwatson			error = mac_biba_subject_privileged(subj);
1847105634Srwatson			if (error)
1848105634Srwatson				return (error);
1849105634Srwatson		}
1850105634Srwatson	}
1851105634Srwatson
1852101099Srwatson	return (0);
1853101099Srwatson}
1854101099Srwatson
1855101099Srwatsonstatic int
1856101099Srwatsonmac_biba_check_socket_visible(struct ucred *cred, struct socket *socket,
1857101099Srwatson    struct label *socketlabel)
1858101099Srwatson{
1859101099Srwatson	struct mac_biba *subj, *obj;
1860101099Srwatson
1861105722Srwatson	if (!mac_biba_enabled)
1862105722Srwatson		return (0);
1863105722Srwatson
1864101099Srwatson	subj = SLOT(&cred->cr_label);
1865101099Srwatson	obj = SLOT(socketlabel);
1866101099Srwatson
1867101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1868101099Srwatson		return (ENOENT);
1869101099Srwatson
1870101099Srwatson	return (0);
1871101099Srwatson}
1872101099Srwatson
1873101099Srwatsonstatic int
1874106161Srwatsonmac_biba_check_system_swapon(struct ucred *cred, struct vnode *vp,
1875106161Srwatson    struct label *label)
1876106161Srwatson{
1877106161Srwatson	struct mac_biba *subj, *obj;
1878106161Srwatson
1879106161Srwatson	if (!mac_biba_enabled)
1880106161Srwatson		return (0);
1881106161Srwatson
1882106161Srwatson	subj = SLOT(&cred->cr_label);
1883106161Srwatson	obj = SLOT(label);
1884106161Srwatson
1885106161Srwatson	if (!mac_biba_subject_privileged(subj))
1886106161Srwatson		return (EPERM);
1887106161Srwatson
1888106161Srwatson	if (!mac_biba_high_single(obj))
1889106161Srwatson		return (EACCES);
1890106161Srwatson
1891106161Srwatson	return (0);
1892106161Srwatson}
1893106161Srwatson
1894106161Srwatsonstatic int
1895106161Srwatsonmac_biba_check_system_sysctl(struct ucred *cred, int *name, u_int namelen,
1896106161Srwatson    void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen)
1897106161Srwatson{
1898106161Srwatson	struct mac_biba *subj;
1899106161Srwatson	int error;
1900106161Srwatson
1901106161Srwatson	if (!mac_biba_enabled)
1902106161Srwatson		return (0);
1903106161Srwatson
1904106161Srwatson	subj = SLOT(&cred->cr_label);
1905106161Srwatson
1906106161Srwatson	/*
1907106161Srwatson	 * In general, treat sysctl variables as biba/high, but also
1908106161Srwatson	 * require privilege to change them, since they are a
1909106161Srwatson	 * communications channel between grades.  Exempt MIB
1910106161Srwatson	 * queries from this due to undocmented sysctl magic.
1911106161Srwatson	 * XXXMAC: This probably requires some more review.
1912106161Srwatson	 */
1913106161Srwatson	if (new != NULL) {
1914106161Srwatson		if (namelen > 0 && name[0] == 0)
1915106161Srwatson			return (0);
1916106161Srwatson
1917106161Srwatson		if (!mac_biba_subject_dominate_high(subj))
1918106161Srwatson			return (EACCES);
1919106161Srwatson
1920106161Srwatson		error = mac_biba_subject_privileged(subj);
1921106161Srwatson		if (error)
1922106161Srwatson			return (error);
1923106161Srwatson	}
1924106161Srwatson
1925106161Srwatson	return (0);
1926106161Srwatson}
1927106161Srwatson
1928106161Srwatsonstatic int
1929101099Srwatsonmac_biba_check_vnode_chdir(struct ucred *cred, struct vnode *dvp,
1930101099Srwatson    struct label *dlabel)
1931101099Srwatson{
1932101099Srwatson	struct mac_biba *subj, *obj;
1933101099Srwatson
1934101099Srwatson	if (!mac_biba_enabled)
1935101099Srwatson		return (0);
1936101099Srwatson
1937101099Srwatson	subj = SLOT(&cred->cr_label);
1938101099Srwatson	obj = SLOT(dlabel);
1939101099Srwatson
1940101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1941101099Srwatson		return (EACCES);
1942101099Srwatson
1943101099Srwatson	return (0);
1944101099Srwatson}
1945101099Srwatson
1946101099Srwatsonstatic int
1947101099Srwatsonmac_biba_check_vnode_chroot(struct ucred *cred, struct vnode *dvp,
1948101099Srwatson    struct label *dlabel)
1949101099Srwatson{
1950101099Srwatson	struct mac_biba *subj, *obj;
1951101099Srwatson
1952101099Srwatson	if (!mac_biba_enabled)
1953101099Srwatson		return (0);
1954101099Srwatson
1955101099Srwatson	subj = SLOT(&cred->cr_label);
1956101099Srwatson	obj = SLOT(dlabel);
1957101099Srwatson
1958101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1959101099Srwatson		return (EACCES);
1960101099Srwatson
1961101099Srwatson	return (0);
1962101099Srwatson}
1963101099Srwatson
1964101099Srwatsonstatic int
1965101099Srwatsonmac_biba_check_vnode_create(struct ucred *cred, struct vnode *dvp,
1966101099Srwatson    struct label *dlabel, struct componentname *cnp, struct vattr *vap)
1967101099Srwatson{
1968101099Srwatson	struct mac_biba *subj, *obj;
1969101099Srwatson
1970101099Srwatson	if (!mac_biba_enabled)
1971101099Srwatson		return (0);
1972101099Srwatson
1973101099Srwatson	subj = SLOT(&cred->cr_label);
1974101099Srwatson	obj = SLOT(dlabel);
1975101099Srwatson
1976101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1977101099Srwatson		return (EACCES);
1978101099Srwatson
1979101099Srwatson	return (0);
1980101099Srwatson}
1981101099Srwatson
1982101099Srwatsonstatic int
1983101099Srwatsonmac_biba_check_vnode_delete(struct ucred *cred, struct vnode *dvp,
1984101099Srwatson    struct label *dlabel, struct vnode *vp, struct label *label,
1985101099Srwatson    struct componentname *cnp)
1986101099Srwatson{
1987101099Srwatson	struct mac_biba *subj, *obj;
1988101099Srwatson
1989101099Srwatson	if (!mac_biba_enabled)
1990101099Srwatson		return (0);
1991101099Srwatson
1992101099Srwatson	subj = SLOT(&cred->cr_label);
1993101099Srwatson	obj = SLOT(dlabel);
1994101099Srwatson
1995101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1996101099Srwatson		return (EACCES);
1997101099Srwatson
1998101099Srwatson	obj = SLOT(label);
1999101099Srwatson
2000101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2001101099Srwatson		return (EACCES);
2002101099Srwatson
2003101099Srwatson	return (0);
2004101099Srwatson}
2005101099Srwatson
2006101099Srwatsonstatic int
2007101099Srwatsonmac_biba_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
2008101099Srwatson    struct label *label, acl_type_t type)
2009101099Srwatson{
2010101099Srwatson	struct mac_biba *subj, *obj;
2011101099Srwatson
2012101099Srwatson	if (!mac_biba_enabled)
2013101099Srwatson		return (0);
2014101099Srwatson
2015101099Srwatson	subj = SLOT(&cred->cr_label);
2016101099Srwatson	obj = SLOT(label);
2017101099Srwatson
2018101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2019101099Srwatson		return (EACCES);
2020101099Srwatson
2021101099Srwatson	return (0);
2022101099Srwatson}
2023101099Srwatson
2024101099Srwatsonstatic int
2025101099Srwatsonmac_biba_check_vnode_exec(struct ucred *cred, struct vnode *vp,
2026101099Srwatson    struct label *label)
2027101099Srwatson{
2028101099Srwatson	struct mac_biba *subj, *obj;
2029101099Srwatson
2030101099Srwatson	if (!mac_biba_enabled)
2031101099Srwatson		return (0);
2032101099Srwatson
2033101099Srwatson	subj = SLOT(&cred->cr_label);
2034101099Srwatson	obj = SLOT(label);
2035101099Srwatson
2036101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
2037101099Srwatson		return (EACCES);
2038101099Srwatson
2039101099Srwatson	return (0);
2040101099Srwatson}
2041101099Srwatson
2042101099Srwatsonstatic int
2043101099Srwatsonmac_biba_check_vnode_getacl(struct ucred *cred, struct vnode *vp,
2044101099Srwatson    struct label *label, acl_type_t type)
2045101099Srwatson{
2046101099Srwatson	struct mac_biba *subj, *obj;
2047101099Srwatson
2048101099Srwatson	if (!mac_biba_enabled)
2049101099Srwatson		return (0);
2050101099Srwatson
2051101099Srwatson	subj = SLOT(&cred->cr_label);
2052101099Srwatson	obj = SLOT(label);
2053101099Srwatson
2054101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
2055101099Srwatson		return (EACCES);
2056101099Srwatson
2057101099Srwatson	return (0);
2058101099Srwatson}
2059101099Srwatson
2060101099Srwatsonstatic int
2061101099Srwatsonmac_biba_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
2062101099Srwatson    struct label *label, int attrnamespace, const char *name, struct uio *uio)
2063101099Srwatson{
2064101099Srwatson	struct mac_biba *subj, *obj;
2065101099Srwatson
2066101099Srwatson	if (!mac_biba_enabled)
2067101099Srwatson		return (0);
2068101099Srwatson
2069101099Srwatson	subj = SLOT(&cred->cr_label);
2070101099Srwatson	obj = SLOT(label);
2071101099Srwatson
2072101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
2073101099Srwatson		return (EACCES);
2074101099Srwatson
2075101099Srwatson	return (0);
2076101099Srwatson}
2077101099Srwatson
2078101099Srwatsonstatic int
2079104530Srwatsonmac_biba_check_vnode_link(struct ucred *cred, struct vnode *dvp,
2080104530Srwatson    struct label *dlabel, struct vnode *vp, struct label *label,
2081104530Srwatson    struct componentname *cnp)
2082104530Srwatson{
2083104530Srwatson	struct mac_biba *subj, *obj;
2084104530Srwatson
2085104530Srwatson	if (!mac_biba_enabled)
2086104530Srwatson		return (0);
2087104530Srwatson
2088104530Srwatson	subj = SLOT(&cred->cr_label);
2089104530Srwatson	obj = SLOT(dlabel);
2090104530Srwatson
2091104530Srwatson	if (!mac_biba_dominate_single(subj, obj))
2092104530Srwatson		return (EACCES);
2093104530Srwatson
2094104530Srwatson	obj = SLOT(label);
2095104530Srwatson
2096104530Srwatson	if (!mac_biba_dominate_single(subj, obj))
2097104530Srwatson		return (EACCES);
2098104530Srwatson
2099104530Srwatson	return (0);
2100104530Srwatson}
2101104530Srwatson
2102104530Srwatsonstatic int
2103103759Srwatsonmac_biba_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
2104101099Srwatson    struct label *dlabel, struct componentname *cnp)
2105101099Srwatson{
2106101099Srwatson	struct mac_biba *subj, *obj;
2107103759Srwatson
2108101099Srwatson	if (!mac_biba_enabled)
2109101099Srwatson		return (0);
2110103759Srwatson
2111101099Srwatson	subj = SLOT(&cred->cr_label);
2112101099Srwatson	obj = SLOT(dlabel);
2113103759Srwatson
2114101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
2115101099Srwatson		return (EACCES);
2116101099Srwatson
2117103759Srwatson	return (0);
2118101099Srwatson}
2119101099Srwatson
2120101099Srwatsonstatic int
2121104546Srwatsonmac_biba_check_vnode_mmap(struct ucred *cred, struct vnode *vp,
2122104546Srwatson    struct label *label, int prot)
2123104546Srwatson{
2124104546Srwatson	struct mac_biba *subj, *obj;
2125104546Srwatson
2126104546Srwatson	/*
2127104546Srwatson	 * Rely on the use of open()-time protections to handle
2128104546Srwatson	 * non-revocation cases.
2129104546Srwatson	 */
2130105637Srwatson	if (!mac_biba_enabled || !revocation_enabled)
2131104546Srwatson		return (0);
2132104546Srwatson
2133104546Srwatson	subj = SLOT(&cred->cr_label);
2134104546Srwatson	obj = SLOT(label);
2135104546Srwatson
2136104546Srwatson	if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
2137104546Srwatson		if (!mac_biba_dominate_single(obj, subj))
2138104546Srwatson			return (EACCES);
2139104546Srwatson	}
2140104546Srwatson	if (prot & VM_PROT_WRITE) {
2141104546Srwatson		if (!mac_biba_dominate_single(subj, obj))
2142104546Srwatson			return (EACCES);
2143104546Srwatson	}
2144104546Srwatson
2145104569Srwatson	return (0);
2146104546Srwatson}
2147104546Srwatson
2148104546Srwatsonstatic int
2149101099Srwatsonmac_biba_check_vnode_open(struct ucred *cred, struct vnode *vp,
2150106212Srwatson    struct label *vnodelabel, int acc_mode)
2151101099Srwatson{
2152101099Srwatson	struct mac_biba *subj, *obj;
2153101099Srwatson
2154101099Srwatson	if (!mac_biba_enabled)
2155101099Srwatson		return (0);
2156101099Srwatson
2157101099Srwatson	subj = SLOT(&cred->cr_label);
2158101099Srwatson	obj = SLOT(vnodelabel);
2159101099Srwatson
2160101099Srwatson	/* XXX privilege override for admin? */
2161101099Srwatson	if (acc_mode & (VREAD | VEXEC | VSTAT)) {
2162101099Srwatson		if (!mac_biba_dominate_single(obj, subj))
2163101099Srwatson			return (EACCES);
2164101099Srwatson	}
2165101099Srwatson	if (acc_mode & (VWRITE | VAPPEND | VADMIN)) {
2166101099Srwatson		if (!mac_biba_dominate_single(subj, obj))
2167101099Srwatson			return (EACCES);
2168101099Srwatson	}
2169101099Srwatson
2170101099Srwatson	return (0);
2171101099Srwatson}
2172101099Srwatson
2173101099Srwatsonstatic int
2174102129Srwatsonmac_biba_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred,
2175102129Srwatson    struct vnode *vp, struct label *label)
2176102112Srwatson{
2177102112Srwatson	struct mac_biba *subj, *obj;
2178102112Srwatson
2179105637Srwatson	if (!mac_biba_enabled || !revocation_enabled)
2180102112Srwatson		return (0);
2181102112Srwatson
2182102129Srwatson	subj = SLOT(&active_cred->cr_label);
2183102112Srwatson	obj = SLOT(label);
2184102112Srwatson
2185102112Srwatson	if (!mac_biba_dominate_single(obj, subj))
2186102112Srwatson		return (EACCES);
2187102112Srwatson
2188102112Srwatson	return (0);
2189102112Srwatson}
2190102112Srwatson
2191102112Srwatsonstatic int
2192102129Srwatsonmac_biba_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
2193102129Srwatson    struct vnode *vp, struct label *label)
2194102112Srwatson{
2195102112Srwatson	struct mac_biba *subj, *obj;
2196102112Srwatson
2197105637Srwatson	if (!mac_biba_enabled || !revocation_enabled)
2198102112Srwatson		return (0);
2199102112Srwatson
2200102129Srwatson	subj = SLOT(&active_cred->cr_label);
2201102112Srwatson	obj = SLOT(label);
2202102112Srwatson
2203102112Srwatson	if (!mac_biba_dominate_single(obj, subj))
2204102112Srwatson		return (EACCES);
2205102112Srwatson
2206102112Srwatson	return (0);
2207102112Srwatson}
2208102112Srwatson
2209102112Srwatsonstatic int
2210101099Srwatsonmac_biba_check_vnode_readdir(struct ucred *cred, struct vnode *dvp,
2211101099Srwatson    struct label *dlabel)
2212101099Srwatson{
2213101099Srwatson	struct mac_biba *subj, *obj;
2214101099Srwatson
2215101099Srwatson	if (!mac_biba_enabled)
2216101099Srwatson		return (0);
2217101099Srwatson
2218101099Srwatson	subj = SLOT(&cred->cr_label);
2219101099Srwatson	obj = SLOT(dlabel);
2220101099Srwatson
2221101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
2222101099Srwatson		return (EACCES);
2223101099Srwatson
2224101099Srwatson	return (0);
2225101099Srwatson}
2226101099Srwatson
2227101099Srwatsonstatic int
2228101099Srwatsonmac_biba_check_vnode_readlink(struct ucred *cred, struct vnode *vp,
2229101099Srwatson    struct label *label)
2230101099Srwatson{
2231101099Srwatson	struct mac_biba *subj, *obj;
2232101099Srwatson
2233101099Srwatson	if (!mac_biba_enabled)
2234101099Srwatson		return (0);
2235101099Srwatson
2236101099Srwatson	subj = SLOT(&cred->cr_label);
2237101099Srwatson	obj = SLOT(label);
2238101099Srwatson
2239101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
2240101099Srwatson		return (EACCES);
2241101099Srwatson
2242101099Srwatson	return (0);
2243101099Srwatson}
2244101099Srwatson
2245101099Srwatsonstatic int
2246101099Srwatsonmac_biba_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
2247101099Srwatson    struct label *vnodelabel, struct label *newlabel)
2248101099Srwatson{
2249101099Srwatson	struct mac_biba *old, *new, *subj;
2250105634Srwatson	int error;
2251101099Srwatson
2252101099Srwatson	old = SLOT(vnodelabel);
2253101099Srwatson	new = SLOT(newlabel);
2254101099Srwatson	subj = SLOT(&cred->cr_label);
2255101099Srwatson
2256101099Srwatson	/*
2257105634Srwatson	 * If there is a Biba label update for the vnode, it must be a
2258105634Srwatson	 * single label.
2259101099Srwatson	 */
2260105634Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE);
2261105634Srwatson	if (error)
2262105634Srwatson		return (error);
2263101099Srwatson
2264101099Srwatson	/*
2265105634Srwatson	 * To perform a relabel of the vnode (Biba label or not), Biba must
2266105634Srwatson	 * authorize the relabel.
2267101099Srwatson	 */
2268105634Srwatson	if (!mac_biba_single_in_range(old, subj))
2269101099Srwatson		return (EPERM);
2270101099Srwatson
2271101099Srwatson	/*
2272105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
2273101099Srwatson	 */
2274105634Srwatson	if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) {
2275105634Srwatson		/*
2276105634Srwatson		 * To change the Biba label on a vnode, the new vnode label
2277105634Srwatson		 * must be in the subject range.
2278105634Srwatson		 */
2279105634Srwatson		if (!mac_biba_single_in_range(new, subj))
2280105634Srwatson			return (EPERM);
2281101099Srwatson
2282105634Srwatson		/*
2283105634Srwatson		 * To change the Biba label on the vnode to be EQUAL,
2284105634Srwatson		 * the subject must have appropriate privilege.
2285105634Srwatson		 */
2286105634Srwatson		if (mac_biba_contains_equal(new)) {
2287106090Srwatson			error = mac_biba_subject_privileged(subj);
2288105634Srwatson			if (error)
2289105634Srwatson				return (error);
2290105634Srwatson		}
2291105634Srwatson	}
2292105634Srwatson
2293105634Srwatson	return (0);
2294101099Srwatson}
2295101099Srwatson
2296101099Srwatsonstatic int
2297101099Srwatsonmac_biba_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
2298101099Srwatson    struct label *dlabel, struct vnode *vp, struct label *label,
2299101099Srwatson    struct componentname *cnp)
2300101099Srwatson{
2301101099Srwatson	struct mac_biba *subj, *obj;
2302101099Srwatson
2303101099Srwatson	if (!mac_biba_enabled)
2304101099Srwatson		return (0);
2305101099Srwatson
2306101099Srwatson	subj = SLOT(&cred->cr_label);
2307101099Srwatson	obj = SLOT(dlabel);
2308101099Srwatson
2309101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2310101099Srwatson		return (EACCES);
2311101099Srwatson
2312101099Srwatson	obj = SLOT(label);
2313101099Srwatson
2314101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2315101099Srwatson		return (EACCES);
2316101099Srwatson
2317101099Srwatson	return (0);
2318101099Srwatson}
2319101099Srwatson
2320101099Srwatsonstatic int
2321101099Srwatsonmac_biba_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
2322101099Srwatson    struct label *dlabel, struct vnode *vp, struct label *label, int samedir,
2323101099Srwatson    struct componentname *cnp)
2324101099Srwatson{
2325101099Srwatson	struct mac_biba *subj, *obj;
2326101099Srwatson
2327101099Srwatson	if (!mac_biba_enabled)
2328101099Srwatson		return (0);
2329101099Srwatson
2330101099Srwatson	subj = SLOT(&cred->cr_label);
2331101099Srwatson	obj = SLOT(dlabel);
2332101099Srwatson
2333101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2334101099Srwatson		return (EACCES);
2335101099Srwatson
2336101099Srwatson	if (vp != NULL) {
2337101099Srwatson		obj = SLOT(label);
2338101099Srwatson
2339101099Srwatson		if (!mac_biba_dominate_single(subj, obj))
2340101099Srwatson			return (EACCES);
2341101099Srwatson	}
2342101099Srwatson
2343101099Srwatson	return (0);
2344101099Srwatson}
2345101099Srwatson
2346101099Srwatsonstatic int
2347101099Srwatsonmac_biba_check_vnode_revoke(struct ucred *cred, struct vnode *vp,
2348101099Srwatson    struct label *label)
2349101099Srwatson{
2350101099Srwatson	struct mac_biba *subj, *obj;
2351101099Srwatson
2352101099Srwatson	if (!mac_biba_enabled)
2353101099Srwatson		return (0);
2354101099Srwatson
2355101099Srwatson	subj = SLOT(&cred->cr_label);
2356101099Srwatson	obj = SLOT(label);
2357101099Srwatson
2358101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2359101099Srwatson		return (EACCES);
2360101099Srwatson
2361101099Srwatson	return (0);
2362101099Srwatson}
2363101099Srwatson
2364101099Srwatsonstatic int
2365101099Srwatsonmac_biba_check_vnode_setacl(struct ucred *cred, struct vnode *vp,
2366101099Srwatson    struct label *label, acl_type_t type, struct acl *acl)
2367101099Srwatson{
2368101099Srwatson	struct mac_biba *subj, *obj;
2369101099Srwatson
2370101099Srwatson	if (!mac_biba_enabled)
2371101099Srwatson		return (0);
2372101099Srwatson
2373101099Srwatson	subj = SLOT(&cred->cr_label);
2374101099Srwatson	obj = SLOT(label);
2375101099Srwatson
2376101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2377101099Srwatson		return (EACCES);
2378101099Srwatson
2379101099Srwatson	return (0);
2380101099Srwatson}
2381101099Srwatson
2382101099Srwatsonstatic int
2383101099Srwatsonmac_biba_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
2384101099Srwatson    struct label *vnodelabel, int attrnamespace, const char *name,
2385101099Srwatson    struct uio *uio)
2386101099Srwatson{
2387101099Srwatson	struct mac_biba *subj, *obj;
2388101099Srwatson
2389101099Srwatson	if (!mac_biba_enabled)
2390101099Srwatson		return (0);
2391101099Srwatson
2392101099Srwatson	subj = SLOT(&cred->cr_label);
2393101099Srwatson	obj = SLOT(vnodelabel);
2394101099Srwatson
2395101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2396101099Srwatson		return (EACCES);
2397101099Srwatson
2398101099Srwatson	/* XXX: protect the MAC EA in a special way? */
2399101099Srwatson
2400101099Srwatson	return (0);
2401101099Srwatson}
2402101099Srwatson
2403101099Srwatsonstatic int
2404101099Srwatsonmac_biba_check_vnode_setflags(struct ucred *cred, struct vnode *vp,
2405101099Srwatson    struct label *vnodelabel, u_long flags)
2406101099Srwatson{
2407101099Srwatson	struct mac_biba *subj, *obj;
2408101099Srwatson
2409101099Srwatson	if (!mac_biba_enabled)
2410101099Srwatson		return (0);
2411101099Srwatson
2412101099Srwatson	subj = SLOT(&cred->cr_label);
2413101099Srwatson	obj = SLOT(vnodelabel);
2414101099Srwatson
2415101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2416101099Srwatson		return (EACCES);
2417101099Srwatson
2418101099Srwatson	return (0);
2419101099Srwatson}
2420101099Srwatson
2421101099Srwatsonstatic int
2422101099Srwatsonmac_biba_check_vnode_setmode(struct ucred *cred, struct vnode *vp,
2423101099Srwatson    struct label *vnodelabel, mode_t mode)
2424101099Srwatson{
2425101099Srwatson	struct mac_biba *subj, *obj;
2426101099Srwatson
2427101099Srwatson	if (!mac_biba_enabled)
2428101099Srwatson		return (0);
2429101099Srwatson
2430101099Srwatson	subj = SLOT(&cred->cr_label);
2431101099Srwatson	obj = SLOT(vnodelabel);
2432101099Srwatson
2433101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2434101099Srwatson		return (EACCES);
2435101099Srwatson
2436101099Srwatson	return (0);
2437101099Srwatson}
2438101099Srwatson
2439101099Srwatsonstatic int
2440101099Srwatsonmac_biba_check_vnode_setowner(struct ucred *cred, struct vnode *vp,
2441101099Srwatson    struct label *vnodelabel, uid_t uid, gid_t gid)
2442101099Srwatson{
2443101099Srwatson	struct mac_biba *subj, *obj;
2444101099Srwatson
2445101099Srwatson	if (!mac_biba_enabled)
2446101099Srwatson		return (0);
2447101099Srwatson
2448101099Srwatson	subj = SLOT(&cred->cr_label);
2449101099Srwatson	obj = SLOT(vnodelabel);
2450101099Srwatson
2451101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2452101099Srwatson		return (EACCES);
2453101099Srwatson
2454101099Srwatson	return (0);
2455101099Srwatson}
2456101099Srwatson
2457101099Srwatsonstatic int
2458101099Srwatsonmac_biba_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
2459101099Srwatson    struct label *vnodelabel, struct timespec atime, struct timespec mtime)
2460101099Srwatson{
2461101099Srwatson	struct mac_biba *subj, *obj;
2462101099Srwatson
2463101099Srwatson	if (!mac_biba_enabled)
2464101099Srwatson		return (0);
2465101099Srwatson
2466101099Srwatson	subj = SLOT(&cred->cr_label);
2467101099Srwatson	obj = SLOT(vnodelabel);
2468101099Srwatson
2469101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2470101099Srwatson		return (EACCES);
2471101099Srwatson
2472101099Srwatson	return (0);
2473101099Srwatson}
2474101099Srwatson
2475101099Srwatsonstatic int
2476102129Srwatsonmac_biba_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
2477102129Srwatson    struct vnode *vp, struct label *vnodelabel)
2478101099Srwatson{
2479101099Srwatson	struct mac_biba *subj, *obj;
2480101099Srwatson
2481101099Srwatson	if (!mac_biba_enabled)
2482101099Srwatson		return (0);
2483101099Srwatson
2484102129Srwatson	subj = SLOT(&active_cred->cr_label);
2485101099Srwatson	obj = SLOT(vnodelabel);
2486101099Srwatson
2487101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
2488101099Srwatson		return (EACCES);
2489101099Srwatson
2490101099Srwatson	return (0);
2491101099Srwatson}
2492101099Srwatson
2493102112Srwatsonstatic int
2494102129Srwatsonmac_biba_check_vnode_write(struct ucred *active_cred,
2495102129Srwatson    struct ucred *file_cred, struct vnode *vp, struct label *label)
2496102112Srwatson{
2497102112Srwatson	struct mac_biba *subj, *obj;
2498102112Srwatson
2499105637Srwatson	if (!mac_biba_enabled || !revocation_enabled)
2500102112Srwatson		return (0);
2501102112Srwatson
2502102129Srwatson	subj = SLOT(&active_cred->cr_label);
2503102112Srwatson	obj = SLOT(label);
2504102112Srwatson
2505102112Srwatson	if (!mac_biba_dominate_single(subj, obj))
2506102112Srwatson		return (EACCES);
2507102112Srwatson
2508102112Srwatson	return (0);
2509102112Srwatson}
2510102112Srwatson
2511101099Srwatsonstatic struct mac_policy_op_entry mac_biba_ops[] =
2512101099Srwatson{
2513101099Srwatson	{ MAC_DESTROY,
2514101099Srwatson	    (macop_t)mac_biba_destroy },
2515101099Srwatson	{ MAC_INIT,
2516101099Srwatson	    (macop_t)mac_biba_init },
2517104514Srwatson	{ MAC_INIT_BPFDESC_LABEL,
2518104514Srwatson	    (macop_t)mac_biba_init_label },
2519104514Srwatson	{ MAC_INIT_CRED_LABEL,
2520104514Srwatson	    (macop_t)mac_biba_init_label },
2521104514Srwatson	{ MAC_INIT_DEVFSDIRENT_LABEL,
2522104514Srwatson	    (macop_t)mac_biba_init_label },
2523104514Srwatson	{ MAC_INIT_IFNET_LABEL,
2524104514Srwatson	    (macop_t)mac_biba_init_label },
2525104514Srwatson	{ MAC_INIT_IPQ_LABEL,
2526104514Srwatson	    (macop_t)mac_biba_init_label },
2527104514Srwatson	{ MAC_INIT_MBUF_LABEL,
2528104514Srwatson	    (macop_t)mac_biba_init_label_waitcheck },
2529104514Srwatson	{ MAC_INIT_MOUNT_LABEL,
2530104514Srwatson	    (macop_t)mac_biba_init_label },
2531104514Srwatson	{ MAC_INIT_MOUNT_FS_LABEL,
2532104514Srwatson	    (macop_t)mac_biba_init_label },
2533104514Srwatson	{ MAC_INIT_PIPE_LABEL,
2534104514Srwatson	    (macop_t)mac_biba_init_label },
2535104514Srwatson	{ MAC_INIT_SOCKET_LABEL,
2536104541Srwatson	    (macop_t)mac_biba_init_label_waitcheck },
2537104514Srwatson	{ MAC_INIT_SOCKET_PEER_LABEL,
2538104541Srwatson	    (macop_t)mac_biba_init_label_waitcheck },
2539104514Srwatson	{ MAC_INIT_VNODE_LABEL,
2540104514Srwatson	    (macop_t)mac_biba_init_label },
2541104514Srwatson	{ MAC_DESTROY_BPFDESC_LABEL,
2542104514Srwatson	    (macop_t)mac_biba_destroy_label },
2543104514Srwatson	{ MAC_DESTROY_CRED_LABEL,
2544104514Srwatson	    (macop_t)mac_biba_destroy_label },
2545104514Srwatson	{ MAC_DESTROY_DEVFSDIRENT_LABEL,
2546104514Srwatson	    (macop_t)mac_biba_destroy_label },
2547104514Srwatson	{ MAC_DESTROY_IFNET_LABEL,
2548104514Srwatson	    (macop_t)mac_biba_destroy_label },
2549104514Srwatson	{ MAC_DESTROY_IPQ_LABEL,
2550104514Srwatson	    (macop_t)mac_biba_destroy_label },
2551104514Srwatson	{ MAC_DESTROY_MBUF_LABEL,
2552104514Srwatson	    (macop_t)mac_biba_destroy_label },
2553104514Srwatson	{ MAC_DESTROY_MOUNT_LABEL,
2554104514Srwatson	    (macop_t)mac_biba_destroy_label },
2555104514Srwatson	{ MAC_DESTROY_MOUNT_FS_LABEL,
2556104514Srwatson	    (macop_t)mac_biba_destroy_label },
2557104514Srwatson	{ MAC_DESTROY_PIPE_LABEL,
2558104514Srwatson	    (macop_t)mac_biba_destroy_label },
2559104514Srwatson	{ MAC_DESTROY_SOCKET_LABEL,
2560104514Srwatson	    (macop_t)mac_biba_destroy_label },
2561104514Srwatson	{ MAC_DESTROY_SOCKET_PEER_LABEL,
2562104514Srwatson	    (macop_t)mac_biba_destroy_label },
2563104514Srwatson	{ MAC_DESTROY_VNODE_LABEL,
2564104514Srwatson	    (macop_t)mac_biba_destroy_label },
2565105696Srwatson	{ MAC_COPY_PIPE_LABEL,
2566105696Srwatson	    (macop_t)mac_biba_copy_label },
2567105696Srwatson	{ MAC_COPY_VNODE_LABEL,
2568105696Srwatson	    (macop_t)mac_biba_copy_label },
2569105696Srwatson	{ MAC_EXTERNALIZE_CRED_LABEL,
2570105696Srwatson	    (macop_t)mac_biba_externalize_label },
2571105696Srwatson	{ MAC_EXTERNALIZE_IFNET_LABEL,
2572105696Srwatson	    (macop_t)mac_biba_externalize_label },
2573105696Srwatson	{ MAC_EXTERNALIZE_PIPE_LABEL,
2574105696Srwatson	    (macop_t)mac_biba_externalize_label },
2575105696Srwatson	{ MAC_EXTERNALIZE_SOCKET_LABEL,
2576105696Srwatson	    (macop_t)mac_biba_externalize_label },
2577105696Srwatson	{ MAC_EXTERNALIZE_SOCKET_PEER_LABEL,
2578105696Srwatson	    (macop_t)mac_biba_externalize_label },
2579105696Srwatson	{ MAC_EXTERNALIZE_VNODE_LABEL,
2580105696Srwatson	    (macop_t)mac_biba_externalize_label },
2581105696Srwatson	{ MAC_INTERNALIZE_CRED_LABEL,
2582105696Srwatson	    (macop_t)mac_biba_internalize_label },
2583105696Srwatson	{ MAC_INTERNALIZE_IFNET_LABEL,
2584105696Srwatson	    (macop_t)mac_biba_internalize_label },
2585105696Srwatson	{ MAC_INTERNALIZE_PIPE_LABEL,
2586105696Srwatson	    (macop_t)mac_biba_internalize_label },
2587105696Srwatson	{ MAC_INTERNALIZE_SOCKET_LABEL,
2588105696Srwatson	    (macop_t)mac_biba_internalize_label },
2589105696Srwatson	{ MAC_INTERNALIZE_VNODE_LABEL,
2590105696Srwatson	    (macop_t)mac_biba_internalize_label },
2591101099Srwatson	{ MAC_CREATE_DEVFS_DEVICE,
2592101099Srwatson	    (macop_t)mac_biba_create_devfs_device },
2593101099Srwatson	{ MAC_CREATE_DEVFS_DIRECTORY,
2594101099Srwatson	    (macop_t)mac_biba_create_devfs_directory },
2595104535Srwatson	{ MAC_CREATE_DEVFS_SYMLINK,
2596104535Srwatson	    (macop_t)mac_biba_create_devfs_symlink },
2597101099Srwatson	{ MAC_CREATE_DEVFS_VNODE,
2598101099Srwatson	    (macop_t)mac_biba_create_devfs_vnode },
2599101099Srwatson	{ MAC_CREATE_MOUNT,
2600101099Srwatson	    (macop_t)mac_biba_create_mount },
2601101099Srwatson	{ MAC_CREATE_ROOT_MOUNT,
2602101099Srwatson	    (macop_t)mac_biba_create_root_mount },
2603101099Srwatson	{ MAC_RELABEL_VNODE,
2604101099Srwatson	    (macop_t)mac_biba_relabel_vnode },
2605101099Srwatson	{ MAC_UPDATE_DEVFSDIRENT,
2606101099Srwatson	    (macop_t)mac_biba_update_devfsdirent },
2607105988Srwatson	{ MAC_ASSOCIATE_VNODE_DEVFS,
2608105988Srwatson	    (macop_t)mac_biba_associate_vnode_devfs },
2609105988Srwatson	{ MAC_ASSOCIATE_VNODE_EXTATTR,
2610105988Srwatson	    (macop_t)mac_biba_associate_vnode_extattr },
2611105988Srwatson	{ MAC_ASSOCIATE_VNODE_SINGLELABEL,
2612105988Srwatson	    (macop_t)mac_biba_associate_vnode_singlelabel },
2613105988Srwatson	{ MAC_CREATE_VNODE_EXTATTR,
2614105988Srwatson	    (macop_t)mac_biba_create_vnode_extattr },
2615105988Srwatson	{ MAC_SETLABEL_VNODE_EXTATTR,
2616105988Srwatson	    (macop_t)mac_biba_setlabel_vnode_extattr },
2617101099Srwatson	{ MAC_CREATE_MBUF_FROM_SOCKET,
2618101099Srwatson	    (macop_t)mac_biba_create_mbuf_from_socket },
2619101099Srwatson	{ MAC_CREATE_PIPE,
2620101099Srwatson	    (macop_t)mac_biba_create_pipe },
2621101099Srwatson	{ MAC_CREATE_SOCKET,
2622101099Srwatson	    (macop_t)mac_biba_create_socket },
2623101099Srwatson	{ MAC_CREATE_SOCKET_FROM_SOCKET,
2624101099Srwatson	    (macop_t)mac_biba_create_socket_from_socket },
2625101099Srwatson	{ MAC_RELABEL_PIPE,
2626101099Srwatson	    (macop_t)mac_biba_relabel_pipe },
2627101099Srwatson	{ MAC_RELABEL_SOCKET,
2628101099Srwatson	    (macop_t)mac_biba_relabel_socket },
2629101099Srwatson	{ MAC_SET_SOCKET_PEER_FROM_MBUF,
2630101099Srwatson	    (macop_t)mac_biba_set_socket_peer_from_mbuf },
2631101099Srwatson	{ MAC_SET_SOCKET_PEER_FROM_SOCKET,
2632101099Srwatson	    (macop_t)mac_biba_set_socket_peer_from_socket },
2633101099Srwatson	{ MAC_CREATE_BPFDESC,
2634101099Srwatson	    (macop_t)mac_biba_create_bpfdesc },
2635101099Srwatson	{ MAC_CREATE_DATAGRAM_FROM_IPQ,
2636101099Srwatson	    (macop_t)mac_biba_create_datagram_from_ipq },
2637101099Srwatson	{ MAC_CREATE_FRAGMENT,
2638101099Srwatson	    (macop_t)mac_biba_create_fragment },
2639101099Srwatson	{ MAC_CREATE_IFNET,
2640101099Srwatson	    (macop_t)mac_biba_create_ifnet },
2641101099Srwatson	{ MAC_CREATE_IPQ,
2642101099Srwatson	    (macop_t)mac_biba_create_ipq },
2643101099Srwatson	{ MAC_CREATE_MBUF_FROM_MBUF,
2644101099Srwatson	    (macop_t)mac_biba_create_mbuf_from_mbuf },
2645101099Srwatson	{ MAC_CREATE_MBUF_LINKLAYER,
2646101099Srwatson	    (macop_t)mac_biba_create_mbuf_linklayer },
2647101099Srwatson	{ MAC_CREATE_MBUF_FROM_BPFDESC,
2648101099Srwatson	    (macop_t)mac_biba_create_mbuf_from_bpfdesc },
2649101099Srwatson	{ MAC_CREATE_MBUF_FROM_IFNET,
2650101099Srwatson	    (macop_t)mac_biba_create_mbuf_from_ifnet },
2651101099Srwatson	{ MAC_CREATE_MBUF_MULTICAST_ENCAP,
2652101099Srwatson	    (macop_t)mac_biba_create_mbuf_multicast_encap },
2653101099Srwatson	{ MAC_CREATE_MBUF_NETLAYER,
2654101099Srwatson	    (macop_t)mac_biba_create_mbuf_netlayer },
2655101099Srwatson	{ MAC_FRAGMENT_MATCH,
2656101099Srwatson	    (macop_t)mac_biba_fragment_match },
2657101099Srwatson	{ MAC_RELABEL_IFNET,
2658101099Srwatson	    (macop_t)mac_biba_relabel_ifnet },
2659101099Srwatson	{ MAC_UPDATE_IPQ,
2660101099Srwatson	    (macop_t)mac_biba_update_ipq },
2661101099Srwatson	{ MAC_CREATE_CRED,
2662101099Srwatson	    (macop_t)mac_biba_create_cred },
2663101099Srwatson	{ MAC_EXECVE_TRANSITION,
2664101099Srwatson	    (macop_t)mac_biba_execve_transition },
2665101099Srwatson	{ MAC_EXECVE_WILL_TRANSITION,
2666101099Srwatson	    (macop_t)mac_biba_execve_will_transition },
2667101099Srwatson	{ MAC_CREATE_PROC0,
2668101099Srwatson	    (macop_t)mac_biba_create_proc0 },
2669101099Srwatson	{ MAC_CREATE_PROC1,
2670101099Srwatson	    (macop_t)mac_biba_create_proc1 },
2671101099Srwatson	{ MAC_RELABEL_CRED,
2672101099Srwatson	    (macop_t)mac_biba_relabel_cred },
2673101099Srwatson	{ MAC_CHECK_BPFDESC_RECEIVE,
2674101099Srwatson	    (macop_t)mac_biba_check_bpfdesc_receive },
2675101099Srwatson	{ MAC_CHECK_CRED_RELABEL,
2676101099Srwatson	    (macop_t)mac_biba_check_cred_relabel },
2677101099Srwatson	{ MAC_CHECK_CRED_VISIBLE,
2678101099Srwatson	    (macop_t)mac_biba_check_cred_visible },
2679101099Srwatson	{ MAC_CHECK_IFNET_RELABEL,
2680101099Srwatson	    (macop_t)mac_biba_check_ifnet_relabel },
2681101099Srwatson	{ MAC_CHECK_IFNET_TRANSMIT,
2682101099Srwatson	    (macop_t)mac_biba_check_ifnet_transmit },
2683101099Srwatson	{ MAC_CHECK_MOUNT_STAT,
2684101099Srwatson	    (macop_t)mac_biba_check_mount_stat },
2685101099Srwatson	{ MAC_CHECK_PIPE_IOCTL,
2686101099Srwatson	    (macop_t)mac_biba_check_pipe_ioctl },
2687102115Srwatson	{ MAC_CHECK_PIPE_POLL,
2688102115Srwatson	    (macop_t)mac_biba_check_pipe_poll },
2689102115Srwatson	{ MAC_CHECK_PIPE_READ,
2690102115Srwatson	    (macop_t)mac_biba_check_pipe_read },
2691101099Srwatson	{ MAC_CHECK_PIPE_RELABEL,
2692101099Srwatson	    (macop_t)mac_biba_check_pipe_relabel },
2693102115Srwatson	{ MAC_CHECK_PIPE_STAT,
2694102115Srwatson	    (macop_t)mac_biba_check_pipe_stat },
2695102115Srwatson	{ MAC_CHECK_PIPE_WRITE,
2696102115Srwatson	    (macop_t)mac_biba_check_pipe_write },
2697101099Srwatson	{ MAC_CHECK_PROC_DEBUG,
2698101099Srwatson	    (macop_t)mac_biba_check_proc_debug },
2699101099Srwatson	{ MAC_CHECK_PROC_SCHED,
2700101099Srwatson	    (macop_t)mac_biba_check_proc_sched },
2701101099Srwatson	{ MAC_CHECK_PROC_SIGNAL,
2702101099Srwatson	    (macop_t)mac_biba_check_proc_signal },
2703101934Srwatson	{ MAC_CHECK_SOCKET_DELIVER,
2704101934Srwatson	    (macop_t)mac_biba_check_socket_deliver },
2705101099Srwatson	{ MAC_CHECK_SOCKET_RELABEL,
2706101099Srwatson	    (macop_t)mac_biba_check_socket_relabel },
2707101099Srwatson	{ MAC_CHECK_SOCKET_VISIBLE,
2708101099Srwatson	    (macop_t)mac_biba_check_socket_visible },
2709106161Srwatson	{ MAC_CHECK_SYSTEM_SWAPON,
2710106161Srwatson	    (macop_t)mac_biba_check_system_swapon },
2711106161Srwatson	{ MAC_CHECK_SYSTEM_SYSCTL,
2712106161Srwatson	    (macop_t)mac_biba_check_system_sysctl },
2713101099Srwatson	{ MAC_CHECK_VNODE_ACCESS,
2714105635Srwatson	    (macop_t)mac_biba_check_vnode_open },
2715101099Srwatson	{ MAC_CHECK_VNODE_CHDIR,
2716101099Srwatson	    (macop_t)mac_biba_check_vnode_chdir },
2717101099Srwatson	{ MAC_CHECK_VNODE_CHROOT,
2718101099Srwatson	    (macop_t)mac_biba_check_vnode_chroot },
2719101099Srwatson	{ MAC_CHECK_VNODE_CREATE,
2720101099Srwatson	    (macop_t)mac_biba_check_vnode_create },
2721101099Srwatson	{ MAC_CHECK_VNODE_DELETE,
2722101099Srwatson	    (macop_t)mac_biba_check_vnode_delete },
2723101099Srwatson	{ MAC_CHECK_VNODE_DELETEACL,
2724101099Srwatson	    (macop_t)mac_biba_check_vnode_deleteacl },
2725101099Srwatson	{ MAC_CHECK_VNODE_EXEC,
2726101099Srwatson	    (macop_t)mac_biba_check_vnode_exec },
2727101099Srwatson	{ MAC_CHECK_VNODE_GETACL,
2728101099Srwatson	    (macop_t)mac_biba_check_vnode_getacl },
2729101099Srwatson	{ MAC_CHECK_VNODE_GETEXTATTR,
2730101099Srwatson	    (macop_t)mac_biba_check_vnode_getextattr },
2731104530Srwatson	{ MAC_CHECK_VNODE_LINK,
2732104530Srwatson	    (macop_t)mac_biba_check_vnode_link },
2733101099Srwatson	{ MAC_CHECK_VNODE_LOOKUP,
2734101099Srwatson	    (macop_t)mac_biba_check_vnode_lookup },
2735104546Srwatson	{ MAC_CHECK_VNODE_MMAP,
2736104546Srwatson	    (macop_t)mac_biba_check_vnode_mmap },
2737104546Srwatson	{ MAC_CHECK_VNODE_MPROTECT,
2738104546Srwatson	    (macop_t)mac_biba_check_vnode_mmap },
2739101099Srwatson	{ MAC_CHECK_VNODE_OPEN,
2740101099Srwatson	    (macop_t)mac_biba_check_vnode_open },
2741102112Srwatson	{ MAC_CHECK_VNODE_POLL,
2742102112Srwatson	    (macop_t)mac_biba_check_vnode_poll },
2743102112Srwatson	{ MAC_CHECK_VNODE_READ,
2744102112Srwatson	    (macop_t)mac_biba_check_vnode_read },
2745101099Srwatson	{ MAC_CHECK_VNODE_READDIR,
2746101099Srwatson	    (macop_t)mac_biba_check_vnode_readdir },
2747101099Srwatson	{ MAC_CHECK_VNODE_READLINK,
2748101099Srwatson	    (macop_t)mac_biba_check_vnode_readlink },
2749101099Srwatson	{ MAC_CHECK_VNODE_RELABEL,
2750101099Srwatson	    (macop_t)mac_biba_check_vnode_relabel },
2751101099Srwatson	{ MAC_CHECK_VNODE_RENAME_FROM,
2752101099Srwatson	    (macop_t)mac_biba_check_vnode_rename_from },
2753101099Srwatson	{ MAC_CHECK_VNODE_RENAME_TO,
2754101099Srwatson	    (macop_t)mac_biba_check_vnode_rename_to },
2755101099Srwatson	{ MAC_CHECK_VNODE_REVOKE,
2756101099Srwatson	    (macop_t)mac_biba_check_vnode_revoke },
2757101099Srwatson	{ MAC_CHECK_VNODE_SETACL,
2758101099Srwatson	    (macop_t)mac_biba_check_vnode_setacl },
2759101099Srwatson	{ MAC_CHECK_VNODE_SETEXTATTR,
2760101099Srwatson	    (macop_t)mac_biba_check_vnode_setextattr },
2761101099Srwatson	{ MAC_CHECK_VNODE_SETFLAGS,
2762101099Srwatson	    (macop_t)mac_biba_check_vnode_setflags },
2763101099Srwatson	{ MAC_CHECK_VNODE_SETMODE,
2764101099Srwatson	    (macop_t)mac_biba_check_vnode_setmode },
2765101099Srwatson	{ MAC_CHECK_VNODE_SETOWNER,
2766101099Srwatson	    (macop_t)mac_biba_check_vnode_setowner },
2767101099Srwatson	{ MAC_CHECK_VNODE_SETUTIMES,
2768101099Srwatson	    (macop_t)mac_biba_check_vnode_setutimes },
2769101099Srwatson	{ MAC_CHECK_VNODE_STAT,
2770101099Srwatson	    (macop_t)mac_biba_check_vnode_stat },
2771102112Srwatson	{ MAC_CHECK_VNODE_WRITE,
2772102112Srwatson	    (macop_t)mac_biba_check_vnode_write },
2773101099Srwatson	{ MAC_OP_LAST, NULL }
2774101099Srwatson};
2775101099Srwatson
2776101099SrwatsonMAC_POLICY_SET(mac_biba_ops, trustedbsd_mac_biba, "TrustedBSD MAC/Biba",
2777101099Srwatson    MPC_LOADTIME_FLAG_NOTLATE, &mac_biba_slot);
2778