mac_biba.c revision 160243
1101099Srwatson/*-
2126097Srwatson * Copyright (c) 1999-2002 Robert N. M. Watson
3140628Srwatson * Copyright (c) 2001-2005 McAfee, Inc.
4101099Srwatson * All rights reserved.
5101099Srwatson *
6101099Srwatson * This software was developed by Robert Watson for the TrustedBSD Project.
7101099Srwatson *
8140628Srwatson * This software was developed for the FreeBSD Project in part by McAfee
9140628Srwatson * Research, the Security Research Division of McAfee, Inc. under
10140628Srwatson * DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA
11140628Srwatson * 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 160243 2006-07-10 19:13:32Z csjp $
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>
50145076Scsjp#include <sys/mman.h>
51101099Srwatson#include <sys/mount.h>
52101099Srwatson#include <sys/proc.h>
53115497Srwatson#include <sys/sbuf.h>
54101099Srwatson#include <sys/systm.h>
55101099Srwatson#include <sys/sysproto.h>
56101099Srwatson#include <sys/sysent.h>
57105696Srwatson#include <sys/systm.h>
58101099Srwatson#include <sys/vnode.h>
59101099Srwatson#include <sys/file.h>
60101099Srwatson#include <sys/socket.h>
61101099Srwatson#include <sys/socketvar.h>
62101099Srwatson#include <sys/pipe.h>
63150340Sphk#include <sys/sx.h>
64101099Srwatson#include <sys/sysctl.h>
65140628Srwatson#include <sys/msg.h>
66140628Srwatson#include <sys/sem.h>
67140628Srwatson#include <sys/shm.h>
68101099Srwatson
69145855Srwatson#include <posix4/ksem.h>
70145855Srwatson
71101099Srwatson#include <fs/devfs/devfs.h>
72101099Srwatson
73101099Srwatson#include <net/bpfdesc.h>
74101099Srwatson#include <net/if.h>
75101099Srwatson#include <net/if_types.h>
76101099Srwatson#include <net/if_var.h>
77101099Srwatson
78101099Srwatson#include <netinet/in.h>
79122875Srwatson#include <netinet/in_pcb.h>
80101099Srwatson#include <netinet/ip_var.h>
81101099Srwatson
82122879Srwatson#include <vm/uma.h>
83101099Srwatson#include <vm/vm.h>
84101099Srwatson
85101099Srwatson#include <sys/mac_policy.h>
86101099Srwatson
87101099Srwatson#include <security/mac_biba/mac_biba.h>
88101099Srwatson
89101099SrwatsonSYSCTL_DECL(_security_mac);
90101099Srwatson
91101099SrwatsonSYSCTL_NODE(_security_mac, OID_AUTO, biba, CTLFLAG_RW, 0,
92101099Srwatson    "TrustedBSD mac_biba policy controls");
93101099Srwatson
94105988Srwatsonstatic int	mac_biba_label_size = sizeof(struct mac_biba);
95105988SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, label_size, CTLFLAG_RD,
96105988Srwatson    &mac_biba_label_size, 0, "Size of struct mac_biba");
97105988Srwatson
98107731Srwatsonstatic int	mac_biba_enabled = 1;
99101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, enabled, CTLFLAG_RW,
100101099Srwatson    &mac_biba_enabled, 0, "Enforce MAC/Biba policy");
101102980SrwatsonTUNABLE_INT("security.mac.biba.enabled", &mac_biba_enabled);
102101099Srwatson
103101099Srwatsonstatic int	destroyed_not_inited;
104101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, destroyed_not_inited, CTLFLAG_RD,
105101099Srwatson    &destroyed_not_inited, 0, "Count of labels destroyed but not inited");
106101099Srwatson
107101099Srwatsonstatic int	trust_all_interfaces = 0;
108101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, trust_all_interfaces, CTLFLAG_RD,
109101099Srwatson    &trust_all_interfaces, 0, "Consider all interfaces 'trusted' by MAC/Biba");
110101099SrwatsonTUNABLE_INT("security.mac.biba.trust_all_interfaces", &trust_all_interfaces);
111101099Srwatson
112101099Srwatsonstatic char	trusted_interfaces[128];
113101099SrwatsonSYSCTL_STRING(_security_mac_biba, OID_AUTO, trusted_interfaces, CTLFLAG_RD,
114101099Srwatson    trusted_interfaces, 0, "Interfaces considered 'trusted' by MAC/Biba");
115101099SrwatsonTUNABLE_STR("security.mac.biba.trusted_interfaces", trusted_interfaces,
116101099Srwatson    sizeof(trusted_interfaces));
117101099Srwatson
118105643Srwatsonstatic int	max_compartments = MAC_BIBA_MAX_COMPARTMENTS;
119105643SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, max_compartments, CTLFLAG_RD,
120105643Srwatson    &max_compartments, 0, "Maximum supported compartments");
121105643Srwatson
122105606Srwatsonstatic int	ptys_equal = 0;
123105606SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, ptys_equal, CTLFLAG_RW,
124105606Srwatson    &ptys_equal, 0, "Label pty devices as biba/equal on create");
125105606SrwatsonTUNABLE_INT("security.mac.biba.ptys_equal", &ptys_equal);
126105606Srwatson
127153927Scsjpstatic int	interfaces_equal;
128153927ScsjpSYSCTL_INT(_security_mac_biba, OID_AUTO, interfaces_equal, CTLFLAG_RW,
129153927Scsjp    &interfaces_equal, 0, "Label network interfaces as biba/equal on create");
130153927ScsjpTUNABLE_INT("security.mac.biba.interfaces_equal", &interfaces_equal);
131153927Scsjp
132105637Srwatsonstatic int	revocation_enabled = 0;
133101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, revocation_enabled, CTLFLAG_RW,
134105637Srwatson    &revocation_enabled, 0, "Revoke access to objects on relabel");
135105637SrwatsonTUNABLE_INT("security.mac.biba.revocation_enabled", &revocation_enabled);
136101099Srwatson
137101099Srwatsonstatic int	mac_biba_slot;
138101099Srwatson#define	SLOT(l)	((struct mac_biba *)LABEL_TO_SLOT((l), mac_biba_slot).l_ptr)
139132781Skan#define	SLOT_SET(l, val) (LABEL_TO_SLOT((l), mac_biba_slot).l_ptr = (val))
140101099Srwatson
141122879Srwatsonstatic uma_zone_t	zone_biba;
142101099Srwatson
143105643Srwatsonstatic __inline int
144105643Srwatsonbiba_bit_set_empty(u_char *set) {
145105643Srwatson	int i;
146105643Srwatson
147105643Srwatson	for (i = 0; i < MAC_BIBA_MAX_COMPARTMENTS >> 3; i++)
148105643Srwatson		if (set[i] != 0)
149105643Srwatson			return (0);
150105643Srwatson	return (1);
151105643Srwatson}
152105643Srwatson
153101099Srwatsonstatic struct mac_biba *
154104514Srwatsonbiba_alloc(int flag)
155101099Srwatson{
156101099Srwatson
157122879Srwatson	return (uma_zalloc(zone_biba, flag | M_ZERO));
158101099Srwatson}
159101099Srwatson
160101099Srwatsonstatic void
161101099Srwatsonbiba_free(struct mac_biba *mac_biba)
162101099Srwatson{
163101099Srwatson
164101099Srwatson	if (mac_biba != NULL)
165122879Srwatson		uma_zfree(zone_biba, mac_biba);
166101099Srwatson	else
167101099Srwatson		atomic_add_int(&destroyed_not_inited, 1);
168101099Srwatson}
169101099Srwatson
170101099Srwatsonstatic int
171105634Srwatsonbiba_atmostflags(struct mac_biba *mac_biba, int flags)
172105634Srwatson{
173105634Srwatson
174105634Srwatson	if ((mac_biba->mb_flags & flags) != mac_biba->mb_flags)
175105634Srwatson		return (EINVAL);
176105634Srwatson	return (0);
177105634Srwatson}
178105634Srwatson
179105634Srwatsonstatic int
180101099Srwatsonmac_biba_dominate_element(struct mac_biba_element *a,
181101099Srwatson    struct mac_biba_element *b)
182101099Srwatson{
183105643Srwatson	int bit;
184101099Srwatson
185105736Srwatson	switch (a->mbe_type) {
186101099Srwatson	case MAC_BIBA_TYPE_EQUAL:
187101099Srwatson	case MAC_BIBA_TYPE_HIGH:
188101099Srwatson		return (1);
189101099Srwatson
190101099Srwatson	case MAC_BIBA_TYPE_LOW:
191101099Srwatson		switch (b->mbe_type) {
192101099Srwatson		case MAC_BIBA_TYPE_GRADE:
193101099Srwatson		case MAC_BIBA_TYPE_HIGH:
194101099Srwatson			return (0);
195101099Srwatson
196101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
197101099Srwatson		case MAC_BIBA_TYPE_LOW:
198101099Srwatson			return (1);
199101099Srwatson
200101099Srwatson		default:
201101099Srwatson			panic("mac_biba_dominate_element: b->mbe_type invalid");
202101099Srwatson		}
203101099Srwatson
204101099Srwatson	case MAC_BIBA_TYPE_GRADE:
205101099Srwatson		switch (b->mbe_type) {
206101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
207101099Srwatson		case MAC_BIBA_TYPE_LOW:
208101099Srwatson			return (1);
209101099Srwatson
210101099Srwatson		case MAC_BIBA_TYPE_HIGH:
211101099Srwatson			return (0);
212101099Srwatson
213101099Srwatson		case MAC_BIBA_TYPE_GRADE:
214105643Srwatson			for (bit = 1; bit <= MAC_BIBA_MAX_COMPARTMENTS; bit++)
215105643Srwatson				if (!MAC_BIBA_BIT_TEST(bit,
216105643Srwatson				    a->mbe_compartments) &&
217105643Srwatson				    MAC_BIBA_BIT_TEST(bit, b->mbe_compartments))
218105643Srwatson					return (0);
219101099Srwatson			return (a->mbe_grade >= b->mbe_grade);
220101099Srwatson
221101099Srwatson		default:
222101099Srwatson			panic("mac_biba_dominate_element: b->mbe_type invalid");
223101099Srwatson		}
224101099Srwatson
225101099Srwatson	default:
226101099Srwatson		panic("mac_biba_dominate_element: a->mbe_type invalid");
227101099Srwatson	}
228101099Srwatson
229101099Srwatson	return (0);
230101099Srwatson}
231101099Srwatson
232101099Srwatsonstatic int
233105988Srwatsonmac_biba_subject_dominate_high(struct mac_biba *mac_biba)
234105988Srwatson{
235105988Srwatson	struct mac_biba_element *element;
236105988Srwatson
237132232Srwatson	KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
238132232Srwatson	    ("mac_biba_effective_in_range: mac_biba not effective"));
239132232Srwatson	element = &mac_biba->mb_effective;
240105988Srwatson
241105988Srwatson	return (element->mbe_type == MAC_BIBA_TYPE_EQUAL ||
242105988Srwatson	    element->mbe_type == MAC_BIBA_TYPE_HIGH);
243105988Srwatson}
244105988Srwatson
245105988Srwatsonstatic int
246101099Srwatsonmac_biba_range_in_range(struct mac_biba *rangea, struct mac_biba *rangeb)
247101099Srwatson{
248101099Srwatson
249101099Srwatson	return (mac_biba_dominate_element(&rangeb->mb_rangehigh,
250101099Srwatson	    &rangea->mb_rangehigh) &&
251101099Srwatson	    mac_biba_dominate_element(&rangea->mb_rangelow,
252101099Srwatson	    &rangeb->mb_rangelow));
253101099Srwatson}
254101099Srwatson
255101099Srwatsonstatic int
256136774Srwatsonmac_biba_effective_in_range(struct mac_biba *effective,
257136774Srwatson    struct mac_biba *range)
258101099Srwatson{
259101099Srwatson
260132232Srwatson	KASSERT((effective->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
261132232Srwatson	    ("mac_biba_effective_in_range: a not effective"));
262103750Srwatson	KASSERT((range->mb_flags & MAC_BIBA_FLAG_RANGE) != 0,
263132232Srwatson	    ("mac_biba_effective_in_range: b not range"));
264101099Srwatson
265101099Srwatson	return (mac_biba_dominate_element(&range->mb_rangehigh,
266132232Srwatson	    &effective->mb_effective) &&
267132232Srwatson	    mac_biba_dominate_element(&effective->mb_effective,
268101099Srwatson	    &range->mb_rangelow));
269101099Srwatson
270101099Srwatson	return (1);
271101099Srwatson}
272101099Srwatson
273101099Srwatsonstatic int
274132232Srwatsonmac_biba_dominate_effective(struct mac_biba *a, struct mac_biba *b)
275101099Srwatson{
276132232Srwatson	KASSERT((a->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
277132232Srwatson	    ("mac_biba_dominate_effective: a not effective"));
278132232Srwatson	KASSERT((b->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
279132232Srwatson	    ("mac_biba_dominate_effective: b not effective"));
280101099Srwatson
281132232Srwatson	return (mac_biba_dominate_element(&a->mb_effective, &b->mb_effective));
282101099Srwatson}
283101099Srwatson
284101099Srwatsonstatic int
285101099Srwatsonmac_biba_equal_element(struct mac_biba_element *a, struct mac_biba_element *b)
286101099Srwatson{
287101099Srwatson
288101099Srwatson	if (a->mbe_type == MAC_BIBA_TYPE_EQUAL ||
289101099Srwatson	    b->mbe_type == MAC_BIBA_TYPE_EQUAL)
290101099Srwatson		return (1);
291101099Srwatson
292101099Srwatson	return (a->mbe_type == b->mbe_type && a->mbe_grade == b->mbe_grade);
293101099Srwatson}
294101099Srwatson
295101099Srwatsonstatic int
296132232Srwatsonmac_biba_equal_effective(struct mac_biba *a, struct mac_biba *b)
297101099Srwatson{
298101099Srwatson
299132232Srwatson	KASSERT((a->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
300132232Srwatson	    ("mac_biba_equal_effective: a not effective"));
301132232Srwatson	KASSERT((b->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
302132232Srwatson	    ("mac_biba_equal_effective: b not effective"));
303101099Srwatson
304132232Srwatson	return (mac_biba_equal_element(&a->mb_effective, &b->mb_effective));
305101099Srwatson}
306101099Srwatson
307101099Srwatsonstatic int
308105634Srwatsonmac_biba_contains_equal(struct mac_biba *mac_biba)
309105634Srwatson{
310105634Srwatson
311132232Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_EFFECTIVE)
312132232Srwatson		if (mac_biba->mb_effective.mbe_type == MAC_BIBA_TYPE_EQUAL)
313105634Srwatson			return (1);
314105634Srwatson
315105634Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
316105634Srwatson		if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL)
317105634Srwatson			return (1);
318105634Srwatson		if (mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL)
319105637Srwatson			return (1);
320105634Srwatson	}
321105634Srwatson
322105634Srwatson	return (0);
323105634Srwatson}
324105634Srwatson
325105634Srwatsonstatic int
326106090Srwatsonmac_biba_subject_privileged(struct mac_biba *mac_biba)
327105634Srwatson{
328105634Srwatson
329105634Srwatson	KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAGS_BOTH) ==
330105634Srwatson	    MAC_BIBA_FLAGS_BOTH,
331106090Srwatson	    ("mac_biba_subject_privileged: subject doesn't have both labels"));
332105634Srwatson
333132232Srwatson	/* If the effective is EQUAL, it's ok. */
334132232Srwatson	if (mac_biba->mb_effective.mbe_type == MAC_BIBA_TYPE_EQUAL)
335105634Srwatson		return (0);
336105634Srwatson
337105634Srwatson	/* If either range endpoint is EQUAL, it's ok. */
338105634Srwatson	if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL ||
339105634Srwatson	    mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL)
340105634Srwatson		return (0);
341105634Srwatson
342105634Srwatson	/* If the range is low-high, it's ok. */
343105634Srwatson	if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_LOW &&
344105634Srwatson	    mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_HIGH)
345105634Srwatson		return (0);
346105634Srwatson
347105634Srwatson	/* It's not ok. */
348105634Srwatson	return (EPERM);
349105634Srwatson}
350105634Srwatson
351106091Srwatsonstatic int
352132232Srwatsonmac_biba_high_effective(struct mac_biba *mac_biba)
353105988Srwatson{
354105988Srwatson
355132232Srwatson	KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
356132232Srwatson	    ("mac_biba_equal_effective: mac_biba not effective"));
357105988Srwatson
358132232Srwatson	return (mac_biba->mb_effective.mbe_type == MAC_BIBA_TYPE_HIGH);
359105988Srwatson}
360105988Srwatson
361105634Srwatsonstatic int
362101099Srwatsonmac_biba_valid(struct mac_biba *mac_biba)
363101099Srwatson{
364101099Srwatson
365132232Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
366132232Srwatson		switch (mac_biba->mb_effective.mbe_type) {
367101099Srwatson		case MAC_BIBA_TYPE_GRADE:
368101099Srwatson			break;
369101099Srwatson
370101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
371101099Srwatson		case MAC_BIBA_TYPE_HIGH:
372101099Srwatson		case MAC_BIBA_TYPE_LOW:
373132232Srwatson			if (mac_biba->mb_effective.mbe_grade != 0 ||
374105643Srwatson			    !MAC_BIBA_BIT_SET_EMPTY(
375132232Srwatson			    mac_biba->mb_effective.mbe_compartments))
376101099Srwatson				return (EINVAL);
377101099Srwatson			break;
378101099Srwatson
379101099Srwatson		default:
380101099Srwatson			return (EINVAL);
381101099Srwatson		}
382101099Srwatson	} else {
383132232Srwatson		if (mac_biba->mb_effective.mbe_type != MAC_BIBA_TYPE_UNDEF)
384101099Srwatson			return (EINVAL);
385101099Srwatson	}
386101099Srwatson
387101099Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
388101099Srwatson		switch (mac_biba->mb_rangelow.mbe_type) {
389101099Srwatson		case MAC_BIBA_TYPE_GRADE:
390101099Srwatson			break;
391101099Srwatson
392101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
393101099Srwatson		case MAC_BIBA_TYPE_HIGH:
394101099Srwatson		case MAC_BIBA_TYPE_LOW:
395105643Srwatson			if (mac_biba->mb_rangelow.mbe_grade != 0 ||
396105643Srwatson			    !MAC_BIBA_BIT_SET_EMPTY(
397105643Srwatson			    mac_biba->mb_rangelow.mbe_compartments))
398101099Srwatson				return (EINVAL);
399101099Srwatson			break;
400101099Srwatson
401101099Srwatson		default:
402101099Srwatson			return (EINVAL);
403101099Srwatson		}
404101099Srwatson
405101099Srwatson		switch (mac_biba->mb_rangehigh.mbe_type) {
406101099Srwatson		case MAC_BIBA_TYPE_GRADE:
407101099Srwatson			break;
408101099Srwatson
409101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
410101099Srwatson		case MAC_BIBA_TYPE_HIGH:
411101099Srwatson		case MAC_BIBA_TYPE_LOW:
412105643Srwatson			if (mac_biba->mb_rangehigh.mbe_grade != 0 ||
413105643Srwatson			    !MAC_BIBA_BIT_SET_EMPTY(
414105643Srwatson			    mac_biba->mb_rangehigh.mbe_compartments))
415101099Srwatson				return (EINVAL);
416101099Srwatson			break;
417101099Srwatson
418101099Srwatson		default:
419101099Srwatson			return (EINVAL);
420101099Srwatson		}
421101099Srwatson		if (!mac_biba_dominate_element(&mac_biba->mb_rangehigh,
422101099Srwatson		    &mac_biba->mb_rangelow))
423101099Srwatson			return (EINVAL);
424101099Srwatson	} else {
425101099Srwatson		if (mac_biba->mb_rangelow.mbe_type != MAC_BIBA_TYPE_UNDEF ||
426101099Srwatson		    mac_biba->mb_rangehigh.mbe_type != MAC_BIBA_TYPE_UNDEF)
427101099Srwatson			return (EINVAL);
428101099Srwatson	}
429101099Srwatson
430101099Srwatson	return (0);
431101099Srwatson}
432101099Srwatson
433101099Srwatsonstatic void
434101099Srwatsonmac_biba_set_range(struct mac_biba *mac_biba, u_short typelow,
435105643Srwatson    u_short gradelow, u_char *compartmentslow, u_short typehigh,
436105643Srwatson    u_short gradehigh, u_char *compartmentshigh)
437101099Srwatson{
438101099Srwatson
439101099Srwatson	mac_biba->mb_rangelow.mbe_type = typelow;
440101099Srwatson	mac_biba->mb_rangelow.mbe_grade = gradelow;
441105643Srwatson	if (compartmentslow != NULL)
442105643Srwatson		memcpy(mac_biba->mb_rangelow.mbe_compartments,
443105643Srwatson		    compartmentslow,
444105643Srwatson		    sizeof(mac_biba->mb_rangelow.mbe_compartments));
445101099Srwatson	mac_biba->mb_rangehigh.mbe_type = typehigh;
446101099Srwatson	mac_biba->mb_rangehigh.mbe_grade = gradehigh;
447105643Srwatson	if (compartmentshigh != NULL)
448105643Srwatson		memcpy(mac_biba->mb_rangehigh.mbe_compartments,
449105643Srwatson		    compartmentshigh,
450105643Srwatson		    sizeof(mac_biba->mb_rangehigh.mbe_compartments));
451101099Srwatson	mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE;
452101099Srwatson}
453101099Srwatson
454101099Srwatsonstatic void
455132232Srwatsonmac_biba_set_effective(struct mac_biba *mac_biba, u_short type, u_short grade,
456105643Srwatson    u_char *compartments)
457101099Srwatson{
458101099Srwatson
459132232Srwatson	mac_biba->mb_effective.mbe_type = type;
460132232Srwatson	mac_biba->mb_effective.mbe_grade = grade;
461105643Srwatson	if (compartments != NULL)
462132232Srwatson		memcpy(mac_biba->mb_effective.mbe_compartments, compartments,
463132232Srwatson		    sizeof(mac_biba->mb_effective.mbe_compartments));
464132232Srwatson	mac_biba->mb_flags |= MAC_BIBA_FLAG_EFFECTIVE;
465101099Srwatson}
466101099Srwatson
467101099Srwatsonstatic void
468101099Srwatsonmac_biba_copy_range(struct mac_biba *labelfrom, struct mac_biba *labelto)
469101099Srwatson{
470105643Srwatson
471101099Srwatson	KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_RANGE) != 0,
472101099Srwatson	    ("mac_biba_copy_range: labelfrom not range"));
473101099Srwatson
474101099Srwatson	labelto->mb_rangelow = labelfrom->mb_rangelow;
475101099Srwatson	labelto->mb_rangehigh = labelfrom->mb_rangehigh;
476101099Srwatson	labelto->mb_flags |= MAC_BIBA_FLAG_RANGE;
477101099Srwatson}
478101099Srwatson
479101099Srwatsonstatic void
480132232Srwatsonmac_biba_copy_effective(struct mac_biba *labelfrom, struct mac_biba *labelto)
481101099Srwatson{
482101099Srwatson
483132232Srwatson	KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
484132232Srwatson	    ("mac_biba_copy_effective: labelfrom not effective"));
485101099Srwatson
486132232Srwatson	labelto->mb_effective = labelfrom->mb_effective;
487132232Srwatson	labelto->mb_flags |= MAC_BIBA_FLAG_EFFECTIVE;
488101099Srwatson}
489101099Srwatson
490105656Srwatsonstatic void
491105656Srwatsonmac_biba_copy(struct mac_biba *source, struct mac_biba *dest)
492105656Srwatson{
493105656Srwatson
494132232Srwatson	if (source->mb_flags & MAC_BIBA_FLAG_EFFECTIVE)
495132232Srwatson		mac_biba_copy_effective(source, dest);
496105656Srwatson	if (source->mb_flags & MAC_BIBA_FLAG_RANGE)
497105656Srwatson		mac_biba_copy_range(source, dest);
498105656Srwatson}
499105656Srwatson
500101099Srwatson/*
501101099Srwatson * Policy module operations.
502101099Srwatson */
503101099Srwatsonstatic void
504101099Srwatsonmac_biba_init(struct mac_policy_conf *conf)
505101099Srwatson{
506101099Srwatson
507122879Srwatson	zone_biba = uma_zcreate("mac_biba", sizeof(struct mac_biba), NULL,
508122879Srwatson	    NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
509101099Srwatson}
510101099Srwatson
511101099Srwatson/*
512101099Srwatson * Label operations.
513101099Srwatson */
514101099Srwatsonstatic void
515104514Srwatsonmac_biba_init_label(struct label *label)
516101099Srwatson{
517101099Srwatson
518132781Skan	SLOT_SET(label, biba_alloc(M_WAITOK));
519101099Srwatson}
520101099Srwatson
521101099Srwatsonstatic int
522104514Srwatsonmac_biba_init_label_waitcheck(struct label *label, int flag)
523101099Srwatson{
524101099Srwatson
525132781Skan	SLOT_SET(label, biba_alloc(flag));
526101099Srwatson	if (SLOT(label) == NULL)
527101099Srwatson		return (ENOMEM);
528101099Srwatson
529101099Srwatson	return (0);
530101099Srwatson}
531101099Srwatson
532101099Srwatsonstatic void
533104514Srwatsonmac_biba_destroy_label(struct label *label)
534101099Srwatson{
535101099Srwatson
536101099Srwatson	biba_free(SLOT(label));
537132781Skan	SLOT_SET(label, NULL);
538101099Srwatson}
539101099Srwatson
540105696Srwatson/*
541115497Srwatson * mac_biba_element_to_string() accepts an sbuf and Biba element.  It
542115497Srwatson * converts the Biba element to a string and stores the result in the
543115497Srwatson * sbuf; if there isn't space in the sbuf, -1 is returned.
544105696Srwatson */
545115497Srwatsonstatic int
546115497Srwatsonmac_biba_element_to_string(struct sbuf *sb, struct mac_biba_element *element)
547105696Srwatson{
548115497Srwatson	int i, first;
549105696Srwatson
550105696Srwatson	switch (element->mbe_type) {
551105696Srwatson	case MAC_BIBA_TYPE_HIGH:
552115497Srwatson		return (sbuf_printf(sb, "high"));
553105696Srwatson
554105696Srwatson	case MAC_BIBA_TYPE_LOW:
555115497Srwatson		return (sbuf_printf(sb, "low"));
556105696Srwatson
557105696Srwatson	case MAC_BIBA_TYPE_EQUAL:
558115497Srwatson		return (sbuf_printf(sb, "equal"));
559105696Srwatson
560105696Srwatson	case MAC_BIBA_TYPE_GRADE:
561115497Srwatson		if (sbuf_printf(sb, "%d", element->mbe_grade) == -1)
562115497Srwatson			return (-1);
563115497Srwatson
564115497Srwatson		first = 1;
565115497Srwatson		for (i = 1; i <= MAC_BIBA_MAX_COMPARTMENTS; i++) {
566115497Srwatson			if (MAC_BIBA_BIT_TEST(i, element->mbe_compartments)) {
567115497Srwatson				if (first) {
568115497Srwatson					if (sbuf_putc(sb, ':') == -1)
569115497Srwatson						return (-1);
570115497Srwatson					if (sbuf_printf(sb, "%d", i) == -1)
571115497Srwatson						return (-1);
572115497Srwatson					first = 0;
573115497Srwatson				} else {
574115497Srwatson					if (sbuf_printf(sb, "+%d", i) == -1)
575115497Srwatson						return (-1);
576115497Srwatson				}
577115497Srwatson			}
578105696Srwatson		}
579115497Srwatson		return (0);
580105696Srwatson
581105696Srwatson	default:
582105696Srwatson		panic("mac_biba_element_to_string: invalid type (%d)",
583105696Srwatson		    element->mbe_type);
584105696Srwatson	}
585105696Srwatson}
586105696Srwatson
587115497Srwatson/*
588116701Srwatson * mac_biba_to_string() converts a Biba label to a string, and places
589116701Srwatson * the results in the passed sbuf.  It returns 0 on success, or EINVAL
590116701Srwatson * if there isn't room in the sbuf.  Note: the sbuf will be modified
591116701Srwatson * even in a failure case, so the caller may need to revert the sbuf
592116701Srwatson * by restoring the offset if that's undesired.
593115497Srwatson */
594101099Srwatsonstatic int
595116701Srwatsonmac_biba_to_string(struct sbuf *sb, struct mac_biba *mac_biba)
596101099Srwatson{
597105696Srwatson
598132232Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
599132232Srwatson		if (mac_biba_element_to_string(sb, &mac_biba->mb_effective)
600115497Srwatson		    == -1)
601105696Srwatson			return (EINVAL);
602105696Srwatson	}
603105696Srwatson
604105696Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
605116701Srwatson		if (sbuf_putc(sb, '(') == -1)
606105696Srwatson			return (EINVAL);
607105696Srwatson
608116701Srwatson		if (mac_biba_element_to_string(sb, &mac_biba->mb_rangelow)
609115497Srwatson		    == -1)
610105696Srwatson			return (EINVAL);
611105696Srwatson
612116701Srwatson		if (sbuf_putc(sb, '-') == -1)
613105696Srwatson			return (EINVAL);
614105696Srwatson
615116701Srwatson		if (mac_biba_element_to_string(sb, &mac_biba->mb_rangehigh)
616115497Srwatson		    == -1)
617105696Srwatson			return (EINVAL);
618105696Srwatson
619116701Srwatson		if (sbuf_putc(sb, ')') == -1)
620105696Srwatson			return (EINVAL);
621105696Srwatson	}
622105696Srwatson
623105696Srwatson	return (0);
624105696Srwatson}
625105696Srwatson
626105696Srwatsonstatic int
627105696Srwatsonmac_biba_externalize_label(struct label *label, char *element_name,
628116701Srwatson    struct sbuf *sb, int *claimed)
629105696Srwatson{
630101099Srwatson	struct mac_biba *mac_biba;
631101099Srwatson
632105696Srwatson	if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0)
633105696Srwatson		return (0);
634105696Srwatson
635105696Srwatson	(*claimed)++;
636105696Srwatson
637101099Srwatson	mac_biba = SLOT(label);
638116701Srwatson	return (mac_biba_to_string(sb, mac_biba));
639105696Srwatson}
640105696Srwatson
641105696Srwatsonstatic int
642105696Srwatsonmac_biba_parse_element(struct mac_biba_element *element, char *string)
643101099Srwatson{
644115395Srwatson	char *compartment, *end, *grade;
645115395Srwatson	int value;
646105696Srwatson
647105696Srwatson	if (strcmp(string, "high") == 0 ||
648105696Srwatson	    strcmp(string, "hi") == 0) {
649105696Srwatson		element->mbe_type = MAC_BIBA_TYPE_HIGH;
650105696Srwatson		element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
651105696Srwatson	} else if (strcmp(string, "low") == 0 ||
652105696Srwatson	    strcmp(string, "lo") == 0) {
653105696Srwatson		element->mbe_type = MAC_BIBA_TYPE_LOW;
654105696Srwatson		element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
655105696Srwatson	} else if (strcmp(string, "equal") == 0 ||
656105696Srwatson	    strcmp(string, "eq") == 0) {
657105696Srwatson		element->mbe_type = MAC_BIBA_TYPE_EQUAL;
658105696Srwatson		element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
659105696Srwatson	} else {
660115395Srwatson		element->mbe_type = MAC_BIBA_TYPE_GRADE;
661105696Srwatson
662115395Srwatson		/*
663115395Srwatson		 * Numeric grade piece of the element.
664115395Srwatson		 */
665115395Srwatson		grade = strsep(&string, ":");
666115395Srwatson		value = strtol(grade, &end, 10);
667115395Srwatson		if (end == grade || *end != '\0')
668105696Srwatson			return (EINVAL);
669115395Srwatson		if (value < 0 || value > 65535)
670115395Srwatson			return (EINVAL);
671115395Srwatson		element->mbe_grade = value;
672105696Srwatson
673115395Srwatson		/*
674115395Srwatson		 * Optional compartment piece of the element.  If none
675115395Srwatson		 * are included, we assume that the label has no
676115395Srwatson		 * compartments.
677115395Srwatson		 */
678115395Srwatson		if (string == NULL)
679115395Srwatson			return (0);
680115395Srwatson		if (*string == '\0')
681115395Srwatson			return (0);
682105696Srwatson
683115395Srwatson		while ((compartment = strsep(&string, "+")) != NULL) {
684115395Srwatson			value = strtol(compartment, &end, 10);
685115395Srwatson			if (compartment == end || *end != '\0')
686105696Srwatson				return (EINVAL);
687115395Srwatson			if (value < 1 || value > MAC_BIBA_MAX_COMPARTMENTS)
688105696Srwatson				return (EINVAL);
689115395Srwatson			MAC_BIBA_BIT_SET(value, element->mbe_compartments);
690105696Srwatson		}
691105696Srwatson	}
692105696Srwatson
693105696Srwatson	return (0);
694105696Srwatson}
695105696Srwatson
696105696Srwatson/*
697105696Srwatson * Note: destructively consumes the string, make a local copy before
698105696Srwatson * calling if that's a problem.
699105696Srwatson */
700105696Srwatsonstatic int
701105696Srwatsonmac_biba_parse(struct mac_biba *mac_biba, char *string)
702105696Srwatson{
703132232Srwatson	char *rangehigh, *rangelow, *effective;
704101099Srwatson	int error;
705101099Srwatson
706132232Srwatson	effective = strsep(&string, "(");
707132232Srwatson	if (*effective == '\0')
708132232Srwatson		effective = NULL;
709115395Srwatson
710115395Srwatson	if (string != NULL) {
711115395Srwatson		rangelow = strsep(&string, "-");
712115395Srwatson		if (string == NULL)
713105696Srwatson			return (EINVAL);
714115395Srwatson		rangehigh = strsep(&string, ")");
715115395Srwatson		if (string == NULL)
716105696Srwatson			return (EINVAL);
717115395Srwatson		if (*string != '\0')
718105696Srwatson			return (EINVAL);
719115395Srwatson	} else {
720115395Srwatson		rangelow = NULL;
721115395Srwatson		rangehigh = NULL;
722105696Srwatson	}
723115395Srwatson
724105696Srwatson	KASSERT((rangelow != NULL && rangehigh != NULL) ||
725105696Srwatson	    (rangelow == NULL && rangehigh == NULL),
726115395Srwatson	    ("mac_biba_parse: range mismatch"));
727101099Srwatson
728105696Srwatson	bzero(mac_biba, sizeof(*mac_biba));
729132232Srwatson	if (effective != NULL) {
730132232Srwatson		error = mac_biba_parse_element(&mac_biba->mb_effective, effective);
731105696Srwatson		if (error)
732105696Srwatson			return (error);
733132232Srwatson		mac_biba->mb_flags |= MAC_BIBA_FLAG_EFFECTIVE;
734105696Srwatson	}
735105696Srwatson
736105696Srwatson	if (rangelow != NULL) {
737105696Srwatson		error = mac_biba_parse_element(&mac_biba->mb_rangelow,
738105696Srwatson		    rangelow);
739105696Srwatson		if (error)
740105696Srwatson			return (error);
741105696Srwatson		error = mac_biba_parse_element(&mac_biba->mb_rangehigh,
742105696Srwatson		    rangehigh);
743105696Srwatson		if (error)
744105696Srwatson			return (error);
745105696Srwatson		mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE;
746105696Srwatson	}
747105696Srwatson
748101099Srwatson	error = mac_biba_valid(mac_biba);
749101099Srwatson	if (error)
750101099Srwatson		return (error);
751101099Srwatson
752105696Srwatson	return (0);
753105696Srwatson}
754101099Srwatson
755105696Srwatsonstatic int
756105696Srwatsonmac_biba_internalize_label(struct label *label, char *element_name,
757105696Srwatson    char *element_data, int *claimed)
758105696Srwatson{
759105696Srwatson	struct mac_biba *mac_biba, mac_biba_temp;
760105696Srwatson	int error;
761105696Srwatson
762105696Srwatson	if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0)
763105696Srwatson		return (0);
764105696Srwatson
765105696Srwatson	(*claimed)++;
766105696Srwatson
767105696Srwatson	error = mac_biba_parse(&mac_biba_temp, element_data);
768105696Srwatson	if (error)
769105696Srwatson		return (error);
770105696Srwatson
771105696Srwatson	mac_biba = SLOT(label);
772105696Srwatson	*mac_biba = mac_biba_temp;
773105696Srwatson
774101099Srwatson	return (0);
775101099Srwatson}
776101099Srwatson
777105696Srwatsonstatic void
778105696Srwatsonmac_biba_copy_label(struct label *src, struct label *dest)
779105696Srwatson{
780105696Srwatson
781105696Srwatson	*SLOT(dest) = *SLOT(src);
782105696Srwatson}
783105696Srwatson
784101099Srwatson/*
785101099Srwatson * Labeling event operations: file system objects, and things that look
786101099Srwatson * a lot like file system objects.
787101099Srwatson */
788101099Srwatsonstatic void
789147982Srwatsonmac_biba_create_devfs_device(struct ucred *cred, struct mount *mp,
790147982Srwatson    struct cdev *dev, struct devfs_dirent *devfs_dirent, struct label *label)
791101099Srwatson{
792101099Srwatson	struct mac_biba *mac_biba;
793101099Srwatson	int biba_type;
794101099Srwatson
795101099Srwatson	mac_biba = SLOT(label);
796101099Srwatson	if (strcmp(dev->si_name, "null") == 0 ||
797101099Srwatson	    strcmp(dev->si_name, "zero") == 0 ||
798101099Srwatson	    strcmp(dev->si_name, "random") == 0 ||
799101099Srwatson	    strncmp(dev->si_name, "fd/", strlen("fd/")) == 0)
800101099Srwatson		biba_type = MAC_BIBA_TYPE_EQUAL;
801105606Srwatson	else if (ptys_equal &&
802105606Srwatson	    (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 ||
803105606Srwatson	    strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0))
804105606Srwatson		biba_type = MAC_BIBA_TYPE_EQUAL;
805101099Srwatson	else
806101099Srwatson		biba_type = MAC_BIBA_TYPE_HIGH;
807132232Srwatson	mac_biba_set_effective(mac_biba, biba_type, 0, NULL);
808101099Srwatson}
809101099Srwatson
810101099Srwatsonstatic void
811107698Srwatsonmac_biba_create_devfs_directory(struct mount *mp, char *dirname,
812107698Srwatson    int dirnamelen, struct devfs_dirent *devfs_dirent, struct label *label)
813101099Srwatson{
814101099Srwatson	struct mac_biba *mac_biba;
815101099Srwatson
816101099Srwatson	mac_biba = SLOT(label);
817132232Srwatson	mac_biba_set_effective(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
818101099Srwatson}
819101099Srwatson
820101099Srwatsonstatic void
821107698Srwatsonmac_biba_create_devfs_symlink(struct ucred *cred, struct mount *mp,
822107698Srwatson    struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de,
823122563Srwatson    struct label *delabel)
824104535Srwatson{
825104535Srwatson	struct mac_biba *source, *dest;
826104535Srwatson
827122524Srwatson	source = SLOT(cred->cr_label);
828104535Srwatson	dest = SLOT(delabel);
829104535Srwatson
830132232Srwatson	mac_biba_copy_effective(source, dest);
831104535Srwatson}
832104535Srwatson
833104535Srwatsonstatic void
834101099Srwatsonmac_biba_create_mount(struct ucred *cred, struct mount *mp,
835101099Srwatson    struct label *mntlabel, struct label *fslabel)
836101099Srwatson{
837101099Srwatson	struct mac_biba *source, *dest;
838101099Srwatson
839122524Srwatson	source = SLOT(cred->cr_label);
840101099Srwatson	dest = SLOT(mntlabel);
841132232Srwatson	mac_biba_copy_effective(source, dest);
842101099Srwatson	dest = SLOT(fslabel);
843132232Srwatson	mac_biba_copy_effective(source, dest);
844101099Srwatson}
845101099Srwatson
846101099Srwatsonstatic void
847101099Srwatsonmac_biba_relabel_vnode(struct ucred *cred, struct vnode *vp,
848101099Srwatson    struct label *vnodelabel, struct label *label)
849101099Srwatson{
850101099Srwatson	struct mac_biba *source, *dest;
851101099Srwatson
852101099Srwatson	source = SLOT(label);
853101099Srwatson	dest = SLOT(vnodelabel);
854101099Srwatson
855105656Srwatson	mac_biba_copy(source, dest);
856101099Srwatson}
857101099Srwatson
858101099Srwatsonstatic void
859107698Srwatsonmac_biba_update_devfsdirent(struct mount *mp,
860107698Srwatson    struct devfs_dirent *devfs_dirent, struct label *direntlabel,
861107698Srwatson    struct vnode *vp, struct label *vnodelabel)
862101099Srwatson{
863101099Srwatson	struct mac_biba *source, *dest;
864101099Srwatson
865101099Srwatson	source = SLOT(vnodelabel);
866101099Srwatson	dest = SLOT(direntlabel);
867101099Srwatson
868105656Srwatson	mac_biba_copy(source, dest);
869101099Srwatson}
870101099Srwatson
871101099Srwatsonstatic void
872105988Srwatsonmac_biba_associate_vnode_devfs(struct mount *mp, struct label *fslabel,
873105988Srwatson    struct devfs_dirent *de, struct label *delabel, struct vnode *vp,
874105988Srwatson    struct label *vlabel)
875101099Srwatson{
876101099Srwatson	struct mac_biba *source, *dest;
877101099Srwatson
878105988Srwatson	source = SLOT(delabel);
879105988Srwatson	dest = SLOT(vlabel);
880101099Srwatson
881132232Srwatson	mac_biba_copy_effective(source, dest);
882101099Srwatson}
883101099Srwatson
884101099Srwatsonstatic int
885105988Srwatsonmac_biba_associate_vnode_extattr(struct mount *mp, struct label *fslabel,
886105988Srwatson    struct vnode *vp, struct label *vlabel)
887101099Srwatson{
888105988Srwatson	struct mac_biba temp, *source, *dest;
889106354Smux	int buflen, error;
890101099Srwatson
891105988Srwatson	source = SLOT(fslabel);
892105988Srwatson	dest = SLOT(vlabel);
893101099Srwatson
894105988Srwatson	buflen = sizeof(temp);
895105988Srwatson	bzero(&temp, buflen);
896105988Srwatson
897105988Srwatson	error = vn_extattr_get(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
898105988Srwatson	    MAC_BIBA_EXTATTR_NAME, &buflen, (char *) &temp, curthread);
899105988Srwatson	if (error == ENOATTR || error == EOPNOTSUPP) {
900105988Srwatson		/* Fall back to the fslabel. */
901132232Srwatson		mac_biba_copy_effective(source, dest);
902105988Srwatson		return (0);
903105988Srwatson	} else if (error)
904101099Srwatson		return (error);
905101099Srwatson
906105988Srwatson	if (buflen != sizeof(temp)) {
907105988Srwatson		printf("mac_biba_associate_vnode_extattr: bad size %d\n",
908105988Srwatson		    buflen);
909105988Srwatson		return (EPERM);
910105988Srwatson	}
911105988Srwatson	if (mac_biba_valid(&temp) != 0) {
912105988Srwatson		printf("mac_biba_associate_vnode_extattr: invalid\n");
913105988Srwatson		return (EPERM);
914105988Srwatson	}
915132232Srwatson	if ((temp.mb_flags & MAC_BIBA_FLAGS_BOTH) != MAC_BIBA_FLAG_EFFECTIVE) {
916132232Srwatson		printf("mac_biba_associate_vnode_extattr: not effective\n");
917105988Srwatson		return (EPERM);
918105988Srwatson	}
919101099Srwatson
920132232Srwatson	mac_biba_copy_effective(&temp, dest);
921101099Srwatson	return (0);
922101099Srwatson}
923101099Srwatson
924101099Srwatsonstatic void
925105988Srwatsonmac_biba_associate_vnode_singlelabel(struct mount *mp,
926105988Srwatson    struct label *fslabel, struct vnode *vp, struct label *vlabel)
927101099Srwatson{
928101099Srwatson	struct mac_biba *source, *dest;
929101099Srwatson
930101099Srwatson	source = SLOT(fslabel);
931105988Srwatson	dest = SLOT(vlabel);
932101099Srwatson
933132232Srwatson	mac_biba_copy_effective(source, dest);
934101099Srwatson}
935101099Srwatson
936105988Srwatsonstatic int
937105988Srwatsonmac_biba_create_vnode_extattr(struct ucred *cred, struct mount *mp,
938105988Srwatson    struct label *fslabel, struct vnode *dvp, struct label *dlabel,
939105988Srwatson    struct vnode *vp, struct label *vlabel, struct componentname *cnp)
940105988Srwatson{
941105988Srwatson	struct mac_biba *source, *dest, temp;
942105988Srwatson	size_t buflen;
943105988Srwatson	int error;
944105988Srwatson
945105988Srwatson	buflen = sizeof(temp);
946105988Srwatson	bzero(&temp, buflen);
947105988Srwatson
948122524Srwatson	source = SLOT(cred->cr_label);
949105988Srwatson	dest = SLOT(vlabel);
950132232Srwatson	mac_biba_copy_effective(source, &temp);
951105988Srwatson
952105988Srwatson	error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
953105988Srwatson	    MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread);
954105988Srwatson	if (error == 0)
955132232Srwatson		mac_biba_copy_effective(source, dest);
956105988Srwatson	return (error);
957105988Srwatson}
958105988Srwatson
959105988Srwatsonstatic int
960105988Srwatsonmac_biba_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp,
961105988Srwatson    struct label *vlabel, struct label *intlabel)
962105988Srwatson{
963105988Srwatson	struct mac_biba *source, temp;
964105988Srwatson	size_t buflen;
965105988Srwatson	int error;
966105988Srwatson
967105988Srwatson	buflen = sizeof(temp);
968105988Srwatson	bzero(&temp, buflen);
969105988Srwatson
970105988Srwatson	source = SLOT(intlabel);
971132232Srwatson	if ((source->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) == 0)
972105988Srwatson		return (0);
973105988Srwatson
974132232Srwatson	mac_biba_copy_effective(source, &temp);
975105988Srwatson
976105988Srwatson	error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
977105988Srwatson	    MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread);
978105988Srwatson	return (error);
979105988Srwatson}
980105988Srwatson
981101099Srwatson/*
982101099Srwatson * Labeling event operations: IPC object.
983101099Srwatson */
984101099Srwatsonstatic void
985122875Srwatsonmac_biba_create_inpcb_from_socket(struct socket *so, struct label *solabel,
986122875Srwatson    struct inpcb *inp, struct label *inplabel)
987122875Srwatson{
988122875Srwatson	struct mac_biba *source, *dest;
989122875Srwatson
990122875Srwatson	source = SLOT(solabel);
991122875Srwatson	dest = SLOT(inplabel);
992122875Srwatson
993132232Srwatson	mac_biba_copy_effective(source, dest);
994122875Srwatson}
995122875Srwatson
996122875Srwatsonstatic void
997101099Srwatsonmac_biba_create_mbuf_from_socket(struct socket *so, struct label *socketlabel,
998101099Srwatson    struct mbuf *m, struct label *mbuflabel)
999101099Srwatson{
1000101099Srwatson	struct mac_biba *source, *dest;
1001101099Srwatson
1002101099Srwatson	source = SLOT(socketlabel);
1003101099Srwatson	dest = SLOT(mbuflabel);
1004101099Srwatson
1005132232Srwatson	mac_biba_copy_effective(source, dest);
1006101099Srwatson}
1007101099Srwatson
1008101099Srwatsonstatic void
1009101099Srwatsonmac_biba_create_socket(struct ucred *cred, struct socket *socket,
1010101099Srwatson    struct label *socketlabel)
1011101099Srwatson{
1012101099Srwatson	struct mac_biba *source, *dest;
1013101099Srwatson
1014122524Srwatson	source = SLOT(cred->cr_label);
1015101099Srwatson	dest = SLOT(socketlabel);
1016101099Srwatson
1017132232Srwatson	mac_biba_copy_effective(source, dest);
1018101099Srwatson}
1019101099Srwatson
1020101099Srwatsonstatic void
1021125293Srwatsonmac_biba_create_pipe(struct ucred *cred, struct pipepair *pp,
1022101099Srwatson    struct label *pipelabel)
1023101099Srwatson{
1024101099Srwatson	struct mac_biba *source, *dest;
1025101099Srwatson
1026122524Srwatson	source = SLOT(cred->cr_label);
1027101099Srwatson	dest = SLOT(pipelabel);
1028101099Srwatson
1029132232Srwatson	mac_biba_copy_effective(source, dest);
1030101099Srwatson}
1031101099Srwatson
1032101099Srwatsonstatic void
1033145855Srwatsonmac_biba_create_posix_sem(struct ucred *cred, struct ksem *ksemptr,
1034145855Srwatson    struct label *ks_label)
1035145855Srwatson{
1036145855Srwatson	struct mac_biba *source, *dest;
1037145855Srwatson
1038145855Srwatson	source = SLOT(cred->cr_label);
1039145855Srwatson	dest = SLOT(ks_label);
1040145855Srwatson
1041145855Srwatson	mac_biba_copy_effective(source, dest);
1042145855Srwatson}
1043145855Srwatson
1044145855Srwatsonstatic void
1045101099Srwatsonmac_biba_create_socket_from_socket(struct socket *oldsocket,
1046101099Srwatson    struct label *oldsocketlabel, struct socket *newsocket,
1047101099Srwatson    struct label *newsocketlabel)
1048101099Srwatson{
1049101099Srwatson	struct mac_biba *source, *dest;
1050101099Srwatson
1051101099Srwatson	source = SLOT(oldsocketlabel);
1052101099Srwatson	dest = SLOT(newsocketlabel);
1053101099Srwatson
1054132232Srwatson	mac_biba_copy_effective(source, dest);
1055101099Srwatson}
1056101099Srwatson
1057101099Srwatsonstatic void
1058101099Srwatsonmac_biba_relabel_socket(struct ucred *cred, struct socket *socket,
1059101099Srwatson    struct label *socketlabel, struct label *newlabel)
1060101099Srwatson{
1061101099Srwatson	struct mac_biba *source, *dest;
1062101099Srwatson
1063101099Srwatson	source = SLOT(newlabel);
1064101099Srwatson	dest = SLOT(socketlabel);
1065101099Srwatson
1066105656Srwatson	mac_biba_copy(source, dest);
1067101099Srwatson}
1068101099Srwatson
1069101099Srwatsonstatic void
1070125293Srwatsonmac_biba_relabel_pipe(struct ucred *cred, struct pipepair *pp,
1071101099Srwatson    struct label *pipelabel, struct label *newlabel)
1072101099Srwatson{
1073101099Srwatson	struct mac_biba *source, *dest;
1074101099Srwatson
1075101099Srwatson	source = SLOT(newlabel);
1076101099Srwatson	dest = SLOT(pipelabel);
1077101099Srwatson
1078105656Srwatson	mac_biba_copy(source, dest);
1079101099Srwatson}
1080101099Srwatson
1081101099Srwatsonstatic void
1082101099Srwatsonmac_biba_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel,
1083101099Srwatson    struct socket *socket, struct label *socketpeerlabel)
1084101099Srwatson{
1085101099Srwatson	struct mac_biba *source, *dest;
1086101099Srwatson
1087101099Srwatson	source = SLOT(mbuflabel);
1088101099Srwatson	dest = SLOT(socketpeerlabel);
1089101099Srwatson
1090132232Srwatson	mac_biba_copy_effective(source, dest);
1091101099Srwatson}
1092101099Srwatson
1093101099Srwatson/*
1094140628Srwatson * Labeling event operations: System V IPC objects.
1095140628Srwatson */
1096140628Srwatson
1097140628Srwatsonstatic void
1098140628Srwatsonmac_biba_create_sysv_msgmsg(struct ucred *cred, struct msqid_kernel *msqkptr,
1099140628Srwatson    struct label *msqlabel, struct msg *msgptr, struct label *msglabel)
1100140628Srwatson{
1101140628Srwatson	struct mac_biba *source, *dest;
1102140628Srwatson
1103140628Srwatson	/* Ignore the msgq label */
1104140628Srwatson	source = SLOT(cred->cr_label);
1105140628Srwatson	dest = SLOT(msglabel);
1106140628Srwatson
1107140628Srwatson	mac_biba_copy_effective(source, dest);
1108140628Srwatson}
1109140628Srwatson
1110140628Srwatsonstatic void
1111140628Srwatsonmac_biba_create_sysv_msgqueue(struct ucred *cred,
1112140628Srwatson    struct msqid_kernel *msqkptr, struct label *msqlabel)
1113140628Srwatson{
1114140628Srwatson	struct mac_biba *source, *dest;
1115140628Srwatson
1116140628Srwatson	source = SLOT(cred->cr_label);
1117140628Srwatson	dest = SLOT(msqlabel);
1118140628Srwatson
1119140628Srwatson	mac_biba_copy_effective(source, dest);
1120140628Srwatson}
1121140628Srwatson
1122140628Srwatsonstatic void
1123147091Srwatsonmac_biba_create_sysv_sem(struct ucred *cred, struct semid_kernel *semakptr,
1124140628Srwatson    struct label *semalabel)
1125140628Srwatson{
1126140628Srwatson	struct mac_biba *source, *dest;
1127140628Srwatson
1128140628Srwatson	source = SLOT(cred->cr_label);
1129140628Srwatson	dest = SLOT(semalabel);
1130140628Srwatson
1131140628Srwatson	mac_biba_copy_effective(source, dest);
1132140628Srwatson}
1133140628Srwatson
1134140628Srwatsonstatic void
1135140628Srwatsonmac_biba_create_sysv_shm(struct ucred *cred, struct shmid_kernel *shmsegptr,
1136140628Srwatson    struct label *shmlabel)
1137140628Srwatson{
1138140628Srwatson	struct mac_biba *source, *dest;
1139140628Srwatson
1140140628Srwatson	source = SLOT(cred->cr_label);
1141140628Srwatson	dest = SLOT(shmlabel);
1142140628Srwatson
1143140628Srwatson	mac_biba_copy_effective(source, dest);
1144140628Srwatson}
1145140628Srwatson
1146140628Srwatson/*
1147101099Srwatson * Labeling event operations: network objects.
1148101099Srwatson */
1149101099Srwatsonstatic void
1150101099Srwatsonmac_biba_set_socket_peer_from_socket(struct socket *oldsocket,
1151101099Srwatson    struct label *oldsocketlabel, struct socket *newsocket,
1152101099Srwatson    struct label *newsocketpeerlabel)
1153101099Srwatson{
1154101099Srwatson	struct mac_biba *source, *dest;
1155101099Srwatson
1156101099Srwatson	source = SLOT(oldsocketlabel);
1157101099Srwatson	dest = SLOT(newsocketpeerlabel);
1158101099Srwatson
1159132232Srwatson	mac_biba_copy_effective(source, dest);
1160101099Srwatson}
1161101099Srwatson
1162101099Srwatsonstatic void
1163101099Srwatsonmac_biba_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d,
1164101099Srwatson    struct label *bpflabel)
1165101099Srwatson{
1166101099Srwatson	struct mac_biba *source, *dest;
1167101099Srwatson
1168122524Srwatson	source = SLOT(cred->cr_label);
1169101099Srwatson	dest = SLOT(bpflabel);
1170101099Srwatson
1171132232Srwatson	mac_biba_copy_effective(source, dest);
1172101099Srwatson}
1173101099Srwatson
1174101099Srwatsonstatic void
1175101099Srwatsonmac_biba_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel)
1176101099Srwatson{
1177121816Sbrooks	char tifname[IFNAMSIZ], *p, *q;
1178101099Srwatson	char tiflist[sizeof(trusted_interfaces)];
1179101099Srwatson	struct mac_biba *dest;
1180110350Srwatson	int len, type;
1181101099Srwatson
1182101099Srwatson	dest = SLOT(ifnetlabel);
1183101099Srwatson
1184153927Scsjp	if (ifnet->if_type == IFT_LOOP || interfaces_equal != 0) {
1185110350Srwatson		type = MAC_BIBA_TYPE_EQUAL;
1186101099Srwatson		goto set;
1187101099Srwatson	}
1188101099Srwatson
1189101099Srwatson	if (trust_all_interfaces) {
1190110350Srwatson		type = MAC_BIBA_TYPE_HIGH;
1191101099Srwatson		goto set;
1192101099Srwatson	}
1193101099Srwatson
1194110350Srwatson	type = MAC_BIBA_TYPE_LOW;
1195101099Srwatson
1196101099Srwatson	if (trusted_interfaces[0] == '\0' ||
1197101099Srwatson	    !strvalid(trusted_interfaces, sizeof(trusted_interfaces)))
1198101099Srwatson		goto set;
1199101099Srwatson
1200106089Srwatson	bzero(tiflist, sizeof(tiflist));
1201101099Srwatson	for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++)
1202101099Srwatson		if(*p != ' ' && *p != '\t')
1203101099Srwatson			*q = *p;
1204101099Srwatson
1205101099Srwatson	for (p = q = tiflist;; p++) {
1206101099Srwatson		if (*p == ',' || *p == '\0') {
1207101099Srwatson			len = p - q;
1208101099Srwatson			if (len < IFNAMSIZ) {
1209101099Srwatson				bzero(tifname, sizeof(tifname));
1210101099Srwatson				bcopy(q, tifname, len);
1211121816Sbrooks				if (strcmp(tifname, ifnet->if_xname) == 0) {
1212110350Srwatson					type = MAC_BIBA_TYPE_HIGH;
1213101099Srwatson					break;
1214101099Srwatson				}
1215106089Srwatson			} else {
1216106089Srwatson				*p = '\0';
1217106089Srwatson				printf("mac_biba warning: interface name "
1218106089Srwatson				    "\"%s\" is too long (must be < %d)\n",
1219106089Srwatson				    q, IFNAMSIZ);
1220101099Srwatson			}
1221101099Srwatson			if (*p == '\0')
1222101099Srwatson				break;
1223101099Srwatson			q = p + 1;
1224101099Srwatson		}
1225101099Srwatson	}
1226101099Srwatsonset:
1227132232Srwatson	mac_biba_set_effective(dest, type, 0, NULL);
1228110350Srwatson	mac_biba_set_range(dest, type, 0, NULL, type, 0, NULL);
1229101099Srwatson}
1230101099Srwatson
1231101099Srwatsonstatic void
1232101099Srwatsonmac_biba_create_ipq(struct mbuf *fragment, struct label *fragmentlabel,
1233101099Srwatson    struct ipq *ipq, struct label *ipqlabel)
1234101099Srwatson{
1235101099Srwatson	struct mac_biba *source, *dest;
1236101099Srwatson
1237101099Srwatson	source = SLOT(fragmentlabel);
1238101099Srwatson	dest = SLOT(ipqlabel);
1239101099Srwatson
1240132232Srwatson	mac_biba_copy_effective(source, dest);
1241101099Srwatson}
1242101099Srwatson
1243101099Srwatsonstatic void
1244101099Srwatsonmac_biba_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel,
1245101099Srwatson    struct mbuf *datagram, struct label *datagramlabel)
1246101099Srwatson{
1247101099Srwatson	struct mac_biba *source, *dest;
1248101099Srwatson
1249101099Srwatson	source = SLOT(ipqlabel);
1250101099Srwatson	dest = SLOT(datagramlabel);
1251101099Srwatson
1252101099Srwatson	/* Just use the head, since we require them all to match. */
1253132232Srwatson	mac_biba_copy_effective(source, dest);
1254101099Srwatson}
1255101099Srwatson
1256101099Srwatsonstatic void
1257101099Srwatsonmac_biba_create_fragment(struct mbuf *datagram, struct label *datagramlabel,
1258101099Srwatson    struct mbuf *fragment, struct label *fragmentlabel)
1259101099Srwatson{
1260101099Srwatson	struct mac_biba *source, *dest;
1261101099Srwatson
1262101099Srwatson	source = SLOT(datagramlabel);
1263101099Srwatson	dest = SLOT(fragmentlabel);
1264101099Srwatson
1265132232Srwatson	mac_biba_copy_effective(source, dest);
1266101099Srwatson}
1267101099Srwatson
1268101099Srwatsonstatic void
1269123607Srwatsonmac_biba_create_mbuf_from_inpcb(struct inpcb *inp, struct label *inplabel,
1270123607Srwatson    struct mbuf *m, struct label *mlabel)
1271123607Srwatson{
1272123607Srwatson	struct mac_biba *source, *dest;
1273123607Srwatson
1274123607Srwatson	source = SLOT(inplabel);
1275123607Srwatson	dest = SLOT(mlabel);
1276123607Srwatson
1277132232Srwatson	mac_biba_copy_effective(source, dest);
1278123607Srwatson}
1279123607Srwatson
1280123607Srwatsonstatic void
1281101099Srwatsonmac_biba_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel,
1282101099Srwatson    struct mbuf *mbuf, struct label *mbuflabel)
1283101099Srwatson{
1284101099Srwatson	struct mac_biba *dest;
1285101099Srwatson
1286101099Srwatson	dest = SLOT(mbuflabel);
1287101099Srwatson
1288132232Srwatson	mac_biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1289101099Srwatson}
1290101099Srwatson
1291101099Srwatsonstatic void
1292101099Srwatsonmac_biba_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel,
1293101099Srwatson    struct mbuf *mbuf, struct label *mbuflabel)
1294101099Srwatson{
1295101099Srwatson	struct mac_biba *source, *dest;
1296101099Srwatson
1297101099Srwatson	source = SLOT(bpflabel);
1298101099Srwatson	dest = SLOT(mbuflabel);
1299101099Srwatson
1300132232Srwatson	mac_biba_copy_effective(source, dest);
1301101099Srwatson}
1302101099Srwatson
1303101099Srwatsonstatic void
1304101099Srwatsonmac_biba_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel,
1305101099Srwatson    struct mbuf *m, struct label *mbuflabel)
1306101099Srwatson{
1307101099Srwatson	struct mac_biba *source, *dest;
1308101099Srwatson
1309101099Srwatson	source = SLOT(ifnetlabel);
1310101099Srwatson	dest = SLOT(mbuflabel);
1311101099Srwatson
1312132232Srwatson	mac_biba_copy_effective(source, dest);
1313101099Srwatson}
1314101099Srwatson
1315101099Srwatsonstatic void
1316101099Srwatsonmac_biba_create_mbuf_multicast_encap(struct mbuf *oldmbuf,
1317101099Srwatson    struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel,
1318101099Srwatson    struct mbuf *newmbuf, struct label *newmbuflabel)
1319101099Srwatson{
1320101099Srwatson	struct mac_biba *source, *dest;
1321101099Srwatson
1322101099Srwatson	source = SLOT(oldmbuflabel);
1323101099Srwatson	dest = SLOT(newmbuflabel);
1324101099Srwatson
1325132232Srwatson	mac_biba_copy_effective(source, dest);
1326101099Srwatson}
1327101099Srwatson
1328101099Srwatsonstatic void
1329101099Srwatsonmac_biba_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel,
1330101099Srwatson    struct mbuf *newmbuf, struct label *newmbuflabel)
1331101099Srwatson{
1332101099Srwatson	struct mac_biba *source, *dest;
1333101099Srwatson
1334101099Srwatson	source = SLOT(oldmbuflabel);
1335101099Srwatson	dest = SLOT(newmbuflabel);
1336101099Srwatson
1337132232Srwatson	mac_biba_copy_effective(source, dest);
1338101099Srwatson}
1339101099Srwatson
1340101099Srwatsonstatic int
1341101099Srwatsonmac_biba_fragment_match(struct mbuf *fragment, struct label *fragmentlabel,
1342101099Srwatson    struct ipq *ipq, struct label *ipqlabel)
1343101099Srwatson{
1344101099Srwatson	struct mac_biba *a, *b;
1345101099Srwatson
1346101099Srwatson	a = SLOT(ipqlabel);
1347101099Srwatson	b = SLOT(fragmentlabel);
1348101099Srwatson
1349132232Srwatson	return (mac_biba_equal_effective(a, b));
1350101099Srwatson}
1351101099Srwatson
1352101099Srwatsonstatic void
1353101099Srwatsonmac_biba_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet,
1354101099Srwatson    struct label *ifnetlabel, struct label *newlabel)
1355101099Srwatson{
1356101099Srwatson	struct mac_biba *source, *dest;
1357101099Srwatson
1358101099Srwatson	source = SLOT(newlabel);
1359101099Srwatson	dest = SLOT(ifnetlabel);
1360101099Srwatson
1361105656Srwatson	mac_biba_copy(source, dest);
1362101099Srwatson}
1363101099Srwatson
1364101099Srwatsonstatic void
1365101099Srwatsonmac_biba_update_ipq(struct mbuf *fragment, struct label *fragmentlabel,
1366101099Srwatson    struct ipq *ipq, struct label *ipqlabel)
1367101099Srwatson{
1368101099Srwatson
1369101099Srwatson	/* NOOP: we only accept matching labels, so no need to update */
1370101099Srwatson}
1371101099Srwatson
1372122875Srwatsonstatic void
1373122875Srwatsonmac_biba_inpcb_sosetlabel(struct socket *so, struct label *solabel,
1374122875Srwatson    struct inpcb *inp, struct label *inplabel)
1375122875Srwatson{
1376122875Srwatson	struct mac_biba *source, *dest;
1377122875Srwatson
1378122875Srwatson	source = SLOT(solabel);
1379122875Srwatson	dest = SLOT(inplabel);
1380122875Srwatson
1381122875Srwatson	mac_biba_copy(source, dest);
1382122875Srwatson}
1383122875Srwatson
1384101099Srwatson/*
1385101099Srwatson * Labeling event operations: processes.
1386101099Srwatson */
1387101099Srwatsonstatic void
1388101099Srwatsonmac_biba_create_proc0(struct ucred *cred)
1389101099Srwatson{
1390101099Srwatson	struct mac_biba *dest;
1391101099Srwatson
1392122524Srwatson	dest = SLOT(cred->cr_label);
1393101099Srwatson
1394132232Srwatson	mac_biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1395105643Srwatson	mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL,
1396105643Srwatson	    MAC_BIBA_TYPE_HIGH, 0, NULL);
1397101099Srwatson}
1398101099Srwatson
1399101099Srwatsonstatic void
1400101099Srwatsonmac_biba_create_proc1(struct ucred *cred)
1401101099Srwatson{
1402101099Srwatson	struct mac_biba *dest;
1403101099Srwatson
1404122524Srwatson	dest = SLOT(cred->cr_label);
1405101099Srwatson
1406132232Srwatson	mac_biba_set_effective(dest, MAC_BIBA_TYPE_HIGH, 0, NULL);
1407105643Srwatson	mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL,
1408105643Srwatson	    MAC_BIBA_TYPE_HIGH, 0, NULL);
1409101099Srwatson}
1410101099Srwatson
1411101099Srwatsonstatic void
1412101099Srwatsonmac_biba_relabel_cred(struct ucred *cred, struct label *newlabel)
1413101099Srwatson{
1414101099Srwatson	struct mac_biba *source, *dest;
1415101099Srwatson
1416101099Srwatson	source = SLOT(newlabel);
1417122524Srwatson	dest = SLOT(cred->cr_label);
1418101099Srwatson
1419105656Srwatson	mac_biba_copy(source, dest);
1420101099Srwatson}
1421101099Srwatson
1422101099Srwatson/*
1423140628Srwatson * Label cleanup/flush operations
1424140628Srwatson */
1425140628Srwatsonstatic void
1426140628Srwatsonmac_biba_cleanup_sysv_msgmsg(struct label *msglabel)
1427140628Srwatson{
1428140628Srwatson
1429140628Srwatson	bzero(SLOT(msglabel), sizeof(struct mac_biba));
1430140628Srwatson}
1431140628Srwatson
1432140628Srwatsonstatic void
1433140628Srwatsonmac_biba_cleanup_sysv_msgqueue(struct label *msqlabel)
1434140628Srwatson{
1435140628Srwatson
1436140628Srwatson	bzero(SLOT(msqlabel), sizeof(struct mac_biba));
1437140628Srwatson}
1438140628Srwatson
1439140628Srwatsonstatic void
1440147091Srwatsonmac_biba_cleanup_sysv_sem(struct label *semalabel)
1441140628Srwatson{
1442140628Srwatson
1443140628Srwatson	bzero(SLOT(semalabel), sizeof(struct mac_biba));
1444140628Srwatson}
1445140628Srwatson
1446140628Srwatsonstatic void
1447140628Srwatsonmac_biba_cleanup_sysv_shm(struct label *shmlabel)
1448140628Srwatson{
1449140628Srwatson	bzero(SLOT(shmlabel), sizeof(struct mac_biba));
1450140628Srwatson}
1451140628Srwatson
1452140628Srwatson/*
1453101099Srwatson * Access control checks.
1454101099Srwatson */
1455101099Srwatsonstatic int
1456101099Srwatsonmac_biba_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel,
1457101099Srwatson    struct ifnet *ifnet, struct label *ifnetlabel)
1458101099Srwatson{
1459101099Srwatson	struct mac_biba *a, *b;
1460101099Srwatson
1461101099Srwatson	if (!mac_biba_enabled)
1462101099Srwatson		return (0);
1463101099Srwatson
1464101099Srwatson	a = SLOT(bpflabel);
1465101099Srwatson	b = SLOT(ifnetlabel);
1466101099Srwatson
1467132232Srwatson	if (mac_biba_equal_effective(a, b))
1468101099Srwatson		return (0);
1469101099Srwatson	return (EACCES);
1470101099Srwatson}
1471101099Srwatson
1472101099Srwatsonstatic int
1473101099Srwatsonmac_biba_check_cred_relabel(struct ucred *cred, struct label *newlabel)
1474101099Srwatson{
1475101099Srwatson	struct mac_biba *subj, *new;
1476105634Srwatson	int error;
1477101099Srwatson
1478122524Srwatson	subj = SLOT(cred->cr_label);
1479101099Srwatson	new = SLOT(newlabel);
1480101099Srwatson
1481101099Srwatson	/*
1482105634Srwatson	 * If there is a Biba label update for the credential, it may
1483132232Srwatson	 * be an update of the effective, range, or both.
1484101099Srwatson	 */
1485105634Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
1486105634Srwatson	if (error)
1487105634Srwatson		return (error);
1488101099Srwatson
1489101099Srwatson	/*
1490105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
1491101099Srwatson	 */
1492105634Srwatson	if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) {
1493105634Srwatson		/*
1494110351Srwatson		 * If the change request modifies both the Biba label
1495132232Srwatson		 * effective and range, check that the new effective will be
1496110351Srwatson		 * in the new range.
1497110351Srwatson		 */
1498110351Srwatson		if ((new->mb_flags & MAC_BIBA_FLAGS_BOTH) ==
1499110351Srwatson		    MAC_BIBA_FLAGS_BOTH &&
1500132232Srwatson		    !mac_biba_effective_in_range(new, new))
1501110351Srwatson			return (EINVAL);
1502110351Srwatson
1503110351Srwatson		/*
1504132232Srwatson		 * To change the Biba effective label on a credential, the
1505132232Srwatson		 * new effective label must be in the current range.
1506105634Srwatson		 */
1507132232Srwatson		if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE &&
1508132232Srwatson		    !mac_biba_effective_in_range(new, subj))
1509105634Srwatson			return (EPERM);
1510101099Srwatson
1511105634Srwatson		/*
1512105634Srwatson		 * To change the Biba range on a credential, the new
1513105634Srwatson		 * range label must be in the current range.
1514105634Srwatson		 */
1515105634Srwatson		if (new->mb_flags & MAC_BIBA_FLAG_RANGE &&
1516105634Srwatson		    !mac_biba_range_in_range(new, subj))
1517105634Srwatson			return (EPERM);
1518101099Srwatson
1519105634Srwatson		/*
1520105634Srwatson		 * To have EQUAL in any component of the new credential
1521105634Srwatson		 * Biba label, the subject must already have EQUAL in
1522105634Srwatson		 * their label.
1523105634Srwatson		 */
1524105634Srwatson		if (mac_biba_contains_equal(new)) {
1525106090Srwatson			error = mac_biba_subject_privileged(subj);
1526105634Srwatson			if (error)
1527105634Srwatson				return (error);
1528105634Srwatson		}
1529105634Srwatson	}
1530105634Srwatson
1531101099Srwatson	return (0);
1532101099Srwatson}
1533101099Srwatson
1534101099Srwatsonstatic int
1535101099Srwatsonmac_biba_check_cred_visible(struct ucred *u1, struct ucred *u2)
1536101099Srwatson{
1537101099Srwatson	struct mac_biba *subj, *obj;
1538101099Srwatson
1539101099Srwatson	if (!mac_biba_enabled)
1540101099Srwatson		return (0);
1541101099Srwatson
1542122524Srwatson	subj = SLOT(u1->cr_label);
1543122524Srwatson	obj = SLOT(u2->cr_label);
1544101099Srwatson
1545101099Srwatson	/* XXX: range */
1546132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
1547101099Srwatson		return (ESRCH);
1548101099Srwatson
1549101099Srwatson	return (0);
1550101099Srwatson}
1551101099Srwatson
1552101099Srwatsonstatic int
1553101099Srwatsonmac_biba_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet,
1554101099Srwatson    struct label *ifnetlabel, struct label *newlabel)
1555101099Srwatson{
1556101099Srwatson	struct mac_biba *subj, *new;
1557105634Srwatson	int error;
1558101099Srwatson
1559122524Srwatson	subj = SLOT(cred->cr_label);
1560101099Srwatson	new = SLOT(newlabel);
1561101099Srwatson
1562105634Srwatson	/*
1563105634Srwatson	 * If there is a Biba label update for the interface, it may
1564132232Srwatson	 * be an update of the effective, range, or both.
1565105634Srwatson	 */
1566105634Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
1567105634Srwatson	if (error)
1568105634Srwatson		return (error);
1569101099Srwatson
1570105634Srwatson	/*
1571106160Srwatson	 * Relabling network interfaces requires Biba privilege.
1572106160Srwatson	 */
1573106160Srwatson	error = mac_biba_subject_privileged(subj);
1574106160Srwatson	if (error)
1575106160Srwatson		return (error);
1576106160Srwatson
1577105634Srwatson	return (0);
1578101099Srwatson}
1579101099Srwatson
1580103759Srwatsonstatic int
1581101099Srwatsonmac_biba_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel,
1582101099Srwatson    struct mbuf *m, struct label *mbuflabel)
1583101099Srwatson{
1584101099Srwatson	struct mac_biba *p, *i;
1585103761Srwatson
1586101099Srwatson	if (!mac_biba_enabled)
1587101099Srwatson		return (0);
1588101099Srwatson
1589101099Srwatson	p = SLOT(mbuflabel);
1590101099Srwatson	i = SLOT(ifnetlabel);
1591103759Srwatson
1592132232Srwatson	return (mac_biba_effective_in_range(p, i) ? 0 : EACCES);
1593101099Srwatson}
1594101099Srwatson
1595101099Srwatsonstatic int
1596122875Srwatsonmac_biba_check_inpcb_deliver(struct inpcb *inp, struct label *inplabel,
1597122875Srwatson    struct mbuf *m, struct label *mlabel)
1598122875Srwatson{
1599122875Srwatson	struct mac_biba *p, *i;
1600122875Srwatson
1601122875Srwatson	if (!mac_biba_enabled)
1602122875Srwatson		return (0);
1603122875Srwatson
1604122875Srwatson	p = SLOT(mlabel);
1605122875Srwatson	i = SLOT(inplabel);
1606122875Srwatson
1607132232Srwatson	return (mac_biba_equal_effective(p, i) ? 0 : EACCES);
1608122875Srwatson}
1609122875Srwatson
1610122875Srwatsonstatic int
1611140628Srwatsonmac_biba_check_sysv_msgrcv(struct ucred *cred, struct msg *msgptr,
1612140628Srwatson    struct label *msglabel)
1613140628Srwatson{
1614140628Srwatson	struct mac_biba *subj, *obj;
1615140628Srwatson
1616140628Srwatson	if (!mac_biba_enabled)
1617140628Srwatson		return (0);
1618140628Srwatson
1619140628Srwatson	subj = SLOT(cred->cr_label);
1620140628Srwatson	obj = SLOT(msglabel);
1621140628Srwatson
1622140628Srwatson	if (!mac_biba_dominate_effective(obj, subj))
1623140628Srwatson		return (EACCES);
1624140628Srwatson
1625140628Srwatson	return (0);
1626140628Srwatson}
1627140628Srwatson
1628140628Srwatsonstatic int
1629140628Srwatsonmac_biba_check_sysv_msgrmid(struct ucred *cred, struct msg *msgptr,
1630140628Srwatson    struct label *msglabel)
1631140628Srwatson{
1632140628Srwatson	struct mac_biba *subj, *obj;
1633140628Srwatson
1634140628Srwatson	if (!mac_biba_enabled)
1635140628Srwatson		return (0);
1636140628Srwatson
1637140628Srwatson	subj = SLOT(cred->cr_label);
1638140628Srwatson	obj = SLOT(msglabel);
1639140628Srwatson
1640140628Srwatson	if (!mac_biba_dominate_effective(subj, obj))
1641140628Srwatson		return (EACCES);
1642140628Srwatson
1643140628Srwatson	return (0);
1644140628Srwatson}
1645140628Srwatson
1646140628Srwatsonstatic int
1647140628Srwatsonmac_biba_check_sysv_msqget(struct ucred *cred, struct msqid_kernel *msqkptr,
1648140628Srwatson    struct label *msqklabel)
1649140628Srwatson{
1650140628Srwatson	struct mac_biba *subj, *obj;
1651140628Srwatson
1652140628Srwatson	if (!mac_biba_enabled)
1653140628Srwatson		return (0);
1654140628Srwatson
1655140628Srwatson	subj = SLOT(cred->cr_label);
1656140628Srwatson	obj = SLOT(msqklabel);
1657140628Srwatson
1658140628Srwatson	if (!mac_biba_dominate_effective(obj, subj))
1659140628Srwatson		return (EACCES);
1660140628Srwatson
1661140628Srwatson	return (0);
1662140628Srwatson}
1663140628Srwatson
1664140628Srwatsonstatic int
1665140628Srwatsonmac_biba_check_sysv_msqsnd(struct ucred *cred, struct msqid_kernel *msqkptr,
1666140628Srwatson    struct label *msqklabel)
1667140628Srwatson{
1668140628Srwatson	struct mac_biba *subj, *obj;
1669140628Srwatson
1670140628Srwatson	if (!mac_biba_enabled)
1671140628Srwatson		return (0);
1672140628Srwatson
1673140628Srwatson	subj = SLOT(cred->cr_label);
1674140628Srwatson	obj = SLOT(msqklabel);
1675140628Srwatson
1676140628Srwatson	if (!mac_biba_dominate_effective(subj, obj))
1677140628Srwatson		return (EACCES);
1678140628Srwatson
1679140628Srwatson	return (0);
1680140628Srwatson}
1681140628Srwatson
1682140628Srwatsonstatic int
1683140628Srwatsonmac_biba_check_sysv_msqrcv(struct ucred *cred, struct msqid_kernel *msqkptr,
1684140628Srwatson    struct label *msqklabel)
1685140628Srwatson{
1686140628Srwatson	struct mac_biba *subj, *obj;
1687140628Srwatson
1688140628Srwatson	if (!mac_biba_enabled)
1689140628Srwatson		return (0);
1690140628Srwatson
1691140628Srwatson	subj = SLOT(cred->cr_label);
1692140628Srwatson	obj = SLOT(msqklabel);
1693140628Srwatson
1694140628Srwatson	if (!mac_biba_dominate_effective(obj, subj))
1695140628Srwatson		return (EACCES);
1696140628Srwatson
1697140628Srwatson	return (0);
1698140628Srwatson}
1699140628Srwatson
1700140628Srwatson
1701140628Srwatsonstatic int
1702140628Srwatsonmac_biba_check_sysv_msqctl(struct ucred *cred, struct msqid_kernel *msqkptr,
1703140628Srwatson    struct label *msqklabel, int cmd)
1704140628Srwatson{
1705140628Srwatson	struct mac_biba *subj, *obj;
1706140628Srwatson
1707140628Srwatson	if (!mac_biba_enabled)
1708140628Srwatson		return (0);
1709140628Srwatson
1710140628Srwatson	subj = SLOT(cred->cr_label);
1711140628Srwatson	obj = SLOT(msqklabel);
1712140628Srwatson
1713140628Srwatson	switch(cmd) {
1714140628Srwatson	case IPC_RMID:
1715140628Srwatson	case IPC_SET:
1716140628Srwatson		if (!mac_biba_dominate_effective(subj, obj))
1717140628Srwatson			return (EACCES);
1718140628Srwatson		break;
1719140628Srwatson
1720140628Srwatson	case IPC_STAT:
1721140628Srwatson		if (!mac_biba_dominate_effective(obj, subj))
1722140628Srwatson			return (EACCES);
1723140628Srwatson		break;
1724140628Srwatson
1725140628Srwatson	default:
1726140628Srwatson		return (EACCES);
1727140628Srwatson	}
1728140628Srwatson
1729140628Srwatson	return (0);
1730140628Srwatson}
1731140628Srwatson
1732140628Srwatsonstatic int
1733140628Srwatsonmac_biba_check_sysv_semctl(struct ucred *cred, struct semid_kernel *semakptr,
1734140628Srwatson    struct label *semaklabel, int cmd)
1735140628Srwatson{
1736140628Srwatson	struct mac_biba *subj, *obj;
1737140628Srwatson
1738140628Srwatson	if (!mac_biba_enabled)
1739140628Srwatson		return (0);
1740140628Srwatson
1741140628Srwatson	subj = SLOT(cred->cr_label);
1742140628Srwatson	obj = SLOT(semaklabel);
1743140628Srwatson
1744140628Srwatson	switch(cmd) {
1745140628Srwatson	case IPC_RMID:
1746140628Srwatson	case IPC_SET:
1747140628Srwatson	case SETVAL:
1748140628Srwatson	case SETALL:
1749140628Srwatson		if (!mac_biba_dominate_effective(subj, obj))
1750140628Srwatson			return (EACCES);
1751140628Srwatson		break;
1752140628Srwatson
1753140628Srwatson	case IPC_STAT:
1754140628Srwatson	case GETVAL:
1755140628Srwatson	case GETPID:
1756140628Srwatson	case GETNCNT:
1757140628Srwatson	case GETZCNT:
1758140628Srwatson	case GETALL:
1759140628Srwatson		if (!mac_biba_dominate_effective(obj, subj))
1760140628Srwatson			return (EACCES);
1761140628Srwatson		break;
1762140628Srwatson
1763140628Srwatson	default:
1764140628Srwatson		return (EACCES);
1765140628Srwatson	}
1766140628Srwatson
1767140628Srwatson	return (0);
1768140628Srwatson}
1769140628Srwatson
1770140628Srwatson
1771140628Srwatsonstatic int
1772140628Srwatsonmac_biba_check_sysv_semget(struct ucred *cred, struct semid_kernel *semakptr,
1773140628Srwatson    struct label *semaklabel)
1774140628Srwatson{
1775140628Srwatson	struct mac_biba *subj, *obj;
1776140628Srwatson
1777140628Srwatson	if (!mac_biba_enabled)
1778140628Srwatson		return (0);
1779140628Srwatson
1780140628Srwatson	subj = SLOT(cred->cr_label);
1781140628Srwatson	obj = SLOT(semaklabel);
1782140628Srwatson
1783140628Srwatson	if (!mac_biba_dominate_effective(obj, subj))
1784140628Srwatson		return (EACCES);
1785140628Srwatson
1786140628Srwatson	return (0);
1787140628Srwatson}
1788140628Srwatson
1789140628Srwatson
1790140628Srwatsonstatic int
1791140628Srwatsonmac_biba_check_sysv_semop(struct ucred *cred, struct semid_kernel *semakptr,
1792140628Srwatson    struct label *semaklabel, size_t accesstype)
1793140628Srwatson{
1794140628Srwatson	struct mac_biba *subj, *obj;
1795140628Srwatson
1796140628Srwatson	if (!mac_biba_enabled)
1797140628Srwatson		return (0);
1798140628Srwatson
1799140628Srwatson	subj = SLOT(cred->cr_label);
1800140628Srwatson	obj = SLOT(semaklabel);
1801140628Srwatson
1802140628Srwatson	if (accesstype & SEM_R)
1803140628Srwatson		if (!mac_biba_dominate_effective(obj, subj))
1804140628Srwatson			return (EACCES);
1805140628Srwatson
1806140628Srwatson	if (accesstype & SEM_A)
1807140628Srwatson		if (!mac_biba_dominate_effective(subj, obj))
1808140628Srwatson			return (EACCES);
1809140628Srwatson
1810140628Srwatson	return (0);
1811140628Srwatson}
1812140628Srwatson
1813140628Srwatsonstatic int
1814140628Srwatsonmac_biba_check_sysv_shmat(struct ucred *cred, struct shmid_kernel *shmsegptr,
1815140628Srwatson    struct label *shmseglabel, int shmflg)
1816140628Srwatson{
1817140628Srwatson	struct mac_biba *subj, *obj;
1818140628Srwatson
1819140628Srwatson	if (!mac_biba_enabled)
1820140628Srwatson		return (0);
1821140628Srwatson
1822140628Srwatson	subj = SLOT(cred->cr_label);
1823140628Srwatson	obj = SLOT(shmseglabel);
1824140628Srwatson
1825140628Srwatson	if (!mac_biba_dominate_effective(obj, subj))
1826140628Srwatson		return (EACCES);
1827140628Srwatson	if ((shmflg & SHM_RDONLY) == 0) {
1828140628Srwatson		if (!mac_biba_dominate_effective(subj, obj))
1829140628Srwatson			return (EACCES);
1830140628Srwatson	}
1831140628Srwatson
1832140628Srwatson	return (0);
1833140628Srwatson}
1834140628Srwatson
1835140628Srwatsonstatic int
1836140628Srwatsonmac_biba_check_sysv_shmctl(struct ucred *cred, struct shmid_kernel *shmsegptr,
1837140628Srwatson    struct label *shmseglabel, int cmd)
1838140628Srwatson{
1839140628Srwatson	struct mac_biba *subj, *obj;
1840140628Srwatson
1841140628Srwatson	if (!mac_biba_enabled)
1842140628Srwatson		return (0);
1843140628Srwatson
1844140628Srwatson	subj = SLOT(cred->cr_label);
1845140628Srwatson	obj = SLOT(shmseglabel);
1846140628Srwatson
1847140628Srwatson	switch(cmd) {
1848140628Srwatson	case IPC_RMID:
1849140628Srwatson	case IPC_SET:
1850140628Srwatson		if (!mac_biba_dominate_effective(subj, obj))
1851140628Srwatson			return (EACCES);
1852140628Srwatson		break;
1853140628Srwatson
1854140628Srwatson	case IPC_STAT:
1855140628Srwatson	case SHM_STAT:
1856140628Srwatson		if (!mac_biba_dominate_effective(obj, subj))
1857140628Srwatson			return (EACCES);
1858140628Srwatson		break;
1859140628Srwatson
1860140628Srwatson	default:
1861140628Srwatson		return (EACCES);
1862140628Srwatson	}
1863140628Srwatson
1864140628Srwatson	return (0);
1865140628Srwatson}
1866140628Srwatson
1867140628Srwatsonstatic int
1868140628Srwatsonmac_biba_check_sysv_shmget(struct ucred *cred, struct shmid_kernel *shmsegptr,
1869140628Srwatson    struct label *shmseglabel, int shmflg)
1870140628Srwatson{
1871140628Srwatson	struct mac_biba *subj, *obj;
1872140628Srwatson
1873140628Srwatson	if (!mac_biba_enabled)
1874140628Srwatson		return (0);
1875140628Srwatson
1876140628Srwatson	subj = SLOT(cred->cr_label);
1877140628Srwatson	obj = SLOT(shmseglabel);
1878140628Srwatson
1879140628Srwatson	if (!mac_biba_dominate_effective(obj, subj))
1880140628Srwatson		return (EACCES);
1881140628Srwatson
1882140628Srwatson	return (0);
1883140628Srwatson}
1884140628Srwatson
1885140628Srwatsonstatic int
1886110354Srwatsonmac_biba_check_kld_load(struct ucred *cred, struct vnode *vp,
1887110354Srwatson    struct label *label)
1888110354Srwatson{
1889110354Srwatson	struct mac_biba *subj, *obj;
1890110354Srwatson	int error;
1891110354Srwatson
1892110354Srwatson	if (!mac_biba_enabled)
1893110354Srwatson		return (0);
1894110354Srwatson
1895122524Srwatson	subj = SLOT(cred->cr_label);
1896110354Srwatson
1897110354Srwatson	error = mac_biba_subject_privileged(subj);
1898110354Srwatson	if (error)
1899110354Srwatson		return (error);
1900110354Srwatson
1901110354Srwatson	obj = SLOT(label);
1902132232Srwatson	if (!mac_biba_high_effective(obj))
1903110354Srwatson		return (EACCES);
1904110354Srwatson
1905110354Srwatson	return (0);
1906110354Srwatson}
1907110354Srwatson
1908110354Srwatson
1909110354Srwatsonstatic int
1910110354Srwatsonmac_biba_check_kld_unload(struct ucred *cred)
1911110354Srwatson{
1912110354Srwatson	struct mac_biba *subj;
1913110354Srwatson
1914110354Srwatson	if (!mac_biba_enabled)
1915110354Srwatson		return (0);
1916110354Srwatson
1917122524Srwatson	subj = SLOT(cred->cr_label);
1918110354Srwatson
1919110354Srwatson	return (mac_biba_subject_privileged(subj));
1920110354Srwatson}
1921110354Srwatson
1922110354Srwatsonstatic int
1923101099Srwatsonmac_biba_check_mount_stat(struct ucred *cred, struct mount *mp,
1924101099Srwatson    struct label *mntlabel)
1925101099Srwatson{
1926101099Srwatson	struct mac_biba *subj, *obj;
1927101099Srwatson
1928101099Srwatson	if (!mac_biba_enabled)
1929101099Srwatson		return (0);
1930101099Srwatson
1931122524Srwatson	subj = SLOT(cred->cr_label);
1932101099Srwatson	obj = SLOT(mntlabel);
1933101099Srwatson
1934132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
1935101099Srwatson		return (EACCES);
1936101099Srwatson
1937101099Srwatson	return (0);
1938101099Srwatson}
1939101099Srwatson
1940101099Srwatsonstatic int
1941125293Srwatsonmac_biba_check_pipe_ioctl(struct ucred *cred, struct pipepair *pp,
1942101099Srwatson    struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data)
1943101099Srwatson{
1944103759Srwatson
1945101099Srwatson	if(!mac_biba_enabled)
1946101099Srwatson		return (0);
1947101099Srwatson
1948101099Srwatson	/* XXX: This will be implemented soon... */
1949101099Srwatson
1950101099Srwatson	return (0);
1951101099Srwatson}
1952101099Srwatson
1953101099Srwatsonstatic int
1954125293Srwatsonmac_biba_check_pipe_poll(struct ucred *cred, struct pipepair *pp,
1955102115Srwatson    struct label *pipelabel)
1956101099Srwatson{
1957101099Srwatson	struct mac_biba *subj, *obj;
1958101099Srwatson
1959101099Srwatson	if (!mac_biba_enabled)
1960101099Srwatson		return (0);
1961101099Srwatson
1962122524Srwatson	subj = SLOT(cred->cr_label);
1963101099Srwatson	obj = SLOT((pipelabel));
1964101099Srwatson
1965132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
1966102115Srwatson		return (EACCES);
1967101099Srwatson
1968101099Srwatson	return (0);
1969101099Srwatson}
1970101099Srwatson
1971101099Srwatsonstatic int
1972125293Srwatsonmac_biba_check_pipe_read(struct ucred *cred, struct pipepair *pp,
1973102115Srwatson    struct label *pipelabel)
1974102115Srwatson{
1975102115Srwatson	struct mac_biba *subj, *obj;
1976102115Srwatson
1977102115Srwatson	if (!mac_biba_enabled)
1978102115Srwatson		return (0);
1979102115Srwatson
1980122524Srwatson	subj = SLOT(cred->cr_label);
1981102115Srwatson	obj = SLOT((pipelabel));
1982102115Srwatson
1983132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
1984102115Srwatson		return (EACCES);
1985102115Srwatson
1986102115Srwatson	return (0);
1987102115Srwatson}
1988102115Srwatson
1989102115Srwatsonstatic int
1990125293Srwatsonmac_biba_check_pipe_relabel(struct ucred *cred, struct pipepair *pp,
1991101099Srwatson    struct label *pipelabel, struct label *newlabel)
1992101099Srwatson{
1993101099Srwatson	struct mac_biba *subj, *obj, *new;
1994105634Srwatson	int error;
1995101099Srwatson
1996101099Srwatson	new = SLOT(newlabel);
1997122524Srwatson	subj = SLOT(cred->cr_label);
1998101099Srwatson	obj = SLOT(pipelabel);
1999101099Srwatson
2000101099Srwatson	/*
2001105634Srwatson	 * If there is a Biba label update for a pipe, it must be a
2002132232Srwatson	 * effective update.
2003101099Srwatson	 */
2004132232Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE);
2005105634Srwatson	if (error)
2006105634Srwatson		return (error);
2007101099Srwatson
2008101099Srwatson	/*
2009105634Srwatson	 * To perform a relabel of a pipe (Biba label or not), Biba must
2010105634Srwatson	 * authorize the relabel.
2011101099Srwatson	 */
2012132232Srwatson	if (!mac_biba_effective_in_range(obj, subj))
2013101099Srwatson		return (EPERM);
2014101099Srwatson
2015101099Srwatson	/*
2016105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
2017101099Srwatson	 */
2018132232Srwatson	if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
2019105634Srwatson		/*
2020105634Srwatson		 * To change the Biba label on a pipe, the new pipe label
2021105634Srwatson		 * must be in the subject range.
2022105634Srwatson		 */
2023132232Srwatson		if (!mac_biba_effective_in_range(new, subj))
2024105634Srwatson			return (EPERM);
2025101099Srwatson
2026105634Srwatson		/*
2027105634Srwatson		 * To change the Biba label on a pipe to be EQUAL, the
2028105634Srwatson		 * subject must have appropriate privilege.
2029105634Srwatson		 */
2030105634Srwatson		if (mac_biba_contains_equal(new)) {
2031106090Srwatson			error = mac_biba_subject_privileged(subj);
2032105634Srwatson			if (error)
2033105634Srwatson				return (error);
2034105634Srwatson		}
2035105634Srwatson	}
2036105634Srwatson
2037101099Srwatson	return (0);
2038101099Srwatson}
2039101099Srwatson
2040101099Srwatsonstatic int
2041125293Srwatsonmac_biba_check_pipe_stat(struct ucred *cred, struct pipepair *pp,
2042102115Srwatson    struct label *pipelabel)
2043102115Srwatson{
2044102115Srwatson	struct mac_biba *subj, *obj;
2045102115Srwatson
2046102115Srwatson	if (!mac_biba_enabled)
2047102115Srwatson		return (0);
2048102115Srwatson
2049122524Srwatson	subj = SLOT(cred->cr_label);
2050102115Srwatson	obj = SLOT((pipelabel));
2051102115Srwatson
2052132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2053102115Srwatson		return (EACCES);
2054102115Srwatson
2055102115Srwatson	return (0);
2056102115Srwatson}
2057102115Srwatson
2058102115Srwatsonstatic int
2059125293Srwatsonmac_biba_check_pipe_write(struct ucred *cred, struct pipepair *pp,
2060102115Srwatson    struct label *pipelabel)
2061102115Srwatson{
2062102115Srwatson	struct mac_biba *subj, *obj;
2063102115Srwatson
2064102115Srwatson	if (!mac_biba_enabled)
2065102115Srwatson		return (0);
2066102115Srwatson
2067122524Srwatson	subj = SLOT(cred->cr_label);
2068102115Srwatson	obj = SLOT((pipelabel));
2069102115Srwatson
2070132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2071102115Srwatson		return (EACCES);
2072102115Srwatson
2073102115Srwatson	return (0);
2074102115Srwatson}
2075102115Srwatson
2076102115Srwatsonstatic int
2077145855Srwatsonmac_biba_check_posix_sem_write(struct ucred *cred, struct ksem *ksemptr,
2078145855Srwatson    struct label *ks_label)
2079145855Srwatson{
2080145855Srwatson	struct mac_biba *subj, *obj;
2081145855Srwatson
2082145855Srwatson	if (!mac_biba_enabled)
2083145855Srwatson		return (0);
2084145855Srwatson
2085145855Srwatson	subj = SLOT(cred->cr_label);
2086145855Srwatson	obj = SLOT(ks_label);
2087145855Srwatson
2088145855Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2089145855Srwatson		return (EACCES);
2090145855Srwatson
2091145855Srwatson	return (0);
2092145855Srwatson}
2093145855Srwatson
2094145855Srwatsonstatic int
2095145855Srwatsonmac_biba_check_posix_sem_rdonly(struct ucred *cred, struct ksem *ksemptr,
2096145855Srwatson    struct label *ks_label)
2097145855Srwatson{
2098145855Srwatson	struct mac_biba *subj, *obj;
2099145855Srwatson
2100145855Srwatson	if (!mac_biba_enabled)
2101145855Srwatson		return (0);
2102145855Srwatson
2103145855Srwatson	subj = SLOT(cred->cr_label);
2104145855Srwatson	obj = SLOT(ks_label);
2105145855Srwatson
2106145855Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2107145855Srwatson		return (EACCES);
2108145855Srwatson
2109145855Srwatson	return (0);
2110145855Srwatson}
2111145855Srwatson
2112145855Srwatsonstatic int
2113101099Srwatsonmac_biba_check_proc_debug(struct ucred *cred, struct proc *proc)
2114101099Srwatson{
2115101099Srwatson	struct mac_biba *subj, *obj;
2116101099Srwatson
2117101099Srwatson	if (!mac_biba_enabled)
2118101099Srwatson		return (0);
2119101099Srwatson
2120122524Srwatson	subj = SLOT(cred->cr_label);
2121122524Srwatson	obj = SLOT(proc->p_ucred->cr_label);
2122101099Srwatson
2123101099Srwatson	/* XXX: range checks */
2124132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2125101099Srwatson		return (ESRCH);
2126132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2127101099Srwatson		return (EACCES);
2128101099Srwatson
2129101099Srwatson	return (0);
2130101099Srwatson}
2131101099Srwatson
2132101099Srwatsonstatic int
2133101099Srwatsonmac_biba_check_proc_sched(struct ucred *cred, struct proc *proc)
2134101099Srwatson{
2135101099Srwatson	struct mac_biba *subj, *obj;
2136103759Srwatson
2137101099Srwatson	if (!mac_biba_enabled)
2138101099Srwatson		return (0);
2139101099Srwatson
2140122524Srwatson	subj = SLOT(cred->cr_label);
2141122524Srwatson	obj = SLOT(proc->p_ucred->cr_label);
2142103759Srwatson
2143101099Srwatson	/* XXX: range checks */
2144132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2145101099Srwatson		return (ESRCH);
2146132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2147101099Srwatson		return (EACCES);
2148101099Srwatson
2149101099Srwatson	return (0);
2150101099Srwatson}
2151101099Srwatson
2152101099Srwatsonstatic int
2153101099Srwatsonmac_biba_check_proc_signal(struct ucred *cred, struct proc *proc, int signum)
2154101099Srwatson{
2155101099Srwatson	struct mac_biba *subj, *obj;
2156103759Srwatson
2157101099Srwatson	if (!mac_biba_enabled)
2158101099Srwatson		return (0);
2159101099Srwatson
2160122524Srwatson	subj = SLOT(cred->cr_label);
2161122524Srwatson	obj = SLOT(proc->p_ucred->cr_label);
2162103759Srwatson
2163101099Srwatson	/* XXX: range checks */
2164132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2165101099Srwatson		return (ESRCH);
2166132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2167101099Srwatson		return (EACCES);
2168101099Srwatson
2169101099Srwatson	return (0);
2170101099Srwatson}
2171101099Srwatson
2172101099Srwatsonstatic int
2173101934Srwatsonmac_biba_check_socket_deliver(struct socket *so, struct label *socketlabel,
2174101099Srwatson    struct mbuf *m, struct label *mbuflabel)
2175101099Srwatson{
2176101099Srwatson	struct mac_biba *p, *s;
2177101099Srwatson
2178101099Srwatson	if (!mac_biba_enabled)
2179101099Srwatson		return (0);
2180101099Srwatson
2181101099Srwatson	p = SLOT(mbuflabel);
2182101099Srwatson	s = SLOT(socketlabel);
2183101099Srwatson
2184132232Srwatson	return (mac_biba_equal_effective(p, s) ? 0 : EACCES);
2185101099Srwatson}
2186101099Srwatson
2187101099Srwatsonstatic int
2188106214Srwatsonmac_biba_check_socket_relabel(struct ucred *cred, struct socket *so,
2189101099Srwatson    struct label *socketlabel, struct label *newlabel)
2190101099Srwatson{
2191101099Srwatson	struct mac_biba *subj, *obj, *new;
2192105634Srwatson	int error;
2193101099Srwatson
2194101099Srwatson	new = SLOT(newlabel);
2195122524Srwatson	subj = SLOT(cred->cr_label);
2196101099Srwatson	obj = SLOT(socketlabel);
2197101099Srwatson
2198101099Srwatson	/*
2199105634Srwatson	 * If there is a Biba label update for the socket, it may be
2200132232Srwatson	 * an update of effective.
2201101099Srwatson	 */
2202132232Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE);
2203105634Srwatson	if (error)
2204105634Srwatson		return (error);
2205101099Srwatson
2206101099Srwatson	/*
2207132232Srwatson	 * To relabel a socket, the old socket effective must be in the subject
2208101099Srwatson	 * range.
2209101099Srwatson	 */
2210132232Srwatson	if (!mac_biba_effective_in_range(obj, subj))
2211101099Srwatson		return (EPERM);
2212101099Srwatson
2213101099Srwatson	/*
2214105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
2215101099Srwatson	 */
2216132232Srwatson	if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
2217105634Srwatson		/*
2218132232Srwatson		 * To relabel a socket, the new socket effective must be in
2219105634Srwatson		 * the subject range.
2220105634Srwatson		 */
2221132232Srwatson		if (!mac_biba_effective_in_range(new, subj))
2222105634Srwatson			return (EPERM);
2223101099Srwatson
2224105634Srwatson		/*
2225105634Srwatson		 * To change the Biba label on the socket to contain EQUAL,
2226105634Srwatson		 * the subject must have appropriate privilege.
2227105634Srwatson		 */
2228105634Srwatson		if (mac_biba_contains_equal(new)) {
2229106090Srwatson			error = mac_biba_subject_privileged(subj);
2230105634Srwatson			if (error)
2231105634Srwatson				return (error);
2232105634Srwatson		}
2233105634Srwatson	}
2234105634Srwatson
2235101099Srwatson	return (0);
2236101099Srwatson}
2237101099Srwatson
2238101099Srwatsonstatic int
2239101099Srwatsonmac_biba_check_socket_visible(struct ucred *cred, struct socket *socket,
2240101099Srwatson    struct label *socketlabel)
2241101099Srwatson{
2242101099Srwatson	struct mac_biba *subj, *obj;
2243101099Srwatson
2244105722Srwatson	if (!mac_biba_enabled)
2245105722Srwatson		return (0);
2246105722Srwatson
2247122524Srwatson	subj = SLOT(cred->cr_label);
2248101099Srwatson	obj = SLOT(socketlabel);
2249101099Srwatson
2250132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2251101099Srwatson		return (ENOENT);
2252101099Srwatson
2253101099Srwatson	return (0);
2254101099Srwatson}
2255101099Srwatson
2256101099Srwatsonstatic int
2257112574Srwatsonmac_biba_check_sysarch_ioperm(struct ucred *cred)
2258112574Srwatson{
2259112574Srwatson	struct mac_biba *subj;
2260112574Srwatson	int error;
2261112574Srwatson
2262112574Srwatson	if (!mac_biba_enabled)
2263112574Srwatson		return (0);
2264112574Srwatson
2265122524Srwatson	subj = SLOT(cred->cr_label);
2266112574Srwatson
2267112574Srwatson	error = mac_biba_subject_privileged(subj);
2268112574Srwatson	if (error)
2269112574Srwatson		return (error);
2270112574Srwatson
2271112574Srwatson	return (0);
2272112574Srwatson}
2273112574Srwatson
2274112574Srwatsonstatic int
2275106418Srwatsonmac_biba_check_system_acct(struct ucred *cred, struct vnode *vp,
2276106418Srwatson    struct label *label)
2277106418Srwatson{
2278106418Srwatson	struct mac_biba *subj, *obj;
2279106418Srwatson	int error;
2280106418Srwatson
2281106418Srwatson	if (!mac_biba_enabled)
2282106418Srwatson		return (0);
2283106418Srwatson
2284122524Srwatson	subj = SLOT(cred->cr_label);
2285106418Srwatson
2286106418Srwatson	error = mac_biba_subject_privileged(subj);
2287106418Srwatson	if (error)
2288106418Srwatson		return (error);
2289106418Srwatson
2290106418Srwatson	if (label == NULL)
2291106418Srwatson		return (0);
2292106418Srwatson
2293106418Srwatson	obj = SLOT(label);
2294132232Srwatson	if (!mac_biba_high_effective(obj))
2295106418Srwatson		return (EACCES);
2296106418Srwatson
2297106418Srwatson	return (0);
2298106418Srwatson}
2299106418Srwatson
2300106418Srwatsonstatic int
2301106418Srwatsonmac_biba_check_system_settime(struct ucred *cred)
2302106418Srwatson{
2303106418Srwatson	struct mac_biba *subj;
2304106418Srwatson	int error;
2305106418Srwatson
2306106418Srwatson	if (!mac_biba_enabled)
2307106418Srwatson		return (0);
2308106418Srwatson
2309122524Srwatson	subj = SLOT(cred->cr_label);
2310106418Srwatson
2311106418Srwatson	error = mac_biba_subject_privileged(subj);
2312106418Srwatson	if (error)
2313106418Srwatson		return (error);
2314106418Srwatson
2315106418Srwatson	return (0);
2316106418Srwatson}
2317106418Srwatson
2318106418Srwatsonstatic int
2319106161Srwatsonmac_biba_check_system_swapon(struct ucred *cred, struct vnode *vp,
2320106161Srwatson    struct label *label)
2321106161Srwatson{
2322106161Srwatson	struct mac_biba *subj, *obj;
2323106416Srwatson	int error;
2324106161Srwatson
2325106161Srwatson	if (!mac_biba_enabled)
2326106161Srwatson		return (0);
2327106161Srwatson
2328122524Srwatson	subj = SLOT(cred->cr_label);
2329106161Srwatson	obj = SLOT(label);
2330106161Srwatson
2331106416Srwatson	error = mac_biba_subject_privileged(subj);
2332106416Srwatson	if (error)
2333106416Srwatson		return (error);
2334106161Srwatson
2335132232Srwatson	if (!mac_biba_high_effective(obj))
2336106161Srwatson		return (EACCES);
2337106161Srwatson
2338106161Srwatson	return (0);
2339106161Srwatson}
2340106161Srwatson
2341106161Srwatsonstatic int
2342112574Srwatsonmac_biba_check_system_swapoff(struct ucred *cred, struct vnode *vp,
2343112574Srwatson    struct label *label)
2344112574Srwatson{
2345112574Srwatson	struct mac_biba *subj, *obj;
2346112574Srwatson	int error;
2347112574Srwatson
2348112574Srwatson	if (!mac_biba_enabled)
2349112574Srwatson		return (0);
2350112574Srwatson
2351122524Srwatson	subj = SLOT(cred->cr_label);
2352112574Srwatson	obj = SLOT(label);
2353112574Srwatson
2354112574Srwatson	error = mac_biba_subject_privileged(subj);
2355112574Srwatson	if (error)
2356112574Srwatson		return (error);
2357112574Srwatson
2358112574Srwatson	return (0);
2359112574Srwatson}
2360112574Srwatson
2361112574Srwatsonstatic int
2362126121Spjdmac_biba_check_system_sysctl(struct ucred *cred, struct sysctl_oid *oidp,
2363126121Spjd    void *arg1, int arg2, struct sysctl_req *req)
2364106161Srwatson{
2365106161Srwatson	struct mac_biba *subj;
2366106161Srwatson	int error;
2367106161Srwatson
2368106161Srwatson	if (!mac_biba_enabled)
2369106161Srwatson		return (0);
2370106161Srwatson
2371122524Srwatson	subj = SLOT(cred->cr_label);
2372106161Srwatson
2373106161Srwatson	/*
2374126121Spjd	 * Treat sysctl variables without CTLFLAG_ANYBODY flag as
2375126121Spjd	 * biba/high, but also require privilege to change them.
2376106161Srwatson	 */
2377126121Spjd	if (req->newptr != NULL && (oidp->oid_kind & CTLFLAG_ANYBODY) == 0) {
2378106161Srwatson		if (!mac_biba_subject_dominate_high(subj))
2379106161Srwatson			return (EACCES);
2380106161Srwatson
2381106161Srwatson		error = mac_biba_subject_privileged(subj);
2382106161Srwatson		if (error)
2383106161Srwatson			return (error);
2384106161Srwatson	}
2385106161Srwatson
2386106161Srwatson	return (0);
2387106161Srwatson}
2388106161Srwatson
2389106161Srwatsonstatic int
2390101099Srwatsonmac_biba_check_vnode_chdir(struct ucred *cred, struct vnode *dvp,
2391101099Srwatson    struct label *dlabel)
2392101099Srwatson{
2393101099Srwatson	struct mac_biba *subj, *obj;
2394101099Srwatson
2395101099Srwatson	if (!mac_biba_enabled)
2396101099Srwatson		return (0);
2397101099Srwatson
2398122524Srwatson	subj = SLOT(cred->cr_label);
2399101099Srwatson	obj = SLOT(dlabel);
2400101099Srwatson
2401132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2402101099Srwatson		return (EACCES);
2403101099Srwatson
2404101099Srwatson	return (0);
2405101099Srwatson}
2406101099Srwatson
2407101099Srwatsonstatic int
2408101099Srwatsonmac_biba_check_vnode_chroot(struct ucred *cred, struct vnode *dvp,
2409101099Srwatson    struct label *dlabel)
2410101099Srwatson{
2411101099Srwatson	struct mac_biba *subj, *obj;
2412101099Srwatson
2413101099Srwatson	if (!mac_biba_enabled)
2414101099Srwatson		return (0);
2415101099Srwatson
2416122524Srwatson	subj = SLOT(cred->cr_label);
2417101099Srwatson	obj = SLOT(dlabel);
2418101099Srwatson
2419132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2420101099Srwatson		return (EACCES);
2421101099Srwatson
2422101099Srwatson	return (0);
2423101099Srwatson}
2424101099Srwatson
2425101099Srwatsonstatic int
2426101099Srwatsonmac_biba_check_vnode_create(struct ucred *cred, struct vnode *dvp,
2427101099Srwatson    struct label *dlabel, struct componentname *cnp, struct vattr *vap)
2428101099Srwatson{
2429101099Srwatson	struct mac_biba *subj, *obj;
2430101099Srwatson
2431101099Srwatson	if (!mac_biba_enabled)
2432101099Srwatson		return (0);
2433101099Srwatson
2434122524Srwatson	subj = SLOT(cred->cr_label);
2435101099Srwatson	obj = SLOT(dlabel);
2436101099Srwatson
2437132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2438101099Srwatson		return (EACCES);
2439101099Srwatson
2440101099Srwatson	return (0);
2441101099Srwatson}
2442101099Srwatson
2443101099Srwatsonstatic int
2444101099Srwatsonmac_biba_check_vnode_delete(struct ucred *cred, struct vnode *dvp,
2445101099Srwatson    struct label *dlabel, struct vnode *vp, struct label *label,
2446101099Srwatson    struct componentname *cnp)
2447101099Srwatson{
2448101099Srwatson	struct mac_biba *subj, *obj;
2449101099Srwatson
2450101099Srwatson	if (!mac_biba_enabled)
2451101099Srwatson		return (0);
2452101099Srwatson
2453122524Srwatson	subj = SLOT(cred->cr_label);
2454101099Srwatson	obj = SLOT(dlabel);
2455101099Srwatson
2456132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2457101099Srwatson		return (EACCES);
2458101099Srwatson
2459101099Srwatson	obj = SLOT(label);
2460101099Srwatson
2461132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2462101099Srwatson		return (EACCES);
2463101099Srwatson
2464101099Srwatson	return (0);
2465101099Srwatson}
2466101099Srwatson
2467101099Srwatsonstatic int
2468101099Srwatsonmac_biba_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
2469101099Srwatson    struct label *label, acl_type_t type)
2470101099Srwatson{
2471101099Srwatson	struct mac_biba *subj, *obj;
2472101099Srwatson
2473101099Srwatson	if (!mac_biba_enabled)
2474101099Srwatson		return (0);
2475101099Srwatson
2476122524Srwatson	subj = SLOT(cred->cr_label);
2477101099Srwatson	obj = SLOT(label);
2478101099Srwatson
2479132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2480101099Srwatson		return (EACCES);
2481101099Srwatson
2482101099Srwatson	return (0);
2483101099Srwatson}
2484101099Srwatson
2485101099Srwatsonstatic int
2486119202Srwatsonmac_biba_check_vnode_deleteextattr(struct ucred *cred, struct vnode *vp,
2487119202Srwatson    struct label *label, int attrnamespace, const char *name)
2488119202Srwatson{
2489119202Srwatson	struct mac_biba *subj, *obj;
2490119202Srwatson
2491119202Srwatson	if (!mac_biba_enabled)
2492119202Srwatson		return (0);
2493119202Srwatson
2494122524Srwatson	subj = SLOT(cred->cr_label);
2495119202Srwatson	obj = SLOT(label);
2496119202Srwatson
2497132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2498119202Srwatson		return (EACCES);
2499119202Srwatson
2500119202Srwatson	return (0);
2501119202Srwatson}
2502119202Srwatson
2503119202Srwatsonstatic int
2504101099Srwatsonmac_biba_check_vnode_exec(struct ucred *cred, struct vnode *vp,
2505106648Srwatson    struct label *label, struct image_params *imgp,
2506106648Srwatson    struct label *execlabel)
2507101099Srwatson{
2508106648Srwatson	struct mac_biba *subj, *obj, *exec;
2509106648Srwatson	int error;
2510101099Srwatson
2511106648Srwatson	if (execlabel != NULL) {
2512106648Srwatson		/*
2513106648Srwatson		 * We currently don't permit labels to be changed at
2514106648Srwatson		 * exec-time as part of Biba, so disallow non-NULL
2515106648Srwatson		 * Biba label elements in the execlabel.
2516106648Srwatson		 */
2517106648Srwatson		exec = SLOT(execlabel);
2518106648Srwatson		error = biba_atmostflags(exec, 0);
2519106648Srwatson		if (error)
2520106648Srwatson			return (error);
2521106648Srwatson	}
2522106648Srwatson
2523101099Srwatson	if (!mac_biba_enabled)
2524101099Srwatson		return (0);
2525101099Srwatson
2526122524Srwatson	subj = SLOT(cred->cr_label);
2527101099Srwatson	obj = SLOT(label);
2528101099Srwatson
2529132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2530101099Srwatson		return (EACCES);
2531101099Srwatson
2532101099Srwatson	return (0);
2533101099Srwatson}
2534101099Srwatson
2535101099Srwatsonstatic int
2536101099Srwatsonmac_biba_check_vnode_getacl(struct ucred *cred, struct vnode *vp,
2537101099Srwatson    struct label *label, acl_type_t type)
2538101099Srwatson{
2539101099Srwatson	struct mac_biba *subj, *obj;
2540101099Srwatson
2541101099Srwatson	if (!mac_biba_enabled)
2542101099Srwatson		return (0);
2543101099Srwatson
2544122524Srwatson	subj = SLOT(cred->cr_label);
2545101099Srwatson	obj = SLOT(label);
2546101099Srwatson
2547132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2548101099Srwatson		return (EACCES);
2549101099Srwatson
2550101099Srwatson	return (0);
2551101099Srwatson}
2552101099Srwatson
2553101099Srwatsonstatic int
2554101099Srwatsonmac_biba_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
2555101099Srwatson    struct label *label, int attrnamespace, const char *name, struct uio *uio)
2556101099Srwatson{
2557101099Srwatson	struct mac_biba *subj, *obj;
2558101099Srwatson
2559101099Srwatson	if (!mac_biba_enabled)
2560101099Srwatson		return (0);
2561101099Srwatson
2562122524Srwatson	subj = SLOT(cred->cr_label);
2563101099Srwatson	obj = SLOT(label);
2564101099Srwatson
2565132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2566101099Srwatson		return (EACCES);
2567101099Srwatson
2568101099Srwatson	return (0);
2569101099Srwatson}
2570101099Srwatson
2571101099Srwatsonstatic int
2572104530Srwatsonmac_biba_check_vnode_link(struct ucred *cred, struct vnode *dvp,
2573104530Srwatson    struct label *dlabel, struct vnode *vp, struct label *label,
2574104530Srwatson    struct componentname *cnp)
2575104530Srwatson{
2576104530Srwatson	struct mac_biba *subj, *obj;
2577104530Srwatson
2578104530Srwatson	if (!mac_biba_enabled)
2579104530Srwatson		return (0);
2580104530Srwatson
2581122524Srwatson	subj = SLOT(cred->cr_label);
2582104530Srwatson	obj = SLOT(dlabel);
2583104530Srwatson
2584132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2585104530Srwatson		return (EACCES);
2586104530Srwatson
2587104530Srwatson	obj = SLOT(label);
2588104530Srwatson
2589132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2590104530Srwatson		return (EACCES);
2591104530Srwatson
2592104530Srwatson	return (0);
2593104530Srwatson}
2594104530Srwatson
2595104530Srwatsonstatic int
2596119202Srwatsonmac_biba_check_vnode_listextattr(struct ucred *cred, struct vnode *vp,
2597119202Srwatson    struct label *label, int attrnamespace)
2598119202Srwatson{
2599119202Srwatson	struct mac_biba *subj, *obj;
2600119202Srwatson
2601119202Srwatson	if (!mac_biba_enabled)
2602119202Srwatson		return (0);
2603119202Srwatson
2604122524Srwatson	subj = SLOT(cred->cr_label);
2605119202Srwatson	obj = SLOT(label);
2606119202Srwatson
2607132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2608119202Srwatson		return (EACCES);
2609119202Srwatson
2610119202Srwatson	return (0);
2611119202Srwatson}
2612119202Srwatson
2613119202Srwatsonstatic int
2614103759Srwatsonmac_biba_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
2615101099Srwatson    struct label *dlabel, struct componentname *cnp)
2616101099Srwatson{
2617101099Srwatson	struct mac_biba *subj, *obj;
2618103759Srwatson
2619101099Srwatson	if (!mac_biba_enabled)
2620101099Srwatson		return (0);
2621103759Srwatson
2622122524Srwatson	subj = SLOT(cred->cr_label);
2623101099Srwatson	obj = SLOT(dlabel);
2624103759Srwatson
2625132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2626101099Srwatson		return (EACCES);
2627101099Srwatson
2628103759Srwatson	return (0);
2629101099Srwatson}
2630101099Srwatson
2631101099Srwatsonstatic int
2632104546Srwatsonmac_biba_check_vnode_mmap(struct ucred *cred, struct vnode *vp,
2633145076Scsjp    struct label *label, int prot, int flags)
2634104546Srwatson{
2635104546Srwatson	struct mac_biba *subj, *obj;
2636104546Srwatson
2637104546Srwatson	/*
2638104546Srwatson	 * Rely on the use of open()-time protections to handle
2639104546Srwatson	 * non-revocation cases.
2640104546Srwatson	 */
2641105637Srwatson	if (!mac_biba_enabled || !revocation_enabled)
2642104546Srwatson		return (0);
2643104546Srwatson
2644122524Srwatson	subj = SLOT(cred->cr_label);
2645104546Srwatson	obj = SLOT(label);
2646104546Srwatson
2647104546Srwatson	if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
2648132232Srwatson		if (!mac_biba_dominate_effective(obj, subj))
2649104546Srwatson			return (EACCES);
2650104546Srwatson	}
2651145076Scsjp	if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) {
2652132232Srwatson		if (!mac_biba_dominate_effective(subj, obj))
2653104546Srwatson			return (EACCES);
2654104546Srwatson	}
2655104546Srwatson
2656104569Srwatson	return (0);
2657104546Srwatson}
2658104546Srwatson
2659104546Srwatsonstatic int
2660101099Srwatsonmac_biba_check_vnode_open(struct ucred *cred, struct vnode *vp,
2661106212Srwatson    struct label *vnodelabel, int acc_mode)
2662101099Srwatson{
2663101099Srwatson	struct mac_biba *subj, *obj;
2664101099Srwatson
2665101099Srwatson	if (!mac_biba_enabled)
2666101099Srwatson		return (0);
2667101099Srwatson
2668122524Srwatson	subj = SLOT(cred->cr_label);
2669101099Srwatson	obj = SLOT(vnodelabel);
2670101099Srwatson
2671101099Srwatson	/* XXX privilege override for admin? */
2672101099Srwatson	if (acc_mode & (VREAD | VEXEC | VSTAT)) {
2673132232Srwatson		if (!mac_biba_dominate_effective(obj, subj))
2674101099Srwatson			return (EACCES);
2675101099Srwatson	}
2676101099Srwatson	if (acc_mode & (VWRITE | VAPPEND | VADMIN)) {
2677132232Srwatson		if (!mac_biba_dominate_effective(subj, obj))
2678101099Srwatson			return (EACCES);
2679101099Srwatson	}
2680101099Srwatson
2681101099Srwatson	return (0);
2682101099Srwatson}
2683101099Srwatson
2684101099Srwatsonstatic int
2685102129Srwatsonmac_biba_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred,
2686102129Srwatson    struct vnode *vp, struct label *label)
2687102112Srwatson{
2688102112Srwatson	struct mac_biba *subj, *obj;
2689102112Srwatson
2690105637Srwatson	if (!mac_biba_enabled || !revocation_enabled)
2691102112Srwatson		return (0);
2692102112Srwatson
2693122524Srwatson	subj = SLOT(active_cred->cr_label);
2694102112Srwatson	obj = SLOT(label);
2695102112Srwatson
2696132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2697102112Srwatson		return (EACCES);
2698102112Srwatson
2699102112Srwatson	return (0);
2700102112Srwatson}
2701102112Srwatson
2702102112Srwatsonstatic int
2703102129Srwatsonmac_biba_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
2704102129Srwatson    struct vnode *vp, struct label *label)
2705102112Srwatson{
2706102112Srwatson	struct mac_biba *subj, *obj;
2707102112Srwatson
2708105637Srwatson	if (!mac_biba_enabled || !revocation_enabled)
2709102112Srwatson		return (0);
2710102112Srwatson
2711122524Srwatson	subj = SLOT(active_cred->cr_label);
2712102112Srwatson	obj = SLOT(label);
2713102112Srwatson
2714132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2715102112Srwatson		return (EACCES);
2716102112Srwatson
2717102112Srwatson	return (0);
2718102112Srwatson}
2719102112Srwatson
2720102112Srwatsonstatic int
2721101099Srwatsonmac_biba_check_vnode_readdir(struct ucred *cred, struct vnode *dvp,
2722101099Srwatson    struct label *dlabel)
2723101099Srwatson{
2724101099Srwatson	struct mac_biba *subj, *obj;
2725101099Srwatson
2726101099Srwatson	if (!mac_biba_enabled)
2727101099Srwatson		return (0);
2728101099Srwatson
2729122524Srwatson	subj = SLOT(cred->cr_label);
2730101099Srwatson	obj = SLOT(dlabel);
2731101099Srwatson
2732132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2733101099Srwatson		return (EACCES);
2734101099Srwatson
2735101099Srwatson	return (0);
2736101099Srwatson}
2737101099Srwatson
2738101099Srwatsonstatic int
2739101099Srwatsonmac_biba_check_vnode_readlink(struct ucred *cred, struct vnode *vp,
2740101099Srwatson    struct label *label)
2741101099Srwatson{
2742101099Srwatson	struct mac_biba *subj, *obj;
2743101099Srwatson
2744101099Srwatson	if (!mac_biba_enabled)
2745101099Srwatson		return (0);
2746101099Srwatson
2747122524Srwatson	subj = SLOT(cred->cr_label);
2748101099Srwatson	obj = SLOT(label);
2749101099Srwatson
2750132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2751101099Srwatson		return (EACCES);
2752101099Srwatson
2753101099Srwatson	return (0);
2754101099Srwatson}
2755101099Srwatson
2756101099Srwatsonstatic int
2757101099Srwatsonmac_biba_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
2758101099Srwatson    struct label *vnodelabel, struct label *newlabel)
2759101099Srwatson{
2760101099Srwatson	struct mac_biba *old, *new, *subj;
2761105634Srwatson	int error;
2762101099Srwatson
2763101099Srwatson	old = SLOT(vnodelabel);
2764101099Srwatson	new = SLOT(newlabel);
2765122524Srwatson	subj = SLOT(cred->cr_label);
2766101099Srwatson
2767101099Srwatson	/*
2768105634Srwatson	 * If there is a Biba label update for the vnode, it must be a
2769132232Srwatson	 * effective label.
2770101099Srwatson	 */
2771132232Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE);
2772105634Srwatson	if (error)
2773105634Srwatson		return (error);
2774101099Srwatson
2775101099Srwatson	/*
2776105634Srwatson	 * To perform a relabel of the vnode (Biba label or not), Biba must
2777105634Srwatson	 * authorize the relabel.
2778101099Srwatson	 */
2779132232Srwatson	if (!mac_biba_effective_in_range(old, subj))
2780101099Srwatson		return (EPERM);
2781101099Srwatson
2782101099Srwatson	/*
2783105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
2784101099Srwatson	 */
2785132232Srwatson	if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
2786105634Srwatson		/*
2787105634Srwatson		 * To change the Biba label on a vnode, the new vnode label
2788105634Srwatson		 * must be in the subject range.
2789105634Srwatson		 */
2790132232Srwatson		if (!mac_biba_effective_in_range(new, subj))
2791105634Srwatson			return (EPERM);
2792101099Srwatson
2793105634Srwatson		/*
2794105634Srwatson		 * To change the Biba label on the vnode to be EQUAL,
2795105634Srwatson		 * the subject must have appropriate privilege.
2796105634Srwatson		 */
2797105634Srwatson		if (mac_biba_contains_equal(new)) {
2798106090Srwatson			error = mac_biba_subject_privileged(subj);
2799105634Srwatson			if (error)
2800105634Srwatson				return (error);
2801105634Srwatson		}
2802105634Srwatson	}
2803105634Srwatson
2804105634Srwatson	return (0);
2805101099Srwatson}
2806101099Srwatson
2807101099Srwatsonstatic int
2808101099Srwatsonmac_biba_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
2809101099Srwatson    struct label *dlabel, struct vnode *vp, struct label *label,
2810101099Srwatson    struct componentname *cnp)
2811101099Srwatson{
2812101099Srwatson	struct mac_biba *subj, *obj;
2813101099Srwatson
2814101099Srwatson	if (!mac_biba_enabled)
2815101099Srwatson		return (0);
2816101099Srwatson
2817122524Srwatson	subj = SLOT(cred->cr_label);
2818101099Srwatson	obj = SLOT(dlabel);
2819101099Srwatson
2820132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2821101099Srwatson		return (EACCES);
2822101099Srwatson
2823101099Srwatson	obj = SLOT(label);
2824101099Srwatson
2825132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2826101099Srwatson		return (EACCES);
2827101099Srwatson
2828101099Srwatson	return (0);
2829101099Srwatson}
2830101099Srwatson
2831101099Srwatsonstatic int
2832101099Srwatsonmac_biba_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
2833101099Srwatson    struct label *dlabel, struct vnode *vp, struct label *label, int samedir,
2834101099Srwatson    struct componentname *cnp)
2835101099Srwatson{
2836101099Srwatson	struct mac_biba *subj, *obj;
2837101099Srwatson
2838101099Srwatson	if (!mac_biba_enabled)
2839101099Srwatson		return (0);
2840101099Srwatson
2841122524Srwatson	subj = SLOT(cred->cr_label);
2842101099Srwatson	obj = SLOT(dlabel);
2843101099Srwatson
2844132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2845101099Srwatson		return (EACCES);
2846101099Srwatson
2847101099Srwatson	if (vp != NULL) {
2848101099Srwatson		obj = SLOT(label);
2849101099Srwatson
2850132232Srwatson		if (!mac_biba_dominate_effective(subj, obj))
2851101099Srwatson			return (EACCES);
2852101099Srwatson	}
2853101099Srwatson
2854101099Srwatson	return (0);
2855101099Srwatson}
2856101099Srwatson
2857101099Srwatsonstatic int
2858101099Srwatsonmac_biba_check_vnode_revoke(struct ucred *cred, struct vnode *vp,
2859101099Srwatson    struct label *label)
2860101099Srwatson{
2861101099Srwatson	struct mac_biba *subj, *obj;
2862101099Srwatson
2863101099Srwatson	if (!mac_biba_enabled)
2864101099Srwatson		return (0);
2865101099Srwatson
2866122524Srwatson	subj = SLOT(cred->cr_label);
2867101099Srwatson	obj = SLOT(label);
2868101099Srwatson
2869132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2870101099Srwatson		return (EACCES);
2871101099Srwatson
2872101099Srwatson	return (0);
2873101099Srwatson}
2874101099Srwatson
2875101099Srwatsonstatic int
2876101099Srwatsonmac_biba_check_vnode_setacl(struct ucred *cred, struct vnode *vp,
2877101099Srwatson    struct label *label, acl_type_t type, struct acl *acl)
2878101099Srwatson{
2879101099Srwatson	struct mac_biba *subj, *obj;
2880101099Srwatson
2881101099Srwatson	if (!mac_biba_enabled)
2882101099Srwatson		return (0);
2883101099Srwatson
2884122524Srwatson	subj = SLOT(cred->cr_label);
2885101099Srwatson	obj = SLOT(label);
2886101099Srwatson
2887132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2888101099Srwatson		return (EACCES);
2889101099Srwatson
2890101099Srwatson	return (0);
2891101099Srwatson}
2892101099Srwatson
2893101099Srwatsonstatic int
2894101099Srwatsonmac_biba_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
2895101099Srwatson    struct label *vnodelabel, int attrnamespace, const char *name,
2896101099Srwatson    struct uio *uio)
2897101099Srwatson{
2898101099Srwatson	struct mac_biba *subj, *obj;
2899101099Srwatson
2900101099Srwatson	if (!mac_biba_enabled)
2901101099Srwatson		return (0);
2902101099Srwatson
2903122524Srwatson	subj = SLOT(cred->cr_label);
2904101099Srwatson	obj = SLOT(vnodelabel);
2905101099Srwatson
2906132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2907101099Srwatson		return (EACCES);
2908101099Srwatson
2909101099Srwatson	/* XXX: protect the MAC EA in a special way? */
2910101099Srwatson
2911101099Srwatson	return (0);
2912101099Srwatson}
2913101099Srwatson
2914101099Srwatsonstatic int
2915101099Srwatsonmac_biba_check_vnode_setflags(struct ucred *cred, struct vnode *vp,
2916101099Srwatson    struct label *vnodelabel, u_long flags)
2917101099Srwatson{
2918101099Srwatson	struct mac_biba *subj, *obj;
2919101099Srwatson
2920101099Srwatson	if (!mac_biba_enabled)
2921101099Srwatson		return (0);
2922101099Srwatson
2923122524Srwatson	subj = SLOT(cred->cr_label);
2924101099Srwatson	obj = SLOT(vnodelabel);
2925101099Srwatson
2926132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2927101099Srwatson		return (EACCES);
2928101099Srwatson
2929101099Srwatson	return (0);
2930101099Srwatson}
2931101099Srwatson
2932101099Srwatsonstatic int
2933101099Srwatsonmac_biba_check_vnode_setmode(struct ucred *cred, struct vnode *vp,
2934101099Srwatson    struct label *vnodelabel, mode_t mode)
2935101099Srwatson{
2936101099Srwatson	struct mac_biba *subj, *obj;
2937101099Srwatson
2938101099Srwatson	if (!mac_biba_enabled)
2939101099Srwatson		return (0);
2940101099Srwatson
2941122524Srwatson	subj = SLOT(cred->cr_label);
2942101099Srwatson	obj = SLOT(vnodelabel);
2943101099Srwatson
2944132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2945101099Srwatson		return (EACCES);
2946101099Srwatson
2947101099Srwatson	return (0);
2948101099Srwatson}
2949101099Srwatson
2950101099Srwatsonstatic int
2951101099Srwatsonmac_biba_check_vnode_setowner(struct ucred *cred, struct vnode *vp,
2952101099Srwatson    struct label *vnodelabel, uid_t uid, gid_t gid)
2953101099Srwatson{
2954101099Srwatson	struct mac_biba *subj, *obj;
2955101099Srwatson
2956101099Srwatson	if (!mac_biba_enabled)
2957101099Srwatson		return (0);
2958101099Srwatson
2959122524Srwatson	subj = SLOT(cred->cr_label);
2960101099Srwatson	obj = SLOT(vnodelabel);
2961101099Srwatson
2962132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2963101099Srwatson		return (EACCES);
2964101099Srwatson
2965101099Srwatson	return (0);
2966101099Srwatson}
2967101099Srwatson
2968101099Srwatsonstatic int
2969101099Srwatsonmac_biba_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
2970101099Srwatson    struct label *vnodelabel, struct timespec atime, struct timespec mtime)
2971101099Srwatson{
2972101099Srwatson	struct mac_biba *subj, *obj;
2973101099Srwatson
2974101099Srwatson	if (!mac_biba_enabled)
2975101099Srwatson		return (0);
2976101099Srwatson
2977122524Srwatson	subj = SLOT(cred->cr_label);
2978101099Srwatson	obj = SLOT(vnodelabel);
2979101099Srwatson
2980132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2981101099Srwatson		return (EACCES);
2982101099Srwatson
2983101099Srwatson	return (0);
2984101099Srwatson}
2985101099Srwatson
2986101099Srwatsonstatic int
2987102129Srwatsonmac_biba_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
2988102129Srwatson    struct vnode *vp, struct label *vnodelabel)
2989101099Srwatson{
2990101099Srwatson	struct mac_biba *subj, *obj;
2991101099Srwatson
2992101099Srwatson	if (!mac_biba_enabled)
2993101099Srwatson		return (0);
2994101099Srwatson
2995122524Srwatson	subj = SLOT(active_cred->cr_label);
2996101099Srwatson	obj = SLOT(vnodelabel);
2997101099Srwatson
2998132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2999101099Srwatson		return (EACCES);
3000101099Srwatson
3001101099Srwatson	return (0);
3002101099Srwatson}
3003101099Srwatson
3004102112Srwatsonstatic int
3005102129Srwatsonmac_biba_check_vnode_write(struct ucred *active_cred,
3006102129Srwatson    struct ucred *file_cred, struct vnode *vp, struct label *label)
3007102112Srwatson{
3008102112Srwatson	struct mac_biba *subj, *obj;
3009102112Srwatson
3010105637Srwatson	if (!mac_biba_enabled || !revocation_enabled)
3011102112Srwatson		return (0);
3012102112Srwatson
3013122524Srwatson	subj = SLOT(active_cred->cr_label);
3014102112Srwatson	obj = SLOT(label);
3015102112Srwatson
3016132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
3017102112Srwatson		return (EACCES);
3018102112Srwatson
3019102112Srwatson	return (0);
3020102112Srwatson}
3021102112Srwatson
3022160243Scsjpstatic int
3023160243Scsjpmac_biba_associate_nfsd_label(struct ucred *cred)
3024160243Scsjp{
3025160243Scsjp	struct mac_biba *label;
3026160243Scsjp
3027160243Scsjp	label = SLOT(cred->cr_label);
3028160243Scsjp	mac_biba_set_effective(label, MAC_BIBA_TYPE_LOW, 0, NULL);
3029160243Scsjp	mac_biba_set_range(label, MAC_BIBA_TYPE_LOW, 0, NULL,
3030160243Scsjp	    MAC_BIBA_TYPE_HIGH, 0, NULL);
3031160243Scsjp	return (0);
3032160243Scsjp}
3033160243Scsjp
3034106217Srwatsonstatic struct mac_policy_ops mac_biba_ops =
3035101099Srwatson{
3036106217Srwatson	.mpo_init = mac_biba_init,
3037106217Srwatson	.mpo_init_bpfdesc_label = mac_biba_init_label,
3038106217Srwatson	.mpo_init_cred_label = mac_biba_init_label,
3039106217Srwatson	.mpo_init_devfsdirent_label = mac_biba_init_label,
3040106217Srwatson	.mpo_init_ifnet_label = mac_biba_init_label,
3041122875Srwatson	.mpo_init_inpcb_label = mac_biba_init_label_waitcheck,
3042140628Srwatson	.mpo_init_sysv_msgmsg_label = mac_biba_init_label,
3043140628Srwatson	.mpo_init_sysv_msgqueue_label = mac_biba_init_label,
3044147091Srwatson	.mpo_init_sysv_sem_label = mac_biba_init_label,
3045140628Srwatson	.mpo_init_sysv_shm_label = mac_biba_init_label,
3046112675Srwatson	.mpo_init_ipq_label = mac_biba_init_label_waitcheck,
3047106217Srwatson	.mpo_init_mbuf_label = mac_biba_init_label_waitcheck,
3048106217Srwatson	.mpo_init_mount_label = mac_biba_init_label,
3049106217Srwatson	.mpo_init_mount_fs_label = mac_biba_init_label,
3050106217Srwatson	.mpo_init_pipe_label = mac_biba_init_label,
3051145855Srwatson	.mpo_init_posix_sem_label = mac_biba_init_label,
3052106217Srwatson	.mpo_init_socket_label = mac_biba_init_label_waitcheck,
3053106217Srwatson	.mpo_init_socket_peer_label = mac_biba_init_label_waitcheck,
3054106217Srwatson	.mpo_init_vnode_label = mac_biba_init_label,
3055106217Srwatson	.mpo_destroy_bpfdesc_label = mac_biba_destroy_label,
3056106217Srwatson	.mpo_destroy_cred_label = mac_biba_destroy_label,
3057106217Srwatson	.mpo_destroy_devfsdirent_label = mac_biba_destroy_label,
3058106217Srwatson	.mpo_destroy_ifnet_label = mac_biba_destroy_label,
3059122875Srwatson	.mpo_destroy_inpcb_label = mac_biba_destroy_label,
3060140628Srwatson	.mpo_destroy_sysv_msgmsg_label = mac_biba_destroy_label,
3061140628Srwatson	.mpo_destroy_sysv_msgqueue_label = mac_biba_destroy_label,
3062147091Srwatson	.mpo_destroy_sysv_sem_label = mac_biba_destroy_label,
3063140628Srwatson	.mpo_destroy_sysv_shm_label = mac_biba_destroy_label,
3064106217Srwatson	.mpo_destroy_ipq_label = mac_biba_destroy_label,
3065106217Srwatson	.mpo_destroy_mbuf_label = mac_biba_destroy_label,
3066106217Srwatson	.mpo_destroy_mount_label = mac_biba_destroy_label,
3067106217Srwatson	.mpo_destroy_mount_fs_label = mac_biba_destroy_label,
3068106217Srwatson	.mpo_destroy_pipe_label = mac_biba_destroy_label,
3069145855Srwatson	.mpo_destroy_posix_sem_label = mac_biba_destroy_label,
3070106217Srwatson	.mpo_destroy_socket_label = mac_biba_destroy_label,
3071106217Srwatson	.mpo_destroy_socket_peer_label = mac_biba_destroy_label,
3072106217Srwatson	.mpo_destroy_vnode_label = mac_biba_destroy_label,
3073123173Srwatson	.mpo_copy_cred_label = mac_biba_copy_label,
3074131025Srwatson	.mpo_copy_ifnet_label = mac_biba_copy_label,
3075115707Srwatson	.mpo_copy_mbuf_label = mac_biba_copy_label,
3076106217Srwatson	.mpo_copy_pipe_label = mac_biba_copy_label,
3077122820Srwatson	.mpo_copy_socket_label = mac_biba_copy_label,
3078106217Srwatson	.mpo_copy_vnode_label = mac_biba_copy_label,
3079106217Srwatson	.mpo_externalize_cred_label = mac_biba_externalize_label,
3080106217Srwatson	.mpo_externalize_ifnet_label = mac_biba_externalize_label,
3081106217Srwatson	.mpo_externalize_pipe_label = mac_biba_externalize_label,
3082106217Srwatson	.mpo_externalize_socket_label = mac_biba_externalize_label,
3083106217Srwatson	.mpo_externalize_socket_peer_label = mac_biba_externalize_label,
3084106217Srwatson	.mpo_externalize_vnode_label = mac_biba_externalize_label,
3085106217Srwatson	.mpo_internalize_cred_label = mac_biba_internalize_label,
3086106217Srwatson	.mpo_internalize_ifnet_label = mac_biba_internalize_label,
3087106217Srwatson	.mpo_internalize_pipe_label = mac_biba_internalize_label,
3088106217Srwatson	.mpo_internalize_socket_label = mac_biba_internalize_label,
3089106217Srwatson	.mpo_internalize_vnode_label = mac_biba_internalize_label,
3090106217Srwatson	.mpo_create_devfs_device = mac_biba_create_devfs_device,
3091106217Srwatson	.mpo_create_devfs_directory = mac_biba_create_devfs_directory,
3092106217Srwatson	.mpo_create_devfs_symlink = mac_biba_create_devfs_symlink,
3093106217Srwatson	.mpo_create_mount = mac_biba_create_mount,
3094106217Srwatson	.mpo_relabel_vnode = mac_biba_relabel_vnode,
3095106217Srwatson	.mpo_update_devfsdirent = mac_biba_update_devfsdirent,
3096106217Srwatson	.mpo_associate_vnode_devfs = mac_biba_associate_vnode_devfs,
3097106217Srwatson	.mpo_associate_vnode_extattr = mac_biba_associate_vnode_extattr,
3098106217Srwatson	.mpo_associate_vnode_singlelabel = mac_biba_associate_vnode_singlelabel,
3099106217Srwatson	.mpo_create_vnode_extattr = mac_biba_create_vnode_extattr,
3100106217Srwatson	.mpo_setlabel_vnode_extattr = mac_biba_setlabel_vnode_extattr,
3101106217Srwatson	.mpo_create_mbuf_from_socket = mac_biba_create_mbuf_from_socket,
3102106217Srwatson	.mpo_create_pipe = mac_biba_create_pipe,
3103145855Srwatson	.mpo_create_posix_sem = mac_biba_create_posix_sem,
3104106217Srwatson	.mpo_create_socket = mac_biba_create_socket,
3105106217Srwatson	.mpo_create_socket_from_socket = mac_biba_create_socket_from_socket,
3106106217Srwatson	.mpo_relabel_pipe = mac_biba_relabel_pipe,
3107106217Srwatson	.mpo_relabel_socket = mac_biba_relabel_socket,
3108106217Srwatson	.mpo_set_socket_peer_from_mbuf = mac_biba_set_socket_peer_from_mbuf,
3109106217Srwatson	.mpo_set_socket_peer_from_socket = mac_biba_set_socket_peer_from_socket,
3110106217Srwatson	.mpo_create_bpfdesc = mac_biba_create_bpfdesc,
3111106217Srwatson	.mpo_create_datagram_from_ipq = mac_biba_create_datagram_from_ipq,
3112106217Srwatson	.mpo_create_fragment = mac_biba_create_fragment,
3113106217Srwatson	.mpo_create_ifnet = mac_biba_create_ifnet,
3114122875Srwatson	.mpo_create_inpcb_from_socket = mac_biba_create_inpcb_from_socket,
3115140628Srwatson	.mpo_create_sysv_msgmsg = mac_biba_create_sysv_msgmsg,
3116140628Srwatson	.mpo_create_sysv_msgqueue = mac_biba_create_sysv_msgqueue,
3117147091Srwatson	.mpo_create_sysv_sem = mac_biba_create_sysv_sem,
3118140628Srwatson	.mpo_create_sysv_shm = mac_biba_create_sysv_shm,
3119106217Srwatson	.mpo_create_ipq = mac_biba_create_ipq,
3120123607Srwatson	.mpo_create_mbuf_from_inpcb = mac_biba_create_mbuf_from_inpcb,
3121106217Srwatson	.mpo_create_mbuf_linklayer = mac_biba_create_mbuf_linklayer,
3122106217Srwatson	.mpo_create_mbuf_from_bpfdesc = mac_biba_create_mbuf_from_bpfdesc,
3123106217Srwatson	.mpo_create_mbuf_from_ifnet = mac_biba_create_mbuf_from_ifnet,
3124106217Srwatson	.mpo_create_mbuf_multicast_encap = mac_biba_create_mbuf_multicast_encap,
3125106217Srwatson	.mpo_create_mbuf_netlayer = mac_biba_create_mbuf_netlayer,
3126106217Srwatson	.mpo_fragment_match = mac_biba_fragment_match,
3127106217Srwatson	.mpo_relabel_ifnet = mac_biba_relabel_ifnet,
3128106217Srwatson	.mpo_update_ipq = mac_biba_update_ipq,
3129122875Srwatson	.mpo_inpcb_sosetlabel = mac_biba_inpcb_sosetlabel,
3130106217Srwatson	.mpo_create_proc0 = mac_biba_create_proc0,
3131106217Srwatson	.mpo_create_proc1 = mac_biba_create_proc1,
3132106217Srwatson	.mpo_relabel_cred = mac_biba_relabel_cred,
3133140628Srwatson	.mpo_cleanup_sysv_msgmsg = mac_biba_cleanup_sysv_msgmsg,
3134140628Srwatson	.mpo_cleanup_sysv_msgqueue = mac_biba_cleanup_sysv_msgqueue,
3135147091Srwatson	.mpo_cleanup_sysv_sem = mac_biba_cleanup_sysv_sem,
3136140628Srwatson	.mpo_cleanup_sysv_shm = mac_biba_cleanup_sysv_shm,
3137106217Srwatson	.mpo_check_bpfdesc_receive = mac_biba_check_bpfdesc_receive,
3138106217Srwatson	.mpo_check_cred_relabel = mac_biba_check_cred_relabel,
3139106217Srwatson	.mpo_check_cred_visible = mac_biba_check_cred_visible,
3140106217Srwatson	.mpo_check_ifnet_relabel = mac_biba_check_ifnet_relabel,
3141106217Srwatson	.mpo_check_ifnet_transmit = mac_biba_check_ifnet_transmit,
3142122875Srwatson	.mpo_check_inpcb_deliver = mac_biba_check_inpcb_deliver,
3143140628Srwatson	.mpo_check_sysv_msgrcv = mac_biba_check_sysv_msgrcv,
3144140628Srwatson	.mpo_check_sysv_msgrmid = mac_biba_check_sysv_msgrmid,
3145140628Srwatson	.mpo_check_sysv_msqget = mac_biba_check_sysv_msqget,
3146140628Srwatson	.mpo_check_sysv_msqsnd = mac_biba_check_sysv_msqsnd,
3147140628Srwatson	.mpo_check_sysv_msqrcv = mac_biba_check_sysv_msqrcv,
3148140628Srwatson	.mpo_check_sysv_msqctl = mac_biba_check_sysv_msqctl,
3149140628Srwatson	.mpo_check_sysv_semctl = mac_biba_check_sysv_semctl,
3150140628Srwatson	.mpo_check_sysv_semget = mac_biba_check_sysv_semget,
3151140628Srwatson	.mpo_check_sysv_semop = mac_biba_check_sysv_semop,
3152140628Srwatson	.mpo_check_sysv_shmat = mac_biba_check_sysv_shmat,
3153140628Srwatson	.mpo_check_sysv_shmctl = mac_biba_check_sysv_shmctl,
3154140628Srwatson	.mpo_check_sysv_shmget = mac_biba_check_sysv_shmget,
3155110354Srwatson	.mpo_check_kld_load = mac_biba_check_kld_load,
3156110354Srwatson	.mpo_check_kld_unload = mac_biba_check_kld_unload,
3157106217Srwatson	.mpo_check_mount_stat = mac_biba_check_mount_stat,
3158106217Srwatson	.mpo_check_pipe_ioctl = mac_biba_check_pipe_ioctl,
3159106217Srwatson	.mpo_check_pipe_poll = mac_biba_check_pipe_poll,
3160106217Srwatson	.mpo_check_pipe_read = mac_biba_check_pipe_read,
3161106217Srwatson	.mpo_check_pipe_relabel = mac_biba_check_pipe_relabel,
3162106217Srwatson	.mpo_check_pipe_stat = mac_biba_check_pipe_stat,
3163106217Srwatson	.mpo_check_pipe_write = mac_biba_check_pipe_write,
3164145855Srwatson	.mpo_check_posix_sem_destroy = mac_biba_check_posix_sem_write,
3165145855Srwatson	.mpo_check_posix_sem_getvalue = mac_biba_check_posix_sem_rdonly,
3166145855Srwatson	.mpo_check_posix_sem_open = mac_biba_check_posix_sem_write,
3167145855Srwatson	.mpo_check_posix_sem_post = mac_biba_check_posix_sem_write,
3168145855Srwatson	.mpo_check_posix_sem_unlink = mac_biba_check_posix_sem_write,
3169145855Srwatson	.mpo_check_posix_sem_wait = mac_biba_check_posix_sem_write,
3170106217Srwatson	.mpo_check_proc_debug = mac_biba_check_proc_debug,
3171106217Srwatson	.mpo_check_proc_sched = mac_biba_check_proc_sched,
3172106217Srwatson	.mpo_check_proc_signal = mac_biba_check_proc_signal,
3173106217Srwatson	.mpo_check_socket_deliver = mac_biba_check_socket_deliver,
3174106217Srwatson	.mpo_check_socket_relabel = mac_biba_check_socket_relabel,
3175106217Srwatson	.mpo_check_socket_visible = mac_biba_check_socket_visible,
3176112574Srwatson	.mpo_check_sysarch_ioperm = mac_biba_check_sysarch_ioperm,
3177106418Srwatson	.mpo_check_system_acct = mac_biba_check_system_acct,
3178106418Srwatson	.mpo_check_system_settime = mac_biba_check_system_settime,
3179106217Srwatson	.mpo_check_system_swapon = mac_biba_check_system_swapon,
3180112574Srwatson	.mpo_check_system_swapoff = mac_biba_check_system_swapoff,
3181106217Srwatson	.mpo_check_system_sysctl = mac_biba_check_system_sysctl,
3182106217Srwatson	.mpo_check_vnode_access = mac_biba_check_vnode_open,
3183106217Srwatson	.mpo_check_vnode_chdir = mac_biba_check_vnode_chdir,
3184106217Srwatson	.mpo_check_vnode_chroot = mac_biba_check_vnode_chroot,
3185106217Srwatson	.mpo_check_vnode_create = mac_biba_check_vnode_create,
3186106217Srwatson	.mpo_check_vnode_delete = mac_biba_check_vnode_delete,
3187106217Srwatson	.mpo_check_vnode_deleteacl = mac_biba_check_vnode_deleteacl,
3188119202Srwatson	.mpo_check_vnode_deleteextattr = mac_biba_check_vnode_deleteextattr,
3189106217Srwatson	.mpo_check_vnode_exec = mac_biba_check_vnode_exec,
3190106217Srwatson	.mpo_check_vnode_getacl = mac_biba_check_vnode_getacl,
3191106217Srwatson	.mpo_check_vnode_getextattr = mac_biba_check_vnode_getextattr,
3192106217Srwatson	.mpo_check_vnode_link = mac_biba_check_vnode_link,
3193119202Srwatson	.mpo_check_vnode_listextattr = mac_biba_check_vnode_listextattr,
3194106217Srwatson	.mpo_check_vnode_lookup = mac_biba_check_vnode_lookup,
3195106217Srwatson	.mpo_check_vnode_mmap = mac_biba_check_vnode_mmap,
3196106217Srwatson	.mpo_check_vnode_open = mac_biba_check_vnode_open,
3197106217Srwatson	.mpo_check_vnode_poll = mac_biba_check_vnode_poll,
3198106217Srwatson	.mpo_check_vnode_read = mac_biba_check_vnode_read,
3199106217Srwatson	.mpo_check_vnode_readdir = mac_biba_check_vnode_readdir,
3200106217Srwatson	.mpo_check_vnode_readlink = mac_biba_check_vnode_readlink,
3201106217Srwatson	.mpo_check_vnode_relabel = mac_biba_check_vnode_relabel,
3202106217Srwatson	.mpo_check_vnode_rename_from = mac_biba_check_vnode_rename_from,
3203106217Srwatson	.mpo_check_vnode_rename_to = mac_biba_check_vnode_rename_to,
3204106217Srwatson	.mpo_check_vnode_revoke = mac_biba_check_vnode_revoke,
3205106217Srwatson	.mpo_check_vnode_setacl = mac_biba_check_vnode_setacl,
3206106217Srwatson	.mpo_check_vnode_setextattr = mac_biba_check_vnode_setextattr,
3207106217Srwatson	.mpo_check_vnode_setflags = mac_biba_check_vnode_setflags,
3208106217Srwatson	.mpo_check_vnode_setmode = mac_biba_check_vnode_setmode,
3209106217Srwatson	.mpo_check_vnode_setowner = mac_biba_check_vnode_setowner,
3210106217Srwatson	.mpo_check_vnode_setutimes = mac_biba_check_vnode_setutimes,
3211106217Srwatson	.mpo_check_vnode_stat = mac_biba_check_vnode_stat,
3212106217Srwatson	.mpo_check_vnode_write = mac_biba_check_vnode_write,
3213160243Scsjp	.mpo_associate_nfsd_label = mac_biba_associate_nfsd_label,
3214101099Srwatson};
3215101099Srwatson
3216112717SrwatsonMAC_POLICY_SET(&mac_biba_ops, mac_biba, "TrustedBSD MAC/Biba",
3217113531Srwatson    MPC_LOADTIME_FLAG_NOTLATE | MPC_LOADTIME_FLAG_LABELMBUFS, &mac_biba_slot);
3218