mac_biba.c revision 166617
1101099Srwatson/*-
2166533Srwatson * Copyright (c) 1999-2002, 2007 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 166617 2007-02-10 08:59:39Z rwatson $
35101099Srwatson */
36101099Srwatson
37101099Srwatson/*
38101099Srwatson * Developed by the TrustedBSD Project.
39101099Srwatson * Biba fixed label mandatory integrity policy.
40101099Srwatson */
41101099Srwatson
42101099Srwatson#include <sys/types.h>
43101099Srwatson#include <sys/param.h>
44101099Srwatson#include <sys/acl.h>
45101099Srwatson#include <sys/conf.h>
46105988Srwatson#include <sys/extattr.h>
47101099Srwatson#include <sys/kernel.h>
48164184Strhodes#include <sys/ksem.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
69101099Srwatson#include <fs/devfs/devfs.h>
70101099Srwatson
71101099Srwatson#include <net/bpfdesc.h>
72101099Srwatson#include <net/if.h>
73101099Srwatson#include <net/if_types.h>
74101099Srwatson#include <net/if_var.h>
75101099Srwatson
76101099Srwatson#include <netinet/in.h>
77122875Srwatson#include <netinet/in_pcb.h>
78101099Srwatson#include <netinet/ip_var.h>
79101099Srwatson
80122879Srwatson#include <vm/uma.h>
81101099Srwatson#include <vm/vm.h>
82101099Srwatson
83165469Srwatson#include <security/mac/mac_policy.h>
84101099Srwatson#include <security/mac_biba/mac_biba.h>
85101099Srwatson
86101099SrwatsonSYSCTL_DECL(_security_mac);
87101099Srwatson
88101099SrwatsonSYSCTL_NODE(_security_mac, OID_AUTO, biba, CTLFLAG_RW, 0,
89101099Srwatson    "TrustedBSD mac_biba policy controls");
90101099Srwatson
91105988Srwatsonstatic int	mac_biba_label_size = sizeof(struct mac_biba);
92105988SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, label_size, CTLFLAG_RD,
93105988Srwatson    &mac_biba_label_size, 0, "Size of struct mac_biba");
94105988Srwatson
95107731Srwatsonstatic int	mac_biba_enabled = 1;
96101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, enabled, CTLFLAG_RW,
97101099Srwatson    &mac_biba_enabled, 0, "Enforce MAC/Biba policy");
98102980SrwatsonTUNABLE_INT("security.mac.biba.enabled", &mac_biba_enabled);
99101099Srwatson
100101099Srwatsonstatic int	destroyed_not_inited;
101101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, destroyed_not_inited, CTLFLAG_RD,
102101099Srwatson    &destroyed_not_inited, 0, "Count of labels destroyed but not inited");
103101099Srwatson
104101099Srwatsonstatic int	trust_all_interfaces = 0;
105101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, trust_all_interfaces, CTLFLAG_RD,
106101099Srwatson    &trust_all_interfaces, 0, "Consider all interfaces 'trusted' by MAC/Biba");
107101099SrwatsonTUNABLE_INT("security.mac.biba.trust_all_interfaces", &trust_all_interfaces);
108101099Srwatson
109101099Srwatsonstatic char	trusted_interfaces[128];
110101099SrwatsonSYSCTL_STRING(_security_mac_biba, OID_AUTO, trusted_interfaces, CTLFLAG_RD,
111101099Srwatson    trusted_interfaces, 0, "Interfaces considered 'trusted' by MAC/Biba");
112101099SrwatsonTUNABLE_STR("security.mac.biba.trusted_interfaces", trusted_interfaces,
113101099Srwatson    sizeof(trusted_interfaces));
114101099Srwatson
115105643Srwatsonstatic int	max_compartments = MAC_BIBA_MAX_COMPARTMENTS;
116105643SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, max_compartments, CTLFLAG_RD,
117105643Srwatson    &max_compartments, 0, "Maximum supported compartments");
118105643Srwatson
119105606Srwatsonstatic int	ptys_equal = 0;
120105606SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, ptys_equal, CTLFLAG_RW,
121105606Srwatson    &ptys_equal, 0, "Label pty devices as biba/equal on create");
122105606SrwatsonTUNABLE_INT("security.mac.biba.ptys_equal", &ptys_equal);
123105606Srwatson
124153927Scsjpstatic int	interfaces_equal;
125153927ScsjpSYSCTL_INT(_security_mac_biba, OID_AUTO, interfaces_equal, CTLFLAG_RW,
126153927Scsjp    &interfaces_equal, 0, "Label network interfaces as biba/equal on create");
127153927ScsjpTUNABLE_INT("security.mac.biba.interfaces_equal", &interfaces_equal);
128153927Scsjp
129105637Srwatsonstatic int	revocation_enabled = 0;
130101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, revocation_enabled, CTLFLAG_RW,
131105637Srwatson    &revocation_enabled, 0, "Revoke access to objects on relabel");
132105637SrwatsonTUNABLE_INT("security.mac.biba.revocation_enabled", &revocation_enabled);
133101099Srwatson
134101099Srwatsonstatic int	mac_biba_slot;
135166533Srwatson#define	SLOT(l)	((struct mac_biba *)mac_label_get((l), mac_biba_slot))
136166533Srwatson#define	SLOT_SET(l, val) mac_label_set((l), mac_biba_slot, (uintptr_t)(val))
137101099Srwatson
138122879Srwatsonstatic uma_zone_t	zone_biba;
139101099Srwatson
140105643Srwatsonstatic __inline int
141105643Srwatsonbiba_bit_set_empty(u_char *set) {
142105643Srwatson	int i;
143105643Srwatson
144105643Srwatson	for (i = 0; i < MAC_BIBA_MAX_COMPARTMENTS >> 3; i++)
145105643Srwatson		if (set[i] != 0)
146105643Srwatson			return (0);
147105643Srwatson	return (1);
148105643Srwatson}
149105643Srwatson
150101099Srwatsonstatic struct mac_biba *
151104514Srwatsonbiba_alloc(int flag)
152101099Srwatson{
153101099Srwatson
154122879Srwatson	return (uma_zalloc(zone_biba, flag | M_ZERO));
155101099Srwatson}
156101099Srwatson
157101099Srwatsonstatic void
158101099Srwatsonbiba_free(struct mac_biba *mac_biba)
159101099Srwatson{
160101099Srwatson
161101099Srwatson	if (mac_biba != NULL)
162122879Srwatson		uma_zfree(zone_biba, mac_biba);
163101099Srwatson	else
164101099Srwatson		atomic_add_int(&destroyed_not_inited, 1);
165101099Srwatson}
166101099Srwatson
167101099Srwatsonstatic int
168105634Srwatsonbiba_atmostflags(struct mac_biba *mac_biba, int flags)
169105634Srwatson{
170105634Srwatson
171105634Srwatson	if ((mac_biba->mb_flags & flags) != mac_biba->mb_flags)
172105634Srwatson		return (EINVAL);
173105634Srwatson	return (0);
174105634Srwatson}
175105634Srwatson
176105634Srwatsonstatic int
177101099Srwatsonmac_biba_dominate_element(struct mac_biba_element *a,
178101099Srwatson    struct mac_biba_element *b)
179101099Srwatson{
180105643Srwatson	int bit;
181101099Srwatson
182105736Srwatson	switch (a->mbe_type) {
183101099Srwatson	case MAC_BIBA_TYPE_EQUAL:
184101099Srwatson	case MAC_BIBA_TYPE_HIGH:
185101099Srwatson		return (1);
186101099Srwatson
187101099Srwatson	case MAC_BIBA_TYPE_LOW:
188101099Srwatson		switch (b->mbe_type) {
189101099Srwatson		case MAC_BIBA_TYPE_GRADE:
190101099Srwatson		case MAC_BIBA_TYPE_HIGH:
191101099Srwatson			return (0);
192101099Srwatson
193101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
194101099Srwatson		case MAC_BIBA_TYPE_LOW:
195101099Srwatson			return (1);
196101099Srwatson
197101099Srwatson		default:
198101099Srwatson			panic("mac_biba_dominate_element: b->mbe_type invalid");
199101099Srwatson		}
200101099Srwatson
201101099Srwatson	case MAC_BIBA_TYPE_GRADE:
202101099Srwatson		switch (b->mbe_type) {
203101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
204101099Srwatson		case MAC_BIBA_TYPE_LOW:
205101099Srwatson			return (1);
206101099Srwatson
207101099Srwatson		case MAC_BIBA_TYPE_HIGH:
208101099Srwatson			return (0);
209101099Srwatson
210101099Srwatson		case MAC_BIBA_TYPE_GRADE:
211105643Srwatson			for (bit = 1; bit <= MAC_BIBA_MAX_COMPARTMENTS; bit++)
212105643Srwatson				if (!MAC_BIBA_BIT_TEST(bit,
213105643Srwatson				    a->mbe_compartments) &&
214105643Srwatson				    MAC_BIBA_BIT_TEST(bit, b->mbe_compartments))
215105643Srwatson					return (0);
216101099Srwatson			return (a->mbe_grade >= b->mbe_grade);
217101099Srwatson
218101099Srwatson		default:
219101099Srwatson			panic("mac_biba_dominate_element: b->mbe_type invalid");
220101099Srwatson		}
221101099Srwatson
222101099Srwatson	default:
223101099Srwatson		panic("mac_biba_dominate_element: a->mbe_type invalid");
224101099Srwatson	}
225101099Srwatson
226101099Srwatson	return (0);
227101099Srwatson}
228101099Srwatson
229101099Srwatsonstatic int
230105988Srwatsonmac_biba_subject_dominate_high(struct mac_biba *mac_biba)
231105988Srwatson{
232105988Srwatson	struct mac_biba_element *element;
233105988Srwatson
234132232Srwatson	KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
235132232Srwatson	    ("mac_biba_effective_in_range: mac_biba not effective"));
236132232Srwatson	element = &mac_biba->mb_effective;
237105988Srwatson
238105988Srwatson	return (element->mbe_type == MAC_BIBA_TYPE_EQUAL ||
239105988Srwatson	    element->mbe_type == MAC_BIBA_TYPE_HIGH);
240105988Srwatson}
241105988Srwatson
242105988Srwatsonstatic int
243101099Srwatsonmac_biba_range_in_range(struct mac_biba *rangea, struct mac_biba *rangeb)
244101099Srwatson{
245101099Srwatson
246101099Srwatson	return (mac_biba_dominate_element(&rangeb->mb_rangehigh,
247101099Srwatson	    &rangea->mb_rangehigh) &&
248101099Srwatson	    mac_biba_dominate_element(&rangea->mb_rangelow,
249101099Srwatson	    &rangeb->mb_rangelow));
250101099Srwatson}
251101099Srwatson
252101099Srwatsonstatic int
253136774Srwatsonmac_biba_effective_in_range(struct mac_biba *effective,
254136774Srwatson    struct mac_biba *range)
255101099Srwatson{
256101099Srwatson
257132232Srwatson	KASSERT((effective->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
258132232Srwatson	    ("mac_biba_effective_in_range: a not effective"));
259103750Srwatson	KASSERT((range->mb_flags & MAC_BIBA_FLAG_RANGE) != 0,
260132232Srwatson	    ("mac_biba_effective_in_range: b not range"));
261101099Srwatson
262101099Srwatson	return (mac_biba_dominate_element(&range->mb_rangehigh,
263132232Srwatson	    &effective->mb_effective) &&
264132232Srwatson	    mac_biba_dominate_element(&effective->mb_effective,
265101099Srwatson	    &range->mb_rangelow));
266101099Srwatson
267101099Srwatson	return (1);
268101099Srwatson}
269101099Srwatson
270101099Srwatsonstatic int
271132232Srwatsonmac_biba_dominate_effective(struct mac_biba *a, struct mac_biba *b)
272101099Srwatson{
273132232Srwatson	KASSERT((a->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
274132232Srwatson	    ("mac_biba_dominate_effective: a not effective"));
275132232Srwatson	KASSERT((b->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
276132232Srwatson	    ("mac_biba_dominate_effective: b not effective"));
277101099Srwatson
278132232Srwatson	return (mac_biba_dominate_element(&a->mb_effective, &b->mb_effective));
279101099Srwatson}
280101099Srwatson
281101099Srwatsonstatic int
282101099Srwatsonmac_biba_equal_element(struct mac_biba_element *a, struct mac_biba_element *b)
283101099Srwatson{
284101099Srwatson
285101099Srwatson	if (a->mbe_type == MAC_BIBA_TYPE_EQUAL ||
286101099Srwatson	    b->mbe_type == MAC_BIBA_TYPE_EQUAL)
287101099Srwatson		return (1);
288101099Srwatson
289101099Srwatson	return (a->mbe_type == b->mbe_type && a->mbe_grade == b->mbe_grade);
290101099Srwatson}
291101099Srwatson
292101099Srwatsonstatic int
293132232Srwatsonmac_biba_equal_effective(struct mac_biba *a, struct mac_biba *b)
294101099Srwatson{
295101099Srwatson
296132232Srwatson	KASSERT((a->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
297132232Srwatson	    ("mac_biba_equal_effective: a not effective"));
298132232Srwatson	KASSERT((b->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
299132232Srwatson	    ("mac_biba_equal_effective: b not effective"));
300101099Srwatson
301132232Srwatson	return (mac_biba_equal_element(&a->mb_effective, &b->mb_effective));
302101099Srwatson}
303101099Srwatson
304101099Srwatsonstatic int
305105634Srwatsonmac_biba_contains_equal(struct mac_biba *mac_biba)
306105634Srwatson{
307105634Srwatson
308132232Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_EFFECTIVE)
309132232Srwatson		if (mac_biba->mb_effective.mbe_type == MAC_BIBA_TYPE_EQUAL)
310105634Srwatson			return (1);
311105634Srwatson
312105634Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
313105634Srwatson		if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL)
314105634Srwatson			return (1);
315105634Srwatson		if (mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL)
316105637Srwatson			return (1);
317105634Srwatson	}
318105634Srwatson
319105634Srwatson	return (0);
320105634Srwatson}
321105634Srwatson
322105634Srwatsonstatic int
323106090Srwatsonmac_biba_subject_privileged(struct mac_biba *mac_biba)
324105634Srwatson{
325105634Srwatson
326105634Srwatson	KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAGS_BOTH) ==
327105634Srwatson	    MAC_BIBA_FLAGS_BOTH,
328106090Srwatson	    ("mac_biba_subject_privileged: subject doesn't have both labels"));
329105634Srwatson
330132232Srwatson	/* If the effective is EQUAL, it's ok. */
331132232Srwatson	if (mac_biba->mb_effective.mbe_type == MAC_BIBA_TYPE_EQUAL)
332105634Srwatson		return (0);
333105634Srwatson
334105634Srwatson	/* If either range endpoint is EQUAL, it's ok. */
335105634Srwatson	if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL ||
336105634Srwatson	    mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL)
337105634Srwatson		return (0);
338105634Srwatson
339105634Srwatson	/* If the range is low-high, it's ok. */
340105634Srwatson	if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_LOW &&
341105634Srwatson	    mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_HIGH)
342105634Srwatson		return (0);
343105634Srwatson
344105634Srwatson	/* It's not ok. */
345105634Srwatson	return (EPERM);
346105634Srwatson}
347105634Srwatson
348106091Srwatsonstatic int
349132232Srwatsonmac_biba_high_effective(struct mac_biba *mac_biba)
350105988Srwatson{
351105988Srwatson
352132232Srwatson	KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
353132232Srwatson	    ("mac_biba_equal_effective: mac_biba not effective"));
354105988Srwatson
355132232Srwatson	return (mac_biba->mb_effective.mbe_type == MAC_BIBA_TYPE_HIGH);
356105988Srwatson}
357105988Srwatson
358105634Srwatsonstatic int
359101099Srwatsonmac_biba_valid(struct mac_biba *mac_biba)
360101099Srwatson{
361101099Srwatson
362132232Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
363132232Srwatson		switch (mac_biba->mb_effective.mbe_type) {
364101099Srwatson		case MAC_BIBA_TYPE_GRADE:
365101099Srwatson			break;
366101099Srwatson
367101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
368101099Srwatson		case MAC_BIBA_TYPE_HIGH:
369101099Srwatson		case MAC_BIBA_TYPE_LOW:
370132232Srwatson			if (mac_biba->mb_effective.mbe_grade != 0 ||
371105643Srwatson			    !MAC_BIBA_BIT_SET_EMPTY(
372132232Srwatson			    mac_biba->mb_effective.mbe_compartments))
373101099Srwatson				return (EINVAL);
374101099Srwatson			break;
375101099Srwatson
376101099Srwatson		default:
377101099Srwatson			return (EINVAL);
378101099Srwatson		}
379101099Srwatson	} else {
380132232Srwatson		if (mac_biba->mb_effective.mbe_type != MAC_BIBA_TYPE_UNDEF)
381101099Srwatson			return (EINVAL);
382101099Srwatson	}
383101099Srwatson
384101099Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
385101099Srwatson		switch (mac_biba->mb_rangelow.mbe_type) {
386101099Srwatson		case MAC_BIBA_TYPE_GRADE:
387101099Srwatson			break;
388101099Srwatson
389101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
390101099Srwatson		case MAC_BIBA_TYPE_HIGH:
391101099Srwatson		case MAC_BIBA_TYPE_LOW:
392105643Srwatson			if (mac_biba->mb_rangelow.mbe_grade != 0 ||
393105643Srwatson			    !MAC_BIBA_BIT_SET_EMPTY(
394105643Srwatson			    mac_biba->mb_rangelow.mbe_compartments))
395101099Srwatson				return (EINVAL);
396101099Srwatson			break;
397101099Srwatson
398101099Srwatson		default:
399101099Srwatson			return (EINVAL);
400101099Srwatson		}
401101099Srwatson
402101099Srwatson		switch (mac_biba->mb_rangehigh.mbe_type) {
403101099Srwatson		case MAC_BIBA_TYPE_GRADE:
404101099Srwatson			break;
405101099Srwatson
406101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
407101099Srwatson		case MAC_BIBA_TYPE_HIGH:
408101099Srwatson		case MAC_BIBA_TYPE_LOW:
409105643Srwatson			if (mac_biba->mb_rangehigh.mbe_grade != 0 ||
410105643Srwatson			    !MAC_BIBA_BIT_SET_EMPTY(
411105643Srwatson			    mac_biba->mb_rangehigh.mbe_compartments))
412101099Srwatson				return (EINVAL);
413101099Srwatson			break;
414101099Srwatson
415101099Srwatson		default:
416101099Srwatson			return (EINVAL);
417101099Srwatson		}
418101099Srwatson		if (!mac_biba_dominate_element(&mac_biba->mb_rangehigh,
419101099Srwatson		    &mac_biba->mb_rangelow))
420101099Srwatson			return (EINVAL);
421101099Srwatson	} else {
422101099Srwatson		if (mac_biba->mb_rangelow.mbe_type != MAC_BIBA_TYPE_UNDEF ||
423101099Srwatson		    mac_biba->mb_rangehigh.mbe_type != MAC_BIBA_TYPE_UNDEF)
424101099Srwatson			return (EINVAL);
425101099Srwatson	}
426101099Srwatson
427101099Srwatson	return (0);
428101099Srwatson}
429101099Srwatson
430101099Srwatsonstatic void
431101099Srwatsonmac_biba_set_range(struct mac_biba *mac_biba, u_short typelow,
432105643Srwatson    u_short gradelow, u_char *compartmentslow, u_short typehigh,
433105643Srwatson    u_short gradehigh, u_char *compartmentshigh)
434101099Srwatson{
435101099Srwatson
436101099Srwatson	mac_biba->mb_rangelow.mbe_type = typelow;
437101099Srwatson	mac_biba->mb_rangelow.mbe_grade = gradelow;
438105643Srwatson	if (compartmentslow != NULL)
439105643Srwatson		memcpy(mac_biba->mb_rangelow.mbe_compartments,
440105643Srwatson		    compartmentslow,
441105643Srwatson		    sizeof(mac_biba->mb_rangelow.mbe_compartments));
442101099Srwatson	mac_biba->mb_rangehigh.mbe_type = typehigh;
443101099Srwatson	mac_biba->mb_rangehigh.mbe_grade = gradehigh;
444105643Srwatson	if (compartmentshigh != NULL)
445105643Srwatson		memcpy(mac_biba->mb_rangehigh.mbe_compartments,
446105643Srwatson		    compartmentshigh,
447105643Srwatson		    sizeof(mac_biba->mb_rangehigh.mbe_compartments));
448101099Srwatson	mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE;
449101099Srwatson}
450101099Srwatson
451101099Srwatsonstatic void
452132232Srwatsonmac_biba_set_effective(struct mac_biba *mac_biba, u_short type, u_short grade,
453105643Srwatson    u_char *compartments)
454101099Srwatson{
455101099Srwatson
456132232Srwatson	mac_biba->mb_effective.mbe_type = type;
457132232Srwatson	mac_biba->mb_effective.mbe_grade = grade;
458105643Srwatson	if (compartments != NULL)
459132232Srwatson		memcpy(mac_biba->mb_effective.mbe_compartments, compartments,
460132232Srwatson		    sizeof(mac_biba->mb_effective.mbe_compartments));
461132232Srwatson	mac_biba->mb_flags |= MAC_BIBA_FLAG_EFFECTIVE;
462101099Srwatson}
463101099Srwatson
464101099Srwatsonstatic void
465101099Srwatsonmac_biba_copy_range(struct mac_biba *labelfrom, struct mac_biba *labelto)
466101099Srwatson{
467105643Srwatson
468101099Srwatson	KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_RANGE) != 0,
469101099Srwatson	    ("mac_biba_copy_range: labelfrom not range"));
470101099Srwatson
471101099Srwatson	labelto->mb_rangelow = labelfrom->mb_rangelow;
472101099Srwatson	labelto->mb_rangehigh = labelfrom->mb_rangehigh;
473101099Srwatson	labelto->mb_flags |= MAC_BIBA_FLAG_RANGE;
474101099Srwatson}
475101099Srwatson
476101099Srwatsonstatic void
477132232Srwatsonmac_biba_copy_effective(struct mac_biba *labelfrom, struct mac_biba *labelto)
478101099Srwatson{
479101099Srwatson
480132232Srwatson	KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
481132232Srwatson	    ("mac_biba_copy_effective: labelfrom not effective"));
482101099Srwatson
483132232Srwatson	labelto->mb_effective = labelfrom->mb_effective;
484132232Srwatson	labelto->mb_flags |= MAC_BIBA_FLAG_EFFECTIVE;
485101099Srwatson}
486101099Srwatson
487105656Srwatsonstatic void
488105656Srwatsonmac_biba_copy(struct mac_biba *source, struct mac_biba *dest)
489105656Srwatson{
490105656Srwatson
491132232Srwatson	if (source->mb_flags & MAC_BIBA_FLAG_EFFECTIVE)
492132232Srwatson		mac_biba_copy_effective(source, dest);
493105656Srwatson	if (source->mb_flags & MAC_BIBA_FLAG_RANGE)
494105656Srwatson		mac_biba_copy_range(source, dest);
495105656Srwatson}
496105656Srwatson
497101099Srwatson/*
498101099Srwatson * Policy module operations.
499101099Srwatson */
500101099Srwatsonstatic void
501101099Srwatsonmac_biba_init(struct mac_policy_conf *conf)
502101099Srwatson{
503101099Srwatson
504122879Srwatson	zone_biba = uma_zcreate("mac_biba", sizeof(struct mac_biba), NULL,
505122879Srwatson	    NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
506101099Srwatson}
507101099Srwatson
508101099Srwatson/*
509101099Srwatson * Label operations.
510101099Srwatson */
511101099Srwatsonstatic void
512104514Srwatsonmac_biba_init_label(struct label *label)
513101099Srwatson{
514101099Srwatson
515132781Skan	SLOT_SET(label, biba_alloc(M_WAITOK));
516101099Srwatson}
517101099Srwatson
518101099Srwatsonstatic int
519104514Srwatsonmac_biba_init_label_waitcheck(struct label *label, int flag)
520101099Srwatson{
521101099Srwatson
522132781Skan	SLOT_SET(label, biba_alloc(flag));
523101099Srwatson	if (SLOT(label) == NULL)
524101099Srwatson		return (ENOMEM);
525101099Srwatson
526101099Srwatson	return (0);
527101099Srwatson}
528101099Srwatson
529101099Srwatsonstatic void
530104514Srwatsonmac_biba_destroy_label(struct label *label)
531101099Srwatson{
532101099Srwatson
533101099Srwatson	biba_free(SLOT(label));
534132781Skan	SLOT_SET(label, NULL);
535101099Srwatson}
536101099Srwatson
537105696Srwatson/*
538115497Srwatson * mac_biba_element_to_string() accepts an sbuf and Biba element.  It
539115497Srwatson * converts the Biba element to a string and stores the result in the
540115497Srwatson * sbuf; if there isn't space in the sbuf, -1 is returned.
541105696Srwatson */
542115497Srwatsonstatic int
543115497Srwatsonmac_biba_element_to_string(struct sbuf *sb, struct mac_biba_element *element)
544105696Srwatson{
545115497Srwatson	int i, first;
546105696Srwatson
547105696Srwatson	switch (element->mbe_type) {
548105696Srwatson	case MAC_BIBA_TYPE_HIGH:
549115497Srwatson		return (sbuf_printf(sb, "high"));
550105696Srwatson
551105696Srwatson	case MAC_BIBA_TYPE_LOW:
552115497Srwatson		return (sbuf_printf(sb, "low"));
553105696Srwatson
554105696Srwatson	case MAC_BIBA_TYPE_EQUAL:
555115497Srwatson		return (sbuf_printf(sb, "equal"));
556105696Srwatson
557105696Srwatson	case MAC_BIBA_TYPE_GRADE:
558115497Srwatson		if (sbuf_printf(sb, "%d", element->mbe_grade) == -1)
559115497Srwatson			return (-1);
560115497Srwatson
561115497Srwatson		first = 1;
562115497Srwatson		for (i = 1; i <= MAC_BIBA_MAX_COMPARTMENTS; i++) {
563115497Srwatson			if (MAC_BIBA_BIT_TEST(i, element->mbe_compartments)) {
564115497Srwatson				if (first) {
565115497Srwatson					if (sbuf_putc(sb, ':') == -1)
566115497Srwatson						return (-1);
567115497Srwatson					if (sbuf_printf(sb, "%d", i) == -1)
568115497Srwatson						return (-1);
569115497Srwatson					first = 0;
570115497Srwatson				} else {
571115497Srwatson					if (sbuf_printf(sb, "+%d", i) == -1)
572115497Srwatson						return (-1);
573115497Srwatson				}
574115497Srwatson			}
575105696Srwatson		}
576115497Srwatson		return (0);
577105696Srwatson
578105696Srwatson	default:
579105696Srwatson		panic("mac_biba_element_to_string: invalid type (%d)",
580105696Srwatson		    element->mbe_type);
581105696Srwatson	}
582105696Srwatson}
583105696Srwatson
584115497Srwatson/*
585116701Srwatson * mac_biba_to_string() converts a Biba label to a string, and places
586116701Srwatson * the results in the passed sbuf.  It returns 0 on success, or EINVAL
587116701Srwatson * if there isn't room in the sbuf.  Note: the sbuf will be modified
588116701Srwatson * even in a failure case, so the caller may need to revert the sbuf
589116701Srwatson * by restoring the offset if that's undesired.
590115497Srwatson */
591101099Srwatsonstatic int
592116701Srwatsonmac_biba_to_string(struct sbuf *sb, struct mac_biba *mac_biba)
593101099Srwatson{
594105696Srwatson
595132232Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
596132232Srwatson		if (mac_biba_element_to_string(sb, &mac_biba->mb_effective)
597115497Srwatson		    == -1)
598105696Srwatson			return (EINVAL);
599105696Srwatson	}
600105696Srwatson
601105696Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
602116701Srwatson		if (sbuf_putc(sb, '(') == -1)
603105696Srwatson			return (EINVAL);
604105696Srwatson
605116701Srwatson		if (mac_biba_element_to_string(sb, &mac_biba->mb_rangelow)
606115497Srwatson		    == -1)
607105696Srwatson			return (EINVAL);
608105696Srwatson
609116701Srwatson		if (sbuf_putc(sb, '-') == -1)
610105696Srwatson			return (EINVAL);
611105696Srwatson
612116701Srwatson		if (mac_biba_element_to_string(sb, &mac_biba->mb_rangehigh)
613115497Srwatson		    == -1)
614105696Srwatson			return (EINVAL);
615105696Srwatson
616116701Srwatson		if (sbuf_putc(sb, ')') == -1)
617105696Srwatson			return (EINVAL);
618105696Srwatson	}
619105696Srwatson
620105696Srwatson	return (0);
621105696Srwatson}
622105696Srwatson
623105696Srwatsonstatic int
624105696Srwatsonmac_biba_externalize_label(struct label *label, char *element_name,
625116701Srwatson    struct sbuf *sb, int *claimed)
626105696Srwatson{
627101099Srwatson	struct mac_biba *mac_biba;
628101099Srwatson
629105696Srwatson	if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0)
630105696Srwatson		return (0);
631105696Srwatson
632105696Srwatson	(*claimed)++;
633105696Srwatson
634101099Srwatson	mac_biba = SLOT(label);
635116701Srwatson	return (mac_biba_to_string(sb, mac_biba));
636105696Srwatson}
637105696Srwatson
638105696Srwatsonstatic int
639105696Srwatsonmac_biba_parse_element(struct mac_biba_element *element, char *string)
640101099Srwatson{
641115395Srwatson	char *compartment, *end, *grade;
642115395Srwatson	int value;
643105696Srwatson
644105696Srwatson	if (strcmp(string, "high") == 0 ||
645105696Srwatson	    strcmp(string, "hi") == 0) {
646105696Srwatson		element->mbe_type = MAC_BIBA_TYPE_HIGH;
647105696Srwatson		element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
648105696Srwatson	} else if (strcmp(string, "low") == 0 ||
649105696Srwatson	    strcmp(string, "lo") == 0) {
650105696Srwatson		element->mbe_type = MAC_BIBA_TYPE_LOW;
651105696Srwatson		element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
652105696Srwatson	} else if (strcmp(string, "equal") == 0 ||
653105696Srwatson	    strcmp(string, "eq") == 0) {
654105696Srwatson		element->mbe_type = MAC_BIBA_TYPE_EQUAL;
655105696Srwatson		element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
656105696Srwatson	} else {
657115395Srwatson		element->mbe_type = MAC_BIBA_TYPE_GRADE;
658105696Srwatson
659115395Srwatson		/*
660115395Srwatson		 * Numeric grade piece of the element.
661115395Srwatson		 */
662115395Srwatson		grade = strsep(&string, ":");
663115395Srwatson		value = strtol(grade, &end, 10);
664115395Srwatson		if (end == grade || *end != '\0')
665105696Srwatson			return (EINVAL);
666115395Srwatson		if (value < 0 || value > 65535)
667115395Srwatson			return (EINVAL);
668115395Srwatson		element->mbe_grade = value;
669105696Srwatson
670115395Srwatson		/*
671115395Srwatson		 * Optional compartment piece of the element.  If none
672115395Srwatson		 * are included, we assume that the label has no
673115395Srwatson		 * compartments.
674115395Srwatson		 */
675115395Srwatson		if (string == NULL)
676115395Srwatson			return (0);
677115395Srwatson		if (*string == '\0')
678115395Srwatson			return (0);
679105696Srwatson
680115395Srwatson		while ((compartment = strsep(&string, "+")) != NULL) {
681115395Srwatson			value = strtol(compartment, &end, 10);
682115395Srwatson			if (compartment == end || *end != '\0')
683105696Srwatson				return (EINVAL);
684115395Srwatson			if (value < 1 || value > MAC_BIBA_MAX_COMPARTMENTS)
685105696Srwatson				return (EINVAL);
686115395Srwatson			MAC_BIBA_BIT_SET(value, element->mbe_compartments);
687105696Srwatson		}
688105696Srwatson	}
689105696Srwatson
690105696Srwatson	return (0);
691105696Srwatson}
692105696Srwatson
693105696Srwatson/*
694105696Srwatson * Note: destructively consumes the string, make a local copy before
695105696Srwatson * calling if that's a problem.
696105696Srwatson */
697105696Srwatsonstatic int
698105696Srwatsonmac_biba_parse(struct mac_biba *mac_biba, char *string)
699105696Srwatson{
700132232Srwatson	char *rangehigh, *rangelow, *effective;
701101099Srwatson	int error;
702101099Srwatson
703132232Srwatson	effective = strsep(&string, "(");
704132232Srwatson	if (*effective == '\0')
705132232Srwatson		effective = NULL;
706115395Srwatson
707115395Srwatson	if (string != NULL) {
708115395Srwatson		rangelow = strsep(&string, "-");
709115395Srwatson		if (string == NULL)
710105696Srwatson			return (EINVAL);
711115395Srwatson		rangehigh = strsep(&string, ")");
712115395Srwatson		if (string == NULL)
713105696Srwatson			return (EINVAL);
714115395Srwatson		if (*string != '\0')
715105696Srwatson			return (EINVAL);
716115395Srwatson	} else {
717115395Srwatson		rangelow = NULL;
718115395Srwatson		rangehigh = NULL;
719105696Srwatson	}
720115395Srwatson
721105696Srwatson	KASSERT((rangelow != NULL && rangehigh != NULL) ||
722105696Srwatson	    (rangelow == NULL && rangehigh == NULL),
723115395Srwatson	    ("mac_biba_parse: range mismatch"));
724101099Srwatson
725105696Srwatson	bzero(mac_biba, sizeof(*mac_biba));
726132232Srwatson	if (effective != NULL) {
727132232Srwatson		error = mac_biba_parse_element(&mac_biba->mb_effective, effective);
728105696Srwatson		if (error)
729105696Srwatson			return (error);
730132232Srwatson		mac_biba->mb_flags |= MAC_BIBA_FLAG_EFFECTIVE;
731105696Srwatson	}
732105696Srwatson
733105696Srwatson	if (rangelow != NULL) {
734105696Srwatson		error = mac_biba_parse_element(&mac_biba->mb_rangelow,
735105696Srwatson		    rangelow);
736105696Srwatson		if (error)
737105696Srwatson			return (error);
738105696Srwatson		error = mac_biba_parse_element(&mac_biba->mb_rangehigh,
739105696Srwatson		    rangehigh);
740105696Srwatson		if (error)
741105696Srwatson			return (error);
742105696Srwatson		mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE;
743105696Srwatson	}
744105696Srwatson
745101099Srwatson	error = mac_biba_valid(mac_biba);
746101099Srwatson	if (error)
747101099Srwatson		return (error);
748101099Srwatson
749105696Srwatson	return (0);
750105696Srwatson}
751101099Srwatson
752105696Srwatsonstatic int
753105696Srwatsonmac_biba_internalize_label(struct label *label, char *element_name,
754105696Srwatson    char *element_data, int *claimed)
755105696Srwatson{
756105696Srwatson	struct mac_biba *mac_biba, mac_biba_temp;
757105696Srwatson	int error;
758105696Srwatson
759105696Srwatson	if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0)
760105696Srwatson		return (0);
761105696Srwatson
762105696Srwatson	(*claimed)++;
763105696Srwatson
764105696Srwatson	error = mac_biba_parse(&mac_biba_temp, element_data);
765105696Srwatson	if (error)
766105696Srwatson		return (error);
767105696Srwatson
768105696Srwatson	mac_biba = SLOT(label);
769105696Srwatson	*mac_biba = mac_biba_temp;
770105696Srwatson
771101099Srwatson	return (0);
772101099Srwatson}
773101099Srwatson
774105696Srwatsonstatic void
775105696Srwatsonmac_biba_copy_label(struct label *src, struct label *dest)
776105696Srwatson{
777105696Srwatson
778105696Srwatson	*SLOT(dest) = *SLOT(src);
779105696Srwatson}
780105696Srwatson
781101099Srwatson/*
782101099Srwatson * Labeling event operations: file system objects, and things that look
783101099Srwatson * a lot like file system objects.
784101099Srwatson */
785101099Srwatsonstatic void
786147982Srwatsonmac_biba_create_devfs_device(struct ucred *cred, struct mount *mp,
787147982Srwatson    struct cdev *dev, struct devfs_dirent *devfs_dirent, struct label *label)
788101099Srwatson{
789101099Srwatson	struct mac_biba *mac_biba;
790101099Srwatson	int biba_type;
791101099Srwatson
792101099Srwatson	mac_biba = SLOT(label);
793101099Srwatson	if (strcmp(dev->si_name, "null") == 0 ||
794101099Srwatson	    strcmp(dev->si_name, "zero") == 0 ||
795101099Srwatson	    strcmp(dev->si_name, "random") == 0 ||
796101099Srwatson	    strncmp(dev->si_name, "fd/", strlen("fd/")) == 0)
797101099Srwatson		biba_type = MAC_BIBA_TYPE_EQUAL;
798105606Srwatson	else if (ptys_equal &&
799105606Srwatson	    (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 ||
800105606Srwatson	    strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0))
801105606Srwatson		biba_type = MAC_BIBA_TYPE_EQUAL;
802101099Srwatson	else
803101099Srwatson		biba_type = MAC_BIBA_TYPE_HIGH;
804132232Srwatson	mac_biba_set_effective(mac_biba, biba_type, 0, NULL);
805101099Srwatson}
806101099Srwatson
807101099Srwatsonstatic void
808107698Srwatsonmac_biba_create_devfs_directory(struct mount *mp, char *dirname,
809107698Srwatson    int dirnamelen, struct devfs_dirent *devfs_dirent, struct label *label)
810101099Srwatson{
811101099Srwatson	struct mac_biba *mac_biba;
812101099Srwatson
813101099Srwatson	mac_biba = SLOT(label);
814132232Srwatson	mac_biba_set_effective(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
815101099Srwatson}
816101099Srwatson
817101099Srwatsonstatic void
818107698Srwatsonmac_biba_create_devfs_symlink(struct ucred *cred, struct mount *mp,
819107698Srwatson    struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de,
820122563Srwatson    struct label *delabel)
821104535Srwatson{
822104535Srwatson	struct mac_biba *source, *dest;
823104535Srwatson
824122524Srwatson	source = SLOT(cred->cr_label);
825104535Srwatson	dest = SLOT(delabel);
826104535Srwatson
827132232Srwatson	mac_biba_copy_effective(source, dest);
828104535Srwatson}
829104535Srwatson
830104535Srwatsonstatic void
831101099Srwatsonmac_biba_create_mount(struct ucred *cred, struct mount *mp,
832101099Srwatson    struct label *mntlabel, struct label *fslabel)
833101099Srwatson{
834101099Srwatson	struct mac_biba *source, *dest;
835101099Srwatson
836122524Srwatson	source = SLOT(cred->cr_label);
837101099Srwatson	dest = SLOT(mntlabel);
838132232Srwatson	mac_biba_copy_effective(source, dest);
839101099Srwatson	dest = SLOT(fslabel);
840132232Srwatson	mac_biba_copy_effective(source, dest);
841101099Srwatson}
842101099Srwatson
843101099Srwatsonstatic void
844101099Srwatsonmac_biba_relabel_vnode(struct ucred *cred, struct vnode *vp,
845101099Srwatson    struct label *vnodelabel, struct label *label)
846101099Srwatson{
847101099Srwatson	struct mac_biba *source, *dest;
848101099Srwatson
849101099Srwatson	source = SLOT(label);
850101099Srwatson	dest = SLOT(vnodelabel);
851101099Srwatson
852105656Srwatson	mac_biba_copy(source, dest);
853101099Srwatson}
854101099Srwatson
855101099Srwatsonstatic void
856107698Srwatsonmac_biba_update_devfsdirent(struct mount *mp,
857107698Srwatson    struct devfs_dirent *devfs_dirent, struct label *direntlabel,
858107698Srwatson    struct vnode *vp, struct label *vnodelabel)
859101099Srwatson{
860101099Srwatson	struct mac_biba *source, *dest;
861101099Srwatson
862101099Srwatson	source = SLOT(vnodelabel);
863101099Srwatson	dest = SLOT(direntlabel);
864101099Srwatson
865105656Srwatson	mac_biba_copy(source, dest);
866101099Srwatson}
867101099Srwatson
868101099Srwatsonstatic void
869105988Srwatsonmac_biba_associate_vnode_devfs(struct mount *mp, struct label *fslabel,
870105988Srwatson    struct devfs_dirent *de, struct label *delabel, struct vnode *vp,
871105988Srwatson    struct label *vlabel)
872101099Srwatson{
873101099Srwatson	struct mac_biba *source, *dest;
874101099Srwatson
875105988Srwatson	source = SLOT(delabel);
876105988Srwatson	dest = SLOT(vlabel);
877101099Srwatson
878132232Srwatson	mac_biba_copy_effective(source, dest);
879101099Srwatson}
880101099Srwatson
881101099Srwatsonstatic int
882105988Srwatsonmac_biba_associate_vnode_extattr(struct mount *mp, struct label *fslabel,
883105988Srwatson    struct vnode *vp, struct label *vlabel)
884101099Srwatson{
885105988Srwatson	struct mac_biba temp, *source, *dest;
886106354Smux	int buflen, error;
887101099Srwatson
888105988Srwatson	source = SLOT(fslabel);
889105988Srwatson	dest = SLOT(vlabel);
890101099Srwatson
891105988Srwatson	buflen = sizeof(temp);
892105988Srwatson	bzero(&temp, buflen);
893105988Srwatson
894105988Srwatson	error = vn_extattr_get(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
895105988Srwatson	    MAC_BIBA_EXTATTR_NAME, &buflen, (char *) &temp, curthread);
896105988Srwatson	if (error == ENOATTR || error == EOPNOTSUPP) {
897105988Srwatson		/* Fall back to the fslabel. */
898132232Srwatson		mac_biba_copy_effective(source, dest);
899105988Srwatson		return (0);
900105988Srwatson	} else if (error)
901101099Srwatson		return (error);
902101099Srwatson
903105988Srwatson	if (buflen != sizeof(temp)) {
904105988Srwatson		printf("mac_biba_associate_vnode_extattr: bad size %d\n",
905105988Srwatson		    buflen);
906105988Srwatson		return (EPERM);
907105988Srwatson	}
908105988Srwatson	if (mac_biba_valid(&temp) != 0) {
909105988Srwatson		printf("mac_biba_associate_vnode_extattr: invalid\n");
910105988Srwatson		return (EPERM);
911105988Srwatson	}
912132232Srwatson	if ((temp.mb_flags & MAC_BIBA_FLAGS_BOTH) != MAC_BIBA_FLAG_EFFECTIVE) {
913132232Srwatson		printf("mac_biba_associate_vnode_extattr: not effective\n");
914105988Srwatson		return (EPERM);
915105988Srwatson	}
916101099Srwatson
917132232Srwatson	mac_biba_copy_effective(&temp, dest);
918101099Srwatson	return (0);
919101099Srwatson}
920101099Srwatson
921101099Srwatsonstatic void
922105988Srwatsonmac_biba_associate_vnode_singlelabel(struct mount *mp,
923105988Srwatson    struct label *fslabel, struct vnode *vp, struct label *vlabel)
924101099Srwatson{
925101099Srwatson	struct mac_biba *source, *dest;
926101099Srwatson
927101099Srwatson	source = SLOT(fslabel);
928105988Srwatson	dest = SLOT(vlabel);
929101099Srwatson
930132232Srwatson	mac_biba_copy_effective(source, dest);
931101099Srwatson}
932101099Srwatson
933105988Srwatsonstatic int
934105988Srwatsonmac_biba_create_vnode_extattr(struct ucred *cred, struct mount *mp,
935105988Srwatson    struct label *fslabel, struct vnode *dvp, struct label *dlabel,
936105988Srwatson    struct vnode *vp, struct label *vlabel, struct componentname *cnp)
937105988Srwatson{
938105988Srwatson	struct mac_biba *source, *dest, temp;
939105988Srwatson	size_t buflen;
940105988Srwatson	int error;
941105988Srwatson
942105988Srwatson	buflen = sizeof(temp);
943105988Srwatson	bzero(&temp, buflen);
944105988Srwatson
945122524Srwatson	source = SLOT(cred->cr_label);
946105988Srwatson	dest = SLOT(vlabel);
947132232Srwatson	mac_biba_copy_effective(source, &temp);
948105988Srwatson
949105988Srwatson	error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
950105988Srwatson	    MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread);
951105988Srwatson	if (error == 0)
952132232Srwatson		mac_biba_copy_effective(source, dest);
953105988Srwatson	return (error);
954105988Srwatson}
955105988Srwatson
956105988Srwatsonstatic int
957105988Srwatsonmac_biba_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp,
958105988Srwatson    struct label *vlabel, struct label *intlabel)
959105988Srwatson{
960105988Srwatson	struct mac_biba *source, temp;
961105988Srwatson	size_t buflen;
962105988Srwatson	int error;
963105988Srwatson
964105988Srwatson	buflen = sizeof(temp);
965105988Srwatson	bzero(&temp, buflen);
966105988Srwatson
967105988Srwatson	source = SLOT(intlabel);
968132232Srwatson	if ((source->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) == 0)
969105988Srwatson		return (0);
970105988Srwatson
971132232Srwatson	mac_biba_copy_effective(source, &temp);
972105988Srwatson
973105988Srwatson	error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
974105988Srwatson	    MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread);
975105988Srwatson	return (error);
976105988Srwatson}
977105988Srwatson
978101099Srwatson/*
979101099Srwatson * Labeling event operations: IPC object.
980101099Srwatson */
981101099Srwatsonstatic void
982122875Srwatsonmac_biba_create_inpcb_from_socket(struct socket *so, struct label *solabel,
983122875Srwatson    struct inpcb *inp, struct label *inplabel)
984122875Srwatson{
985122875Srwatson	struct mac_biba *source, *dest;
986122875Srwatson
987122875Srwatson	source = SLOT(solabel);
988122875Srwatson	dest = SLOT(inplabel);
989122875Srwatson
990132232Srwatson	mac_biba_copy_effective(source, dest);
991122875Srwatson}
992122875Srwatson
993122875Srwatsonstatic void
994101099Srwatsonmac_biba_create_mbuf_from_socket(struct socket *so, struct label *socketlabel,
995101099Srwatson    struct mbuf *m, struct label *mbuflabel)
996101099Srwatson{
997101099Srwatson	struct mac_biba *source, *dest;
998101099Srwatson
999101099Srwatson	source = SLOT(socketlabel);
1000101099Srwatson	dest = SLOT(mbuflabel);
1001101099Srwatson
1002132232Srwatson	mac_biba_copy_effective(source, dest);
1003101099Srwatson}
1004101099Srwatson
1005101099Srwatsonstatic void
1006101099Srwatsonmac_biba_create_socket(struct ucred *cred, struct socket *socket,
1007101099Srwatson    struct label *socketlabel)
1008101099Srwatson{
1009101099Srwatson	struct mac_biba *source, *dest;
1010101099Srwatson
1011122524Srwatson	source = SLOT(cred->cr_label);
1012101099Srwatson	dest = SLOT(socketlabel);
1013101099Srwatson
1014132232Srwatson	mac_biba_copy_effective(source, dest);
1015101099Srwatson}
1016101099Srwatson
1017101099Srwatsonstatic void
1018125293Srwatsonmac_biba_create_pipe(struct ucred *cred, struct pipepair *pp,
1019101099Srwatson    struct label *pipelabel)
1020101099Srwatson{
1021101099Srwatson	struct mac_biba *source, *dest;
1022101099Srwatson
1023122524Srwatson	source = SLOT(cred->cr_label);
1024101099Srwatson	dest = SLOT(pipelabel);
1025101099Srwatson
1026132232Srwatson	mac_biba_copy_effective(source, dest);
1027101099Srwatson}
1028101099Srwatson
1029101099Srwatsonstatic void
1030145855Srwatsonmac_biba_create_posix_sem(struct ucred *cred, struct ksem *ksemptr,
1031145855Srwatson    struct label *ks_label)
1032145855Srwatson{
1033145855Srwatson	struct mac_biba *source, *dest;
1034145855Srwatson
1035145855Srwatson	source = SLOT(cred->cr_label);
1036145855Srwatson	dest = SLOT(ks_label);
1037145855Srwatson
1038145855Srwatson	mac_biba_copy_effective(source, dest);
1039145855Srwatson}
1040145855Srwatson
1041145855Srwatsonstatic void
1042101099Srwatsonmac_biba_create_socket_from_socket(struct socket *oldsocket,
1043101099Srwatson    struct label *oldsocketlabel, struct socket *newsocket,
1044101099Srwatson    struct label *newsocketlabel)
1045101099Srwatson{
1046101099Srwatson	struct mac_biba *source, *dest;
1047101099Srwatson
1048101099Srwatson	source = SLOT(oldsocketlabel);
1049101099Srwatson	dest = SLOT(newsocketlabel);
1050101099Srwatson
1051132232Srwatson	mac_biba_copy_effective(source, dest);
1052101099Srwatson}
1053101099Srwatson
1054101099Srwatsonstatic void
1055101099Srwatsonmac_biba_relabel_socket(struct ucred *cred, struct socket *socket,
1056101099Srwatson    struct label *socketlabel, struct label *newlabel)
1057101099Srwatson{
1058101099Srwatson	struct mac_biba *source, *dest;
1059101099Srwatson
1060101099Srwatson	source = SLOT(newlabel);
1061101099Srwatson	dest = SLOT(socketlabel);
1062101099Srwatson
1063105656Srwatson	mac_biba_copy(source, dest);
1064101099Srwatson}
1065101099Srwatson
1066101099Srwatsonstatic void
1067125293Srwatsonmac_biba_relabel_pipe(struct ucred *cred, struct pipepair *pp,
1068101099Srwatson    struct label *pipelabel, struct label *newlabel)
1069101099Srwatson{
1070101099Srwatson	struct mac_biba *source, *dest;
1071101099Srwatson
1072101099Srwatson	source = SLOT(newlabel);
1073101099Srwatson	dest = SLOT(pipelabel);
1074101099Srwatson
1075105656Srwatson	mac_biba_copy(source, dest);
1076101099Srwatson}
1077101099Srwatson
1078101099Srwatsonstatic void
1079101099Srwatsonmac_biba_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel,
1080101099Srwatson    struct socket *socket, struct label *socketpeerlabel)
1081101099Srwatson{
1082101099Srwatson	struct mac_biba *source, *dest;
1083101099Srwatson
1084101099Srwatson	source = SLOT(mbuflabel);
1085101099Srwatson	dest = SLOT(socketpeerlabel);
1086101099Srwatson
1087132232Srwatson	mac_biba_copy_effective(source, dest);
1088101099Srwatson}
1089101099Srwatson
1090101099Srwatson/*
1091140628Srwatson * Labeling event operations: System V IPC objects.
1092140628Srwatson */
1093140628Srwatson
1094140628Srwatsonstatic void
1095140628Srwatsonmac_biba_create_sysv_msgmsg(struct ucred *cred, struct msqid_kernel *msqkptr,
1096140628Srwatson    struct label *msqlabel, struct msg *msgptr, struct label *msglabel)
1097140628Srwatson{
1098140628Srwatson	struct mac_biba *source, *dest;
1099140628Srwatson
1100140628Srwatson	/* Ignore the msgq label */
1101140628Srwatson	source = SLOT(cred->cr_label);
1102140628Srwatson	dest = SLOT(msglabel);
1103140628Srwatson
1104140628Srwatson	mac_biba_copy_effective(source, dest);
1105140628Srwatson}
1106140628Srwatson
1107140628Srwatsonstatic void
1108140628Srwatsonmac_biba_create_sysv_msgqueue(struct ucred *cred,
1109140628Srwatson    struct msqid_kernel *msqkptr, struct label *msqlabel)
1110140628Srwatson{
1111140628Srwatson	struct mac_biba *source, *dest;
1112140628Srwatson
1113140628Srwatson	source = SLOT(cred->cr_label);
1114140628Srwatson	dest = SLOT(msqlabel);
1115140628Srwatson
1116140628Srwatson	mac_biba_copy_effective(source, dest);
1117140628Srwatson}
1118140628Srwatson
1119140628Srwatsonstatic void
1120147091Srwatsonmac_biba_create_sysv_sem(struct ucred *cred, struct semid_kernel *semakptr,
1121140628Srwatson    struct label *semalabel)
1122140628Srwatson{
1123140628Srwatson	struct mac_biba *source, *dest;
1124140628Srwatson
1125140628Srwatson	source = SLOT(cred->cr_label);
1126140628Srwatson	dest = SLOT(semalabel);
1127140628Srwatson
1128140628Srwatson	mac_biba_copy_effective(source, dest);
1129140628Srwatson}
1130140628Srwatson
1131140628Srwatsonstatic void
1132140628Srwatsonmac_biba_create_sysv_shm(struct ucred *cred, struct shmid_kernel *shmsegptr,
1133140628Srwatson    struct label *shmlabel)
1134140628Srwatson{
1135140628Srwatson	struct mac_biba *source, *dest;
1136140628Srwatson
1137140628Srwatson	source = SLOT(cred->cr_label);
1138140628Srwatson	dest = SLOT(shmlabel);
1139140628Srwatson
1140140628Srwatson	mac_biba_copy_effective(source, dest);
1141140628Srwatson}
1142140628Srwatson
1143140628Srwatson/*
1144101099Srwatson * Labeling event operations: network objects.
1145101099Srwatson */
1146101099Srwatsonstatic void
1147101099Srwatsonmac_biba_set_socket_peer_from_socket(struct socket *oldsocket,
1148101099Srwatson    struct label *oldsocketlabel, struct socket *newsocket,
1149101099Srwatson    struct label *newsocketpeerlabel)
1150101099Srwatson{
1151101099Srwatson	struct mac_biba *source, *dest;
1152101099Srwatson
1153101099Srwatson	source = SLOT(oldsocketlabel);
1154101099Srwatson	dest = SLOT(newsocketpeerlabel);
1155101099Srwatson
1156132232Srwatson	mac_biba_copy_effective(source, dest);
1157101099Srwatson}
1158101099Srwatson
1159101099Srwatsonstatic void
1160101099Srwatsonmac_biba_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d,
1161101099Srwatson    struct label *bpflabel)
1162101099Srwatson{
1163101099Srwatson	struct mac_biba *source, *dest;
1164101099Srwatson
1165122524Srwatson	source = SLOT(cred->cr_label);
1166101099Srwatson	dest = SLOT(bpflabel);
1167101099Srwatson
1168132232Srwatson	mac_biba_copy_effective(source, dest);
1169101099Srwatson}
1170101099Srwatson
1171101099Srwatsonstatic void
1172101099Srwatsonmac_biba_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel)
1173101099Srwatson{
1174121816Sbrooks	char tifname[IFNAMSIZ], *p, *q;
1175101099Srwatson	char tiflist[sizeof(trusted_interfaces)];
1176101099Srwatson	struct mac_biba *dest;
1177110350Srwatson	int len, type;
1178101099Srwatson
1179101099Srwatson	dest = SLOT(ifnetlabel);
1180101099Srwatson
1181153927Scsjp	if (ifnet->if_type == IFT_LOOP || interfaces_equal != 0) {
1182110350Srwatson		type = MAC_BIBA_TYPE_EQUAL;
1183101099Srwatson		goto set;
1184101099Srwatson	}
1185101099Srwatson
1186101099Srwatson	if (trust_all_interfaces) {
1187110350Srwatson		type = MAC_BIBA_TYPE_HIGH;
1188101099Srwatson		goto set;
1189101099Srwatson	}
1190101099Srwatson
1191110350Srwatson	type = MAC_BIBA_TYPE_LOW;
1192101099Srwatson
1193101099Srwatson	if (trusted_interfaces[0] == '\0' ||
1194101099Srwatson	    !strvalid(trusted_interfaces, sizeof(trusted_interfaces)))
1195101099Srwatson		goto set;
1196101099Srwatson
1197106089Srwatson	bzero(tiflist, sizeof(tiflist));
1198101099Srwatson	for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++)
1199101099Srwatson		if(*p != ' ' && *p != '\t')
1200101099Srwatson			*q = *p;
1201101099Srwatson
1202101099Srwatson	for (p = q = tiflist;; p++) {
1203101099Srwatson		if (*p == ',' || *p == '\0') {
1204101099Srwatson			len = p - q;
1205101099Srwatson			if (len < IFNAMSIZ) {
1206101099Srwatson				bzero(tifname, sizeof(tifname));
1207101099Srwatson				bcopy(q, tifname, len);
1208121816Sbrooks				if (strcmp(tifname, ifnet->if_xname) == 0) {
1209110350Srwatson					type = MAC_BIBA_TYPE_HIGH;
1210101099Srwatson					break;
1211101099Srwatson				}
1212106089Srwatson			} else {
1213106089Srwatson				*p = '\0';
1214106089Srwatson				printf("mac_biba warning: interface name "
1215106089Srwatson				    "\"%s\" is too long (must be < %d)\n",
1216106089Srwatson				    q, IFNAMSIZ);
1217101099Srwatson			}
1218101099Srwatson			if (*p == '\0')
1219101099Srwatson				break;
1220101099Srwatson			q = p + 1;
1221101099Srwatson		}
1222101099Srwatson	}
1223101099Srwatsonset:
1224132232Srwatson	mac_biba_set_effective(dest, type, 0, NULL);
1225110350Srwatson	mac_biba_set_range(dest, type, 0, NULL, type, 0, NULL);
1226101099Srwatson}
1227101099Srwatson
1228101099Srwatsonstatic void
1229101099Srwatsonmac_biba_create_ipq(struct mbuf *fragment, struct label *fragmentlabel,
1230101099Srwatson    struct ipq *ipq, struct label *ipqlabel)
1231101099Srwatson{
1232101099Srwatson	struct mac_biba *source, *dest;
1233101099Srwatson
1234101099Srwatson	source = SLOT(fragmentlabel);
1235101099Srwatson	dest = SLOT(ipqlabel);
1236101099Srwatson
1237132232Srwatson	mac_biba_copy_effective(source, dest);
1238101099Srwatson}
1239101099Srwatson
1240101099Srwatsonstatic void
1241101099Srwatsonmac_biba_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel,
1242101099Srwatson    struct mbuf *datagram, struct label *datagramlabel)
1243101099Srwatson{
1244101099Srwatson	struct mac_biba *source, *dest;
1245101099Srwatson
1246101099Srwatson	source = SLOT(ipqlabel);
1247101099Srwatson	dest = SLOT(datagramlabel);
1248101099Srwatson
1249101099Srwatson	/* Just use the head, since we require them all to match. */
1250132232Srwatson	mac_biba_copy_effective(source, dest);
1251101099Srwatson}
1252101099Srwatson
1253101099Srwatsonstatic void
1254101099Srwatsonmac_biba_create_fragment(struct mbuf *datagram, struct label *datagramlabel,
1255101099Srwatson    struct mbuf *fragment, struct label *fragmentlabel)
1256101099Srwatson{
1257101099Srwatson	struct mac_biba *source, *dest;
1258101099Srwatson
1259101099Srwatson	source = SLOT(datagramlabel);
1260101099Srwatson	dest = SLOT(fragmentlabel);
1261101099Srwatson
1262132232Srwatson	mac_biba_copy_effective(source, dest);
1263101099Srwatson}
1264101099Srwatson
1265101099Srwatsonstatic void
1266123607Srwatsonmac_biba_create_mbuf_from_inpcb(struct inpcb *inp, struct label *inplabel,
1267123607Srwatson    struct mbuf *m, struct label *mlabel)
1268123607Srwatson{
1269123607Srwatson	struct mac_biba *source, *dest;
1270123607Srwatson
1271123607Srwatson	source = SLOT(inplabel);
1272123607Srwatson	dest = SLOT(mlabel);
1273123607Srwatson
1274132232Srwatson	mac_biba_copy_effective(source, dest);
1275123607Srwatson}
1276123607Srwatson
1277123607Srwatsonstatic void
1278101099Srwatsonmac_biba_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel,
1279101099Srwatson    struct mbuf *mbuf, struct label *mbuflabel)
1280101099Srwatson{
1281101099Srwatson	struct mac_biba *dest;
1282101099Srwatson
1283101099Srwatson	dest = SLOT(mbuflabel);
1284101099Srwatson
1285132232Srwatson	mac_biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1286101099Srwatson}
1287101099Srwatson
1288101099Srwatsonstatic void
1289101099Srwatsonmac_biba_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel,
1290101099Srwatson    struct mbuf *mbuf, struct label *mbuflabel)
1291101099Srwatson{
1292101099Srwatson	struct mac_biba *source, *dest;
1293101099Srwatson
1294101099Srwatson	source = SLOT(bpflabel);
1295101099Srwatson	dest = SLOT(mbuflabel);
1296101099Srwatson
1297132232Srwatson	mac_biba_copy_effective(source, dest);
1298101099Srwatson}
1299101099Srwatson
1300101099Srwatsonstatic void
1301101099Srwatsonmac_biba_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel,
1302101099Srwatson    struct mbuf *m, struct label *mbuflabel)
1303101099Srwatson{
1304101099Srwatson	struct mac_biba *source, *dest;
1305101099Srwatson
1306101099Srwatson	source = SLOT(ifnetlabel);
1307101099Srwatson	dest = SLOT(mbuflabel);
1308101099Srwatson
1309132232Srwatson	mac_biba_copy_effective(source, dest);
1310101099Srwatson}
1311101099Srwatson
1312101099Srwatsonstatic void
1313101099Srwatsonmac_biba_create_mbuf_multicast_encap(struct mbuf *oldmbuf,
1314101099Srwatson    struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel,
1315101099Srwatson    struct mbuf *newmbuf, struct label *newmbuflabel)
1316101099Srwatson{
1317101099Srwatson	struct mac_biba *source, *dest;
1318101099Srwatson
1319101099Srwatson	source = SLOT(oldmbuflabel);
1320101099Srwatson	dest = SLOT(newmbuflabel);
1321101099Srwatson
1322132232Srwatson	mac_biba_copy_effective(source, dest);
1323101099Srwatson}
1324101099Srwatson
1325101099Srwatsonstatic void
1326101099Srwatsonmac_biba_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel,
1327101099Srwatson    struct mbuf *newmbuf, struct label *newmbuflabel)
1328101099Srwatson{
1329101099Srwatson	struct mac_biba *source, *dest;
1330101099Srwatson
1331101099Srwatson	source = SLOT(oldmbuflabel);
1332101099Srwatson	dest = SLOT(newmbuflabel);
1333101099Srwatson
1334132232Srwatson	mac_biba_copy_effective(source, dest);
1335101099Srwatson}
1336101099Srwatson
1337101099Srwatsonstatic int
1338101099Srwatsonmac_biba_fragment_match(struct mbuf *fragment, struct label *fragmentlabel,
1339101099Srwatson    struct ipq *ipq, struct label *ipqlabel)
1340101099Srwatson{
1341101099Srwatson	struct mac_biba *a, *b;
1342101099Srwatson
1343101099Srwatson	a = SLOT(ipqlabel);
1344101099Srwatson	b = SLOT(fragmentlabel);
1345101099Srwatson
1346132232Srwatson	return (mac_biba_equal_effective(a, b));
1347101099Srwatson}
1348101099Srwatson
1349101099Srwatsonstatic void
1350101099Srwatsonmac_biba_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet,
1351101099Srwatson    struct label *ifnetlabel, struct label *newlabel)
1352101099Srwatson{
1353101099Srwatson	struct mac_biba *source, *dest;
1354101099Srwatson
1355101099Srwatson	source = SLOT(newlabel);
1356101099Srwatson	dest = SLOT(ifnetlabel);
1357101099Srwatson
1358105656Srwatson	mac_biba_copy(source, dest);
1359101099Srwatson}
1360101099Srwatson
1361101099Srwatsonstatic void
1362101099Srwatsonmac_biba_update_ipq(struct mbuf *fragment, struct label *fragmentlabel,
1363101099Srwatson    struct ipq *ipq, struct label *ipqlabel)
1364101099Srwatson{
1365101099Srwatson
1366101099Srwatson	/* NOOP: we only accept matching labels, so no need to update */
1367101099Srwatson}
1368101099Srwatson
1369122875Srwatsonstatic void
1370122875Srwatsonmac_biba_inpcb_sosetlabel(struct socket *so, struct label *solabel,
1371122875Srwatson    struct inpcb *inp, struct label *inplabel)
1372122875Srwatson{
1373122875Srwatson	struct mac_biba *source, *dest;
1374122875Srwatson
1375122875Srwatson	source = SLOT(solabel);
1376122875Srwatson	dest = SLOT(inplabel);
1377122875Srwatson
1378122875Srwatson	mac_biba_copy(source, dest);
1379122875Srwatson}
1380122875Srwatson
1381162238Scsjpstatic void
1382162238Scsjpmac_biba_create_mbuf_from_firewall(struct mbuf *m, struct label *label)
1383162238Scsjp{
1384162238Scsjp	struct mac_biba *dest;
1385162238Scsjp
1386162238Scsjp	dest = SLOT(label);
1387162238Scsjp
1388162238Scsjp	/* XXX: where is the label for the firewall really comming from? */
1389162238Scsjp	mac_biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1390162238Scsjp}
1391162238Scsjp
1392101099Srwatson/*
1393101099Srwatson * Labeling event operations: processes.
1394101099Srwatson */
1395101099Srwatsonstatic void
1396101099Srwatsonmac_biba_create_proc0(struct ucred *cred)
1397101099Srwatson{
1398101099Srwatson	struct mac_biba *dest;
1399101099Srwatson
1400122524Srwatson	dest = SLOT(cred->cr_label);
1401101099Srwatson
1402132232Srwatson	mac_biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1403105643Srwatson	mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL,
1404105643Srwatson	    MAC_BIBA_TYPE_HIGH, 0, NULL);
1405101099Srwatson}
1406101099Srwatson
1407101099Srwatsonstatic void
1408101099Srwatsonmac_biba_create_proc1(struct ucred *cred)
1409101099Srwatson{
1410101099Srwatson	struct mac_biba *dest;
1411101099Srwatson
1412122524Srwatson	dest = SLOT(cred->cr_label);
1413101099Srwatson
1414132232Srwatson	mac_biba_set_effective(dest, MAC_BIBA_TYPE_HIGH, 0, NULL);
1415105643Srwatson	mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL,
1416105643Srwatson	    MAC_BIBA_TYPE_HIGH, 0, NULL);
1417101099Srwatson}
1418101099Srwatson
1419101099Srwatsonstatic void
1420101099Srwatsonmac_biba_relabel_cred(struct ucred *cred, struct label *newlabel)
1421101099Srwatson{
1422101099Srwatson	struct mac_biba *source, *dest;
1423101099Srwatson
1424101099Srwatson	source = SLOT(newlabel);
1425122524Srwatson	dest = SLOT(cred->cr_label);
1426101099Srwatson
1427105656Srwatson	mac_biba_copy(source, dest);
1428101099Srwatson}
1429101099Srwatson
1430101099Srwatson/*
1431140628Srwatson * Label cleanup/flush operations
1432140628Srwatson */
1433140628Srwatsonstatic void
1434140628Srwatsonmac_biba_cleanup_sysv_msgmsg(struct label *msglabel)
1435140628Srwatson{
1436140628Srwatson
1437140628Srwatson	bzero(SLOT(msglabel), sizeof(struct mac_biba));
1438140628Srwatson}
1439140628Srwatson
1440140628Srwatsonstatic void
1441140628Srwatsonmac_biba_cleanup_sysv_msgqueue(struct label *msqlabel)
1442140628Srwatson{
1443140628Srwatson
1444140628Srwatson	bzero(SLOT(msqlabel), sizeof(struct mac_biba));
1445140628Srwatson}
1446140628Srwatson
1447140628Srwatsonstatic void
1448147091Srwatsonmac_biba_cleanup_sysv_sem(struct label *semalabel)
1449140628Srwatson{
1450140628Srwatson
1451140628Srwatson	bzero(SLOT(semalabel), sizeof(struct mac_biba));
1452140628Srwatson}
1453140628Srwatson
1454140628Srwatsonstatic void
1455140628Srwatsonmac_biba_cleanup_sysv_shm(struct label *shmlabel)
1456140628Srwatson{
1457140628Srwatson	bzero(SLOT(shmlabel), sizeof(struct mac_biba));
1458140628Srwatson}
1459140628Srwatson
1460140628Srwatson/*
1461101099Srwatson * Access control checks.
1462101099Srwatson */
1463101099Srwatsonstatic int
1464101099Srwatsonmac_biba_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel,
1465101099Srwatson    struct ifnet *ifnet, struct label *ifnetlabel)
1466101099Srwatson{
1467101099Srwatson	struct mac_biba *a, *b;
1468101099Srwatson
1469101099Srwatson	if (!mac_biba_enabled)
1470101099Srwatson		return (0);
1471101099Srwatson
1472101099Srwatson	a = SLOT(bpflabel);
1473101099Srwatson	b = SLOT(ifnetlabel);
1474101099Srwatson
1475132232Srwatson	if (mac_biba_equal_effective(a, b))
1476101099Srwatson		return (0);
1477101099Srwatson	return (EACCES);
1478101099Srwatson}
1479101099Srwatson
1480101099Srwatsonstatic int
1481101099Srwatsonmac_biba_check_cred_relabel(struct ucred *cred, struct label *newlabel)
1482101099Srwatson{
1483101099Srwatson	struct mac_biba *subj, *new;
1484105634Srwatson	int error;
1485101099Srwatson
1486122524Srwatson	subj = SLOT(cred->cr_label);
1487101099Srwatson	new = SLOT(newlabel);
1488101099Srwatson
1489101099Srwatson	/*
1490105634Srwatson	 * If there is a Biba label update for the credential, it may
1491132232Srwatson	 * be an update of the effective, range, or both.
1492101099Srwatson	 */
1493105634Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
1494105634Srwatson	if (error)
1495105634Srwatson		return (error);
1496101099Srwatson
1497101099Srwatson	/*
1498105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
1499101099Srwatson	 */
1500105634Srwatson	if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) {
1501105634Srwatson		/*
1502110351Srwatson		 * If the change request modifies both the Biba label
1503132232Srwatson		 * effective and range, check that the new effective will be
1504110351Srwatson		 * in the new range.
1505110351Srwatson		 */
1506110351Srwatson		if ((new->mb_flags & MAC_BIBA_FLAGS_BOTH) ==
1507110351Srwatson		    MAC_BIBA_FLAGS_BOTH &&
1508132232Srwatson		    !mac_biba_effective_in_range(new, new))
1509110351Srwatson			return (EINVAL);
1510110351Srwatson
1511110351Srwatson		/*
1512132232Srwatson		 * To change the Biba effective label on a credential, the
1513132232Srwatson		 * new effective label must be in the current range.
1514105634Srwatson		 */
1515132232Srwatson		if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE &&
1516132232Srwatson		    !mac_biba_effective_in_range(new, subj))
1517105634Srwatson			return (EPERM);
1518101099Srwatson
1519105634Srwatson		/*
1520105634Srwatson		 * To change the Biba range on a credential, the new
1521105634Srwatson		 * range label must be in the current range.
1522105634Srwatson		 */
1523105634Srwatson		if (new->mb_flags & MAC_BIBA_FLAG_RANGE &&
1524105634Srwatson		    !mac_biba_range_in_range(new, subj))
1525105634Srwatson			return (EPERM);
1526101099Srwatson
1527105634Srwatson		/*
1528105634Srwatson		 * To have EQUAL in any component of the new credential
1529105634Srwatson		 * Biba label, the subject must already have EQUAL in
1530105634Srwatson		 * their label.
1531105634Srwatson		 */
1532105634Srwatson		if (mac_biba_contains_equal(new)) {
1533106090Srwatson			error = mac_biba_subject_privileged(subj);
1534105634Srwatson			if (error)
1535105634Srwatson				return (error);
1536105634Srwatson		}
1537105634Srwatson	}
1538105634Srwatson
1539101099Srwatson	return (0);
1540101099Srwatson}
1541101099Srwatson
1542101099Srwatsonstatic int
1543101099Srwatsonmac_biba_check_cred_visible(struct ucred *u1, struct ucred *u2)
1544101099Srwatson{
1545101099Srwatson	struct mac_biba *subj, *obj;
1546101099Srwatson
1547101099Srwatson	if (!mac_biba_enabled)
1548101099Srwatson		return (0);
1549101099Srwatson
1550122524Srwatson	subj = SLOT(u1->cr_label);
1551122524Srwatson	obj = SLOT(u2->cr_label);
1552101099Srwatson
1553101099Srwatson	/* XXX: range */
1554132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
1555101099Srwatson		return (ESRCH);
1556101099Srwatson
1557101099Srwatson	return (0);
1558101099Srwatson}
1559101099Srwatson
1560101099Srwatsonstatic int
1561101099Srwatsonmac_biba_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet,
1562101099Srwatson    struct label *ifnetlabel, struct label *newlabel)
1563101099Srwatson{
1564101099Srwatson	struct mac_biba *subj, *new;
1565105634Srwatson	int error;
1566101099Srwatson
1567122524Srwatson	subj = SLOT(cred->cr_label);
1568101099Srwatson	new = SLOT(newlabel);
1569101099Srwatson
1570105634Srwatson	/*
1571105634Srwatson	 * If there is a Biba label update for the interface, it may
1572132232Srwatson	 * be an update of the effective, range, or both.
1573105634Srwatson	 */
1574105634Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
1575105634Srwatson	if (error)
1576105634Srwatson		return (error);
1577101099Srwatson
1578105634Srwatson	/*
1579106160Srwatson	 * Relabling network interfaces requires Biba privilege.
1580106160Srwatson	 */
1581106160Srwatson	error = mac_biba_subject_privileged(subj);
1582106160Srwatson	if (error)
1583106160Srwatson		return (error);
1584106160Srwatson
1585105634Srwatson	return (0);
1586101099Srwatson}
1587101099Srwatson
1588103759Srwatsonstatic int
1589101099Srwatsonmac_biba_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel,
1590101099Srwatson    struct mbuf *m, struct label *mbuflabel)
1591101099Srwatson{
1592101099Srwatson	struct mac_biba *p, *i;
1593103761Srwatson
1594101099Srwatson	if (!mac_biba_enabled)
1595101099Srwatson		return (0);
1596101099Srwatson
1597101099Srwatson	p = SLOT(mbuflabel);
1598101099Srwatson	i = SLOT(ifnetlabel);
1599103759Srwatson
1600132232Srwatson	return (mac_biba_effective_in_range(p, i) ? 0 : EACCES);
1601101099Srwatson}
1602101099Srwatson
1603101099Srwatsonstatic int
1604122875Srwatsonmac_biba_check_inpcb_deliver(struct inpcb *inp, struct label *inplabel,
1605122875Srwatson    struct mbuf *m, struct label *mlabel)
1606122875Srwatson{
1607122875Srwatson	struct mac_biba *p, *i;
1608122875Srwatson
1609122875Srwatson	if (!mac_biba_enabled)
1610122875Srwatson		return (0);
1611122875Srwatson
1612122875Srwatson	p = SLOT(mlabel);
1613122875Srwatson	i = SLOT(inplabel);
1614122875Srwatson
1615132232Srwatson	return (mac_biba_equal_effective(p, i) ? 0 : EACCES);
1616122875Srwatson}
1617122875Srwatson
1618122875Srwatsonstatic int
1619140628Srwatsonmac_biba_check_sysv_msgrcv(struct ucred *cred, struct msg *msgptr,
1620140628Srwatson    struct label *msglabel)
1621140628Srwatson{
1622140628Srwatson	struct mac_biba *subj, *obj;
1623140628Srwatson
1624140628Srwatson	if (!mac_biba_enabled)
1625140628Srwatson		return (0);
1626140628Srwatson
1627140628Srwatson	subj = SLOT(cred->cr_label);
1628140628Srwatson	obj = SLOT(msglabel);
1629140628Srwatson
1630140628Srwatson	if (!mac_biba_dominate_effective(obj, subj))
1631140628Srwatson		return (EACCES);
1632140628Srwatson
1633140628Srwatson	return (0);
1634140628Srwatson}
1635140628Srwatson
1636140628Srwatsonstatic int
1637140628Srwatsonmac_biba_check_sysv_msgrmid(struct ucred *cred, struct msg *msgptr,
1638140628Srwatson    struct label *msglabel)
1639140628Srwatson{
1640140628Srwatson	struct mac_biba *subj, *obj;
1641140628Srwatson
1642140628Srwatson	if (!mac_biba_enabled)
1643140628Srwatson		return (0);
1644140628Srwatson
1645140628Srwatson	subj = SLOT(cred->cr_label);
1646140628Srwatson	obj = SLOT(msglabel);
1647140628Srwatson
1648140628Srwatson	if (!mac_biba_dominate_effective(subj, obj))
1649140628Srwatson		return (EACCES);
1650140628Srwatson
1651140628Srwatson	return (0);
1652140628Srwatson}
1653140628Srwatson
1654140628Srwatsonstatic int
1655140628Srwatsonmac_biba_check_sysv_msqget(struct ucred *cred, struct msqid_kernel *msqkptr,
1656140628Srwatson    struct label *msqklabel)
1657140628Srwatson{
1658140628Srwatson	struct mac_biba *subj, *obj;
1659140628Srwatson
1660140628Srwatson	if (!mac_biba_enabled)
1661140628Srwatson		return (0);
1662140628Srwatson
1663140628Srwatson	subj = SLOT(cred->cr_label);
1664140628Srwatson	obj = SLOT(msqklabel);
1665140628Srwatson
1666140628Srwatson	if (!mac_biba_dominate_effective(obj, subj))
1667140628Srwatson		return (EACCES);
1668140628Srwatson
1669140628Srwatson	return (0);
1670140628Srwatson}
1671140628Srwatson
1672140628Srwatsonstatic int
1673140628Srwatsonmac_biba_check_sysv_msqsnd(struct ucred *cred, struct msqid_kernel *msqkptr,
1674140628Srwatson    struct label *msqklabel)
1675140628Srwatson{
1676140628Srwatson	struct mac_biba *subj, *obj;
1677140628Srwatson
1678140628Srwatson	if (!mac_biba_enabled)
1679140628Srwatson		return (0);
1680140628Srwatson
1681140628Srwatson	subj = SLOT(cred->cr_label);
1682140628Srwatson	obj = SLOT(msqklabel);
1683140628Srwatson
1684140628Srwatson	if (!mac_biba_dominate_effective(subj, obj))
1685140628Srwatson		return (EACCES);
1686140628Srwatson
1687140628Srwatson	return (0);
1688140628Srwatson}
1689140628Srwatson
1690140628Srwatsonstatic int
1691140628Srwatsonmac_biba_check_sysv_msqrcv(struct ucred *cred, struct msqid_kernel *msqkptr,
1692140628Srwatson    struct label *msqklabel)
1693140628Srwatson{
1694140628Srwatson	struct mac_biba *subj, *obj;
1695140628Srwatson
1696140628Srwatson	if (!mac_biba_enabled)
1697140628Srwatson		return (0);
1698140628Srwatson
1699140628Srwatson	subj = SLOT(cred->cr_label);
1700140628Srwatson	obj = SLOT(msqklabel);
1701140628Srwatson
1702140628Srwatson	if (!mac_biba_dominate_effective(obj, subj))
1703140628Srwatson		return (EACCES);
1704140628Srwatson
1705140628Srwatson	return (0);
1706140628Srwatson}
1707140628Srwatson
1708140628Srwatson
1709140628Srwatsonstatic int
1710140628Srwatsonmac_biba_check_sysv_msqctl(struct ucred *cred, struct msqid_kernel *msqkptr,
1711140628Srwatson    struct label *msqklabel, int cmd)
1712140628Srwatson{
1713140628Srwatson	struct mac_biba *subj, *obj;
1714140628Srwatson
1715140628Srwatson	if (!mac_biba_enabled)
1716140628Srwatson		return (0);
1717140628Srwatson
1718140628Srwatson	subj = SLOT(cred->cr_label);
1719140628Srwatson	obj = SLOT(msqklabel);
1720140628Srwatson
1721140628Srwatson	switch(cmd) {
1722140628Srwatson	case IPC_RMID:
1723140628Srwatson	case IPC_SET:
1724140628Srwatson		if (!mac_biba_dominate_effective(subj, obj))
1725140628Srwatson			return (EACCES);
1726140628Srwatson		break;
1727140628Srwatson
1728140628Srwatson	case IPC_STAT:
1729140628Srwatson		if (!mac_biba_dominate_effective(obj, subj))
1730140628Srwatson			return (EACCES);
1731140628Srwatson		break;
1732140628Srwatson
1733140628Srwatson	default:
1734140628Srwatson		return (EACCES);
1735140628Srwatson	}
1736140628Srwatson
1737140628Srwatson	return (0);
1738140628Srwatson}
1739140628Srwatson
1740140628Srwatsonstatic int
1741140628Srwatsonmac_biba_check_sysv_semctl(struct ucred *cred, struct semid_kernel *semakptr,
1742140628Srwatson    struct label *semaklabel, int cmd)
1743140628Srwatson{
1744140628Srwatson	struct mac_biba *subj, *obj;
1745140628Srwatson
1746140628Srwatson	if (!mac_biba_enabled)
1747140628Srwatson		return (0);
1748140628Srwatson
1749140628Srwatson	subj = SLOT(cred->cr_label);
1750140628Srwatson	obj = SLOT(semaklabel);
1751140628Srwatson
1752140628Srwatson	switch(cmd) {
1753140628Srwatson	case IPC_RMID:
1754140628Srwatson	case IPC_SET:
1755140628Srwatson	case SETVAL:
1756140628Srwatson	case SETALL:
1757140628Srwatson		if (!mac_biba_dominate_effective(subj, obj))
1758140628Srwatson			return (EACCES);
1759140628Srwatson		break;
1760140628Srwatson
1761140628Srwatson	case IPC_STAT:
1762140628Srwatson	case GETVAL:
1763140628Srwatson	case GETPID:
1764140628Srwatson	case GETNCNT:
1765140628Srwatson	case GETZCNT:
1766140628Srwatson	case GETALL:
1767140628Srwatson		if (!mac_biba_dominate_effective(obj, subj))
1768140628Srwatson			return (EACCES);
1769140628Srwatson		break;
1770140628Srwatson
1771140628Srwatson	default:
1772140628Srwatson		return (EACCES);
1773140628Srwatson	}
1774140628Srwatson
1775140628Srwatson	return (0);
1776140628Srwatson}
1777140628Srwatson
1778140628Srwatson
1779140628Srwatsonstatic int
1780140628Srwatsonmac_biba_check_sysv_semget(struct ucred *cred, struct semid_kernel *semakptr,
1781140628Srwatson    struct label *semaklabel)
1782140628Srwatson{
1783140628Srwatson	struct mac_biba *subj, *obj;
1784140628Srwatson
1785140628Srwatson	if (!mac_biba_enabled)
1786140628Srwatson		return (0);
1787140628Srwatson
1788140628Srwatson	subj = SLOT(cred->cr_label);
1789140628Srwatson	obj = SLOT(semaklabel);
1790140628Srwatson
1791140628Srwatson	if (!mac_biba_dominate_effective(obj, subj))
1792140628Srwatson		return (EACCES);
1793140628Srwatson
1794140628Srwatson	return (0);
1795140628Srwatson}
1796140628Srwatson
1797140628Srwatson
1798140628Srwatsonstatic int
1799140628Srwatsonmac_biba_check_sysv_semop(struct ucred *cred, struct semid_kernel *semakptr,
1800140628Srwatson    struct label *semaklabel, size_t accesstype)
1801140628Srwatson{
1802140628Srwatson	struct mac_biba *subj, *obj;
1803140628Srwatson
1804140628Srwatson	if (!mac_biba_enabled)
1805140628Srwatson		return (0);
1806140628Srwatson
1807140628Srwatson	subj = SLOT(cred->cr_label);
1808140628Srwatson	obj = SLOT(semaklabel);
1809140628Srwatson
1810140628Srwatson	if (accesstype & SEM_R)
1811140628Srwatson		if (!mac_biba_dominate_effective(obj, subj))
1812140628Srwatson			return (EACCES);
1813140628Srwatson
1814140628Srwatson	if (accesstype & SEM_A)
1815140628Srwatson		if (!mac_biba_dominate_effective(subj, obj))
1816140628Srwatson			return (EACCES);
1817140628Srwatson
1818140628Srwatson	return (0);
1819140628Srwatson}
1820140628Srwatson
1821140628Srwatsonstatic int
1822140628Srwatsonmac_biba_check_sysv_shmat(struct ucred *cred, struct shmid_kernel *shmsegptr,
1823140628Srwatson    struct label *shmseglabel, int shmflg)
1824140628Srwatson{
1825140628Srwatson	struct mac_biba *subj, *obj;
1826140628Srwatson
1827140628Srwatson	if (!mac_biba_enabled)
1828140628Srwatson		return (0);
1829140628Srwatson
1830140628Srwatson	subj = SLOT(cred->cr_label);
1831140628Srwatson	obj = SLOT(shmseglabel);
1832140628Srwatson
1833140628Srwatson	if (!mac_biba_dominate_effective(obj, subj))
1834140628Srwatson		return (EACCES);
1835140628Srwatson	if ((shmflg & SHM_RDONLY) == 0) {
1836140628Srwatson		if (!mac_biba_dominate_effective(subj, obj))
1837140628Srwatson			return (EACCES);
1838140628Srwatson	}
1839140628Srwatson
1840140628Srwatson	return (0);
1841140628Srwatson}
1842140628Srwatson
1843140628Srwatsonstatic int
1844140628Srwatsonmac_biba_check_sysv_shmctl(struct ucred *cred, struct shmid_kernel *shmsegptr,
1845140628Srwatson    struct label *shmseglabel, int cmd)
1846140628Srwatson{
1847140628Srwatson	struct mac_biba *subj, *obj;
1848140628Srwatson
1849140628Srwatson	if (!mac_biba_enabled)
1850140628Srwatson		return (0);
1851140628Srwatson
1852140628Srwatson	subj = SLOT(cred->cr_label);
1853140628Srwatson	obj = SLOT(shmseglabel);
1854140628Srwatson
1855140628Srwatson	switch(cmd) {
1856140628Srwatson	case IPC_RMID:
1857140628Srwatson	case IPC_SET:
1858140628Srwatson		if (!mac_biba_dominate_effective(subj, obj))
1859140628Srwatson			return (EACCES);
1860140628Srwatson		break;
1861140628Srwatson
1862140628Srwatson	case IPC_STAT:
1863140628Srwatson	case SHM_STAT:
1864140628Srwatson		if (!mac_biba_dominate_effective(obj, subj))
1865140628Srwatson			return (EACCES);
1866140628Srwatson		break;
1867140628Srwatson
1868140628Srwatson	default:
1869140628Srwatson		return (EACCES);
1870140628Srwatson	}
1871140628Srwatson
1872140628Srwatson	return (0);
1873140628Srwatson}
1874140628Srwatson
1875140628Srwatsonstatic int
1876140628Srwatsonmac_biba_check_sysv_shmget(struct ucred *cred, struct shmid_kernel *shmsegptr,
1877140628Srwatson    struct label *shmseglabel, int shmflg)
1878140628Srwatson{
1879140628Srwatson	struct mac_biba *subj, *obj;
1880140628Srwatson
1881140628Srwatson	if (!mac_biba_enabled)
1882140628Srwatson		return (0);
1883140628Srwatson
1884140628Srwatson	subj = SLOT(cred->cr_label);
1885140628Srwatson	obj = SLOT(shmseglabel);
1886140628Srwatson
1887140628Srwatson	if (!mac_biba_dominate_effective(obj, subj))
1888140628Srwatson		return (EACCES);
1889140628Srwatson
1890140628Srwatson	return (0);
1891140628Srwatson}
1892140628Srwatson
1893140628Srwatsonstatic int
1894110354Srwatsonmac_biba_check_kld_load(struct ucred *cred, struct vnode *vp,
1895110354Srwatson    struct label *label)
1896110354Srwatson{
1897110354Srwatson	struct mac_biba *subj, *obj;
1898110354Srwatson	int error;
1899110354Srwatson
1900110354Srwatson	if (!mac_biba_enabled)
1901110354Srwatson		return (0);
1902110354Srwatson
1903122524Srwatson	subj = SLOT(cred->cr_label);
1904110354Srwatson
1905110354Srwatson	error = mac_biba_subject_privileged(subj);
1906110354Srwatson	if (error)
1907110354Srwatson		return (error);
1908110354Srwatson
1909110354Srwatson	obj = SLOT(label);
1910132232Srwatson	if (!mac_biba_high_effective(obj))
1911110354Srwatson		return (EACCES);
1912110354Srwatson
1913110354Srwatson	return (0);
1914110354Srwatson}
1915110354Srwatson
1916110354Srwatson
1917110354Srwatsonstatic int
1918110354Srwatsonmac_biba_check_kld_unload(struct ucred *cred)
1919110354Srwatson{
1920110354Srwatson	struct mac_biba *subj;
1921110354Srwatson
1922110354Srwatson	if (!mac_biba_enabled)
1923110354Srwatson		return (0);
1924110354Srwatson
1925122524Srwatson	subj = SLOT(cred->cr_label);
1926110354Srwatson
1927110354Srwatson	return (mac_biba_subject_privileged(subj));
1928110354Srwatson}
1929110354Srwatson
1930110354Srwatsonstatic int
1931101099Srwatsonmac_biba_check_mount_stat(struct ucred *cred, struct mount *mp,
1932101099Srwatson    struct label *mntlabel)
1933101099Srwatson{
1934101099Srwatson	struct mac_biba *subj, *obj;
1935101099Srwatson
1936101099Srwatson	if (!mac_biba_enabled)
1937101099Srwatson		return (0);
1938101099Srwatson
1939122524Srwatson	subj = SLOT(cred->cr_label);
1940101099Srwatson	obj = SLOT(mntlabel);
1941101099Srwatson
1942132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
1943101099Srwatson		return (EACCES);
1944101099Srwatson
1945101099Srwatson	return (0);
1946101099Srwatson}
1947101099Srwatson
1948101099Srwatsonstatic int
1949125293Srwatsonmac_biba_check_pipe_ioctl(struct ucred *cred, struct pipepair *pp,
1950101099Srwatson    struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data)
1951101099Srwatson{
1952103759Srwatson
1953101099Srwatson	if(!mac_biba_enabled)
1954101099Srwatson		return (0);
1955101099Srwatson
1956101099Srwatson	/* XXX: This will be implemented soon... */
1957101099Srwatson
1958101099Srwatson	return (0);
1959101099Srwatson}
1960101099Srwatson
1961101099Srwatsonstatic int
1962125293Srwatsonmac_biba_check_pipe_poll(struct ucred *cred, struct pipepair *pp,
1963102115Srwatson    struct label *pipelabel)
1964101099Srwatson{
1965101099Srwatson	struct mac_biba *subj, *obj;
1966101099Srwatson
1967101099Srwatson	if (!mac_biba_enabled)
1968101099Srwatson		return (0);
1969101099Srwatson
1970122524Srwatson	subj = SLOT(cred->cr_label);
1971101099Srwatson	obj = SLOT((pipelabel));
1972101099Srwatson
1973132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
1974102115Srwatson		return (EACCES);
1975101099Srwatson
1976101099Srwatson	return (0);
1977101099Srwatson}
1978101099Srwatson
1979101099Srwatsonstatic int
1980125293Srwatsonmac_biba_check_pipe_read(struct ucred *cred, struct pipepair *pp,
1981102115Srwatson    struct label *pipelabel)
1982102115Srwatson{
1983102115Srwatson	struct mac_biba *subj, *obj;
1984102115Srwatson
1985102115Srwatson	if (!mac_biba_enabled)
1986102115Srwatson		return (0);
1987102115Srwatson
1988122524Srwatson	subj = SLOT(cred->cr_label);
1989102115Srwatson	obj = SLOT((pipelabel));
1990102115Srwatson
1991132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
1992102115Srwatson		return (EACCES);
1993102115Srwatson
1994102115Srwatson	return (0);
1995102115Srwatson}
1996102115Srwatson
1997102115Srwatsonstatic int
1998125293Srwatsonmac_biba_check_pipe_relabel(struct ucred *cred, struct pipepair *pp,
1999101099Srwatson    struct label *pipelabel, struct label *newlabel)
2000101099Srwatson{
2001101099Srwatson	struct mac_biba *subj, *obj, *new;
2002105634Srwatson	int error;
2003101099Srwatson
2004101099Srwatson	new = SLOT(newlabel);
2005122524Srwatson	subj = SLOT(cred->cr_label);
2006101099Srwatson	obj = SLOT(pipelabel);
2007101099Srwatson
2008101099Srwatson	/*
2009105634Srwatson	 * If there is a Biba label update for a pipe, it must be a
2010132232Srwatson	 * effective update.
2011101099Srwatson	 */
2012132232Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE);
2013105634Srwatson	if (error)
2014105634Srwatson		return (error);
2015101099Srwatson
2016101099Srwatson	/*
2017105634Srwatson	 * To perform a relabel of a pipe (Biba label or not), Biba must
2018105634Srwatson	 * authorize the relabel.
2019101099Srwatson	 */
2020132232Srwatson	if (!mac_biba_effective_in_range(obj, subj))
2021101099Srwatson		return (EPERM);
2022101099Srwatson
2023101099Srwatson	/*
2024105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
2025101099Srwatson	 */
2026132232Srwatson	if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
2027105634Srwatson		/*
2028105634Srwatson		 * To change the Biba label on a pipe, the new pipe label
2029105634Srwatson		 * must be in the subject range.
2030105634Srwatson		 */
2031132232Srwatson		if (!mac_biba_effective_in_range(new, subj))
2032105634Srwatson			return (EPERM);
2033101099Srwatson
2034105634Srwatson		/*
2035105634Srwatson		 * To change the Biba label on a pipe to be EQUAL, the
2036105634Srwatson		 * subject must have appropriate privilege.
2037105634Srwatson		 */
2038105634Srwatson		if (mac_biba_contains_equal(new)) {
2039106090Srwatson			error = mac_biba_subject_privileged(subj);
2040105634Srwatson			if (error)
2041105634Srwatson				return (error);
2042105634Srwatson		}
2043105634Srwatson	}
2044105634Srwatson
2045101099Srwatson	return (0);
2046101099Srwatson}
2047101099Srwatson
2048101099Srwatsonstatic int
2049125293Srwatsonmac_biba_check_pipe_stat(struct ucred *cred, struct pipepair *pp,
2050102115Srwatson    struct label *pipelabel)
2051102115Srwatson{
2052102115Srwatson	struct mac_biba *subj, *obj;
2053102115Srwatson
2054102115Srwatson	if (!mac_biba_enabled)
2055102115Srwatson		return (0);
2056102115Srwatson
2057122524Srwatson	subj = SLOT(cred->cr_label);
2058102115Srwatson	obj = SLOT((pipelabel));
2059102115Srwatson
2060132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2061102115Srwatson		return (EACCES);
2062102115Srwatson
2063102115Srwatson	return (0);
2064102115Srwatson}
2065102115Srwatson
2066102115Srwatsonstatic int
2067125293Srwatsonmac_biba_check_pipe_write(struct ucred *cred, struct pipepair *pp,
2068102115Srwatson    struct label *pipelabel)
2069102115Srwatson{
2070102115Srwatson	struct mac_biba *subj, *obj;
2071102115Srwatson
2072102115Srwatson	if (!mac_biba_enabled)
2073102115Srwatson		return (0);
2074102115Srwatson
2075122524Srwatson	subj = SLOT(cred->cr_label);
2076102115Srwatson	obj = SLOT((pipelabel));
2077102115Srwatson
2078132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2079102115Srwatson		return (EACCES);
2080102115Srwatson
2081102115Srwatson	return (0);
2082102115Srwatson}
2083102115Srwatson
2084102115Srwatsonstatic int
2085145855Srwatsonmac_biba_check_posix_sem_write(struct ucred *cred, struct ksem *ksemptr,
2086145855Srwatson    struct label *ks_label)
2087145855Srwatson{
2088145855Srwatson	struct mac_biba *subj, *obj;
2089145855Srwatson
2090145855Srwatson	if (!mac_biba_enabled)
2091145855Srwatson		return (0);
2092145855Srwatson
2093145855Srwatson	subj = SLOT(cred->cr_label);
2094145855Srwatson	obj = SLOT(ks_label);
2095145855Srwatson
2096145855Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2097145855Srwatson		return (EACCES);
2098145855Srwatson
2099145855Srwatson	return (0);
2100145855Srwatson}
2101145855Srwatson
2102145855Srwatsonstatic int
2103145855Srwatsonmac_biba_check_posix_sem_rdonly(struct ucred *cred, struct ksem *ksemptr,
2104145855Srwatson    struct label *ks_label)
2105145855Srwatson{
2106145855Srwatson	struct mac_biba *subj, *obj;
2107145855Srwatson
2108145855Srwatson	if (!mac_biba_enabled)
2109145855Srwatson		return (0);
2110145855Srwatson
2111145855Srwatson	subj = SLOT(cred->cr_label);
2112145855Srwatson	obj = SLOT(ks_label);
2113145855Srwatson
2114145855Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2115145855Srwatson		return (EACCES);
2116145855Srwatson
2117145855Srwatson	return (0);
2118145855Srwatson}
2119145855Srwatson
2120145855Srwatsonstatic int
2121101099Srwatsonmac_biba_check_proc_debug(struct ucred *cred, struct proc *proc)
2122101099Srwatson{
2123101099Srwatson	struct mac_biba *subj, *obj;
2124101099Srwatson
2125101099Srwatson	if (!mac_biba_enabled)
2126101099Srwatson		return (0);
2127101099Srwatson
2128122524Srwatson	subj = SLOT(cred->cr_label);
2129122524Srwatson	obj = SLOT(proc->p_ucred->cr_label);
2130101099Srwatson
2131101099Srwatson	/* XXX: range checks */
2132132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2133101099Srwatson		return (ESRCH);
2134132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2135101099Srwatson		return (EACCES);
2136101099Srwatson
2137101099Srwatson	return (0);
2138101099Srwatson}
2139101099Srwatson
2140101099Srwatsonstatic int
2141101099Srwatsonmac_biba_check_proc_sched(struct ucred *cred, struct proc *proc)
2142101099Srwatson{
2143101099Srwatson	struct mac_biba *subj, *obj;
2144103759Srwatson
2145101099Srwatson	if (!mac_biba_enabled)
2146101099Srwatson		return (0);
2147101099Srwatson
2148122524Srwatson	subj = SLOT(cred->cr_label);
2149122524Srwatson	obj = SLOT(proc->p_ucred->cr_label);
2150103759Srwatson
2151101099Srwatson	/* XXX: range checks */
2152132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2153101099Srwatson		return (ESRCH);
2154132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2155101099Srwatson		return (EACCES);
2156101099Srwatson
2157101099Srwatson	return (0);
2158101099Srwatson}
2159101099Srwatson
2160101099Srwatsonstatic int
2161101099Srwatsonmac_biba_check_proc_signal(struct ucred *cred, struct proc *proc, int signum)
2162101099Srwatson{
2163101099Srwatson	struct mac_biba *subj, *obj;
2164103759Srwatson
2165101099Srwatson	if (!mac_biba_enabled)
2166101099Srwatson		return (0);
2167101099Srwatson
2168122524Srwatson	subj = SLOT(cred->cr_label);
2169122524Srwatson	obj = SLOT(proc->p_ucred->cr_label);
2170103759Srwatson
2171101099Srwatson	/* XXX: range checks */
2172132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2173101099Srwatson		return (ESRCH);
2174132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2175101099Srwatson		return (EACCES);
2176101099Srwatson
2177101099Srwatson	return (0);
2178101099Srwatson}
2179101099Srwatson
2180101099Srwatsonstatic int
2181101934Srwatsonmac_biba_check_socket_deliver(struct socket *so, struct label *socketlabel,
2182101099Srwatson    struct mbuf *m, struct label *mbuflabel)
2183101099Srwatson{
2184101099Srwatson	struct mac_biba *p, *s;
2185101099Srwatson
2186101099Srwatson	if (!mac_biba_enabled)
2187101099Srwatson		return (0);
2188101099Srwatson
2189101099Srwatson	p = SLOT(mbuflabel);
2190101099Srwatson	s = SLOT(socketlabel);
2191101099Srwatson
2192132232Srwatson	return (mac_biba_equal_effective(p, s) ? 0 : EACCES);
2193101099Srwatson}
2194101099Srwatson
2195101099Srwatsonstatic int
2196106214Srwatsonmac_biba_check_socket_relabel(struct ucred *cred, struct socket *so,
2197101099Srwatson    struct label *socketlabel, struct label *newlabel)
2198101099Srwatson{
2199101099Srwatson	struct mac_biba *subj, *obj, *new;
2200105634Srwatson	int error;
2201101099Srwatson
2202101099Srwatson	new = SLOT(newlabel);
2203122524Srwatson	subj = SLOT(cred->cr_label);
2204101099Srwatson	obj = SLOT(socketlabel);
2205101099Srwatson
2206101099Srwatson	/*
2207105634Srwatson	 * If there is a Biba label update for the socket, it may be
2208132232Srwatson	 * an update of effective.
2209101099Srwatson	 */
2210132232Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE);
2211105634Srwatson	if (error)
2212105634Srwatson		return (error);
2213101099Srwatson
2214101099Srwatson	/*
2215132232Srwatson	 * To relabel a socket, the old socket effective must be in the subject
2216101099Srwatson	 * range.
2217101099Srwatson	 */
2218132232Srwatson	if (!mac_biba_effective_in_range(obj, subj))
2219101099Srwatson		return (EPERM);
2220101099Srwatson
2221101099Srwatson	/*
2222105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
2223101099Srwatson	 */
2224132232Srwatson	if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
2225105634Srwatson		/*
2226132232Srwatson		 * To relabel a socket, the new socket effective must be in
2227105634Srwatson		 * the subject range.
2228105634Srwatson		 */
2229132232Srwatson		if (!mac_biba_effective_in_range(new, subj))
2230105634Srwatson			return (EPERM);
2231101099Srwatson
2232105634Srwatson		/*
2233105634Srwatson		 * To change the Biba label on the socket to contain EQUAL,
2234105634Srwatson		 * the subject must have appropriate privilege.
2235105634Srwatson		 */
2236105634Srwatson		if (mac_biba_contains_equal(new)) {
2237106090Srwatson			error = mac_biba_subject_privileged(subj);
2238105634Srwatson			if (error)
2239105634Srwatson				return (error);
2240105634Srwatson		}
2241105634Srwatson	}
2242105634Srwatson
2243101099Srwatson	return (0);
2244101099Srwatson}
2245101099Srwatson
2246101099Srwatsonstatic int
2247101099Srwatsonmac_biba_check_socket_visible(struct ucred *cred, struct socket *socket,
2248101099Srwatson    struct label *socketlabel)
2249101099Srwatson{
2250101099Srwatson	struct mac_biba *subj, *obj;
2251101099Srwatson
2252105722Srwatson	if (!mac_biba_enabled)
2253105722Srwatson		return (0);
2254105722Srwatson
2255122524Srwatson	subj = SLOT(cred->cr_label);
2256101099Srwatson	obj = SLOT(socketlabel);
2257101099Srwatson
2258132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2259101099Srwatson		return (ENOENT);
2260101099Srwatson
2261101099Srwatson	return (0);
2262101099Srwatson}
2263101099Srwatson
2264101099Srwatsonstatic int
2265112574Srwatsonmac_biba_check_sysarch_ioperm(struct ucred *cred)
2266112574Srwatson{
2267112574Srwatson	struct mac_biba *subj;
2268112574Srwatson	int error;
2269112574Srwatson
2270112574Srwatson	if (!mac_biba_enabled)
2271112574Srwatson		return (0);
2272112574Srwatson
2273122524Srwatson	subj = SLOT(cred->cr_label);
2274112574Srwatson
2275112574Srwatson	error = mac_biba_subject_privileged(subj);
2276112574Srwatson	if (error)
2277112574Srwatson		return (error);
2278112574Srwatson
2279112574Srwatson	return (0);
2280112574Srwatson}
2281112574Srwatson
2282112574Srwatsonstatic int
2283106418Srwatsonmac_biba_check_system_acct(struct ucred *cred, struct vnode *vp,
2284106418Srwatson    struct label *label)
2285106418Srwatson{
2286106418Srwatson	struct mac_biba *subj, *obj;
2287106418Srwatson	int error;
2288106418Srwatson
2289106418Srwatson	if (!mac_biba_enabled)
2290106418Srwatson		return (0);
2291106418Srwatson
2292122524Srwatson	subj = SLOT(cred->cr_label);
2293106418Srwatson
2294106418Srwatson	error = mac_biba_subject_privileged(subj);
2295106418Srwatson	if (error)
2296106418Srwatson		return (error);
2297106418Srwatson
2298106418Srwatson	if (label == NULL)
2299106418Srwatson		return (0);
2300106418Srwatson
2301106418Srwatson	obj = SLOT(label);
2302132232Srwatson	if (!mac_biba_high_effective(obj))
2303106418Srwatson		return (EACCES);
2304106418Srwatson
2305106418Srwatson	return (0);
2306106418Srwatson}
2307106418Srwatson
2308106418Srwatsonstatic int
2309106418Srwatsonmac_biba_check_system_settime(struct ucred *cred)
2310106418Srwatson{
2311106418Srwatson	struct mac_biba *subj;
2312106418Srwatson	int error;
2313106418Srwatson
2314106418Srwatson	if (!mac_biba_enabled)
2315106418Srwatson		return (0);
2316106418Srwatson
2317122524Srwatson	subj = SLOT(cred->cr_label);
2318106418Srwatson
2319106418Srwatson	error = mac_biba_subject_privileged(subj);
2320106418Srwatson	if (error)
2321106418Srwatson		return (error);
2322106418Srwatson
2323106418Srwatson	return (0);
2324106418Srwatson}
2325106418Srwatson
2326106418Srwatsonstatic int
2327106161Srwatsonmac_biba_check_system_swapon(struct ucred *cred, struct vnode *vp,
2328106161Srwatson    struct label *label)
2329106161Srwatson{
2330106161Srwatson	struct mac_biba *subj, *obj;
2331106416Srwatson	int error;
2332106161Srwatson
2333106161Srwatson	if (!mac_biba_enabled)
2334106161Srwatson		return (0);
2335106161Srwatson
2336122524Srwatson	subj = SLOT(cred->cr_label);
2337106161Srwatson	obj = SLOT(label);
2338106161Srwatson
2339106416Srwatson	error = mac_biba_subject_privileged(subj);
2340106416Srwatson	if (error)
2341106416Srwatson		return (error);
2342106161Srwatson
2343132232Srwatson	if (!mac_biba_high_effective(obj))
2344106161Srwatson		return (EACCES);
2345106161Srwatson
2346106161Srwatson	return (0);
2347106161Srwatson}
2348106161Srwatson
2349106161Srwatsonstatic int
2350112574Srwatsonmac_biba_check_system_swapoff(struct ucred *cred, struct vnode *vp,
2351112574Srwatson    struct label *label)
2352112574Srwatson{
2353166617Srwatson	struct mac_biba *subj;
2354112574Srwatson	int error;
2355112574Srwatson
2356112574Srwatson	if (!mac_biba_enabled)
2357112574Srwatson		return (0);
2358112574Srwatson
2359122524Srwatson	subj = SLOT(cred->cr_label);
2360112574Srwatson
2361112574Srwatson	error = mac_biba_subject_privileged(subj);
2362112574Srwatson	if (error)
2363112574Srwatson		return (error);
2364112574Srwatson
2365112574Srwatson	return (0);
2366112574Srwatson}
2367112574Srwatson
2368112574Srwatsonstatic int
2369126121Spjdmac_biba_check_system_sysctl(struct ucred *cred, struct sysctl_oid *oidp,
2370126121Spjd    void *arg1, int arg2, struct sysctl_req *req)
2371106161Srwatson{
2372106161Srwatson	struct mac_biba *subj;
2373106161Srwatson	int error;
2374106161Srwatson
2375106161Srwatson	if (!mac_biba_enabled)
2376106161Srwatson		return (0);
2377106161Srwatson
2378122524Srwatson	subj = SLOT(cred->cr_label);
2379106161Srwatson
2380106161Srwatson	/*
2381126121Spjd	 * Treat sysctl variables without CTLFLAG_ANYBODY flag as
2382126121Spjd	 * biba/high, but also require privilege to change them.
2383106161Srwatson	 */
2384126121Spjd	if (req->newptr != NULL && (oidp->oid_kind & CTLFLAG_ANYBODY) == 0) {
2385106161Srwatson		if (!mac_biba_subject_dominate_high(subj))
2386106161Srwatson			return (EACCES);
2387106161Srwatson
2388106161Srwatson		error = mac_biba_subject_privileged(subj);
2389106161Srwatson		if (error)
2390106161Srwatson			return (error);
2391106161Srwatson	}
2392106161Srwatson
2393106161Srwatson	return (0);
2394106161Srwatson}
2395106161Srwatson
2396106161Srwatsonstatic int
2397101099Srwatsonmac_biba_check_vnode_chdir(struct ucred *cred, struct vnode *dvp,
2398101099Srwatson    struct label *dlabel)
2399101099Srwatson{
2400101099Srwatson	struct mac_biba *subj, *obj;
2401101099Srwatson
2402101099Srwatson	if (!mac_biba_enabled)
2403101099Srwatson		return (0);
2404101099Srwatson
2405122524Srwatson	subj = SLOT(cred->cr_label);
2406101099Srwatson	obj = SLOT(dlabel);
2407101099Srwatson
2408132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2409101099Srwatson		return (EACCES);
2410101099Srwatson
2411101099Srwatson	return (0);
2412101099Srwatson}
2413101099Srwatson
2414101099Srwatsonstatic int
2415101099Srwatsonmac_biba_check_vnode_chroot(struct ucred *cred, struct vnode *dvp,
2416101099Srwatson    struct label *dlabel)
2417101099Srwatson{
2418101099Srwatson	struct mac_biba *subj, *obj;
2419101099Srwatson
2420101099Srwatson	if (!mac_biba_enabled)
2421101099Srwatson		return (0);
2422101099Srwatson
2423122524Srwatson	subj = SLOT(cred->cr_label);
2424101099Srwatson	obj = SLOT(dlabel);
2425101099Srwatson
2426132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2427101099Srwatson		return (EACCES);
2428101099Srwatson
2429101099Srwatson	return (0);
2430101099Srwatson}
2431101099Srwatson
2432101099Srwatsonstatic int
2433101099Srwatsonmac_biba_check_vnode_create(struct ucred *cred, struct vnode *dvp,
2434101099Srwatson    struct label *dlabel, struct componentname *cnp, struct vattr *vap)
2435101099Srwatson{
2436101099Srwatson	struct mac_biba *subj, *obj;
2437101099Srwatson
2438101099Srwatson	if (!mac_biba_enabled)
2439101099Srwatson		return (0);
2440101099Srwatson
2441122524Srwatson	subj = SLOT(cred->cr_label);
2442101099Srwatson	obj = SLOT(dlabel);
2443101099Srwatson
2444132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2445101099Srwatson		return (EACCES);
2446101099Srwatson
2447101099Srwatson	return (0);
2448101099Srwatson}
2449101099Srwatson
2450101099Srwatsonstatic int
2451101099Srwatsonmac_biba_check_vnode_delete(struct ucred *cred, struct vnode *dvp,
2452101099Srwatson    struct label *dlabel, struct vnode *vp, struct label *label,
2453101099Srwatson    struct componentname *cnp)
2454101099Srwatson{
2455101099Srwatson	struct mac_biba *subj, *obj;
2456101099Srwatson
2457101099Srwatson	if (!mac_biba_enabled)
2458101099Srwatson		return (0);
2459101099Srwatson
2460122524Srwatson	subj = SLOT(cred->cr_label);
2461101099Srwatson	obj = SLOT(dlabel);
2462101099Srwatson
2463132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2464101099Srwatson		return (EACCES);
2465101099Srwatson
2466101099Srwatson	obj = SLOT(label);
2467101099Srwatson
2468132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2469101099Srwatson		return (EACCES);
2470101099Srwatson
2471101099Srwatson	return (0);
2472101099Srwatson}
2473101099Srwatson
2474101099Srwatsonstatic int
2475101099Srwatsonmac_biba_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
2476101099Srwatson    struct label *label, acl_type_t type)
2477101099Srwatson{
2478101099Srwatson	struct mac_biba *subj, *obj;
2479101099Srwatson
2480101099Srwatson	if (!mac_biba_enabled)
2481101099Srwatson		return (0);
2482101099Srwatson
2483122524Srwatson	subj = SLOT(cred->cr_label);
2484101099Srwatson	obj = SLOT(label);
2485101099Srwatson
2486132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2487101099Srwatson		return (EACCES);
2488101099Srwatson
2489101099Srwatson	return (0);
2490101099Srwatson}
2491101099Srwatson
2492101099Srwatsonstatic int
2493119202Srwatsonmac_biba_check_vnode_deleteextattr(struct ucred *cred, struct vnode *vp,
2494119202Srwatson    struct label *label, int attrnamespace, const char *name)
2495119202Srwatson{
2496119202Srwatson	struct mac_biba *subj, *obj;
2497119202Srwatson
2498119202Srwatson	if (!mac_biba_enabled)
2499119202Srwatson		return (0);
2500119202Srwatson
2501122524Srwatson	subj = SLOT(cred->cr_label);
2502119202Srwatson	obj = SLOT(label);
2503119202Srwatson
2504132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2505119202Srwatson		return (EACCES);
2506119202Srwatson
2507119202Srwatson	return (0);
2508119202Srwatson}
2509119202Srwatson
2510119202Srwatsonstatic int
2511101099Srwatsonmac_biba_check_vnode_exec(struct ucred *cred, struct vnode *vp,
2512106648Srwatson    struct label *label, struct image_params *imgp,
2513106648Srwatson    struct label *execlabel)
2514101099Srwatson{
2515106648Srwatson	struct mac_biba *subj, *obj, *exec;
2516106648Srwatson	int error;
2517101099Srwatson
2518106648Srwatson	if (execlabel != NULL) {
2519106648Srwatson		/*
2520106648Srwatson		 * We currently don't permit labels to be changed at
2521106648Srwatson		 * exec-time as part of Biba, so disallow non-NULL
2522106648Srwatson		 * Biba label elements in the execlabel.
2523106648Srwatson		 */
2524106648Srwatson		exec = SLOT(execlabel);
2525106648Srwatson		error = biba_atmostflags(exec, 0);
2526106648Srwatson		if (error)
2527106648Srwatson			return (error);
2528106648Srwatson	}
2529106648Srwatson
2530101099Srwatson	if (!mac_biba_enabled)
2531101099Srwatson		return (0);
2532101099Srwatson
2533122524Srwatson	subj = SLOT(cred->cr_label);
2534101099Srwatson	obj = SLOT(label);
2535101099Srwatson
2536132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2537101099Srwatson		return (EACCES);
2538101099Srwatson
2539101099Srwatson	return (0);
2540101099Srwatson}
2541101099Srwatson
2542101099Srwatsonstatic int
2543101099Srwatsonmac_biba_check_vnode_getacl(struct ucred *cred, struct vnode *vp,
2544101099Srwatson    struct label *label, acl_type_t type)
2545101099Srwatson{
2546101099Srwatson	struct mac_biba *subj, *obj;
2547101099Srwatson
2548101099Srwatson	if (!mac_biba_enabled)
2549101099Srwatson		return (0);
2550101099Srwatson
2551122524Srwatson	subj = SLOT(cred->cr_label);
2552101099Srwatson	obj = SLOT(label);
2553101099Srwatson
2554132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2555101099Srwatson		return (EACCES);
2556101099Srwatson
2557101099Srwatson	return (0);
2558101099Srwatson}
2559101099Srwatson
2560101099Srwatsonstatic int
2561101099Srwatsonmac_biba_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
2562101099Srwatson    struct label *label, int attrnamespace, const char *name, struct uio *uio)
2563101099Srwatson{
2564101099Srwatson	struct mac_biba *subj, *obj;
2565101099Srwatson
2566101099Srwatson	if (!mac_biba_enabled)
2567101099Srwatson		return (0);
2568101099Srwatson
2569122524Srwatson	subj = SLOT(cred->cr_label);
2570101099Srwatson	obj = SLOT(label);
2571101099Srwatson
2572132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2573101099Srwatson		return (EACCES);
2574101099Srwatson
2575101099Srwatson	return (0);
2576101099Srwatson}
2577101099Srwatson
2578101099Srwatsonstatic int
2579104530Srwatsonmac_biba_check_vnode_link(struct ucred *cred, struct vnode *dvp,
2580104530Srwatson    struct label *dlabel, struct vnode *vp, struct label *label,
2581104530Srwatson    struct componentname *cnp)
2582104530Srwatson{
2583104530Srwatson	struct mac_biba *subj, *obj;
2584104530Srwatson
2585104530Srwatson	if (!mac_biba_enabled)
2586104530Srwatson		return (0);
2587104530Srwatson
2588122524Srwatson	subj = SLOT(cred->cr_label);
2589104530Srwatson	obj = SLOT(dlabel);
2590104530Srwatson
2591132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2592104530Srwatson		return (EACCES);
2593104530Srwatson
2594104530Srwatson	obj = SLOT(label);
2595104530Srwatson
2596132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2597104530Srwatson		return (EACCES);
2598104530Srwatson
2599104530Srwatson	return (0);
2600104530Srwatson}
2601104530Srwatson
2602104530Srwatsonstatic int
2603119202Srwatsonmac_biba_check_vnode_listextattr(struct ucred *cred, struct vnode *vp,
2604119202Srwatson    struct label *label, int attrnamespace)
2605119202Srwatson{
2606119202Srwatson	struct mac_biba *subj, *obj;
2607119202Srwatson
2608119202Srwatson	if (!mac_biba_enabled)
2609119202Srwatson		return (0);
2610119202Srwatson
2611122524Srwatson	subj = SLOT(cred->cr_label);
2612119202Srwatson	obj = SLOT(label);
2613119202Srwatson
2614132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2615119202Srwatson		return (EACCES);
2616119202Srwatson
2617119202Srwatson	return (0);
2618119202Srwatson}
2619119202Srwatson
2620119202Srwatsonstatic int
2621103759Srwatsonmac_biba_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
2622101099Srwatson    struct label *dlabel, struct componentname *cnp)
2623101099Srwatson{
2624101099Srwatson	struct mac_biba *subj, *obj;
2625103759Srwatson
2626101099Srwatson	if (!mac_biba_enabled)
2627101099Srwatson		return (0);
2628103759Srwatson
2629122524Srwatson	subj = SLOT(cred->cr_label);
2630101099Srwatson	obj = SLOT(dlabel);
2631103759Srwatson
2632132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2633101099Srwatson		return (EACCES);
2634101099Srwatson
2635103759Srwatson	return (0);
2636101099Srwatson}
2637101099Srwatson
2638101099Srwatsonstatic int
2639104546Srwatsonmac_biba_check_vnode_mmap(struct ucred *cred, struct vnode *vp,
2640145076Scsjp    struct label *label, int prot, int flags)
2641104546Srwatson{
2642104546Srwatson	struct mac_biba *subj, *obj;
2643104546Srwatson
2644104546Srwatson	/*
2645104546Srwatson	 * Rely on the use of open()-time protections to handle
2646104546Srwatson	 * non-revocation cases.
2647104546Srwatson	 */
2648105637Srwatson	if (!mac_biba_enabled || !revocation_enabled)
2649104546Srwatson		return (0);
2650104546Srwatson
2651122524Srwatson	subj = SLOT(cred->cr_label);
2652104546Srwatson	obj = SLOT(label);
2653104546Srwatson
2654104546Srwatson	if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
2655132232Srwatson		if (!mac_biba_dominate_effective(obj, subj))
2656104546Srwatson			return (EACCES);
2657104546Srwatson	}
2658145076Scsjp	if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) {
2659132232Srwatson		if (!mac_biba_dominate_effective(subj, obj))
2660104546Srwatson			return (EACCES);
2661104546Srwatson	}
2662104546Srwatson
2663104569Srwatson	return (0);
2664104546Srwatson}
2665104546Srwatson
2666104546Srwatsonstatic int
2667101099Srwatsonmac_biba_check_vnode_open(struct ucred *cred, struct vnode *vp,
2668106212Srwatson    struct label *vnodelabel, int acc_mode)
2669101099Srwatson{
2670101099Srwatson	struct mac_biba *subj, *obj;
2671101099Srwatson
2672101099Srwatson	if (!mac_biba_enabled)
2673101099Srwatson		return (0);
2674101099Srwatson
2675122524Srwatson	subj = SLOT(cred->cr_label);
2676101099Srwatson	obj = SLOT(vnodelabel);
2677101099Srwatson
2678101099Srwatson	/* XXX privilege override for admin? */
2679101099Srwatson	if (acc_mode & (VREAD | VEXEC | VSTAT)) {
2680132232Srwatson		if (!mac_biba_dominate_effective(obj, subj))
2681101099Srwatson			return (EACCES);
2682101099Srwatson	}
2683101099Srwatson	if (acc_mode & (VWRITE | VAPPEND | VADMIN)) {
2684132232Srwatson		if (!mac_biba_dominate_effective(subj, obj))
2685101099Srwatson			return (EACCES);
2686101099Srwatson	}
2687101099Srwatson
2688101099Srwatson	return (0);
2689101099Srwatson}
2690101099Srwatson
2691101099Srwatsonstatic int
2692102129Srwatsonmac_biba_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred,
2693102129Srwatson    struct vnode *vp, struct label *label)
2694102112Srwatson{
2695102112Srwatson	struct mac_biba *subj, *obj;
2696102112Srwatson
2697105637Srwatson	if (!mac_biba_enabled || !revocation_enabled)
2698102112Srwatson		return (0);
2699102112Srwatson
2700122524Srwatson	subj = SLOT(active_cred->cr_label);
2701102112Srwatson	obj = SLOT(label);
2702102112Srwatson
2703132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2704102112Srwatson		return (EACCES);
2705102112Srwatson
2706102112Srwatson	return (0);
2707102112Srwatson}
2708102112Srwatson
2709102112Srwatsonstatic int
2710102129Srwatsonmac_biba_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
2711102129Srwatson    struct vnode *vp, struct label *label)
2712102112Srwatson{
2713102112Srwatson	struct mac_biba *subj, *obj;
2714102112Srwatson
2715105637Srwatson	if (!mac_biba_enabled || !revocation_enabled)
2716102112Srwatson		return (0);
2717102112Srwatson
2718122524Srwatson	subj = SLOT(active_cred->cr_label);
2719102112Srwatson	obj = SLOT(label);
2720102112Srwatson
2721132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2722102112Srwatson		return (EACCES);
2723102112Srwatson
2724102112Srwatson	return (0);
2725102112Srwatson}
2726102112Srwatson
2727102112Srwatsonstatic int
2728101099Srwatsonmac_biba_check_vnode_readdir(struct ucred *cred, struct vnode *dvp,
2729101099Srwatson    struct label *dlabel)
2730101099Srwatson{
2731101099Srwatson	struct mac_biba *subj, *obj;
2732101099Srwatson
2733101099Srwatson	if (!mac_biba_enabled)
2734101099Srwatson		return (0);
2735101099Srwatson
2736122524Srwatson	subj = SLOT(cred->cr_label);
2737101099Srwatson	obj = SLOT(dlabel);
2738101099Srwatson
2739132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2740101099Srwatson		return (EACCES);
2741101099Srwatson
2742101099Srwatson	return (0);
2743101099Srwatson}
2744101099Srwatson
2745101099Srwatsonstatic int
2746101099Srwatsonmac_biba_check_vnode_readlink(struct ucred *cred, struct vnode *vp,
2747101099Srwatson    struct label *label)
2748101099Srwatson{
2749101099Srwatson	struct mac_biba *subj, *obj;
2750101099Srwatson
2751101099Srwatson	if (!mac_biba_enabled)
2752101099Srwatson		return (0);
2753101099Srwatson
2754122524Srwatson	subj = SLOT(cred->cr_label);
2755101099Srwatson	obj = SLOT(label);
2756101099Srwatson
2757132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2758101099Srwatson		return (EACCES);
2759101099Srwatson
2760101099Srwatson	return (0);
2761101099Srwatson}
2762101099Srwatson
2763101099Srwatsonstatic int
2764101099Srwatsonmac_biba_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
2765101099Srwatson    struct label *vnodelabel, struct label *newlabel)
2766101099Srwatson{
2767101099Srwatson	struct mac_biba *old, *new, *subj;
2768105634Srwatson	int error;
2769101099Srwatson
2770101099Srwatson	old = SLOT(vnodelabel);
2771101099Srwatson	new = SLOT(newlabel);
2772122524Srwatson	subj = SLOT(cred->cr_label);
2773101099Srwatson
2774101099Srwatson	/*
2775105634Srwatson	 * If there is a Biba label update for the vnode, it must be a
2776132232Srwatson	 * effective label.
2777101099Srwatson	 */
2778132232Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE);
2779105634Srwatson	if (error)
2780105634Srwatson		return (error);
2781101099Srwatson
2782101099Srwatson	/*
2783105634Srwatson	 * To perform a relabel of the vnode (Biba label or not), Biba must
2784105634Srwatson	 * authorize the relabel.
2785101099Srwatson	 */
2786132232Srwatson	if (!mac_biba_effective_in_range(old, subj))
2787101099Srwatson		return (EPERM);
2788101099Srwatson
2789101099Srwatson	/*
2790105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
2791101099Srwatson	 */
2792132232Srwatson	if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
2793105634Srwatson		/*
2794105634Srwatson		 * To change the Biba label on a vnode, the new vnode label
2795105634Srwatson		 * must be in the subject range.
2796105634Srwatson		 */
2797132232Srwatson		if (!mac_biba_effective_in_range(new, subj))
2798105634Srwatson			return (EPERM);
2799101099Srwatson
2800105634Srwatson		/*
2801105634Srwatson		 * To change the Biba label on the vnode to be EQUAL,
2802105634Srwatson		 * the subject must have appropriate privilege.
2803105634Srwatson		 */
2804105634Srwatson		if (mac_biba_contains_equal(new)) {
2805106090Srwatson			error = mac_biba_subject_privileged(subj);
2806105634Srwatson			if (error)
2807105634Srwatson				return (error);
2808105634Srwatson		}
2809105634Srwatson	}
2810105634Srwatson
2811105634Srwatson	return (0);
2812101099Srwatson}
2813101099Srwatson
2814101099Srwatsonstatic int
2815101099Srwatsonmac_biba_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
2816101099Srwatson    struct label *dlabel, struct vnode *vp, struct label *label,
2817101099Srwatson    struct componentname *cnp)
2818101099Srwatson{
2819101099Srwatson	struct mac_biba *subj, *obj;
2820101099Srwatson
2821101099Srwatson	if (!mac_biba_enabled)
2822101099Srwatson		return (0);
2823101099Srwatson
2824122524Srwatson	subj = SLOT(cred->cr_label);
2825101099Srwatson	obj = SLOT(dlabel);
2826101099Srwatson
2827132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2828101099Srwatson		return (EACCES);
2829101099Srwatson
2830101099Srwatson	obj = SLOT(label);
2831101099Srwatson
2832132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2833101099Srwatson		return (EACCES);
2834101099Srwatson
2835101099Srwatson	return (0);
2836101099Srwatson}
2837101099Srwatson
2838101099Srwatsonstatic int
2839101099Srwatsonmac_biba_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
2840101099Srwatson    struct label *dlabel, struct vnode *vp, struct label *label, int samedir,
2841101099Srwatson    struct componentname *cnp)
2842101099Srwatson{
2843101099Srwatson	struct mac_biba *subj, *obj;
2844101099Srwatson
2845101099Srwatson	if (!mac_biba_enabled)
2846101099Srwatson		return (0);
2847101099Srwatson
2848122524Srwatson	subj = SLOT(cred->cr_label);
2849101099Srwatson	obj = SLOT(dlabel);
2850101099Srwatson
2851132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2852101099Srwatson		return (EACCES);
2853101099Srwatson
2854101099Srwatson	if (vp != NULL) {
2855101099Srwatson		obj = SLOT(label);
2856101099Srwatson
2857132232Srwatson		if (!mac_biba_dominate_effective(subj, obj))
2858101099Srwatson			return (EACCES);
2859101099Srwatson	}
2860101099Srwatson
2861101099Srwatson	return (0);
2862101099Srwatson}
2863101099Srwatson
2864101099Srwatsonstatic int
2865101099Srwatsonmac_biba_check_vnode_revoke(struct ucred *cred, struct vnode *vp,
2866101099Srwatson    struct label *label)
2867101099Srwatson{
2868101099Srwatson	struct mac_biba *subj, *obj;
2869101099Srwatson
2870101099Srwatson	if (!mac_biba_enabled)
2871101099Srwatson		return (0);
2872101099Srwatson
2873122524Srwatson	subj = SLOT(cred->cr_label);
2874101099Srwatson	obj = SLOT(label);
2875101099Srwatson
2876132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2877101099Srwatson		return (EACCES);
2878101099Srwatson
2879101099Srwatson	return (0);
2880101099Srwatson}
2881101099Srwatson
2882101099Srwatsonstatic int
2883101099Srwatsonmac_biba_check_vnode_setacl(struct ucred *cred, struct vnode *vp,
2884101099Srwatson    struct label *label, acl_type_t type, struct acl *acl)
2885101099Srwatson{
2886101099Srwatson	struct mac_biba *subj, *obj;
2887101099Srwatson
2888101099Srwatson	if (!mac_biba_enabled)
2889101099Srwatson		return (0);
2890101099Srwatson
2891122524Srwatson	subj = SLOT(cred->cr_label);
2892101099Srwatson	obj = SLOT(label);
2893101099Srwatson
2894132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2895101099Srwatson		return (EACCES);
2896101099Srwatson
2897101099Srwatson	return (0);
2898101099Srwatson}
2899101099Srwatson
2900101099Srwatsonstatic int
2901101099Srwatsonmac_biba_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
2902101099Srwatson    struct label *vnodelabel, int attrnamespace, const char *name,
2903101099Srwatson    struct uio *uio)
2904101099Srwatson{
2905101099Srwatson	struct mac_biba *subj, *obj;
2906101099Srwatson
2907101099Srwatson	if (!mac_biba_enabled)
2908101099Srwatson		return (0);
2909101099Srwatson
2910122524Srwatson	subj = SLOT(cred->cr_label);
2911101099Srwatson	obj = SLOT(vnodelabel);
2912101099Srwatson
2913132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2914101099Srwatson		return (EACCES);
2915101099Srwatson
2916101099Srwatson	/* XXX: protect the MAC EA in a special way? */
2917101099Srwatson
2918101099Srwatson	return (0);
2919101099Srwatson}
2920101099Srwatson
2921101099Srwatsonstatic int
2922101099Srwatsonmac_biba_check_vnode_setflags(struct ucred *cred, struct vnode *vp,
2923101099Srwatson    struct label *vnodelabel, u_long flags)
2924101099Srwatson{
2925101099Srwatson	struct mac_biba *subj, *obj;
2926101099Srwatson
2927101099Srwatson	if (!mac_biba_enabled)
2928101099Srwatson		return (0);
2929101099Srwatson
2930122524Srwatson	subj = SLOT(cred->cr_label);
2931101099Srwatson	obj = SLOT(vnodelabel);
2932101099Srwatson
2933132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2934101099Srwatson		return (EACCES);
2935101099Srwatson
2936101099Srwatson	return (0);
2937101099Srwatson}
2938101099Srwatson
2939101099Srwatsonstatic int
2940101099Srwatsonmac_biba_check_vnode_setmode(struct ucred *cred, struct vnode *vp,
2941101099Srwatson    struct label *vnodelabel, mode_t mode)
2942101099Srwatson{
2943101099Srwatson	struct mac_biba *subj, *obj;
2944101099Srwatson
2945101099Srwatson	if (!mac_biba_enabled)
2946101099Srwatson		return (0);
2947101099Srwatson
2948122524Srwatson	subj = SLOT(cred->cr_label);
2949101099Srwatson	obj = SLOT(vnodelabel);
2950101099Srwatson
2951132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2952101099Srwatson		return (EACCES);
2953101099Srwatson
2954101099Srwatson	return (0);
2955101099Srwatson}
2956101099Srwatson
2957101099Srwatsonstatic int
2958101099Srwatsonmac_biba_check_vnode_setowner(struct ucred *cred, struct vnode *vp,
2959101099Srwatson    struct label *vnodelabel, uid_t uid, gid_t gid)
2960101099Srwatson{
2961101099Srwatson	struct mac_biba *subj, *obj;
2962101099Srwatson
2963101099Srwatson	if (!mac_biba_enabled)
2964101099Srwatson		return (0);
2965101099Srwatson
2966122524Srwatson	subj = SLOT(cred->cr_label);
2967101099Srwatson	obj = SLOT(vnodelabel);
2968101099Srwatson
2969132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2970101099Srwatson		return (EACCES);
2971101099Srwatson
2972101099Srwatson	return (0);
2973101099Srwatson}
2974101099Srwatson
2975101099Srwatsonstatic int
2976101099Srwatsonmac_biba_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
2977101099Srwatson    struct label *vnodelabel, struct timespec atime, struct timespec mtime)
2978101099Srwatson{
2979101099Srwatson	struct mac_biba *subj, *obj;
2980101099Srwatson
2981101099Srwatson	if (!mac_biba_enabled)
2982101099Srwatson		return (0);
2983101099Srwatson
2984122524Srwatson	subj = SLOT(cred->cr_label);
2985101099Srwatson	obj = SLOT(vnodelabel);
2986101099Srwatson
2987132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2988101099Srwatson		return (EACCES);
2989101099Srwatson
2990101099Srwatson	return (0);
2991101099Srwatson}
2992101099Srwatson
2993101099Srwatsonstatic int
2994102129Srwatsonmac_biba_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
2995102129Srwatson    struct vnode *vp, struct label *vnodelabel)
2996101099Srwatson{
2997101099Srwatson	struct mac_biba *subj, *obj;
2998101099Srwatson
2999101099Srwatson	if (!mac_biba_enabled)
3000101099Srwatson		return (0);
3001101099Srwatson
3002122524Srwatson	subj = SLOT(active_cred->cr_label);
3003101099Srwatson	obj = SLOT(vnodelabel);
3004101099Srwatson
3005132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
3006101099Srwatson		return (EACCES);
3007101099Srwatson
3008101099Srwatson	return (0);
3009101099Srwatson}
3010101099Srwatson
3011102112Srwatsonstatic int
3012102129Srwatsonmac_biba_check_vnode_write(struct ucred *active_cred,
3013102129Srwatson    struct ucred *file_cred, struct vnode *vp, struct label *label)
3014102112Srwatson{
3015102112Srwatson	struct mac_biba *subj, *obj;
3016102112Srwatson
3017105637Srwatson	if (!mac_biba_enabled || !revocation_enabled)
3018102112Srwatson		return (0);
3019102112Srwatson
3020122524Srwatson	subj = SLOT(active_cred->cr_label);
3021102112Srwatson	obj = SLOT(label);
3022102112Srwatson
3023132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
3024102112Srwatson		return (EACCES);
3025102112Srwatson
3026102112Srwatson	return (0);
3027102112Srwatson}
3028102112Srwatson
3029161026Srwatsonstatic void
3030160243Scsjpmac_biba_associate_nfsd_label(struct ucred *cred)
3031160243Scsjp{
3032160243Scsjp	struct mac_biba *label;
3033160243Scsjp
3034160243Scsjp	label = SLOT(cred->cr_label);
3035160243Scsjp	mac_biba_set_effective(label, MAC_BIBA_TYPE_LOW, 0, NULL);
3036160243Scsjp	mac_biba_set_range(label, MAC_BIBA_TYPE_LOW, 0, NULL,
3037160243Scsjp	    MAC_BIBA_TYPE_HIGH, 0, NULL);
3038160243Scsjp}
3039160243Scsjp
3040165150Scsjpstatic void
3041165150Scsjpmac_biba_init_syncache_from_inpcb(struct label *label, struct inpcb *inp)
3042165150Scsjp{
3043165150Scsjp	struct mac_biba *source, *dest;
3044165150Scsjp
3045165150Scsjp	source = SLOT(inp->inp_label);
3046165150Scsjp	dest = SLOT(label);
3047165150Scsjp	mac_biba_copy_effective(source, dest);
3048165150Scsjp}
3049165150Scsjp
3050165150Scsjpstatic void
3051165150Scsjpmac_biba_create_mbuf_from_syncache(struct label *sc_label, struct mbuf *m,
3052165150Scsjp    struct label *mbuf_label)
3053165150Scsjp{
3054165150Scsjp	struct mac_biba *source, *dest;
3055165150Scsjp
3056165150Scsjp	source = SLOT(sc_label);
3057165150Scsjp	dest = SLOT(mbuf_label);
3058165150Scsjp	mac_biba_copy_effective(source, dest);
3059165150Scsjp}
3060165150Scsjp
3061106217Srwatsonstatic struct mac_policy_ops mac_biba_ops =
3062101099Srwatson{
3063106217Srwatson	.mpo_init = mac_biba_init,
3064106217Srwatson	.mpo_init_bpfdesc_label = mac_biba_init_label,
3065106217Srwatson	.mpo_init_cred_label = mac_biba_init_label,
3066106217Srwatson	.mpo_init_devfsdirent_label = mac_biba_init_label,
3067106217Srwatson	.mpo_init_ifnet_label = mac_biba_init_label,
3068122875Srwatson	.mpo_init_inpcb_label = mac_biba_init_label_waitcheck,
3069165150Scsjp	.mpo_init_syncache_label = mac_biba_init_label_waitcheck,
3070140628Srwatson	.mpo_init_sysv_msgmsg_label = mac_biba_init_label,
3071140628Srwatson	.mpo_init_sysv_msgqueue_label = mac_biba_init_label,
3072147091Srwatson	.mpo_init_sysv_sem_label = mac_biba_init_label,
3073140628Srwatson	.mpo_init_sysv_shm_label = mac_biba_init_label,
3074112675Srwatson	.mpo_init_ipq_label = mac_biba_init_label_waitcheck,
3075106217Srwatson	.mpo_init_mbuf_label = mac_biba_init_label_waitcheck,
3076106217Srwatson	.mpo_init_mount_label = mac_biba_init_label,
3077106217Srwatson	.mpo_init_mount_fs_label = mac_biba_init_label,
3078106217Srwatson	.mpo_init_pipe_label = mac_biba_init_label,
3079145855Srwatson	.mpo_init_posix_sem_label = mac_biba_init_label,
3080106217Srwatson	.mpo_init_socket_label = mac_biba_init_label_waitcheck,
3081106217Srwatson	.mpo_init_socket_peer_label = mac_biba_init_label_waitcheck,
3082165150Scsjp	.mpo_init_syncache_from_inpcb = mac_biba_init_syncache_from_inpcb,
3083106217Srwatson	.mpo_init_vnode_label = mac_biba_init_label,
3084106217Srwatson	.mpo_destroy_bpfdesc_label = mac_biba_destroy_label,
3085106217Srwatson	.mpo_destroy_cred_label = mac_biba_destroy_label,
3086106217Srwatson	.mpo_destroy_devfsdirent_label = mac_biba_destroy_label,
3087106217Srwatson	.mpo_destroy_ifnet_label = mac_biba_destroy_label,
3088122875Srwatson	.mpo_destroy_inpcb_label = mac_biba_destroy_label,
3089165150Scsjp	.mpo_destroy_syncache_label = mac_biba_destroy_label,
3090140628Srwatson	.mpo_destroy_sysv_msgmsg_label = mac_biba_destroy_label,
3091140628Srwatson	.mpo_destroy_sysv_msgqueue_label = mac_biba_destroy_label,
3092147091Srwatson	.mpo_destroy_sysv_sem_label = mac_biba_destroy_label,
3093140628Srwatson	.mpo_destroy_sysv_shm_label = mac_biba_destroy_label,
3094106217Srwatson	.mpo_destroy_ipq_label = mac_biba_destroy_label,
3095106217Srwatson	.mpo_destroy_mbuf_label = mac_biba_destroy_label,
3096106217Srwatson	.mpo_destroy_mount_label = mac_biba_destroy_label,
3097106217Srwatson	.mpo_destroy_mount_fs_label = mac_biba_destroy_label,
3098106217Srwatson	.mpo_destroy_pipe_label = mac_biba_destroy_label,
3099145855Srwatson	.mpo_destroy_posix_sem_label = mac_biba_destroy_label,
3100106217Srwatson	.mpo_destroy_socket_label = mac_biba_destroy_label,
3101106217Srwatson	.mpo_destroy_socket_peer_label = mac_biba_destroy_label,
3102106217Srwatson	.mpo_destroy_vnode_label = mac_biba_destroy_label,
3103123173Srwatson	.mpo_copy_cred_label = mac_biba_copy_label,
3104131025Srwatson	.mpo_copy_ifnet_label = mac_biba_copy_label,
3105115707Srwatson	.mpo_copy_mbuf_label = mac_biba_copy_label,
3106106217Srwatson	.mpo_copy_pipe_label = mac_biba_copy_label,
3107122820Srwatson	.mpo_copy_socket_label = mac_biba_copy_label,
3108106217Srwatson	.mpo_copy_vnode_label = mac_biba_copy_label,
3109106217Srwatson	.mpo_externalize_cred_label = mac_biba_externalize_label,
3110106217Srwatson	.mpo_externalize_ifnet_label = mac_biba_externalize_label,
3111106217Srwatson	.mpo_externalize_pipe_label = mac_biba_externalize_label,
3112106217Srwatson	.mpo_externalize_socket_label = mac_biba_externalize_label,
3113106217Srwatson	.mpo_externalize_socket_peer_label = mac_biba_externalize_label,
3114106217Srwatson	.mpo_externalize_vnode_label = mac_biba_externalize_label,
3115106217Srwatson	.mpo_internalize_cred_label = mac_biba_internalize_label,
3116106217Srwatson	.mpo_internalize_ifnet_label = mac_biba_internalize_label,
3117106217Srwatson	.mpo_internalize_pipe_label = mac_biba_internalize_label,
3118106217Srwatson	.mpo_internalize_socket_label = mac_biba_internalize_label,
3119106217Srwatson	.mpo_internalize_vnode_label = mac_biba_internalize_label,
3120106217Srwatson	.mpo_create_devfs_device = mac_biba_create_devfs_device,
3121106217Srwatson	.mpo_create_devfs_directory = mac_biba_create_devfs_directory,
3122106217Srwatson	.mpo_create_devfs_symlink = mac_biba_create_devfs_symlink,
3123106217Srwatson	.mpo_create_mount = mac_biba_create_mount,
3124106217Srwatson	.mpo_relabel_vnode = mac_biba_relabel_vnode,
3125106217Srwatson	.mpo_update_devfsdirent = mac_biba_update_devfsdirent,
3126106217Srwatson	.mpo_associate_vnode_devfs = mac_biba_associate_vnode_devfs,
3127106217Srwatson	.mpo_associate_vnode_extattr = mac_biba_associate_vnode_extattr,
3128106217Srwatson	.mpo_associate_vnode_singlelabel = mac_biba_associate_vnode_singlelabel,
3129106217Srwatson	.mpo_create_vnode_extattr = mac_biba_create_vnode_extattr,
3130106217Srwatson	.mpo_setlabel_vnode_extattr = mac_biba_setlabel_vnode_extattr,
3131106217Srwatson	.mpo_create_mbuf_from_socket = mac_biba_create_mbuf_from_socket,
3132165150Scsjp	.mpo_create_mbuf_from_syncache = mac_biba_create_mbuf_from_syncache,
3133106217Srwatson	.mpo_create_pipe = mac_biba_create_pipe,
3134145855Srwatson	.mpo_create_posix_sem = mac_biba_create_posix_sem,
3135106217Srwatson	.mpo_create_socket = mac_biba_create_socket,
3136106217Srwatson	.mpo_create_socket_from_socket = mac_biba_create_socket_from_socket,
3137106217Srwatson	.mpo_relabel_pipe = mac_biba_relabel_pipe,
3138106217Srwatson	.mpo_relabel_socket = mac_biba_relabel_socket,
3139106217Srwatson	.mpo_set_socket_peer_from_mbuf = mac_biba_set_socket_peer_from_mbuf,
3140106217Srwatson	.mpo_set_socket_peer_from_socket = mac_biba_set_socket_peer_from_socket,
3141106217Srwatson	.mpo_create_bpfdesc = mac_biba_create_bpfdesc,
3142106217Srwatson	.mpo_create_datagram_from_ipq = mac_biba_create_datagram_from_ipq,
3143106217Srwatson	.mpo_create_fragment = mac_biba_create_fragment,
3144106217Srwatson	.mpo_create_ifnet = mac_biba_create_ifnet,
3145122875Srwatson	.mpo_create_inpcb_from_socket = mac_biba_create_inpcb_from_socket,
3146140628Srwatson	.mpo_create_sysv_msgmsg = mac_biba_create_sysv_msgmsg,
3147140628Srwatson	.mpo_create_sysv_msgqueue = mac_biba_create_sysv_msgqueue,
3148147091Srwatson	.mpo_create_sysv_sem = mac_biba_create_sysv_sem,
3149140628Srwatson	.mpo_create_sysv_shm = mac_biba_create_sysv_shm,
3150106217Srwatson	.mpo_create_ipq = mac_biba_create_ipq,
3151123607Srwatson	.mpo_create_mbuf_from_inpcb = mac_biba_create_mbuf_from_inpcb,
3152106217Srwatson	.mpo_create_mbuf_linklayer = mac_biba_create_mbuf_linklayer,
3153106217Srwatson	.mpo_create_mbuf_from_bpfdesc = mac_biba_create_mbuf_from_bpfdesc,
3154106217Srwatson	.mpo_create_mbuf_from_ifnet = mac_biba_create_mbuf_from_ifnet,
3155106217Srwatson	.mpo_create_mbuf_multicast_encap = mac_biba_create_mbuf_multicast_encap,
3156106217Srwatson	.mpo_create_mbuf_netlayer = mac_biba_create_mbuf_netlayer,
3157106217Srwatson	.mpo_fragment_match = mac_biba_fragment_match,
3158106217Srwatson	.mpo_relabel_ifnet = mac_biba_relabel_ifnet,
3159106217Srwatson	.mpo_update_ipq = mac_biba_update_ipq,
3160122875Srwatson	.mpo_inpcb_sosetlabel = mac_biba_inpcb_sosetlabel,
3161106217Srwatson	.mpo_create_proc0 = mac_biba_create_proc0,
3162106217Srwatson	.mpo_create_proc1 = mac_biba_create_proc1,
3163106217Srwatson	.mpo_relabel_cred = mac_biba_relabel_cred,
3164140628Srwatson	.mpo_cleanup_sysv_msgmsg = mac_biba_cleanup_sysv_msgmsg,
3165140628Srwatson	.mpo_cleanup_sysv_msgqueue = mac_biba_cleanup_sysv_msgqueue,
3166147091Srwatson	.mpo_cleanup_sysv_sem = mac_biba_cleanup_sysv_sem,
3167140628Srwatson	.mpo_cleanup_sysv_shm = mac_biba_cleanup_sysv_shm,
3168106217Srwatson	.mpo_check_bpfdesc_receive = mac_biba_check_bpfdesc_receive,
3169106217Srwatson	.mpo_check_cred_relabel = mac_biba_check_cred_relabel,
3170106217Srwatson	.mpo_check_cred_visible = mac_biba_check_cred_visible,
3171106217Srwatson	.mpo_check_ifnet_relabel = mac_biba_check_ifnet_relabel,
3172106217Srwatson	.mpo_check_ifnet_transmit = mac_biba_check_ifnet_transmit,
3173122875Srwatson	.mpo_check_inpcb_deliver = mac_biba_check_inpcb_deliver,
3174140628Srwatson	.mpo_check_sysv_msgrcv = mac_biba_check_sysv_msgrcv,
3175140628Srwatson	.mpo_check_sysv_msgrmid = mac_biba_check_sysv_msgrmid,
3176140628Srwatson	.mpo_check_sysv_msqget = mac_biba_check_sysv_msqget,
3177140628Srwatson	.mpo_check_sysv_msqsnd = mac_biba_check_sysv_msqsnd,
3178140628Srwatson	.mpo_check_sysv_msqrcv = mac_biba_check_sysv_msqrcv,
3179140628Srwatson	.mpo_check_sysv_msqctl = mac_biba_check_sysv_msqctl,
3180140628Srwatson	.mpo_check_sysv_semctl = mac_biba_check_sysv_semctl,
3181140628Srwatson	.mpo_check_sysv_semget = mac_biba_check_sysv_semget,
3182140628Srwatson	.mpo_check_sysv_semop = mac_biba_check_sysv_semop,
3183140628Srwatson	.mpo_check_sysv_shmat = mac_biba_check_sysv_shmat,
3184140628Srwatson	.mpo_check_sysv_shmctl = mac_biba_check_sysv_shmctl,
3185140628Srwatson	.mpo_check_sysv_shmget = mac_biba_check_sysv_shmget,
3186110354Srwatson	.mpo_check_kld_load = mac_biba_check_kld_load,
3187110354Srwatson	.mpo_check_kld_unload = mac_biba_check_kld_unload,
3188106217Srwatson	.mpo_check_mount_stat = mac_biba_check_mount_stat,
3189106217Srwatson	.mpo_check_pipe_ioctl = mac_biba_check_pipe_ioctl,
3190106217Srwatson	.mpo_check_pipe_poll = mac_biba_check_pipe_poll,
3191106217Srwatson	.mpo_check_pipe_read = mac_biba_check_pipe_read,
3192106217Srwatson	.mpo_check_pipe_relabel = mac_biba_check_pipe_relabel,
3193106217Srwatson	.mpo_check_pipe_stat = mac_biba_check_pipe_stat,
3194106217Srwatson	.mpo_check_pipe_write = mac_biba_check_pipe_write,
3195145855Srwatson	.mpo_check_posix_sem_destroy = mac_biba_check_posix_sem_write,
3196145855Srwatson	.mpo_check_posix_sem_getvalue = mac_biba_check_posix_sem_rdonly,
3197145855Srwatson	.mpo_check_posix_sem_open = mac_biba_check_posix_sem_write,
3198145855Srwatson	.mpo_check_posix_sem_post = mac_biba_check_posix_sem_write,
3199145855Srwatson	.mpo_check_posix_sem_unlink = mac_biba_check_posix_sem_write,
3200145855Srwatson	.mpo_check_posix_sem_wait = mac_biba_check_posix_sem_write,
3201106217Srwatson	.mpo_check_proc_debug = mac_biba_check_proc_debug,
3202106217Srwatson	.mpo_check_proc_sched = mac_biba_check_proc_sched,
3203106217Srwatson	.mpo_check_proc_signal = mac_biba_check_proc_signal,
3204106217Srwatson	.mpo_check_socket_deliver = mac_biba_check_socket_deliver,
3205106217Srwatson	.mpo_check_socket_relabel = mac_biba_check_socket_relabel,
3206106217Srwatson	.mpo_check_socket_visible = mac_biba_check_socket_visible,
3207112574Srwatson	.mpo_check_sysarch_ioperm = mac_biba_check_sysarch_ioperm,
3208106418Srwatson	.mpo_check_system_acct = mac_biba_check_system_acct,
3209106418Srwatson	.mpo_check_system_settime = mac_biba_check_system_settime,
3210106217Srwatson	.mpo_check_system_swapon = mac_biba_check_system_swapon,
3211112574Srwatson	.mpo_check_system_swapoff = mac_biba_check_system_swapoff,
3212106217Srwatson	.mpo_check_system_sysctl = mac_biba_check_system_sysctl,
3213106217Srwatson	.mpo_check_vnode_access = mac_biba_check_vnode_open,
3214106217Srwatson	.mpo_check_vnode_chdir = mac_biba_check_vnode_chdir,
3215106217Srwatson	.mpo_check_vnode_chroot = mac_biba_check_vnode_chroot,
3216106217Srwatson	.mpo_check_vnode_create = mac_biba_check_vnode_create,
3217106217Srwatson	.mpo_check_vnode_delete = mac_biba_check_vnode_delete,
3218106217Srwatson	.mpo_check_vnode_deleteacl = mac_biba_check_vnode_deleteacl,
3219119202Srwatson	.mpo_check_vnode_deleteextattr = mac_biba_check_vnode_deleteextattr,
3220106217Srwatson	.mpo_check_vnode_exec = mac_biba_check_vnode_exec,
3221106217Srwatson	.mpo_check_vnode_getacl = mac_biba_check_vnode_getacl,
3222106217Srwatson	.mpo_check_vnode_getextattr = mac_biba_check_vnode_getextattr,
3223106217Srwatson	.mpo_check_vnode_link = mac_biba_check_vnode_link,
3224119202Srwatson	.mpo_check_vnode_listextattr = mac_biba_check_vnode_listextattr,
3225106217Srwatson	.mpo_check_vnode_lookup = mac_biba_check_vnode_lookup,
3226106217Srwatson	.mpo_check_vnode_mmap = mac_biba_check_vnode_mmap,
3227106217Srwatson	.mpo_check_vnode_open = mac_biba_check_vnode_open,
3228106217Srwatson	.mpo_check_vnode_poll = mac_biba_check_vnode_poll,
3229106217Srwatson	.mpo_check_vnode_read = mac_biba_check_vnode_read,
3230106217Srwatson	.mpo_check_vnode_readdir = mac_biba_check_vnode_readdir,
3231106217Srwatson	.mpo_check_vnode_readlink = mac_biba_check_vnode_readlink,
3232106217Srwatson	.mpo_check_vnode_relabel = mac_biba_check_vnode_relabel,
3233106217Srwatson	.mpo_check_vnode_rename_from = mac_biba_check_vnode_rename_from,
3234106217Srwatson	.mpo_check_vnode_rename_to = mac_biba_check_vnode_rename_to,
3235106217Srwatson	.mpo_check_vnode_revoke = mac_biba_check_vnode_revoke,
3236106217Srwatson	.mpo_check_vnode_setacl = mac_biba_check_vnode_setacl,
3237106217Srwatson	.mpo_check_vnode_setextattr = mac_biba_check_vnode_setextattr,
3238106217Srwatson	.mpo_check_vnode_setflags = mac_biba_check_vnode_setflags,
3239106217Srwatson	.mpo_check_vnode_setmode = mac_biba_check_vnode_setmode,
3240106217Srwatson	.mpo_check_vnode_setowner = mac_biba_check_vnode_setowner,
3241106217Srwatson	.mpo_check_vnode_setutimes = mac_biba_check_vnode_setutimes,
3242106217Srwatson	.mpo_check_vnode_stat = mac_biba_check_vnode_stat,
3243106217Srwatson	.mpo_check_vnode_write = mac_biba_check_vnode_write,
3244160243Scsjp	.mpo_associate_nfsd_label = mac_biba_associate_nfsd_label,
3245162238Scsjp	.mpo_create_mbuf_from_firewall = mac_biba_create_mbuf_from_firewall,
3246101099Srwatson};
3247101099Srwatson
3248112717SrwatsonMAC_POLICY_SET(&mac_biba_ops, mac_biba, "TrustedBSD MAC/Biba",
3249113531Srwatson    MPC_LOADTIME_FLAG_NOTLATE | MPC_LOADTIME_FLAG_LABELMBUFS, &mac_biba_slot);
3250