mac_biba.c revision 123173
1101099Srwatson/*-
2101099Srwatson * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson
3115497Srwatson * Copyright (c) 2001, 2002, 2003 Networks Associates Technology, Inc.
4101099Srwatson * All rights reserved.
5101099Srwatson *
6101099Srwatson * This software was developed by Robert Watson for the TrustedBSD Project.
7101099Srwatson *
8106393Srwatson * This software was developed for the FreeBSD Project in part by Network
9106393Srwatson * Associates Laboratories, the Security Research Division of Network
10106393Srwatson * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"),
11106393Srwatson * as part of the DARPA CHATS research program.
12101099Srwatson *
13101099Srwatson * Redistribution and use in source and binary forms, with or without
14101099Srwatson * modification, are permitted provided that the following conditions
15101099Srwatson * are met:
16101099Srwatson * 1. Redistributions of source code must retain the above copyright
17101099Srwatson *    notice, this list of conditions and the following disclaimer.
18101099Srwatson * 2. Redistributions in binary form must reproduce the above copyright
19101099Srwatson *    notice, this list of conditions and the following disclaimer in the
20101099Srwatson *    documentation and/or other materials provided with the distribution.
21101099Srwatson *
22101099Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
23101099Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24101099Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25101099Srwatson * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
26101099Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27101099Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28101099Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29101099Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30101099Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31101099Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32101099Srwatson * SUCH DAMAGE.
33101099Srwatson *
34101099Srwatson * $FreeBSD: head/sys/security/mac_biba/mac_biba.c 123173 2003-12-06 21:48:03Z rwatson $
35101099Srwatson */
36101099Srwatson
37101099Srwatson/*
38101099Srwatson * Developed by the TrustedBSD Project.
39101099Srwatson * Biba fixed label mandatory integrity policy.
40101099Srwatson */
41101099Srwatson
42101099Srwatson#include <sys/types.h>
43101099Srwatson#include <sys/param.h>
44101099Srwatson#include <sys/acl.h>
45101099Srwatson#include <sys/conf.h>
46105988Srwatson#include <sys/extattr.h>
47101099Srwatson#include <sys/kernel.h>
48101099Srwatson#include <sys/mac.h>
49103183Sbde#include <sys/malloc.h>
50101099Srwatson#include <sys/mount.h>
51101099Srwatson#include <sys/proc.h>
52115497Srwatson#include <sys/sbuf.h>
53101099Srwatson#include <sys/systm.h>
54101099Srwatson#include <sys/sysproto.h>
55101099Srwatson#include <sys/sysent.h>
56105696Srwatson#include <sys/systm.h>
57101099Srwatson#include <sys/vnode.h>
58101099Srwatson#include <sys/file.h>
59101099Srwatson#include <sys/socket.h>
60101099Srwatson#include <sys/socketvar.h>
61101099Srwatson#include <sys/pipe.h>
62101099Srwatson#include <sys/sysctl.h>
63101099Srwatson
64101099Srwatson#include <fs/devfs/devfs.h>
65101099Srwatson
66101099Srwatson#include <net/bpfdesc.h>
67101099Srwatson#include <net/if.h>
68101099Srwatson#include <net/if_types.h>
69101099Srwatson#include <net/if_var.h>
70101099Srwatson
71101099Srwatson#include <netinet/in.h>
72122875Srwatson#include <netinet/in_pcb.h>
73101099Srwatson#include <netinet/ip_var.h>
74101099Srwatson
75122879Srwatson#include <vm/uma.h>
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
91107731Srwatsonstatic int	mac_biba_enabled = 1;
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
128122879Srwatsonstatic uma_zone_t	zone_biba;
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
144122879Srwatson	return (uma_zalloc(zone_biba, flag | M_ZERO));
145101099Srwatson}
146101099Srwatson
147101099Srwatsonstatic void
148101099Srwatsonbiba_free(struct mac_biba *mac_biba)
149101099Srwatson{
150101099Srwatson
151101099Srwatson	if (mac_biba != NULL)
152122879Srwatson		uma_zfree(zone_biba, mac_biba);
153101099Srwatson	else
154101099Srwatson		atomic_add_int(&destroyed_not_inited, 1);
155101099Srwatson}
156101099Srwatson
157101099Srwatsonstatic int
158105634Srwatsonbiba_atmostflags(struct mac_biba *mac_biba, int flags)
159105634Srwatson{
160105634Srwatson
161105634Srwatson	if ((mac_biba->mb_flags & flags) != mac_biba->mb_flags)
162105634Srwatson		return (EINVAL);
163105634Srwatson	return (0);
164105634Srwatson}
165105634Srwatson
166105634Srwatsonstatic int
167101099Srwatsonmac_biba_dominate_element(struct mac_biba_element *a,
168101099Srwatson    struct mac_biba_element *b)
169101099Srwatson{
170105643Srwatson	int bit;
171101099Srwatson
172105736Srwatson	switch (a->mbe_type) {
173101099Srwatson	case MAC_BIBA_TYPE_EQUAL:
174101099Srwatson	case MAC_BIBA_TYPE_HIGH:
175101099Srwatson		return (1);
176101099Srwatson
177101099Srwatson	case MAC_BIBA_TYPE_LOW:
178101099Srwatson		switch (b->mbe_type) {
179101099Srwatson		case MAC_BIBA_TYPE_GRADE:
180101099Srwatson		case MAC_BIBA_TYPE_HIGH:
181101099Srwatson			return (0);
182101099Srwatson
183101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
184101099Srwatson		case MAC_BIBA_TYPE_LOW:
185101099Srwatson			return (1);
186101099Srwatson
187101099Srwatson		default:
188101099Srwatson			panic("mac_biba_dominate_element: b->mbe_type invalid");
189101099Srwatson		}
190101099Srwatson
191101099Srwatson	case MAC_BIBA_TYPE_GRADE:
192101099Srwatson		switch (b->mbe_type) {
193101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
194101099Srwatson		case MAC_BIBA_TYPE_LOW:
195101099Srwatson			return (1);
196101099Srwatson
197101099Srwatson		case MAC_BIBA_TYPE_HIGH:
198101099Srwatson			return (0);
199101099Srwatson
200101099Srwatson		case MAC_BIBA_TYPE_GRADE:
201105643Srwatson			for (bit = 1; bit <= MAC_BIBA_MAX_COMPARTMENTS; bit++)
202105643Srwatson				if (!MAC_BIBA_BIT_TEST(bit,
203105643Srwatson				    a->mbe_compartments) &&
204105643Srwatson				    MAC_BIBA_BIT_TEST(bit, b->mbe_compartments))
205105643Srwatson					return (0);
206101099Srwatson			return (a->mbe_grade >= b->mbe_grade);
207101099Srwatson
208101099Srwatson		default:
209101099Srwatson			panic("mac_biba_dominate_element: b->mbe_type invalid");
210101099Srwatson		}
211101099Srwatson
212101099Srwatson	default:
213101099Srwatson		panic("mac_biba_dominate_element: a->mbe_type invalid");
214101099Srwatson	}
215101099Srwatson
216101099Srwatson	return (0);
217101099Srwatson}
218101099Srwatson
219101099Srwatsonstatic int
220105988Srwatsonmac_biba_subject_dominate_high(struct mac_biba *mac_biba)
221105988Srwatson{
222105988Srwatson	struct mac_biba_element *element;
223105988Srwatson
224106174Srwatson	KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
225105988Srwatson	    ("mac_biba_single_in_range: mac_biba not single"));
226105988Srwatson	element = &mac_biba->mb_single;
227105988Srwatson
228105988Srwatson	return (element->mbe_type == MAC_BIBA_TYPE_EQUAL ||
229105988Srwatson	    element->mbe_type == MAC_BIBA_TYPE_HIGH);
230105988Srwatson}
231105988Srwatson
232105988Srwatsonstatic int
233101099Srwatsonmac_biba_range_in_range(struct mac_biba *rangea, struct mac_biba *rangeb)
234101099Srwatson{
235101099Srwatson
236101099Srwatson	return (mac_biba_dominate_element(&rangeb->mb_rangehigh,
237101099Srwatson	    &rangea->mb_rangehigh) &&
238101099Srwatson	    mac_biba_dominate_element(&rangea->mb_rangelow,
239101099Srwatson	    &rangeb->mb_rangelow));
240101099Srwatson}
241101099Srwatson
242101099Srwatsonstatic int
243101099Srwatsonmac_biba_single_in_range(struct mac_biba *single, struct mac_biba *range)
244101099Srwatson{
245101099Srwatson
246103750Srwatson	KASSERT((single->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
247101099Srwatson	    ("mac_biba_single_in_range: a not single"));
248103750Srwatson	KASSERT((range->mb_flags & MAC_BIBA_FLAG_RANGE) != 0,
249101099Srwatson	    ("mac_biba_single_in_range: b not range"));
250101099Srwatson
251101099Srwatson	return (mac_biba_dominate_element(&range->mb_rangehigh,
252101099Srwatson	    &single->mb_single) &&
253101099Srwatson	    mac_biba_dominate_element(&single->mb_single,
254101099Srwatson	    &range->mb_rangelow));
255101099Srwatson
256101099Srwatson	return (1);
257101099Srwatson}
258101099Srwatson
259101099Srwatsonstatic int
260101099Srwatsonmac_biba_dominate_single(struct mac_biba *a, struct mac_biba *b)
261101099Srwatson{
262101099Srwatson	KASSERT((a->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
263101099Srwatson	    ("mac_biba_dominate_single: a not single"));
264101099Srwatson	KASSERT((b->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
265101099Srwatson	    ("mac_biba_dominate_single: b not single"));
266101099Srwatson
267101099Srwatson	return (mac_biba_dominate_element(&a->mb_single, &b->mb_single));
268101099Srwatson}
269101099Srwatson
270101099Srwatsonstatic int
271101099Srwatsonmac_biba_equal_element(struct mac_biba_element *a, struct mac_biba_element *b)
272101099Srwatson{
273101099Srwatson
274101099Srwatson	if (a->mbe_type == MAC_BIBA_TYPE_EQUAL ||
275101099Srwatson	    b->mbe_type == MAC_BIBA_TYPE_EQUAL)
276101099Srwatson		return (1);
277101099Srwatson
278101099Srwatson	return (a->mbe_type == b->mbe_type && a->mbe_grade == b->mbe_grade);
279101099Srwatson}
280101099Srwatson
281101099Srwatsonstatic int
282101099Srwatsonmac_biba_equal_single(struct mac_biba *a, struct mac_biba *b)
283101099Srwatson{
284101099Srwatson
285101099Srwatson	KASSERT((a->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
286101099Srwatson	    ("mac_biba_equal_single: a not single"));
287101099Srwatson	KASSERT((b->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
288101099Srwatson	    ("mac_biba_equal_single: b not single"));
289101099Srwatson
290101099Srwatson	return (mac_biba_equal_element(&a->mb_single, &b->mb_single));
291101099Srwatson}
292101099Srwatson
293101099Srwatsonstatic int
294105634Srwatsonmac_biba_contains_equal(struct mac_biba *mac_biba)
295105634Srwatson{
296105634Srwatson
297105634Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE)
298105634Srwatson		if (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_EQUAL)
299105634Srwatson			return (1);
300105634Srwatson
301105634Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
302105634Srwatson		if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL)
303105634Srwatson			return (1);
304105634Srwatson		if (mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL)
305105637Srwatson			return (1);
306105634Srwatson	}
307105634Srwatson
308105634Srwatson	return (0);
309105634Srwatson}
310105634Srwatson
311105634Srwatsonstatic int
312106090Srwatsonmac_biba_subject_privileged(struct mac_biba *mac_biba)
313105634Srwatson{
314105634Srwatson
315105634Srwatson	KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAGS_BOTH) ==
316105634Srwatson	    MAC_BIBA_FLAGS_BOTH,
317106090Srwatson	    ("mac_biba_subject_privileged: subject doesn't have both labels"));
318105634Srwatson
319105634Srwatson	/* If the single is EQUAL, it's ok. */
320105634Srwatson	if (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_EQUAL)
321105634Srwatson		return (0);
322105634Srwatson
323105634Srwatson	/* If either range endpoint is EQUAL, it's ok. */
324105634Srwatson	if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL ||
325105634Srwatson	    mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL)
326105634Srwatson		return (0);
327105634Srwatson
328105634Srwatson	/* If the range is low-high, it's ok. */
329105634Srwatson	if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_LOW &&
330105634Srwatson	    mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_HIGH)
331105634Srwatson		return (0);
332105634Srwatson
333105634Srwatson	/* It's not ok. */
334105634Srwatson	return (EPERM);
335105634Srwatson}
336105634Srwatson
337106091Srwatsonstatic int
338105988Srwatsonmac_biba_high_single(struct mac_biba *mac_biba)
339105988Srwatson{
340105988Srwatson
341105988Srwatson	KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
342105988Srwatson	    ("mac_biba_equal_single: mac_biba not single"));
343105988Srwatson
344105988Srwatson	return (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_HIGH);
345105988Srwatson}
346105988Srwatson
347105634Srwatsonstatic int
348101099Srwatsonmac_biba_valid(struct mac_biba *mac_biba)
349101099Srwatson{
350101099Srwatson
351101099Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) {
352101099Srwatson		switch (mac_biba->mb_single.mbe_type) {
353101099Srwatson		case MAC_BIBA_TYPE_GRADE:
354101099Srwatson			break;
355101099Srwatson
356101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
357101099Srwatson		case MAC_BIBA_TYPE_HIGH:
358101099Srwatson		case MAC_BIBA_TYPE_LOW:
359105643Srwatson			if (mac_biba->mb_single.mbe_grade != 0 ||
360105643Srwatson			    !MAC_BIBA_BIT_SET_EMPTY(
361105643Srwatson			    mac_biba->mb_single.mbe_compartments))
362101099Srwatson				return (EINVAL);
363101099Srwatson			break;
364101099Srwatson
365101099Srwatson		default:
366101099Srwatson			return (EINVAL);
367101099Srwatson		}
368101099Srwatson	} else {
369101099Srwatson		if (mac_biba->mb_single.mbe_type != MAC_BIBA_TYPE_UNDEF)
370101099Srwatson			return (EINVAL);
371101099Srwatson	}
372101099Srwatson
373101099Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
374101099Srwatson		switch (mac_biba->mb_rangelow.mbe_type) {
375101099Srwatson		case MAC_BIBA_TYPE_GRADE:
376101099Srwatson			break;
377101099Srwatson
378101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
379101099Srwatson		case MAC_BIBA_TYPE_HIGH:
380101099Srwatson		case MAC_BIBA_TYPE_LOW:
381105643Srwatson			if (mac_biba->mb_rangelow.mbe_grade != 0 ||
382105643Srwatson			    !MAC_BIBA_BIT_SET_EMPTY(
383105643Srwatson			    mac_biba->mb_rangelow.mbe_compartments))
384101099Srwatson				return (EINVAL);
385101099Srwatson			break;
386101099Srwatson
387101099Srwatson		default:
388101099Srwatson			return (EINVAL);
389101099Srwatson		}
390101099Srwatson
391101099Srwatson		switch (mac_biba->mb_rangehigh.mbe_type) {
392101099Srwatson		case MAC_BIBA_TYPE_GRADE:
393101099Srwatson			break;
394101099Srwatson
395101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
396101099Srwatson		case MAC_BIBA_TYPE_HIGH:
397101099Srwatson		case MAC_BIBA_TYPE_LOW:
398105643Srwatson			if (mac_biba->mb_rangehigh.mbe_grade != 0 ||
399105643Srwatson			    !MAC_BIBA_BIT_SET_EMPTY(
400105643Srwatson			    mac_biba->mb_rangehigh.mbe_compartments))
401101099Srwatson				return (EINVAL);
402101099Srwatson			break;
403101099Srwatson
404101099Srwatson		default:
405101099Srwatson			return (EINVAL);
406101099Srwatson		}
407101099Srwatson		if (!mac_biba_dominate_element(&mac_biba->mb_rangehigh,
408101099Srwatson		    &mac_biba->mb_rangelow))
409101099Srwatson			return (EINVAL);
410101099Srwatson	} else {
411101099Srwatson		if (mac_biba->mb_rangelow.mbe_type != MAC_BIBA_TYPE_UNDEF ||
412101099Srwatson		    mac_biba->mb_rangehigh.mbe_type != MAC_BIBA_TYPE_UNDEF)
413101099Srwatson			return (EINVAL);
414101099Srwatson	}
415101099Srwatson
416101099Srwatson	return (0);
417101099Srwatson}
418101099Srwatson
419101099Srwatsonstatic void
420101099Srwatsonmac_biba_set_range(struct mac_biba *mac_biba, u_short typelow,
421105643Srwatson    u_short gradelow, u_char *compartmentslow, u_short typehigh,
422105643Srwatson    u_short gradehigh, u_char *compartmentshigh)
423101099Srwatson{
424101099Srwatson
425101099Srwatson	mac_biba->mb_rangelow.mbe_type = typelow;
426101099Srwatson	mac_biba->mb_rangelow.mbe_grade = gradelow;
427105643Srwatson	if (compartmentslow != NULL)
428105643Srwatson		memcpy(mac_biba->mb_rangelow.mbe_compartments,
429105643Srwatson		    compartmentslow,
430105643Srwatson		    sizeof(mac_biba->mb_rangelow.mbe_compartments));
431101099Srwatson	mac_biba->mb_rangehigh.mbe_type = typehigh;
432101099Srwatson	mac_biba->mb_rangehigh.mbe_grade = gradehigh;
433105643Srwatson	if (compartmentshigh != NULL)
434105643Srwatson		memcpy(mac_biba->mb_rangehigh.mbe_compartments,
435105643Srwatson		    compartmentshigh,
436105643Srwatson		    sizeof(mac_biba->mb_rangehigh.mbe_compartments));
437101099Srwatson	mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE;
438101099Srwatson}
439101099Srwatson
440101099Srwatsonstatic void
441105643Srwatsonmac_biba_set_single(struct mac_biba *mac_biba, u_short type, u_short grade,
442105643Srwatson    u_char *compartments)
443101099Srwatson{
444101099Srwatson
445101099Srwatson	mac_biba->mb_single.mbe_type = type;
446101099Srwatson	mac_biba->mb_single.mbe_grade = grade;
447105643Srwatson	if (compartments != NULL)
448105643Srwatson		memcpy(mac_biba->mb_single.mbe_compartments, compartments,
449105643Srwatson		    sizeof(mac_biba->mb_single.mbe_compartments));
450101099Srwatson	mac_biba->mb_flags |= MAC_BIBA_FLAG_SINGLE;
451101099Srwatson}
452101099Srwatson
453101099Srwatsonstatic void
454101099Srwatsonmac_biba_copy_range(struct mac_biba *labelfrom, struct mac_biba *labelto)
455101099Srwatson{
456105643Srwatson
457101099Srwatson	KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_RANGE) != 0,
458101099Srwatson	    ("mac_biba_copy_range: labelfrom not range"));
459101099Srwatson
460101099Srwatson	labelto->mb_rangelow = labelfrom->mb_rangelow;
461101099Srwatson	labelto->mb_rangehigh = labelfrom->mb_rangehigh;
462101099Srwatson	labelto->mb_flags |= MAC_BIBA_FLAG_RANGE;
463101099Srwatson}
464101099Srwatson
465101099Srwatsonstatic void
466101099Srwatsonmac_biba_copy_single(struct mac_biba *labelfrom, struct mac_biba *labelto)
467101099Srwatson{
468101099Srwatson
469101099Srwatson	KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
470101099Srwatson	    ("mac_biba_copy_single: labelfrom not single"));
471101099Srwatson
472101099Srwatson	labelto->mb_single = labelfrom->mb_single;
473101099Srwatson	labelto->mb_flags |= MAC_BIBA_FLAG_SINGLE;
474101099Srwatson}
475101099Srwatson
476105656Srwatsonstatic void
477105656Srwatsonmac_biba_copy(struct mac_biba *source, struct mac_biba *dest)
478105656Srwatson{
479105656Srwatson
480105656Srwatson	if (source->mb_flags & MAC_BIBA_FLAG_SINGLE)
481105656Srwatson		mac_biba_copy_single(source, dest);
482105656Srwatson	if (source->mb_flags & MAC_BIBA_FLAG_RANGE)
483105656Srwatson		mac_biba_copy_range(source, dest);
484105656Srwatson}
485105656Srwatson
486101099Srwatson/*
487101099Srwatson * Policy module operations.
488101099Srwatson */
489101099Srwatsonstatic void
490101099Srwatsonmac_biba_init(struct mac_policy_conf *conf)
491101099Srwatson{
492101099Srwatson
493122879Srwatson	zone_biba = uma_zcreate("mac_biba", sizeof(struct mac_biba), NULL,
494122879Srwatson	    NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
495101099Srwatson}
496101099Srwatson
497101099Srwatson/*
498101099Srwatson * Label operations.
499101099Srwatson */
500101099Srwatsonstatic void
501104514Srwatsonmac_biba_init_label(struct label *label)
502101099Srwatson{
503101099Srwatson
504111119Simp	SLOT(label) = biba_alloc(M_WAITOK);
505101099Srwatson}
506101099Srwatson
507101099Srwatsonstatic int
508104514Srwatsonmac_biba_init_label_waitcheck(struct label *label, int flag)
509101099Srwatson{
510101099Srwatson
511104514Srwatson	SLOT(label) = biba_alloc(flag);
512101099Srwatson	if (SLOT(label) == NULL)
513101099Srwatson		return (ENOMEM);
514101099Srwatson
515101099Srwatson	return (0);
516101099Srwatson}
517101099Srwatson
518101099Srwatsonstatic void
519104514Srwatsonmac_biba_destroy_label(struct label *label)
520101099Srwatson{
521101099Srwatson
522101099Srwatson	biba_free(SLOT(label));
523101099Srwatson	SLOT(label) = NULL;
524101099Srwatson}
525101099Srwatson
526105696Srwatson/*
527115497Srwatson * mac_biba_element_to_string() accepts an sbuf and Biba element.  It
528115497Srwatson * converts the Biba element to a string and stores the result in the
529115497Srwatson * sbuf; if there isn't space in the sbuf, -1 is returned.
530105696Srwatson */
531115497Srwatsonstatic int
532115497Srwatsonmac_biba_element_to_string(struct sbuf *sb, struct mac_biba_element *element)
533105696Srwatson{
534115497Srwatson	int i, first;
535105696Srwatson
536105696Srwatson	switch (element->mbe_type) {
537105696Srwatson	case MAC_BIBA_TYPE_HIGH:
538115497Srwatson		return (sbuf_printf(sb, "high"));
539105696Srwatson
540105696Srwatson	case MAC_BIBA_TYPE_LOW:
541115497Srwatson		return (sbuf_printf(sb, "low"));
542105696Srwatson
543105696Srwatson	case MAC_BIBA_TYPE_EQUAL:
544115497Srwatson		return (sbuf_printf(sb, "equal"));
545105696Srwatson
546105696Srwatson	case MAC_BIBA_TYPE_GRADE:
547115497Srwatson		if (sbuf_printf(sb, "%d", element->mbe_grade) == -1)
548115497Srwatson			return (-1);
549115497Srwatson
550115497Srwatson		first = 1;
551115497Srwatson		for (i = 1; i <= MAC_BIBA_MAX_COMPARTMENTS; i++) {
552115497Srwatson			if (MAC_BIBA_BIT_TEST(i, element->mbe_compartments)) {
553115497Srwatson				if (first) {
554115497Srwatson					if (sbuf_putc(sb, ':') == -1)
555115497Srwatson						return (-1);
556115497Srwatson					if (sbuf_printf(sb, "%d", i) == -1)
557115497Srwatson						return (-1);
558115497Srwatson					first = 0;
559115497Srwatson				} else {
560115497Srwatson					if (sbuf_printf(sb, "+%d", i) == -1)
561115497Srwatson						return (-1);
562115497Srwatson				}
563115497Srwatson			}
564105696Srwatson		}
565115497Srwatson		return (0);
566105696Srwatson
567105696Srwatson	default:
568105696Srwatson		panic("mac_biba_element_to_string: invalid type (%d)",
569105696Srwatson		    element->mbe_type);
570105696Srwatson	}
571105696Srwatson}
572105696Srwatson
573115497Srwatson/*
574116701Srwatson * mac_biba_to_string() converts a Biba label to a string, and places
575116701Srwatson * the results in the passed sbuf.  It returns 0 on success, or EINVAL
576116701Srwatson * if there isn't room in the sbuf.  Note: the sbuf will be modified
577116701Srwatson * even in a failure case, so the caller may need to revert the sbuf
578116701Srwatson * by restoring the offset if that's undesired.
579115497Srwatson */
580101099Srwatsonstatic int
581116701Srwatsonmac_biba_to_string(struct sbuf *sb, struct mac_biba *mac_biba)
582101099Srwatson{
583105696Srwatson
584105696Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) {
585116701Srwatson		if (mac_biba_element_to_string(sb, &mac_biba->mb_single)
586115497Srwatson		    == -1)
587105696Srwatson			return (EINVAL);
588105696Srwatson	}
589105696Srwatson
590105696Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
591116701Srwatson		if (sbuf_putc(sb, '(') == -1)
592105696Srwatson			return (EINVAL);
593105696Srwatson
594116701Srwatson		if (mac_biba_element_to_string(sb, &mac_biba->mb_rangelow)
595115497Srwatson		    == -1)
596105696Srwatson			return (EINVAL);
597105696Srwatson
598116701Srwatson		if (sbuf_putc(sb, '-') == -1)
599105696Srwatson			return (EINVAL);
600105696Srwatson
601116701Srwatson		if (mac_biba_element_to_string(sb, &mac_biba->mb_rangehigh)
602115497Srwatson		    == -1)
603105696Srwatson			return (EINVAL);
604105696Srwatson
605116701Srwatson		if (sbuf_putc(sb, ')') == -1)
606105696Srwatson			return (EINVAL);
607105696Srwatson	}
608105696Srwatson
609105696Srwatson	return (0);
610105696Srwatson}
611105696Srwatson
612105696Srwatsonstatic int
613105696Srwatsonmac_biba_externalize_label(struct label *label, char *element_name,
614116701Srwatson    struct sbuf *sb, int *claimed)
615105696Srwatson{
616101099Srwatson	struct mac_biba *mac_biba;
617101099Srwatson
618105696Srwatson	if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0)
619105696Srwatson		return (0);
620105696Srwatson
621105696Srwatson	(*claimed)++;
622105696Srwatson
623101099Srwatson	mac_biba = SLOT(label);
624116701Srwatson	return (mac_biba_to_string(sb, mac_biba));
625105696Srwatson}
626105696Srwatson
627105696Srwatsonstatic int
628105696Srwatsonmac_biba_parse_element(struct mac_biba_element *element, char *string)
629101099Srwatson{
630115395Srwatson	char *compartment, *end, *grade;
631115395Srwatson	int value;
632105696Srwatson
633105696Srwatson	if (strcmp(string, "high") == 0 ||
634105696Srwatson	    strcmp(string, "hi") == 0) {
635105696Srwatson		element->mbe_type = MAC_BIBA_TYPE_HIGH;
636105696Srwatson		element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
637105696Srwatson	} else if (strcmp(string, "low") == 0 ||
638105696Srwatson	    strcmp(string, "lo") == 0) {
639105696Srwatson		element->mbe_type = MAC_BIBA_TYPE_LOW;
640105696Srwatson		element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
641105696Srwatson	} else if (strcmp(string, "equal") == 0 ||
642105696Srwatson	    strcmp(string, "eq") == 0) {
643105696Srwatson		element->mbe_type = MAC_BIBA_TYPE_EQUAL;
644105696Srwatson		element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
645105696Srwatson	} else {
646115395Srwatson		element->mbe_type = MAC_BIBA_TYPE_GRADE;
647105696Srwatson
648115395Srwatson		/*
649115395Srwatson		 * Numeric grade piece of the element.
650115395Srwatson		 */
651115395Srwatson		grade = strsep(&string, ":");
652115395Srwatson		value = strtol(grade, &end, 10);
653115395Srwatson		if (end == grade || *end != '\0')
654105696Srwatson			return (EINVAL);
655115395Srwatson		if (value < 0 || value > 65535)
656115395Srwatson			return (EINVAL);
657115395Srwatson		element->mbe_grade = value;
658105696Srwatson
659115395Srwatson		/*
660115395Srwatson		 * Optional compartment piece of the element.  If none
661115395Srwatson		 * are included, we assume that the label has no
662115395Srwatson		 * compartments.
663115395Srwatson		 */
664115395Srwatson		if (string == NULL)
665115395Srwatson			return (0);
666115395Srwatson		if (*string == '\0')
667115395Srwatson			return (0);
668105696Srwatson
669115395Srwatson		while ((compartment = strsep(&string, "+")) != NULL) {
670115395Srwatson			value = strtol(compartment, &end, 10);
671115395Srwatson			if (compartment == end || *end != '\0')
672105696Srwatson				return (EINVAL);
673115395Srwatson			if (value < 1 || value > MAC_BIBA_MAX_COMPARTMENTS)
674105696Srwatson				return (EINVAL);
675115395Srwatson			MAC_BIBA_BIT_SET(value, element->mbe_compartments);
676105696Srwatson		}
677105696Srwatson	}
678105696Srwatson
679105696Srwatson	return (0);
680105696Srwatson}
681105696Srwatson
682105696Srwatson/*
683105696Srwatson * Note: destructively consumes the string, make a local copy before
684105696Srwatson * calling if that's a problem.
685105696Srwatson */
686105696Srwatsonstatic int
687105696Srwatsonmac_biba_parse(struct mac_biba *mac_biba, char *string)
688105696Srwatson{
689115395Srwatson	char *rangehigh, *rangelow, *single;
690101099Srwatson	int error;
691101099Srwatson
692115395Srwatson	single = strsep(&string, "(");
693115395Srwatson	if (*single == '\0')
694105696Srwatson		single = NULL;
695115395Srwatson
696115395Srwatson	if (string != NULL) {
697115395Srwatson		rangelow = strsep(&string, "-");
698115395Srwatson		if (string == NULL)
699105696Srwatson			return (EINVAL);
700115395Srwatson		rangehigh = strsep(&string, ")");
701115395Srwatson		if (string == NULL)
702105696Srwatson			return (EINVAL);
703115395Srwatson		if (*string != '\0')
704105696Srwatson			return (EINVAL);
705115395Srwatson	} else {
706115395Srwatson		rangelow = NULL;
707115395Srwatson		rangehigh = NULL;
708105696Srwatson	}
709115395Srwatson
710105696Srwatson	KASSERT((rangelow != NULL && rangehigh != NULL) ||
711105696Srwatson	    (rangelow == NULL && rangehigh == NULL),
712115395Srwatson	    ("mac_biba_parse: range mismatch"));
713101099Srwatson
714105696Srwatson	bzero(mac_biba, sizeof(*mac_biba));
715105696Srwatson	if (single != NULL) {
716105696Srwatson		error = mac_biba_parse_element(&mac_biba->mb_single, single);
717105696Srwatson		if (error)
718105696Srwatson			return (error);
719105696Srwatson		mac_biba->mb_flags |= MAC_BIBA_FLAG_SINGLE;
720105696Srwatson	}
721105696Srwatson
722105696Srwatson	if (rangelow != NULL) {
723105696Srwatson		error = mac_biba_parse_element(&mac_biba->mb_rangelow,
724105696Srwatson		    rangelow);
725105696Srwatson		if (error)
726105696Srwatson			return (error);
727105696Srwatson		error = mac_biba_parse_element(&mac_biba->mb_rangehigh,
728105696Srwatson		    rangehigh);
729105696Srwatson		if (error)
730105696Srwatson			return (error);
731105696Srwatson		mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE;
732105696Srwatson	}
733105696Srwatson
734101099Srwatson	error = mac_biba_valid(mac_biba);
735101099Srwatson	if (error)
736101099Srwatson		return (error);
737101099Srwatson
738105696Srwatson	return (0);
739105696Srwatson}
740101099Srwatson
741105696Srwatsonstatic int
742105696Srwatsonmac_biba_internalize_label(struct label *label, char *element_name,
743105696Srwatson    char *element_data, int *claimed)
744105696Srwatson{
745105696Srwatson	struct mac_biba *mac_biba, mac_biba_temp;
746105696Srwatson	int error;
747105696Srwatson
748105696Srwatson	if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0)
749105696Srwatson		return (0);
750105696Srwatson
751105696Srwatson	(*claimed)++;
752105696Srwatson
753105696Srwatson	error = mac_biba_parse(&mac_biba_temp, element_data);
754105696Srwatson	if (error)
755105696Srwatson		return (error);
756105696Srwatson
757105696Srwatson	mac_biba = SLOT(label);
758105696Srwatson	*mac_biba = mac_biba_temp;
759105696Srwatson
760101099Srwatson	return (0);
761101099Srwatson}
762101099Srwatson
763105696Srwatsonstatic void
764105696Srwatsonmac_biba_copy_label(struct label *src, struct label *dest)
765105696Srwatson{
766105696Srwatson
767105696Srwatson	*SLOT(dest) = *SLOT(src);
768105696Srwatson}
769105696Srwatson
770101099Srwatson/*
771101099Srwatson * Labeling event operations: file system objects, and things that look
772101099Srwatson * a lot like file system objects.
773101099Srwatson */
774101099Srwatsonstatic void
775107698Srwatsonmac_biba_create_devfs_device(struct mount *mp, dev_t dev,
776107698Srwatson    struct devfs_dirent *devfs_dirent, struct label *label)
777101099Srwatson{
778101099Srwatson	struct mac_biba *mac_biba;
779101099Srwatson	int biba_type;
780101099Srwatson
781101099Srwatson	mac_biba = SLOT(label);
782101099Srwatson	if (strcmp(dev->si_name, "null") == 0 ||
783101099Srwatson	    strcmp(dev->si_name, "zero") == 0 ||
784101099Srwatson	    strcmp(dev->si_name, "random") == 0 ||
785101099Srwatson	    strncmp(dev->si_name, "fd/", strlen("fd/")) == 0)
786101099Srwatson		biba_type = MAC_BIBA_TYPE_EQUAL;
787105606Srwatson	else if (ptys_equal &&
788105606Srwatson	    (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 ||
789105606Srwatson	    strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0))
790105606Srwatson		biba_type = MAC_BIBA_TYPE_EQUAL;
791101099Srwatson	else
792101099Srwatson		biba_type = MAC_BIBA_TYPE_HIGH;
793105643Srwatson	mac_biba_set_single(mac_biba, biba_type, 0, NULL);
794101099Srwatson}
795101099Srwatson
796101099Srwatsonstatic void
797107698Srwatsonmac_biba_create_devfs_directory(struct mount *mp, char *dirname,
798107698Srwatson    int dirnamelen, struct devfs_dirent *devfs_dirent, struct label *label)
799101099Srwatson{
800101099Srwatson	struct mac_biba *mac_biba;
801101099Srwatson
802101099Srwatson	mac_biba = SLOT(label);
803105643Srwatson	mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
804101099Srwatson}
805101099Srwatson
806101099Srwatsonstatic void
807107698Srwatsonmac_biba_create_devfs_symlink(struct ucred *cred, struct mount *mp,
808107698Srwatson    struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de,
809122563Srwatson    struct label *delabel)
810104535Srwatson{
811104535Srwatson	struct mac_biba *source, *dest;
812104535Srwatson
813122524Srwatson	source = SLOT(cred->cr_label);
814104535Srwatson	dest = SLOT(delabel);
815104535Srwatson
816104535Srwatson	mac_biba_copy_single(source, dest);
817104535Srwatson}
818104535Srwatson
819104535Srwatsonstatic void
820101099Srwatsonmac_biba_create_mount(struct ucred *cred, struct mount *mp,
821101099Srwatson    struct label *mntlabel, struct label *fslabel)
822101099Srwatson{
823101099Srwatson	struct mac_biba *source, *dest;
824101099Srwatson
825122524Srwatson	source = SLOT(cred->cr_label);
826101099Srwatson	dest = SLOT(mntlabel);
827101099Srwatson	mac_biba_copy_single(source, dest);
828101099Srwatson	dest = SLOT(fslabel);
829101099Srwatson	mac_biba_copy_single(source, dest);
830101099Srwatson}
831101099Srwatson
832101099Srwatsonstatic void
833101099Srwatsonmac_biba_create_root_mount(struct ucred *cred, struct mount *mp,
834101099Srwatson    struct label *mntlabel, struct label *fslabel)
835101099Srwatson{
836101099Srwatson	struct mac_biba *mac_biba;
837101099Srwatson
838101099Srwatson	/* Always mount root as high integrity. */
839101099Srwatson	mac_biba = SLOT(fslabel);
840105643Srwatson	mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
841101099Srwatson	mac_biba = SLOT(mntlabel);
842105643Srwatson	mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
843101099Srwatson}
844101099Srwatson
845101099Srwatsonstatic void
846101099Srwatsonmac_biba_relabel_vnode(struct ucred *cred, struct vnode *vp,
847101099Srwatson    struct label *vnodelabel, struct label *label)
848101099Srwatson{
849101099Srwatson	struct mac_biba *source, *dest;
850101099Srwatson
851101099Srwatson	source = SLOT(label);
852101099Srwatson	dest = SLOT(vnodelabel);
853101099Srwatson
854105656Srwatson	mac_biba_copy(source, dest);
855101099Srwatson}
856101099Srwatson
857101099Srwatsonstatic void
858107698Srwatsonmac_biba_update_devfsdirent(struct mount *mp,
859107698Srwatson    struct devfs_dirent *devfs_dirent, struct label *direntlabel,
860107698Srwatson    struct vnode *vp, struct label *vnodelabel)
861101099Srwatson{
862101099Srwatson	struct mac_biba *source, *dest;
863101099Srwatson
864101099Srwatson	source = SLOT(vnodelabel);
865101099Srwatson	dest = SLOT(direntlabel);
866101099Srwatson
867105656Srwatson	mac_biba_copy(source, dest);
868101099Srwatson}
869101099Srwatson
870101099Srwatsonstatic void
871105988Srwatsonmac_biba_associate_vnode_devfs(struct mount *mp, struct label *fslabel,
872105988Srwatson    struct devfs_dirent *de, struct label *delabel, struct vnode *vp,
873105988Srwatson    struct label *vlabel)
874101099Srwatson{
875101099Srwatson	struct mac_biba *source, *dest;
876101099Srwatson
877105988Srwatson	source = SLOT(delabel);
878105988Srwatson	dest = SLOT(vlabel);
879101099Srwatson
880101099Srwatson	mac_biba_copy_single(source, dest);
881101099Srwatson}
882101099Srwatson
883101099Srwatsonstatic int
884105988Srwatsonmac_biba_associate_vnode_extattr(struct mount *mp, struct label *fslabel,
885105988Srwatson    struct vnode *vp, struct label *vlabel)
886101099Srwatson{
887105988Srwatson	struct mac_biba temp, *source, *dest;
888106354Smux	int buflen, error;
889101099Srwatson
890105988Srwatson	source = SLOT(fslabel);
891105988Srwatson	dest = SLOT(vlabel);
892101099Srwatson
893105988Srwatson	buflen = sizeof(temp);
894105988Srwatson	bzero(&temp, buflen);
895105988Srwatson
896105988Srwatson	error = vn_extattr_get(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
897105988Srwatson	    MAC_BIBA_EXTATTR_NAME, &buflen, (char *) &temp, curthread);
898105988Srwatson	if (error == ENOATTR || error == EOPNOTSUPP) {
899105988Srwatson		/* Fall back to the fslabel. */
900105988Srwatson		mac_biba_copy_single(source, dest);
901105988Srwatson		return (0);
902105988Srwatson	} else if (error)
903101099Srwatson		return (error);
904101099Srwatson
905105988Srwatson	if (buflen != sizeof(temp)) {
906105988Srwatson		printf("mac_biba_associate_vnode_extattr: bad size %d\n",
907105988Srwatson		    buflen);
908105988Srwatson		return (EPERM);
909105988Srwatson	}
910105988Srwatson	if (mac_biba_valid(&temp) != 0) {
911105988Srwatson		printf("mac_biba_associate_vnode_extattr: invalid\n");
912105988Srwatson		return (EPERM);
913105988Srwatson	}
914105988Srwatson	if ((temp.mb_flags & MAC_BIBA_FLAGS_BOTH) != MAC_BIBA_FLAG_SINGLE) {
915105988Srwatson		printf("mac_biba_associate_vnode_extattr: not single\n");
916105988Srwatson		return (EPERM);
917105988Srwatson	}
918101099Srwatson
919105988Srwatson	mac_biba_copy_single(&temp, dest);
920101099Srwatson	return (0);
921101099Srwatson}
922101099Srwatson
923101099Srwatsonstatic void
924105988Srwatsonmac_biba_associate_vnode_singlelabel(struct mount *mp,
925105988Srwatson    struct label *fslabel, struct vnode *vp, struct label *vlabel)
926101099Srwatson{
927101099Srwatson	struct mac_biba *source, *dest;
928101099Srwatson
929101099Srwatson	source = SLOT(fslabel);
930105988Srwatson	dest = SLOT(vlabel);
931101099Srwatson
932101099Srwatson	mac_biba_copy_single(source, dest);
933101099Srwatson}
934101099Srwatson
935105988Srwatsonstatic int
936105988Srwatsonmac_biba_create_vnode_extattr(struct ucred *cred, struct mount *mp,
937105988Srwatson    struct label *fslabel, struct vnode *dvp, struct label *dlabel,
938105988Srwatson    struct vnode *vp, struct label *vlabel, struct componentname *cnp)
939105988Srwatson{
940105988Srwatson	struct mac_biba *source, *dest, temp;
941105988Srwatson	size_t buflen;
942105988Srwatson	int error;
943105988Srwatson
944105988Srwatson	buflen = sizeof(temp);
945105988Srwatson	bzero(&temp, buflen);
946105988Srwatson
947122524Srwatson	source = SLOT(cred->cr_label);
948105988Srwatson	dest = SLOT(vlabel);
949105988Srwatson	mac_biba_copy_single(source, &temp);
950105988Srwatson
951105988Srwatson	error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
952105988Srwatson	    MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread);
953105988Srwatson	if (error == 0)
954105988Srwatson		mac_biba_copy_single(source, dest);
955105988Srwatson	return (error);
956105988Srwatson}
957105988Srwatson
958105988Srwatsonstatic int
959105988Srwatsonmac_biba_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp,
960105988Srwatson    struct label *vlabel, struct label *intlabel)
961105988Srwatson{
962105988Srwatson	struct mac_biba *source, temp;
963105988Srwatson	size_t buflen;
964105988Srwatson	int error;
965105988Srwatson
966105988Srwatson	buflen = sizeof(temp);
967105988Srwatson	bzero(&temp, buflen);
968105988Srwatson
969105988Srwatson	source = SLOT(intlabel);
970105988Srwatson	if ((source->mb_flags & MAC_BIBA_FLAG_SINGLE) == 0)
971105988Srwatson		return (0);
972105988Srwatson
973105988Srwatson	mac_biba_copy_single(source, &temp);
974105988Srwatson
975105988Srwatson	error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
976105988Srwatson	    MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread);
977105988Srwatson	return (error);
978105988Srwatson}
979105988Srwatson
980101099Srwatson/*
981101099Srwatson * Labeling event operations: IPC object.
982101099Srwatson */
983101099Srwatsonstatic void
984122875Srwatsonmac_biba_create_inpcb_from_socket(struct socket *so, struct label *solabel,
985122875Srwatson    struct inpcb *inp, struct label *inplabel)
986122875Srwatson{
987122875Srwatson	struct mac_biba *source, *dest;
988122875Srwatson
989122875Srwatson	source = SLOT(solabel);
990122875Srwatson	dest = SLOT(inplabel);
991122875Srwatson
992122875Srwatson	mac_biba_copy_single(source, dest);
993122875Srwatson}
994122875Srwatson
995122875Srwatsonstatic void
996101099Srwatsonmac_biba_create_mbuf_from_socket(struct socket *so, struct label *socketlabel,
997101099Srwatson    struct mbuf *m, struct label *mbuflabel)
998101099Srwatson{
999101099Srwatson	struct mac_biba *source, *dest;
1000101099Srwatson
1001101099Srwatson	source = SLOT(socketlabel);
1002101099Srwatson	dest = SLOT(mbuflabel);
1003101099Srwatson
1004101099Srwatson	mac_biba_copy_single(source, dest);
1005101099Srwatson}
1006101099Srwatson
1007101099Srwatsonstatic void
1008101099Srwatsonmac_biba_create_socket(struct ucred *cred, struct socket *socket,
1009101099Srwatson    struct label *socketlabel)
1010101099Srwatson{
1011101099Srwatson	struct mac_biba *source, *dest;
1012101099Srwatson
1013122524Srwatson	source = SLOT(cred->cr_label);
1014101099Srwatson	dest = SLOT(socketlabel);
1015101099Srwatson
1016101099Srwatson	mac_biba_copy_single(source, dest);
1017101099Srwatson}
1018101099Srwatson
1019101099Srwatsonstatic void
1020101099Srwatsonmac_biba_create_pipe(struct ucred *cred, struct pipe *pipe,
1021101099Srwatson    struct label *pipelabel)
1022101099Srwatson{
1023101099Srwatson	struct mac_biba *source, *dest;
1024101099Srwatson
1025122524Srwatson	source = SLOT(cred->cr_label);
1026101099Srwatson	dest = SLOT(pipelabel);
1027101099Srwatson
1028101099Srwatson	mac_biba_copy_single(source, dest);
1029101099Srwatson}
1030101099Srwatson
1031101099Srwatsonstatic void
1032101099Srwatsonmac_biba_create_socket_from_socket(struct socket *oldsocket,
1033101099Srwatson    struct label *oldsocketlabel, struct socket *newsocket,
1034101099Srwatson    struct label *newsocketlabel)
1035101099Srwatson{
1036101099Srwatson	struct mac_biba *source, *dest;
1037101099Srwatson
1038101099Srwatson	source = SLOT(oldsocketlabel);
1039101099Srwatson	dest = SLOT(newsocketlabel);
1040101099Srwatson
1041101099Srwatson	mac_biba_copy_single(source, dest);
1042101099Srwatson}
1043101099Srwatson
1044101099Srwatsonstatic void
1045101099Srwatsonmac_biba_relabel_socket(struct ucred *cred, struct socket *socket,
1046101099Srwatson    struct label *socketlabel, struct label *newlabel)
1047101099Srwatson{
1048101099Srwatson	struct mac_biba *source, *dest;
1049101099Srwatson
1050101099Srwatson	source = SLOT(newlabel);
1051101099Srwatson	dest = SLOT(socketlabel);
1052101099Srwatson
1053105656Srwatson	mac_biba_copy(source, dest);
1054101099Srwatson}
1055101099Srwatson
1056101099Srwatsonstatic void
1057101099Srwatsonmac_biba_relabel_pipe(struct ucred *cred, struct pipe *pipe,
1058101099Srwatson    struct label *pipelabel, struct label *newlabel)
1059101099Srwatson{
1060101099Srwatson	struct mac_biba *source, *dest;
1061101099Srwatson
1062101099Srwatson	source = SLOT(newlabel);
1063101099Srwatson	dest = SLOT(pipelabel);
1064101099Srwatson
1065105656Srwatson	mac_biba_copy(source, dest);
1066101099Srwatson}
1067101099Srwatson
1068101099Srwatsonstatic void
1069101099Srwatsonmac_biba_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel,
1070101099Srwatson    struct socket *socket, struct label *socketpeerlabel)
1071101099Srwatson{
1072101099Srwatson	struct mac_biba *source, *dest;
1073101099Srwatson
1074101099Srwatson	source = SLOT(mbuflabel);
1075101099Srwatson	dest = SLOT(socketpeerlabel);
1076101099Srwatson
1077101099Srwatson	mac_biba_copy_single(source, dest);
1078101099Srwatson}
1079101099Srwatson
1080101099Srwatson/*
1081101099Srwatson * Labeling event operations: network objects.
1082101099Srwatson */
1083101099Srwatsonstatic void
1084101099Srwatsonmac_biba_set_socket_peer_from_socket(struct socket *oldsocket,
1085101099Srwatson    struct label *oldsocketlabel, struct socket *newsocket,
1086101099Srwatson    struct label *newsocketpeerlabel)
1087101099Srwatson{
1088101099Srwatson	struct mac_biba *source, *dest;
1089101099Srwatson
1090101099Srwatson	source = SLOT(oldsocketlabel);
1091101099Srwatson	dest = SLOT(newsocketpeerlabel);
1092101099Srwatson
1093101099Srwatson	mac_biba_copy_single(source, dest);
1094101099Srwatson}
1095101099Srwatson
1096101099Srwatsonstatic void
1097101099Srwatsonmac_biba_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d,
1098101099Srwatson    struct label *bpflabel)
1099101099Srwatson{
1100101099Srwatson	struct mac_biba *source, *dest;
1101101099Srwatson
1102122524Srwatson	source = SLOT(cred->cr_label);
1103101099Srwatson	dest = SLOT(bpflabel);
1104101099Srwatson
1105101099Srwatson	mac_biba_copy_single(source, dest);
1106101099Srwatson}
1107101099Srwatson
1108101099Srwatsonstatic void
1109101099Srwatsonmac_biba_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel)
1110101099Srwatson{
1111121816Sbrooks	char tifname[IFNAMSIZ], *p, *q;
1112101099Srwatson	char tiflist[sizeof(trusted_interfaces)];
1113101099Srwatson	struct mac_biba *dest;
1114110350Srwatson	int len, type;
1115101099Srwatson
1116101099Srwatson	dest = SLOT(ifnetlabel);
1117101099Srwatson
1118101099Srwatson	if (ifnet->if_type == IFT_LOOP) {
1119110350Srwatson		type = MAC_BIBA_TYPE_EQUAL;
1120101099Srwatson		goto set;
1121101099Srwatson	}
1122101099Srwatson
1123101099Srwatson	if (trust_all_interfaces) {
1124110350Srwatson		type = MAC_BIBA_TYPE_HIGH;
1125101099Srwatson		goto set;
1126101099Srwatson	}
1127101099Srwatson
1128110350Srwatson	type = MAC_BIBA_TYPE_LOW;
1129101099Srwatson
1130101099Srwatson	if (trusted_interfaces[0] == '\0' ||
1131101099Srwatson	    !strvalid(trusted_interfaces, sizeof(trusted_interfaces)))
1132101099Srwatson		goto set;
1133101099Srwatson
1134106089Srwatson	bzero(tiflist, sizeof(tiflist));
1135101099Srwatson	for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++)
1136101099Srwatson		if(*p != ' ' && *p != '\t')
1137101099Srwatson			*q = *p;
1138101099Srwatson
1139101099Srwatson	for (p = q = tiflist;; p++) {
1140101099Srwatson		if (*p == ',' || *p == '\0') {
1141101099Srwatson			len = p - q;
1142101099Srwatson			if (len < IFNAMSIZ) {
1143101099Srwatson				bzero(tifname, sizeof(tifname));
1144101099Srwatson				bcopy(q, tifname, len);
1145121816Sbrooks				if (strcmp(tifname, ifnet->if_xname) == 0) {
1146110350Srwatson					type = MAC_BIBA_TYPE_HIGH;
1147101099Srwatson					break;
1148101099Srwatson				}
1149106089Srwatson			} else {
1150106089Srwatson				*p = '\0';
1151106089Srwatson				printf("mac_biba warning: interface name "
1152106089Srwatson				    "\"%s\" is too long (must be < %d)\n",
1153106089Srwatson				    q, IFNAMSIZ);
1154101099Srwatson			}
1155101099Srwatson			if (*p == '\0')
1156101099Srwatson				break;
1157101099Srwatson			q = p + 1;
1158101099Srwatson		}
1159101099Srwatson	}
1160101099Srwatsonset:
1161110350Srwatson	mac_biba_set_single(dest, type, 0, NULL);
1162110350Srwatson	mac_biba_set_range(dest, type, 0, NULL, type, 0, NULL);
1163101099Srwatson}
1164101099Srwatson
1165101099Srwatsonstatic void
1166101099Srwatsonmac_biba_create_ipq(struct mbuf *fragment, struct label *fragmentlabel,
1167101099Srwatson    struct ipq *ipq, struct label *ipqlabel)
1168101099Srwatson{
1169101099Srwatson	struct mac_biba *source, *dest;
1170101099Srwatson
1171101099Srwatson	source = SLOT(fragmentlabel);
1172101099Srwatson	dest = SLOT(ipqlabel);
1173101099Srwatson
1174101099Srwatson	mac_biba_copy_single(source, dest);
1175101099Srwatson}
1176101099Srwatson
1177101099Srwatsonstatic void
1178101099Srwatsonmac_biba_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel,
1179101099Srwatson    struct mbuf *datagram, struct label *datagramlabel)
1180101099Srwatson{
1181101099Srwatson	struct mac_biba *source, *dest;
1182101099Srwatson
1183101099Srwatson	source = SLOT(ipqlabel);
1184101099Srwatson	dest = SLOT(datagramlabel);
1185101099Srwatson
1186101099Srwatson	/* Just use the head, since we require them all to match. */
1187101099Srwatson	mac_biba_copy_single(source, dest);
1188101099Srwatson}
1189101099Srwatson
1190101099Srwatsonstatic void
1191101099Srwatsonmac_biba_create_fragment(struct mbuf *datagram, struct label *datagramlabel,
1192101099Srwatson    struct mbuf *fragment, struct label *fragmentlabel)
1193101099Srwatson{
1194101099Srwatson	struct mac_biba *source, *dest;
1195101099Srwatson
1196101099Srwatson	source = SLOT(datagramlabel);
1197101099Srwatson	dest = SLOT(fragmentlabel);
1198101099Srwatson
1199101099Srwatson	mac_biba_copy_single(source, dest);
1200101099Srwatson}
1201101099Srwatson
1202101099Srwatsonstatic void
1203101099Srwatsonmac_biba_create_mbuf_from_mbuf(struct mbuf *oldmbuf,
1204101099Srwatson    struct label *oldmbuflabel, struct mbuf *newmbuf,
1205101099Srwatson    struct label *newmbuflabel)
1206101099Srwatson{
1207101099Srwatson	struct mac_biba *source, *dest;
1208101099Srwatson
1209101099Srwatson	source = SLOT(oldmbuflabel);
1210101099Srwatson	dest = SLOT(newmbuflabel);
1211101099Srwatson
1212105656Srwatson	/*
1213105656Srwatson	 * Because the source mbuf may not yet have been "created",
1214105696Srwatson	 * just initialized, we do a conditional copy.  Since we don't
1215105656Srwatson	 * allow mbufs to have ranges, do a KASSERT to make sure that
1216105656Srwatson	 * doesn't happen.
1217105656Srwatson	 */
1218105656Srwatson	KASSERT((source->mb_flags & MAC_BIBA_FLAG_RANGE) == 0,
1219105656Srwatson	    ("mac_biba_create_mbuf_from_mbuf: source mbuf has range"));
1220105656Srwatson	mac_biba_copy(source, dest);
1221101099Srwatson}
1222101099Srwatson
1223101099Srwatsonstatic void
1224101099Srwatsonmac_biba_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel,
1225101099Srwatson    struct mbuf *mbuf, struct label *mbuflabel)
1226101099Srwatson{
1227101099Srwatson	struct mac_biba *dest;
1228101099Srwatson
1229101099Srwatson	dest = SLOT(mbuflabel);
1230101099Srwatson
1231105643Srwatson	mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1232101099Srwatson}
1233101099Srwatson
1234101099Srwatsonstatic void
1235101099Srwatsonmac_biba_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel,
1236101099Srwatson    struct mbuf *mbuf, struct label *mbuflabel)
1237101099Srwatson{
1238101099Srwatson	struct mac_biba *source, *dest;
1239101099Srwatson
1240101099Srwatson	source = SLOT(bpflabel);
1241101099Srwatson	dest = SLOT(mbuflabel);
1242101099Srwatson
1243101099Srwatson	mac_biba_copy_single(source, dest);
1244101099Srwatson}
1245101099Srwatson
1246101099Srwatsonstatic void
1247101099Srwatsonmac_biba_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel,
1248101099Srwatson    struct mbuf *m, struct label *mbuflabel)
1249101099Srwatson{
1250101099Srwatson	struct mac_biba *source, *dest;
1251101099Srwatson
1252101099Srwatson	source = SLOT(ifnetlabel);
1253101099Srwatson	dest = SLOT(mbuflabel);
1254101099Srwatson
1255101099Srwatson	mac_biba_copy_single(source, dest);
1256101099Srwatson}
1257101099Srwatson
1258101099Srwatsonstatic void
1259101099Srwatsonmac_biba_create_mbuf_multicast_encap(struct mbuf *oldmbuf,
1260101099Srwatson    struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel,
1261101099Srwatson    struct mbuf *newmbuf, struct label *newmbuflabel)
1262101099Srwatson{
1263101099Srwatson	struct mac_biba *source, *dest;
1264101099Srwatson
1265101099Srwatson	source = SLOT(oldmbuflabel);
1266101099Srwatson	dest = SLOT(newmbuflabel);
1267101099Srwatson
1268101099Srwatson	mac_biba_copy_single(source, dest);
1269101099Srwatson}
1270101099Srwatson
1271101099Srwatsonstatic void
1272101099Srwatsonmac_biba_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel,
1273101099Srwatson    struct mbuf *newmbuf, struct label *newmbuflabel)
1274101099Srwatson{
1275101099Srwatson	struct mac_biba *source, *dest;
1276101099Srwatson
1277101099Srwatson	source = SLOT(oldmbuflabel);
1278101099Srwatson	dest = SLOT(newmbuflabel);
1279101099Srwatson
1280101099Srwatson	mac_biba_copy_single(source, dest);
1281101099Srwatson}
1282101099Srwatson
1283101099Srwatsonstatic int
1284101099Srwatsonmac_biba_fragment_match(struct mbuf *fragment, struct label *fragmentlabel,
1285101099Srwatson    struct ipq *ipq, struct label *ipqlabel)
1286101099Srwatson{
1287101099Srwatson	struct mac_biba *a, *b;
1288101099Srwatson
1289101099Srwatson	a = SLOT(ipqlabel);
1290101099Srwatson	b = SLOT(fragmentlabel);
1291101099Srwatson
1292101099Srwatson	return (mac_biba_equal_single(a, b));
1293101099Srwatson}
1294101099Srwatson
1295101099Srwatsonstatic void
1296101099Srwatsonmac_biba_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet,
1297101099Srwatson    struct label *ifnetlabel, struct label *newlabel)
1298101099Srwatson{
1299101099Srwatson	struct mac_biba *source, *dest;
1300101099Srwatson
1301101099Srwatson	source = SLOT(newlabel);
1302101099Srwatson	dest = SLOT(ifnetlabel);
1303101099Srwatson
1304105656Srwatson	mac_biba_copy(source, dest);
1305101099Srwatson}
1306101099Srwatson
1307101099Srwatsonstatic void
1308101099Srwatsonmac_biba_update_ipq(struct mbuf *fragment, struct label *fragmentlabel,
1309101099Srwatson    struct ipq *ipq, struct label *ipqlabel)
1310101099Srwatson{
1311101099Srwatson
1312101099Srwatson	/* NOOP: we only accept matching labels, so no need to update */
1313101099Srwatson}
1314101099Srwatson
1315122875Srwatsonstatic void
1316122875Srwatsonmac_biba_inpcb_sosetlabel(struct socket *so, struct label *solabel,
1317122875Srwatson    struct inpcb *inp, struct label *inplabel)
1318122875Srwatson{
1319122875Srwatson	struct mac_biba *source, *dest;
1320122875Srwatson
1321122875Srwatson	source = SLOT(solabel);
1322122875Srwatson	dest = SLOT(inplabel);
1323122875Srwatson
1324122875Srwatson	mac_biba_copy(source, dest);
1325122875Srwatson}
1326122875Srwatson
1327101099Srwatson/*
1328101099Srwatson * Labeling event operations: processes.
1329101099Srwatson */
1330101099Srwatsonstatic void
1331101099Srwatsonmac_biba_create_proc0(struct ucred *cred)
1332101099Srwatson{
1333101099Srwatson	struct mac_biba *dest;
1334101099Srwatson
1335122524Srwatson	dest = SLOT(cred->cr_label);
1336101099Srwatson
1337105643Srwatson	mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1338105643Srwatson	mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL,
1339105643Srwatson	    MAC_BIBA_TYPE_HIGH, 0, NULL);
1340101099Srwatson}
1341101099Srwatson
1342101099Srwatsonstatic void
1343101099Srwatsonmac_biba_create_proc1(struct ucred *cred)
1344101099Srwatson{
1345101099Srwatson	struct mac_biba *dest;
1346101099Srwatson
1347122524Srwatson	dest = SLOT(cred->cr_label);
1348101099Srwatson
1349105643Srwatson	mac_biba_set_single(dest, MAC_BIBA_TYPE_HIGH, 0, NULL);
1350105643Srwatson	mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL,
1351105643Srwatson	    MAC_BIBA_TYPE_HIGH, 0, NULL);
1352101099Srwatson}
1353101099Srwatson
1354101099Srwatsonstatic void
1355101099Srwatsonmac_biba_relabel_cred(struct ucred *cred, struct label *newlabel)
1356101099Srwatson{
1357101099Srwatson	struct mac_biba *source, *dest;
1358101099Srwatson
1359101099Srwatson	source = SLOT(newlabel);
1360122524Srwatson	dest = SLOT(cred->cr_label);
1361101099Srwatson
1362105656Srwatson	mac_biba_copy(source, dest);
1363101099Srwatson}
1364101099Srwatson
1365101099Srwatson/*
1366101099Srwatson * Access control checks.
1367101099Srwatson */
1368101099Srwatsonstatic int
1369101099Srwatsonmac_biba_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel,
1370101099Srwatson    struct ifnet *ifnet, struct label *ifnetlabel)
1371101099Srwatson{
1372101099Srwatson	struct mac_biba *a, *b;
1373101099Srwatson
1374101099Srwatson	if (!mac_biba_enabled)
1375101099Srwatson		return (0);
1376101099Srwatson
1377101099Srwatson	a = SLOT(bpflabel);
1378101099Srwatson	b = SLOT(ifnetlabel);
1379101099Srwatson
1380101099Srwatson	if (mac_biba_equal_single(a, b))
1381101099Srwatson		return (0);
1382101099Srwatson	return (EACCES);
1383101099Srwatson}
1384101099Srwatson
1385101099Srwatsonstatic int
1386101099Srwatsonmac_biba_check_cred_relabel(struct ucred *cred, struct label *newlabel)
1387101099Srwatson{
1388101099Srwatson	struct mac_biba *subj, *new;
1389105634Srwatson	int error;
1390101099Srwatson
1391122524Srwatson	subj = SLOT(cred->cr_label);
1392101099Srwatson	new = SLOT(newlabel);
1393101099Srwatson
1394101099Srwatson	/*
1395105634Srwatson	 * If there is a Biba label update for the credential, it may
1396105634Srwatson	 * be an update of the single, range, or both.
1397101099Srwatson	 */
1398105634Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
1399105634Srwatson	if (error)
1400105634Srwatson		return (error);
1401101099Srwatson
1402101099Srwatson	/*
1403105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
1404101099Srwatson	 */
1405105634Srwatson	if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) {
1406105634Srwatson		/*
1407110351Srwatson		 * If the change request modifies both the Biba label
1408110351Srwatson		 * single and range, check that the new single will be
1409110351Srwatson		 * in the new range.
1410110351Srwatson		 */
1411110351Srwatson		if ((new->mb_flags & MAC_BIBA_FLAGS_BOTH) ==
1412110351Srwatson		    MAC_BIBA_FLAGS_BOTH &&
1413110351Srwatson		    !mac_biba_single_in_range(new, new))
1414110351Srwatson			return (EINVAL);
1415110351Srwatson
1416110351Srwatson		/*
1417105634Srwatson		 * To change the Biba single label on a credential, the
1418105634Srwatson		 * new single label must be in the current range.
1419105634Srwatson		 */
1420105634Srwatson		if (new->mb_flags & MAC_BIBA_FLAG_SINGLE &&
1421105634Srwatson		    !mac_biba_single_in_range(new, subj))
1422105634Srwatson			return (EPERM);
1423101099Srwatson
1424105634Srwatson		/*
1425105634Srwatson		 * To change the Biba range on a credential, the new
1426105634Srwatson		 * range label must be in the current range.
1427105634Srwatson		 */
1428105634Srwatson		if (new->mb_flags & MAC_BIBA_FLAG_RANGE &&
1429105634Srwatson		    !mac_biba_range_in_range(new, subj))
1430105634Srwatson			return (EPERM);
1431101099Srwatson
1432105634Srwatson		/*
1433105634Srwatson		 * To have EQUAL in any component of the new credential
1434105634Srwatson		 * Biba label, the subject must already have EQUAL in
1435105634Srwatson		 * their label.
1436105634Srwatson		 */
1437105634Srwatson		if (mac_biba_contains_equal(new)) {
1438106090Srwatson			error = mac_biba_subject_privileged(subj);
1439105634Srwatson			if (error)
1440105634Srwatson				return (error);
1441105634Srwatson		}
1442105634Srwatson	}
1443105634Srwatson
1444101099Srwatson	return (0);
1445101099Srwatson}
1446101099Srwatson
1447101099Srwatsonstatic int
1448101099Srwatsonmac_biba_check_cred_visible(struct ucred *u1, struct ucred *u2)
1449101099Srwatson{
1450101099Srwatson	struct mac_biba *subj, *obj;
1451101099Srwatson
1452101099Srwatson	if (!mac_biba_enabled)
1453101099Srwatson		return (0);
1454101099Srwatson
1455122524Srwatson	subj = SLOT(u1->cr_label);
1456122524Srwatson	obj = SLOT(u2->cr_label);
1457101099Srwatson
1458101099Srwatson	/* XXX: range */
1459101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1460101099Srwatson		return (ESRCH);
1461101099Srwatson
1462101099Srwatson	return (0);
1463101099Srwatson}
1464101099Srwatson
1465101099Srwatsonstatic int
1466101099Srwatsonmac_biba_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet,
1467101099Srwatson    struct label *ifnetlabel, struct label *newlabel)
1468101099Srwatson{
1469101099Srwatson	struct mac_biba *subj, *new;
1470105634Srwatson	int error;
1471101099Srwatson
1472122524Srwatson	subj = SLOT(cred->cr_label);
1473101099Srwatson	new = SLOT(newlabel);
1474101099Srwatson
1475105634Srwatson	/*
1476105634Srwatson	 * If there is a Biba label update for the interface, it may
1477105634Srwatson	 * be an update of the single, range, or both.
1478105634Srwatson	 */
1479105634Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
1480105634Srwatson	if (error)
1481105634Srwatson		return (error);
1482101099Srwatson
1483105634Srwatson	/*
1484106160Srwatson	 * Relabling network interfaces requires Biba privilege.
1485106160Srwatson	 */
1486106160Srwatson	error = mac_biba_subject_privileged(subj);
1487106160Srwatson	if (error)
1488106160Srwatson		return (error);
1489106160Srwatson
1490105634Srwatson	return (0);
1491101099Srwatson}
1492101099Srwatson
1493103759Srwatsonstatic int
1494101099Srwatsonmac_biba_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel,
1495101099Srwatson    struct mbuf *m, struct label *mbuflabel)
1496101099Srwatson{
1497101099Srwatson	struct mac_biba *p, *i;
1498103761Srwatson
1499101099Srwatson	if (!mac_biba_enabled)
1500101099Srwatson		return (0);
1501101099Srwatson
1502101099Srwatson	p = SLOT(mbuflabel);
1503101099Srwatson	i = SLOT(ifnetlabel);
1504103759Srwatson
1505101099Srwatson	return (mac_biba_single_in_range(p, i) ? 0 : EACCES);
1506101099Srwatson}
1507101099Srwatson
1508101099Srwatsonstatic int
1509122875Srwatsonmac_biba_check_inpcb_deliver(struct inpcb *inp, struct label *inplabel,
1510122875Srwatson    struct mbuf *m, struct label *mlabel)
1511122875Srwatson{
1512122875Srwatson	struct mac_biba *p, *i;
1513122875Srwatson
1514122875Srwatson	if (!mac_biba_enabled)
1515122875Srwatson		return (0);
1516122875Srwatson
1517122875Srwatson	p = SLOT(mlabel);
1518122875Srwatson	i = SLOT(inplabel);
1519122875Srwatson
1520122875Srwatson	return (mac_biba_equal_single(p, i) ? 0 : EACCES);
1521122875Srwatson}
1522122875Srwatson
1523122875Srwatsonstatic int
1524110354Srwatsonmac_biba_check_kld_load(struct ucred *cred, struct vnode *vp,
1525110354Srwatson    struct label *label)
1526110354Srwatson{
1527110354Srwatson	struct mac_biba *subj, *obj;
1528110354Srwatson	int error;
1529110354Srwatson
1530110354Srwatson	if (!mac_biba_enabled)
1531110354Srwatson		return (0);
1532110354Srwatson
1533122524Srwatson	subj = SLOT(cred->cr_label);
1534110354Srwatson
1535110354Srwatson	error = mac_biba_subject_privileged(subj);
1536110354Srwatson	if (error)
1537110354Srwatson		return (error);
1538110354Srwatson
1539110354Srwatson	obj = SLOT(label);
1540110354Srwatson	if (!mac_biba_high_single(obj))
1541110354Srwatson		return (EACCES);
1542110354Srwatson
1543110354Srwatson	return (0);
1544110354Srwatson}
1545110354Srwatson
1546110354Srwatson
1547110354Srwatsonstatic int
1548110354Srwatsonmac_biba_check_kld_unload(struct ucred *cred)
1549110354Srwatson{
1550110354Srwatson	struct mac_biba *subj;
1551110354Srwatson
1552110354Srwatson	if (!mac_biba_enabled)
1553110354Srwatson		return (0);
1554110354Srwatson
1555122524Srwatson	subj = SLOT(cred->cr_label);
1556110354Srwatson
1557110354Srwatson	return (mac_biba_subject_privileged(subj));
1558110354Srwatson}
1559110354Srwatson
1560110354Srwatsonstatic int
1561101099Srwatsonmac_biba_check_mount_stat(struct ucred *cred, struct mount *mp,
1562101099Srwatson    struct label *mntlabel)
1563101099Srwatson{
1564101099Srwatson	struct mac_biba *subj, *obj;
1565101099Srwatson
1566101099Srwatson	if (!mac_biba_enabled)
1567101099Srwatson		return (0);
1568101099Srwatson
1569122524Srwatson	subj = SLOT(cred->cr_label);
1570101099Srwatson	obj = SLOT(mntlabel);
1571101099Srwatson
1572101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1573101099Srwatson		return (EACCES);
1574101099Srwatson
1575101099Srwatson	return (0);
1576101099Srwatson}
1577101099Srwatson
1578101099Srwatsonstatic int
1579101099Srwatsonmac_biba_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe,
1580101099Srwatson    struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data)
1581101099Srwatson{
1582103759Srwatson
1583101099Srwatson	if(!mac_biba_enabled)
1584101099Srwatson		return (0);
1585101099Srwatson
1586101099Srwatson	/* XXX: This will be implemented soon... */
1587101099Srwatson
1588101099Srwatson	return (0);
1589101099Srwatson}
1590101099Srwatson
1591101099Srwatsonstatic int
1592102115Srwatsonmac_biba_check_pipe_poll(struct ucred *cred, struct pipe *pipe,
1593102115Srwatson    struct label *pipelabel)
1594101099Srwatson{
1595101099Srwatson	struct mac_biba *subj, *obj;
1596101099Srwatson
1597101099Srwatson	if (!mac_biba_enabled)
1598101099Srwatson		return (0);
1599101099Srwatson
1600122524Srwatson	subj = SLOT(cred->cr_label);
1601101099Srwatson	obj = SLOT((pipelabel));
1602101099Srwatson
1603102115Srwatson	if (!mac_biba_dominate_single(obj, subj))
1604102115Srwatson		return (EACCES);
1605101099Srwatson
1606101099Srwatson	return (0);
1607101099Srwatson}
1608101099Srwatson
1609101099Srwatsonstatic int
1610102115Srwatsonmac_biba_check_pipe_read(struct ucred *cred, struct pipe *pipe,
1611102115Srwatson    struct label *pipelabel)
1612102115Srwatson{
1613102115Srwatson	struct mac_biba *subj, *obj;
1614102115Srwatson
1615102115Srwatson	if (!mac_biba_enabled)
1616102115Srwatson		return (0);
1617102115Srwatson
1618122524Srwatson	subj = SLOT(cred->cr_label);
1619102115Srwatson	obj = SLOT((pipelabel));
1620102115Srwatson
1621102115Srwatson	if (!mac_biba_dominate_single(obj, subj))
1622102115Srwatson		return (EACCES);
1623102115Srwatson
1624102115Srwatson	return (0);
1625102115Srwatson}
1626102115Srwatson
1627102115Srwatsonstatic int
1628101099Srwatsonmac_biba_check_pipe_relabel(struct ucred *cred, struct pipe *pipe,
1629101099Srwatson    struct label *pipelabel, struct label *newlabel)
1630101099Srwatson{
1631101099Srwatson	struct mac_biba *subj, *obj, *new;
1632105634Srwatson	int error;
1633101099Srwatson
1634101099Srwatson	new = SLOT(newlabel);
1635122524Srwatson	subj = SLOT(cred->cr_label);
1636101099Srwatson	obj = SLOT(pipelabel);
1637101099Srwatson
1638101099Srwatson	/*
1639105634Srwatson	 * If there is a Biba label update for a pipe, it must be a
1640105634Srwatson	 * single update.
1641101099Srwatson	 */
1642105634Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE);
1643105634Srwatson	if (error)
1644105634Srwatson		return (error);
1645101099Srwatson
1646101099Srwatson	/*
1647105634Srwatson	 * To perform a relabel of a pipe (Biba label or not), Biba must
1648105634Srwatson	 * authorize the relabel.
1649101099Srwatson	 */
1650105634Srwatson	if (!mac_biba_single_in_range(obj, subj))
1651101099Srwatson		return (EPERM);
1652101099Srwatson
1653101099Srwatson	/*
1654105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
1655101099Srwatson	 */
1656105634Srwatson	if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) {
1657105634Srwatson		/*
1658105634Srwatson		 * To change the Biba label on a pipe, the new pipe label
1659105634Srwatson		 * must be in the subject range.
1660105634Srwatson		 */
1661105634Srwatson		if (!mac_biba_single_in_range(new, subj))
1662105634Srwatson			return (EPERM);
1663101099Srwatson
1664105634Srwatson		/*
1665105634Srwatson		 * To change the Biba label on a pipe to be EQUAL, the
1666105634Srwatson		 * subject must have appropriate privilege.
1667105634Srwatson		 */
1668105634Srwatson		if (mac_biba_contains_equal(new)) {
1669106090Srwatson			error = mac_biba_subject_privileged(subj);
1670105634Srwatson			if (error)
1671105634Srwatson				return (error);
1672105634Srwatson		}
1673105634Srwatson	}
1674105634Srwatson
1675101099Srwatson	return (0);
1676101099Srwatson}
1677101099Srwatson
1678101099Srwatsonstatic int
1679102115Srwatsonmac_biba_check_pipe_stat(struct ucred *cred, struct pipe *pipe,
1680102115Srwatson    struct label *pipelabel)
1681102115Srwatson{
1682102115Srwatson	struct mac_biba *subj, *obj;
1683102115Srwatson
1684102115Srwatson	if (!mac_biba_enabled)
1685102115Srwatson		return (0);
1686102115Srwatson
1687122524Srwatson	subj = SLOT(cred->cr_label);
1688102115Srwatson	obj = SLOT((pipelabel));
1689102115Srwatson
1690102115Srwatson	if (!mac_biba_dominate_single(obj, subj))
1691102115Srwatson		return (EACCES);
1692102115Srwatson
1693102115Srwatson	return (0);
1694102115Srwatson}
1695102115Srwatson
1696102115Srwatsonstatic int
1697102115Srwatsonmac_biba_check_pipe_write(struct ucred *cred, struct pipe *pipe,
1698102115Srwatson    struct label *pipelabel)
1699102115Srwatson{
1700102115Srwatson	struct mac_biba *subj, *obj;
1701102115Srwatson
1702102115Srwatson	if (!mac_biba_enabled)
1703102115Srwatson		return (0);
1704102115Srwatson
1705122524Srwatson	subj = SLOT(cred->cr_label);
1706102115Srwatson	obj = SLOT((pipelabel));
1707102115Srwatson
1708102115Srwatson	if (!mac_biba_dominate_single(subj, obj))
1709102115Srwatson		return (EACCES);
1710102115Srwatson
1711102115Srwatson	return (0);
1712102115Srwatson}
1713102115Srwatson
1714102115Srwatsonstatic int
1715101099Srwatsonmac_biba_check_proc_debug(struct ucred *cred, struct proc *proc)
1716101099Srwatson{
1717101099Srwatson	struct mac_biba *subj, *obj;
1718101099Srwatson
1719101099Srwatson	if (!mac_biba_enabled)
1720101099Srwatson		return (0);
1721101099Srwatson
1722122524Srwatson	subj = SLOT(cred->cr_label);
1723122524Srwatson	obj = SLOT(proc->p_ucred->cr_label);
1724101099Srwatson
1725101099Srwatson	/* XXX: range checks */
1726101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1727101099Srwatson		return (ESRCH);
1728101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1729101099Srwatson		return (EACCES);
1730101099Srwatson
1731101099Srwatson	return (0);
1732101099Srwatson}
1733101099Srwatson
1734101099Srwatsonstatic int
1735101099Srwatsonmac_biba_check_proc_sched(struct ucred *cred, struct proc *proc)
1736101099Srwatson{
1737101099Srwatson	struct mac_biba *subj, *obj;
1738103759Srwatson
1739101099Srwatson	if (!mac_biba_enabled)
1740101099Srwatson		return (0);
1741101099Srwatson
1742122524Srwatson	subj = SLOT(cred->cr_label);
1743122524Srwatson	obj = SLOT(proc->p_ucred->cr_label);
1744103759Srwatson
1745101099Srwatson	/* XXX: range checks */
1746101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1747101099Srwatson		return (ESRCH);
1748101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1749101099Srwatson		return (EACCES);
1750101099Srwatson
1751101099Srwatson	return (0);
1752101099Srwatson}
1753101099Srwatson
1754101099Srwatsonstatic int
1755101099Srwatsonmac_biba_check_proc_signal(struct ucred *cred, struct proc *proc, int signum)
1756101099Srwatson{
1757101099Srwatson	struct mac_biba *subj, *obj;
1758103759Srwatson
1759101099Srwatson	if (!mac_biba_enabled)
1760101099Srwatson		return (0);
1761101099Srwatson
1762122524Srwatson	subj = SLOT(cred->cr_label);
1763122524Srwatson	obj = SLOT(proc->p_ucred->cr_label);
1764103759Srwatson
1765101099Srwatson	/* XXX: range checks */
1766101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1767101099Srwatson		return (ESRCH);
1768101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1769101099Srwatson		return (EACCES);
1770101099Srwatson
1771101099Srwatson	return (0);
1772101099Srwatson}
1773101099Srwatson
1774101099Srwatsonstatic int
1775101934Srwatsonmac_biba_check_socket_deliver(struct socket *so, struct label *socketlabel,
1776101099Srwatson    struct mbuf *m, struct label *mbuflabel)
1777101099Srwatson{
1778101099Srwatson	struct mac_biba *p, *s;
1779101099Srwatson
1780101099Srwatson	if (!mac_biba_enabled)
1781101099Srwatson		return (0);
1782101099Srwatson
1783101099Srwatson	p = SLOT(mbuflabel);
1784101099Srwatson	s = SLOT(socketlabel);
1785101099Srwatson
1786101099Srwatson	return (mac_biba_equal_single(p, s) ? 0 : EACCES);
1787101099Srwatson}
1788101099Srwatson
1789101099Srwatsonstatic int
1790106214Srwatsonmac_biba_check_socket_relabel(struct ucred *cred, struct socket *so,
1791101099Srwatson    struct label *socketlabel, struct label *newlabel)
1792101099Srwatson{
1793101099Srwatson	struct mac_biba *subj, *obj, *new;
1794105634Srwatson	int error;
1795101099Srwatson
1796101099Srwatson	new = SLOT(newlabel);
1797122524Srwatson	subj = SLOT(cred->cr_label);
1798101099Srwatson	obj = SLOT(socketlabel);
1799101099Srwatson
1800101099Srwatson	/*
1801105634Srwatson	 * If there is a Biba label update for the socket, it may be
1802105634Srwatson	 * an update of single.
1803101099Srwatson	 */
1804105634Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE);
1805105634Srwatson	if (error)
1806105634Srwatson		return (error);
1807101099Srwatson
1808101099Srwatson	/*
1809105634Srwatson	 * To relabel a socket, the old socket single must be in the subject
1810101099Srwatson	 * range.
1811101099Srwatson	 */
1812105634Srwatson	if (!mac_biba_single_in_range(obj, subj))
1813101099Srwatson		return (EPERM);
1814101099Srwatson
1815101099Srwatson	/*
1816105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
1817101099Srwatson	 */
1818105634Srwatson	if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) {
1819105634Srwatson		/*
1820105634Srwatson		 * To relabel a socket, the new socket single must be in
1821105634Srwatson		 * the subject range.
1822105634Srwatson		 */
1823105634Srwatson		if (!mac_biba_single_in_range(new, subj))
1824105634Srwatson			return (EPERM);
1825101099Srwatson
1826105634Srwatson		/*
1827105634Srwatson		 * To change the Biba label on the socket to contain EQUAL,
1828105634Srwatson		 * the subject must have appropriate privilege.
1829105634Srwatson		 */
1830105634Srwatson		if (mac_biba_contains_equal(new)) {
1831106090Srwatson			error = mac_biba_subject_privileged(subj);
1832105634Srwatson			if (error)
1833105634Srwatson				return (error);
1834105634Srwatson		}
1835105634Srwatson	}
1836105634Srwatson
1837101099Srwatson	return (0);
1838101099Srwatson}
1839101099Srwatson
1840101099Srwatsonstatic int
1841101099Srwatsonmac_biba_check_socket_visible(struct ucred *cred, struct socket *socket,
1842101099Srwatson    struct label *socketlabel)
1843101099Srwatson{
1844101099Srwatson	struct mac_biba *subj, *obj;
1845101099Srwatson
1846105722Srwatson	if (!mac_biba_enabled)
1847105722Srwatson		return (0);
1848105722Srwatson
1849122524Srwatson	subj = SLOT(cred->cr_label);
1850101099Srwatson	obj = SLOT(socketlabel);
1851101099Srwatson
1852101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1853101099Srwatson		return (ENOENT);
1854101099Srwatson
1855101099Srwatson	return (0);
1856101099Srwatson}
1857101099Srwatson
1858101099Srwatsonstatic int
1859112574Srwatsonmac_biba_check_sysarch_ioperm(struct ucred *cred)
1860112574Srwatson{
1861112574Srwatson	struct mac_biba *subj;
1862112574Srwatson	int error;
1863112574Srwatson
1864112574Srwatson	if (!mac_biba_enabled)
1865112574Srwatson		return (0);
1866112574Srwatson
1867122524Srwatson	subj = SLOT(cred->cr_label);
1868112574Srwatson
1869112574Srwatson	error = mac_biba_subject_privileged(subj);
1870112574Srwatson	if (error)
1871112574Srwatson		return (error);
1872112574Srwatson
1873112574Srwatson	return (0);
1874112574Srwatson}
1875112574Srwatson
1876112574Srwatsonstatic int
1877106418Srwatsonmac_biba_check_system_acct(struct ucred *cred, struct vnode *vp,
1878106418Srwatson    struct label *label)
1879106418Srwatson{
1880106418Srwatson	struct mac_biba *subj, *obj;
1881106418Srwatson	int error;
1882106418Srwatson
1883106418Srwatson	if (!mac_biba_enabled)
1884106418Srwatson		return (0);
1885106418Srwatson
1886122524Srwatson	subj = SLOT(cred->cr_label);
1887106418Srwatson
1888106418Srwatson	error = mac_biba_subject_privileged(subj);
1889106418Srwatson	if (error)
1890106418Srwatson		return (error);
1891106418Srwatson
1892106418Srwatson	if (label == NULL)
1893106418Srwatson		return (0);
1894106418Srwatson
1895106418Srwatson	obj = SLOT(label);
1896106418Srwatson	if (!mac_biba_high_single(obj))
1897106418Srwatson		return (EACCES);
1898106418Srwatson
1899106418Srwatson	return (0);
1900106418Srwatson}
1901106418Srwatson
1902106418Srwatsonstatic int
1903106418Srwatsonmac_biba_check_system_settime(struct ucred *cred)
1904106418Srwatson{
1905106418Srwatson	struct mac_biba *subj;
1906106418Srwatson	int error;
1907106418Srwatson
1908106418Srwatson	if (!mac_biba_enabled)
1909106418Srwatson		return (0);
1910106418Srwatson
1911122524Srwatson	subj = SLOT(cred->cr_label);
1912106418Srwatson
1913106418Srwatson	error = mac_biba_subject_privileged(subj);
1914106418Srwatson	if (error)
1915106418Srwatson		return (error);
1916106418Srwatson
1917106418Srwatson	return (0);
1918106418Srwatson}
1919106418Srwatson
1920106418Srwatsonstatic int
1921106161Srwatsonmac_biba_check_system_swapon(struct ucred *cred, struct vnode *vp,
1922106161Srwatson    struct label *label)
1923106161Srwatson{
1924106161Srwatson	struct mac_biba *subj, *obj;
1925106416Srwatson	int error;
1926106161Srwatson
1927106161Srwatson	if (!mac_biba_enabled)
1928106161Srwatson		return (0);
1929106161Srwatson
1930122524Srwatson	subj = SLOT(cred->cr_label);
1931106161Srwatson	obj = SLOT(label);
1932106161Srwatson
1933106416Srwatson	error = mac_biba_subject_privileged(subj);
1934106416Srwatson	if (error)
1935106416Srwatson		return (error);
1936106161Srwatson
1937106161Srwatson	if (!mac_biba_high_single(obj))
1938106161Srwatson		return (EACCES);
1939106161Srwatson
1940106161Srwatson	return (0);
1941106161Srwatson}
1942106161Srwatson
1943106161Srwatsonstatic int
1944112574Srwatsonmac_biba_check_system_swapoff(struct ucred *cred, struct vnode *vp,
1945112574Srwatson    struct label *label)
1946112574Srwatson{
1947112574Srwatson	struct mac_biba *subj, *obj;
1948112574Srwatson	int error;
1949112574Srwatson
1950112574Srwatson	if (!mac_biba_enabled)
1951112574Srwatson		return (0);
1952112574Srwatson
1953122524Srwatson	subj = SLOT(cred->cr_label);
1954112574Srwatson	obj = SLOT(label);
1955112574Srwatson
1956112574Srwatson	error = mac_biba_subject_privileged(subj);
1957112574Srwatson	if (error)
1958112574Srwatson		return (error);
1959112574Srwatson
1960112574Srwatson	return (0);
1961112574Srwatson}
1962112574Srwatson
1963112574Srwatsonstatic int
1964106161Srwatsonmac_biba_check_system_sysctl(struct ucred *cred, int *name, u_int namelen,
1965106161Srwatson    void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen)
1966106161Srwatson{
1967106161Srwatson	struct mac_biba *subj;
1968106161Srwatson	int error;
1969106161Srwatson
1970106161Srwatson	if (!mac_biba_enabled)
1971106161Srwatson		return (0);
1972106161Srwatson
1973122524Srwatson	subj = SLOT(cred->cr_label);
1974106161Srwatson
1975106161Srwatson	/*
1976106161Srwatson	 * In general, treat sysctl variables as biba/high, but also
1977106161Srwatson	 * require privilege to change them, since they are a
1978106161Srwatson	 * communications channel between grades.  Exempt MIB
1979106161Srwatson	 * queries from this due to undocmented sysctl magic.
1980106161Srwatson	 * XXXMAC: This probably requires some more review.
1981106161Srwatson	 */
1982106161Srwatson	if (new != NULL) {
1983106161Srwatson		if (namelen > 0 && name[0] == 0)
1984106161Srwatson			return (0);
1985106161Srwatson
1986106161Srwatson		if (!mac_biba_subject_dominate_high(subj))
1987106161Srwatson			return (EACCES);
1988106161Srwatson
1989106161Srwatson		error = mac_biba_subject_privileged(subj);
1990106161Srwatson		if (error)
1991106161Srwatson			return (error);
1992106161Srwatson	}
1993106161Srwatson
1994106161Srwatson	return (0);
1995106161Srwatson}
1996106161Srwatson
1997106161Srwatsonstatic int
1998101099Srwatsonmac_biba_check_vnode_chdir(struct ucred *cred, struct vnode *dvp,
1999101099Srwatson    struct label *dlabel)
2000101099Srwatson{
2001101099Srwatson	struct mac_biba *subj, *obj;
2002101099Srwatson
2003101099Srwatson	if (!mac_biba_enabled)
2004101099Srwatson		return (0);
2005101099Srwatson
2006122524Srwatson	subj = SLOT(cred->cr_label);
2007101099Srwatson	obj = SLOT(dlabel);
2008101099Srwatson
2009101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
2010101099Srwatson		return (EACCES);
2011101099Srwatson
2012101099Srwatson	return (0);
2013101099Srwatson}
2014101099Srwatson
2015101099Srwatsonstatic int
2016101099Srwatsonmac_biba_check_vnode_chroot(struct ucred *cred, struct vnode *dvp,
2017101099Srwatson    struct label *dlabel)
2018101099Srwatson{
2019101099Srwatson	struct mac_biba *subj, *obj;
2020101099Srwatson
2021101099Srwatson	if (!mac_biba_enabled)
2022101099Srwatson		return (0);
2023101099Srwatson
2024122524Srwatson	subj = SLOT(cred->cr_label);
2025101099Srwatson	obj = SLOT(dlabel);
2026101099Srwatson
2027101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
2028101099Srwatson		return (EACCES);
2029101099Srwatson
2030101099Srwatson	return (0);
2031101099Srwatson}
2032101099Srwatson
2033101099Srwatsonstatic int
2034101099Srwatsonmac_biba_check_vnode_create(struct ucred *cred, struct vnode *dvp,
2035101099Srwatson    struct label *dlabel, struct componentname *cnp, struct vattr *vap)
2036101099Srwatson{
2037101099Srwatson	struct mac_biba *subj, *obj;
2038101099Srwatson
2039101099Srwatson	if (!mac_biba_enabled)
2040101099Srwatson		return (0);
2041101099Srwatson
2042122524Srwatson	subj = SLOT(cred->cr_label);
2043101099Srwatson	obj = SLOT(dlabel);
2044101099Srwatson
2045101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2046101099Srwatson		return (EACCES);
2047101099Srwatson
2048101099Srwatson	return (0);
2049101099Srwatson}
2050101099Srwatson
2051101099Srwatsonstatic int
2052101099Srwatsonmac_biba_check_vnode_delete(struct ucred *cred, struct vnode *dvp,
2053101099Srwatson    struct label *dlabel, struct vnode *vp, struct label *label,
2054101099Srwatson    struct componentname *cnp)
2055101099Srwatson{
2056101099Srwatson	struct mac_biba *subj, *obj;
2057101099Srwatson
2058101099Srwatson	if (!mac_biba_enabled)
2059101099Srwatson		return (0);
2060101099Srwatson
2061122524Srwatson	subj = SLOT(cred->cr_label);
2062101099Srwatson	obj = SLOT(dlabel);
2063101099Srwatson
2064101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2065101099Srwatson		return (EACCES);
2066101099Srwatson
2067101099Srwatson	obj = SLOT(label);
2068101099Srwatson
2069101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2070101099Srwatson		return (EACCES);
2071101099Srwatson
2072101099Srwatson	return (0);
2073101099Srwatson}
2074101099Srwatson
2075101099Srwatsonstatic int
2076101099Srwatsonmac_biba_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
2077101099Srwatson    struct label *label, acl_type_t type)
2078101099Srwatson{
2079101099Srwatson	struct mac_biba *subj, *obj;
2080101099Srwatson
2081101099Srwatson	if (!mac_biba_enabled)
2082101099Srwatson		return (0);
2083101099Srwatson
2084122524Srwatson	subj = SLOT(cred->cr_label);
2085101099Srwatson	obj = SLOT(label);
2086101099Srwatson
2087101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2088101099Srwatson		return (EACCES);
2089101099Srwatson
2090101099Srwatson	return (0);
2091101099Srwatson}
2092101099Srwatson
2093101099Srwatsonstatic int
2094119202Srwatsonmac_biba_check_vnode_deleteextattr(struct ucred *cred, struct vnode *vp,
2095119202Srwatson    struct label *label, int attrnamespace, const char *name)
2096119202Srwatson{
2097119202Srwatson	struct mac_biba *subj, *obj;
2098119202Srwatson
2099119202Srwatson	if (!mac_biba_enabled)
2100119202Srwatson		return (0);
2101119202Srwatson
2102122524Srwatson	subj = SLOT(cred->cr_label);
2103119202Srwatson	obj = SLOT(label);
2104119202Srwatson
2105119202Srwatson	if (!mac_biba_dominate_single(subj, obj))
2106119202Srwatson		return (EACCES);
2107119202Srwatson
2108119202Srwatson	return (0);
2109119202Srwatson}
2110119202Srwatson
2111119202Srwatsonstatic int
2112101099Srwatsonmac_biba_check_vnode_exec(struct ucred *cred, struct vnode *vp,
2113106648Srwatson    struct label *label, struct image_params *imgp,
2114106648Srwatson    struct label *execlabel)
2115101099Srwatson{
2116106648Srwatson	struct mac_biba *subj, *obj, *exec;
2117106648Srwatson	int error;
2118101099Srwatson
2119106648Srwatson	if (execlabel != NULL) {
2120106648Srwatson		/*
2121106648Srwatson		 * We currently don't permit labels to be changed at
2122106648Srwatson		 * exec-time as part of Biba, so disallow non-NULL
2123106648Srwatson		 * Biba label elements in the execlabel.
2124106648Srwatson		 */
2125106648Srwatson		exec = SLOT(execlabel);
2126106648Srwatson		error = biba_atmostflags(exec, 0);
2127106648Srwatson		if (error)
2128106648Srwatson			return (error);
2129106648Srwatson	}
2130106648Srwatson
2131101099Srwatson	if (!mac_biba_enabled)
2132101099Srwatson		return (0);
2133101099Srwatson
2134122524Srwatson	subj = SLOT(cred->cr_label);
2135101099Srwatson	obj = SLOT(label);
2136101099Srwatson
2137101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
2138101099Srwatson		return (EACCES);
2139101099Srwatson
2140101099Srwatson	return (0);
2141101099Srwatson}
2142101099Srwatson
2143101099Srwatsonstatic int
2144101099Srwatsonmac_biba_check_vnode_getacl(struct ucred *cred, struct vnode *vp,
2145101099Srwatson    struct label *label, acl_type_t type)
2146101099Srwatson{
2147101099Srwatson	struct mac_biba *subj, *obj;
2148101099Srwatson
2149101099Srwatson	if (!mac_biba_enabled)
2150101099Srwatson		return (0);
2151101099Srwatson
2152122524Srwatson	subj = SLOT(cred->cr_label);
2153101099Srwatson	obj = SLOT(label);
2154101099Srwatson
2155101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
2156101099Srwatson		return (EACCES);
2157101099Srwatson
2158101099Srwatson	return (0);
2159101099Srwatson}
2160101099Srwatson
2161101099Srwatsonstatic int
2162101099Srwatsonmac_biba_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
2163101099Srwatson    struct label *label, int attrnamespace, const char *name, struct uio *uio)
2164101099Srwatson{
2165101099Srwatson	struct mac_biba *subj, *obj;
2166101099Srwatson
2167101099Srwatson	if (!mac_biba_enabled)
2168101099Srwatson		return (0);
2169101099Srwatson
2170122524Srwatson	subj = SLOT(cred->cr_label);
2171101099Srwatson	obj = SLOT(label);
2172101099Srwatson
2173101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
2174101099Srwatson		return (EACCES);
2175101099Srwatson
2176101099Srwatson	return (0);
2177101099Srwatson}
2178101099Srwatson
2179101099Srwatsonstatic int
2180104530Srwatsonmac_biba_check_vnode_link(struct ucred *cred, struct vnode *dvp,
2181104530Srwatson    struct label *dlabel, struct vnode *vp, struct label *label,
2182104530Srwatson    struct componentname *cnp)
2183104530Srwatson{
2184104530Srwatson	struct mac_biba *subj, *obj;
2185104530Srwatson
2186104530Srwatson	if (!mac_biba_enabled)
2187104530Srwatson		return (0);
2188104530Srwatson
2189122524Srwatson	subj = SLOT(cred->cr_label);
2190104530Srwatson	obj = SLOT(dlabel);
2191104530Srwatson
2192104530Srwatson	if (!mac_biba_dominate_single(subj, obj))
2193104530Srwatson		return (EACCES);
2194104530Srwatson
2195104530Srwatson	obj = SLOT(label);
2196104530Srwatson
2197104530Srwatson	if (!mac_biba_dominate_single(subj, obj))
2198104530Srwatson		return (EACCES);
2199104530Srwatson
2200104530Srwatson	return (0);
2201104530Srwatson}
2202104530Srwatson
2203104530Srwatsonstatic int
2204119202Srwatsonmac_biba_check_vnode_listextattr(struct ucred *cred, struct vnode *vp,
2205119202Srwatson    struct label *label, int attrnamespace)
2206119202Srwatson{
2207119202Srwatson	struct mac_biba *subj, *obj;
2208119202Srwatson
2209119202Srwatson	if (!mac_biba_enabled)
2210119202Srwatson		return (0);
2211119202Srwatson
2212122524Srwatson	subj = SLOT(cred->cr_label);
2213119202Srwatson	obj = SLOT(label);
2214119202Srwatson
2215119202Srwatson	if (!mac_biba_dominate_single(obj, subj))
2216119202Srwatson		return (EACCES);
2217119202Srwatson
2218119202Srwatson	return (0);
2219119202Srwatson}
2220119202Srwatson
2221119202Srwatsonstatic int
2222103759Srwatsonmac_biba_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
2223101099Srwatson    struct label *dlabel, struct componentname *cnp)
2224101099Srwatson{
2225101099Srwatson	struct mac_biba *subj, *obj;
2226103759Srwatson
2227101099Srwatson	if (!mac_biba_enabled)
2228101099Srwatson		return (0);
2229103759Srwatson
2230122524Srwatson	subj = SLOT(cred->cr_label);
2231101099Srwatson	obj = SLOT(dlabel);
2232103759Srwatson
2233101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
2234101099Srwatson		return (EACCES);
2235101099Srwatson
2236103759Srwatson	return (0);
2237101099Srwatson}
2238101099Srwatson
2239101099Srwatsonstatic int
2240104546Srwatsonmac_biba_check_vnode_mmap(struct ucred *cred, struct vnode *vp,
2241104546Srwatson    struct label *label, int prot)
2242104546Srwatson{
2243104546Srwatson	struct mac_biba *subj, *obj;
2244104546Srwatson
2245104546Srwatson	/*
2246104546Srwatson	 * Rely on the use of open()-time protections to handle
2247104546Srwatson	 * non-revocation cases.
2248104546Srwatson	 */
2249105637Srwatson	if (!mac_biba_enabled || !revocation_enabled)
2250104546Srwatson		return (0);
2251104546Srwatson
2252122524Srwatson	subj = SLOT(cred->cr_label);
2253104546Srwatson	obj = SLOT(label);
2254104546Srwatson
2255104546Srwatson	if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
2256104546Srwatson		if (!mac_biba_dominate_single(obj, subj))
2257104546Srwatson			return (EACCES);
2258104546Srwatson	}
2259104546Srwatson	if (prot & VM_PROT_WRITE) {
2260104546Srwatson		if (!mac_biba_dominate_single(subj, obj))
2261104546Srwatson			return (EACCES);
2262104546Srwatson	}
2263104546Srwatson
2264104569Srwatson	return (0);
2265104546Srwatson}
2266104546Srwatson
2267104546Srwatsonstatic int
2268101099Srwatsonmac_biba_check_vnode_open(struct ucred *cred, struct vnode *vp,
2269106212Srwatson    struct label *vnodelabel, int acc_mode)
2270101099Srwatson{
2271101099Srwatson	struct mac_biba *subj, *obj;
2272101099Srwatson
2273101099Srwatson	if (!mac_biba_enabled)
2274101099Srwatson		return (0);
2275101099Srwatson
2276122524Srwatson	subj = SLOT(cred->cr_label);
2277101099Srwatson	obj = SLOT(vnodelabel);
2278101099Srwatson
2279101099Srwatson	/* XXX privilege override for admin? */
2280101099Srwatson	if (acc_mode & (VREAD | VEXEC | VSTAT)) {
2281101099Srwatson		if (!mac_biba_dominate_single(obj, subj))
2282101099Srwatson			return (EACCES);
2283101099Srwatson	}
2284101099Srwatson	if (acc_mode & (VWRITE | VAPPEND | VADMIN)) {
2285101099Srwatson		if (!mac_biba_dominate_single(subj, obj))
2286101099Srwatson			return (EACCES);
2287101099Srwatson	}
2288101099Srwatson
2289101099Srwatson	return (0);
2290101099Srwatson}
2291101099Srwatson
2292101099Srwatsonstatic int
2293102129Srwatsonmac_biba_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred,
2294102129Srwatson    struct vnode *vp, struct label *label)
2295102112Srwatson{
2296102112Srwatson	struct mac_biba *subj, *obj;
2297102112Srwatson
2298105637Srwatson	if (!mac_biba_enabled || !revocation_enabled)
2299102112Srwatson		return (0);
2300102112Srwatson
2301122524Srwatson	subj = SLOT(active_cred->cr_label);
2302102112Srwatson	obj = SLOT(label);
2303102112Srwatson
2304102112Srwatson	if (!mac_biba_dominate_single(obj, subj))
2305102112Srwatson		return (EACCES);
2306102112Srwatson
2307102112Srwatson	return (0);
2308102112Srwatson}
2309102112Srwatson
2310102112Srwatsonstatic int
2311102129Srwatsonmac_biba_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
2312102129Srwatson    struct vnode *vp, struct label *label)
2313102112Srwatson{
2314102112Srwatson	struct mac_biba *subj, *obj;
2315102112Srwatson
2316105637Srwatson	if (!mac_biba_enabled || !revocation_enabled)
2317102112Srwatson		return (0);
2318102112Srwatson
2319122524Srwatson	subj = SLOT(active_cred->cr_label);
2320102112Srwatson	obj = SLOT(label);
2321102112Srwatson
2322102112Srwatson	if (!mac_biba_dominate_single(obj, subj))
2323102112Srwatson		return (EACCES);
2324102112Srwatson
2325102112Srwatson	return (0);
2326102112Srwatson}
2327102112Srwatson
2328102112Srwatsonstatic int
2329101099Srwatsonmac_biba_check_vnode_readdir(struct ucred *cred, struct vnode *dvp,
2330101099Srwatson    struct label *dlabel)
2331101099Srwatson{
2332101099Srwatson	struct mac_biba *subj, *obj;
2333101099Srwatson
2334101099Srwatson	if (!mac_biba_enabled)
2335101099Srwatson		return (0);
2336101099Srwatson
2337122524Srwatson	subj = SLOT(cred->cr_label);
2338101099Srwatson	obj = SLOT(dlabel);
2339101099Srwatson
2340101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
2341101099Srwatson		return (EACCES);
2342101099Srwatson
2343101099Srwatson	return (0);
2344101099Srwatson}
2345101099Srwatson
2346101099Srwatsonstatic int
2347101099Srwatsonmac_biba_check_vnode_readlink(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
2355122524Srwatson	subj = SLOT(cred->cr_label);
2356101099Srwatson	obj = SLOT(label);
2357101099Srwatson
2358101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
2359101099Srwatson		return (EACCES);
2360101099Srwatson
2361101099Srwatson	return (0);
2362101099Srwatson}
2363101099Srwatson
2364101099Srwatsonstatic int
2365101099Srwatsonmac_biba_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
2366101099Srwatson    struct label *vnodelabel, struct label *newlabel)
2367101099Srwatson{
2368101099Srwatson	struct mac_biba *old, *new, *subj;
2369105634Srwatson	int error;
2370101099Srwatson
2371101099Srwatson	old = SLOT(vnodelabel);
2372101099Srwatson	new = SLOT(newlabel);
2373122524Srwatson	subj = SLOT(cred->cr_label);
2374101099Srwatson
2375101099Srwatson	/*
2376105634Srwatson	 * If there is a Biba label update for the vnode, it must be a
2377105634Srwatson	 * single label.
2378101099Srwatson	 */
2379105634Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE);
2380105634Srwatson	if (error)
2381105634Srwatson		return (error);
2382101099Srwatson
2383101099Srwatson	/*
2384105634Srwatson	 * To perform a relabel of the vnode (Biba label or not), Biba must
2385105634Srwatson	 * authorize the relabel.
2386101099Srwatson	 */
2387105634Srwatson	if (!mac_biba_single_in_range(old, subj))
2388101099Srwatson		return (EPERM);
2389101099Srwatson
2390101099Srwatson	/*
2391105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
2392101099Srwatson	 */
2393105634Srwatson	if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) {
2394105634Srwatson		/*
2395105634Srwatson		 * To change the Biba label on a vnode, the new vnode label
2396105634Srwatson		 * must be in the subject range.
2397105634Srwatson		 */
2398105634Srwatson		if (!mac_biba_single_in_range(new, subj))
2399105634Srwatson			return (EPERM);
2400101099Srwatson
2401105634Srwatson		/*
2402105634Srwatson		 * To change the Biba label on the vnode to be EQUAL,
2403105634Srwatson		 * the subject must have appropriate privilege.
2404105634Srwatson		 */
2405105634Srwatson		if (mac_biba_contains_equal(new)) {
2406106090Srwatson			error = mac_biba_subject_privileged(subj);
2407105634Srwatson			if (error)
2408105634Srwatson				return (error);
2409105634Srwatson		}
2410105634Srwatson	}
2411105634Srwatson
2412105634Srwatson	return (0);
2413101099Srwatson}
2414101099Srwatson
2415101099Srwatsonstatic int
2416101099Srwatsonmac_biba_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
2417101099Srwatson    struct label *dlabel, struct vnode *vp, struct label *label,
2418101099Srwatson    struct componentname *cnp)
2419101099Srwatson{
2420101099Srwatson	struct mac_biba *subj, *obj;
2421101099Srwatson
2422101099Srwatson	if (!mac_biba_enabled)
2423101099Srwatson		return (0);
2424101099Srwatson
2425122524Srwatson	subj = SLOT(cred->cr_label);
2426101099Srwatson	obj = SLOT(dlabel);
2427101099Srwatson
2428101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2429101099Srwatson		return (EACCES);
2430101099Srwatson
2431101099Srwatson	obj = SLOT(label);
2432101099Srwatson
2433101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2434101099Srwatson		return (EACCES);
2435101099Srwatson
2436101099Srwatson	return (0);
2437101099Srwatson}
2438101099Srwatson
2439101099Srwatsonstatic int
2440101099Srwatsonmac_biba_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
2441101099Srwatson    struct label *dlabel, struct vnode *vp, struct label *label, int samedir,
2442101099Srwatson    struct componentname *cnp)
2443101099Srwatson{
2444101099Srwatson	struct mac_biba *subj, *obj;
2445101099Srwatson
2446101099Srwatson	if (!mac_biba_enabled)
2447101099Srwatson		return (0);
2448101099Srwatson
2449122524Srwatson	subj = SLOT(cred->cr_label);
2450101099Srwatson	obj = SLOT(dlabel);
2451101099Srwatson
2452101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2453101099Srwatson		return (EACCES);
2454101099Srwatson
2455101099Srwatson	if (vp != NULL) {
2456101099Srwatson		obj = SLOT(label);
2457101099Srwatson
2458101099Srwatson		if (!mac_biba_dominate_single(subj, obj))
2459101099Srwatson			return (EACCES);
2460101099Srwatson	}
2461101099Srwatson
2462101099Srwatson	return (0);
2463101099Srwatson}
2464101099Srwatson
2465101099Srwatsonstatic int
2466101099Srwatsonmac_biba_check_vnode_revoke(struct ucred *cred, struct vnode *vp,
2467101099Srwatson    struct label *label)
2468101099Srwatson{
2469101099Srwatson	struct mac_biba *subj, *obj;
2470101099Srwatson
2471101099Srwatson	if (!mac_biba_enabled)
2472101099Srwatson		return (0);
2473101099Srwatson
2474122524Srwatson	subj = SLOT(cred->cr_label);
2475101099Srwatson	obj = SLOT(label);
2476101099Srwatson
2477101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2478101099Srwatson		return (EACCES);
2479101099Srwatson
2480101099Srwatson	return (0);
2481101099Srwatson}
2482101099Srwatson
2483101099Srwatsonstatic int
2484101099Srwatsonmac_biba_check_vnode_setacl(struct ucred *cred, struct vnode *vp,
2485101099Srwatson    struct label *label, acl_type_t type, struct acl *acl)
2486101099Srwatson{
2487101099Srwatson	struct mac_biba *subj, *obj;
2488101099Srwatson
2489101099Srwatson	if (!mac_biba_enabled)
2490101099Srwatson		return (0);
2491101099Srwatson
2492122524Srwatson	subj = SLOT(cred->cr_label);
2493101099Srwatson	obj = SLOT(label);
2494101099Srwatson
2495101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2496101099Srwatson		return (EACCES);
2497101099Srwatson
2498101099Srwatson	return (0);
2499101099Srwatson}
2500101099Srwatson
2501101099Srwatsonstatic int
2502101099Srwatsonmac_biba_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
2503101099Srwatson    struct label *vnodelabel, int attrnamespace, const char *name,
2504101099Srwatson    struct uio *uio)
2505101099Srwatson{
2506101099Srwatson	struct mac_biba *subj, *obj;
2507101099Srwatson
2508101099Srwatson	if (!mac_biba_enabled)
2509101099Srwatson		return (0);
2510101099Srwatson
2511122524Srwatson	subj = SLOT(cred->cr_label);
2512101099Srwatson	obj = SLOT(vnodelabel);
2513101099Srwatson
2514101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2515101099Srwatson		return (EACCES);
2516101099Srwatson
2517101099Srwatson	/* XXX: protect the MAC EA in a special way? */
2518101099Srwatson
2519101099Srwatson	return (0);
2520101099Srwatson}
2521101099Srwatson
2522101099Srwatsonstatic int
2523101099Srwatsonmac_biba_check_vnode_setflags(struct ucred *cred, struct vnode *vp,
2524101099Srwatson    struct label *vnodelabel, u_long flags)
2525101099Srwatson{
2526101099Srwatson	struct mac_biba *subj, *obj;
2527101099Srwatson
2528101099Srwatson	if (!mac_biba_enabled)
2529101099Srwatson		return (0);
2530101099Srwatson
2531122524Srwatson	subj = SLOT(cred->cr_label);
2532101099Srwatson	obj = SLOT(vnodelabel);
2533101099Srwatson
2534101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2535101099Srwatson		return (EACCES);
2536101099Srwatson
2537101099Srwatson	return (0);
2538101099Srwatson}
2539101099Srwatson
2540101099Srwatsonstatic int
2541101099Srwatsonmac_biba_check_vnode_setmode(struct ucred *cred, struct vnode *vp,
2542101099Srwatson    struct label *vnodelabel, mode_t mode)
2543101099Srwatson{
2544101099Srwatson	struct mac_biba *subj, *obj;
2545101099Srwatson
2546101099Srwatson	if (!mac_biba_enabled)
2547101099Srwatson		return (0);
2548101099Srwatson
2549122524Srwatson	subj = SLOT(cred->cr_label);
2550101099Srwatson	obj = SLOT(vnodelabel);
2551101099Srwatson
2552101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2553101099Srwatson		return (EACCES);
2554101099Srwatson
2555101099Srwatson	return (0);
2556101099Srwatson}
2557101099Srwatson
2558101099Srwatsonstatic int
2559101099Srwatsonmac_biba_check_vnode_setowner(struct ucred *cred, struct vnode *vp,
2560101099Srwatson    struct label *vnodelabel, uid_t uid, gid_t gid)
2561101099Srwatson{
2562101099Srwatson	struct mac_biba *subj, *obj;
2563101099Srwatson
2564101099Srwatson	if (!mac_biba_enabled)
2565101099Srwatson		return (0);
2566101099Srwatson
2567122524Srwatson	subj = SLOT(cred->cr_label);
2568101099Srwatson	obj = SLOT(vnodelabel);
2569101099Srwatson
2570101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2571101099Srwatson		return (EACCES);
2572101099Srwatson
2573101099Srwatson	return (0);
2574101099Srwatson}
2575101099Srwatson
2576101099Srwatsonstatic int
2577101099Srwatsonmac_biba_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
2578101099Srwatson    struct label *vnodelabel, struct timespec atime, struct timespec mtime)
2579101099Srwatson{
2580101099Srwatson	struct mac_biba *subj, *obj;
2581101099Srwatson
2582101099Srwatson	if (!mac_biba_enabled)
2583101099Srwatson		return (0);
2584101099Srwatson
2585122524Srwatson	subj = SLOT(cred->cr_label);
2586101099Srwatson	obj = SLOT(vnodelabel);
2587101099Srwatson
2588101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2589101099Srwatson		return (EACCES);
2590101099Srwatson
2591101099Srwatson	return (0);
2592101099Srwatson}
2593101099Srwatson
2594101099Srwatsonstatic int
2595102129Srwatsonmac_biba_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
2596102129Srwatson    struct vnode *vp, struct label *vnodelabel)
2597101099Srwatson{
2598101099Srwatson	struct mac_biba *subj, *obj;
2599101099Srwatson
2600101099Srwatson	if (!mac_biba_enabled)
2601101099Srwatson		return (0);
2602101099Srwatson
2603122524Srwatson	subj = SLOT(active_cred->cr_label);
2604101099Srwatson	obj = SLOT(vnodelabel);
2605101099Srwatson
2606101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
2607101099Srwatson		return (EACCES);
2608101099Srwatson
2609101099Srwatson	return (0);
2610101099Srwatson}
2611101099Srwatson
2612102112Srwatsonstatic int
2613102129Srwatsonmac_biba_check_vnode_write(struct ucred *active_cred,
2614102129Srwatson    struct ucred *file_cred, struct vnode *vp, struct label *label)
2615102112Srwatson{
2616102112Srwatson	struct mac_biba *subj, *obj;
2617102112Srwatson
2618105637Srwatson	if (!mac_biba_enabled || !revocation_enabled)
2619102112Srwatson		return (0);
2620102112Srwatson
2621122524Srwatson	subj = SLOT(active_cred->cr_label);
2622102112Srwatson	obj = SLOT(label);
2623102112Srwatson
2624102112Srwatson	if (!mac_biba_dominate_single(subj, obj))
2625102112Srwatson		return (EACCES);
2626102112Srwatson
2627102112Srwatson	return (0);
2628102112Srwatson}
2629102112Srwatson
2630106217Srwatsonstatic struct mac_policy_ops mac_biba_ops =
2631101099Srwatson{
2632106217Srwatson	.mpo_init = mac_biba_init,
2633106217Srwatson	.mpo_init_bpfdesc_label = mac_biba_init_label,
2634106217Srwatson	.mpo_init_cred_label = mac_biba_init_label,
2635106217Srwatson	.mpo_init_devfsdirent_label = mac_biba_init_label,
2636106217Srwatson	.mpo_init_ifnet_label = mac_biba_init_label,
2637122875Srwatson	.mpo_init_inpcb_label = mac_biba_init_label_waitcheck,
2638112675Srwatson	.mpo_init_ipq_label = mac_biba_init_label_waitcheck,
2639106217Srwatson	.mpo_init_mbuf_label = mac_biba_init_label_waitcheck,
2640106217Srwatson	.mpo_init_mount_label = mac_biba_init_label,
2641106217Srwatson	.mpo_init_mount_fs_label = mac_biba_init_label,
2642106217Srwatson	.mpo_init_pipe_label = mac_biba_init_label,
2643106217Srwatson	.mpo_init_socket_label = mac_biba_init_label_waitcheck,
2644106217Srwatson	.mpo_init_socket_peer_label = mac_biba_init_label_waitcheck,
2645106217Srwatson	.mpo_init_vnode_label = mac_biba_init_label,
2646106217Srwatson	.mpo_destroy_bpfdesc_label = mac_biba_destroy_label,
2647106217Srwatson	.mpo_destroy_cred_label = mac_biba_destroy_label,
2648106217Srwatson	.mpo_destroy_devfsdirent_label = mac_biba_destroy_label,
2649106217Srwatson	.mpo_destroy_ifnet_label = mac_biba_destroy_label,
2650122875Srwatson	.mpo_destroy_inpcb_label = mac_biba_destroy_label,
2651106217Srwatson	.mpo_destroy_ipq_label = mac_biba_destroy_label,
2652106217Srwatson	.mpo_destroy_mbuf_label = mac_biba_destroy_label,
2653106217Srwatson	.mpo_destroy_mount_label = mac_biba_destroy_label,
2654106217Srwatson	.mpo_destroy_mount_fs_label = mac_biba_destroy_label,
2655106217Srwatson	.mpo_destroy_pipe_label = mac_biba_destroy_label,
2656106217Srwatson	.mpo_destroy_socket_label = mac_biba_destroy_label,
2657106217Srwatson	.mpo_destroy_socket_peer_label = mac_biba_destroy_label,
2658106217Srwatson	.mpo_destroy_vnode_label = mac_biba_destroy_label,
2659123173Srwatson	.mpo_copy_cred_label = mac_biba_copy_label,
2660115707Srwatson	.mpo_copy_mbuf_label = mac_biba_copy_label,
2661106217Srwatson	.mpo_copy_pipe_label = mac_biba_copy_label,
2662122820Srwatson	.mpo_copy_socket_label = mac_biba_copy_label,
2663106217Srwatson	.mpo_copy_vnode_label = mac_biba_copy_label,
2664106217Srwatson	.mpo_externalize_cred_label = mac_biba_externalize_label,
2665106217Srwatson	.mpo_externalize_ifnet_label = mac_biba_externalize_label,
2666106217Srwatson	.mpo_externalize_pipe_label = mac_biba_externalize_label,
2667106217Srwatson	.mpo_externalize_socket_label = mac_biba_externalize_label,
2668106217Srwatson	.mpo_externalize_socket_peer_label = mac_biba_externalize_label,
2669106217Srwatson	.mpo_externalize_vnode_label = mac_biba_externalize_label,
2670106217Srwatson	.mpo_internalize_cred_label = mac_biba_internalize_label,
2671106217Srwatson	.mpo_internalize_ifnet_label = mac_biba_internalize_label,
2672106217Srwatson	.mpo_internalize_pipe_label = mac_biba_internalize_label,
2673106217Srwatson	.mpo_internalize_socket_label = mac_biba_internalize_label,
2674106217Srwatson	.mpo_internalize_vnode_label = mac_biba_internalize_label,
2675106217Srwatson	.mpo_create_devfs_device = mac_biba_create_devfs_device,
2676106217Srwatson	.mpo_create_devfs_directory = mac_biba_create_devfs_directory,
2677106217Srwatson	.mpo_create_devfs_symlink = mac_biba_create_devfs_symlink,
2678106217Srwatson	.mpo_create_mount = mac_biba_create_mount,
2679106217Srwatson	.mpo_create_root_mount = mac_biba_create_root_mount,
2680106217Srwatson	.mpo_relabel_vnode = mac_biba_relabel_vnode,
2681106217Srwatson	.mpo_update_devfsdirent = mac_biba_update_devfsdirent,
2682106217Srwatson	.mpo_associate_vnode_devfs = mac_biba_associate_vnode_devfs,
2683106217Srwatson	.mpo_associate_vnode_extattr = mac_biba_associate_vnode_extattr,
2684106217Srwatson	.mpo_associate_vnode_singlelabel = mac_biba_associate_vnode_singlelabel,
2685106217Srwatson	.mpo_create_vnode_extattr = mac_biba_create_vnode_extattr,
2686106217Srwatson	.mpo_setlabel_vnode_extattr = mac_biba_setlabel_vnode_extattr,
2687106217Srwatson	.mpo_create_mbuf_from_socket = mac_biba_create_mbuf_from_socket,
2688106217Srwatson	.mpo_create_pipe = mac_biba_create_pipe,
2689106217Srwatson	.mpo_create_socket = mac_biba_create_socket,
2690106217Srwatson	.mpo_create_socket_from_socket = mac_biba_create_socket_from_socket,
2691106217Srwatson	.mpo_relabel_pipe = mac_biba_relabel_pipe,
2692106217Srwatson	.mpo_relabel_socket = mac_biba_relabel_socket,
2693106217Srwatson	.mpo_set_socket_peer_from_mbuf = mac_biba_set_socket_peer_from_mbuf,
2694106217Srwatson	.mpo_set_socket_peer_from_socket = mac_biba_set_socket_peer_from_socket,
2695106217Srwatson	.mpo_create_bpfdesc = mac_biba_create_bpfdesc,
2696106217Srwatson	.mpo_create_datagram_from_ipq = mac_biba_create_datagram_from_ipq,
2697106217Srwatson	.mpo_create_fragment = mac_biba_create_fragment,
2698106217Srwatson	.mpo_create_ifnet = mac_biba_create_ifnet,
2699122875Srwatson	.mpo_create_inpcb_from_socket = mac_biba_create_inpcb_from_socket,
2700106217Srwatson	.mpo_create_ipq = mac_biba_create_ipq,
2701106217Srwatson	.mpo_create_mbuf_from_mbuf = mac_biba_create_mbuf_from_mbuf,
2702106217Srwatson	.mpo_create_mbuf_linklayer = mac_biba_create_mbuf_linklayer,
2703106217Srwatson	.mpo_create_mbuf_from_bpfdesc = mac_biba_create_mbuf_from_bpfdesc,
2704106217Srwatson	.mpo_create_mbuf_from_ifnet = mac_biba_create_mbuf_from_ifnet,
2705106217Srwatson	.mpo_create_mbuf_multicast_encap = mac_biba_create_mbuf_multicast_encap,
2706106217Srwatson	.mpo_create_mbuf_netlayer = mac_biba_create_mbuf_netlayer,
2707106217Srwatson	.mpo_fragment_match = mac_biba_fragment_match,
2708106217Srwatson	.mpo_relabel_ifnet = mac_biba_relabel_ifnet,
2709106217Srwatson	.mpo_update_ipq = mac_biba_update_ipq,
2710122875Srwatson	.mpo_inpcb_sosetlabel = mac_biba_inpcb_sosetlabel,
2711106217Srwatson	.mpo_create_proc0 = mac_biba_create_proc0,
2712106217Srwatson	.mpo_create_proc1 = mac_biba_create_proc1,
2713106217Srwatson	.mpo_relabel_cred = mac_biba_relabel_cred,
2714106217Srwatson	.mpo_check_bpfdesc_receive = mac_biba_check_bpfdesc_receive,
2715106217Srwatson	.mpo_check_cred_relabel = mac_biba_check_cred_relabel,
2716106217Srwatson	.mpo_check_cred_visible = mac_biba_check_cred_visible,
2717106217Srwatson	.mpo_check_ifnet_relabel = mac_biba_check_ifnet_relabel,
2718106217Srwatson	.mpo_check_ifnet_transmit = mac_biba_check_ifnet_transmit,
2719122875Srwatson	.mpo_check_inpcb_deliver = mac_biba_check_inpcb_deliver,
2720110354Srwatson	.mpo_check_kld_load = mac_biba_check_kld_load,
2721110354Srwatson	.mpo_check_kld_unload = mac_biba_check_kld_unload,
2722106217Srwatson	.mpo_check_mount_stat = mac_biba_check_mount_stat,
2723106217Srwatson	.mpo_check_pipe_ioctl = mac_biba_check_pipe_ioctl,
2724106217Srwatson	.mpo_check_pipe_poll = mac_biba_check_pipe_poll,
2725106217Srwatson	.mpo_check_pipe_read = mac_biba_check_pipe_read,
2726106217Srwatson	.mpo_check_pipe_relabel = mac_biba_check_pipe_relabel,
2727106217Srwatson	.mpo_check_pipe_stat = mac_biba_check_pipe_stat,
2728106217Srwatson	.mpo_check_pipe_write = mac_biba_check_pipe_write,
2729106217Srwatson	.mpo_check_proc_debug = mac_biba_check_proc_debug,
2730106217Srwatson	.mpo_check_proc_sched = mac_biba_check_proc_sched,
2731106217Srwatson	.mpo_check_proc_signal = mac_biba_check_proc_signal,
2732106217Srwatson	.mpo_check_socket_deliver = mac_biba_check_socket_deliver,
2733106217Srwatson	.mpo_check_socket_relabel = mac_biba_check_socket_relabel,
2734106217Srwatson	.mpo_check_socket_visible = mac_biba_check_socket_visible,
2735112574Srwatson	.mpo_check_sysarch_ioperm = mac_biba_check_sysarch_ioperm,
2736106418Srwatson	.mpo_check_system_acct = mac_biba_check_system_acct,
2737106418Srwatson	.mpo_check_system_settime = mac_biba_check_system_settime,
2738106217Srwatson	.mpo_check_system_swapon = mac_biba_check_system_swapon,
2739112574Srwatson	.mpo_check_system_swapoff = mac_biba_check_system_swapoff,
2740106217Srwatson	.mpo_check_system_sysctl = mac_biba_check_system_sysctl,
2741106217Srwatson	.mpo_check_vnode_access = mac_biba_check_vnode_open,
2742106217Srwatson	.mpo_check_vnode_chdir = mac_biba_check_vnode_chdir,
2743106217Srwatson	.mpo_check_vnode_chroot = mac_biba_check_vnode_chroot,
2744106217Srwatson	.mpo_check_vnode_create = mac_biba_check_vnode_create,
2745106217Srwatson	.mpo_check_vnode_delete = mac_biba_check_vnode_delete,
2746106217Srwatson	.mpo_check_vnode_deleteacl = mac_biba_check_vnode_deleteacl,
2747119202Srwatson	.mpo_check_vnode_deleteextattr = mac_biba_check_vnode_deleteextattr,
2748106217Srwatson	.mpo_check_vnode_exec = mac_biba_check_vnode_exec,
2749106217Srwatson	.mpo_check_vnode_getacl = mac_biba_check_vnode_getacl,
2750106217Srwatson	.mpo_check_vnode_getextattr = mac_biba_check_vnode_getextattr,
2751106217Srwatson	.mpo_check_vnode_link = mac_biba_check_vnode_link,
2752119202Srwatson	.mpo_check_vnode_listextattr = mac_biba_check_vnode_listextattr,
2753106217Srwatson	.mpo_check_vnode_lookup = mac_biba_check_vnode_lookup,
2754106217Srwatson	.mpo_check_vnode_mmap = mac_biba_check_vnode_mmap,
2755106217Srwatson	.mpo_check_vnode_mprotect = mac_biba_check_vnode_mmap,
2756106217Srwatson	.mpo_check_vnode_open = mac_biba_check_vnode_open,
2757106217Srwatson	.mpo_check_vnode_poll = mac_biba_check_vnode_poll,
2758106217Srwatson	.mpo_check_vnode_read = mac_biba_check_vnode_read,
2759106217Srwatson	.mpo_check_vnode_readdir = mac_biba_check_vnode_readdir,
2760106217Srwatson	.mpo_check_vnode_readlink = mac_biba_check_vnode_readlink,
2761106217Srwatson	.mpo_check_vnode_relabel = mac_biba_check_vnode_relabel,
2762106217Srwatson	.mpo_check_vnode_rename_from = mac_biba_check_vnode_rename_from,
2763106217Srwatson	.mpo_check_vnode_rename_to = mac_biba_check_vnode_rename_to,
2764106217Srwatson	.mpo_check_vnode_revoke = mac_biba_check_vnode_revoke,
2765106217Srwatson	.mpo_check_vnode_setacl = mac_biba_check_vnode_setacl,
2766106217Srwatson	.mpo_check_vnode_setextattr = mac_biba_check_vnode_setextattr,
2767106217Srwatson	.mpo_check_vnode_setflags = mac_biba_check_vnode_setflags,
2768106217Srwatson	.mpo_check_vnode_setmode = mac_biba_check_vnode_setmode,
2769106217Srwatson	.mpo_check_vnode_setowner = mac_biba_check_vnode_setowner,
2770106217Srwatson	.mpo_check_vnode_setutimes = mac_biba_check_vnode_setutimes,
2771106217Srwatson	.mpo_check_vnode_stat = mac_biba_check_vnode_stat,
2772106217Srwatson	.mpo_check_vnode_write = mac_biba_check_vnode_write,
2773101099Srwatson};
2774101099Srwatson
2775112717SrwatsonMAC_POLICY_SET(&mac_biba_ops, mac_biba, "TrustedBSD MAC/Biba",
2776113531Srwatson    MPC_LOADTIME_FLAG_NOTLATE | MPC_LOADTIME_FLAG_LABELMBUFS, &mac_biba_slot);
2777