mac_biba.c revision 122563
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 122563 2003-11-12 15:09:39Z 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/*
579116701Srwatson * mac_biba_to_string() converts a Biba label to a string, and places
580116701Srwatson * the results in the passed sbuf.  It returns 0 on success, or EINVAL
581116701Srwatson * if there isn't room in the sbuf.  Note: the sbuf will be modified
582116701Srwatson * even in a failure case, so the caller may need to revert the sbuf
583116701Srwatson * by restoring the offset if that's undesired.
584115497Srwatson */
585101099Srwatsonstatic int
586116701Srwatsonmac_biba_to_string(struct sbuf *sb, struct mac_biba *mac_biba)
587101099Srwatson{
588105696Srwatson
589105696Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) {
590116701Srwatson		if (mac_biba_element_to_string(sb, &mac_biba->mb_single)
591115497Srwatson		    == -1)
592105696Srwatson			return (EINVAL);
593105696Srwatson	}
594105696Srwatson
595105696Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
596116701Srwatson		if (sbuf_putc(sb, '(') == -1)
597105696Srwatson			return (EINVAL);
598105696Srwatson
599116701Srwatson		if (mac_biba_element_to_string(sb, &mac_biba->mb_rangelow)
600115497Srwatson		    == -1)
601105696Srwatson			return (EINVAL);
602105696Srwatson
603116701Srwatson		if (sbuf_putc(sb, '-') == -1)
604105696Srwatson			return (EINVAL);
605105696Srwatson
606116701Srwatson		if (mac_biba_element_to_string(sb, &mac_biba->mb_rangehigh)
607115497Srwatson		    == -1)
608105696Srwatson			return (EINVAL);
609105696Srwatson
610116701Srwatson		if (sbuf_putc(sb, ')') == -1)
611105696Srwatson			return (EINVAL);
612105696Srwatson	}
613105696Srwatson
614105696Srwatson	return (0);
615105696Srwatson}
616105696Srwatson
617105696Srwatsonstatic int
618105696Srwatsonmac_biba_externalize_label(struct label *label, char *element_name,
619116701Srwatson    struct sbuf *sb, int *claimed)
620105696Srwatson{
621101099Srwatson	struct mac_biba *mac_biba;
622101099Srwatson
623105696Srwatson	if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0)
624105696Srwatson		return (0);
625105696Srwatson
626105696Srwatson	(*claimed)++;
627105696Srwatson
628101099Srwatson	mac_biba = SLOT(label);
629116701Srwatson	return (mac_biba_to_string(sb, mac_biba));
630105696Srwatson}
631105696Srwatson
632105696Srwatsonstatic int
633105696Srwatsonmac_biba_parse_element(struct mac_biba_element *element, char *string)
634101099Srwatson{
635115395Srwatson	char *compartment, *end, *grade;
636115395Srwatson	int value;
637105696Srwatson
638105696Srwatson	if (strcmp(string, "high") == 0 ||
639105696Srwatson	    strcmp(string, "hi") == 0) {
640105696Srwatson		element->mbe_type = MAC_BIBA_TYPE_HIGH;
641105696Srwatson		element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
642105696Srwatson	} else if (strcmp(string, "low") == 0 ||
643105696Srwatson	    strcmp(string, "lo") == 0) {
644105696Srwatson		element->mbe_type = MAC_BIBA_TYPE_LOW;
645105696Srwatson		element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
646105696Srwatson	} else if (strcmp(string, "equal") == 0 ||
647105696Srwatson	    strcmp(string, "eq") == 0) {
648105696Srwatson		element->mbe_type = MAC_BIBA_TYPE_EQUAL;
649105696Srwatson		element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
650105696Srwatson	} else {
651115395Srwatson		element->mbe_type = MAC_BIBA_TYPE_GRADE;
652105696Srwatson
653115395Srwatson		/*
654115395Srwatson		 * Numeric grade piece of the element.
655115395Srwatson		 */
656115395Srwatson		grade = strsep(&string, ":");
657115395Srwatson		value = strtol(grade, &end, 10);
658115395Srwatson		if (end == grade || *end != '\0')
659105696Srwatson			return (EINVAL);
660115395Srwatson		if (value < 0 || value > 65535)
661115395Srwatson			return (EINVAL);
662115395Srwatson		element->mbe_grade = value;
663105696Srwatson
664115395Srwatson		/*
665115395Srwatson		 * Optional compartment piece of the element.  If none
666115395Srwatson		 * are included, we assume that the label has no
667115395Srwatson		 * compartments.
668115395Srwatson		 */
669115395Srwatson		if (string == NULL)
670115395Srwatson			return (0);
671115395Srwatson		if (*string == '\0')
672115395Srwatson			return (0);
673105696Srwatson
674115395Srwatson		while ((compartment = strsep(&string, "+")) != NULL) {
675115395Srwatson			value = strtol(compartment, &end, 10);
676115395Srwatson			if (compartment == end || *end != '\0')
677105696Srwatson				return (EINVAL);
678115395Srwatson			if (value < 1 || value > MAC_BIBA_MAX_COMPARTMENTS)
679105696Srwatson				return (EINVAL);
680115395Srwatson			MAC_BIBA_BIT_SET(value, element->mbe_compartments);
681105696Srwatson		}
682105696Srwatson	}
683105696Srwatson
684105696Srwatson	return (0);
685105696Srwatson}
686105696Srwatson
687105696Srwatson/*
688105696Srwatson * Note: destructively consumes the string, make a local copy before
689105696Srwatson * calling if that's a problem.
690105696Srwatson */
691105696Srwatsonstatic int
692105696Srwatsonmac_biba_parse(struct mac_biba *mac_biba, char *string)
693105696Srwatson{
694115395Srwatson	char *rangehigh, *rangelow, *single;
695101099Srwatson	int error;
696101099Srwatson
697115395Srwatson	single = strsep(&string, "(");
698115395Srwatson	if (*single == '\0')
699105696Srwatson		single = NULL;
700115395Srwatson
701115395Srwatson	if (string != NULL) {
702115395Srwatson		rangelow = strsep(&string, "-");
703115395Srwatson		if (string == NULL)
704105696Srwatson			return (EINVAL);
705115395Srwatson		rangehigh = strsep(&string, ")");
706115395Srwatson		if (string == NULL)
707105696Srwatson			return (EINVAL);
708115395Srwatson		if (*string != '\0')
709105696Srwatson			return (EINVAL);
710115395Srwatson	} else {
711115395Srwatson		rangelow = NULL;
712115395Srwatson		rangehigh = NULL;
713105696Srwatson	}
714115395Srwatson
715105696Srwatson	KASSERT((rangelow != NULL && rangehigh != NULL) ||
716105696Srwatson	    (rangelow == NULL && rangehigh == NULL),
717115395Srwatson	    ("mac_biba_parse: range mismatch"));
718101099Srwatson
719105696Srwatson	bzero(mac_biba, sizeof(*mac_biba));
720105696Srwatson	if (single != NULL) {
721105696Srwatson		error = mac_biba_parse_element(&mac_biba->mb_single, single);
722105696Srwatson		if (error)
723105696Srwatson			return (error);
724105696Srwatson		mac_biba->mb_flags |= MAC_BIBA_FLAG_SINGLE;
725105696Srwatson	}
726105696Srwatson
727105696Srwatson	if (rangelow != NULL) {
728105696Srwatson		error = mac_biba_parse_element(&mac_biba->mb_rangelow,
729105696Srwatson		    rangelow);
730105696Srwatson		if (error)
731105696Srwatson			return (error);
732105696Srwatson		error = mac_biba_parse_element(&mac_biba->mb_rangehigh,
733105696Srwatson		    rangehigh);
734105696Srwatson		if (error)
735105696Srwatson			return (error);
736105696Srwatson		mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE;
737105696Srwatson	}
738105696Srwatson
739101099Srwatson	error = mac_biba_valid(mac_biba);
740101099Srwatson	if (error)
741101099Srwatson		return (error);
742101099Srwatson
743105696Srwatson	return (0);
744105696Srwatson}
745101099Srwatson
746105696Srwatsonstatic int
747105696Srwatsonmac_biba_internalize_label(struct label *label, char *element_name,
748105696Srwatson    char *element_data, int *claimed)
749105696Srwatson{
750105696Srwatson	struct mac_biba *mac_biba, mac_biba_temp;
751105696Srwatson	int error;
752105696Srwatson
753105696Srwatson	if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0)
754105696Srwatson		return (0);
755105696Srwatson
756105696Srwatson	(*claimed)++;
757105696Srwatson
758105696Srwatson	error = mac_biba_parse(&mac_biba_temp, element_data);
759105696Srwatson	if (error)
760105696Srwatson		return (error);
761105696Srwatson
762105696Srwatson	mac_biba = SLOT(label);
763105696Srwatson	*mac_biba = mac_biba_temp;
764105696Srwatson
765101099Srwatson	return (0);
766101099Srwatson}
767101099Srwatson
768105696Srwatsonstatic void
769105696Srwatsonmac_biba_copy_label(struct label *src, struct label *dest)
770105696Srwatson{
771105696Srwatson
772105696Srwatson	*SLOT(dest) = *SLOT(src);
773105696Srwatson}
774105696Srwatson
775101099Srwatson/*
776101099Srwatson * Labeling event operations: file system objects, and things that look
777101099Srwatson * a lot like file system objects.
778101099Srwatson */
779101099Srwatsonstatic void
780107698Srwatsonmac_biba_create_devfs_device(struct mount *mp, dev_t dev,
781107698Srwatson    struct devfs_dirent *devfs_dirent, struct label *label)
782101099Srwatson{
783101099Srwatson	struct mac_biba *mac_biba;
784101099Srwatson	int biba_type;
785101099Srwatson
786101099Srwatson	mac_biba = SLOT(label);
787101099Srwatson	if (strcmp(dev->si_name, "null") == 0 ||
788101099Srwatson	    strcmp(dev->si_name, "zero") == 0 ||
789101099Srwatson	    strcmp(dev->si_name, "random") == 0 ||
790101099Srwatson	    strncmp(dev->si_name, "fd/", strlen("fd/")) == 0)
791101099Srwatson		biba_type = MAC_BIBA_TYPE_EQUAL;
792105606Srwatson	else if (ptys_equal &&
793105606Srwatson	    (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 ||
794105606Srwatson	    strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0))
795105606Srwatson		biba_type = MAC_BIBA_TYPE_EQUAL;
796101099Srwatson	else
797101099Srwatson		biba_type = MAC_BIBA_TYPE_HIGH;
798105643Srwatson	mac_biba_set_single(mac_biba, biba_type, 0, NULL);
799101099Srwatson}
800101099Srwatson
801101099Srwatsonstatic void
802107698Srwatsonmac_biba_create_devfs_directory(struct mount *mp, char *dirname,
803107698Srwatson    int dirnamelen, struct devfs_dirent *devfs_dirent, struct label *label)
804101099Srwatson{
805101099Srwatson	struct mac_biba *mac_biba;
806101099Srwatson
807101099Srwatson	mac_biba = SLOT(label);
808105643Srwatson	mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
809101099Srwatson}
810101099Srwatson
811101099Srwatsonstatic void
812107698Srwatsonmac_biba_create_devfs_symlink(struct ucred *cred, struct mount *mp,
813107698Srwatson    struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de,
814122563Srwatson    struct label *delabel)
815104535Srwatson{
816104535Srwatson	struct mac_biba *source, *dest;
817104535Srwatson
818122524Srwatson	source = SLOT(cred->cr_label);
819104535Srwatson	dest = SLOT(delabel);
820104535Srwatson
821104535Srwatson	mac_biba_copy_single(source, dest);
822104535Srwatson}
823104535Srwatson
824104535Srwatsonstatic void
825101099Srwatsonmac_biba_create_mount(struct ucred *cred, struct mount *mp,
826101099Srwatson    struct label *mntlabel, struct label *fslabel)
827101099Srwatson{
828101099Srwatson	struct mac_biba *source, *dest;
829101099Srwatson
830122524Srwatson	source = SLOT(cred->cr_label);
831101099Srwatson	dest = SLOT(mntlabel);
832101099Srwatson	mac_biba_copy_single(source, dest);
833101099Srwatson	dest = SLOT(fslabel);
834101099Srwatson	mac_biba_copy_single(source, dest);
835101099Srwatson}
836101099Srwatson
837101099Srwatsonstatic void
838101099Srwatsonmac_biba_create_root_mount(struct ucred *cred, struct mount *mp,
839101099Srwatson    struct label *mntlabel, struct label *fslabel)
840101099Srwatson{
841101099Srwatson	struct mac_biba *mac_biba;
842101099Srwatson
843101099Srwatson	/* Always mount root as high integrity. */
844101099Srwatson	mac_biba = SLOT(fslabel);
845105643Srwatson	mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
846101099Srwatson	mac_biba = SLOT(mntlabel);
847105643Srwatson	mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
848101099Srwatson}
849101099Srwatson
850101099Srwatsonstatic void
851101099Srwatsonmac_biba_relabel_vnode(struct ucred *cred, struct vnode *vp,
852101099Srwatson    struct label *vnodelabel, struct label *label)
853101099Srwatson{
854101099Srwatson	struct mac_biba *source, *dest;
855101099Srwatson
856101099Srwatson	source = SLOT(label);
857101099Srwatson	dest = SLOT(vnodelabel);
858101099Srwatson
859105656Srwatson	mac_biba_copy(source, dest);
860101099Srwatson}
861101099Srwatson
862101099Srwatsonstatic void
863107698Srwatsonmac_biba_update_devfsdirent(struct mount *mp,
864107698Srwatson    struct devfs_dirent *devfs_dirent, struct label *direntlabel,
865107698Srwatson    struct vnode *vp, struct label *vnodelabel)
866101099Srwatson{
867101099Srwatson	struct mac_biba *source, *dest;
868101099Srwatson
869101099Srwatson	source = SLOT(vnodelabel);
870101099Srwatson	dest = SLOT(direntlabel);
871101099Srwatson
872105656Srwatson	mac_biba_copy(source, dest);
873101099Srwatson}
874101099Srwatson
875101099Srwatsonstatic void
876105988Srwatsonmac_biba_associate_vnode_devfs(struct mount *mp, struct label *fslabel,
877105988Srwatson    struct devfs_dirent *de, struct label *delabel, struct vnode *vp,
878105988Srwatson    struct label *vlabel)
879101099Srwatson{
880101099Srwatson	struct mac_biba *source, *dest;
881101099Srwatson
882105988Srwatson	source = SLOT(delabel);
883105988Srwatson	dest = SLOT(vlabel);
884101099Srwatson
885101099Srwatson	mac_biba_copy_single(source, dest);
886101099Srwatson}
887101099Srwatson
888101099Srwatsonstatic int
889105988Srwatsonmac_biba_associate_vnode_extattr(struct mount *mp, struct label *fslabel,
890105988Srwatson    struct vnode *vp, struct label *vlabel)
891101099Srwatson{
892105988Srwatson	struct mac_biba temp, *source, *dest;
893106354Smux	int buflen, error;
894101099Srwatson
895105988Srwatson	source = SLOT(fslabel);
896105988Srwatson	dest = SLOT(vlabel);
897101099Srwatson
898105988Srwatson	buflen = sizeof(temp);
899105988Srwatson	bzero(&temp, buflen);
900105988Srwatson
901105988Srwatson	error = vn_extattr_get(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
902105988Srwatson	    MAC_BIBA_EXTATTR_NAME, &buflen, (char *) &temp, curthread);
903105988Srwatson	if (error == ENOATTR || error == EOPNOTSUPP) {
904105988Srwatson		/* Fall back to the fslabel. */
905105988Srwatson		mac_biba_copy_single(source, dest);
906105988Srwatson		return (0);
907105988Srwatson	} else if (error)
908101099Srwatson		return (error);
909101099Srwatson
910105988Srwatson	if (buflen != sizeof(temp)) {
911105988Srwatson		printf("mac_biba_associate_vnode_extattr: bad size %d\n",
912105988Srwatson		    buflen);
913105988Srwatson		return (EPERM);
914105988Srwatson	}
915105988Srwatson	if (mac_biba_valid(&temp) != 0) {
916105988Srwatson		printf("mac_biba_associate_vnode_extattr: invalid\n");
917105988Srwatson		return (EPERM);
918105988Srwatson	}
919105988Srwatson	if ((temp.mb_flags & MAC_BIBA_FLAGS_BOTH) != MAC_BIBA_FLAG_SINGLE) {
920105988Srwatson		printf("mac_biba_associate_vnode_extattr: not single\n");
921105988Srwatson		return (EPERM);
922105988Srwatson	}
923101099Srwatson
924105988Srwatson	mac_biba_copy_single(&temp, dest);
925101099Srwatson	return (0);
926101099Srwatson}
927101099Srwatson
928101099Srwatsonstatic void
929105988Srwatsonmac_biba_associate_vnode_singlelabel(struct mount *mp,
930105988Srwatson    struct label *fslabel, struct vnode *vp, struct label *vlabel)
931101099Srwatson{
932101099Srwatson	struct mac_biba *source, *dest;
933101099Srwatson
934101099Srwatson	source = SLOT(fslabel);
935105988Srwatson	dest = SLOT(vlabel);
936101099Srwatson
937101099Srwatson	mac_biba_copy_single(source, dest);
938101099Srwatson}
939101099Srwatson
940105988Srwatsonstatic int
941105988Srwatsonmac_biba_create_vnode_extattr(struct ucred *cred, struct mount *mp,
942105988Srwatson    struct label *fslabel, struct vnode *dvp, struct label *dlabel,
943105988Srwatson    struct vnode *vp, struct label *vlabel, struct componentname *cnp)
944105988Srwatson{
945105988Srwatson	struct mac_biba *source, *dest, temp;
946105988Srwatson	size_t buflen;
947105988Srwatson	int error;
948105988Srwatson
949105988Srwatson	buflen = sizeof(temp);
950105988Srwatson	bzero(&temp, buflen);
951105988Srwatson
952122524Srwatson	source = SLOT(cred->cr_label);
953105988Srwatson	dest = SLOT(vlabel);
954105988Srwatson	mac_biba_copy_single(source, &temp);
955105988Srwatson
956105988Srwatson	error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
957105988Srwatson	    MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread);
958105988Srwatson	if (error == 0)
959105988Srwatson		mac_biba_copy_single(source, dest);
960105988Srwatson	return (error);
961105988Srwatson}
962105988Srwatson
963105988Srwatsonstatic int
964105988Srwatsonmac_biba_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp,
965105988Srwatson    struct label *vlabel, struct label *intlabel)
966105988Srwatson{
967105988Srwatson	struct mac_biba *source, temp;
968105988Srwatson	size_t buflen;
969105988Srwatson	int error;
970105988Srwatson
971105988Srwatson	buflen = sizeof(temp);
972105988Srwatson	bzero(&temp, buflen);
973105988Srwatson
974105988Srwatson	source = SLOT(intlabel);
975105988Srwatson	if ((source->mb_flags & MAC_BIBA_FLAG_SINGLE) == 0)
976105988Srwatson		return (0);
977105988Srwatson
978105988Srwatson	mac_biba_copy_single(source, &temp);
979105988Srwatson
980105988Srwatson	error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
981105988Srwatson	    MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread);
982105988Srwatson	return (error);
983105988Srwatson}
984105988Srwatson
985101099Srwatson/*
986101099Srwatson * Labeling event operations: IPC object.
987101099Srwatson */
988101099Srwatsonstatic void
989101099Srwatsonmac_biba_create_mbuf_from_socket(struct socket *so, struct label *socketlabel,
990101099Srwatson    struct mbuf *m, struct label *mbuflabel)
991101099Srwatson{
992101099Srwatson	struct mac_biba *source, *dest;
993101099Srwatson
994101099Srwatson	source = SLOT(socketlabel);
995101099Srwatson	dest = SLOT(mbuflabel);
996101099Srwatson
997101099Srwatson	mac_biba_copy_single(source, dest);
998101099Srwatson}
999101099Srwatson
1000101099Srwatsonstatic void
1001101099Srwatsonmac_biba_create_socket(struct ucred *cred, struct socket *socket,
1002101099Srwatson    struct label *socketlabel)
1003101099Srwatson{
1004101099Srwatson	struct mac_biba *source, *dest;
1005101099Srwatson
1006122524Srwatson	source = SLOT(cred->cr_label);
1007101099Srwatson	dest = SLOT(socketlabel);
1008101099Srwatson
1009101099Srwatson	mac_biba_copy_single(source, dest);
1010101099Srwatson}
1011101099Srwatson
1012101099Srwatsonstatic void
1013101099Srwatsonmac_biba_create_pipe(struct ucred *cred, struct pipe *pipe,
1014101099Srwatson    struct label *pipelabel)
1015101099Srwatson{
1016101099Srwatson	struct mac_biba *source, *dest;
1017101099Srwatson
1018122524Srwatson	source = SLOT(cred->cr_label);
1019101099Srwatson	dest = SLOT(pipelabel);
1020101099Srwatson
1021101099Srwatson	mac_biba_copy_single(source, dest);
1022101099Srwatson}
1023101099Srwatson
1024101099Srwatsonstatic void
1025101099Srwatsonmac_biba_create_socket_from_socket(struct socket *oldsocket,
1026101099Srwatson    struct label *oldsocketlabel, struct socket *newsocket,
1027101099Srwatson    struct label *newsocketlabel)
1028101099Srwatson{
1029101099Srwatson	struct mac_biba *source, *dest;
1030101099Srwatson
1031101099Srwatson	source = SLOT(oldsocketlabel);
1032101099Srwatson	dest = SLOT(newsocketlabel);
1033101099Srwatson
1034101099Srwatson	mac_biba_copy_single(source, dest);
1035101099Srwatson}
1036101099Srwatson
1037101099Srwatsonstatic void
1038101099Srwatsonmac_biba_relabel_socket(struct ucred *cred, struct socket *socket,
1039101099Srwatson    struct label *socketlabel, struct label *newlabel)
1040101099Srwatson{
1041101099Srwatson	struct mac_biba *source, *dest;
1042101099Srwatson
1043101099Srwatson	source = SLOT(newlabel);
1044101099Srwatson	dest = SLOT(socketlabel);
1045101099Srwatson
1046105656Srwatson	mac_biba_copy(source, dest);
1047101099Srwatson}
1048101099Srwatson
1049101099Srwatsonstatic void
1050101099Srwatsonmac_biba_relabel_pipe(struct ucred *cred, struct pipe *pipe,
1051101099Srwatson    struct label *pipelabel, struct label *newlabel)
1052101099Srwatson{
1053101099Srwatson	struct mac_biba *source, *dest;
1054101099Srwatson
1055101099Srwatson	source = SLOT(newlabel);
1056101099Srwatson	dest = SLOT(pipelabel);
1057101099Srwatson
1058105656Srwatson	mac_biba_copy(source, dest);
1059101099Srwatson}
1060101099Srwatson
1061101099Srwatsonstatic void
1062101099Srwatsonmac_biba_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel,
1063101099Srwatson    struct socket *socket, struct label *socketpeerlabel)
1064101099Srwatson{
1065101099Srwatson	struct mac_biba *source, *dest;
1066101099Srwatson
1067101099Srwatson	source = SLOT(mbuflabel);
1068101099Srwatson	dest = SLOT(socketpeerlabel);
1069101099Srwatson
1070101099Srwatson	mac_biba_copy_single(source, dest);
1071101099Srwatson}
1072101099Srwatson
1073101099Srwatson/*
1074101099Srwatson * Labeling event operations: network objects.
1075101099Srwatson */
1076101099Srwatsonstatic void
1077101099Srwatsonmac_biba_set_socket_peer_from_socket(struct socket *oldsocket,
1078101099Srwatson    struct label *oldsocketlabel, struct socket *newsocket,
1079101099Srwatson    struct label *newsocketpeerlabel)
1080101099Srwatson{
1081101099Srwatson	struct mac_biba *source, *dest;
1082101099Srwatson
1083101099Srwatson	source = SLOT(oldsocketlabel);
1084101099Srwatson	dest = SLOT(newsocketpeerlabel);
1085101099Srwatson
1086101099Srwatson	mac_biba_copy_single(source, dest);
1087101099Srwatson}
1088101099Srwatson
1089101099Srwatsonstatic void
1090101099Srwatsonmac_biba_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d,
1091101099Srwatson    struct label *bpflabel)
1092101099Srwatson{
1093101099Srwatson	struct mac_biba *source, *dest;
1094101099Srwatson
1095122524Srwatson	source = SLOT(cred->cr_label);
1096101099Srwatson	dest = SLOT(bpflabel);
1097101099Srwatson
1098101099Srwatson	mac_biba_copy_single(source, dest);
1099101099Srwatson}
1100101099Srwatson
1101101099Srwatsonstatic void
1102101099Srwatsonmac_biba_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel)
1103101099Srwatson{
1104121816Sbrooks	char tifname[IFNAMSIZ], *p, *q;
1105101099Srwatson	char tiflist[sizeof(trusted_interfaces)];
1106101099Srwatson	struct mac_biba *dest;
1107110350Srwatson	int len, type;
1108101099Srwatson
1109101099Srwatson	dest = SLOT(ifnetlabel);
1110101099Srwatson
1111101099Srwatson	if (ifnet->if_type == IFT_LOOP) {
1112110350Srwatson		type = MAC_BIBA_TYPE_EQUAL;
1113101099Srwatson		goto set;
1114101099Srwatson	}
1115101099Srwatson
1116101099Srwatson	if (trust_all_interfaces) {
1117110350Srwatson		type = MAC_BIBA_TYPE_HIGH;
1118101099Srwatson		goto set;
1119101099Srwatson	}
1120101099Srwatson
1121110350Srwatson	type = MAC_BIBA_TYPE_LOW;
1122101099Srwatson
1123101099Srwatson	if (trusted_interfaces[0] == '\0' ||
1124101099Srwatson	    !strvalid(trusted_interfaces, sizeof(trusted_interfaces)))
1125101099Srwatson		goto set;
1126101099Srwatson
1127106089Srwatson	bzero(tiflist, sizeof(tiflist));
1128101099Srwatson	for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++)
1129101099Srwatson		if(*p != ' ' && *p != '\t')
1130101099Srwatson			*q = *p;
1131101099Srwatson
1132101099Srwatson	for (p = q = tiflist;; p++) {
1133101099Srwatson		if (*p == ',' || *p == '\0') {
1134101099Srwatson			len = p - q;
1135101099Srwatson			if (len < IFNAMSIZ) {
1136101099Srwatson				bzero(tifname, sizeof(tifname));
1137101099Srwatson				bcopy(q, tifname, len);
1138121816Sbrooks				if (strcmp(tifname, ifnet->if_xname) == 0) {
1139110350Srwatson					type = MAC_BIBA_TYPE_HIGH;
1140101099Srwatson					break;
1141101099Srwatson				}
1142106089Srwatson			} else {
1143106089Srwatson				*p = '\0';
1144106089Srwatson				printf("mac_biba warning: interface name "
1145106089Srwatson				    "\"%s\" is too long (must be < %d)\n",
1146106089Srwatson				    q, IFNAMSIZ);
1147101099Srwatson			}
1148101099Srwatson			if (*p == '\0')
1149101099Srwatson				break;
1150101099Srwatson			q = p + 1;
1151101099Srwatson		}
1152101099Srwatson	}
1153101099Srwatsonset:
1154110350Srwatson	mac_biba_set_single(dest, type, 0, NULL);
1155110350Srwatson	mac_biba_set_range(dest, type, 0, NULL, type, 0, NULL);
1156101099Srwatson}
1157101099Srwatson
1158101099Srwatsonstatic void
1159101099Srwatsonmac_biba_create_ipq(struct mbuf *fragment, struct label *fragmentlabel,
1160101099Srwatson    struct ipq *ipq, struct label *ipqlabel)
1161101099Srwatson{
1162101099Srwatson	struct mac_biba *source, *dest;
1163101099Srwatson
1164101099Srwatson	source = SLOT(fragmentlabel);
1165101099Srwatson	dest = SLOT(ipqlabel);
1166101099Srwatson
1167101099Srwatson	mac_biba_copy_single(source, dest);
1168101099Srwatson}
1169101099Srwatson
1170101099Srwatsonstatic void
1171101099Srwatsonmac_biba_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel,
1172101099Srwatson    struct mbuf *datagram, struct label *datagramlabel)
1173101099Srwatson{
1174101099Srwatson	struct mac_biba *source, *dest;
1175101099Srwatson
1176101099Srwatson	source = SLOT(ipqlabel);
1177101099Srwatson	dest = SLOT(datagramlabel);
1178101099Srwatson
1179101099Srwatson	/* Just use the head, since we require them all to match. */
1180101099Srwatson	mac_biba_copy_single(source, dest);
1181101099Srwatson}
1182101099Srwatson
1183101099Srwatsonstatic void
1184101099Srwatsonmac_biba_create_fragment(struct mbuf *datagram, struct label *datagramlabel,
1185101099Srwatson    struct mbuf *fragment, struct label *fragmentlabel)
1186101099Srwatson{
1187101099Srwatson	struct mac_biba *source, *dest;
1188101099Srwatson
1189101099Srwatson	source = SLOT(datagramlabel);
1190101099Srwatson	dest = SLOT(fragmentlabel);
1191101099Srwatson
1192101099Srwatson	mac_biba_copy_single(source, dest);
1193101099Srwatson}
1194101099Srwatson
1195101099Srwatsonstatic void
1196101099Srwatsonmac_biba_create_mbuf_from_mbuf(struct mbuf *oldmbuf,
1197101099Srwatson    struct label *oldmbuflabel, struct mbuf *newmbuf,
1198101099Srwatson    struct label *newmbuflabel)
1199101099Srwatson{
1200101099Srwatson	struct mac_biba *source, *dest;
1201101099Srwatson
1202101099Srwatson	source = SLOT(oldmbuflabel);
1203101099Srwatson	dest = SLOT(newmbuflabel);
1204101099Srwatson
1205105656Srwatson	/*
1206105656Srwatson	 * Because the source mbuf may not yet have been "created",
1207105696Srwatson	 * just initialized, we do a conditional copy.  Since we don't
1208105656Srwatson	 * allow mbufs to have ranges, do a KASSERT to make sure that
1209105656Srwatson	 * doesn't happen.
1210105656Srwatson	 */
1211105656Srwatson	KASSERT((source->mb_flags & MAC_BIBA_FLAG_RANGE) == 0,
1212105656Srwatson	    ("mac_biba_create_mbuf_from_mbuf: source mbuf has range"));
1213105656Srwatson	mac_biba_copy(source, dest);
1214101099Srwatson}
1215101099Srwatson
1216101099Srwatsonstatic void
1217101099Srwatsonmac_biba_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel,
1218101099Srwatson    struct mbuf *mbuf, struct label *mbuflabel)
1219101099Srwatson{
1220101099Srwatson	struct mac_biba *dest;
1221101099Srwatson
1222101099Srwatson	dest = SLOT(mbuflabel);
1223101099Srwatson
1224105643Srwatson	mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1225101099Srwatson}
1226101099Srwatson
1227101099Srwatsonstatic void
1228101099Srwatsonmac_biba_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel,
1229101099Srwatson    struct mbuf *mbuf, struct label *mbuflabel)
1230101099Srwatson{
1231101099Srwatson	struct mac_biba *source, *dest;
1232101099Srwatson
1233101099Srwatson	source = SLOT(bpflabel);
1234101099Srwatson	dest = SLOT(mbuflabel);
1235101099Srwatson
1236101099Srwatson	mac_biba_copy_single(source, dest);
1237101099Srwatson}
1238101099Srwatson
1239101099Srwatsonstatic void
1240101099Srwatsonmac_biba_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel,
1241101099Srwatson    struct mbuf *m, struct label *mbuflabel)
1242101099Srwatson{
1243101099Srwatson	struct mac_biba *source, *dest;
1244101099Srwatson
1245101099Srwatson	source = SLOT(ifnetlabel);
1246101099Srwatson	dest = SLOT(mbuflabel);
1247101099Srwatson
1248101099Srwatson	mac_biba_copy_single(source, dest);
1249101099Srwatson}
1250101099Srwatson
1251101099Srwatsonstatic void
1252101099Srwatsonmac_biba_create_mbuf_multicast_encap(struct mbuf *oldmbuf,
1253101099Srwatson    struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel,
1254101099Srwatson    struct mbuf *newmbuf, struct label *newmbuflabel)
1255101099Srwatson{
1256101099Srwatson	struct mac_biba *source, *dest;
1257101099Srwatson
1258101099Srwatson	source = SLOT(oldmbuflabel);
1259101099Srwatson	dest = SLOT(newmbuflabel);
1260101099Srwatson
1261101099Srwatson	mac_biba_copy_single(source, dest);
1262101099Srwatson}
1263101099Srwatson
1264101099Srwatsonstatic void
1265101099Srwatsonmac_biba_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel,
1266101099Srwatson    struct mbuf *newmbuf, struct label *newmbuflabel)
1267101099Srwatson{
1268101099Srwatson	struct mac_biba *source, *dest;
1269101099Srwatson
1270101099Srwatson	source = SLOT(oldmbuflabel);
1271101099Srwatson	dest = SLOT(newmbuflabel);
1272101099Srwatson
1273101099Srwatson	mac_biba_copy_single(source, dest);
1274101099Srwatson}
1275101099Srwatson
1276101099Srwatsonstatic int
1277101099Srwatsonmac_biba_fragment_match(struct mbuf *fragment, struct label *fragmentlabel,
1278101099Srwatson    struct ipq *ipq, struct label *ipqlabel)
1279101099Srwatson{
1280101099Srwatson	struct mac_biba *a, *b;
1281101099Srwatson
1282101099Srwatson	a = SLOT(ipqlabel);
1283101099Srwatson	b = SLOT(fragmentlabel);
1284101099Srwatson
1285101099Srwatson	return (mac_biba_equal_single(a, b));
1286101099Srwatson}
1287101099Srwatson
1288101099Srwatsonstatic void
1289101099Srwatsonmac_biba_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet,
1290101099Srwatson    struct label *ifnetlabel, struct label *newlabel)
1291101099Srwatson{
1292101099Srwatson	struct mac_biba *source, *dest;
1293101099Srwatson
1294101099Srwatson	source = SLOT(newlabel);
1295101099Srwatson	dest = SLOT(ifnetlabel);
1296101099Srwatson
1297105656Srwatson	mac_biba_copy(source, dest);
1298101099Srwatson}
1299101099Srwatson
1300101099Srwatsonstatic void
1301101099Srwatsonmac_biba_update_ipq(struct mbuf *fragment, struct label *fragmentlabel,
1302101099Srwatson    struct ipq *ipq, struct label *ipqlabel)
1303101099Srwatson{
1304101099Srwatson
1305101099Srwatson	/* NOOP: we only accept matching labels, so no need to update */
1306101099Srwatson}
1307101099Srwatson
1308101099Srwatson/*
1309101099Srwatson * Labeling event operations: processes.
1310101099Srwatson */
1311101099Srwatsonstatic void
1312101099Srwatsonmac_biba_create_cred(struct ucred *cred_parent, struct ucred *cred_child)
1313101099Srwatson{
1314101099Srwatson	struct mac_biba *source, *dest;
1315101099Srwatson
1316122524Srwatson	source = SLOT(cred_parent->cr_label);
1317122524Srwatson	dest = SLOT(cred_child->cr_label);
1318101099Srwatson
1319101099Srwatson	mac_biba_copy_single(source, dest);
1320101099Srwatson	mac_biba_copy_range(source, dest);
1321101099Srwatson}
1322101099Srwatson
1323101099Srwatsonstatic void
1324101099Srwatsonmac_biba_create_proc0(struct ucred *cred)
1325101099Srwatson{
1326101099Srwatson	struct mac_biba *dest;
1327101099Srwatson
1328122524Srwatson	dest = SLOT(cred->cr_label);
1329101099Srwatson
1330105643Srwatson	mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1331105643Srwatson	mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL,
1332105643Srwatson	    MAC_BIBA_TYPE_HIGH, 0, NULL);
1333101099Srwatson}
1334101099Srwatson
1335101099Srwatsonstatic void
1336101099Srwatsonmac_biba_create_proc1(struct ucred *cred)
1337101099Srwatson{
1338101099Srwatson	struct mac_biba *dest;
1339101099Srwatson
1340122524Srwatson	dest = SLOT(cred->cr_label);
1341101099Srwatson
1342105643Srwatson	mac_biba_set_single(dest, MAC_BIBA_TYPE_HIGH, 0, NULL);
1343105643Srwatson	mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL,
1344105643Srwatson	    MAC_BIBA_TYPE_HIGH, 0, NULL);
1345101099Srwatson}
1346101099Srwatson
1347101099Srwatsonstatic void
1348101099Srwatsonmac_biba_relabel_cred(struct ucred *cred, struct label *newlabel)
1349101099Srwatson{
1350101099Srwatson	struct mac_biba *source, *dest;
1351101099Srwatson
1352101099Srwatson	source = SLOT(newlabel);
1353122524Srwatson	dest = SLOT(cred->cr_label);
1354101099Srwatson
1355105656Srwatson	mac_biba_copy(source, dest);
1356101099Srwatson}
1357101099Srwatson
1358101099Srwatson/*
1359101099Srwatson * Access control checks.
1360101099Srwatson */
1361101099Srwatsonstatic int
1362101099Srwatsonmac_biba_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel,
1363101099Srwatson    struct ifnet *ifnet, struct label *ifnetlabel)
1364101099Srwatson{
1365101099Srwatson	struct mac_biba *a, *b;
1366101099Srwatson
1367101099Srwatson	if (!mac_biba_enabled)
1368101099Srwatson		return (0);
1369101099Srwatson
1370101099Srwatson	a = SLOT(bpflabel);
1371101099Srwatson	b = SLOT(ifnetlabel);
1372101099Srwatson
1373101099Srwatson	if (mac_biba_equal_single(a, b))
1374101099Srwatson		return (0);
1375101099Srwatson	return (EACCES);
1376101099Srwatson}
1377101099Srwatson
1378101099Srwatsonstatic int
1379101099Srwatsonmac_biba_check_cred_relabel(struct ucred *cred, struct label *newlabel)
1380101099Srwatson{
1381101099Srwatson	struct mac_biba *subj, *new;
1382105634Srwatson	int error;
1383101099Srwatson
1384122524Srwatson	subj = SLOT(cred->cr_label);
1385101099Srwatson	new = SLOT(newlabel);
1386101099Srwatson
1387101099Srwatson	/*
1388105634Srwatson	 * If there is a Biba label update for the credential, it may
1389105634Srwatson	 * be an update of the single, range, or both.
1390101099Srwatson	 */
1391105634Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
1392105634Srwatson	if (error)
1393105634Srwatson		return (error);
1394101099Srwatson
1395101099Srwatson	/*
1396105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
1397101099Srwatson	 */
1398105634Srwatson	if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) {
1399105634Srwatson		/*
1400110351Srwatson		 * If the change request modifies both the Biba label
1401110351Srwatson		 * single and range, check that the new single will be
1402110351Srwatson		 * in the new range.
1403110351Srwatson		 */
1404110351Srwatson		if ((new->mb_flags & MAC_BIBA_FLAGS_BOTH) ==
1405110351Srwatson		    MAC_BIBA_FLAGS_BOTH &&
1406110351Srwatson		    !mac_biba_single_in_range(new, new))
1407110351Srwatson			return (EINVAL);
1408110351Srwatson
1409110351Srwatson		/*
1410105634Srwatson		 * To change the Biba single label on a credential, the
1411105634Srwatson		 * new single label must be in the current range.
1412105634Srwatson		 */
1413105634Srwatson		if (new->mb_flags & MAC_BIBA_FLAG_SINGLE &&
1414105634Srwatson		    !mac_biba_single_in_range(new, subj))
1415105634Srwatson			return (EPERM);
1416101099Srwatson
1417105634Srwatson		/*
1418105634Srwatson		 * To change the Biba range on a credential, the new
1419105634Srwatson		 * range label must be in the current range.
1420105634Srwatson		 */
1421105634Srwatson		if (new->mb_flags & MAC_BIBA_FLAG_RANGE &&
1422105634Srwatson		    !mac_biba_range_in_range(new, subj))
1423105634Srwatson			return (EPERM);
1424101099Srwatson
1425105634Srwatson		/*
1426105634Srwatson		 * To have EQUAL in any component of the new credential
1427105634Srwatson		 * Biba label, the subject must already have EQUAL in
1428105634Srwatson		 * their label.
1429105634Srwatson		 */
1430105634Srwatson		if (mac_biba_contains_equal(new)) {
1431106090Srwatson			error = mac_biba_subject_privileged(subj);
1432105634Srwatson			if (error)
1433105634Srwatson				return (error);
1434105634Srwatson		}
1435105634Srwatson	}
1436105634Srwatson
1437101099Srwatson	return (0);
1438101099Srwatson}
1439101099Srwatson
1440101099Srwatsonstatic int
1441101099Srwatsonmac_biba_check_cred_visible(struct ucred *u1, struct ucred *u2)
1442101099Srwatson{
1443101099Srwatson	struct mac_biba *subj, *obj;
1444101099Srwatson
1445101099Srwatson	if (!mac_biba_enabled)
1446101099Srwatson		return (0);
1447101099Srwatson
1448122524Srwatson	subj = SLOT(u1->cr_label);
1449122524Srwatson	obj = SLOT(u2->cr_label);
1450101099Srwatson
1451101099Srwatson	/* XXX: range */
1452101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1453101099Srwatson		return (ESRCH);
1454101099Srwatson
1455101099Srwatson	return (0);
1456101099Srwatson}
1457101099Srwatson
1458101099Srwatsonstatic int
1459101099Srwatsonmac_biba_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet,
1460101099Srwatson    struct label *ifnetlabel, struct label *newlabel)
1461101099Srwatson{
1462101099Srwatson	struct mac_biba *subj, *new;
1463105634Srwatson	int error;
1464101099Srwatson
1465122524Srwatson	subj = SLOT(cred->cr_label);
1466101099Srwatson	new = SLOT(newlabel);
1467101099Srwatson
1468105634Srwatson	/*
1469105634Srwatson	 * If there is a Biba label update for the interface, it may
1470105634Srwatson	 * be an update of the single, range, or both.
1471105634Srwatson	 */
1472105634Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
1473105634Srwatson	if (error)
1474105634Srwatson		return (error);
1475101099Srwatson
1476105634Srwatson	/*
1477106160Srwatson	 * Relabling network interfaces requires Biba privilege.
1478106160Srwatson	 */
1479106160Srwatson	error = mac_biba_subject_privileged(subj);
1480106160Srwatson	if (error)
1481106160Srwatson		return (error);
1482106160Srwatson
1483105634Srwatson	return (0);
1484101099Srwatson}
1485101099Srwatson
1486103759Srwatsonstatic int
1487101099Srwatsonmac_biba_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel,
1488101099Srwatson    struct mbuf *m, struct label *mbuflabel)
1489101099Srwatson{
1490101099Srwatson	struct mac_biba *p, *i;
1491103761Srwatson
1492101099Srwatson	if (!mac_biba_enabled)
1493101099Srwatson		return (0);
1494101099Srwatson
1495101099Srwatson	p = SLOT(mbuflabel);
1496101099Srwatson	i = SLOT(ifnetlabel);
1497103759Srwatson
1498101099Srwatson	return (mac_biba_single_in_range(p, i) ? 0 : EACCES);
1499101099Srwatson}
1500101099Srwatson
1501101099Srwatsonstatic int
1502110354Srwatsonmac_biba_check_kld_load(struct ucred *cred, struct vnode *vp,
1503110354Srwatson    struct label *label)
1504110354Srwatson{
1505110354Srwatson	struct mac_biba *subj, *obj;
1506110354Srwatson	int error;
1507110354Srwatson
1508110354Srwatson	if (!mac_biba_enabled)
1509110354Srwatson		return (0);
1510110354Srwatson
1511122524Srwatson	subj = SLOT(cred->cr_label);
1512110354Srwatson
1513110354Srwatson	error = mac_biba_subject_privileged(subj);
1514110354Srwatson	if (error)
1515110354Srwatson		return (error);
1516110354Srwatson
1517110354Srwatson	obj = SLOT(label);
1518110354Srwatson	if (!mac_biba_high_single(obj))
1519110354Srwatson		return (EACCES);
1520110354Srwatson
1521110354Srwatson	return (0);
1522110354Srwatson}
1523110354Srwatson
1524110354Srwatson
1525110354Srwatsonstatic int
1526110354Srwatsonmac_biba_check_kld_unload(struct ucred *cred)
1527110354Srwatson{
1528110354Srwatson	struct mac_biba *subj;
1529110354Srwatson
1530110354Srwatson	if (!mac_biba_enabled)
1531110354Srwatson		return (0);
1532110354Srwatson
1533122524Srwatson	subj = SLOT(cred->cr_label);
1534110354Srwatson
1535110354Srwatson	return (mac_biba_subject_privileged(subj));
1536110354Srwatson}
1537110354Srwatson
1538110354Srwatsonstatic int
1539101099Srwatsonmac_biba_check_mount_stat(struct ucred *cred, struct mount *mp,
1540101099Srwatson    struct label *mntlabel)
1541101099Srwatson{
1542101099Srwatson	struct mac_biba *subj, *obj;
1543101099Srwatson
1544101099Srwatson	if (!mac_biba_enabled)
1545101099Srwatson		return (0);
1546101099Srwatson
1547122524Srwatson	subj = SLOT(cred->cr_label);
1548101099Srwatson	obj = SLOT(mntlabel);
1549101099Srwatson
1550101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1551101099Srwatson		return (EACCES);
1552101099Srwatson
1553101099Srwatson	return (0);
1554101099Srwatson}
1555101099Srwatson
1556101099Srwatsonstatic int
1557101099Srwatsonmac_biba_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe,
1558101099Srwatson    struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data)
1559101099Srwatson{
1560103759Srwatson
1561101099Srwatson	if(!mac_biba_enabled)
1562101099Srwatson		return (0);
1563101099Srwatson
1564101099Srwatson	/* XXX: This will be implemented soon... */
1565101099Srwatson
1566101099Srwatson	return (0);
1567101099Srwatson}
1568101099Srwatson
1569101099Srwatsonstatic int
1570102115Srwatsonmac_biba_check_pipe_poll(struct ucred *cred, struct pipe *pipe,
1571102115Srwatson    struct label *pipelabel)
1572101099Srwatson{
1573101099Srwatson	struct mac_biba *subj, *obj;
1574101099Srwatson
1575101099Srwatson	if (!mac_biba_enabled)
1576101099Srwatson		return (0);
1577101099Srwatson
1578122524Srwatson	subj = SLOT(cred->cr_label);
1579101099Srwatson	obj = SLOT((pipelabel));
1580101099Srwatson
1581102115Srwatson	if (!mac_biba_dominate_single(obj, subj))
1582102115Srwatson		return (EACCES);
1583101099Srwatson
1584101099Srwatson	return (0);
1585101099Srwatson}
1586101099Srwatson
1587101099Srwatsonstatic int
1588102115Srwatsonmac_biba_check_pipe_read(struct ucred *cred, struct pipe *pipe,
1589102115Srwatson    struct label *pipelabel)
1590102115Srwatson{
1591102115Srwatson	struct mac_biba *subj, *obj;
1592102115Srwatson
1593102115Srwatson	if (!mac_biba_enabled)
1594102115Srwatson		return (0);
1595102115Srwatson
1596122524Srwatson	subj = SLOT(cred->cr_label);
1597102115Srwatson	obj = SLOT((pipelabel));
1598102115Srwatson
1599102115Srwatson	if (!mac_biba_dominate_single(obj, subj))
1600102115Srwatson		return (EACCES);
1601102115Srwatson
1602102115Srwatson	return (0);
1603102115Srwatson}
1604102115Srwatson
1605102115Srwatsonstatic int
1606101099Srwatsonmac_biba_check_pipe_relabel(struct ucred *cred, struct pipe *pipe,
1607101099Srwatson    struct label *pipelabel, struct label *newlabel)
1608101099Srwatson{
1609101099Srwatson	struct mac_biba *subj, *obj, *new;
1610105634Srwatson	int error;
1611101099Srwatson
1612101099Srwatson	new = SLOT(newlabel);
1613122524Srwatson	subj = SLOT(cred->cr_label);
1614101099Srwatson	obj = SLOT(pipelabel);
1615101099Srwatson
1616101099Srwatson	/*
1617105634Srwatson	 * If there is a Biba label update for a pipe, it must be a
1618105634Srwatson	 * single update.
1619101099Srwatson	 */
1620105634Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE);
1621105634Srwatson	if (error)
1622105634Srwatson		return (error);
1623101099Srwatson
1624101099Srwatson	/*
1625105634Srwatson	 * To perform a relabel of a pipe (Biba label or not), Biba must
1626105634Srwatson	 * authorize the relabel.
1627101099Srwatson	 */
1628105634Srwatson	if (!mac_biba_single_in_range(obj, subj))
1629101099Srwatson		return (EPERM);
1630101099Srwatson
1631101099Srwatson	/*
1632105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
1633101099Srwatson	 */
1634105634Srwatson	if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) {
1635105634Srwatson		/*
1636105634Srwatson		 * To change the Biba label on a pipe, the new pipe label
1637105634Srwatson		 * must be in the subject range.
1638105634Srwatson		 */
1639105634Srwatson		if (!mac_biba_single_in_range(new, subj))
1640105634Srwatson			return (EPERM);
1641101099Srwatson
1642105634Srwatson		/*
1643105634Srwatson		 * To change the Biba label on a pipe to be EQUAL, the
1644105634Srwatson		 * subject must have appropriate privilege.
1645105634Srwatson		 */
1646105634Srwatson		if (mac_biba_contains_equal(new)) {
1647106090Srwatson			error = mac_biba_subject_privileged(subj);
1648105634Srwatson			if (error)
1649105634Srwatson				return (error);
1650105634Srwatson		}
1651105634Srwatson	}
1652105634Srwatson
1653101099Srwatson	return (0);
1654101099Srwatson}
1655101099Srwatson
1656101099Srwatsonstatic int
1657102115Srwatsonmac_biba_check_pipe_stat(struct ucred *cred, struct pipe *pipe,
1658102115Srwatson    struct label *pipelabel)
1659102115Srwatson{
1660102115Srwatson	struct mac_biba *subj, *obj;
1661102115Srwatson
1662102115Srwatson	if (!mac_biba_enabled)
1663102115Srwatson		return (0);
1664102115Srwatson
1665122524Srwatson	subj = SLOT(cred->cr_label);
1666102115Srwatson	obj = SLOT((pipelabel));
1667102115Srwatson
1668102115Srwatson	if (!mac_biba_dominate_single(obj, subj))
1669102115Srwatson		return (EACCES);
1670102115Srwatson
1671102115Srwatson	return (0);
1672102115Srwatson}
1673102115Srwatson
1674102115Srwatsonstatic int
1675102115Srwatsonmac_biba_check_pipe_write(struct ucred *cred, struct pipe *pipe,
1676102115Srwatson    struct label *pipelabel)
1677102115Srwatson{
1678102115Srwatson	struct mac_biba *subj, *obj;
1679102115Srwatson
1680102115Srwatson	if (!mac_biba_enabled)
1681102115Srwatson		return (0);
1682102115Srwatson
1683122524Srwatson	subj = SLOT(cred->cr_label);
1684102115Srwatson	obj = SLOT((pipelabel));
1685102115Srwatson
1686102115Srwatson	if (!mac_biba_dominate_single(subj, obj))
1687102115Srwatson		return (EACCES);
1688102115Srwatson
1689102115Srwatson	return (0);
1690102115Srwatson}
1691102115Srwatson
1692102115Srwatsonstatic int
1693101099Srwatsonmac_biba_check_proc_debug(struct ucred *cred, struct proc *proc)
1694101099Srwatson{
1695101099Srwatson	struct mac_biba *subj, *obj;
1696101099Srwatson
1697101099Srwatson	if (!mac_biba_enabled)
1698101099Srwatson		return (0);
1699101099Srwatson
1700122524Srwatson	subj = SLOT(cred->cr_label);
1701122524Srwatson	obj = SLOT(proc->p_ucred->cr_label);
1702101099Srwatson
1703101099Srwatson	/* XXX: range checks */
1704101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1705101099Srwatson		return (ESRCH);
1706101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1707101099Srwatson		return (EACCES);
1708101099Srwatson
1709101099Srwatson	return (0);
1710101099Srwatson}
1711101099Srwatson
1712101099Srwatsonstatic int
1713101099Srwatsonmac_biba_check_proc_sched(struct ucred *cred, struct proc *proc)
1714101099Srwatson{
1715101099Srwatson	struct mac_biba *subj, *obj;
1716103759Srwatson
1717101099Srwatson	if (!mac_biba_enabled)
1718101099Srwatson		return (0);
1719101099Srwatson
1720122524Srwatson	subj = SLOT(cred->cr_label);
1721122524Srwatson	obj = SLOT(proc->p_ucred->cr_label);
1722103759Srwatson
1723101099Srwatson	/* XXX: range checks */
1724101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1725101099Srwatson		return (ESRCH);
1726101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1727101099Srwatson		return (EACCES);
1728101099Srwatson
1729101099Srwatson	return (0);
1730101099Srwatson}
1731101099Srwatson
1732101099Srwatsonstatic int
1733101099Srwatsonmac_biba_check_proc_signal(struct ucred *cred, struct proc *proc, int signum)
1734101099Srwatson{
1735101099Srwatson	struct mac_biba *subj, *obj;
1736103759Srwatson
1737101099Srwatson	if (!mac_biba_enabled)
1738101099Srwatson		return (0);
1739101099Srwatson
1740122524Srwatson	subj = SLOT(cred->cr_label);
1741122524Srwatson	obj = SLOT(proc->p_ucred->cr_label);
1742103759Srwatson
1743101099Srwatson	/* XXX: range checks */
1744101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1745101099Srwatson		return (ESRCH);
1746101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1747101099Srwatson		return (EACCES);
1748101099Srwatson
1749101099Srwatson	return (0);
1750101099Srwatson}
1751101099Srwatson
1752101099Srwatsonstatic int
1753101934Srwatsonmac_biba_check_socket_deliver(struct socket *so, struct label *socketlabel,
1754101099Srwatson    struct mbuf *m, struct label *mbuflabel)
1755101099Srwatson{
1756101099Srwatson	struct mac_biba *p, *s;
1757101099Srwatson
1758101099Srwatson	if (!mac_biba_enabled)
1759101099Srwatson		return (0);
1760101099Srwatson
1761101099Srwatson	p = SLOT(mbuflabel);
1762101099Srwatson	s = SLOT(socketlabel);
1763101099Srwatson
1764101099Srwatson	return (mac_biba_equal_single(p, s) ? 0 : EACCES);
1765101099Srwatson}
1766101099Srwatson
1767101099Srwatsonstatic int
1768106214Srwatsonmac_biba_check_socket_relabel(struct ucred *cred, struct socket *so,
1769101099Srwatson    struct label *socketlabel, struct label *newlabel)
1770101099Srwatson{
1771101099Srwatson	struct mac_biba *subj, *obj, *new;
1772105634Srwatson	int error;
1773101099Srwatson
1774101099Srwatson	new = SLOT(newlabel);
1775122524Srwatson	subj = SLOT(cred->cr_label);
1776101099Srwatson	obj = SLOT(socketlabel);
1777101099Srwatson
1778101099Srwatson	/*
1779105634Srwatson	 * If there is a Biba label update for the socket, it may be
1780105634Srwatson	 * an update of single.
1781101099Srwatson	 */
1782105634Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE);
1783105634Srwatson	if (error)
1784105634Srwatson		return (error);
1785101099Srwatson
1786101099Srwatson	/*
1787105634Srwatson	 * To relabel a socket, the old socket single must be in the subject
1788101099Srwatson	 * range.
1789101099Srwatson	 */
1790105634Srwatson	if (!mac_biba_single_in_range(obj, subj))
1791101099Srwatson		return (EPERM);
1792101099Srwatson
1793101099Srwatson	/*
1794105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
1795101099Srwatson	 */
1796105634Srwatson	if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) {
1797105634Srwatson		/*
1798105634Srwatson		 * To relabel a socket, the new socket single must be in
1799105634Srwatson		 * the subject range.
1800105634Srwatson		 */
1801105634Srwatson		if (!mac_biba_single_in_range(new, subj))
1802105634Srwatson			return (EPERM);
1803101099Srwatson
1804105634Srwatson		/*
1805105634Srwatson		 * To change the Biba label on the socket to contain EQUAL,
1806105634Srwatson		 * the subject must have appropriate privilege.
1807105634Srwatson		 */
1808105634Srwatson		if (mac_biba_contains_equal(new)) {
1809106090Srwatson			error = mac_biba_subject_privileged(subj);
1810105634Srwatson			if (error)
1811105634Srwatson				return (error);
1812105634Srwatson		}
1813105634Srwatson	}
1814105634Srwatson
1815101099Srwatson	return (0);
1816101099Srwatson}
1817101099Srwatson
1818101099Srwatsonstatic int
1819101099Srwatsonmac_biba_check_socket_visible(struct ucred *cred, struct socket *socket,
1820101099Srwatson    struct label *socketlabel)
1821101099Srwatson{
1822101099Srwatson	struct mac_biba *subj, *obj;
1823101099Srwatson
1824105722Srwatson	if (!mac_biba_enabled)
1825105722Srwatson		return (0);
1826105722Srwatson
1827122524Srwatson	subj = SLOT(cred->cr_label);
1828101099Srwatson	obj = SLOT(socketlabel);
1829101099Srwatson
1830101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1831101099Srwatson		return (ENOENT);
1832101099Srwatson
1833101099Srwatson	return (0);
1834101099Srwatson}
1835101099Srwatson
1836101099Srwatsonstatic int
1837112574Srwatsonmac_biba_check_sysarch_ioperm(struct ucred *cred)
1838112574Srwatson{
1839112574Srwatson	struct mac_biba *subj;
1840112574Srwatson	int error;
1841112574Srwatson
1842112574Srwatson	if (!mac_biba_enabled)
1843112574Srwatson		return (0);
1844112574Srwatson
1845122524Srwatson	subj = SLOT(cred->cr_label);
1846112574Srwatson
1847112574Srwatson	error = mac_biba_subject_privileged(subj);
1848112574Srwatson	if (error)
1849112574Srwatson		return (error);
1850112574Srwatson
1851112574Srwatson	return (0);
1852112574Srwatson}
1853112574Srwatson
1854112574Srwatsonstatic int
1855106418Srwatsonmac_biba_check_system_acct(struct ucred *cred, struct vnode *vp,
1856106418Srwatson    struct label *label)
1857106418Srwatson{
1858106418Srwatson	struct mac_biba *subj, *obj;
1859106418Srwatson	int error;
1860106418Srwatson
1861106418Srwatson	if (!mac_biba_enabled)
1862106418Srwatson		return (0);
1863106418Srwatson
1864122524Srwatson	subj = SLOT(cred->cr_label);
1865106418Srwatson
1866106418Srwatson	error = mac_biba_subject_privileged(subj);
1867106418Srwatson	if (error)
1868106418Srwatson		return (error);
1869106418Srwatson
1870106418Srwatson	if (label == NULL)
1871106418Srwatson		return (0);
1872106418Srwatson
1873106418Srwatson	obj = SLOT(label);
1874106418Srwatson	if (!mac_biba_high_single(obj))
1875106418Srwatson		return (EACCES);
1876106418Srwatson
1877106418Srwatson	return (0);
1878106418Srwatson}
1879106418Srwatson
1880106418Srwatsonstatic int
1881106418Srwatsonmac_biba_check_system_settime(struct ucred *cred)
1882106418Srwatson{
1883106418Srwatson	struct mac_biba *subj;
1884106418Srwatson	int error;
1885106418Srwatson
1886106418Srwatson	if (!mac_biba_enabled)
1887106418Srwatson		return (0);
1888106418Srwatson
1889122524Srwatson	subj = SLOT(cred->cr_label);
1890106418Srwatson
1891106418Srwatson	error = mac_biba_subject_privileged(subj);
1892106418Srwatson	if (error)
1893106418Srwatson		return (error);
1894106418Srwatson
1895106418Srwatson	return (0);
1896106418Srwatson}
1897106418Srwatson
1898106418Srwatsonstatic int
1899106161Srwatsonmac_biba_check_system_swapon(struct ucred *cred, struct vnode *vp,
1900106161Srwatson    struct label *label)
1901106161Srwatson{
1902106161Srwatson	struct mac_biba *subj, *obj;
1903106416Srwatson	int error;
1904106161Srwatson
1905106161Srwatson	if (!mac_biba_enabled)
1906106161Srwatson		return (0);
1907106161Srwatson
1908122524Srwatson	subj = SLOT(cred->cr_label);
1909106161Srwatson	obj = SLOT(label);
1910106161Srwatson
1911106416Srwatson	error = mac_biba_subject_privileged(subj);
1912106416Srwatson	if (error)
1913106416Srwatson		return (error);
1914106161Srwatson
1915106161Srwatson	if (!mac_biba_high_single(obj))
1916106161Srwatson		return (EACCES);
1917106161Srwatson
1918106161Srwatson	return (0);
1919106161Srwatson}
1920106161Srwatson
1921106161Srwatsonstatic int
1922112574Srwatsonmac_biba_check_system_swapoff(struct ucred *cred, struct vnode *vp,
1923112574Srwatson    struct label *label)
1924112574Srwatson{
1925112574Srwatson	struct mac_biba *subj, *obj;
1926112574Srwatson	int error;
1927112574Srwatson
1928112574Srwatson	if (!mac_biba_enabled)
1929112574Srwatson		return (0);
1930112574Srwatson
1931122524Srwatson	subj = SLOT(cred->cr_label);
1932112574Srwatson	obj = SLOT(label);
1933112574Srwatson
1934112574Srwatson	error = mac_biba_subject_privileged(subj);
1935112574Srwatson	if (error)
1936112574Srwatson		return (error);
1937112574Srwatson
1938112574Srwatson	return (0);
1939112574Srwatson}
1940112574Srwatson
1941112574Srwatsonstatic int
1942106161Srwatsonmac_biba_check_system_sysctl(struct ucred *cred, int *name, u_int namelen,
1943106161Srwatson    void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen)
1944106161Srwatson{
1945106161Srwatson	struct mac_biba *subj;
1946106161Srwatson	int error;
1947106161Srwatson
1948106161Srwatson	if (!mac_biba_enabled)
1949106161Srwatson		return (0);
1950106161Srwatson
1951122524Srwatson	subj = SLOT(cred->cr_label);
1952106161Srwatson
1953106161Srwatson	/*
1954106161Srwatson	 * In general, treat sysctl variables as biba/high, but also
1955106161Srwatson	 * require privilege to change them, since they are a
1956106161Srwatson	 * communications channel between grades.  Exempt MIB
1957106161Srwatson	 * queries from this due to undocmented sysctl magic.
1958106161Srwatson	 * XXXMAC: This probably requires some more review.
1959106161Srwatson	 */
1960106161Srwatson	if (new != NULL) {
1961106161Srwatson		if (namelen > 0 && name[0] == 0)
1962106161Srwatson			return (0);
1963106161Srwatson
1964106161Srwatson		if (!mac_biba_subject_dominate_high(subj))
1965106161Srwatson			return (EACCES);
1966106161Srwatson
1967106161Srwatson		error = mac_biba_subject_privileged(subj);
1968106161Srwatson		if (error)
1969106161Srwatson			return (error);
1970106161Srwatson	}
1971106161Srwatson
1972106161Srwatson	return (0);
1973106161Srwatson}
1974106161Srwatson
1975106161Srwatsonstatic int
1976101099Srwatsonmac_biba_check_vnode_chdir(struct ucred *cred, struct vnode *dvp,
1977101099Srwatson    struct label *dlabel)
1978101099Srwatson{
1979101099Srwatson	struct mac_biba *subj, *obj;
1980101099Srwatson
1981101099Srwatson	if (!mac_biba_enabled)
1982101099Srwatson		return (0);
1983101099Srwatson
1984122524Srwatson	subj = SLOT(cred->cr_label);
1985101099Srwatson	obj = SLOT(dlabel);
1986101099Srwatson
1987101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1988101099Srwatson		return (EACCES);
1989101099Srwatson
1990101099Srwatson	return (0);
1991101099Srwatson}
1992101099Srwatson
1993101099Srwatsonstatic int
1994101099Srwatsonmac_biba_check_vnode_chroot(struct ucred *cred, struct vnode *dvp,
1995101099Srwatson    struct label *dlabel)
1996101099Srwatson{
1997101099Srwatson	struct mac_biba *subj, *obj;
1998101099Srwatson
1999101099Srwatson	if (!mac_biba_enabled)
2000101099Srwatson		return (0);
2001101099Srwatson
2002122524Srwatson	subj = SLOT(cred->cr_label);
2003101099Srwatson	obj = SLOT(dlabel);
2004101099Srwatson
2005101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
2006101099Srwatson		return (EACCES);
2007101099Srwatson
2008101099Srwatson	return (0);
2009101099Srwatson}
2010101099Srwatson
2011101099Srwatsonstatic int
2012101099Srwatsonmac_biba_check_vnode_create(struct ucred *cred, struct vnode *dvp,
2013101099Srwatson    struct label *dlabel, struct componentname *cnp, struct vattr *vap)
2014101099Srwatson{
2015101099Srwatson	struct mac_biba *subj, *obj;
2016101099Srwatson
2017101099Srwatson	if (!mac_biba_enabled)
2018101099Srwatson		return (0);
2019101099Srwatson
2020122524Srwatson	subj = SLOT(cred->cr_label);
2021101099Srwatson	obj = SLOT(dlabel);
2022101099Srwatson
2023101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2024101099Srwatson		return (EACCES);
2025101099Srwatson
2026101099Srwatson	return (0);
2027101099Srwatson}
2028101099Srwatson
2029101099Srwatsonstatic int
2030101099Srwatsonmac_biba_check_vnode_delete(struct ucred *cred, struct vnode *dvp,
2031101099Srwatson    struct label *dlabel, struct vnode *vp, struct label *label,
2032101099Srwatson    struct componentname *cnp)
2033101099Srwatson{
2034101099Srwatson	struct mac_biba *subj, *obj;
2035101099Srwatson
2036101099Srwatson	if (!mac_biba_enabled)
2037101099Srwatson		return (0);
2038101099Srwatson
2039122524Srwatson	subj = SLOT(cred->cr_label);
2040101099Srwatson	obj = SLOT(dlabel);
2041101099Srwatson
2042101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2043101099Srwatson		return (EACCES);
2044101099Srwatson
2045101099Srwatson	obj = SLOT(label);
2046101099Srwatson
2047101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2048101099Srwatson		return (EACCES);
2049101099Srwatson
2050101099Srwatson	return (0);
2051101099Srwatson}
2052101099Srwatson
2053101099Srwatsonstatic int
2054101099Srwatsonmac_biba_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
2055101099Srwatson    struct label *label, acl_type_t type)
2056101099Srwatson{
2057101099Srwatson	struct mac_biba *subj, *obj;
2058101099Srwatson
2059101099Srwatson	if (!mac_biba_enabled)
2060101099Srwatson		return (0);
2061101099Srwatson
2062122524Srwatson	subj = SLOT(cred->cr_label);
2063101099Srwatson	obj = SLOT(label);
2064101099Srwatson
2065101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2066101099Srwatson		return (EACCES);
2067101099Srwatson
2068101099Srwatson	return (0);
2069101099Srwatson}
2070101099Srwatson
2071101099Srwatsonstatic int
2072119202Srwatsonmac_biba_check_vnode_deleteextattr(struct ucred *cred, struct vnode *vp,
2073119202Srwatson    struct label *label, int attrnamespace, const char *name)
2074119202Srwatson{
2075119202Srwatson	struct mac_biba *subj, *obj;
2076119202Srwatson
2077119202Srwatson	if (!mac_biba_enabled)
2078119202Srwatson		return (0);
2079119202Srwatson
2080122524Srwatson	subj = SLOT(cred->cr_label);
2081119202Srwatson	obj = SLOT(label);
2082119202Srwatson
2083119202Srwatson	if (!mac_biba_dominate_single(subj, obj))
2084119202Srwatson		return (EACCES);
2085119202Srwatson
2086119202Srwatson	return (0);
2087119202Srwatson}
2088119202Srwatson
2089119202Srwatsonstatic int
2090101099Srwatsonmac_biba_check_vnode_exec(struct ucred *cred, struct vnode *vp,
2091106648Srwatson    struct label *label, struct image_params *imgp,
2092106648Srwatson    struct label *execlabel)
2093101099Srwatson{
2094106648Srwatson	struct mac_biba *subj, *obj, *exec;
2095106648Srwatson	int error;
2096101099Srwatson
2097106648Srwatson	if (execlabel != NULL) {
2098106648Srwatson		/*
2099106648Srwatson		 * We currently don't permit labels to be changed at
2100106648Srwatson		 * exec-time as part of Biba, so disallow non-NULL
2101106648Srwatson		 * Biba label elements in the execlabel.
2102106648Srwatson		 */
2103106648Srwatson		exec = SLOT(execlabel);
2104106648Srwatson		error = biba_atmostflags(exec, 0);
2105106648Srwatson		if (error)
2106106648Srwatson			return (error);
2107106648Srwatson	}
2108106648Srwatson
2109101099Srwatson	if (!mac_biba_enabled)
2110101099Srwatson		return (0);
2111101099Srwatson
2112122524Srwatson	subj = SLOT(cred->cr_label);
2113101099Srwatson	obj = SLOT(label);
2114101099Srwatson
2115101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
2116101099Srwatson		return (EACCES);
2117101099Srwatson
2118101099Srwatson	return (0);
2119101099Srwatson}
2120101099Srwatson
2121101099Srwatsonstatic int
2122101099Srwatsonmac_biba_check_vnode_getacl(struct ucred *cred, struct vnode *vp,
2123101099Srwatson    struct label *label, acl_type_t type)
2124101099Srwatson{
2125101099Srwatson	struct mac_biba *subj, *obj;
2126101099Srwatson
2127101099Srwatson	if (!mac_biba_enabled)
2128101099Srwatson		return (0);
2129101099Srwatson
2130122524Srwatson	subj = SLOT(cred->cr_label);
2131101099Srwatson	obj = SLOT(label);
2132101099Srwatson
2133101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
2134101099Srwatson		return (EACCES);
2135101099Srwatson
2136101099Srwatson	return (0);
2137101099Srwatson}
2138101099Srwatson
2139101099Srwatsonstatic int
2140101099Srwatsonmac_biba_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
2141101099Srwatson    struct label *label, int attrnamespace, const char *name, struct uio *uio)
2142101099Srwatson{
2143101099Srwatson	struct mac_biba *subj, *obj;
2144101099Srwatson
2145101099Srwatson	if (!mac_biba_enabled)
2146101099Srwatson		return (0);
2147101099Srwatson
2148122524Srwatson	subj = SLOT(cred->cr_label);
2149101099Srwatson	obj = SLOT(label);
2150101099Srwatson
2151101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
2152101099Srwatson		return (EACCES);
2153101099Srwatson
2154101099Srwatson	return (0);
2155101099Srwatson}
2156101099Srwatson
2157101099Srwatsonstatic int
2158104530Srwatsonmac_biba_check_vnode_link(struct ucred *cred, struct vnode *dvp,
2159104530Srwatson    struct label *dlabel, struct vnode *vp, struct label *label,
2160104530Srwatson    struct componentname *cnp)
2161104530Srwatson{
2162104530Srwatson	struct mac_biba *subj, *obj;
2163104530Srwatson
2164104530Srwatson	if (!mac_biba_enabled)
2165104530Srwatson		return (0);
2166104530Srwatson
2167122524Srwatson	subj = SLOT(cred->cr_label);
2168104530Srwatson	obj = SLOT(dlabel);
2169104530Srwatson
2170104530Srwatson	if (!mac_biba_dominate_single(subj, obj))
2171104530Srwatson		return (EACCES);
2172104530Srwatson
2173104530Srwatson	obj = SLOT(label);
2174104530Srwatson
2175104530Srwatson	if (!mac_biba_dominate_single(subj, obj))
2176104530Srwatson		return (EACCES);
2177104530Srwatson
2178104530Srwatson	return (0);
2179104530Srwatson}
2180104530Srwatson
2181104530Srwatsonstatic int
2182119202Srwatsonmac_biba_check_vnode_listextattr(struct ucred *cred, struct vnode *vp,
2183119202Srwatson    struct label *label, int attrnamespace)
2184119202Srwatson{
2185119202Srwatson	struct mac_biba *subj, *obj;
2186119202Srwatson
2187119202Srwatson	if (!mac_biba_enabled)
2188119202Srwatson		return (0);
2189119202Srwatson
2190122524Srwatson	subj = SLOT(cred->cr_label);
2191119202Srwatson	obj = SLOT(label);
2192119202Srwatson
2193119202Srwatson	if (!mac_biba_dominate_single(obj, subj))
2194119202Srwatson		return (EACCES);
2195119202Srwatson
2196119202Srwatson	return (0);
2197119202Srwatson}
2198119202Srwatson
2199119202Srwatsonstatic int
2200103759Srwatsonmac_biba_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
2201101099Srwatson    struct label *dlabel, struct componentname *cnp)
2202101099Srwatson{
2203101099Srwatson	struct mac_biba *subj, *obj;
2204103759Srwatson
2205101099Srwatson	if (!mac_biba_enabled)
2206101099Srwatson		return (0);
2207103759Srwatson
2208122524Srwatson	subj = SLOT(cred->cr_label);
2209101099Srwatson	obj = SLOT(dlabel);
2210103759Srwatson
2211101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
2212101099Srwatson		return (EACCES);
2213101099Srwatson
2214103759Srwatson	return (0);
2215101099Srwatson}
2216101099Srwatson
2217101099Srwatsonstatic int
2218104546Srwatsonmac_biba_check_vnode_mmap(struct ucred *cred, struct vnode *vp,
2219104546Srwatson    struct label *label, int prot)
2220104546Srwatson{
2221104546Srwatson	struct mac_biba *subj, *obj;
2222104546Srwatson
2223104546Srwatson	/*
2224104546Srwatson	 * Rely on the use of open()-time protections to handle
2225104546Srwatson	 * non-revocation cases.
2226104546Srwatson	 */
2227105637Srwatson	if (!mac_biba_enabled || !revocation_enabled)
2228104546Srwatson		return (0);
2229104546Srwatson
2230122524Srwatson	subj = SLOT(cred->cr_label);
2231104546Srwatson	obj = SLOT(label);
2232104546Srwatson
2233104546Srwatson	if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
2234104546Srwatson		if (!mac_biba_dominate_single(obj, subj))
2235104546Srwatson			return (EACCES);
2236104546Srwatson	}
2237104546Srwatson	if (prot & VM_PROT_WRITE) {
2238104546Srwatson		if (!mac_biba_dominate_single(subj, obj))
2239104546Srwatson			return (EACCES);
2240104546Srwatson	}
2241104546Srwatson
2242104569Srwatson	return (0);
2243104546Srwatson}
2244104546Srwatson
2245104546Srwatsonstatic int
2246101099Srwatsonmac_biba_check_vnode_open(struct ucred *cred, struct vnode *vp,
2247106212Srwatson    struct label *vnodelabel, int acc_mode)
2248101099Srwatson{
2249101099Srwatson	struct mac_biba *subj, *obj;
2250101099Srwatson
2251101099Srwatson	if (!mac_biba_enabled)
2252101099Srwatson		return (0);
2253101099Srwatson
2254122524Srwatson	subj = SLOT(cred->cr_label);
2255101099Srwatson	obj = SLOT(vnodelabel);
2256101099Srwatson
2257101099Srwatson	/* XXX privilege override for admin? */
2258101099Srwatson	if (acc_mode & (VREAD | VEXEC | VSTAT)) {
2259101099Srwatson		if (!mac_biba_dominate_single(obj, subj))
2260101099Srwatson			return (EACCES);
2261101099Srwatson	}
2262101099Srwatson	if (acc_mode & (VWRITE | VAPPEND | VADMIN)) {
2263101099Srwatson		if (!mac_biba_dominate_single(subj, obj))
2264101099Srwatson			return (EACCES);
2265101099Srwatson	}
2266101099Srwatson
2267101099Srwatson	return (0);
2268101099Srwatson}
2269101099Srwatson
2270101099Srwatsonstatic int
2271102129Srwatsonmac_biba_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred,
2272102129Srwatson    struct vnode *vp, struct label *label)
2273102112Srwatson{
2274102112Srwatson	struct mac_biba *subj, *obj;
2275102112Srwatson
2276105637Srwatson	if (!mac_biba_enabled || !revocation_enabled)
2277102112Srwatson		return (0);
2278102112Srwatson
2279122524Srwatson	subj = SLOT(active_cred->cr_label);
2280102112Srwatson	obj = SLOT(label);
2281102112Srwatson
2282102112Srwatson	if (!mac_biba_dominate_single(obj, subj))
2283102112Srwatson		return (EACCES);
2284102112Srwatson
2285102112Srwatson	return (0);
2286102112Srwatson}
2287102112Srwatson
2288102112Srwatsonstatic int
2289102129Srwatsonmac_biba_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
2290102129Srwatson    struct vnode *vp, struct label *label)
2291102112Srwatson{
2292102112Srwatson	struct mac_biba *subj, *obj;
2293102112Srwatson
2294105637Srwatson	if (!mac_biba_enabled || !revocation_enabled)
2295102112Srwatson		return (0);
2296102112Srwatson
2297122524Srwatson	subj = SLOT(active_cred->cr_label);
2298102112Srwatson	obj = SLOT(label);
2299102112Srwatson
2300102112Srwatson	if (!mac_biba_dominate_single(obj, subj))
2301102112Srwatson		return (EACCES);
2302102112Srwatson
2303102112Srwatson	return (0);
2304102112Srwatson}
2305102112Srwatson
2306102112Srwatsonstatic int
2307101099Srwatsonmac_biba_check_vnode_readdir(struct ucred *cred, struct vnode *dvp,
2308101099Srwatson    struct label *dlabel)
2309101099Srwatson{
2310101099Srwatson	struct mac_biba *subj, *obj;
2311101099Srwatson
2312101099Srwatson	if (!mac_biba_enabled)
2313101099Srwatson		return (0);
2314101099Srwatson
2315122524Srwatson	subj = SLOT(cred->cr_label);
2316101099Srwatson	obj = SLOT(dlabel);
2317101099Srwatson
2318101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
2319101099Srwatson		return (EACCES);
2320101099Srwatson
2321101099Srwatson	return (0);
2322101099Srwatson}
2323101099Srwatson
2324101099Srwatsonstatic int
2325101099Srwatsonmac_biba_check_vnode_readlink(struct ucred *cred, struct vnode *vp,
2326101099Srwatson    struct label *label)
2327101099Srwatson{
2328101099Srwatson	struct mac_biba *subj, *obj;
2329101099Srwatson
2330101099Srwatson	if (!mac_biba_enabled)
2331101099Srwatson		return (0);
2332101099Srwatson
2333122524Srwatson	subj = SLOT(cred->cr_label);
2334101099Srwatson	obj = SLOT(label);
2335101099Srwatson
2336101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
2337101099Srwatson		return (EACCES);
2338101099Srwatson
2339101099Srwatson	return (0);
2340101099Srwatson}
2341101099Srwatson
2342101099Srwatsonstatic int
2343101099Srwatsonmac_biba_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
2344101099Srwatson    struct label *vnodelabel, struct label *newlabel)
2345101099Srwatson{
2346101099Srwatson	struct mac_biba *old, *new, *subj;
2347105634Srwatson	int error;
2348101099Srwatson
2349101099Srwatson	old = SLOT(vnodelabel);
2350101099Srwatson	new = SLOT(newlabel);
2351122524Srwatson	subj = SLOT(cred->cr_label);
2352101099Srwatson
2353101099Srwatson	/*
2354105634Srwatson	 * If there is a Biba label update for the vnode, it must be a
2355105634Srwatson	 * single label.
2356101099Srwatson	 */
2357105634Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE);
2358105634Srwatson	if (error)
2359105634Srwatson		return (error);
2360101099Srwatson
2361101099Srwatson	/*
2362105634Srwatson	 * To perform a relabel of the vnode (Biba label or not), Biba must
2363105634Srwatson	 * authorize the relabel.
2364101099Srwatson	 */
2365105634Srwatson	if (!mac_biba_single_in_range(old, subj))
2366101099Srwatson		return (EPERM);
2367101099Srwatson
2368101099Srwatson	/*
2369105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
2370101099Srwatson	 */
2371105634Srwatson	if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) {
2372105634Srwatson		/*
2373105634Srwatson		 * To change the Biba label on a vnode, the new vnode label
2374105634Srwatson		 * must be in the subject range.
2375105634Srwatson		 */
2376105634Srwatson		if (!mac_biba_single_in_range(new, subj))
2377105634Srwatson			return (EPERM);
2378101099Srwatson
2379105634Srwatson		/*
2380105634Srwatson		 * To change the Biba label on the vnode to be EQUAL,
2381105634Srwatson		 * the subject must have appropriate privilege.
2382105634Srwatson		 */
2383105634Srwatson		if (mac_biba_contains_equal(new)) {
2384106090Srwatson			error = mac_biba_subject_privileged(subj);
2385105634Srwatson			if (error)
2386105634Srwatson				return (error);
2387105634Srwatson		}
2388105634Srwatson	}
2389105634Srwatson
2390105634Srwatson	return (0);
2391101099Srwatson}
2392101099Srwatson
2393101099Srwatsonstatic int
2394101099Srwatsonmac_biba_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
2395101099Srwatson    struct label *dlabel, struct vnode *vp, struct label *label,
2396101099Srwatson    struct componentname *cnp)
2397101099Srwatson{
2398101099Srwatson	struct mac_biba *subj, *obj;
2399101099Srwatson
2400101099Srwatson	if (!mac_biba_enabled)
2401101099Srwatson		return (0);
2402101099Srwatson
2403122524Srwatson	subj = SLOT(cred->cr_label);
2404101099Srwatson	obj = SLOT(dlabel);
2405101099Srwatson
2406101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2407101099Srwatson		return (EACCES);
2408101099Srwatson
2409101099Srwatson	obj = SLOT(label);
2410101099Srwatson
2411101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2412101099Srwatson		return (EACCES);
2413101099Srwatson
2414101099Srwatson	return (0);
2415101099Srwatson}
2416101099Srwatson
2417101099Srwatsonstatic int
2418101099Srwatsonmac_biba_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
2419101099Srwatson    struct label *dlabel, struct vnode *vp, struct label *label, int samedir,
2420101099Srwatson    struct componentname *cnp)
2421101099Srwatson{
2422101099Srwatson	struct mac_biba *subj, *obj;
2423101099Srwatson
2424101099Srwatson	if (!mac_biba_enabled)
2425101099Srwatson		return (0);
2426101099Srwatson
2427122524Srwatson	subj = SLOT(cred->cr_label);
2428101099Srwatson	obj = SLOT(dlabel);
2429101099Srwatson
2430101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2431101099Srwatson		return (EACCES);
2432101099Srwatson
2433101099Srwatson	if (vp != NULL) {
2434101099Srwatson		obj = SLOT(label);
2435101099Srwatson
2436101099Srwatson		if (!mac_biba_dominate_single(subj, obj))
2437101099Srwatson			return (EACCES);
2438101099Srwatson	}
2439101099Srwatson
2440101099Srwatson	return (0);
2441101099Srwatson}
2442101099Srwatson
2443101099Srwatsonstatic int
2444101099Srwatsonmac_biba_check_vnode_revoke(struct ucred *cred, struct vnode *vp,
2445101099Srwatson    struct label *label)
2446101099Srwatson{
2447101099Srwatson	struct mac_biba *subj, *obj;
2448101099Srwatson
2449101099Srwatson	if (!mac_biba_enabled)
2450101099Srwatson		return (0);
2451101099Srwatson
2452122524Srwatson	subj = SLOT(cred->cr_label);
2453101099Srwatson	obj = SLOT(label);
2454101099Srwatson
2455101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2456101099Srwatson		return (EACCES);
2457101099Srwatson
2458101099Srwatson	return (0);
2459101099Srwatson}
2460101099Srwatson
2461101099Srwatsonstatic int
2462101099Srwatsonmac_biba_check_vnode_setacl(struct ucred *cred, struct vnode *vp,
2463101099Srwatson    struct label *label, acl_type_t type, struct acl *acl)
2464101099Srwatson{
2465101099Srwatson	struct mac_biba *subj, *obj;
2466101099Srwatson
2467101099Srwatson	if (!mac_biba_enabled)
2468101099Srwatson		return (0);
2469101099Srwatson
2470122524Srwatson	subj = SLOT(cred->cr_label);
2471101099Srwatson	obj = SLOT(label);
2472101099Srwatson
2473101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2474101099Srwatson		return (EACCES);
2475101099Srwatson
2476101099Srwatson	return (0);
2477101099Srwatson}
2478101099Srwatson
2479101099Srwatsonstatic int
2480101099Srwatsonmac_biba_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
2481101099Srwatson    struct label *vnodelabel, int attrnamespace, const char *name,
2482101099Srwatson    struct uio *uio)
2483101099Srwatson{
2484101099Srwatson	struct mac_biba *subj, *obj;
2485101099Srwatson
2486101099Srwatson	if (!mac_biba_enabled)
2487101099Srwatson		return (0);
2488101099Srwatson
2489122524Srwatson	subj = SLOT(cred->cr_label);
2490101099Srwatson	obj = SLOT(vnodelabel);
2491101099Srwatson
2492101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2493101099Srwatson		return (EACCES);
2494101099Srwatson
2495101099Srwatson	/* XXX: protect the MAC EA in a special way? */
2496101099Srwatson
2497101099Srwatson	return (0);
2498101099Srwatson}
2499101099Srwatson
2500101099Srwatsonstatic int
2501101099Srwatsonmac_biba_check_vnode_setflags(struct ucred *cred, struct vnode *vp,
2502101099Srwatson    struct label *vnodelabel, u_long flags)
2503101099Srwatson{
2504101099Srwatson	struct mac_biba *subj, *obj;
2505101099Srwatson
2506101099Srwatson	if (!mac_biba_enabled)
2507101099Srwatson		return (0);
2508101099Srwatson
2509122524Srwatson	subj = SLOT(cred->cr_label);
2510101099Srwatson	obj = SLOT(vnodelabel);
2511101099Srwatson
2512101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2513101099Srwatson		return (EACCES);
2514101099Srwatson
2515101099Srwatson	return (0);
2516101099Srwatson}
2517101099Srwatson
2518101099Srwatsonstatic int
2519101099Srwatsonmac_biba_check_vnode_setmode(struct ucred *cred, struct vnode *vp,
2520101099Srwatson    struct label *vnodelabel, mode_t mode)
2521101099Srwatson{
2522101099Srwatson	struct mac_biba *subj, *obj;
2523101099Srwatson
2524101099Srwatson	if (!mac_biba_enabled)
2525101099Srwatson		return (0);
2526101099Srwatson
2527122524Srwatson	subj = SLOT(cred->cr_label);
2528101099Srwatson	obj = SLOT(vnodelabel);
2529101099Srwatson
2530101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2531101099Srwatson		return (EACCES);
2532101099Srwatson
2533101099Srwatson	return (0);
2534101099Srwatson}
2535101099Srwatson
2536101099Srwatsonstatic int
2537101099Srwatsonmac_biba_check_vnode_setowner(struct ucred *cred, struct vnode *vp,
2538101099Srwatson    struct label *vnodelabel, uid_t uid, gid_t gid)
2539101099Srwatson{
2540101099Srwatson	struct mac_biba *subj, *obj;
2541101099Srwatson
2542101099Srwatson	if (!mac_biba_enabled)
2543101099Srwatson		return (0);
2544101099Srwatson
2545122524Srwatson	subj = SLOT(cred->cr_label);
2546101099Srwatson	obj = SLOT(vnodelabel);
2547101099Srwatson
2548101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2549101099Srwatson		return (EACCES);
2550101099Srwatson
2551101099Srwatson	return (0);
2552101099Srwatson}
2553101099Srwatson
2554101099Srwatsonstatic int
2555101099Srwatsonmac_biba_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
2556101099Srwatson    struct label *vnodelabel, struct timespec atime, struct timespec mtime)
2557101099Srwatson{
2558101099Srwatson	struct mac_biba *subj, *obj;
2559101099Srwatson
2560101099Srwatson	if (!mac_biba_enabled)
2561101099Srwatson		return (0);
2562101099Srwatson
2563122524Srwatson	subj = SLOT(cred->cr_label);
2564101099Srwatson	obj = SLOT(vnodelabel);
2565101099Srwatson
2566101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2567101099Srwatson		return (EACCES);
2568101099Srwatson
2569101099Srwatson	return (0);
2570101099Srwatson}
2571101099Srwatson
2572101099Srwatsonstatic int
2573102129Srwatsonmac_biba_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
2574102129Srwatson    struct vnode *vp, struct label *vnodelabel)
2575101099Srwatson{
2576101099Srwatson	struct mac_biba *subj, *obj;
2577101099Srwatson
2578101099Srwatson	if (!mac_biba_enabled)
2579101099Srwatson		return (0);
2580101099Srwatson
2581122524Srwatson	subj = SLOT(active_cred->cr_label);
2582101099Srwatson	obj = SLOT(vnodelabel);
2583101099Srwatson
2584101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
2585101099Srwatson		return (EACCES);
2586101099Srwatson
2587101099Srwatson	return (0);
2588101099Srwatson}
2589101099Srwatson
2590102112Srwatsonstatic int
2591102129Srwatsonmac_biba_check_vnode_write(struct ucred *active_cred,
2592102129Srwatson    struct ucred *file_cred, struct vnode *vp, struct label *label)
2593102112Srwatson{
2594102112Srwatson	struct mac_biba *subj, *obj;
2595102112Srwatson
2596105637Srwatson	if (!mac_biba_enabled || !revocation_enabled)
2597102112Srwatson		return (0);
2598102112Srwatson
2599122524Srwatson	subj = SLOT(active_cred->cr_label);
2600102112Srwatson	obj = SLOT(label);
2601102112Srwatson
2602102112Srwatson	if (!mac_biba_dominate_single(subj, obj))
2603102112Srwatson		return (EACCES);
2604102112Srwatson
2605102112Srwatson	return (0);
2606102112Srwatson}
2607102112Srwatson
2608106217Srwatsonstatic struct mac_policy_ops mac_biba_ops =
2609101099Srwatson{
2610106217Srwatson	.mpo_destroy = mac_biba_destroy,
2611106217Srwatson	.mpo_init = mac_biba_init,
2612106217Srwatson	.mpo_init_bpfdesc_label = mac_biba_init_label,
2613106217Srwatson	.mpo_init_cred_label = mac_biba_init_label,
2614106217Srwatson	.mpo_init_devfsdirent_label = mac_biba_init_label,
2615106217Srwatson	.mpo_init_ifnet_label = mac_biba_init_label,
2616112675Srwatson	.mpo_init_ipq_label = mac_biba_init_label_waitcheck,
2617106217Srwatson	.mpo_init_mbuf_label = mac_biba_init_label_waitcheck,
2618106217Srwatson	.mpo_init_mount_label = mac_biba_init_label,
2619106217Srwatson	.mpo_init_mount_fs_label = mac_biba_init_label,
2620106217Srwatson	.mpo_init_pipe_label = mac_biba_init_label,
2621106217Srwatson	.mpo_init_socket_label = mac_biba_init_label_waitcheck,
2622106217Srwatson	.mpo_init_socket_peer_label = mac_biba_init_label_waitcheck,
2623106217Srwatson	.mpo_init_vnode_label = mac_biba_init_label,
2624106217Srwatson	.mpo_destroy_bpfdesc_label = mac_biba_destroy_label,
2625106217Srwatson	.mpo_destroy_cred_label = mac_biba_destroy_label,
2626106217Srwatson	.mpo_destroy_devfsdirent_label = mac_biba_destroy_label,
2627106217Srwatson	.mpo_destroy_ifnet_label = mac_biba_destroy_label,
2628106217Srwatson	.mpo_destroy_ipq_label = mac_biba_destroy_label,
2629106217Srwatson	.mpo_destroy_mbuf_label = mac_biba_destroy_label,
2630106217Srwatson	.mpo_destroy_mount_label = mac_biba_destroy_label,
2631106217Srwatson	.mpo_destroy_mount_fs_label = mac_biba_destroy_label,
2632106217Srwatson	.mpo_destroy_pipe_label = mac_biba_destroy_label,
2633106217Srwatson	.mpo_destroy_socket_label = mac_biba_destroy_label,
2634106217Srwatson	.mpo_destroy_socket_peer_label = mac_biba_destroy_label,
2635106217Srwatson	.mpo_destroy_vnode_label = mac_biba_destroy_label,
2636115707Srwatson	.mpo_copy_mbuf_label = mac_biba_copy_label,
2637106217Srwatson	.mpo_copy_pipe_label = mac_biba_copy_label,
2638106217Srwatson	.mpo_copy_vnode_label = mac_biba_copy_label,
2639106217Srwatson	.mpo_externalize_cred_label = mac_biba_externalize_label,
2640106217Srwatson	.mpo_externalize_ifnet_label = mac_biba_externalize_label,
2641106217Srwatson	.mpo_externalize_pipe_label = mac_biba_externalize_label,
2642106217Srwatson	.mpo_externalize_socket_label = mac_biba_externalize_label,
2643106217Srwatson	.mpo_externalize_socket_peer_label = mac_biba_externalize_label,
2644106217Srwatson	.mpo_externalize_vnode_label = mac_biba_externalize_label,
2645106217Srwatson	.mpo_internalize_cred_label = mac_biba_internalize_label,
2646106217Srwatson	.mpo_internalize_ifnet_label = mac_biba_internalize_label,
2647106217Srwatson	.mpo_internalize_pipe_label = mac_biba_internalize_label,
2648106217Srwatson	.mpo_internalize_socket_label = mac_biba_internalize_label,
2649106217Srwatson	.mpo_internalize_vnode_label = mac_biba_internalize_label,
2650106217Srwatson	.mpo_create_devfs_device = mac_biba_create_devfs_device,
2651106217Srwatson	.mpo_create_devfs_directory = mac_biba_create_devfs_directory,
2652106217Srwatson	.mpo_create_devfs_symlink = mac_biba_create_devfs_symlink,
2653106217Srwatson	.mpo_create_mount = mac_biba_create_mount,
2654106217Srwatson	.mpo_create_root_mount = mac_biba_create_root_mount,
2655106217Srwatson	.mpo_relabel_vnode = mac_biba_relabel_vnode,
2656106217Srwatson	.mpo_update_devfsdirent = mac_biba_update_devfsdirent,
2657106217Srwatson	.mpo_associate_vnode_devfs = mac_biba_associate_vnode_devfs,
2658106217Srwatson	.mpo_associate_vnode_extattr = mac_biba_associate_vnode_extattr,
2659106217Srwatson	.mpo_associate_vnode_singlelabel = mac_biba_associate_vnode_singlelabel,
2660106217Srwatson	.mpo_create_vnode_extattr = mac_biba_create_vnode_extattr,
2661106217Srwatson	.mpo_setlabel_vnode_extattr = mac_biba_setlabel_vnode_extattr,
2662106217Srwatson	.mpo_create_mbuf_from_socket = mac_biba_create_mbuf_from_socket,
2663106217Srwatson	.mpo_create_pipe = mac_biba_create_pipe,
2664106217Srwatson	.mpo_create_socket = mac_biba_create_socket,
2665106217Srwatson	.mpo_create_socket_from_socket = mac_biba_create_socket_from_socket,
2666106217Srwatson	.mpo_relabel_pipe = mac_biba_relabel_pipe,
2667106217Srwatson	.mpo_relabel_socket = mac_biba_relabel_socket,
2668106217Srwatson	.mpo_set_socket_peer_from_mbuf = mac_biba_set_socket_peer_from_mbuf,
2669106217Srwatson	.mpo_set_socket_peer_from_socket = mac_biba_set_socket_peer_from_socket,
2670106217Srwatson	.mpo_create_bpfdesc = mac_biba_create_bpfdesc,
2671106217Srwatson	.mpo_create_datagram_from_ipq = mac_biba_create_datagram_from_ipq,
2672106217Srwatson	.mpo_create_fragment = mac_biba_create_fragment,
2673106217Srwatson	.mpo_create_ifnet = mac_biba_create_ifnet,
2674106217Srwatson	.mpo_create_ipq = mac_biba_create_ipq,
2675106217Srwatson	.mpo_create_mbuf_from_mbuf = mac_biba_create_mbuf_from_mbuf,
2676106217Srwatson	.mpo_create_mbuf_linklayer = mac_biba_create_mbuf_linklayer,
2677106217Srwatson	.mpo_create_mbuf_from_bpfdesc = mac_biba_create_mbuf_from_bpfdesc,
2678106217Srwatson	.mpo_create_mbuf_from_ifnet = mac_biba_create_mbuf_from_ifnet,
2679106217Srwatson	.mpo_create_mbuf_multicast_encap = mac_biba_create_mbuf_multicast_encap,
2680106217Srwatson	.mpo_create_mbuf_netlayer = mac_biba_create_mbuf_netlayer,
2681106217Srwatson	.mpo_fragment_match = mac_biba_fragment_match,
2682106217Srwatson	.mpo_relabel_ifnet = mac_biba_relabel_ifnet,
2683106217Srwatson	.mpo_update_ipq = mac_biba_update_ipq,
2684106217Srwatson	.mpo_create_cred = mac_biba_create_cred,
2685106217Srwatson	.mpo_create_proc0 = mac_biba_create_proc0,
2686106217Srwatson	.mpo_create_proc1 = mac_biba_create_proc1,
2687106217Srwatson	.mpo_relabel_cred = mac_biba_relabel_cred,
2688106217Srwatson	.mpo_check_bpfdesc_receive = mac_biba_check_bpfdesc_receive,
2689106217Srwatson	.mpo_check_cred_relabel = mac_biba_check_cred_relabel,
2690106217Srwatson	.mpo_check_cred_visible = mac_biba_check_cred_visible,
2691106217Srwatson	.mpo_check_ifnet_relabel = mac_biba_check_ifnet_relabel,
2692106217Srwatson	.mpo_check_ifnet_transmit = mac_biba_check_ifnet_transmit,
2693110354Srwatson	.mpo_check_kld_load = mac_biba_check_kld_load,
2694110354Srwatson	.mpo_check_kld_unload = mac_biba_check_kld_unload,
2695106217Srwatson	.mpo_check_mount_stat = mac_biba_check_mount_stat,
2696106217Srwatson	.mpo_check_pipe_ioctl = mac_biba_check_pipe_ioctl,
2697106217Srwatson	.mpo_check_pipe_poll = mac_biba_check_pipe_poll,
2698106217Srwatson	.mpo_check_pipe_read = mac_biba_check_pipe_read,
2699106217Srwatson	.mpo_check_pipe_relabel = mac_biba_check_pipe_relabel,
2700106217Srwatson	.mpo_check_pipe_stat = mac_biba_check_pipe_stat,
2701106217Srwatson	.mpo_check_pipe_write = mac_biba_check_pipe_write,
2702106217Srwatson	.mpo_check_proc_debug = mac_biba_check_proc_debug,
2703106217Srwatson	.mpo_check_proc_sched = mac_biba_check_proc_sched,
2704106217Srwatson	.mpo_check_proc_signal = mac_biba_check_proc_signal,
2705106217Srwatson	.mpo_check_socket_deliver = mac_biba_check_socket_deliver,
2706106217Srwatson	.mpo_check_socket_relabel = mac_biba_check_socket_relabel,
2707106217Srwatson	.mpo_check_socket_visible = mac_biba_check_socket_visible,
2708112574Srwatson	.mpo_check_sysarch_ioperm = mac_biba_check_sysarch_ioperm,
2709106418Srwatson	.mpo_check_system_acct = mac_biba_check_system_acct,
2710106418Srwatson	.mpo_check_system_settime = mac_biba_check_system_settime,
2711106217Srwatson	.mpo_check_system_swapon = mac_biba_check_system_swapon,
2712112574Srwatson	.mpo_check_system_swapoff = mac_biba_check_system_swapoff,
2713106217Srwatson	.mpo_check_system_sysctl = mac_biba_check_system_sysctl,
2714106217Srwatson	.mpo_check_vnode_access = mac_biba_check_vnode_open,
2715106217Srwatson	.mpo_check_vnode_chdir = mac_biba_check_vnode_chdir,
2716106217Srwatson	.mpo_check_vnode_chroot = mac_biba_check_vnode_chroot,
2717106217Srwatson	.mpo_check_vnode_create = mac_biba_check_vnode_create,
2718106217Srwatson	.mpo_check_vnode_delete = mac_biba_check_vnode_delete,
2719106217Srwatson	.mpo_check_vnode_deleteacl = mac_biba_check_vnode_deleteacl,
2720119202Srwatson	.mpo_check_vnode_deleteextattr = mac_biba_check_vnode_deleteextattr,
2721106217Srwatson	.mpo_check_vnode_exec = mac_biba_check_vnode_exec,
2722106217Srwatson	.mpo_check_vnode_getacl = mac_biba_check_vnode_getacl,
2723106217Srwatson	.mpo_check_vnode_getextattr = mac_biba_check_vnode_getextattr,
2724106217Srwatson	.mpo_check_vnode_link = mac_biba_check_vnode_link,
2725119202Srwatson	.mpo_check_vnode_listextattr = mac_biba_check_vnode_listextattr,
2726106217Srwatson	.mpo_check_vnode_lookup = mac_biba_check_vnode_lookup,
2727106217Srwatson	.mpo_check_vnode_mmap = mac_biba_check_vnode_mmap,
2728106217Srwatson	.mpo_check_vnode_mprotect = mac_biba_check_vnode_mmap,
2729106217Srwatson	.mpo_check_vnode_open = mac_biba_check_vnode_open,
2730106217Srwatson	.mpo_check_vnode_poll = mac_biba_check_vnode_poll,
2731106217Srwatson	.mpo_check_vnode_read = mac_biba_check_vnode_read,
2732106217Srwatson	.mpo_check_vnode_readdir = mac_biba_check_vnode_readdir,
2733106217Srwatson	.mpo_check_vnode_readlink = mac_biba_check_vnode_readlink,
2734106217Srwatson	.mpo_check_vnode_relabel = mac_biba_check_vnode_relabel,
2735106217Srwatson	.mpo_check_vnode_rename_from = mac_biba_check_vnode_rename_from,
2736106217Srwatson	.mpo_check_vnode_rename_to = mac_biba_check_vnode_rename_to,
2737106217Srwatson	.mpo_check_vnode_revoke = mac_biba_check_vnode_revoke,
2738106217Srwatson	.mpo_check_vnode_setacl = mac_biba_check_vnode_setacl,
2739106217Srwatson	.mpo_check_vnode_setextattr = mac_biba_check_vnode_setextattr,
2740106217Srwatson	.mpo_check_vnode_setflags = mac_biba_check_vnode_setflags,
2741106217Srwatson	.mpo_check_vnode_setmode = mac_biba_check_vnode_setmode,
2742106217Srwatson	.mpo_check_vnode_setowner = mac_biba_check_vnode_setowner,
2743106217Srwatson	.mpo_check_vnode_setutimes = mac_biba_check_vnode_setutimes,
2744106217Srwatson	.mpo_check_vnode_stat = mac_biba_check_vnode_stat,
2745106217Srwatson	.mpo_check_vnode_write = mac_biba_check_vnode_write,
2746101099Srwatson};
2747101099Srwatson
2748112717SrwatsonMAC_POLICY_SET(&mac_biba_ops, mac_biba, "TrustedBSD MAC/Biba",
2749113531Srwatson    MPC_LOADTIME_FLAG_NOTLATE | MPC_LOADTIME_FLAG_LABELMBUFS, &mac_biba_slot);
2750