mac_biba.c revision 115707
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 115707 2003-06-02 17:21:38Z 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>
72101099Srwatson#include <netinet/ip_var.h>
73101099Srwatson
74101099Srwatson#include <vm/vm.h>
75101099Srwatson
76101099Srwatson#include <sys/mac_policy.h>
77101099Srwatson
78101099Srwatson#include <security/mac_biba/mac_biba.h>
79101099Srwatson
80101099SrwatsonSYSCTL_DECL(_security_mac);
81101099Srwatson
82101099SrwatsonSYSCTL_NODE(_security_mac, OID_AUTO, biba, CTLFLAG_RW, 0,
83101099Srwatson    "TrustedBSD mac_biba policy controls");
84101099Srwatson
85105988Srwatsonstatic int	mac_biba_label_size = sizeof(struct mac_biba);
86105988SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, label_size, CTLFLAG_RD,
87105988Srwatson    &mac_biba_label_size, 0, "Size of struct mac_biba");
88105988Srwatson
89107731Srwatsonstatic int	mac_biba_enabled = 1;
90101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, enabled, CTLFLAG_RW,
91101099Srwatson    &mac_biba_enabled, 0, "Enforce MAC/Biba policy");
92102980SrwatsonTUNABLE_INT("security.mac.biba.enabled", &mac_biba_enabled);
93101099Srwatson
94101099Srwatsonstatic int	destroyed_not_inited;
95101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, destroyed_not_inited, CTLFLAG_RD,
96101099Srwatson    &destroyed_not_inited, 0, "Count of labels destroyed but not inited");
97101099Srwatson
98101099Srwatsonstatic int	trust_all_interfaces = 0;
99101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, trust_all_interfaces, CTLFLAG_RD,
100101099Srwatson    &trust_all_interfaces, 0, "Consider all interfaces 'trusted' by MAC/Biba");
101101099SrwatsonTUNABLE_INT("security.mac.biba.trust_all_interfaces", &trust_all_interfaces);
102101099Srwatson
103101099Srwatsonstatic char	trusted_interfaces[128];
104101099SrwatsonSYSCTL_STRING(_security_mac_biba, OID_AUTO, trusted_interfaces, CTLFLAG_RD,
105101099Srwatson    trusted_interfaces, 0, "Interfaces considered 'trusted' by MAC/Biba");
106101099SrwatsonTUNABLE_STR("security.mac.biba.trusted_interfaces", trusted_interfaces,
107101099Srwatson    sizeof(trusted_interfaces));
108101099Srwatson
109105643Srwatsonstatic int	max_compartments = MAC_BIBA_MAX_COMPARTMENTS;
110105643SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, max_compartments, CTLFLAG_RD,
111105643Srwatson    &max_compartments, 0, "Maximum supported compartments");
112105643Srwatson
113105606Srwatsonstatic int	ptys_equal = 0;
114105606SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, ptys_equal, CTLFLAG_RW,
115105606Srwatson    &ptys_equal, 0, "Label pty devices as biba/equal on create");
116105606SrwatsonTUNABLE_INT("security.mac.biba.ptys_equal", &ptys_equal);
117105606Srwatson
118105637Srwatsonstatic int	revocation_enabled = 0;
119101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, revocation_enabled, CTLFLAG_RW,
120105637Srwatson    &revocation_enabled, 0, "Revoke access to objects on relabel");
121105637SrwatsonTUNABLE_INT("security.mac.biba.revocation_enabled", &revocation_enabled);
122101099Srwatson
123101099Srwatsonstatic int	mac_biba_slot;
124101099Srwatson#define	SLOT(l)	((struct mac_biba *)LABEL_TO_SLOT((l), mac_biba_slot).l_ptr)
125101099Srwatson
126101099SrwatsonMALLOC_DEFINE(M_MACBIBA, "biba label", "MAC/Biba labels");
127101099Srwatson
128105643Srwatsonstatic __inline int
129105643Srwatsonbiba_bit_set_empty(u_char *set) {
130105643Srwatson	int i;
131105643Srwatson
132105643Srwatson	for (i = 0; i < MAC_BIBA_MAX_COMPARTMENTS >> 3; i++)
133105643Srwatson		if (set[i] != 0)
134105643Srwatson			return (0);
135105643Srwatson	return (1);
136105643Srwatson}
137105643Srwatson
138101099Srwatsonstatic struct mac_biba *
139104514Srwatsonbiba_alloc(int flag)
140101099Srwatson{
141101099Srwatson	struct mac_biba *mac_biba;
142101099Srwatson
143104514Srwatson	mac_biba = malloc(sizeof(struct mac_biba), M_MACBIBA, M_ZERO | flag);
144101099Srwatson
145101099Srwatson	return (mac_biba);
146101099Srwatson}
147101099Srwatson
148101099Srwatsonstatic void
149101099Srwatsonbiba_free(struct mac_biba *mac_biba)
150101099Srwatson{
151101099Srwatson
152101099Srwatson	if (mac_biba != NULL)
153101099Srwatson		free(mac_biba, M_MACBIBA);
154101099Srwatson	else
155101099Srwatson		atomic_add_int(&destroyed_not_inited, 1);
156101099Srwatson}
157101099Srwatson
158101099Srwatsonstatic int
159105634Srwatsonbiba_atmostflags(struct mac_biba *mac_biba, int flags)
160105634Srwatson{
161105634Srwatson
162105634Srwatson	if ((mac_biba->mb_flags & flags) != mac_biba->mb_flags)
163105634Srwatson		return (EINVAL);
164105634Srwatson	return (0);
165105634Srwatson}
166105634Srwatson
167105634Srwatsonstatic int
168101099Srwatsonmac_biba_dominate_element(struct mac_biba_element *a,
169101099Srwatson    struct mac_biba_element *b)
170101099Srwatson{
171105643Srwatson	int bit;
172101099Srwatson
173105736Srwatson	switch (a->mbe_type) {
174101099Srwatson	case MAC_BIBA_TYPE_EQUAL:
175101099Srwatson	case MAC_BIBA_TYPE_HIGH:
176101099Srwatson		return (1);
177101099Srwatson
178101099Srwatson	case MAC_BIBA_TYPE_LOW:
179101099Srwatson		switch (b->mbe_type) {
180101099Srwatson		case MAC_BIBA_TYPE_GRADE:
181101099Srwatson		case MAC_BIBA_TYPE_HIGH:
182101099Srwatson			return (0);
183101099Srwatson
184101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
185101099Srwatson		case MAC_BIBA_TYPE_LOW:
186101099Srwatson			return (1);
187101099Srwatson
188101099Srwatson		default:
189101099Srwatson			panic("mac_biba_dominate_element: b->mbe_type invalid");
190101099Srwatson		}
191101099Srwatson
192101099Srwatson	case MAC_BIBA_TYPE_GRADE:
193101099Srwatson		switch (b->mbe_type) {
194101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
195101099Srwatson		case MAC_BIBA_TYPE_LOW:
196101099Srwatson			return (1);
197101099Srwatson
198101099Srwatson		case MAC_BIBA_TYPE_HIGH:
199101099Srwatson			return (0);
200101099Srwatson
201101099Srwatson		case MAC_BIBA_TYPE_GRADE:
202105643Srwatson			for (bit = 1; bit <= MAC_BIBA_MAX_COMPARTMENTS; bit++)
203105643Srwatson				if (!MAC_BIBA_BIT_TEST(bit,
204105643Srwatson				    a->mbe_compartments) &&
205105643Srwatson				    MAC_BIBA_BIT_TEST(bit, b->mbe_compartments))
206105643Srwatson					return (0);
207101099Srwatson			return (a->mbe_grade >= b->mbe_grade);
208101099Srwatson
209101099Srwatson		default:
210101099Srwatson			panic("mac_biba_dominate_element: b->mbe_type invalid");
211101099Srwatson		}
212101099Srwatson
213101099Srwatson	default:
214101099Srwatson		panic("mac_biba_dominate_element: a->mbe_type invalid");
215101099Srwatson	}
216101099Srwatson
217101099Srwatson	return (0);
218101099Srwatson}
219101099Srwatson
220101099Srwatsonstatic int
221105988Srwatsonmac_biba_subject_dominate_high(struct mac_biba *mac_biba)
222105988Srwatson{
223105988Srwatson	struct mac_biba_element *element;
224105988Srwatson
225106174Srwatson	KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
226105988Srwatson	    ("mac_biba_single_in_range: mac_biba not single"));
227105988Srwatson	element = &mac_biba->mb_single;
228105988Srwatson
229105988Srwatson	return (element->mbe_type == MAC_BIBA_TYPE_EQUAL ||
230105988Srwatson	    element->mbe_type == MAC_BIBA_TYPE_HIGH);
231105988Srwatson}
232105988Srwatson
233105988Srwatsonstatic int
234101099Srwatsonmac_biba_range_in_range(struct mac_biba *rangea, struct mac_biba *rangeb)
235101099Srwatson{
236101099Srwatson
237101099Srwatson	return (mac_biba_dominate_element(&rangeb->mb_rangehigh,
238101099Srwatson	    &rangea->mb_rangehigh) &&
239101099Srwatson	    mac_biba_dominate_element(&rangea->mb_rangelow,
240101099Srwatson	    &rangeb->mb_rangelow));
241101099Srwatson}
242101099Srwatson
243101099Srwatsonstatic int
244101099Srwatsonmac_biba_single_in_range(struct mac_biba *single, struct mac_biba *range)
245101099Srwatson{
246101099Srwatson
247103750Srwatson	KASSERT((single->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
248101099Srwatson	    ("mac_biba_single_in_range: a not single"));
249103750Srwatson	KASSERT((range->mb_flags & MAC_BIBA_FLAG_RANGE) != 0,
250101099Srwatson	    ("mac_biba_single_in_range: b not range"));
251101099Srwatson
252101099Srwatson	return (mac_biba_dominate_element(&range->mb_rangehigh,
253101099Srwatson	    &single->mb_single) &&
254101099Srwatson	    mac_biba_dominate_element(&single->mb_single,
255101099Srwatson	    &range->mb_rangelow));
256101099Srwatson
257101099Srwatson	return (1);
258101099Srwatson}
259101099Srwatson
260101099Srwatsonstatic int
261101099Srwatsonmac_biba_dominate_single(struct mac_biba *a, struct mac_biba *b)
262101099Srwatson{
263101099Srwatson	KASSERT((a->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
264101099Srwatson	    ("mac_biba_dominate_single: a not single"));
265101099Srwatson	KASSERT((b->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
266101099Srwatson	    ("mac_biba_dominate_single: b not single"));
267101099Srwatson
268101099Srwatson	return (mac_biba_dominate_element(&a->mb_single, &b->mb_single));
269101099Srwatson}
270101099Srwatson
271101099Srwatsonstatic int
272101099Srwatsonmac_biba_equal_element(struct mac_biba_element *a, struct mac_biba_element *b)
273101099Srwatson{
274101099Srwatson
275101099Srwatson	if (a->mbe_type == MAC_BIBA_TYPE_EQUAL ||
276101099Srwatson	    b->mbe_type == MAC_BIBA_TYPE_EQUAL)
277101099Srwatson		return (1);
278101099Srwatson
279101099Srwatson	return (a->mbe_type == b->mbe_type && a->mbe_grade == b->mbe_grade);
280101099Srwatson}
281101099Srwatson
282101099Srwatsonstatic int
283101099Srwatsonmac_biba_equal_single(struct mac_biba *a, struct mac_biba *b)
284101099Srwatson{
285101099Srwatson
286101099Srwatson	KASSERT((a->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
287101099Srwatson	    ("mac_biba_equal_single: a not single"));
288101099Srwatson	KASSERT((b->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
289101099Srwatson	    ("mac_biba_equal_single: b not single"));
290101099Srwatson
291101099Srwatson	return (mac_biba_equal_element(&a->mb_single, &b->mb_single));
292101099Srwatson}
293101099Srwatson
294101099Srwatsonstatic int
295105634Srwatsonmac_biba_contains_equal(struct mac_biba *mac_biba)
296105634Srwatson{
297105634Srwatson
298105634Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE)
299105634Srwatson		if (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_EQUAL)
300105634Srwatson			return (1);
301105634Srwatson
302105634Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
303105634Srwatson		if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL)
304105634Srwatson			return (1);
305105634Srwatson		if (mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL)
306105637Srwatson			return (1);
307105634Srwatson	}
308105634Srwatson
309105634Srwatson	return (0);
310105634Srwatson}
311105634Srwatson
312105634Srwatsonstatic int
313106090Srwatsonmac_biba_subject_privileged(struct mac_biba *mac_biba)
314105634Srwatson{
315105634Srwatson
316105634Srwatson	KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAGS_BOTH) ==
317105634Srwatson	    MAC_BIBA_FLAGS_BOTH,
318106090Srwatson	    ("mac_biba_subject_privileged: subject doesn't have both labels"));
319105634Srwatson
320105634Srwatson	/* If the single is EQUAL, it's ok. */
321105634Srwatson	if (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_EQUAL)
322105634Srwatson		return (0);
323105634Srwatson
324105634Srwatson	/* If either range endpoint is EQUAL, it's ok. */
325105634Srwatson	if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL ||
326105634Srwatson	    mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL)
327105634Srwatson		return (0);
328105634Srwatson
329105634Srwatson	/* If the range is low-high, it's ok. */
330105634Srwatson	if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_LOW &&
331105634Srwatson	    mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_HIGH)
332105634Srwatson		return (0);
333105634Srwatson
334105634Srwatson	/* It's not ok. */
335105634Srwatson	return (EPERM);
336105634Srwatson}
337105634Srwatson
338106091Srwatsonstatic int
339105988Srwatsonmac_biba_high_single(struct mac_biba *mac_biba)
340105988Srwatson{
341105988Srwatson
342105988Srwatson	KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
343105988Srwatson	    ("mac_biba_equal_single: mac_biba not single"));
344105988Srwatson
345105988Srwatson	return (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_HIGH);
346105988Srwatson}
347105988Srwatson
348105634Srwatsonstatic int
349101099Srwatsonmac_biba_valid(struct mac_biba *mac_biba)
350101099Srwatson{
351101099Srwatson
352101099Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) {
353101099Srwatson		switch (mac_biba->mb_single.mbe_type) {
354101099Srwatson		case MAC_BIBA_TYPE_GRADE:
355101099Srwatson			break;
356101099Srwatson
357101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
358101099Srwatson		case MAC_BIBA_TYPE_HIGH:
359101099Srwatson		case MAC_BIBA_TYPE_LOW:
360105643Srwatson			if (mac_biba->mb_single.mbe_grade != 0 ||
361105643Srwatson			    !MAC_BIBA_BIT_SET_EMPTY(
362105643Srwatson			    mac_biba->mb_single.mbe_compartments))
363101099Srwatson				return (EINVAL);
364101099Srwatson			break;
365101099Srwatson
366101099Srwatson		default:
367101099Srwatson			return (EINVAL);
368101099Srwatson		}
369101099Srwatson	} else {
370101099Srwatson		if (mac_biba->mb_single.mbe_type != MAC_BIBA_TYPE_UNDEF)
371101099Srwatson			return (EINVAL);
372101099Srwatson	}
373101099Srwatson
374101099Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
375101099Srwatson		switch (mac_biba->mb_rangelow.mbe_type) {
376101099Srwatson		case MAC_BIBA_TYPE_GRADE:
377101099Srwatson			break;
378101099Srwatson
379101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
380101099Srwatson		case MAC_BIBA_TYPE_HIGH:
381101099Srwatson		case MAC_BIBA_TYPE_LOW:
382105643Srwatson			if (mac_biba->mb_rangelow.mbe_grade != 0 ||
383105643Srwatson			    !MAC_BIBA_BIT_SET_EMPTY(
384105643Srwatson			    mac_biba->mb_rangelow.mbe_compartments))
385101099Srwatson				return (EINVAL);
386101099Srwatson			break;
387101099Srwatson
388101099Srwatson		default:
389101099Srwatson			return (EINVAL);
390101099Srwatson		}
391101099Srwatson
392101099Srwatson		switch (mac_biba->mb_rangehigh.mbe_type) {
393101099Srwatson		case MAC_BIBA_TYPE_GRADE:
394101099Srwatson			break;
395101099Srwatson
396101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
397101099Srwatson		case MAC_BIBA_TYPE_HIGH:
398101099Srwatson		case MAC_BIBA_TYPE_LOW:
399105643Srwatson			if (mac_biba->mb_rangehigh.mbe_grade != 0 ||
400105643Srwatson			    !MAC_BIBA_BIT_SET_EMPTY(
401105643Srwatson			    mac_biba->mb_rangehigh.mbe_compartments))
402101099Srwatson				return (EINVAL);
403101099Srwatson			break;
404101099Srwatson
405101099Srwatson		default:
406101099Srwatson			return (EINVAL);
407101099Srwatson		}
408101099Srwatson		if (!mac_biba_dominate_element(&mac_biba->mb_rangehigh,
409101099Srwatson		    &mac_biba->mb_rangelow))
410101099Srwatson			return (EINVAL);
411101099Srwatson	} else {
412101099Srwatson		if (mac_biba->mb_rangelow.mbe_type != MAC_BIBA_TYPE_UNDEF ||
413101099Srwatson		    mac_biba->mb_rangehigh.mbe_type != MAC_BIBA_TYPE_UNDEF)
414101099Srwatson			return (EINVAL);
415101099Srwatson	}
416101099Srwatson
417101099Srwatson	return (0);
418101099Srwatson}
419101099Srwatson
420101099Srwatsonstatic void
421101099Srwatsonmac_biba_set_range(struct mac_biba *mac_biba, u_short typelow,
422105643Srwatson    u_short gradelow, u_char *compartmentslow, u_short typehigh,
423105643Srwatson    u_short gradehigh, u_char *compartmentshigh)
424101099Srwatson{
425101099Srwatson
426101099Srwatson	mac_biba->mb_rangelow.mbe_type = typelow;
427101099Srwatson	mac_biba->mb_rangelow.mbe_grade = gradelow;
428105643Srwatson	if (compartmentslow != NULL)
429105643Srwatson		memcpy(mac_biba->mb_rangelow.mbe_compartments,
430105643Srwatson		    compartmentslow,
431105643Srwatson		    sizeof(mac_biba->mb_rangelow.mbe_compartments));
432101099Srwatson	mac_biba->mb_rangehigh.mbe_type = typehigh;
433101099Srwatson	mac_biba->mb_rangehigh.mbe_grade = gradehigh;
434105643Srwatson	if (compartmentshigh != NULL)
435105643Srwatson		memcpy(mac_biba->mb_rangehigh.mbe_compartments,
436105643Srwatson		    compartmentshigh,
437105643Srwatson		    sizeof(mac_biba->mb_rangehigh.mbe_compartments));
438101099Srwatson	mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE;
439101099Srwatson}
440101099Srwatson
441101099Srwatsonstatic void
442105643Srwatsonmac_biba_set_single(struct mac_biba *mac_biba, u_short type, u_short grade,
443105643Srwatson    u_char *compartments)
444101099Srwatson{
445101099Srwatson
446101099Srwatson	mac_biba->mb_single.mbe_type = type;
447101099Srwatson	mac_biba->mb_single.mbe_grade = grade;
448105643Srwatson	if (compartments != NULL)
449105643Srwatson		memcpy(mac_biba->mb_single.mbe_compartments, compartments,
450105643Srwatson		    sizeof(mac_biba->mb_single.mbe_compartments));
451101099Srwatson	mac_biba->mb_flags |= MAC_BIBA_FLAG_SINGLE;
452101099Srwatson}
453101099Srwatson
454101099Srwatsonstatic void
455101099Srwatsonmac_biba_copy_range(struct mac_biba *labelfrom, struct mac_biba *labelto)
456101099Srwatson{
457105643Srwatson
458101099Srwatson	KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_RANGE) != 0,
459101099Srwatson	    ("mac_biba_copy_range: labelfrom not range"));
460101099Srwatson
461101099Srwatson	labelto->mb_rangelow = labelfrom->mb_rangelow;
462101099Srwatson	labelto->mb_rangehigh = labelfrom->mb_rangehigh;
463101099Srwatson	labelto->mb_flags |= MAC_BIBA_FLAG_RANGE;
464101099Srwatson}
465101099Srwatson
466101099Srwatsonstatic void
467101099Srwatsonmac_biba_copy_single(struct mac_biba *labelfrom, struct mac_biba *labelto)
468101099Srwatson{
469101099Srwatson
470101099Srwatson	KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
471101099Srwatson	    ("mac_biba_copy_single: labelfrom not single"));
472101099Srwatson
473101099Srwatson	labelto->mb_single = labelfrom->mb_single;
474101099Srwatson	labelto->mb_flags |= MAC_BIBA_FLAG_SINGLE;
475101099Srwatson}
476101099Srwatson
477105656Srwatsonstatic void
478105656Srwatsonmac_biba_copy(struct mac_biba *source, struct mac_biba *dest)
479105656Srwatson{
480105656Srwatson
481105656Srwatson	if (source->mb_flags & MAC_BIBA_FLAG_SINGLE)
482105656Srwatson		mac_biba_copy_single(source, dest);
483105656Srwatson	if (source->mb_flags & MAC_BIBA_FLAG_RANGE)
484105656Srwatson		mac_biba_copy_range(source, dest);
485105656Srwatson}
486105656Srwatson
487101099Srwatson/*
488101099Srwatson * Policy module operations.
489101099Srwatson */
490101099Srwatsonstatic void
491101099Srwatsonmac_biba_destroy(struct mac_policy_conf *conf)
492101099Srwatson{
493101099Srwatson
494101099Srwatson}
495101099Srwatson
496101099Srwatsonstatic void
497101099Srwatsonmac_biba_init(struct mac_policy_conf *conf)
498101099Srwatson{
499101099Srwatson
500101099Srwatson}
501101099Srwatson
502101099Srwatson/*
503101099Srwatson * Label operations.
504101099Srwatson */
505101099Srwatsonstatic void
506104514Srwatsonmac_biba_init_label(struct label *label)
507101099Srwatson{
508101099Srwatson
509111119Simp	SLOT(label) = biba_alloc(M_WAITOK);
510101099Srwatson}
511101099Srwatson
512101099Srwatsonstatic int
513104514Srwatsonmac_biba_init_label_waitcheck(struct label *label, int flag)
514101099Srwatson{
515101099Srwatson
516104514Srwatson	SLOT(label) = biba_alloc(flag);
517101099Srwatson	if (SLOT(label) == NULL)
518101099Srwatson		return (ENOMEM);
519101099Srwatson
520101099Srwatson	return (0);
521101099Srwatson}
522101099Srwatson
523101099Srwatsonstatic void
524104514Srwatsonmac_biba_destroy_label(struct label *label)
525101099Srwatson{
526101099Srwatson
527101099Srwatson	biba_free(SLOT(label));
528101099Srwatson	SLOT(label) = NULL;
529101099Srwatson}
530101099Srwatson
531105696Srwatson/*
532115497Srwatson * mac_biba_element_to_string() accepts an sbuf and Biba element.  It
533115497Srwatson * converts the Biba element to a string and stores the result in the
534115497Srwatson * sbuf; if there isn't space in the sbuf, -1 is returned.
535105696Srwatson */
536115497Srwatsonstatic int
537115497Srwatsonmac_biba_element_to_string(struct sbuf *sb, struct mac_biba_element *element)
538105696Srwatson{
539115497Srwatson	int i, first;
540105696Srwatson
541105696Srwatson	switch (element->mbe_type) {
542105696Srwatson	case MAC_BIBA_TYPE_HIGH:
543115497Srwatson		return (sbuf_printf(sb, "high"));
544105696Srwatson
545105696Srwatson	case MAC_BIBA_TYPE_LOW:
546115497Srwatson		return (sbuf_printf(sb, "low"));
547105696Srwatson
548105696Srwatson	case MAC_BIBA_TYPE_EQUAL:
549115497Srwatson		return (sbuf_printf(sb, "equal"));
550105696Srwatson
551105696Srwatson	case MAC_BIBA_TYPE_GRADE:
552115497Srwatson		if (sbuf_printf(sb, "%d", element->mbe_grade) == -1)
553115497Srwatson			return (-1);
554115497Srwatson
555115497Srwatson		first = 1;
556115497Srwatson		for (i = 1; i <= MAC_BIBA_MAX_COMPARTMENTS; i++) {
557115497Srwatson			if (MAC_BIBA_BIT_TEST(i, element->mbe_compartments)) {
558115497Srwatson				if (first) {
559115497Srwatson					if (sbuf_putc(sb, ':') == -1)
560115497Srwatson						return (-1);
561115497Srwatson					if (sbuf_printf(sb, "%d", i) == -1)
562115497Srwatson						return (-1);
563115497Srwatson					first = 0;
564115497Srwatson				} else {
565115497Srwatson					if (sbuf_printf(sb, "+%d", i) == -1)
566115497Srwatson						return (-1);
567115497Srwatson				}
568115497Srwatson			}
569105696Srwatson		}
570115497Srwatson		return (0);
571105696Srwatson
572105696Srwatson	default:
573105696Srwatson		panic("mac_biba_element_to_string: invalid type (%d)",
574105696Srwatson		    element->mbe_type);
575105696Srwatson	}
576105696Srwatson}
577105696Srwatson
578115497Srwatson/*
579115497Srwatson * mac_biba_to_string() converts an Biba label to a string, placing the
580115497Srwatson * results in the passed string buffer.  It returns 0 on success,
581115497Srwatson * or EINVAL if there isn't room in the buffer.  The size of the
582115497Srwatson * string appended, leaving out the nul termination, is returned to
583115497Srwatson * the caller via *caller_len.  Eventually, we should expose the
584115497Srwatson * sbuf to the caller rather than using C strings at this layer.
585115497Srwatson */
586101099Srwatsonstatic int
587105696Srwatsonmac_biba_to_string(char *string, size_t size, size_t *caller_len,
588105696Srwatson    struct mac_biba *mac_biba)
589101099Srwatson{
590115497Srwatson	struct sbuf sb;
591105696Srwatson
592115497Srwatson	sbuf_new(&sb, string, size, SBUF_FIXEDLEN);
593105696Srwatson
594105696Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) {
595115497Srwatson		if (mac_biba_element_to_string(&sb, &mac_biba->mb_single)
596115497Srwatson		    == -1)
597105696Srwatson			return (EINVAL);
598105696Srwatson	}
599105696Srwatson
600105696Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
601115497Srwatson		if (sbuf_putc(&sb, '(') == -1)
602105696Srwatson			return (EINVAL);
603105696Srwatson
604115497Srwatson		if (mac_biba_element_to_string(&sb, &mac_biba->mb_rangelow)
605115497Srwatson		    == -1)
606105696Srwatson			return (EINVAL);
607105696Srwatson
608115497Srwatson		if (sbuf_putc(&sb, '-') == -1)
609105696Srwatson			return (EINVAL);
610105696Srwatson
611115497Srwatson		if (mac_biba_element_to_string(&sb, &mac_biba->mb_rangehigh)
612115497Srwatson		    == -1)
613105696Srwatson			return (EINVAL);
614105696Srwatson
615115497Srwatson		if (sbuf_putc(&sb, ')') == -1)
616105696Srwatson			return (EINVAL);
617105696Srwatson	}
618105696Srwatson
619115497Srwatson	sbuf_finish(&sb);
620105696Srwatson	*caller_len = strlen(string);
621105696Srwatson	return (0);
622105696Srwatson}
623105696Srwatson
624105696Srwatsonstatic int
625105696Srwatsonmac_biba_externalize_label(struct label *label, char *element_name,
626105696Srwatson    char *element_data, size_t size, size_t *len, int *claimed)
627105696Srwatson{
628101099Srwatson	struct mac_biba *mac_biba;
629105696Srwatson	int error;
630101099Srwatson
631105696Srwatson	if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0)
632105696Srwatson		return (0);
633105696Srwatson
634105696Srwatson	(*claimed)++;
635105696Srwatson
636101099Srwatson	mac_biba = SLOT(label);
637105696Srwatson	error = mac_biba_to_string(element_data, size, len, mac_biba);
638105696Srwatson	if (error)
639105696Srwatson		return (error);
640101099Srwatson
641105696Srwatson	return (0);
642105696Srwatson}
643105696Srwatson
644105696Srwatsonstatic int
645105696Srwatsonmac_biba_parse_element(struct mac_biba_element *element, char *string)
646101099Srwatson{
647115395Srwatson	char *compartment, *end, *grade;
648115395Srwatson	int value;
649105696Srwatson
650105696Srwatson	if (strcmp(string, "high") == 0 ||
651105696Srwatson	    strcmp(string, "hi") == 0) {
652105696Srwatson		element->mbe_type = MAC_BIBA_TYPE_HIGH;
653105696Srwatson		element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
654105696Srwatson	} else if (strcmp(string, "low") == 0 ||
655105696Srwatson	    strcmp(string, "lo") == 0) {
656105696Srwatson		element->mbe_type = MAC_BIBA_TYPE_LOW;
657105696Srwatson		element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
658105696Srwatson	} else if (strcmp(string, "equal") == 0 ||
659105696Srwatson	    strcmp(string, "eq") == 0) {
660105696Srwatson		element->mbe_type = MAC_BIBA_TYPE_EQUAL;
661105696Srwatson		element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
662105696Srwatson	} else {
663115395Srwatson		element->mbe_type = MAC_BIBA_TYPE_GRADE;
664105696Srwatson
665115395Srwatson		/*
666115395Srwatson		 * Numeric grade piece of the element.
667115395Srwatson		 */
668115395Srwatson		grade = strsep(&string, ":");
669115395Srwatson		value = strtol(grade, &end, 10);
670115395Srwatson		if (end == grade || *end != '\0')
671105696Srwatson			return (EINVAL);
672115395Srwatson		if (value < 0 || value > 65535)
673115395Srwatson			return (EINVAL);
674115395Srwatson		element->mbe_grade = value;
675105696Srwatson
676115395Srwatson		/*
677115395Srwatson		 * Optional compartment piece of the element.  If none
678115395Srwatson		 * are included, we assume that the label has no
679115395Srwatson		 * compartments.
680115395Srwatson		 */
681115395Srwatson		if (string == NULL)
682115395Srwatson			return (0);
683115395Srwatson		if (*string == '\0')
684115395Srwatson			return (0);
685105696Srwatson
686115395Srwatson		while ((compartment = strsep(&string, "+")) != NULL) {
687115395Srwatson			value = strtol(compartment, &end, 10);
688115395Srwatson			if (compartment == end || *end != '\0')
689105696Srwatson				return (EINVAL);
690115395Srwatson			if (value < 1 || value > MAC_BIBA_MAX_COMPARTMENTS)
691105696Srwatson				return (EINVAL);
692115395Srwatson			MAC_BIBA_BIT_SET(value, element->mbe_compartments);
693105696Srwatson		}
694105696Srwatson	}
695105696Srwatson
696105696Srwatson	return (0);
697105696Srwatson}
698105696Srwatson
699105696Srwatson/*
700105696Srwatson * Note: destructively consumes the string, make a local copy before
701105696Srwatson * calling if that's a problem.
702105696Srwatson */
703105696Srwatsonstatic int
704105696Srwatsonmac_biba_parse(struct mac_biba *mac_biba, char *string)
705105696Srwatson{
706115395Srwatson	char *rangehigh, *rangelow, *single;
707101099Srwatson	int error;
708101099Srwatson
709115395Srwatson	single = strsep(&string, "(");
710115395Srwatson	if (*single == '\0')
711105696Srwatson		single = NULL;
712115395Srwatson
713115395Srwatson	if (string != NULL) {
714115395Srwatson		rangelow = strsep(&string, "-");
715115395Srwatson		if (string == NULL)
716105696Srwatson			return (EINVAL);
717115395Srwatson		rangehigh = strsep(&string, ")");
718115395Srwatson		if (string == NULL)
719105696Srwatson			return (EINVAL);
720115395Srwatson		if (*string != '\0')
721105696Srwatson			return (EINVAL);
722115395Srwatson	} else {
723115395Srwatson		rangelow = NULL;
724115395Srwatson		rangehigh = NULL;
725105696Srwatson	}
726115395Srwatson
727105696Srwatson	KASSERT((rangelow != NULL && rangehigh != NULL) ||
728105696Srwatson	    (rangelow == NULL && rangehigh == NULL),
729115395Srwatson	    ("mac_biba_parse: range mismatch"));
730101099Srwatson
731105696Srwatson	bzero(mac_biba, sizeof(*mac_biba));
732105696Srwatson	if (single != NULL) {
733105696Srwatson		error = mac_biba_parse_element(&mac_biba->mb_single, single);
734105696Srwatson		if (error)
735105696Srwatson			return (error);
736105696Srwatson		mac_biba->mb_flags |= MAC_BIBA_FLAG_SINGLE;
737105696Srwatson	}
738105696Srwatson
739105696Srwatson	if (rangelow != NULL) {
740105696Srwatson		error = mac_biba_parse_element(&mac_biba->mb_rangelow,
741105696Srwatson		    rangelow);
742105696Srwatson		if (error)
743105696Srwatson			return (error);
744105696Srwatson		error = mac_biba_parse_element(&mac_biba->mb_rangehigh,
745105696Srwatson		    rangehigh);
746105696Srwatson		if (error)
747105696Srwatson			return (error);
748105696Srwatson		mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE;
749105696Srwatson	}
750105696Srwatson
751101099Srwatson	error = mac_biba_valid(mac_biba);
752101099Srwatson	if (error)
753101099Srwatson		return (error);
754101099Srwatson
755105696Srwatson	return (0);
756105696Srwatson}
757101099Srwatson
758105696Srwatsonstatic int
759105696Srwatsonmac_biba_internalize_label(struct label *label, char *element_name,
760105696Srwatson    char *element_data, int *claimed)
761105696Srwatson{
762105696Srwatson	struct mac_biba *mac_biba, mac_biba_temp;
763105696Srwatson	int error;
764105696Srwatson
765105696Srwatson	if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0)
766105696Srwatson		return (0);
767105696Srwatson
768105696Srwatson	(*claimed)++;
769105696Srwatson
770105696Srwatson	error = mac_biba_parse(&mac_biba_temp, element_data);
771105696Srwatson	if (error)
772105696Srwatson		return (error);
773105696Srwatson
774105696Srwatson	mac_biba = SLOT(label);
775105696Srwatson	*mac_biba = mac_biba_temp;
776105696Srwatson
777101099Srwatson	return (0);
778101099Srwatson}
779101099Srwatson
780105696Srwatsonstatic void
781105696Srwatsonmac_biba_copy_label(struct label *src, struct label *dest)
782105696Srwatson{
783105696Srwatson
784105696Srwatson	*SLOT(dest) = *SLOT(src);
785105696Srwatson}
786105696Srwatson
787101099Srwatson/*
788101099Srwatson * Labeling event operations: file system objects, and things that look
789101099Srwatson * a lot like file system objects.
790101099Srwatson */
791101099Srwatsonstatic void
792107698Srwatsonmac_biba_create_devfs_device(struct mount *mp, dev_t dev,
793107698Srwatson    struct devfs_dirent *devfs_dirent, struct label *label)
794101099Srwatson{
795101099Srwatson	struct mac_biba *mac_biba;
796101099Srwatson	int biba_type;
797101099Srwatson
798101099Srwatson	mac_biba = SLOT(label);
799101099Srwatson	if (strcmp(dev->si_name, "null") == 0 ||
800101099Srwatson	    strcmp(dev->si_name, "zero") == 0 ||
801101099Srwatson	    strcmp(dev->si_name, "random") == 0 ||
802101099Srwatson	    strncmp(dev->si_name, "fd/", strlen("fd/")) == 0)
803101099Srwatson		biba_type = MAC_BIBA_TYPE_EQUAL;
804105606Srwatson	else if (ptys_equal &&
805105606Srwatson	    (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 ||
806105606Srwatson	    strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0))
807105606Srwatson		biba_type = MAC_BIBA_TYPE_EQUAL;
808101099Srwatson	else
809101099Srwatson		biba_type = MAC_BIBA_TYPE_HIGH;
810105643Srwatson	mac_biba_set_single(mac_biba, biba_type, 0, NULL);
811101099Srwatson}
812101099Srwatson
813101099Srwatsonstatic void
814107698Srwatsonmac_biba_create_devfs_directory(struct mount *mp, char *dirname,
815107698Srwatson    int dirnamelen, struct devfs_dirent *devfs_dirent, struct label *label)
816101099Srwatson{
817101099Srwatson	struct mac_biba *mac_biba;
818101099Srwatson
819101099Srwatson	mac_biba = SLOT(label);
820105643Srwatson	mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
821101099Srwatson}
822101099Srwatson
823101099Srwatsonstatic void
824107698Srwatsonmac_biba_create_devfs_symlink(struct ucred *cred, struct mount *mp,
825107698Srwatson    struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de,
826107698Srwatson    struct label *delabel)
827104535Srwatson{
828104535Srwatson	struct mac_biba *source, *dest;
829104535Srwatson
830104535Srwatson	source = SLOT(&cred->cr_label);
831104535Srwatson	dest = SLOT(delabel);
832104535Srwatson
833104535Srwatson	mac_biba_copy_single(source, dest);
834104535Srwatson}
835104535Srwatson
836104535Srwatsonstatic void
837101099Srwatsonmac_biba_create_mount(struct ucred *cred, struct mount *mp,
838101099Srwatson    struct label *mntlabel, struct label *fslabel)
839101099Srwatson{
840101099Srwatson	struct mac_biba *source, *dest;
841101099Srwatson
842101099Srwatson	source = SLOT(&cred->cr_label);
843101099Srwatson	dest = SLOT(mntlabel);
844101099Srwatson	mac_biba_copy_single(source, dest);
845101099Srwatson	dest = SLOT(fslabel);
846101099Srwatson	mac_biba_copy_single(source, dest);
847101099Srwatson}
848101099Srwatson
849101099Srwatsonstatic void
850101099Srwatsonmac_biba_create_root_mount(struct ucred *cred, struct mount *mp,
851101099Srwatson    struct label *mntlabel, struct label *fslabel)
852101099Srwatson{
853101099Srwatson	struct mac_biba *mac_biba;
854101099Srwatson
855101099Srwatson	/* Always mount root as high integrity. */
856101099Srwatson	mac_biba = SLOT(fslabel);
857105643Srwatson	mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
858101099Srwatson	mac_biba = SLOT(mntlabel);
859105643Srwatson	mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
860101099Srwatson}
861101099Srwatson
862101099Srwatsonstatic void
863101099Srwatsonmac_biba_relabel_vnode(struct ucred *cred, struct vnode *vp,
864101099Srwatson    struct label *vnodelabel, struct label *label)
865101099Srwatson{
866101099Srwatson	struct mac_biba *source, *dest;
867101099Srwatson
868101099Srwatson	source = SLOT(label);
869101099Srwatson	dest = SLOT(vnodelabel);
870101099Srwatson
871105656Srwatson	mac_biba_copy(source, dest);
872101099Srwatson}
873101099Srwatson
874101099Srwatsonstatic void
875107698Srwatsonmac_biba_update_devfsdirent(struct mount *mp,
876107698Srwatson    struct devfs_dirent *devfs_dirent, struct label *direntlabel,
877107698Srwatson    struct vnode *vp, struct label *vnodelabel)
878101099Srwatson{
879101099Srwatson	struct mac_biba *source, *dest;
880101099Srwatson
881101099Srwatson	source = SLOT(vnodelabel);
882101099Srwatson	dest = SLOT(direntlabel);
883101099Srwatson
884105656Srwatson	mac_biba_copy(source, dest);
885101099Srwatson}
886101099Srwatson
887101099Srwatsonstatic void
888105988Srwatsonmac_biba_associate_vnode_devfs(struct mount *mp, struct label *fslabel,
889105988Srwatson    struct devfs_dirent *de, struct label *delabel, struct vnode *vp,
890105988Srwatson    struct label *vlabel)
891101099Srwatson{
892101099Srwatson	struct mac_biba *source, *dest;
893101099Srwatson
894105988Srwatson	source = SLOT(delabel);
895105988Srwatson	dest = SLOT(vlabel);
896101099Srwatson
897101099Srwatson	mac_biba_copy_single(source, dest);
898101099Srwatson}
899101099Srwatson
900101099Srwatsonstatic int
901105988Srwatsonmac_biba_associate_vnode_extattr(struct mount *mp, struct label *fslabel,
902105988Srwatson    struct vnode *vp, struct label *vlabel)
903101099Srwatson{
904105988Srwatson	struct mac_biba temp, *source, *dest;
905106354Smux	int buflen, error;
906101099Srwatson
907105988Srwatson	source = SLOT(fslabel);
908105988Srwatson	dest = SLOT(vlabel);
909101099Srwatson
910105988Srwatson	buflen = sizeof(temp);
911105988Srwatson	bzero(&temp, buflen);
912105988Srwatson
913105988Srwatson	error = vn_extattr_get(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
914105988Srwatson	    MAC_BIBA_EXTATTR_NAME, &buflen, (char *) &temp, curthread);
915105988Srwatson	if (error == ENOATTR || error == EOPNOTSUPP) {
916105988Srwatson		/* Fall back to the fslabel. */
917105988Srwatson		mac_biba_copy_single(source, dest);
918105988Srwatson		return (0);
919105988Srwatson	} else if (error)
920101099Srwatson		return (error);
921101099Srwatson
922105988Srwatson	if (buflen != sizeof(temp)) {
923105988Srwatson		printf("mac_biba_associate_vnode_extattr: bad size %d\n",
924105988Srwatson		    buflen);
925105988Srwatson		return (EPERM);
926105988Srwatson	}
927105988Srwatson	if (mac_biba_valid(&temp) != 0) {
928105988Srwatson		printf("mac_biba_associate_vnode_extattr: invalid\n");
929105988Srwatson		return (EPERM);
930105988Srwatson	}
931105988Srwatson	if ((temp.mb_flags & MAC_BIBA_FLAGS_BOTH) != MAC_BIBA_FLAG_SINGLE) {
932105988Srwatson		printf("mac_biba_associate_vnode_extattr: not single\n");
933105988Srwatson		return (EPERM);
934105988Srwatson	}
935101099Srwatson
936105988Srwatson	mac_biba_copy_single(&temp, dest);
937101099Srwatson	return (0);
938101099Srwatson}
939101099Srwatson
940101099Srwatsonstatic void
941105988Srwatsonmac_biba_associate_vnode_singlelabel(struct mount *mp,
942105988Srwatson    struct label *fslabel, struct vnode *vp, struct label *vlabel)
943101099Srwatson{
944101099Srwatson	struct mac_biba *source, *dest;
945101099Srwatson
946101099Srwatson	source = SLOT(fslabel);
947105988Srwatson	dest = SLOT(vlabel);
948101099Srwatson
949101099Srwatson	mac_biba_copy_single(source, dest);
950101099Srwatson}
951101099Srwatson
952105988Srwatsonstatic int
953105988Srwatsonmac_biba_create_vnode_extattr(struct ucred *cred, struct mount *mp,
954105988Srwatson    struct label *fslabel, struct vnode *dvp, struct label *dlabel,
955105988Srwatson    struct vnode *vp, struct label *vlabel, struct componentname *cnp)
956105988Srwatson{
957105988Srwatson	struct mac_biba *source, *dest, temp;
958105988Srwatson	size_t buflen;
959105988Srwatson	int error;
960105988Srwatson
961105988Srwatson	buflen = sizeof(temp);
962105988Srwatson	bzero(&temp, buflen);
963105988Srwatson
964105988Srwatson	source = SLOT(&cred->cr_label);
965105988Srwatson	dest = SLOT(vlabel);
966105988Srwatson	mac_biba_copy_single(source, &temp);
967105988Srwatson
968105988Srwatson	error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
969105988Srwatson	    MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread);
970105988Srwatson	if (error == 0)
971105988Srwatson		mac_biba_copy_single(source, dest);
972105988Srwatson	return (error);
973105988Srwatson}
974105988Srwatson
975105988Srwatsonstatic int
976105988Srwatsonmac_biba_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp,
977105988Srwatson    struct label *vlabel, struct label *intlabel)
978105988Srwatson{
979105988Srwatson	struct mac_biba *source, temp;
980105988Srwatson	size_t buflen;
981105988Srwatson	int error;
982105988Srwatson
983105988Srwatson	buflen = sizeof(temp);
984105988Srwatson	bzero(&temp, buflen);
985105988Srwatson
986105988Srwatson	source = SLOT(intlabel);
987105988Srwatson	if ((source->mb_flags & MAC_BIBA_FLAG_SINGLE) == 0)
988105988Srwatson		return (0);
989105988Srwatson
990105988Srwatson	mac_biba_copy_single(source, &temp);
991105988Srwatson
992105988Srwatson	error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
993105988Srwatson	    MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread);
994105988Srwatson	return (error);
995105988Srwatson}
996105988Srwatson
997101099Srwatson/*
998101099Srwatson * Labeling event operations: IPC object.
999101099Srwatson */
1000101099Srwatsonstatic void
1001101099Srwatsonmac_biba_create_mbuf_from_socket(struct socket *so, struct label *socketlabel,
1002101099Srwatson    struct mbuf *m, struct label *mbuflabel)
1003101099Srwatson{
1004101099Srwatson	struct mac_biba *source, *dest;
1005101099Srwatson
1006101099Srwatson	source = SLOT(socketlabel);
1007101099Srwatson	dest = SLOT(mbuflabel);
1008101099Srwatson
1009101099Srwatson	mac_biba_copy_single(source, dest);
1010101099Srwatson}
1011101099Srwatson
1012101099Srwatsonstatic void
1013101099Srwatsonmac_biba_create_socket(struct ucred *cred, struct socket *socket,
1014101099Srwatson    struct label *socketlabel)
1015101099Srwatson{
1016101099Srwatson	struct mac_biba *source, *dest;
1017101099Srwatson
1018101099Srwatson	source = SLOT(&cred->cr_label);
1019101099Srwatson	dest = SLOT(socketlabel);
1020101099Srwatson
1021101099Srwatson	mac_biba_copy_single(source, dest);
1022101099Srwatson}
1023101099Srwatson
1024101099Srwatsonstatic void
1025101099Srwatsonmac_biba_create_pipe(struct ucred *cred, struct pipe *pipe,
1026101099Srwatson    struct label *pipelabel)
1027101099Srwatson{
1028101099Srwatson	struct mac_biba *source, *dest;
1029101099Srwatson
1030101099Srwatson	source = SLOT(&cred->cr_label);
1031101099Srwatson	dest = SLOT(pipelabel);
1032101099Srwatson
1033101099Srwatson	mac_biba_copy_single(source, dest);
1034101099Srwatson}
1035101099Srwatson
1036101099Srwatsonstatic void
1037101099Srwatsonmac_biba_create_socket_from_socket(struct socket *oldsocket,
1038101099Srwatson    struct label *oldsocketlabel, struct socket *newsocket,
1039101099Srwatson    struct label *newsocketlabel)
1040101099Srwatson{
1041101099Srwatson	struct mac_biba *source, *dest;
1042101099Srwatson
1043101099Srwatson	source = SLOT(oldsocketlabel);
1044101099Srwatson	dest = SLOT(newsocketlabel);
1045101099Srwatson
1046101099Srwatson	mac_biba_copy_single(source, dest);
1047101099Srwatson}
1048101099Srwatson
1049101099Srwatsonstatic void
1050101099Srwatsonmac_biba_relabel_socket(struct ucred *cred, struct socket *socket,
1051101099Srwatson    struct label *socketlabel, struct label *newlabel)
1052101099Srwatson{
1053101099Srwatson	struct mac_biba *source, *dest;
1054101099Srwatson
1055101099Srwatson	source = SLOT(newlabel);
1056101099Srwatson	dest = SLOT(socketlabel);
1057101099Srwatson
1058105656Srwatson	mac_biba_copy(source, dest);
1059101099Srwatson}
1060101099Srwatson
1061101099Srwatsonstatic void
1062101099Srwatsonmac_biba_relabel_pipe(struct ucred *cred, struct pipe *pipe,
1063101099Srwatson    struct label *pipelabel, struct label *newlabel)
1064101099Srwatson{
1065101099Srwatson	struct mac_biba *source, *dest;
1066101099Srwatson
1067101099Srwatson	source = SLOT(newlabel);
1068101099Srwatson	dest = SLOT(pipelabel);
1069101099Srwatson
1070105656Srwatson	mac_biba_copy(source, dest);
1071101099Srwatson}
1072101099Srwatson
1073101099Srwatsonstatic void
1074101099Srwatsonmac_biba_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel,
1075101099Srwatson    struct socket *socket, struct label *socketpeerlabel)
1076101099Srwatson{
1077101099Srwatson	struct mac_biba *source, *dest;
1078101099Srwatson
1079101099Srwatson	source = SLOT(mbuflabel);
1080101099Srwatson	dest = SLOT(socketpeerlabel);
1081101099Srwatson
1082101099Srwatson	mac_biba_copy_single(source, dest);
1083101099Srwatson}
1084101099Srwatson
1085101099Srwatson/*
1086101099Srwatson * Labeling event operations: network objects.
1087101099Srwatson */
1088101099Srwatsonstatic void
1089101099Srwatsonmac_biba_set_socket_peer_from_socket(struct socket *oldsocket,
1090101099Srwatson    struct label *oldsocketlabel, struct socket *newsocket,
1091101099Srwatson    struct label *newsocketpeerlabel)
1092101099Srwatson{
1093101099Srwatson	struct mac_biba *source, *dest;
1094101099Srwatson
1095101099Srwatson	source = SLOT(oldsocketlabel);
1096101099Srwatson	dest = SLOT(newsocketpeerlabel);
1097101099Srwatson
1098101099Srwatson	mac_biba_copy_single(source, dest);
1099101099Srwatson}
1100101099Srwatson
1101101099Srwatsonstatic void
1102101099Srwatsonmac_biba_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d,
1103101099Srwatson    struct label *bpflabel)
1104101099Srwatson{
1105101099Srwatson	struct mac_biba *source, *dest;
1106101099Srwatson
1107101099Srwatson	source = SLOT(&cred->cr_label);
1108101099Srwatson	dest = SLOT(bpflabel);
1109101099Srwatson
1110101099Srwatson	mac_biba_copy_single(source, dest);
1111101099Srwatson}
1112101099Srwatson
1113101099Srwatsonstatic void
1114101099Srwatsonmac_biba_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel)
1115101099Srwatson{
1116101099Srwatson	char tifname[IFNAMSIZ], ifname[IFNAMSIZ], *p, *q;
1117101099Srwatson	char tiflist[sizeof(trusted_interfaces)];
1118101099Srwatson	struct mac_biba *dest;
1119110350Srwatson	int len, type;
1120101099Srwatson
1121101099Srwatson	dest = SLOT(ifnetlabel);
1122101099Srwatson
1123101099Srwatson	if (ifnet->if_type == IFT_LOOP) {
1124110350Srwatson		type = MAC_BIBA_TYPE_EQUAL;
1125101099Srwatson		goto set;
1126101099Srwatson	}
1127101099Srwatson
1128101099Srwatson	if (trust_all_interfaces) {
1129110350Srwatson		type = MAC_BIBA_TYPE_HIGH;
1130101099Srwatson		goto set;
1131101099Srwatson	}
1132101099Srwatson
1133110350Srwatson	type = MAC_BIBA_TYPE_LOW;
1134101099Srwatson
1135101099Srwatson	if (trusted_interfaces[0] == '\0' ||
1136101099Srwatson	    !strvalid(trusted_interfaces, sizeof(trusted_interfaces)))
1137101099Srwatson		goto set;
1138101099Srwatson
1139106089Srwatson	bzero(tiflist, sizeof(tiflist));
1140101099Srwatson	for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++)
1141101099Srwatson		if(*p != ' ' && *p != '\t')
1142101099Srwatson			*q = *p;
1143101099Srwatson
1144101099Srwatson	snprintf(ifname, IFNAMSIZ, "%s%d", ifnet->if_name, ifnet->if_unit);
1145101099Srwatson
1146101099Srwatson	for (p = q = tiflist;; p++) {
1147101099Srwatson		if (*p == ',' || *p == '\0') {
1148101099Srwatson			len = p - q;
1149101099Srwatson			if (len < IFNAMSIZ) {
1150101099Srwatson				bzero(tifname, sizeof(tifname));
1151101099Srwatson				bcopy(q, tifname, len);
1152101099Srwatson				if (strcmp(tifname, ifname) == 0) {
1153110350Srwatson					type = MAC_BIBA_TYPE_HIGH;
1154101099Srwatson					break;
1155101099Srwatson				}
1156106089Srwatson			} else {
1157106089Srwatson				*p = '\0';
1158106089Srwatson				printf("mac_biba warning: interface name "
1159106089Srwatson				    "\"%s\" is too long (must be < %d)\n",
1160106089Srwatson				    q, IFNAMSIZ);
1161101099Srwatson			}
1162101099Srwatson			if (*p == '\0')
1163101099Srwatson				break;
1164101099Srwatson			q = p + 1;
1165101099Srwatson		}
1166101099Srwatson	}
1167101099Srwatsonset:
1168110350Srwatson	mac_biba_set_single(dest, type, 0, NULL);
1169110350Srwatson	mac_biba_set_range(dest, type, 0, NULL, type, 0, NULL);
1170101099Srwatson}
1171101099Srwatson
1172101099Srwatsonstatic void
1173101099Srwatsonmac_biba_create_ipq(struct mbuf *fragment, struct label *fragmentlabel,
1174101099Srwatson    struct ipq *ipq, struct label *ipqlabel)
1175101099Srwatson{
1176101099Srwatson	struct mac_biba *source, *dest;
1177101099Srwatson
1178101099Srwatson	source = SLOT(fragmentlabel);
1179101099Srwatson	dest = SLOT(ipqlabel);
1180101099Srwatson
1181101099Srwatson	mac_biba_copy_single(source, dest);
1182101099Srwatson}
1183101099Srwatson
1184101099Srwatsonstatic void
1185101099Srwatsonmac_biba_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel,
1186101099Srwatson    struct mbuf *datagram, struct label *datagramlabel)
1187101099Srwatson{
1188101099Srwatson	struct mac_biba *source, *dest;
1189101099Srwatson
1190101099Srwatson	source = SLOT(ipqlabel);
1191101099Srwatson	dest = SLOT(datagramlabel);
1192101099Srwatson
1193101099Srwatson	/* Just use the head, since we require them all to match. */
1194101099Srwatson	mac_biba_copy_single(source, dest);
1195101099Srwatson}
1196101099Srwatson
1197101099Srwatsonstatic void
1198101099Srwatsonmac_biba_create_fragment(struct mbuf *datagram, struct label *datagramlabel,
1199101099Srwatson    struct mbuf *fragment, struct label *fragmentlabel)
1200101099Srwatson{
1201101099Srwatson	struct mac_biba *source, *dest;
1202101099Srwatson
1203101099Srwatson	source = SLOT(datagramlabel);
1204101099Srwatson	dest = SLOT(fragmentlabel);
1205101099Srwatson
1206101099Srwatson	mac_biba_copy_single(source, dest);
1207101099Srwatson}
1208101099Srwatson
1209101099Srwatsonstatic void
1210101099Srwatsonmac_biba_create_mbuf_from_mbuf(struct mbuf *oldmbuf,
1211101099Srwatson    struct label *oldmbuflabel, struct mbuf *newmbuf,
1212101099Srwatson    struct label *newmbuflabel)
1213101099Srwatson{
1214101099Srwatson	struct mac_biba *source, *dest;
1215101099Srwatson
1216101099Srwatson	source = SLOT(oldmbuflabel);
1217101099Srwatson	dest = SLOT(newmbuflabel);
1218101099Srwatson
1219105656Srwatson	/*
1220105656Srwatson	 * Because the source mbuf may not yet have been "created",
1221105696Srwatson	 * just initialized, we do a conditional copy.  Since we don't
1222105656Srwatson	 * allow mbufs to have ranges, do a KASSERT to make sure that
1223105656Srwatson	 * doesn't happen.
1224105656Srwatson	 */
1225105656Srwatson	KASSERT((source->mb_flags & MAC_BIBA_FLAG_RANGE) == 0,
1226105656Srwatson	    ("mac_biba_create_mbuf_from_mbuf: source mbuf has range"));
1227105656Srwatson	mac_biba_copy(source, dest);
1228101099Srwatson}
1229101099Srwatson
1230101099Srwatsonstatic void
1231101099Srwatsonmac_biba_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel,
1232101099Srwatson    struct mbuf *mbuf, struct label *mbuflabel)
1233101099Srwatson{
1234101099Srwatson	struct mac_biba *dest;
1235101099Srwatson
1236101099Srwatson	dest = SLOT(mbuflabel);
1237101099Srwatson
1238105643Srwatson	mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1239101099Srwatson}
1240101099Srwatson
1241101099Srwatsonstatic void
1242101099Srwatsonmac_biba_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel,
1243101099Srwatson    struct mbuf *mbuf, struct label *mbuflabel)
1244101099Srwatson{
1245101099Srwatson	struct mac_biba *source, *dest;
1246101099Srwatson
1247101099Srwatson	source = SLOT(bpflabel);
1248101099Srwatson	dest = SLOT(mbuflabel);
1249101099Srwatson
1250101099Srwatson	mac_biba_copy_single(source, dest);
1251101099Srwatson}
1252101099Srwatson
1253101099Srwatsonstatic void
1254101099Srwatsonmac_biba_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel,
1255101099Srwatson    struct mbuf *m, struct label *mbuflabel)
1256101099Srwatson{
1257101099Srwatson	struct mac_biba *source, *dest;
1258101099Srwatson
1259101099Srwatson	source = SLOT(ifnetlabel);
1260101099Srwatson	dest = SLOT(mbuflabel);
1261101099Srwatson
1262101099Srwatson	mac_biba_copy_single(source, dest);
1263101099Srwatson}
1264101099Srwatson
1265101099Srwatsonstatic void
1266101099Srwatsonmac_biba_create_mbuf_multicast_encap(struct mbuf *oldmbuf,
1267101099Srwatson    struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel,
1268101099Srwatson    struct mbuf *newmbuf, struct label *newmbuflabel)
1269101099Srwatson{
1270101099Srwatson	struct mac_biba *source, *dest;
1271101099Srwatson
1272101099Srwatson	source = SLOT(oldmbuflabel);
1273101099Srwatson	dest = SLOT(newmbuflabel);
1274101099Srwatson
1275101099Srwatson	mac_biba_copy_single(source, dest);
1276101099Srwatson}
1277101099Srwatson
1278101099Srwatsonstatic void
1279101099Srwatsonmac_biba_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel,
1280101099Srwatson    struct mbuf *newmbuf, struct label *newmbuflabel)
1281101099Srwatson{
1282101099Srwatson	struct mac_biba *source, *dest;
1283101099Srwatson
1284101099Srwatson	source = SLOT(oldmbuflabel);
1285101099Srwatson	dest = SLOT(newmbuflabel);
1286101099Srwatson
1287101099Srwatson	mac_biba_copy_single(source, dest);
1288101099Srwatson}
1289101099Srwatson
1290101099Srwatsonstatic int
1291101099Srwatsonmac_biba_fragment_match(struct mbuf *fragment, struct label *fragmentlabel,
1292101099Srwatson    struct ipq *ipq, struct label *ipqlabel)
1293101099Srwatson{
1294101099Srwatson	struct mac_biba *a, *b;
1295101099Srwatson
1296101099Srwatson	a = SLOT(ipqlabel);
1297101099Srwatson	b = SLOT(fragmentlabel);
1298101099Srwatson
1299101099Srwatson	return (mac_biba_equal_single(a, b));
1300101099Srwatson}
1301101099Srwatson
1302101099Srwatsonstatic void
1303101099Srwatsonmac_biba_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet,
1304101099Srwatson    struct label *ifnetlabel, struct label *newlabel)
1305101099Srwatson{
1306101099Srwatson	struct mac_biba *source, *dest;
1307101099Srwatson
1308101099Srwatson	source = SLOT(newlabel);
1309101099Srwatson	dest = SLOT(ifnetlabel);
1310101099Srwatson
1311105656Srwatson	mac_biba_copy(source, dest);
1312101099Srwatson}
1313101099Srwatson
1314101099Srwatsonstatic void
1315101099Srwatsonmac_biba_update_ipq(struct mbuf *fragment, struct label *fragmentlabel,
1316101099Srwatson    struct ipq *ipq, struct label *ipqlabel)
1317101099Srwatson{
1318101099Srwatson
1319101099Srwatson	/* NOOP: we only accept matching labels, so no need to update */
1320101099Srwatson}
1321101099Srwatson
1322101099Srwatson/*
1323101099Srwatson * Labeling event operations: processes.
1324101099Srwatson */
1325101099Srwatsonstatic void
1326101099Srwatsonmac_biba_create_cred(struct ucred *cred_parent, struct ucred *cred_child)
1327101099Srwatson{
1328101099Srwatson	struct mac_biba *source, *dest;
1329101099Srwatson
1330101099Srwatson	source = SLOT(&cred_parent->cr_label);
1331101099Srwatson	dest = SLOT(&cred_child->cr_label);
1332101099Srwatson
1333101099Srwatson	mac_biba_copy_single(source, dest);
1334101099Srwatson	mac_biba_copy_range(source, dest);
1335101099Srwatson}
1336101099Srwatson
1337101099Srwatsonstatic void
1338101099Srwatsonmac_biba_create_proc0(struct ucred *cred)
1339101099Srwatson{
1340101099Srwatson	struct mac_biba *dest;
1341101099Srwatson
1342101099Srwatson	dest = SLOT(&cred->cr_label);
1343101099Srwatson
1344105643Srwatson	mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1345105643Srwatson	mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL,
1346105643Srwatson	    MAC_BIBA_TYPE_HIGH, 0, NULL);
1347101099Srwatson}
1348101099Srwatson
1349101099Srwatsonstatic void
1350101099Srwatsonmac_biba_create_proc1(struct ucred *cred)
1351101099Srwatson{
1352101099Srwatson	struct mac_biba *dest;
1353101099Srwatson
1354101099Srwatson	dest = SLOT(&cred->cr_label);
1355101099Srwatson
1356105643Srwatson	mac_biba_set_single(dest, MAC_BIBA_TYPE_HIGH, 0, NULL);
1357105643Srwatson	mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL,
1358105643Srwatson	    MAC_BIBA_TYPE_HIGH, 0, NULL);
1359101099Srwatson}
1360101099Srwatson
1361101099Srwatsonstatic void
1362101099Srwatsonmac_biba_relabel_cred(struct ucred *cred, struct label *newlabel)
1363101099Srwatson{
1364101099Srwatson	struct mac_biba *source, *dest;
1365101099Srwatson
1366101099Srwatson	source = SLOT(newlabel);
1367101099Srwatson	dest = SLOT(&cred->cr_label);
1368101099Srwatson
1369105656Srwatson	mac_biba_copy(source, dest);
1370101099Srwatson}
1371101099Srwatson
1372101099Srwatson/*
1373101099Srwatson * Access control checks.
1374101099Srwatson */
1375101099Srwatsonstatic int
1376101099Srwatsonmac_biba_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel,
1377101099Srwatson    struct ifnet *ifnet, struct label *ifnetlabel)
1378101099Srwatson{
1379101099Srwatson	struct mac_biba *a, *b;
1380101099Srwatson
1381101099Srwatson	if (!mac_biba_enabled)
1382101099Srwatson		return (0);
1383101099Srwatson
1384101099Srwatson	a = SLOT(bpflabel);
1385101099Srwatson	b = SLOT(ifnetlabel);
1386101099Srwatson
1387101099Srwatson	if (mac_biba_equal_single(a, b))
1388101099Srwatson		return (0);
1389101099Srwatson	return (EACCES);
1390101099Srwatson}
1391101099Srwatson
1392101099Srwatsonstatic int
1393101099Srwatsonmac_biba_check_cred_relabel(struct ucred *cred, struct label *newlabel)
1394101099Srwatson{
1395101099Srwatson	struct mac_biba *subj, *new;
1396105634Srwatson	int error;
1397101099Srwatson
1398101099Srwatson	subj = SLOT(&cred->cr_label);
1399101099Srwatson	new = SLOT(newlabel);
1400101099Srwatson
1401101099Srwatson	/*
1402105634Srwatson	 * If there is a Biba label update for the credential, it may
1403105634Srwatson	 * be an update of the single, range, or both.
1404101099Srwatson	 */
1405105634Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
1406105634Srwatson	if (error)
1407105634Srwatson		return (error);
1408101099Srwatson
1409101099Srwatson	/*
1410105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
1411101099Srwatson	 */
1412105634Srwatson	if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) {
1413105634Srwatson		/*
1414110351Srwatson		 * If the change request modifies both the Biba label
1415110351Srwatson		 * single and range, check that the new single will be
1416110351Srwatson		 * in the new range.
1417110351Srwatson		 */
1418110351Srwatson		if ((new->mb_flags & MAC_BIBA_FLAGS_BOTH) ==
1419110351Srwatson		    MAC_BIBA_FLAGS_BOTH &&
1420110351Srwatson		    !mac_biba_single_in_range(new, new))
1421110351Srwatson			return (EINVAL);
1422110351Srwatson
1423110351Srwatson		/*
1424105634Srwatson		 * To change the Biba single label on a credential, the
1425105634Srwatson		 * new single label must be in the current range.
1426105634Srwatson		 */
1427105634Srwatson		if (new->mb_flags & MAC_BIBA_FLAG_SINGLE &&
1428105634Srwatson		    !mac_biba_single_in_range(new, subj))
1429105634Srwatson			return (EPERM);
1430101099Srwatson
1431105634Srwatson		/*
1432105634Srwatson		 * To change the Biba range on a credential, the new
1433105634Srwatson		 * range label must be in the current range.
1434105634Srwatson		 */
1435105634Srwatson		if (new->mb_flags & MAC_BIBA_FLAG_RANGE &&
1436105634Srwatson		    !mac_biba_range_in_range(new, subj))
1437105634Srwatson			return (EPERM);
1438101099Srwatson
1439105634Srwatson		/*
1440105634Srwatson		 * To have EQUAL in any component of the new credential
1441105634Srwatson		 * Biba label, the subject must already have EQUAL in
1442105634Srwatson		 * their label.
1443105634Srwatson		 */
1444105634Srwatson		if (mac_biba_contains_equal(new)) {
1445106090Srwatson			error = mac_biba_subject_privileged(subj);
1446105634Srwatson			if (error)
1447105634Srwatson				return (error);
1448105634Srwatson		}
1449105634Srwatson	}
1450105634Srwatson
1451101099Srwatson	return (0);
1452101099Srwatson}
1453101099Srwatson
1454101099Srwatsonstatic int
1455101099Srwatsonmac_biba_check_cred_visible(struct ucred *u1, struct ucred *u2)
1456101099Srwatson{
1457101099Srwatson	struct mac_biba *subj, *obj;
1458101099Srwatson
1459101099Srwatson	if (!mac_biba_enabled)
1460101099Srwatson		return (0);
1461101099Srwatson
1462101099Srwatson	subj = SLOT(&u1->cr_label);
1463101099Srwatson	obj = SLOT(&u2->cr_label);
1464101099Srwatson
1465101099Srwatson	/* XXX: range */
1466101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1467101099Srwatson		return (ESRCH);
1468101099Srwatson
1469101099Srwatson	return (0);
1470101099Srwatson}
1471101099Srwatson
1472101099Srwatsonstatic int
1473101099Srwatsonmac_biba_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet,
1474101099Srwatson    struct label *ifnetlabel, struct label *newlabel)
1475101099Srwatson{
1476101099Srwatson	struct mac_biba *subj, *new;
1477105634Srwatson	int error;
1478101099Srwatson
1479101099Srwatson	subj = SLOT(&cred->cr_label);
1480101099Srwatson	new = SLOT(newlabel);
1481101099Srwatson
1482105634Srwatson	/*
1483105634Srwatson	 * If there is a Biba label update for the interface, it may
1484105634Srwatson	 * be an update of the single, range, or both.
1485105634Srwatson	 */
1486105634Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
1487105634Srwatson	if (error)
1488105634Srwatson		return (error);
1489101099Srwatson
1490105634Srwatson	/*
1491106160Srwatson	 * Relabling network interfaces requires Biba privilege.
1492106160Srwatson	 */
1493106160Srwatson	error = mac_biba_subject_privileged(subj);
1494106160Srwatson	if (error)
1495106160Srwatson		return (error);
1496106160Srwatson
1497106160Srwatson	/*
1498105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
1499105634Srwatson	 */
1500105634Srwatson	if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) {
1501105634Srwatson		/*
1502105634Srwatson		 * Rely on the traditional superuser status for the Biba
1503105634Srwatson		 * interface relabel requirements.  XXXMAC: This will go
1504105634Srwatson		 * away.
1505105634Srwatson		 */
1506105634Srwatson		error = suser_cred(cred, 0);
1507105634Srwatson		if (error)
1508105634Srwatson			return (EPERM);
1509105634Srwatson
1510105634Srwatson		/*
1511105634Srwatson		 * XXXMAC: Additional consistency tests regarding the single
1512105634Srwatson		 * and the range of the new label might be performed here.
1513105634Srwatson		 */
1514105634Srwatson	}
1515105634Srwatson
1516105634Srwatson	return (0);
1517101099Srwatson}
1518101099Srwatson
1519103759Srwatsonstatic int
1520101099Srwatsonmac_biba_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel,
1521101099Srwatson    struct mbuf *m, struct label *mbuflabel)
1522101099Srwatson{
1523101099Srwatson	struct mac_biba *p, *i;
1524103761Srwatson
1525101099Srwatson	if (!mac_biba_enabled)
1526101099Srwatson		return (0);
1527101099Srwatson
1528101099Srwatson	p = SLOT(mbuflabel);
1529101099Srwatson	i = SLOT(ifnetlabel);
1530103759Srwatson
1531101099Srwatson	return (mac_biba_single_in_range(p, i) ? 0 : EACCES);
1532101099Srwatson}
1533101099Srwatson
1534101099Srwatsonstatic int
1535110354Srwatsonmac_biba_check_kld_load(struct ucred *cred, struct vnode *vp,
1536110354Srwatson    struct label *label)
1537110354Srwatson{
1538110354Srwatson	struct mac_biba *subj, *obj;
1539110354Srwatson	int error;
1540110354Srwatson
1541110354Srwatson	if (!mac_biba_enabled)
1542110354Srwatson		return (0);
1543110354Srwatson
1544110354Srwatson	subj = SLOT(&cred->cr_label);
1545110354Srwatson
1546110354Srwatson	error = mac_biba_subject_privileged(subj);
1547110354Srwatson	if (error)
1548110354Srwatson		return (error);
1549110354Srwatson
1550110354Srwatson	obj = SLOT(label);
1551110354Srwatson	if (!mac_biba_high_single(obj))
1552110354Srwatson		return (EACCES);
1553110354Srwatson
1554110354Srwatson	return (0);
1555110354Srwatson}
1556110354Srwatson
1557110354Srwatson
1558110354Srwatsonstatic int
1559110354Srwatsonmac_biba_check_kld_unload(struct ucred *cred)
1560110354Srwatson{
1561110354Srwatson	struct mac_biba *subj;
1562110354Srwatson
1563110354Srwatson	if (!mac_biba_enabled)
1564110354Srwatson		return (0);
1565110354Srwatson
1566110354Srwatson	subj = SLOT(&cred->cr_label);
1567110354Srwatson
1568110354Srwatson	return (mac_biba_subject_privileged(subj));
1569110354Srwatson}
1570110354Srwatson
1571110354Srwatsonstatic int
1572101099Srwatsonmac_biba_check_mount_stat(struct ucred *cred, struct mount *mp,
1573101099Srwatson    struct label *mntlabel)
1574101099Srwatson{
1575101099Srwatson	struct mac_biba *subj, *obj;
1576101099Srwatson
1577101099Srwatson	if (!mac_biba_enabled)
1578101099Srwatson		return (0);
1579101099Srwatson
1580101099Srwatson	subj = SLOT(&cred->cr_label);
1581101099Srwatson	obj = SLOT(mntlabel);
1582101099Srwatson
1583101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1584101099Srwatson		return (EACCES);
1585101099Srwatson
1586101099Srwatson	return (0);
1587101099Srwatson}
1588101099Srwatson
1589101099Srwatsonstatic int
1590101099Srwatsonmac_biba_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe,
1591101099Srwatson    struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data)
1592101099Srwatson{
1593103759Srwatson
1594101099Srwatson	if(!mac_biba_enabled)
1595101099Srwatson		return (0);
1596101099Srwatson
1597101099Srwatson	/* XXX: This will be implemented soon... */
1598101099Srwatson
1599101099Srwatson	return (0);
1600101099Srwatson}
1601101099Srwatson
1602101099Srwatsonstatic int
1603102115Srwatsonmac_biba_check_pipe_poll(struct ucred *cred, struct pipe *pipe,
1604102115Srwatson    struct label *pipelabel)
1605101099Srwatson{
1606101099Srwatson	struct mac_biba *subj, *obj;
1607101099Srwatson
1608101099Srwatson	if (!mac_biba_enabled)
1609101099Srwatson		return (0);
1610101099Srwatson
1611101099Srwatson	subj = SLOT(&cred->cr_label);
1612101099Srwatson	obj = SLOT((pipelabel));
1613101099Srwatson
1614102115Srwatson	if (!mac_biba_dominate_single(obj, subj))
1615102115Srwatson		return (EACCES);
1616101099Srwatson
1617101099Srwatson	return (0);
1618101099Srwatson}
1619101099Srwatson
1620101099Srwatsonstatic int
1621102115Srwatsonmac_biba_check_pipe_read(struct ucred *cred, struct pipe *pipe,
1622102115Srwatson    struct label *pipelabel)
1623102115Srwatson{
1624102115Srwatson	struct mac_biba *subj, *obj;
1625102115Srwatson
1626102115Srwatson	if (!mac_biba_enabled)
1627102115Srwatson		return (0);
1628102115Srwatson
1629102115Srwatson	subj = SLOT(&cred->cr_label);
1630102115Srwatson	obj = SLOT((pipelabel));
1631102115Srwatson
1632102115Srwatson	if (!mac_biba_dominate_single(obj, subj))
1633102115Srwatson		return (EACCES);
1634102115Srwatson
1635102115Srwatson	return (0);
1636102115Srwatson}
1637102115Srwatson
1638102115Srwatsonstatic int
1639101099Srwatsonmac_biba_check_pipe_relabel(struct ucred *cred, struct pipe *pipe,
1640101099Srwatson    struct label *pipelabel, struct label *newlabel)
1641101099Srwatson{
1642101099Srwatson	struct mac_biba *subj, *obj, *new;
1643105634Srwatson	int error;
1644101099Srwatson
1645101099Srwatson	new = SLOT(newlabel);
1646101099Srwatson	subj = SLOT(&cred->cr_label);
1647101099Srwatson	obj = SLOT(pipelabel);
1648101099Srwatson
1649101099Srwatson	/*
1650105634Srwatson	 * If there is a Biba label update for a pipe, it must be a
1651105634Srwatson	 * single update.
1652101099Srwatson	 */
1653105634Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE);
1654105634Srwatson	if (error)
1655105634Srwatson		return (error);
1656101099Srwatson
1657101099Srwatson	/*
1658105634Srwatson	 * To perform a relabel of a pipe (Biba label or not), Biba must
1659105634Srwatson	 * authorize the relabel.
1660101099Srwatson	 */
1661105634Srwatson	if (!mac_biba_single_in_range(obj, subj))
1662101099Srwatson		return (EPERM);
1663101099Srwatson
1664101099Srwatson	/*
1665105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
1666101099Srwatson	 */
1667105634Srwatson	if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) {
1668105634Srwatson		/*
1669105634Srwatson		 * To change the Biba label on a pipe, the new pipe label
1670105634Srwatson		 * must be in the subject range.
1671105634Srwatson		 */
1672105634Srwatson		if (!mac_biba_single_in_range(new, subj))
1673105634Srwatson			return (EPERM);
1674101099Srwatson
1675105634Srwatson		/*
1676105634Srwatson		 * To change the Biba label on a pipe to be EQUAL, the
1677105634Srwatson		 * subject must have appropriate privilege.
1678105634Srwatson		 */
1679105634Srwatson		if (mac_biba_contains_equal(new)) {
1680106090Srwatson			error = mac_biba_subject_privileged(subj);
1681105634Srwatson			if (error)
1682105634Srwatson				return (error);
1683105634Srwatson		}
1684105634Srwatson	}
1685105634Srwatson
1686101099Srwatson	return (0);
1687101099Srwatson}
1688101099Srwatson
1689101099Srwatsonstatic int
1690102115Srwatsonmac_biba_check_pipe_stat(struct ucred *cred, struct pipe *pipe,
1691102115Srwatson    struct label *pipelabel)
1692102115Srwatson{
1693102115Srwatson	struct mac_biba *subj, *obj;
1694102115Srwatson
1695102115Srwatson	if (!mac_biba_enabled)
1696102115Srwatson		return (0);
1697102115Srwatson
1698102115Srwatson	subj = SLOT(&cred->cr_label);
1699102115Srwatson	obj = SLOT((pipelabel));
1700102115Srwatson
1701102115Srwatson	if (!mac_biba_dominate_single(obj, subj))
1702102115Srwatson		return (EACCES);
1703102115Srwatson
1704102115Srwatson	return (0);
1705102115Srwatson}
1706102115Srwatson
1707102115Srwatsonstatic int
1708102115Srwatsonmac_biba_check_pipe_write(struct ucred *cred, struct pipe *pipe,
1709102115Srwatson    struct label *pipelabel)
1710102115Srwatson{
1711102115Srwatson	struct mac_biba *subj, *obj;
1712102115Srwatson
1713102115Srwatson	if (!mac_biba_enabled)
1714102115Srwatson		return (0);
1715102115Srwatson
1716102115Srwatson	subj = SLOT(&cred->cr_label);
1717102115Srwatson	obj = SLOT((pipelabel));
1718102115Srwatson
1719102115Srwatson	if (!mac_biba_dominate_single(subj, obj))
1720102115Srwatson		return (EACCES);
1721102115Srwatson
1722102115Srwatson	return (0);
1723102115Srwatson}
1724102115Srwatson
1725102115Srwatsonstatic int
1726101099Srwatsonmac_biba_check_proc_debug(struct ucred *cred, struct proc *proc)
1727101099Srwatson{
1728101099Srwatson	struct mac_biba *subj, *obj;
1729101099Srwatson
1730101099Srwatson	if (!mac_biba_enabled)
1731101099Srwatson		return (0);
1732101099Srwatson
1733101099Srwatson	subj = SLOT(&cred->cr_label);
1734101099Srwatson	obj = SLOT(&proc->p_ucred->cr_label);
1735101099Srwatson
1736101099Srwatson	/* XXX: range checks */
1737101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1738101099Srwatson		return (ESRCH);
1739101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1740101099Srwatson		return (EACCES);
1741101099Srwatson
1742101099Srwatson	return (0);
1743101099Srwatson}
1744101099Srwatson
1745101099Srwatsonstatic int
1746101099Srwatsonmac_biba_check_proc_sched(struct ucred *cred, struct proc *proc)
1747101099Srwatson{
1748101099Srwatson	struct mac_biba *subj, *obj;
1749103759Srwatson
1750101099Srwatson	if (!mac_biba_enabled)
1751101099Srwatson		return (0);
1752101099Srwatson
1753101099Srwatson	subj = SLOT(&cred->cr_label);
1754101099Srwatson	obj = SLOT(&proc->p_ucred->cr_label);
1755103759Srwatson
1756101099Srwatson	/* XXX: range checks */
1757101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1758101099Srwatson		return (ESRCH);
1759101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1760101099Srwatson		return (EACCES);
1761101099Srwatson
1762101099Srwatson	return (0);
1763101099Srwatson}
1764101099Srwatson
1765101099Srwatsonstatic int
1766101099Srwatsonmac_biba_check_proc_signal(struct ucred *cred, struct proc *proc, int signum)
1767101099Srwatson{
1768101099Srwatson	struct mac_biba *subj, *obj;
1769103759Srwatson
1770101099Srwatson	if (!mac_biba_enabled)
1771101099Srwatson		return (0);
1772101099Srwatson
1773101099Srwatson	subj = SLOT(&cred->cr_label);
1774101099Srwatson	obj = SLOT(&proc->p_ucred->cr_label);
1775103759Srwatson
1776101099Srwatson	/* XXX: range checks */
1777101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1778101099Srwatson		return (ESRCH);
1779101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1780101099Srwatson		return (EACCES);
1781101099Srwatson
1782101099Srwatson	return (0);
1783101099Srwatson}
1784101099Srwatson
1785101099Srwatsonstatic int
1786101934Srwatsonmac_biba_check_socket_deliver(struct socket *so, struct label *socketlabel,
1787101099Srwatson    struct mbuf *m, struct label *mbuflabel)
1788101099Srwatson{
1789101099Srwatson	struct mac_biba *p, *s;
1790101099Srwatson
1791101099Srwatson	if (!mac_biba_enabled)
1792101099Srwatson		return (0);
1793101099Srwatson
1794101099Srwatson	p = SLOT(mbuflabel);
1795101099Srwatson	s = SLOT(socketlabel);
1796101099Srwatson
1797101099Srwatson	return (mac_biba_equal_single(p, s) ? 0 : EACCES);
1798101099Srwatson}
1799101099Srwatson
1800101099Srwatsonstatic int
1801106214Srwatsonmac_biba_check_socket_relabel(struct ucred *cred, struct socket *so,
1802101099Srwatson    struct label *socketlabel, struct label *newlabel)
1803101099Srwatson{
1804101099Srwatson	struct mac_biba *subj, *obj, *new;
1805105634Srwatson	int error;
1806101099Srwatson
1807101099Srwatson	new = SLOT(newlabel);
1808101099Srwatson	subj = SLOT(&cred->cr_label);
1809101099Srwatson	obj = SLOT(socketlabel);
1810101099Srwatson
1811101099Srwatson	/*
1812105634Srwatson	 * If there is a Biba label update for the socket, it may be
1813105634Srwatson	 * an update of single.
1814101099Srwatson	 */
1815105634Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE);
1816105634Srwatson	if (error)
1817105634Srwatson		return (error);
1818101099Srwatson
1819101099Srwatson	/*
1820105634Srwatson	 * To relabel a socket, the old socket single must be in the subject
1821101099Srwatson	 * range.
1822101099Srwatson	 */
1823105634Srwatson	if (!mac_biba_single_in_range(obj, subj))
1824101099Srwatson		return (EPERM);
1825101099Srwatson
1826101099Srwatson	/*
1827105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
1828101099Srwatson	 */
1829105634Srwatson	if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) {
1830105634Srwatson		/*
1831105634Srwatson		 * To relabel a socket, the new socket single must be in
1832105634Srwatson		 * the subject range.
1833105634Srwatson		 */
1834105634Srwatson		if (!mac_biba_single_in_range(new, subj))
1835105634Srwatson			return (EPERM);
1836101099Srwatson
1837105634Srwatson		/*
1838105634Srwatson		 * To change the Biba label on the socket to contain EQUAL,
1839105634Srwatson		 * the subject must have appropriate privilege.
1840105634Srwatson		 */
1841105634Srwatson		if (mac_biba_contains_equal(new)) {
1842106090Srwatson			error = mac_biba_subject_privileged(subj);
1843105634Srwatson			if (error)
1844105634Srwatson				return (error);
1845105634Srwatson		}
1846105634Srwatson	}
1847105634Srwatson
1848101099Srwatson	return (0);
1849101099Srwatson}
1850101099Srwatson
1851101099Srwatsonstatic int
1852101099Srwatsonmac_biba_check_socket_visible(struct ucred *cred, struct socket *socket,
1853101099Srwatson    struct label *socketlabel)
1854101099Srwatson{
1855101099Srwatson	struct mac_biba *subj, *obj;
1856101099Srwatson
1857105722Srwatson	if (!mac_biba_enabled)
1858105722Srwatson		return (0);
1859105722Srwatson
1860101099Srwatson	subj = SLOT(&cred->cr_label);
1861101099Srwatson	obj = SLOT(socketlabel);
1862101099Srwatson
1863101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1864101099Srwatson		return (ENOENT);
1865101099Srwatson
1866101099Srwatson	return (0);
1867101099Srwatson}
1868101099Srwatson
1869101099Srwatsonstatic int
1870112574Srwatsonmac_biba_check_sysarch_ioperm(struct ucred *cred)
1871112574Srwatson{
1872112574Srwatson	struct mac_biba *subj;
1873112574Srwatson	int error;
1874112574Srwatson
1875112574Srwatson	if (!mac_biba_enabled)
1876112574Srwatson		return (0);
1877112574Srwatson
1878112574Srwatson	subj = SLOT(&cred->cr_label);
1879112574Srwatson
1880112574Srwatson	error = mac_biba_subject_privileged(subj);
1881112574Srwatson	if (error)
1882112574Srwatson		return (error);
1883112574Srwatson
1884112574Srwatson	return (0);
1885112574Srwatson}
1886112574Srwatson
1887112574Srwatsonstatic int
1888106418Srwatsonmac_biba_check_system_acct(struct ucred *cred, struct vnode *vp,
1889106418Srwatson    struct label *label)
1890106418Srwatson{
1891106418Srwatson	struct mac_biba *subj, *obj;
1892106418Srwatson	int error;
1893106418Srwatson
1894106418Srwatson	if (!mac_biba_enabled)
1895106418Srwatson		return (0);
1896106418Srwatson
1897106418Srwatson	subj = SLOT(&cred->cr_label);
1898106418Srwatson
1899106418Srwatson	error = mac_biba_subject_privileged(subj);
1900106418Srwatson	if (error)
1901106418Srwatson		return (error);
1902106418Srwatson
1903106418Srwatson	if (label == NULL)
1904106418Srwatson		return (0);
1905106418Srwatson
1906106418Srwatson	obj = SLOT(label);
1907106418Srwatson	if (!mac_biba_high_single(obj))
1908106418Srwatson		return (EACCES);
1909106418Srwatson
1910106418Srwatson	return (0);
1911106418Srwatson}
1912106418Srwatson
1913106418Srwatsonstatic int
1914106418Srwatsonmac_biba_check_system_settime(struct ucred *cred)
1915106418Srwatson{
1916106418Srwatson	struct mac_biba *subj;
1917106418Srwatson	int error;
1918106418Srwatson
1919106418Srwatson	if (!mac_biba_enabled)
1920106418Srwatson		return (0);
1921106418Srwatson
1922106418Srwatson	subj = SLOT(&cred->cr_label);
1923106418Srwatson
1924106418Srwatson	error = mac_biba_subject_privileged(subj);
1925106418Srwatson	if (error)
1926106418Srwatson		return (error);
1927106418Srwatson
1928106418Srwatson	return (0);
1929106418Srwatson}
1930106418Srwatson
1931106418Srwatsonstatic int
1932106161Srwatsonmac_biba_check_system_swapon(struct ucred *cred, struct vnode *vp,
1933106161Srwatson    struct label *label)
1934106161Srwatson{
1935106161Srwatson	struct mac_biba *subj, *obj;
1936106416Srwatson	int error;
1937106161Srwatson
1938106161Srwatson	if (!mac_biba_enabled)
1939106161Srwatson		return (0);
1940106161Srwatson
1941106161Srwatson	subj = SLOT(&cred->cr_label);
1942106161Srwatson	obj = SLOT(label);
1943106161Srwatson
1944106416Srwatson	error = mac_biba_subject_privileged(subj);
1945106416Srwatson	if (error)
1946106416Srwatson		return (error);
1947106161Srwatson
1948106161Srwatson	if (!mac_biba_high_single(obj))
1949106161Srwatson		return (EACCES);
1950106161Srwatson
1951106161Srwatson	return (0);
1952106161Srwatson}
1953106161Srwatson
1954106161Srwatsonstatic int
1955112574Srwatsonmac_biba_check_system_swapoff(struct ucred *cred, struct vnode *vp,
1956112574Srwatson    struct label *label)
1957112574Srwatson{
1958112574Srwatson	struct mac_biba *subj, *obj;
1959112574Srwatson	int error;
1960112574Srwatson
1961112574Srwatson	if (!mac_biba_enabled)
1962112574Srwatson		return (0);
1963112574Srwatson
1964112574Srwatson	subj = SLOT(&cred->cr_label);
1965112574Srwatson	obj = SLOT(label);
1966112574Srwatson
1967112574Srwatson	error = mac_biba_subject_privileged(subj);
1968112574Srwatson	if (error)
1969112574Srwatson		return (error);
1970112574Srwatson
1971112574Srwatson	return (0);
1972112574Srwatson}
1973112574Srwatson
1974112574Srwatsonstatic int
1975106161Srwatsonmac_biba_check_system_sysctl(struct ucred *cred, int *name, u_int namelen,
1976106161Srwatson    void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen)
1977106161Srwatson{
1978106161Srwatson	struct mac_biba *subj;
1979106161Srwatson	int error;
1980106161Srwatson
1981106161Srwatson	if (!mac_biba_enabled)
1982106161Srwatson		return (0);
1983106161Srwatson
1984106161Srwatson	subj = SLOT(&cred->cr_label);
1985106161Srwatson
1986106161Srwatson	/*
1987106161Srwatson	 * In general, treat sysctl variables as biba/high, but also
1988106161Srwatson	 * require privilege to change them, since they are a
1989106161Srwatson	 * communications channel between grades.  Exempt MIB
1990106161Srwatson	 * queries from this due to undocmented sysctl magic.
1991106161Srwatson	 * XXXMAC: This probably requires some more review.
1992106161Srwatson	 */
1993106161Srwatson	if (new != NULL) {
1994106161Srwatson		if (namelen > 0 && name[0] == 0)
1995106161Srwatson			return (0);
1996106161Srwatson
1997106161Srwatson		if (!mac_biba_subject_dominate_high(subj))
1998106161Srwatson			return (EACCES);
1999106161Srwatson
2000106161Srwatson		error = mac_biba_subject_privileged(subj);
2001106161Srwatson		if (error)
2002106161Srwatson			return (error);
2003106161Srwatson	}
2004106161Srwatson
2005106161Srwatson	return (0);
2006106161Srwatson}
2007106161Srwatson
2008106161Srwatsonstatic int
2009101099Srwatsonmac_biba_check_vnode_chdir(struct ucred *cred, struct vnode *dvp,
2010101099Srwatson    struct label *dlabel)
2011101099Srwatson{
2012101099Srwatson	struct mac_biba *subj, *obj;
2013101099Srwatson
2014101099Srwatson	if (!mac_biba_enabled)
2015101099Srwatson		return (0);
2016101099Srwatson
2017101099Srwatson	subj = SLOT(&cred->cr_label);
2018101099Srwatson	obj = SLOT(dlabel);
2019101099Srwatson
2020101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
2021101099Srwatson		return (EACCES);
2022101099Srwatson
2023101099Srwatson	return (0);
2024101099Srwatson}
2025101099Srwatson
2026101099Srwatsonstatic int
2027101099Srwatsonmac_biba_check_vnode_chroot(struct ucred *cred, struct vnode *dvp,
2028101099Srwatson    struct label *dlabel)
2029101099Srwatson{
2030101099Srwatson	struct mac_biba *subj, *obj;
2031101099Srwatson
2032101099Srwatson	if (!mac_biba_enabled)
2033101099Srwatson		return (0);
2034101099Srwatson
2035101099Srwatson	subj = SLOT(&cred->cr_label);
2036101099Srwatson	obj = SLOT(dlabel);
2037101099Srwatson
2038101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
2039101099Srwatson		return (EACCES);
2040101099Srwatson
2041101099Srwatson	return (0);
2042101099Srwatson}
2043101099Srwatson
2044101099Srwatsonstatic int
2045101099Srwatsonmac_biba_check_vnode_create(struct ucred *cred, struct vnode *dvp,
2046101099Srwatson    struct label *dlabel, struct componentname *cnp, struct vattr *vap)
2047101099Srwatson{
2048101099Srwatson	struct mac_biba *subj, *obj;
2049101099Srwatson
2050101099Srwatson	if (!mac_biba_enabled)
2051101099Srwatson		return (0);
2052101099Srwatson
2053101099Srwatson	subj = SLOT(&cred->cr_label);
2054101099Srwatson	obj = SLOT(dlabel);
2055101099Srwatson
2056101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2057101099Srwatson		return (EACCES);
2058101099Srwatson
2059101099Srwatson	return (0);
2060101099Srwatson}
2061101099Srwatson
2062101099Srwatsonstatic int
2063101099Srwatsonmac_biba_check_vnode_delete(struct ucred *cred, struct vnode *dvp,
2064101099Srwatson    struct label *dlabel, struct vnode *vp, struct label *label,
2065101099Srwatson    struct componentname *cnp)
2066101099Srwatson{
2067101099Srwatson	struct mac_biba *subj, *obj;
2068101099Srwatson
2069101099Srwatson	if (!mac_biba_enabled)
2070101099Srwatson		return (0);
2071101099Srwatson
2072101099Srwatson	subj = SLOT(&cred->cr_label);
2073101099Srwatson	obj = SLOT(dlabel);
2074101099Srwatson
2075101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2076101099Srwatson		return (EACCES);
2077101099Srwatson
2078101099Srwatson	obj = SLOT(label);
2079101099Srwatson
2080101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2081101099Srwatson		return (EACCES);
2082101099Srwatson
2083101099Srwatson	return (0);
2084101099Srwatson}
2085101099Srwatson
2086101099Srwatsonstatic int
2087101099Srwatsonmac_biba_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
2088101099Srwatson    struct label *label, acl_type_t type)
2089101099Srwatson{
2090101099Srwatson	struct mac_biba *subj, *obj;
2091101099Srwatson
2092101099Srwatson	if (!mac_biba_enabled)
2093101099Srwatson		return (0);
2094101099Srwatson
2095101099Srwatson	subj = SLOT(&cred->cr_label);
2096101099Srwatson	obj = SLOT(label);
2097101099Srwatson
2098101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2099101099Srwatson		return (EACCES);
2100101099Srwatson
2101101099Srwatson	return (0);
2102101099Srwatson}
2103101099Srwatson
2104101099Srwatsonstatic int
2105101099Srwatsonmac_biba_check_vnode_exec(struct ucred *cred, struct vnode *vp,
2106106648Srwatson    struct label *label, struct image_params *imgp,
2107106648Srwatson    struct label *execlabel)
2108101099Srwatson{
2109106648Srwatson	struct mac_biba *subj, *obj, *exec;
2110106648Srwatson	int error;
2111101099Srwatson
2112106648Srwatson	if (execlabel != NULL) {
2113106648Srwatson		/*
2114106648Srwatson		 * We currently don't permit labels to be changed at
2115106648Srwatson		 * exec-time as part of Biba, so disallow non-NULL
2116106648Srwatson		 * Biba label elements in the execlabel.
2117106648Srwatson		 */
2118106648Srwatson		exec = SLOT(execlabel);
2119106648Srwatson		error = biba_atmostflags(exec, 0);
2120106648Srwatson		if (error)
2121106648Srwatson			return (error);
2122106648Srwatson	}
2123106648Srwatson
2124101099Srwatson	if (!mac_biba_enabled)
2125101099Srwatson		return (0);
2126101099Srwatson
2127101099Srwatson	subj = SLOT(&cred->cr_label);
2128101099Srwatson	obj = SLOT(label);
2129101099Srwatson
2130101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
2131101099Srwatson		return (EACCES);
2132101099Srwatson
2133101099Srwatson	return (0);
2134101099Srwatson}
2135101099Srwatson
2136101099Srwatsonstatic int
2137101099Srwatsonmac_biba_check_vnode_getacl(struct ucred *cred, struct vnode *vp,
2138101099Srwatson    struct label *label, acl_type_t type)
2139101099Srwatson{
2140101099Srwatson	struct mac_biba *subj, *obj;
2141101099Srwatson
2142101099Srwatson	if (!mac_biba_enabled)
2143101099Srwatson		return (0);
2144101099Srwatson
2145101099Srwatson	subj = SLOT(&cred->cr_label);
2146101099Srwatson	obj = SLOT(label);
2147101099Srwatson
2148101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
2149101099Srwatson		return (EACCES);
2150101099Srwatson
2151101099Srwatson	return (0);
2152101099Srwatson}
2153101099Srwatson
2154101099Srwatsonstatic int
2155101099Srwatsonmac_biba_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
2156101099Srwatson    struct label *label, int attrnamespace, const char *name, struct uio *uio)
2157101099Srwatson{
2158101099Srwatson	struct mac_biba *subj, *obj;
2159101099Srwatson
2160101099Srwatson	if (!mac_biba_enabled)
2161101099Srwatson		return (0);
2162101099Srwatson
2163101099Srwatson	subj = SLOT(&cred->cr_label);
2164101099Srwatson	obj = SLOT(label);
2165101099Srwatson
2166101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
2167101099Srwatson		return (EACCES);
2168101099Srwatson
2169101099Srwatson	return (0);
2170101099Srwatson}
2171101099Srwatson
2172101099Srwatsonstatic int
2173104530Srwatsonmac_biba_check_vnode_link(struct ucred *cred, struct vnode *dvp,
2174104530Srwatson    struct label *dlabel, struct vnode *vp, struct label *label,
2175104530Srwatson    struct componentname *cnp)
2176104530Srwatson{
2177104530Srwatson	struct mac_biba *subj, *obj;
2178104530Srwatson
2179104530Srwatson	if (!mac_biba_enabled)
2180104530Srwatson		return (0);
2181104530Srwatson
2182104530Srwatson	subj = SLOT(&cred->cr_label);
2183104530Srwatson	obj = SLOT(dlabel);
2184104530Srwatson
2185104530Srwatson	if (!mac_biba_dominate_single(subj, obj))
2186104530Srwatson		return (EACCES);
2187104530Srwatson
2188104530Srwatson	obj = SLOT(label);
2189104530Srwatson
2190104530Srwatson	if (!mac_biba_dominate_single(subj, obj))
2191104530Srwatson		return (EACCES);
2192104530Srwatson
2193104530Srwatson	return (0);
2194104530Srwatson}
2195104530Srwatson
2196104530Srwatsonstatic int
2197103759Srwatsonmac_biba_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
2198101099Srwatson    struct label *dlabel, struct componentname *cnp)
2199101099Srwatson{
2200101099Srwatson	struct mac_biba *subj, *obj;
2201103759Srwatson
2202101099Srwatson	if (!mac_biba_enabled)
2203101099Srwatson		return (0);
2204103759Srwatson
2205101099Srwatson	subj = SLOT(&cred->cr_label);
2206101099Srwatson	obj = SLOT(dlabel);
2207103759Srwatson
2208101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
2209101099Srwatson		return (EACCES);
2210101099Srwatson
2211103759Srwatson	return (0);
2212101099Srwatson}
2213101099Srwatson
2214101099Srwatsonstatic int
2215104546Srwatsonmac_biba_check_vnode_mmap(struct ucred *cred, struct vnode *vp,
2216104546Srwatson    struct label *label, int prot)
2217104546Srwatson{
2218104546Srwatson	struct mac_biba *subj, *obj;
2219104546Srwatson
2220104546Srwatson	/*
2221104546Srwatson	 * Rely on the use of open()-time protections to handle
2222104546Srwatson	 * non-revocation cases.
2223104546Srwatson	 */
2224105637Srwatson	if (!mac_biba_enabled || !revocation_enabled)
2225104546Srwatson		return (0);
2226104546Srwatson
2227104546Srwatson	subj = SLOT(&cred->cr_label);
2228104546Srwatson	obj = SLOT(label);
2229104546Srwatson
2230104546Srwatson	if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
2231104546Srwatson		if (!mac_biba_dominate_single(obj, subj))
2232104546Srwatson			return (EACCES);
2233104546Srwatson	}
2234104546Srwatson	if (prot & VM_PROT_WRITE) {
2235104546Srwatson		if (!mac_biba_dominate_single(subj, obj))
2236104546Srwatson			return (EACCES);
2237104546Srwatson	}
2238104546Srwatson
2239104569Srwatson	return (0);
2240104546Srwatson}
2241104546Srwatson
2242104546Srwatsonstatic int
2243101099Srwatsonmac_biba_check_vnode_open(struct ucred *cred, struct vnode *vp,
2244106212Srwatson    struct label *vnodelabel, int acc_mode)
2245101099Srwatson{
2246101099Srwatson	struct mac_biba *subj, *obj;
2247101099Srwatson
2248101099Srwatson	if (!mac_biba_enabled)
2249101099Srwatson		return (0);
2250101099Srwatson
2251101099Srwatson	subj = SLOT(&cred->cr_label);
2252101099Srwatson	obj = SLOT(vnodelabel);
2253101099Srwatson
2254101099Srwatson	/* XXX privilege override for admin? */
2255101099Srwatson	if (acc_mode & (VREAD | VEXEC | VSTAT)) {
2256101099Srwatson		if (!mac_biba_dominate_single(obj, subj))
2257101099Srwatson			return (EACCES);
2258101099Srwatson	}
2259101099Srwatson	if (acc_mode & (VWRITE | VAPPEND | VADMIN)) {
2260101099Srwatson		if (!mac_biba_dominate_single(subj, obj))
2261101099Srwatson			return (EACCES);
2262101099Srwatson	}
2263101099Srwatson
2264101099Srwatson	return (0);
2265101099Srwatson}
2266101099Srwatson
2267101099Srwatsonstatic int
2268102129Srwatsonmac_biba_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred,
2269102129Srwatson    struct vnode *vp, struct label *label)
2270102112Srwatson{
2271102112Srwatson	struct mac_biba *subj, *obj;
2272102112Srwatson
2273105637Srwatson	if (!mac_biba_enabled || !revocation_enabled)
2274102112Srwatson		return (0);
2275102112Srwatson
2276102129Srwatson	subj = SLOT(&active_cred->cr_label);
2277102112Srwatson	obj = SLOT(label);
2278102112Srwatson
2279102112Srwatson	if (!mac_biba_dominate_single(obj, subj))
2280102112Srwatson		return (EACCES);
2281102112Srwatson
2282102112Srwatson	return (0);
2283102112Srwatson}
2284102112Srwatson
2285102112Srwatsonstatic int
2286102129Srwatsonmac_biba_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
2287102129Srwatson    struct vnode *vp, struct label *label)
2288102112Srwatson{
2289102112Srwatson	struct mac_biba *subj, *obj;
2290102112Srwatson
2291105637Srwatson	if (!mac_biba_enabled || !revocation_enabled)
2292102112Srwatson		return (0);
2293102112Srwatson
2294102129Srwatson	subj = SLOT(&active_cred->cr_label);
2295102112Srwatson	obj = SLOT(label);
2296102112Srwatson
2297102112Srwatson	if (!mac_biba_dominate_single(obj, subj))
2298102112Srwatson		return (EACCES);
2299102112Srwatson
2300102112Srwatson	return (0);
2301102112Srwatson}
2302102112Srwatson
2303102112Srwatsonstatic int
2304101099Srwatsonmac_biba_check_vnode_readdir(struct ucred *cred, struct vnode *dvp,
2305101099Srwatson    struct label *dlabel)
2306101099Srwatson{
2307101099Srwatson	struct mac_biba *subj, *obj;
2308101099Srwatson
2309101099Srwatson	if (!mac_biba_enabled)
2310101099Srwatson		return (0);
2311101099Srwatson
2312101099Srwatson	subj = SLOT(&cred->cr_label);
2313101099Srwatson	obj = SLOT(dlabel);
2314101099Srwatson
2315101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
2316101099Srwatson		return (EACCES);
2317101099Srwatson
2318101099Srwatson	return (0);
2319101099Srwatson}
2320101099Srwatson
2321101099Srwatsonstatic int
2322101099Srwatsonmac_biba_check_vnode_readlink(struct ucred *cred, struct vnode *vp,
2323101099Srwatson    struct label *label)
2324101099Srwatson{
2325101099Srwatson	struct mac_biba *subj, *obj;
2326101099Srwatson
2327101099Srwatson	if (!mac_biba_enabled)
2328101099Srwatson		return (0);
2329101099Srwatson
2330101099Srwatson	subj = SLOT(&cred->cr_label);
2331101099Srwatson	obj = SLOT(label);
2332101099Srwatson
2333101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
2334101099Srwatson		return (EACCES);
2335101099Srwatson
2336101099Srwatson	return (0);
2337101099Srwatson}
2338101099Srwatson
2339101099Srwatsonstatic int
2340101099Srwatsonmac_biba_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
2341101099Srwatson    struct label *vnodelabel, struct label *newlabel)
2342101099Srwatson{
2343101099Srwatson	struct mac_biba *old, *new, *subj;
2344105634Srwatson	int error;
2345101099Srwatson
2346101099Srwatson	old = SLOT(vnodelabel);
2347101099Srwatson	new = SLOT(newlabel);
2348101099Srwatson	subj = SLOT(&cred->cr_label);
2349101099Srwatson
2350101099Srwatson	/*
2351105634Srwatson	 * If there is a Biba label update for the vnode, it must be a
2352105634Srwatson	 * single label.
2353101099Srwatson	 */
2354105634Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE);
2355105634Srwatson	if (error)
2356105634Srwatson		return (error);
2357101099Srwatson
2358101099Srwatson	/*
2359105634Srwatson	 * To perform a relabel of the vnode (Biba label or not), Biba must
2360105634Srwatson	 * authorize the relabel.
2361101099Srwatson	 */
2362105634Srwatson	if (!mac_biba_single_in_range(old, subj))
2363101099Srwatson		return (EPERM);
2364101099Srwatson
2365101099Srwatson	/*
2366105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
2367101099Srwatson	 */
2368105634Srwatson	if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) {
2369105634Srwatson		/*
2370105634Srwatson		 * To change the Biba label on a vnode, the new vnode label
2371105634Srwatson		 * must be in the subject range.
2372105634Srwatson		 */
2373105634Srwatson		if (!mac_biba_single_in_range(new, subj))
2374105634Srwatson			return (EPERM);
2375101099Srwatson
2376105634Srwatson		/*
2377105634Srwatson		 * To change the Biba label on the vnode to be EQUAL,
2378105634Srwatson		 * the subject must have appropriate privilege.
2379105634Srwatson		 */
2380105634Srwatson		if (mac_biba_contains_equal(new)) {
2381106090Srwatson			error = mac_biba_subject_privileged(subj);
2382105634Srwatson			if (error)
2383105634Srwatson				return (error);
2384105634Srwatson		}
2385105634Srwatson	}
2386105634Srwatson
2387105634Srwatson	return (0);
2388101099Srwatson}
2389101099Srwatson
2390101099Srwatsonstatic int
2391101099Srwatsonmac_biba_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
2392101099Srwatson    struct label *dlabel, struct vnode *vp, struct label *label,
2393101099Srwatson    struct componentname *cnp)
2394101099Srwatson{
2395101099Srwatson	struct mac_biba *subj, *obj;
2396101099Srwatson
2397101099Srwatson	if (!mac_biba_enabled)
2398101099Srwatson		return (0);
2399101099Srwatson
2400101099Srwatson	subj = SLOT(&cred->cr_label);
2401101099Srwatson	obj = SLOT(dlabel);
2402101099Srwatson
2403101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2404101099Srwatson		return (EACCES);
2405101099Srwatson
2406101099Srwatson	obj = SLOT(label);
2407101099Srwatson
2408101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2409101099Srwatson		return (EACCES);
2410101099Srwatson
2411101099Srwatson	return (0);
2412101099Srwatson}
2413101099Srwatson
2414101099Srwatsonstatic int
2415101099Srwatsonmac_biba_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
2416101099Srwatson    struct label *dlabel, struct vnode *vp, struct label *label, int samedir,
2417101099Srwatson    struct componentname *cnp)
2418101099Srwatson{
2419101099Srwatson	struct mac_biba *subj, *obj;
2420101099Srwatson
2421101099Srwatson	if (!mac_biba_enabled)
2422101099Srwatson		return (0);
2423101099Srwatson
2424101099Srwatson	subj = SLOT(&cred->cr_label);
2425101099Srwatson	obj = SLOT(dlabel);
2426101099Srwatson
2427101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2428101099Srwatson		return (EACCES);
2429101099Srwatson
2430101099Srwatson	if (vp != NULL) {
2431101099Srwatson		obj = SLOT(label);
2432101099Srwatson
2433101099Srwatson		if (!mac_biba_dominate_single(subj, obj))
2434101099Srwatson			return (EACCES);
2435101099Srwatson	}
2436101099Srwatson
2437101099Srwatson	return (0);
2438101099Srwatson}
2439101099Srwatson
2440101099Srwatsonstatic int
2441101099Srwatsonmac_biba_check_vnode_revoke(struct ucred *cred, struct vnode *vp,
2442101099Srwatson    struct label *label)
2443101099Srwatson{
2444101099Srwatson	struct mac_biba *subj, *obj;
2445101099Srwatson
2446101099Srwatson	if (!mac_biba_enabled)
2447101099Srwatson		return (0);
2448101099Srwatson
2449101099Srwatson	subj = SLOT(&cred->cr_label);
2450101099Srwatson	obj = SLOT(label);
2451101099Srwatson
2452101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2453101099Srwatson		return (EACCES);
2454101099Srwatson
2455101099Srwatson	return (0);
2456101099Srwatson}
2457101099Srwatson
2458101099Srwatsonstatic int
2459101099Srwatsonmac_biba_check_vnode_setacl(struct ucred *cred, struct vnode *vp,
2460101099Srwatson    struct label *label, acl_type_t type, struct acl *acl)
2461101099Srwatson{
2462101099Srwatson	struct mac_biba *subj, *obj;
2463101099Srwatson
2464101099Srwatson	if (!mac_biba_enabled)
2465101099Srwatson		return (0);
2466101099Srwatson
2467101099Srwatson	subj = SLOT(&cred->cr_label);
2468101099Srwatson	obj = SLOT(label);
2469101099Srwatson
2470101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2471101099Srwatson		return (EACCES);
2472101099Srwatson
2473101099Srwatson	return (0);
2474101099Srwatson}
2475101099Srwatson
2476101099Srwatsonstatic int
2477101099Srwatsonmac_biba_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
2478101099Srwatson    struct label *vnodelabel, int attrnamespace, const char *name,
2479101099Srwatson    struct uio *uio)
2480101099Srwatson{
2481101099Srwatson	struct mac_biba *subj, *obj;
2482101099Srwatson
2483101099Srwatson	if (!mac_biba_enabled)
2484101099Srwatson		return (0);
2485101099Srwatson
2486101099Srwatson	subj = SLOT(&cred->cr_label);
2487101099Srwatson	obj = SLOT(vnodelabel);
2488101099Srwatson
2489101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2490101099Srwatson		return (EACCES);
2491101099Srwatson
2492101099Srwatson	/* XXX: protect the MAC EA in a special way? */
2493101099Srwatson
2494101099Srwatson	return (0);
2495101099Srwatson}
2496101099Srwatson
2497101099Srwatsonstatic int
2498101099Srwatsonmac_biba_check_vnode_setflags(struct ucred *cred, struct vnode *vp,
2499101099Srwatson    struct label *vnodelabel, u_long flags)
2500101099Srwatson{
2501101099Srwatson	struct mac_biba *subj, *obj;
2502101099Srwatson
2503101099Srwatson	if (!mac_biba_enabled)
2504101099Srwatson		return (0);
2505101099Srwatson
2506101099Srwatson	subj = SLOT(&cred->cr_label);
2507101099Srwatson	obj = SLOT(vnodelabel);
2508101099Srwatson
2509101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2510101099Srwatson		return (EACCES);
2511101099Srwatson
2512101099Srwatson	return (0);
2513101099Srwatson}
2514101099Srwatson
2515101099Srwatsonstatic int
2516101099Srwatsonmac_biba_check_vnode_setmode(struct ucred *cred, struct vnode *vp,
2517101099Srwatson    struct label *vnodelabel, mode_t mode)
2518101099Srwatson{
2519101099Srwatson	struct mac_biba *subj, *obj;
2520101099Srwatson
2521101099Srwatson	if (!mac_biba_enabled)
2522101099Srwatson		return (0);
2523101099Srwatson
2524101099Srwatson	subj = SLOT(&cred->cr_label);
2525101099Srwatson	obj = SLOT(vnodelabel);
2526101099Srwatson
2527101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2528101099Srwatson		return (EACCES);
2529101099Srwatson
2530101099Srwatson	return (0);
2531101099Srwatson}
2532101099Srwatson
2533101099Srwatsonstatic int
2534101099Srwatsonmac_biba_check_vnode_setowner(struct ucred *cred, struct vnode *vp,
2535101099Srwatson    struct label *vnodelabel, uid_t uid, gid_t gid)
2536101099Srwatson{
2537101099Srwatson	struct mac_biba *subj, *obj;
2538101099Srwatson
2539101099Srwatson	if (!mac_biba_enabled)
2540101099Srwatson		return (0);
2541101099Srwatson
2542101099Srwatson	subj = SLOT(&cred->cr_label);
2543101099Srwatson	obj = SLOT(vnodelabel);
2544101099Srwatson
2545101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2546101099Srwatson		return (EACCES);
2547101099Srwatson
2548101099Srwatson	return (0);
2549101099Srwatson}
2550101099Srwatson
2551101099Srwatsonstatic int
2552101099Srwatsonmac_biba_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
2553101099Srwatson    struct label *vnodelabel, struct timespec atime, struct timespec mtime)
2554101099Srwatson{
2555101099Srwatson	struct mac_biba *subj, *obj;
2556101099Srwatson
2557101099Srwatson	if (!mac_biba_enabled)
2558101099Srwatson		return (0);
2559101099Srwatson
2560101099Srwatson	subj = SLOT(&cred->cr_label);
2561101099Srwatson	obj = SLOT(vnodelabel);
2562101099Srwatson
2563101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2564101099Srwatson		return (EACCES);
2565101099Srwatson
2566101099Srwatson	return (0);
2567101099Srwatson}
2568101099Srwatson
2569101099Srwatsonstatic int
2570102129Srwatsonmac_biba_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
2571102129Srwatson    struct vnode *vp, struct label *vnodelabel)
2572101099Srwatson{
2573101099Srwatson	struct mac_biba *subj, *obj;
2574101099Srwatson
2575101099Srwatson	if (!mac_biba_enabled)
2576101099Srwatson		return (0);
2577101099Srwatson
2578102129Srwatson	subj = SLOT(&active_cred->cr_label);
2579101099Srwatson	obj = SLOT(vnodelabel);
2580101099Srwatson
2581101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
2582101099Srwatson		return (EACCES);
2583101099Srwatson
2584101099Srwatson	return (0);
2585101099Srwatson}
2586101099Srwatson
2587102112Srwatsonstatic int
2588102129Srwatsonmac_biba_check_vnode_write(struct ucred *active_cred,
2589102129Srwatson    struct ucred *file_cred, struct vnode *vp, struct label *label)
2590102112Srwatson{
2591102112Srwatson	struct mac_biba *subj, *obj;
2592102112Srwatson
2593105637Srwatson	if (!mac_biba_enabled || !revocation_enabled)
2594102112Srwatson		return (0);
2595102112Srwatson
2596102129Srwatson	subj = SLOT(&active_cred->cr_label);
2597102112Srwatson	obj = SLOT(label);
2598102112Srwatson
2599102112Srwatson	if (!mac_biba_dominate_single(subj, obj))
2600102112Srwatson		return (EACCES);
2601102112Srwatson
2602102112Srwatson	return (0);
2603102112Srwatson}
2604102112Srwatson
2605106217Srwatsonstatic struct mac_policy_ops mac_biba_ops =
2606101099Srwatson{
2607106217Srwatson	.mpo_destroy = mac_biba_destroy,
2608106217Srwatson	.mpo_init = mac_biba_init,
2609106217Srwatson	.mpo_init_bpfdesc_label = mac_biba_init_label,
2610106217Srwatson	.mpo_init_cred_label = mac_biba_init_label,
2611106217Srwatson	.mpo_init_devfsdirent_label = mac_biba_init_label,
2612106217Srwatson	.mpo_init_ifnet_label = mac_biba_init_label,
2613112675Srwatson	.mpo_init_ipq_label = mac_biba_init_label_waitcheck,
2614106217Srwatson	.mpo_init_mbuf_label = mac_biba_init_label_waitcheck,
2615106217Srwatson	.mpo_init_mount_label = mac_biba_init_label,
2616106217Srwatson	.mpo_init_mount_fs_label = mac_biba_init_label,
2617106217Srwatson	.mpo_init_pipe_label = mac_biba_init_label,
2618106217Srwatson	.mpo_init_socket_label = mac_biba_init_label_waitcheck,
2619106217Srwatson	.mpo_init_socket_peer_label = mac_biba_init_label_waitcheck,
2620106217Srwatson	.mpo_init_vnode_label = mac_biba_init_label,
2621106217Srwatson	.mpo_destroy_bpfdesc_label = mac_biba_destroy_label,
2622106217Srwatson	.mpo_destroy_cred_label = mac_biba_destroy_label,
2623106217Srwatson	.mpo_destroy_devfsdirent_label = mac_biba_destroy_label,
2624106217Srwatson	.mpo_destroy_ifnet_label = mac_biba_destroy_label,
2625106217Srwatson	.mpo_destroy_ipq_label = mac_biba_destroy_label,
2626106217Srwatson	.mpo_destroy_mbuf_label = mac_biba_destroy_label,
2627106217Srwatson	.mpo_destroy_mount_label = mac_biba_destroy_label,
2628106217Srwatson	.mpo_destroy_mount_fs_label = mac_biba_destroy_label,
2629106217Srwatson	.mpo_destroy_pipe_label = mac_biba_destroy_label,
2630106217Srwatson	.mpo_destroy_socket_label = mac_biba_destroy_label,
2631106217Srwatson	.mpo_destroy_socket_peer_label = mac_biba_destroy_label,
2632106217Srwatson	.mpo_destroy_vnode_label = mac_biba_destroy_label,
2633115707Srwatson	.mpo_copy_mbuf_label = mac_biba_copy_label,
2634106217Srwatson	.mpo_copy_pipe_label = mac_biba_copy_label,
2635106217Srwatson	.mpo_copy_vnode_label = mac_biba_copy_label,
2636106217Srwatson	.mpo_externalize_cred_label = mac_biba_externalize_label,
2637106217Srwatson	.mpo_externalize_ifnet_label = mac_biba_externalize_label,
2638106217Srwatson	.mpo_externalize_pipe_label = mac_biba_externalize_label,
2639106217Srwatson	.mpo_externalize_socket_label = mac_biba_externalize_label,
2640106217Srwatson	.mpo_externalize_socket_peer_label = mac_biba_externalize_label,
2641106217Srwatson	.mpo_externalize_vnode_label = mac_biba_externalize_label,
2642106217Srwatson	.mpo_internalize_cred_label = mac_biba_internalize_label,
2643106217Srwatson	.mpo_internalize_ifnet_label = mac_biba_internalize_label,
2644106217Srwatson	.mpo_internalize_pipe_label = mac_biba_internalize_label,
2645106217Srwatson	.mpo_internalize_socket_label = mac_biba_internalize_label,
2646106217Srwatson	.mpo_internalize_vnode_label = mac_biba_internalize_label,
2647106217Srwatson	.mpo_create_devfs_device = mac_biba_create_devfs_device,
2648106217Srwatson	.mpo_create_devfs_directory = mac_biba_create_devfs_directory,
2649106217Srwatson	.mpo_create_devfs_symlink = mac_biba_create_devfs_symlink,
2650106217Srwatson	.mpo_create_mount = mac_biba_create_mount,
2651106217Srwatson	.mpo_create_root_mount = mac_biba_create_root_mount,
2652106217Srwatson	.mpo_relabel_vnode = mac_biba_relabel_vnode,
2653106217Srwatson	.mpo_update_devfsdirent = mac_biba_update_devfsdirent,
2654106217Srwatson	.mpo_associate_vnode_devfs = mac_biba_associate_vnode_devfs,
2655106217Srwatson	.mpo_associate_vnode_extattr = mac_biba_associate_vnode_extattr,
2656106217Srwatson	.mpo_associate_vnode_singlelabel = mac_biba_associate_vnode_singlelabel,
2657106217Srwatson	.mpo_create_vnode_extattr = mac_biba_create_vnode_extattr,
2658106217Srwatson	.mpo_setlabel_vnode_extattr = mac_biba_setlabel_vnode_extattr,
2659106217Srwatson	.mpo_create_mbuf_from_socket = mac_biba_create_mbuf_from_socket,
2660106217Srwatson	.mpo_create_pipe = mac_biba_create_pipe,
2661106217Srwatson	.mpo_create_socket = mac_biba_create_socket,
2662106217Srwatson	.mpo_create_socket_from_socket = mac_biba_create_socket_from_socket,
2663106217Srwatson	.mpo_relabel_pipe = mac_biba_relabel_pipe,
2664106217Srwatson	.mpo_relabel_socket = mac_biba_relabel_socket,
2665106217Srwatson	.mpo_set_socket_peer_from_mbuf = mac_biba_set_socket_peer_from_mbuf,
2666106217Srwatson	.mpo_set_socket_peer_from_socket = mac_biba_set_socket_peer_from_socket,
2667106217Srwatson	.mpo_create_bpfdesc = mac_biba_create_bpfdesc,
2668106217Srwatson	.mpo_create_datagram_from_ipq = mac_biba_create_datagram_from_ipq,
2669106217Srwatson	.mpo_create_fragment = mac_biba_create_fragment,
2670106217Srwatson	.mpo_create_ifnet = mac_biba_create_ifnet,
2671106217Srwatson	.mpo_create_ipq = mac_biba_create_ipq,
2672106217Srwatson	.mpo_create_mbuf_from_mbuf = mac_biba_create_mbuf_from_mbuf,
2673106217Srwatson	.mpo_create_mbuf_linklayer = mac_biba_create_mbuf_linklayer,
2674106217Srwatson	.mpo_create_mbuf_from_bpfdesc = mac_biba_create_mbuf_from_bpfdesc,
2675106217Srwatson	.mpo_create_mbuf_from_ifnet = mac_biba_create_mbuf_from_ifnet,
2676106217Srwatson	.mpo_create_mbuf_multicast_encap = mac_biba_create_mbuf_multicast_encap,
2677106217Srwatson	.mpo_create_mbuf_netlayer = mac_biba_create_mbuf_netlayer,
2678106217Srwatson	.mpo_fragment_match = mac_biba_fragment_match,
2679106217Srwatson	.mpo_relabel_ifnet = mac_biba_relabel_ifnet,
2680106217Srwatson	.mpo_update_ipq = mac_biba_update_ipq,
2681106217Srwatson	.mpo_create_cred = mac_biba_create_cred,
2682106217Srwatson	.mpo_create_proc0 = mac_biba_create_proc0,
2683106217Srwatson	.mpo_create_proc1 = mac_biba_create_proc1,
2684106217Srwatson	.mpo_relabel_cred = mac_biba_relabel_cred,
2685106217Srwatson	.mpo_check_bpfdesc_receive = mac_biba_check_bpfdesc_receive,
2686106217Srwatson	.mpo_check_cred_relabel = mac_biba_check_cred_relabel,
2687106217Srwatson	.mpo_check_cred_visible = mac_biba_check_cred_visible,
2688106217Srwatson	.mpo_check_ifnet_relabel = mac_biba_check_ifnet_relabel,
2689106217Srwatson	.mpo_check_ifnet_transmit = mac_biba_check_ifnet_transmit,
2690110354Srwatson	.mpo_check_kld_load = mac_biba_check_kld_load,
2691110354Srwatson	.mpo_check_kld_unload = mac_biba_check_kld_unload,
2692106217Srwatson	.mpo_check_mount_stat = mac_biba_check_mount_stat,
2693106217Srwatson	.mpo_check_pipe_ioctl = mac_biba_check_pipe_ioctl,
2694106217Srwatson	.mpo_check_pipe_poll = mac_biba_check_pipe_poll,
2695106217Srwatson	.mpo_check_pipe_read = mac_biba_check_pipe_read,
2696106217Srwatson	.mpo_check_pipe_relabel = mac_biba_check_pipe_relabel,
2697106217Srwatson	.mpo_check_pipe_stat = mac_biba_check_pipe_stat,
2698106217Srwatson	.mpo_check_pipe_write = mac_biba_check_pipe_write,
2699106217Srwatson	.mpo_check_proc_debug = mac_biba_check_proc_debug,
2700106217Srwatson	.mpo_check_proc_sched = mac_biba_check_proc_sched,
2701106217Srwatson	.mpo_check_proc_signal = mac_biba_check_proc_signal,
2702106217Srwatson	.mpo_check_socket_deliver = mac_biba_check_socket_deliver,
2703106217Srwatson	.mpo_check_socket_relabel = mac_biba_check_socket_relabel,
2704106217Srwatson	.mpo_check_socket_visible = mac_biba_check_socket_visible,
2705112574Srwatson	.mpo_check_sysarch_ioperm = mac_biba_check_sysarch_ioperm,
2706106418Srwatson	.mpo_check_system_acct = mac_biba_check_system_acct,
2707106418Srwatson	.mpo_check_system_settime = mac_biba_check_system_settime,
2708106217Srwatson	.mpo_check_system_swapon = mac_biba_check_system_swapon,
2709112574Srwatson	.mpo_check_system_swapoff = mac_biba_check_system_swapoff,
2710106217Srwatson	.mpo_check_system_sysctl = mac_biba_check_system_sysctl,
2711106217Srwatson	.mpo_check_vnode_access = mac_biba_check_vnode_open,
2712106217Srwatson	.mpo_check_vnode_chdir = mac_biba_check_vnode_chdir,
2713106217Srwatson	.mpo_check_vnode_chroot = mac_biba_check_vnode_chroot,
2714106217Srwatson	.mpo_check_vnode_create = mac_biba_check_vnode_create,
2715106217Srwatson	.mpo_check_vnode_delete = mac_biba_check_vnode_delete,
2716106217Srwatson	.mpo_check_vnode_deleteacl = mac_biba_check_vnode_deleteacl,
2717106217Srwatson	.mpo_check_vnode_exec = mac_biba_check_vnode_exec,
2718106217Srwatson	.mpo_check_vnode_getacl = mac_biba_check_vnode_getacl,
2719106217Srwatson	.mpo_check_vnode_getextattr = mac_biba_check_vnode_getextattr,
2720106217Srwatson	.mpo_check_vnode_link = mac_biba_check_vnode_link,
2721106217Srwatson	.mpo_check_vnode_lookup = mac_biba_check_vnode_lookup,
2722106217Srwatson	.mpo_check_vnode_mmap = mac_biba_check_vnode_mmap,
2723106217Srwatson	.mpo_check_vnode_mprotect = mac_biba_check_vnode_mmap,
2724106217Srwatson	.mpo_check_vnode_open = mac_biba_check_vnode_open,
2725106217Srwatson	.mpo_check_vnode_poll = mac_biba_check_vnode_poll,
2726106217Srwatson	.mpo_check_vnode_read = mac_biba_check_vnode_read,
2727106217Srwatson	.mpo_check_vnode_readdir = mac_biba_check_vnode_readdir,
2728106217Srwatson	.mpo_check_vnode_readlink = mac_biba_check_vnode_readlink,
2729106217Srwatson	.mpo_check_vnode_relabel = mac_biba_check_vnode_relabel,
2730106217Srwatson	.mpo_check_vnode_rename_from = mac_biba_check_vnode_rename_from,
2731106217Srwatson	.mpo_check_vnode_rename_to = mac_biba_check_vnode_rename_to,
2732106217Srwatson	.mpo_check_vnode_revoke = mac_biba_check_vnode_revoke,
2733106217Srwatson	.mpo_check_vnode_setacl = mac_biba_check_vnode_setacl,
2734106217Srwatson	.mpo_check_vnode_setextattr = mac_biba_check_vnode_setextattr,
2735106217Srwatson	.mpo_check_vnode_setflags = mac_biba_check_vnode_setflags,
2736106217Srwatson	.mpo_check_vnode_setmode = mac_biba_check_vnode_setmode,
2737106217Srwatson	.mpo_check_vnode_setowner = mac_biba_check_vnode_setowner,
2738106217Srwatson	.mpo_check_vnode_setutimes = mac_biba_check_vnode_setutimes,
2739106217Srwatson	.mpo_check_vnode_stat = mac_biba_check_vnode_stat,
2740106217Srwatson	.mpo_check_vnode_write = mac_biba_check_vnode_write,
2741101099Srwatson};
2742101099Srwatson
2743112717SrwatsonMAC_POLICY_SET(&mac_biba_ops, mac_biba, "TrustedBSD MAC/Biba",
2744113531Srwatson    MPC_LOADTIME_FLAG_NOTLATE | MPC_LOADTIME_FLAG_LABELMBUFS, &mac_biba_slot);
2745