mac_biba.c revision 147091
1101099Srwatson/*-
2126097Srwatson * Copyright (c) 1999-2002 Robert N. M. Watson
3140628Srwatson * Copyright (c) 2001-2005 McAfee, Inc.
4101099Srwatson * All rights reserved.
5101099Srwatson *
6101099Srwatson * This software was developed by Robert Watson for the TrustedBSD Project.
7101099Srwatson *
8140628Srwatson * This software was developed for the FreeBSD Project in part by McAfee
9140628Srwatson * Research, the Security Research Division of McAfee, Inc. under
10140628Srwatson * DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA
11140628Srwatson * CHATS research program.
12101099Srwatson *
13101099Srwatson * Redistribution and use in source and binary forms, with or without
14101099Srwatson * modification, are permitted provided that the following conditions
15101099Srwatson * are met:
16101099Srwatson * 1. Redistributions of source code must retain the above copyright
17101099Srwatson *    notice, this list of conditions and the following disclaimer.
18101099Srwatson * 2. Redistributions in binary form must reproduce the above copyright
19101099Srwatson *    notice, this list of conditions and the following disclaimer in the
20101099Srwatson *    documentation and/or other materials provided with the distribution.
21101099Srwatson *
22101099Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
23101099Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24101099Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25101099Srwatson * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
26101099Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27101099Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28101099Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29101099Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30101099Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31101099Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32101099Srwatson * SUCH DAMAGE.
33101099Srwatson *
34101099Srwatson * $FreeBSD: head/sys/security/mac_biba/mac_biba.c 147091 2005-06-07 05:03:28Z rwatson $
35101099Srwatson */
36101099Srwatson
37101099Srwatson/*
38101099Srwatson * Developed by the TrustedBSD Project.
39101099Srwatson * Biba fixed label mandatory integrity policy.
40101099Srwatson */
41101099Srwatson
42101099Srwatson#include <sys/types.h>
43101099Srwatson#include <sys/param.h>
44101099Srwatson#include <sys/acl.h>
45101099Srwatson#include <sys/conf.h>
46105988Srwatson#include <sys/extattr.h>
47101099Srwatson#include <sys/kernel.h>
48101099Srwatson#include <sys/mac.h>
49103183Sbde#include <sys/malloc.h>
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>
63101099Srwatson#include <sys/sysctl.h>
64140628Srwatson#include <sys/msg.h>
65140628Srwatson#include <sys/sem.h>
66140628Srwatson#include <sys/shm.h>
67101099Srwatson
68145855Srwatson#include <posix4/ksem.h>
69145855Srwatson
70101099Srwatson#include <fs/devfs/devfs.h>
71101099Srwatson
72101099Srwatson#include <net/bpfdesc.h>
73101099Srwatson#include <net/if.h>
74101099Srwatson#include <net/if_types.h>
75101099Srwatson#include <net/if_var.h>
76101099Srwatson
77101099Srwatson#include <netinet/in.h>
78122875Srwatson#include <netinet/in_pcb.h>
79101099Srwatson#include <netinet/ip_var.h>
80101099Srwatson
81122879Srwatson#include <vm/uma.h>
82101099Srwatson#include <vm/vm.h>
83101099Srwatson
84101099Srwatson#include <sys/mac_policy.h>
85101099Srwatson
86101099Srwatson#include <security/mac_biba/mac_biba.h>
87101099Srwatson
88101099SrwatsonSYSCTL_DECL(_security_mac);
89101099Srwatson
90101099SrwatsonSYSCTL_NODE(_security_mac, OID_AUTO, biba, CTLFLAG_RW, 0,
91101099Srwatson    "TrustedBSD mac_biba policy controls");
92101099Srwatson
93105988Srwatsonstatic int	mac_biba_label_size = sizeof(struct mac_biba);
94105988SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, label_size, CTLFLAG_RD,
95105988Srwatson    &mac_biba_label_size, 0, "Size of struct mac_biba");
96105988Srwatson
97107731Srwatsonstatic int	mac_biba_enabled = 1;
98101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, enabled, CTLFLAG_RW,
99101099Srwatson    &mac_biba_enabled, 0, "Enforce MAC/Biba policy");
100102980SrwatsonTUNABLE_INT("security.mac.biba.enabled", &mac_biba_enabled);
101101099Srwatson
102101099Srwatsonstatic int	destroyed_not_inited;
103101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, destroyed_not_inited, CTLFLAG_RD,
104101099Srwatson    &destroyed_not_inited, 0, "Count of labels destroyed but not inited");
105101099Srwatson
106101099Srwatsonstatic int	trust_all_interfaces = 0;
107101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, trust_all_interfaces, CTLFLAG_RD,
108101099Srwatson    &trust_all_interfaces, 0, "Consider all interfaces 'trusted' by MAC/Biba");
109101099SrwatsonTUNABLE_INT("security.mac.biba.trust_all_interfaces", &trust_all_interfaces);
110101099Srwatson
111101099Srwatsonstatic char	trusted_interfaces[128];
112101099SrwatsonSYSCTL_STRING(_security_mac_biba, OID_AUTO, trusted_interfaces, CTLFLAG_RD,
113101099Srwatson    trusted_interfaces, 0, "Interfaces considered 'trusted' by MAC/Biba");
114101099SrwatsonTUNABLE_STR("security.mac.biba.trusted_interfaces", trusted_interfaces,
115101099Srwatson    sizeof(trusted_interfaces));
116101099Srwatson
117105643Srwatsonstatic int	max_compartments = MAC_BIBA_MAX_COMPARTMENTS;
118105643SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, max_compartments, CTLFLAG_RD,
119105643Srwatson    &max_compartments, 0, "Maximum supported compartments");
120105643Srwatson
121105606Srwatsonstatic int	ptys_equal = 0;
122105606SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, ptys_equal, CTLFLAG_RW,
123105606Srwatson    &ptys_equal, 0, "Label pty devices as biba/equal on create");
124105606SrwatsonTUNABLE_INT("security.mac.biba.ptys_equal", &ptys_equal);
125105606Srwatson
126105637Srwatsonstatic int	revocation_enabled = 0;
127101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, revocation_enabled, CTLFLAG_RW,
128105637Srwatson    &revocation_enabled, 0, "Revoke access to objects on relabel");
129105637SrwatsonTUNABLE_INT("security.mac.biba.revocation_enabled", &revocation_enabled);
130101099Srwatson
131101099Srwatsonstatic int	mac_biba_slot;
132101099Srwatson#define	SLOT(l)	((struct mac_biba *)LABEL_TO_SLOT((l), mac_biba_slot).l_ptr)
133132781Skan#define	SLOT_SET(l, val) (LABEL_TO_SLOT((l), mac_biba_slot).l_ptr = (val))
134101099Srwatson
135122879Srwatsonstatic uma_zone_t	zone_biba;
136101099Srwatson
137105643Srwatsonstatic __inline int
138105643Srwatsonbiba_bit_set_empty(u_char *set) {
139105643Srwatson	int i;
140105643Srwatson
141105643Srwatson	for (i = 0; i < MAC_BIBA_MAX_COMPARTMENTS >> 3; i++)
142105643Srwatson		if (set[i] != 0)
143105643Srwatson			return (0);
144105643Srwatson	return (1);
145105643Srwatson}
146105643Srwatson
147101099Srwatsonstatic struct mac_biba *
148104514Srwatsonbiba_alloc(int flag)
149101099Srwatson{
150101099Srwatson
151122879Srwatson	return (uma_zalloc(zone_biba, flag | M_ZERO));
152101099Srwatson}
153101099Srwatson
154101099Srwatsonstatic void
155101099Srwatsonbiba_free(struct mac_biba *mac_biba)
156101099Srwatson{
157101099Srwatson
158101099Srwatson	if (mac_biba != NULL)
159122879Srwatson		uma_zfree(zone_biba, mac_biba);
160101099Srwatson	else
161101099Srwatson		atomic_add_int(&destroyed_not_inited, 1);
162101099Srwatson}
163101099Srwatson
164101099Srwatsonstatic int
165105634Srwatsonbiba_atmostflags(struct mac_biba *mac_biba, int flags)
166105634Srwatson{
167105634Srwatson
168105634Srwatson	if ((mac_biba->mb_flags & flags) != mac_biba->mb_flags)
169105634Srwatson		return (EINVAL);
170105634Srwatson	return (0);
171105634Srwatson}
172105634Srwatson
173105634Srwatsonstatic int
174101099Srwatsonmac_biba_dominate_element(struct mac_biba_element *a,
175101099Srwatson    struct mac_biba_element *b)
176101099Srwatson{
177105643Srwatson	int bit;
178101099Srwatson
179105736Srwatson	switch (a->mbe_type) {
180101099Srwatson	case MAC_BIBA_TYPE_EQUAL:
181101099Srwatson	case MAC_BIBA_TYPE_HIGH:
182101099Srwatson		return (1);
183101099Srwatson
184101099Srwatson	case MAC_BIBA_TYPE_LOW:
185101099Srwatson		switch (b->mbe_type) {
186101099Srwatson		case MAC_BIBA_TYPE_GRADE:
187101099Srwatson		case MAC_BIBA_TYPE_HIGH:
188101099Srwatson			return (0);
189101099Srwatson
190101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
191101099Srwatson		case MAC_BIBA_TYPE_LOW:
192101099Srwatson			return (1);
193101099Srwatson
194101099Srwatson		default:
195101099Srwatson			panic("mac_biba_dominate_element: b->mbe_type invalid");
196101099Srwatson		}
197101099Srwatson
198101099Srwatson	case MAC_BIBA_TYPE_GRADE:
199101099Srwatson		switch (b->mbe_type) {
200101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
201101099Srwatson		case MAC_BIBA_TYPE_LOW:
202101099Srwatson			return (1);
203101099Srwatson
204101099Srwatson		case MAC_BIBA_TYPE_HIGH:
205101099Srwatson			return (0);
206101099Srwatson
207101099Srwatson		case MAC_BIBA_TYPE_GRADE:
208105643Srwatson			for (bit = 1; bit <= MAC_BIBA_MAX_COMPARTMENTS; bit++)
209105643Srwatson				if (!MAC_BIBA_BIT_TEST(bit,
210105643Srwatson				    a->mbe_compartments) &&
211105643Srwatson				    MAC_BIBA_BIT_TEST(bit, b->mbe_compartments))
212105643Srwatson					return (0);
213101099Srwatson			return (a->mbe_grade >= b->mbe_grade);
214101099Srwatson
215101099Srwatson		default:
216101099Srwatson			panic("mac_biba_dominate_element: b->mbe_type invalid");
217101099Srwatson		}
218101099Srwatson
219101099Srwatson	default:
220101099Srwatson		panic("mac_biba_dominate_element: a->mbe_type invalid");
221101099Srwatson	}
222101099Srwatson
223101099Srwatson	return (0);
224101099Srwatson}
225101099Srwatson
226101099Srwatsonstatic int
227105988Srwatsonmac_biba_subject_dominate_high(struct mac_biba *mac_biba)
228105988Srwatson{
229105988Srwatson	struct mac_biba_element *element;
230105988Srwatson
231132232Srwatson	KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
232132232Srwatson	    ("mac_biba_effective_in_range: mac_biba not effective"));
233132232Srwatson	element = &mac_biba->mb_effective;
234105988Srwatson
235105988Srwatson	return (element->mbe_type == MAC_BIBA_TYPE_EQUAL ||
236105988Srwatson	    element->mbe_type == MAC_BIBA_TYPE_HIGH);
237105988Srwatson}
238105988Srwatson
239105988Srwatsonstatic int
240101099Srwatsonmac_biba_range_in_range(struct mac_biba *rangea, struct mac_biba *rangeb)
241101099Srwatson{
242101099Srwatson
243101099Srwatson	return (mac_biba_dominate_element(&rangeb->mb_rangehigh,
244101099Srwatson	    &rangea->mb_rangehigh) &&
245101099Srwatson	    mac_biba_dominate_element(&rangea->mb_rangelow,
246101099Srwatson	    &rangeb->mb_rangelow));
247101099Srwatson}
248101099Srwatson
249101099Srwatsonstatic int
250136774Srwatsonmac_biba_effective_in_range(struct mac_biba *effective,
251136774Srwatson    struct mac_biba *range)
252101099Srwatson{
253101099Srwatson
254132232Srwatson	KASSERT((effective->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
255132232Srwatson	    ("mac_biba_effective_in_range: a not effective"));
256103750Srwatson	KASSERT((range->mb_flags & MAC_BIBA_FLAG_RANGE) != 0,
257132232Srwatson	    ("mac_biba_effective_in_range: b not range"));
258101099Srwatson
259101099Srwatson	return (mac_biba_dominate_element(&range->mb_rangehigh,
260132232Srwatson	    &effective->mb_effective) &&
261132232Srwatson	    mac_biba_dominate_element(&effective->mb_effective,
262101099Srwatson	    &range->mb_rangelow));
263101099Srwatson
264101099Srwatson	return (1);
265101099Srwatson}
266101099Srwatson
267101099Srwatsonstatic int
268132232Srwatsonmac_biba_dominate_effective(struct mac_biba *a, struct mac_biba *b)
269101099Srwatson{
270132232Srwatson	KASSERT((a->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
271132232Srwatson	    ("mac_biba_dominate_effective: a not effective"));
272132232Srwatson	KASSERT((b->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
273132232Srwatson	    ("mac_biba_dominate_effective: b not effective"));
274101099Srwatson
275132232Srwatson	return (mac_biba_dominate_element(&a->mb_effective, &b->mb_effective));
276101099Srwatson}
277101099Srwatson
278101099Srwatsonstatic int
279101099Srwatsonmac_biba_equal_element(struct mac_biba_element *a, struct mac_biba_element *b)
280101099Srwatson{
281101099Srwatson
282101099Srwatson	if (a->mbe_type == MAC_BIBA_TYPE_EQUAL ||
283101099Srwatson	    b->mbe_type == MAC_BIBA_TYPE_EQUAL)
284101099Srwatson		return (1);
285101099Srwatson
286101099Srwatson	return (a->mbe_type == b->mbe_type && a->mbe_grade == b->mbe_grade);
287101099Srwatson}
288101099Srwatson
289101099Srwatsonstatic int
290132232Srwatsonmac_biba_equal_effective(struct mac_biba *a, struct mac_biba *b)
291101099Srwatson{
292101099Srwatson
293132232Srwatson	KASSERT((a->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
294132232Srwatson	    ("mac_biba_equal_effective: a not effective"));
295132232Srwatson	KASSERT((b->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
296132232Srwatson	    ("mac_biba_equal_effective: b not effective"));
297101099Srwatson
298132232Srwatson	return (mac_biba_equal_element(&a->mb_effective, &b->mb_effective));
299101099Srwatson}
300101099Srwatson
301101099Srwatsonstatic int
302105634Srwatsonmac_biba_contains_equal(struct mac_biba *mac_biba)
303105634Srwatson{
304105634Srwatson
305132232Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_EFFECTIVE)
306132232Srwatson		if (mac_biba->mb_effective.mbe_type == MAC_BIBA_TYPE_EQUAL)
307105634Srwatson			return (1);
308105634Srwatson
309105634Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
310105634Srwatson		if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL)
311105634Srwatson			return (1);
312105634Srwatson		if (mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL)
313105637Srwatson			return (1);
314105634Srwatson	}
315105634Srwatson
316105634Srwatson	return (0);
317105634Srwatson}
318105634Srwatson
319105634Srwatsonstatic int
320106090Srwatsonmac_biba_subject_privileged(struct mac_biba *mac_biba)
321105634Srwatson{
322105634Srwatson
323105634Srwatson	KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAGS_BOTH) ==
324105634Srwatson	    MAC_BIBA_FLAGS_BOTH,
325106090Srwatson	    ("mac_biba_subject_privileged: subject doesn't have both labels"));
326105634Srwatson
327132232Srwatson	/* If the effective is EQUAL, it's ok. */
328132232Srwatson	if (mac_biba->mb_effective.mbe_type == MAC_BIBA_TYPE_EQUAL)
329105634Srwatson		return (0);
330105634Srwatson
331105634Srwatson	/* If either range endpoint is EQUAL, it's ok. */
332105634Srwatson	if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL ||
333105634Srwatson	    mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL)
334105634Srwatson		return (0);
335105634Srwatson
336105634Srwatson	/* If the range is low-high, it's ok. */
337105634Srwatson	if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_LOW &&
338105634Srwatson	    mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_HIGH)
339105634Srwatson		return (0);
340105634Srwatson
341105634Srwatson	/* It's not ok. */
342105634Srwatson	return (EPERM);
343105634Srwatson}
344105634Srwatson
345106091Srwatsonstatic int
346132232Srwatsonmac_biba_high_effective(struct mac_biba *mac_biba)
347105988Srwatson{
348105988Srwatson
349132232Srwatson	KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
350132232Srwatson	    ("mac_biba_equal_effective: mac_biba not effective"));
351105988Srwatson
352132232Srwatson	return (mac_biba->mb_effective.mbe_type == MAC_BIBA_TYPE_HIGH);
353105988Srwatson}
354105988Srwatson
355105634Srwatsonstatic int
356101099Srwatsonmac_biba_valid(struct mac_biba *mac_biba)
357101099Srwatson{
358101099Srwatson
359132232Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
360132232Srwatson		switch (mac_biba->mb_effective.mbe_type) {
361101099Srwatson		case MAC_BIBA_TYPE_GRADE:
362101099Srwatson			break;
363101099Srwatson
364101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
365101099Srwatson		case MAC_BIBA_TYPE_HIGH:
366101099Srwatson		case MAC_BIBA_TYPE_LOW:
367132232Srwatson			if (mac_biba->mb_effective.mbe_grade != 0 ||
368105643Srwatson			    !MAC_BIBA_BIT_SET_EMPTY(
369132232Srwatson			    mac_biba->mb_effective.mbe_compartments))
370101099Srwatson				return (EINVAL);
371101099Srwatson			break;
372101099Srwatson
373101099Srwatson		default:
374101099Srwatson			return (EINVAL);
375101099Srwatson		}
376101099Srwatson	} else {
377132232Srwatson		if (mac_biba->mb_effective.mbe_type != MAC_BIBA_TYPE_UNDEF)
378101099Srwatson			return (EINVAL);
379101099Srwatson	}
380101099Srwatson
381101099Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
382101099Srwatson		switch (mac_biba->mb_rangelow.mbe_type) {
383101099Srwatson		case MAC_BIBA_TYPE_GRADE:
384101099Srwatson			break;
385101099Srwatson
386101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
387101099Srwatson		case MAC_BIBA_TYPE_HIGH:
388101099Srwatson		case MAC_BIBA_TYPE_LOW:
389105643Srwatson			if (mac_biba->mb_rangelow.mbe_grade != 0 ||
390105643Srwatson			    !MAC_BIBA_BIT_SET_EMPTY(
391105643Srwatson			    mac_biba->mb_rangelow.mbe_compartments))
392101099Srwatson				return (EINVAL);
393101099Srwatson			break;
394101099Srwatson
395101099Srwatson		default:
396101099Srwatson			return (EINVAL);
397101099Srwatson		}
398101099Srwatson
399101099Srwatson		switch (mac_biba->mb_rangehigh.mbe_type) {
400101099Srwatson		case MAC_BIBA_TYPE_GRADE:
401101099Srwatson			break;
402101099Srwatson
403101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
404101099Srwatson		case MAC_BIBA_TYPE_HIGH:
405101099Srwatson		case MAC_BIBA_TYPE_LOW:
406105643Srwatson			if (mac_biba->mb_rangehigh.mbe_grade != 0 ||
407105643Srwatson			    !MAC_BIBA_BIT_SET_EMPTY(
408105643Srwatson			    mac_biba->mb_rangehigh.mbe_compartments))
409101099Srwatson				return (EINVAL);
410101099Srwatson			break;
411101099Srwatson
412101099Srwatson		default:
413101099Srwatson			return (EINVAL);
414101099Srwatson		}
415101099Srwatson		if (!mac_biba_dominate_element(&mac_biba->mb_rangehigh,
416101099Srwatson		    &mac_biba->mb_rangelow))
417101099Srwatson			return (EINVAL);
418101099Srwatson	} else {
419101099Srwatson		if (mac_biba->mb_rangelow.mbe_type != MAC_BIBA_TYPE_UNDEF ||
420101099Srwatson		    mac_biba->mb_rangehigh.mbe_type != MAC_BIBA_TYPE_UNDEF)
421101099Srwatson			return (EINVAL);
422101099Srwatson	}
423101099Srwatson
424101099Srwatson	return (0);
425101099Srwatson}
426101099Srwatson
427101099Srwatsonstatic void
428101099Srwatsonmac_biba_set_range(struct mac_biba *mac_biba, u_short typelow,
429105643Srwatson    u_short gradelow, u_char *compartmentslow, u_short typehigh,
430105643Srwatson    u_short gradehigh, u_char *compartmentshigh)
431101099Srwatson{
432101099Srwatson
433101099Srwatson	mac_biba->mb_rangelow.mbe_type = typelow;
434101099Srwatson	mac_biba->mb_rangelow.mbe_grade = gradelow;
435105643Srwatson	if (compartmentslow != NULL)
436105643Srwatson		memcpy(mac_biba->mb_rangelow.mbe_compartments,
437105643Srwatson		    compartmentslow,
438105643Srwatson		    sizeof(mac_biba->mb_rangelow.mbe_compartments));
439101099Srwatson	mac_biba->mb_rangehigh.mbe_type = typehigh;
440101099Srwatson	mac_biba->mb_rangehigh.mbe_grade = gradehigh;
441105643Srwatson	if (compartmentshigh != NULL)
442105643Srwatson		memcpy(mac_biba->mb_rangehigh.mbe_compartments,
443105643Srwatson		    compartmentshigh,
444105643Srwatson		    sizeof(mac_biba->mb_rangehigh.mbe_compartments));
445101099Srwatson	mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE;
446101099Srwatson}
447101099Srwatson
448101099Srwatsonstatic void
449132232Srwatsonmac_biba_set_effective(struct mac_biba *mac_biba, u_short type, u_short grade,
450105643Srwatson    u_char *compartments)
451101099Srwatson{
452101099Srwatson
453132232Srwatson	mac_biba->mb_effective.mbe_type = type;
454132232Srwatson	mac_biba->mb_effective.mbe_grade = grade;
455105643Srwatson	if (compartments != NULL)
456132232Srwatson		memcpy(mac_biba->mb_effective.mbe_compartments, compartments,
457132232Srwatson		    sizeof(mac_biba->mb_effective.mbe_compartments));
458132232Srwatson	mac_biba->mb_flags |= MAC_BIBA_FLAG_EFFECTIVE;
459101099Srwatson}
460101099Srwatson
461101099Srwatsonstatic void
462101099Srwatsonmac_biba_copy_range(struct mac_biba *labelfrom, struct mac_biba *labelto)
463101099Srwatson{
464105643Srwatson
465101099Srwatson	KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_RANGE) != 0,
466101099Srwatson	    ("mac_biba_copy_range: labelfrom not range"));
467101099Srwatson
468101099Srwatson	labelto->mb_rangelow = labelfrom->mb_rangelow;
469101099Srwatson	labelto->mb_rangehigh = labelfrom->mb_rangehigh;
470101099Srwatson	labelto->mb_flags |= MAC_BIBA_FLAG_RANGE;
471101099Srwatson}
472101099Srwatson
473101099Srwatsonstatic void
474132232Srwatsonmac_biba_copy_effective(struct mac_biba *labelfrom, struct mac_biba *labelto)
475101099Srwatson{
476101099Srwatson
477132232Srwatson	KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
478132232Srwatson	    ("mac_biba_copy_effective: labelfrom not effective"));
479101099Srwatson
480132232Srwatson	labelto->mb_effective = labelfrom->mb_effective;
481132232Srwatson	labelto->mb_flags |= MAC_BIBA_FLAG_EFFECTIVE;
482101099Srwatson}
483101099Srwatson
484105656Srwatsonstatic void
485105656Srwatsonmac_biba_copy(struct mac_biba *source, struct mac_biba *dest)
486105656Srwatson{
487105656Srwatson
488132232Srwatson	if (source->mb_flags & MAC_BIBA_FLAG_EFFECTIVE)
489132232Srwatson		mac_biba_copy_effective(source, dest);
490105656Srwatson	if (source->mb_flags & MAC_BIBA_FLAG_RANGE)
491105656Srwatson		mac_biba_copy_range(source, dest);
492105656Srwatson}
493105656Srwatson
494101099Srwatson/*
495101099Srwatson * Policy module operations.
496101099Srwatson */
497101099Srwatsonstatic void
498101099Srwatsonmac_biba_init(struct mac_policy_conf *conf)
499101099Srwatson{
500101099Srwatson
501122879Srwatson	zone_biba = uma_zcreate("mac_biba", sizeof(struct mac_biba), NULL,
502122879Srwatson	    NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
503101099Srwatson}
504101099Srwatson
505101099Srwatson/*
506101099Srwatson * Label operations.
507101099Srwatson */
508101099Srwatsonstatic void
509104514Srwatsonmac_biba_init_label(struct label *label)
510101099Srwatson{
511101099Srwatson
512132781Skan	SLOT_SET(label, biba_alloc(M_WAITOK));
513101099Srwatson}
514101099Srwatson
515101099Srwatsonstatic int
516104514Srwatsonmac_biba_init_label_waitcheck(struct label *label, int flag)
517101099Srwatson{
518101099Srwatson
519132781Skan	SLOT_SET(label, biba_alloc(flag));
520101099Srwatson	if (SLOT(label) == NULL)
521101099Srwatson		return (ENOMEM);
522101099Srwatson
523101099Srwatson	return (0);
524101099Srwatson}
525101099Srwatson
526101099Srwatsonstatic void
527104514Srwatsonmac_biba_destroy_label(struct label *label)
528101099Srwatson{
529101099Srwatson
530101099Srwatson	biba_free(SLOT(label));
531132781Skan	SLOT_SET(label, NULL);
532101099Srwatson}
533101099Srwatson
534105696Srwatson/*
535115497Srwatson * mac_biba_element_to_string() accepts an sbuf and Biba element.  It
536115497Srwatson * converts the Biba element to a string and stores the result in the
537115497Srwatson * sbuf; if there isn't space in the sbuf, -1 is returned.
538105696Srwatson */
539115497Srwatsonstatic int
540115497Srwatsonmac_biba_element_to_string(struct sbuf *sb, struct mac_biba_element *element)
541105696Srwatson{
542115497Srwatson	int i, first;
543105696Srwatson
544105696Srwatson	switch (element->mbe_type) {
545105696Srwatson	case MAC_BIBA_TYPE_HIGH:
546115497Srwatson		return (sbuf_printf(sb, "high"));
547105696Srwatson
548105696Srwatson	case MAC_BIBA_TYPE_LOW:
549115497Srwatson		return (sbuf_printf(sb, "low"));
550105696Srwatson
551105696Srwatson	case MAC_BIBA_TYPE_EQUAL:
552115497Srwatson		return (sbuf_printf(sb, "equal"));
553105696Srwatson
554105696Srwatson	case MAC_BIBA_TYPE_GRADE:
555115497Srwatson		if (sbuf_printf(sb, "%d", element->mbe_grade) == -1)
556115497Srwatson			return (-1);
557115497Srwatson
558115497Srwatson		first = 1;
559115497Srwatson		for (i = 1; i <= MAC_BIBA_MAX_COMPARTMENTS; i++) {
560115497Srwatson			if (MAC_BIBA_BIT_TEST(i, element->mbe_compartments)) {
561115497Srwatson				if (first) {
562115497Srwatson					if (sbuf_putc(sb, ':') == -1)
563115497Srwatson						return (-1);
564115497Srwatson					if (sbuf_printf(sb, "%d", i) == -1)
565115497Srwatson						return (-1);
566115497Srwatson					first = 0;
567115497Srwatson				} else {
568115497Srwatson					if (sbuf_printf(sb, "+%d", i) == -1)
569115497Srwatson						return (-1);
570115497Srwatson				}
571115497Srwatson			}
572105696Srwatson		}
573115497Srwatson		return (0);
574105696Srwatson
575105696Srwatson	default:
576105696Srwatson		panic("mac_biba_element_to_string: invalid type (%d)",
577105696Srwatson		    element->mbe_type);
578105696Srwatson	}
579105696Srwatson}
580105696Srwatson
581115497Srwatson/*
582116701Srwatson * mac_biba_to_string() converts a Biba label to a string, and places
583116701Srwatson * the results in the passed sbuf.  It returns 0 on success, or EINVAL
584116701Srwatson * if there isn't room in the sbuf.  Note: the sbuf will be modified
585116701Srwatson * even in a failure case, so the caller may need to revert the sbuf
586116701Srwatson * by restoring the offset if that's undesired.
587115497Srwatson */
588101099Srwatsonstatic int
589116701Srwatsonmac_biba_to_string(struct sbuf *sb, struct mac_biba *mac_biba)
590101099Srwatson{
591105696Srwatson
592132232Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
593132232Srwatson		if (mac_biba_element_to_string(sb, &mac_biba->mb_effective)
594115497Srwatson		    == -1)
595105696Srwatson			return (EINVAL);
596105696Srwatson	}
597105696Srwatson
598105696Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
599116701Srwatson		if (sbuf_putc(sb, '(') == -1)
600105696Srwatson			return (EINVAL);
601105696Srwatson
602116701Srwatson		if (mac_biba_element_to_string(sb, &mac_biba->mb_rangelow)
603115497Srwatson		    == -1)
604105696Srwatson			return (EINVAL);
605105696Srwatson
606116701Srwatson		if (sbuf_putc(sb, '-') == -1)
607105696Srwatson			return (EINVAL);
608105696Srwatson
609116701Srwatson		if (mac_biba_element_to_string(sb, &mac_biba->mb_rangehigh)
610115497Srwatson		    == -1)
611105696Srwatson			return (EINVAL);
612105696Srwatson
613116701Srwatson		if (sbuf_putc(sb, ')') == -1)
614105696Srwatson			return (EINVAL);
615105696Srwatson	}
616105696Srwatson
617105696Srwatson	return (0);
618105696Srwatson}
619105696Srwatson
620105696Srwatsonstatic int
621105696Srwatsonmac_biba_externalize_label(struct label *label, char *element_name,
622116701Srwatson    struct sbuf *sb, int *claimed)
623105696Srwatson{
624101099Srwatson	struct mac_biba *mac_biba;
625101099Srwatson
626105696Srwatson	if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0)
627105696Srwatson		return (0);
628105696Srwatson
629105696Srwatson	(*claimed)++;
630105696Srwatson
631101099Srwatson	mac_biba = SLOT(label);
632116701Srwatson	return (mac_biba_to_string(sb, mac_biba));
633105696Srwatson}
634105696Srwatson
635105696Srwatsonstatic int
636105696Srwatsonmac_biba_parse_element(struct mac_biba_element *element, char *string)
637101099Srwatson{
638115395Srwatson	char *compartment, *end, *grade;
639115395Srwatson	int value;
640105696Srwatson
641105696Srwatson	if (strcmp(string, "high") == 0 ||
642105696Srwatson	    strcmp(string, "hi") == 0) {
643105696Srwatson		element->mbe_type = MAC_BIBA_TYPE_HIGH;
644105696Srwatson		element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
645105696Srwatson	} else if (strcmp(string, "low") == 0 ||
646105696Srwatson	    strcmp(string, "lo") == 0) {
647105696Srwatson		element->mbe_type = MAC_BIBA_TYPE_LOW;
648105696Srwatson		element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
649105696Srwatson	} else if (strcmp(string, "equal") == 0 ||
650105696Srwatson	    strcmp(string, "eq") == 0) {
651105696Srwatson		element->mbe_type = MAC_BIBA_TYPE_EQUAL;
652105696Srwatson		element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
653105696Srwatson	} else {
654115395Srwatson		element->mbe_type = MAC_BIBA_TYPE_GRADE;
655105696Srwatson
656115395Srwatson		/*
657115395Srwatson		 * Numeric grade piece of the element.
658115395Srwatson		 */
659115395Srwatson		grade = strsep(&string, ":");
660115395Srwatson		value = strtol(grade, &end, 10);
661115395Srwatson		if (end == grade || *end != '\0')
662105696Srwatson			return (EINVAL);
663115395Srwatson		if (value < 0 || value > 65535)
664115395Srwatson			return (EINVAL);
665115395Srwatson		element->mbe_grade = value;
666105696Srwatson
667115395Srwatson		/*
668115395Srwatson		 * Optional compartment piece of the element.  If none
669115395Srwatson		 * are included, we assume that the label has no
670115395Srwatson		 * compartments.
671115395Srwatson		 */
672115395Srwatson		if (string == NULL)
673115395Srwatson			return (0);
674115395Srwatson		if (*string == '\0')
675115395Srwatson			return (0);
676105696Srwatson
677115395Srwatson		while ((compartment = strsep(&string, "+")) != NULL) {
678115395Srwatson			value = strtol(compartment, &end, 10);
679115395Srwatson			if (compartment == end || *end != '\0')
680105696Srwatson				return (EINVAL);
681115395Srwatson			if (value < 1 || value > MAC_BIBA_MAX_COMPARTMENTS)
682105696Srwatson				return (EINVAL);
683115395Srwatson			MAC_BIBA_BIT_SET(value, element->mbe_compartments);
684105696Srwatson		}
685105696Srwatson	}
686105696Srwatson
687105696Srwatson	return (0);
688105696Srwatson}
689105696Srwatson
690105696Srwatson/*
691105696Srwatson * Note: destructively consumes the string, make a local copy before
692105696Srwatson * calling if that's a problem.
693105696Srwatson */
694105696Srwatsonstatic int
695105696Srwatsonmac_biba_parse(struct mac_biba *mac_biba, char *string)
696105696Srwatson{
697132232Srwatson	char *rangehigh, *rangelow, *effective;
698101099Srwatson	int error;
699101099Srwatson
700132232Srwatson	effective = strsep(&string, "(");
701132232Srwatson	if (*effective == '\0')
702132232Srwatson		effective = NULL;
703115395Srwatson
704115395Srwatson	if (string != NULL) {
705115395Srwatson		rangelow = strsep(&string, "-");
706115395Srwatson		if (string == NULL)
707105696Srwatson			return (EINVAL);
708115395Srwatson		rangehigh = strsep(&string, ")");
709115395Srwatson		if (string == NULL)
710105696Srwatson			return (EINVAL);
711115395Srwatson		if (*string != '\0')
712105696Srwatson			return (EINVAL);
713115395Srwatson	} else {
714115395Srwatson		rangelow = NULL;
715115395Srwatson		rangehigh = NULL;
716105696Srwatson	}
717115395Srwatson
718105696Srwatson	KASSERT((rangelow != NULL && rangehigh != NULL) ||
719105696Srwatson	    (rangelow == NULL && rangehigh == NULL),
720115395Srwatson	    ("mac_biba_parse: range mismatch"));
721101099Srwatson
722105696Srwatson	bzero(mac_biba, sizeof(*mac_biba));
723132232Srwatson	if (effective != NULL) {
724132232Srwatson		error = mac_biba_parse_element(&mac_biba->mb_effective, effective);
725105696Srwatson		if (error)
726105696Srwatson			return (error);
727132232Srwatson		mac_biba->mb_flags |= MAC_BIBA_FLAG_EFFECTIVE;
728105696Srwatson	}
729105696Srwatson
730105696Srwatson	if (rangelow != NULL) {
731105696Srwatson		error = mac_biba_parse_element(&mac_biba->mb_rangelow,
732105696Srwatson		    rangelow);
733105696Srwatson		if (error)
734105696Srwatson			return (error);
735105696Srwatson		error = mac_biba_parse_element(&mac_biba->mb_rangehigh,
736105696Srwatson		    rangehigh);
737105696Srwatson		if (error)
738105696Srwatson			return (error);
739105696Srwatson		mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE;
740105696Srwatson	}
741105696Srwatson
742101099Srwatson	error = mac_biba_valid(mac_biba);
743101099Srwatson	if (error)
744101099Srwatson		return (error);
745101099Srwatson
746105696Srwatson	return (0);
747105696Srwatson}
748101099Srwatson
749105696Srwatsonstatic int
750105696Srwatsonmac_biba_internalize_label(struct label *label, char *element_name,
751105696Srwatson    char *element_data, int *claimed)
752105696Srwatson{
753105696Srwatson	struct mac_biba *mac_biba, mac_biba_temp;
754105696Srwatson	int error;
755105696Srwatson
756105696Srwatson	if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0)
757105696Srwatson		return (0);
758105696Srwatson
759105696Srwatson	(*claimed)++;
760105696Srwatson
761105696Srwatson	error = mac_biba_parse(&mac_biba_temp, element_data);
762105696Srwatson	if (error)
763105696Srwatson		return (error);
764105696Srwatson
765105696Srwatson	mac_biba = SLOT(label);
766105696Srwatson	*mac_biba = mac_biba_temp;
767105696Srwatson
768101099Srwatson	return (0);
769101099Srwatson}
770101099Srwatson
771105696Srwatsonstatic void
772105696Srwatsonmac_biba_copy_label(struct label *src, struct label *dest)
773105696Srwatson{
774105696Srwatson
775105696Srwatson	*SLOT(dest) = *SLOT(src);
776105696Srwatson}
777105696Srwatson
778101099Srwatson/*
779101099Srwatson * Labeling event operations: file system objects, and things that look
780101099Srwatson * a lot like file system objects.
781101099Srwatson */
782101099Srwatsonstatic void
783130585Sphkmac_biba_create_devfs_device(struct mount *mp, struct cdev *dev,
784107698Srwatson    struct devfs_dirent *devfs_dirent, struct label *label)
785101099Srwatson{
786101099Srwatson	struct mac_biba *mac_biba;
787101099Srwatson	int biba_type;
788101099Srwatson
789101099Srwatson	mac_biba = SLOT(label);
790101099Srwatson	if (strcmp(dev->si_name, "null") == 0 ||
791101099Srwatson	    strcmp(dev->si_name, "zero") == 0 ||
792101099Srwatson	    strcmp(dev->si_name, "random") == 0 ||
793101099Srwatson	    strncmp(dev->si_name, "fd/", strlen("fd/")) == 0)
794101099Srwatson		biba_type = MAC_BIBA_TYPE_EQUAL;
795105606Srwatson	else if (ptys_equal &&
796105606Srwatson	    (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 ||
797105606Srwatson	    strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0))
798105606Srwatson		biba_type = MAC_BIBA_TYPE_EQUAL;
799101099Srwatson	else
800101099Srwatson		biba_type = MAC_BIBA_TYPE_HIGH;
801132232Srwatson	mac_biba_set_effective(mac_biba, biba_type, 0, NULL);
802101099Srwatson}
803101099Srwatson
804101099Srwatsonstatic void
805107698Srwatsonmac_biba_create_devfs_directory(struct mount *mp, char *dirname,
806107698Srwatson    int dirnamelen, struct devfs_dirent *devfs_dirent, struct label *label)
807101099Srwatson{
808101099Srwatson	struct mac_biba *mac_biba;
809101099Srwatson
810101099Srwatson	mac_biba = SLOT(label);
811132232Srwatson	mac_biba_set_effective(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
812101099Srwatson}
813101099Srwatson
814101099Srwatsonstatic void
815107698Srwatsonmac_biba_create_devfs_symlink(struct ucred *cred, struct mount *mp,
816107698Srwatson    struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de,
817122563Srwatson    struct label *delabel)
818104535Srwatson{
819104535Srwatson	struct mac_biba *source, *dest;
820104535Srwatson
821122524Srwatson	source = SLOT(cred->cr_label);
822104535Srwatson	dest = SLOT(delabel);
823104535Srwatson
824132232Srwatson	mac_biba_copy_effective(source, dest);
825104535Srwatson}
826104535Srwatson
827104535Srwatsonstatic void
828101099Srwatsonmac_biba_create_mount(struct ucred *cred, struct mount *mp,
829101099Srwatson    struct label *mntlabel, struct label *fslabel)
830101099Srwatson{
831101099Srwatson	struct mac_biba *source, *dest;
832101099Srwatson
833122524Srwatson	source = SLOT(cred->cr_label);
834101099Srwatson	dest = SLOT(mntlabel);
835132232Srwatson	mac_biba_copy_effective(source, dest);
836101099Srwatson	dest = SLOT(fslabel);
837132232Srwatson	mac_biba_copy_effective(source, dest);
838101099Srwatson}
839101099Srwatson
840101099Srwatsonstatic void
841101099Srwatsonmac_biba_create_root_mount(struct ucred *cred, struct mount *mp,
842101099Srwatson    struct label *mntlabel, struct label *fslabel)
843101099Srwatson{
844101099Srwatson	struct mac_biba *mac_biba;
845101099Srwatson
846101099Srwatson	/* Always mount root as high integrity. */
847101099Srwatson	mac_biba = SLOT(fslabel);
848132232Srwatson	mac_biba_set_effective(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
849101099Srwatson	mac_biba = SLOT(mntlabel);
850132232Srwatson	mac_biba_set_effective(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
851101099Srwatson}
852101099Srwatson
853101099Srwatsonstatic void
854101099Srwatsonmac_biba_relabel_vnode(struct ucred *cred, struct vnode *vp,
855101099Srwatson    struct label *vnodelabel, struct label *label)
856101099Srwatson{
857101099Srwatson	struct mac_biba *source, *dest;
858101099Srwatson
859101099Srwatson	source = SLOT(label);
860101099Srwatson	dest = SLOT(vnodelabel);
861101099Srwatson
862105656Srwatson	mac_biba_copy(source, dest);
863101099Srwatson}
864101099Srwatson
865101099Srwatsonstatic void
866107698Srwatsonmac_biba_update_devfsdirent(struct mount *mp,
867107698Srwatson    struct devfs_dirent *devfs_dirent, struct label *direntlabel,
868107698Srwatson    struct vnode *vp, struct label *vnodelabel)
869101099Srwatson{
870101099Srwatson	struct mac_biba *source, *dest;
871101099Srwatson
872101099Srwatson	source = SLOT(vnodelabel);
873101099Srwatson	dest = SLOT(direntlabel);
874101099Srwatson
875105656Srwatson	mac_biba_copy(source, dest);
876101099Srwatson}
877101099Srwatson
878101099Srwatsonstatic void
879105988Srwatsonmac_biba_associate_vnode_devfs(struct mount *mp, struct label *fslabel,
880105988Srwatson    struct devfs_dirent *de, struct label *delabel, struct vnode *vp,
881105988Srwatson    struct label *vlabel)
882101099Srwatson{
883101099Srwatson	struct mac_biba *source, *dest;
884101099Srwatson
885105988Srwatson	source = SLOT(delabel);
886105988Srwatson	dest = SLOT(vlabel);
887101099Srwatson
888132232Srwatson	mac_biba_copy_effective(source, dest);
889101099Srwatson}
890101099Srwatson
891101099Srwatsonstatic int
892105988Srwatsonmac_biba_associate_vnode_extattr(struct mount *mp, struct label *fslabel,
893105988Srwatson    struct vnode *vp, struct label *vlabel)
894101099Srwatson{
895105988Srwatson	struct mac_biba temp, *source, *dest;
896106354Smux	int buflen, error;
897101099Srwatson
898105988Srwatson	source = SLOT(fslabel);
899105988Srwatson	dest = SLOT(vlabel);
900101099Srwatson
901105988Srwatson	buflen = sizeof(temp);
902105988Srwatson	bzero(&temp, buflen);
903105988Srwatson
904105988Srwatson	error = vn_extattr_get(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
905105988Srwatson	    MAC_BIBA_EXTATTR_NAME, &buflen, (char *) &temp, curthread);
906105988Srwatson	if (error == ENOATTR || error == EOPNOTSUPP) {
907105988Srwatson		/* Fall back to the fslabel. */
908132232Srwatson		mac_biba_copy_effective(source, dest);
909105988Srwatson		return (0);
910105988Srwatson	} else if (error)
911101099Srwatson		return (error);
912101099Srwatson
913105988Srwatson	if (buflen != sizeof(temp)) {
914105988Srwatson		printf("mac_biba_associate_vnode_extattr: bad size %d\n",
915105988Srwatson		    buflen);
916105988Srwatson		return (EPERM);
917105988Srwatson	}
918105988Srwatson	if (mac_biba_valid(&temp) != 0) {
919105988Srwatson		printf("mac_biba_associate_vnode_extattr: invalid\n");
920105988Srwatson		return (EPERM);
921105988Srwatson	}
922132232Srwatson	if ((temp.mb_flags & MAC_BIBA_FLAGS_BOTH) != MAC_BIBA_FLAG_EFFECTIVE) {
923132232Srwatson		printf("mac_biba_associate_vnode_extattr: not effective\n");
924105988Srwatson		return (EPERM);
925105988Srwatson	}
926101099Srwatson
927132232Srwatson	mac_biba_copy_effective(&temp, dest);
928101099Srwatson	return (0);
929101099Srwatson}
930101099Srwatson
931101099Srwatsonstatic void
932105988Srwatsonmac_biba_associate_vnode_singlelabel(struct mount *mp,
933105988Srwatson    struct label *fslabel, struct vnode *vp, struct label *vlabel)
934101099Srwatson{
935101099Srwatson	struct mac_biba *source, *dest;
936101099Srwatson
937101099Srwatson	source = SLOT(fslabel);
938105988Srwatson	dest = SLOT(vlabel);
939101099Srwatson
940132232Srwatson	mac_biba_copy_effective(source, dest);
941101099Srwatson}
942101099Srwatson
943105988Srwatsonstatic int
944105988Srwatsonmac_biba_create_vnode_extattr(struct ucred *cred, struct mount *mp,
945105988Srwatson    struct label *fslabel, struct vnode *dvp, struct label *dlabel,
946105988Srwatson    struct vnode *vp, struct label *vlabel, struct componentname *cnp)
947105988Srwatson{
948105988Srwatson	struct mac_biba *source, *dest, temp;
949105988Srwatson	size_t buflen;
950105988Srwatson	int error;
951105988Srwatson
952105988Srwatson	buflen = sizeof(temp);
953105988Srwatson	bzero(&temp, buflen);
954105988Srwatson
955122524Srwatson	source = SLOT(cred->cr_label);
956105988Srwatson	dest = SLOT(vlabel);
957132232Srwatson	mac_biba_copy_effective(source, &temp);
958105988Srwatson
959105988Srwatson	error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
960105988Srwatson	    MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread);
961105988Srwatson	if (error == 0)
962132232Srwatson		mac_biba_copy_effective(source, dest);
963105988Srwatson	return (error);
964105988Srwatson}
965105988Srwatson
966105988Srwatsonstatic int
967105988Srwatsonmac_biba_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp,
968105988Srwatson    struct label *vlabel, struct label *intlabel)
969105988Srwatson{
970105988Srwatson	struct mac_biba *source, temp;
971105988Srwatson	size_t buflen;
972105988Srwatson	int error;
973105988Srwatson
974105988Srwatson	buflen = sizeof(temp);
975105988Srwatson	bzero(&temp, buflen);
976105988Srwatson
977105988Srwatson	source = SLOT(intlabel);
978132232Srwatson	if ((source->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) == 0)
979105988Srwatson		return (0);
980105988Srwatson
981132232Srwatson	mac_biba_copy_effective(source, &temp);
982105988Srwatson
983105988Srwatson	error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
984105988Srwatson	    MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread);
985105988Srwatson	return (error);
986105988Srwatson}
987105988Srwatson
988101099Srwatson/*
989101099Srwatson * Labeling event operations: IPC object.
990101099Srwatson */
991101099Srwatsonstatic void
992122875Srwatsonmac_biba_create_inpcb_from_socket(struct socket *so, struct label *solabel,
993122875Srwatson    struct inpcb *inp, struct label *inplabel)
994122875Srwatson{
995122875Srwatson	struct mac_biba *source, *dest;
996122875Srwatson
997122875Srwatson	source = SLOT(solabel);
998122875Srwatson	dest = SLOT(inplabel);
999122875Srwatson
1000132232Srwatson	mac_biba_copy_effective(source, dest);
1001122875Srwatson}
1002122875Srwatson
1003122875Srwatsonstatic void
1004101099Srwatsonmac_biba_create_mbuf_from_socket(struct socket *so, struct label *socketlabel,
1005101099Srwatson    struct mbuf *m, struct label *mbuflabel)
1006101099Srwatson{
1007101099Srwatson	struct mac_biba *source, *dest;
1008101099Srwatson
1009101099Srwatson	source = SLOT(socketlabel);
1010101099Srwatson	dest = SLOT(mbuflabel);
1011101099Srwatson
1012132232Srwatson	mac_biba_copy_effective(source, dest);
1013101099Srwatson}
1014101099Srwatson
1015101099Srwatsonstatic void
1016101099Srwatsonmac_biba_create_socket(struct ucred *cred, struct socket *socket,
1017101099Srwatson    struct label *socketlabel)
1018101099Srwatson{
1019101099Srwatson	struct mac_biba *source, *dest;
1020101099Srwatson
1021122524Srwatson	source = SLOT(cred->cr_label);
1022101099Srwatson	dest = SLOT(socketlabel);
1023101099Srwatson
1024132232Srwatson	mac_biba_copy_effective(source, dest);
1025101099Srwatson}
1026101099Srwatson
1027101099Srwatsonstatic void
1028125293Srwatsonmac_biba_create_pipe(struct ucred *cred, struct pipepair *pp,
1029101099Srwatson    struct label *pipelabel)
1030101099Srwatson{
1031101099Srwatson	struct mac_biba *source, *dest;
1032101099Srwatson
1033122524Srwatson	source = SLOT(cred->cr_label);
1034101099Srwatson	dest = SLOT(pipelabel);
1035101099Srwatson
1036132232Srwatson	mac_biba_copy_effective(source, dest);
1037101099Srwatson}
1038101099Srwatson
1039101099Srwatsonstatic void
1040145855Srwatsonmac_biba_create_posix_sem(struct ucred *cred, struct ksem *ksemptr,
1041145855Srwatson    struct label *ks_label)
1042145855Srwatson{
1043145855Srwatson	struct mac_biba *source, *dest;
1044145855Srwatson
1045145855Srwatson	source = SLOT(cred->cr_label);
1046145855Srwatson	dest = SLOT(ks_label);
1047145855Srwatson
1048145855Srwatson	mac_biba_copy_effective(source, dest);
1049145855Srwatson}
1050145855Srwatson
1051145855Srwatsonstatic void
1052101099Srwatsonmac_biba_create_socket_from_socket(struct socket *oldsocket,
1053101099Srwatson    struct label *oldsocketlabel, struct socket *newsocket,
1054101099Srwatson    struct label *newsocketlabel)
1055101099Srwatson{
1056101099Srwatson	struct mac_biba *source, *dest;
1057101099Srwatson
1058101099Srwatson	source = SLOT(oldsocketlabel);
1059101099Srwatson	dest = SLOT(newsocketlabel);
1060101099Srwatson
1061132232Srwatson	mac_biba_copy_effective(source, dest);
1062101099Srwatson}
1063101099Srwatson
1064101099Srwatsonstatic void
1065101099Srwatsonmac_biba_relabel_socket(struct ucred *cred, struct socket *socket,
1066101099Srwatson    struct label *socketlabel, struct label *newlabel)
1067101099Srwatson{
1068101099Srwatson	struct mac_biba *source, *dest;
1069101099Srwatson
1070101099Srwatson	source = SLOT(newlabel);
1071101099Srwatson	dest = SLOT(socketlabel);
1072101099Srwatson
1073105656Srwatson	mac_biba_copy(source, dest);
1074101099Srwatson}
1075101099Srwatson
1076101099Srwatsonstatic void
1077125293Srwatsonmac_biba_relabel_pipe(struct ucred *cred, struct pipepair *pp,
1078101099Srwatson    struct label *pipelabel, struct label *newlabel)
1079101099Srwatson{
1080101099Srwatson	struct mac_biba *source, *dest;
1081101099Srwatson
1082101099Srwatson	source = SLOT(newlabel);
1083101099Srwatson	dest = SLOT(pipelabel);
1084101099Srwatson
1085105656Srwatson	mac_biba_copy(source, dest);
1086101099Srwatson}
1087101099Srwatson
1088101099Srwatsonstatic void
1089101099Srwatsonmac_biba_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel,
1090101099Srwatson    struct socket *socket, struct label *socketpeerlabel)
1091101099Srwatson{
1092101099Srwatson	struct mac_biba *source, *dest;
1093101099Srwatson
1094101099Srwatson	source = SLOT(mbuflabel);
1095101099Srwatson	dest = SLOT(socketpeerlabel);
1096101099Srwatson
1097132232Srwatson	mac_biba_copy_effective(source, dest);
1098101099Srwatson}
1099101099Srwatson
1100101099Srwatson/*
1101140628Srwatson * Labeling event operations: System V IPC objects.
1102140628Srwatson */
1103140628Srwatson
1104140628Srwatsonstatic void
1105140628Srwatsonmac_biba_create_sysv_msgmsg(struct ucred *cred, struct msqid_kernel *msqkptr,
1106140628Srwatson    struct label *msqlabel, struct msg *msgptr, struct label *msglabel)
1107140628Srwatson{
1108140628Srwatson	struct mac_biba *source, *dest;
1109140628Srwatson
1110140628Srwatson	/* Ignore the msgq label */
1111140628Srwatson	source = SLOT(cred->cr_label);
1112140628Srwatson	dest = SLOT(msglabel);
1113140628Srwatson
1114140628Srwatson	mac_biba_copy_effective(source, dest);
1115140628Srwatson}
1116140628Srwatson
1117140628Srwatsonstatic void
1118140628Srwatsonmac_biba_create_sysv_msgqueue(struct ucred *cred,
1119140628Srwatson    struct msqid_kernel *msqkptr, struct label *msqlabel)
1120140628Srwatson{
1121140628Srwatson	struct mac_biba *source, *dest;
1122140628Srwatson
1123140628Srwatson	source = SLOT(cred->cr_label);
1124140628Srwatson	dest = SLOT(msqlabel);
1125140628Srwatson
1126140628Srwatson	mac_biba_copy_effective(source, dest);
1127140628Srwatson}
1128140628Srwatson
1129140628Srwatsonstatic void
1130147091Srwatsonmac_biba_create_sysv_sem(struct ucred *cred, struct semid_kernel *semakptr,
1131140628Srwatson    struct label *semalabel)
1132140628Srwatson{
1133140628Srwatson	struct mac_biba *source, *dest;
1134140628Srwatson
1135140628Srwatson	source = SLOT(cred->cr_label);
1136140628Srwatson	dest = SLOT(semalabel);
1137140628Srwatson
1138140628Srwatson	mac_biba_copy_effective(source, dest);
1139140628Srwatson}
1140140628Srwatson
1141140628Srwatsonstatic void
1142140628Srwatsonmac_biba_create_sysv_shm(struct ucred *cred, struct shmid_kernel *shmsegptr,
1143140628Srwatson    struct label *shmlabel)
1144140628Srwatson{
1145140628Srwatson	struct mac_biba *source, *dest;
1146140628Srwatson
1147140628Srwatson	source = SLOT(cred->cr_label);
1148140628Srwatson	dest = SLOT(shmlabel);
1149140628Srwatson
1150140628Srwatson	mac_biba_copy_effective(source, dest);
1151140628Srwatson}
1152140628Srwatson
1153140628Srwatson/*
1154101099Srwatson * Labeling event operations: network objects.
1155101099Srwatson */
1156101099Srwatsonstatic void
1157101099Srwatsonmac_biba_set_socket_peer_from_socket(struct socket *oldsocket,
1158101099Srwatson    struct label *oldsocketlabel, struct socket *newsocket,
1159101099Srwatson    struct label *newsocketpeerlabel)
1160101099Srwatson{
1161101099Srwatson	struct mac_biba *source, *dest;
1162101099Srwatson
1163101099Srwatson	source = SLOT(oldsocketlabel);
1164101099Srwatson	dest = SLOT(newsocketpeerlabel);
1165101099Srwatson
1166132232Srwatson	mac_biba_copy_effective(source, dest);
1167101099Srwatson}
1168101099Srwatson
1169101099Srwatsonstatic void
1170101099Srwatsonmac_biba_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d,
1171101099Srwatson    struct label *bpflabel)
1172101099Srwatson{
1173101099Srwatson	struct mac_biba *source, *dest;
1174101099Srwatson
1175122524Srwatson	source = SLOT(cred->cr_label);
1176101099Srwatson	dest = SLOT(bpflabel);
1177101099Srwatson
1178132232Srwatson	mac_biba_copy_effective(source, dest);
1179101099Srwatson}
1180101099Srwatson
1181101099Srwatsonstatic void
1182101099Srwatsonmac_biba_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel)
1183101099Srwatson{
1184121816Sbrooks	char tifname[IFNAMSIZ], *p, *q;
1185101099Srwatson	char tiflist[sizeof(trusted_interfaces)];
1186101099Srwatson	struct mac_biba *dest;
1187110350Srwatson	int len, type;
1188101099Srwatson
1189101099Srwatson	dest = SLOT(ifnetlabel);
1190101099Srwatson
1191101099Srwatson	if (ifnet->if_type == IFT_LOOP) {
1192110350Srwatson		type = MAC_BIBA_TYPE_EQUAL;
1193101099Srwatson		goto set;
1194101099Srwatson	}
1195101099Srwatson
1196101099Srwatson	if (trust_all_interfaces) {
1197110350Srwatson		type = MAC_BIBA_TYPE_HIGH;
1198101099Srwatson		goto set;
1199101099Srwatson	}
1200101099Srwatson
1201110350Srwatson	type = MAC_BIBA_TYPE_LOW;
1202101099Srwatson
1203101099Srwatson	if (trusted_interfaces[0] == '\0' ||
1204101099Srwatson	    !strvalid(trusted_interfaces, sizeof(trusted_interfaces)))
1205101099Srwatson		goto set;
1206101099Srwatson
1207106089Srwatson	bzero(tiflist, sizeof(tiflist));
1208101099Srwatson	for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++)
1209101099Srwatson		if(*p != ' ' && *p != '\t')
1210101099Srwatson			*q = *p;
1211101099Srwatson
1212101099Srwatson	for (p = q = tiflist;; p++) {
1213101099Srwatson		if (*p == ',' || *p == '\0') {
1214101099Srwatson			len = p - q;
1215101099Srwatson			if (len < IFNAMSIZ) {
1216101099Srwatson				bzero(tifname, sizeof(tifname));
1217101099Srwatson				bcopy(q, tifname, len);
1218121816Sbrooks				if (strcmp(tifname, ifnet->if_xname) == 0) {
1219110350Srwatson					type = MAC_BIBA_TYPE_HIGH;
1220101099Srwatson					break;
1221101099Srwatson				}
1222106089Srwatson			} else {
1223106089Srwatson				*p = '\0';
1224106089Srwatson				printf("mac_biba warning: interface name "
1225106089Srwatson				    "\"%s\" is too long (must be < %d)\n",
1226106089Srwatson				    q, IFNAMSIZ);
1227101099Srwatson			}
1228101099Srwatson			if (*p == '\0')
1229101099Srwatson				break;
1230101099Srwatson			q = p + 1;
1231101099Srwatson		}
1232101099Srwatson	}
1233101099Srwatsonset:
1234132232Srwatson	mac_biba_set_effective(dest, type, 0, NULL);
1235110350Srwatson	mac_biba_set_range(dest, type, 0, NULL, type, 0, NULL);
1236101099Srwatson}
1237101099Srwatson
1238101099Srwatsonstatic void
1239101099Srwatsonmac_biba_create_ipq(struct mbuf *fragment, struct label *fragmentlabel,
1240101099Srwatson    struct ipq *ipq, struct label *ipqlabel)
1241101099Srwatson{
1242101099Srwatson	struct mac_biba *source, *dest;
1243101099Srwatson
1244101099Srwatson	source = SLOT(fragmentlabel);
1245101099Srwatson	dest = SLOT(ipqlabel);
1246101099Srwatson
1247132232Srwatson	mac_biba_copy_effective(source, dest);
1248101099Srwatson}
1249101099Srwatson
1250101099Srwatsonstatic void
1251101099Srwatsonmac_biba_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel,
1252101099Srwatson    struct mbuf *datagram, struct label *datagramlabel)
1253101099Srwatson{
1254101099Srwatson	struct mac_biba *source, *dest;
1255101099Srwatson
1256101099Srwatson	source = SLOT(ipqlabel);
1257101099Srwatson	dest = SLOT(datagramlabel);
1258101099Srwatson
1259101099Srwatson	/* Just use the head, since we require them all to match. */
1260132232Srwatson	mac_biba_copy_effective(source, dest);
1261101099Srwatson}
1262101099Srwatson
1263101099Srwatsonstatic void
1264101099Srwatsonmac_biba_create_fragment(struct mbuf *datagram, struct label *datagramlabel,
1265101099Srwatson    struct mbuf *fragment, struct label *fragmentlabel)
1266101099Srwatson{
1267101099Srwatson	struct mac_biba *source, *dest;
1268101099Srwatson
1269101099Srwatson	source = SLOT(datagramlabel);
1270101099Srwatson	dest = SLOT(fragmentlabel);
1271101099Srwatson
1272132232Srwatson	mac_biba_copy_effective(source, dest);
1273101099Srwatson}
1274101099Srwatson
1275101099Srwatsonstatic void
1276123607Srwatsonmac_biba_create_mbuf_from_inpcb(struct inpcb *inp, struct label *inplabel,
1277123607Srwatson    struct mbuf *m, struct label *mlabel)
1278123607Srwatson{
1279123607Srwatson	struct mac_biba *source, *dest;
1280123607Srwatson
1281123607Srwatson	source = SLOT(inplabel);
1282123607Srwatson	dest = SLOT(mlabel);
1283123607Srwatson
1284132232Srwatson	mac_biba_copy_effective(source, dest);
1285123607Srwatson}
1286123607Srwatson
1287123607Srwatsonstatic void
1288101099Srwatsonmac_biba_create_mbuf_from_mbuf(struct mbuf *oldmbuf,
1289101099Srwatson    struct label *oldmbuflabel, struct mbuf *newmbuf,
1290101099Srwatson    struct label *newmbuflabel)
1291101099Srwatson{
1292101099Srwatson	struct mac_biba *source, *dest;
1293101099Srwatson
1294101099Srwatson	source = SLOT(oldmbuflabel);
1295101099Srwatson	dest = SLOT(newmbuflabel);
1296101099Srwatson
1297105656Srwatson	/*
1298105656Srwatson	 * Because the source mbuf may not yet have been "created",
1299105696Srwatson	 * just initialized, we do a conditional copy.  Since we don't
1300105656Srwatson	 * allow mbufs to have ranges, do a KASSERT to make sure that
1301105656Srwatson	 * doesn't happen.
1302105656Srwatson	 */
1303105656Srwatson	KASSERT((source->mb_flags & MAC_BIBA_FLAG_RANGE) == 0,
1304105656Srwatson	    ("mac_biba_create_mbuf_from_mbuf: source mbuf has range"));
1305105656Srwatson	mac_biba_copy(source, dest);
1306101099Srwatson}
1307101099Srwatson
1308101099Srwatsonstatic void
1309101099Srwatsonmac_biba_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel,
1310101099Srwatson    struct mbuf *mbuf, struct label *mbuflabel)
1311101099Srwatson{
1312101099Srwatson	struct mac_biba *dest;
1313101099Srwatson
1314101099Srwatson	dest = SLOT(mbuflabel);
1315101099Srwatson
1316132232Srwatson	mac_biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1317101099Srwatson}
1318101099Srwatson
1319101099Srwatsonstatic void
1320101099Srwatsonmac_biba_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel,
1321101099Srwatson    struct mbuf *mbuf, struct label *mbuflabel)
1322101099Srwatson{
1323101099Srwatson	struct mac_biba *source, *dest;
1324101099Srwatson
1325101099Srwatson	source = SLOT(bpflabel);
1326101099Srwatson	dest = SLOT(mbuflabel);
1327101099Srwatson
1328132232Srwatson	mac_biba_copy_effective(source, dest);
1329101099Srwatson}
1330101099Srwatson
1331101099Srwatsonstatic void
1332101099Srwatsonmac_biba_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel,
1333101099Srwatson    struct mbuf *m, struct label *mbuflabel)
1334101099Srwatson{
1335101099Srwatson	struct mac_biba *source, *dest;
1336101099Srwatson
1337101099Srwatson	source = SLOT(ifnetlabel);
1338101099Srwatson	dest = SLOT(mbuflabel);
1339101099Srwatson
1340132232Srwatson	mac_biba_copy_effective(source, dest);
1341101099Srwatson}
1342101099Srwatson
1343101099Srwatsonstatic void
1344101099Srwatsonmac_biba_create_mbuf_multicast_encap(struct mbuf *oldmbuf,
1345101099Srwatson    struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel,
1346101099Srwatson    struct mbuf *newmbuf, struct label *newmbuflabel)
1347101099Srwatson{
1348101099Srwatson	struct mac_biba *source, *dest;
1349101099Srwatson
1350101099Srwatson	source = SLOT(oldmbuflabel);
1351101099Srwatson	dest = SLOT(newmbuflabel);
1352101099Srwatson
1353132232Srwatson	mac_biba_copy_effective(source, dest);
1354101099Srwatson}
1355101099Srwatson
1356101099Srwatsonstatic void
1357101099Srwatsonmac_biba_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel,
1358101099Srwatson    struct mbuf *newmbuf, struct label *newmbuflabel)
1359101099Srwatson{
1360101099Srwatson	struct mac_biba *source, *dest;
1361101099Srwatson
1362101099Srwatson	source = SLOT(oldmbuflabel);
1363101099Srwatson	dest = SLOT(newmbuflabel);
1364101099Srwatson
1365132232Srwatson	mac_biba_copy_effective(source, dest);
1366101099Srwatson}
1367101099Srwatson
1368101099Srwatsonstatic int
1369101099Srwatsonmac_biba_fragment_match(struct mbuf *fragment, struct label *fragmentlabel,
1370101099Srwatson    struct ipq *ipq, struct label *ipqlabel)
1371101099Srwatson{
1372101099Srwatson	struct mac_biba *a, *b;
1373101099Srwatson
1374101099Srwatson	a = SLOT(ipqlabel);
1375101099Srwatson	b = SLOT(fragmentlabel);
1376101099Srwatson
1377132232Srwatson	return (mac_biba_equal_effective(a, b));
1378101099Srwatson}
1379101099Srwatson
1380101099Srwatsonstatic void
1381101099Srwatsonmac_biba_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet,
1382101099Srwatson    struct label *ifnetlabel, struct label *newlabel)
1383101099Srwatson{
1384101099Srwatson	struct mac_biba *source, *dest;
1385101099Srwatson
1386101099Srwatson	source = SLOT(newlabel);
1387101099Srwatson	dest = SLOT(ifnetlabel);
1388101099Srwatson
1389105656Srwatson	mac_biba_copy(source, dest);
1390101099Srwatson}
1391101099Srwatson
1392101099Srwatsonstatic void
1393101099Srwatsonmac_biba_update_ipq(struct mbuf *fragment, struct label *fragmentlabel,
1394101099Srwatson    struct ipq *ipq, struct label *ipqlabel)
1395101099Srwatson{
1396101099Srwatson
1397101099Srwatson	/* NOOP: we only accept matching labels, so no need to update */
1398101099Srwatson}
1399101099Srwatson
1400122875Srwatsonstatic void
1401122875Srwatsonmac_biba_inpcb_sosetlabel(struct socket *so, struct label *solabel,
1402122875Srwatson    struct inpcb *inp, struct label *inplabel)
1403122875Srwatson{
1404122875Srwatson	struct mac_biba *source, *dest;
1405122875Srwatson
1406122875Srwatson	source = SLOT(solabel);
1407122875Srwatson	dest = SLOT(inplabel);
1408122875Srwatson
1409122875Srwatson	mac_biba_copy(source, dest);
1410122875Srwatson}
1411122875Srwatson
1412101099Srwatson/*
1413101099Srwatson * Labeling event operations: processes.
1414101099Srwatson */
1415101099Srwatsonstatic void
1416101099Srwatsonmac_biba_create_proc0(struct ucred *cred)
1417101099Srwatson{
1418101099Srwatson	struct mac_biba *dest;
1419101099Srwatson
1420122524Srwatson	dest = SLOT(cred->cr_label);
1421101099Srwatson
1422132232Srwatson	mac_biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1423105643Srwatson	mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL,
1424105643Srwatson	    MAC_BIBA_TYPE_HIGH, 0, NULL);
1425101099Srwatson}
1426101099Srwatson
1427101099Srwatsonstatic void
1428101099Srwatsonmac_biba_create_proc1(struct ucred *cred)
1429101099Srwatson{
1430101099Srwatson	struct mac_biba *dest;
1431101099Srwatson
1432122524Srwatson	dest = SLOT(cred->cr_label);
1433101099Srwatson
1434132232Srwatson	mac_biba_set_effective(dest, MAC_BIBA_TYPE_HIGH, 0, NULL);
1435105643Srwatson	mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL,
1436105643Srwatson	    MAC_BIBA_TYPE_HIGH, 0, NULL);
1437101099Srwatson}
1438101099Srwatson
1439101099Srwatsonstatic void
1440101099Srwatsonmac_biba_relabel_cred(struct ucred *cred, struct label *newlabel)
1441101099Srwatson{
1442101099Srwatson	struct mac_biba *source, *dest;
1443101099Srwatson
1444101099Srwatson	source = SLOT(newlabel);
1445122524Srwatson	dest = SLOT(cred->cr_label);
1446101099Srwatson
1447105656Srwatson	mac_biba_copy(source, dest);
1448101099Srwatson}
1449101099Srwatson
1450101099Srwatson/*
1451140628Srwatson * Label cleanup/flush operations
1452140628Srwatson */
1453140628Srwatsonstatic void
1454140628Srwatsonmac_biba_cleanup_sysv_msgmsg(struct label *msglabel)
1455140628Srwatson{
1456140628Srwatson
1457140628Srwatson	bzero(SLOT(msglabel), sizeof(struct mac_biba));
1458140628Srwatson}
1459140628Srwatson
1460140628Srwatsonstatic void
1461140628Srwatsonmac_biba_cleanup_sysv_msgqueue(struct label *msqlabel)
1462140628Srwatson{
1463140628Srwatson
1464140628Srwatson	bzero(SLOT(msqlabel), sizeof(struct mac_biba));
1465140628Srwatson}
1466140628Srwatson
1467140628Srwatsonstatic void
1468147091Srwatsonmac_biba_cleanup_sysv_sem(struct label *semalabel)
1469140628Srwatson{
1470140628Srwatson
1471140628Srwatson	bzero(SLOT(semalabel), sizeof(struct mac_biba));
1472140628Srwatson}
1473140628Srwatson
1474140628Srwatsonstatic void
1475140628Srwatsonmac_biba_cleanup_sysv_shm(struct label *shmlabel)
1476140628Srwatson{
1477140628Srwatson	bzero(SLOT(shmlabel), sizeof(struct mac_biba));
1478140628Srwatson}
1479140628Srwatson
1480140628Srwatson/*
1481101099Srwatson * Access control checks.
1482101099Srwatson */
1483101099Srwatsonstatic int
1484101099Srwatsonmac_biba_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel,
1485101099Srwatson    struct ifnet *ifnet, struct label *ifnetlabel)
1486101099Srwatson{
1487101099Srwatson	struct mac_biba *a, *b;
1488101099Srwatson
1489101099Srwatson	if (!mac_biba_enabled)
1490101099Srwatson		return (0);
1491101099Srwatson
1492101099Srwatson	a = SLOT(bpflabel);
1493101099Srwatson	b = SLOT(ifnetlabel);
1494101099Srwatson
1495132232Srwatson	if (mac_biba_equal_effective(a, b))
1496101099Srwatson		return (0);
1497101099Srwatson	return (EACCES);
1498101099Srwatson}
1499101099Srwatson
1500101099Srwatsonstatic int
1501101099Srwatsonmac_biba_check_cred_relabel(struct ucred *cred, struct label *newlabel)
1502101099Srwatson{
1503101099Srwatson	struct mac_biba *subj, *new;
1504105634Srwatson	int error;
1505101099Srwatson
1506122524Srwatson	subj = SLOT(cred->cr_label);
1507101099Srwatson	new = SLOT(newlabel);
1508101099Srwatson
1509101099Srwatson	/*
1510105634Srwatson	 * If there is a Biba label update for the credential, it may
1511132232Srwatson	 * be an update of the effective, range, or both.
1512101099Srwatson	 */
1513105634Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
1514105634Srwatson	if (error)
1515105634Srwatson		return (error);
1516101099Srwatson
1517101099Srwatson	/*
1518105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
1519101099Srwatson	 */
1520105634Srwatson	if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) {
1521105634Srwatson		/*
1522110351Srwatson		 * If the change request modifies both the Biba label
1523132232Srwatson		 * effective and range, check that the new effective will be
1524110351Srwatson		 * in the new range.
1525110351Srwatson		 */
1526110351Srwatson		if ((new->mb_flags & MAC_BIBA_FLAGS_BOTH) ==
1527110351Srwatson		    MAC_BIBA_FLAGS_BOTH &&
1528132232Srwatson		    !mac_biba_effective_in_range(new, new))
1529110351Srwatson			return (EINVAL);
1530110351Srwatson
1531110351Srwatson		/*
1532132232Srwatson		 * To change the Biba effective label on a credential, the
1533132232Srwatson		 * new effective label must be in the current range.
1534105634Srwatson		 */
1535132232Srwatson		if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE &&
1536132232Srwatson		    !mac_biba_effective_in_range(new, subj))
1537105634Srwatson			return (EPERM);
1538101099Srwatson
1539105634Srwatson		/*
1540105634Srwatson		 * To change the Biba range on a credential, the new
1541105634Srwatson		 * range label must be in the current range.
1542105634Srwatson		 */
1543105634Srwatson		if (new->mb_flags & MAC_BIBA_FLAG_RANGE &&
1544105634Srwatson		    !mac_biba_range_in_range(new, subj))
1545105634Srwatson			return (EPERM);
1546101099Srwatson
1547105634Srwatson		/*
1548105634Srwatson		 * To have EQUAL in any component of the new credential
1549105634Srwatson		 * Biba label, the subject must already have EQUAL in
1550105634Srwatson		 * their label.
1551105634Srwatson		 */
1552105634Srwatson		if (mac_biba_contains_equal(new)) {
1553106090Srwatson			error = mac_biba_subject_privileged(subj);
1554105634Srwatson			if (error)
1555105634Srwatson				return (error);
1556105634Srwatson		}
1557105634Srwatson	}
1558105634Srwatson
1559101099Srwatson	return (0);
1560101099Srwatson}
1561101099Srwatson
1562101099Srwatsonstatic int
1563101099Srwatsonmac_biba_check_cred_visible(struct ucred *u1, struct ucred *u2)
1564101099Srwatson{
1565101099Srwatson	struct mac_biba *subj, *obj;
1566101099Srwatson
1567101099Srwatson	if (!mac_biba_enabled)
1568101099Srwatson		return (0);
1569101099Srwatson
1570122524Srwatson	subj = SLOT(u1->cr_label);
1571122524Srwatson	obj = SLOT(u2->cr_label);
1572101099Srwatson
1573101099Srwatson	/* XXX: range */
1574132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
1575101099Srwatson		return (ESRCH);
1576101099Srwatson
1577101099Srwatson	return (0);
1578101099Srwatson}
1579101099Srwatson
1580101099Srwatsonstatic int
1581101099Srwatsonmac_biba_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet,
1582101099Srwatson    struct label *ifnetlabel, struct label *newlabel)
1583101099Srwatson{
1584101099Srwatson	struct mac_biba *subj, *new;
1585105634Srwatson	int error;
1586101099Srwatson
1587122524Srwatson	subj = SLOT(cred->cr_label);
1588101099Srwatson	new = SLOT(newlabel);
1589101099Srwatson
1590105634Srwatson	/*
1591105634Srwatson	 * If there is a Biba label update for the interface, it may
1592132232Srwatson	 * be an update of the effective, range, or both.
1593105634Srwatson	 */
1594105634Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
1595105634Srwatson	if (error)
1596105634Srwatson		return (error);
1597101099Srwatson
1598105634Srwatson	/*
1599106160Srwatson	 * Relabling network interfaces requires Biba privilege.
1600106160Srwatson	 */
1601106160Srwatson	error = mac_biba_subject_privileged(subj);
1602106160Srwatson	if (error)
1603106160Srwatson		return (error);
1604106160Srwatson
1605105634Srwatson	return (0);
1606101099Srwatson}
1607101099Srwatson
1608103759Srwatsonstatic int
1609101099Srwatsonmac_biba_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel,
1610101099Srwatson    struct mbuf *m, struct label *mbuflabel)
1611101099Srwatson{
1612101099Srwatson	struct mac_biba *p, *i;
1613103761Srwatson
1614101099Srwatson	if (!mac_biba_enabled)
1615101099Srwatson		return (0);
1616101099Srwatson
1617101099Srwatson	p = SLOT(mbuflabel);
1618101099Srwatson	i = SLOT(ifnetlabel);
1619103759Srwatson
1620132232Srwatson	return (mac_biba_effective_in_range(p, i) ? 0 : EACCES);
1621101099Srwatson}
1622101099Srwatson
1623101099Srwatsonstatic int
1624122875Srwatsonmac_biba_check_inpcb_deliver(struct inpcb *inp, struct label *inplabel,
1625122875Srwatson    struct mbuf *m, struct label *mlabel)
1626122875Srwatson{
1627122875Srwatson	struct mac_biba *p, *i;
1628122875Srwatson
1629122875Srwatson	if (!mac_biba_enabled)
1630122875Srwatson		return (0);
1631122875Srwatson
1632122875Srwatson	p = SLOT(mlabel);
1633122875Srwatson	i = SLOT(inplabel);
1634122875Srwatson
1635132232Srwatson	return (mac_biba_equal_effective(p, i) ? 0 : EACCES);
1636122875Srwatson}
1637122875Srwatson
1638122875Srwatsonstatic int
1639140628Srwatsonmac_biba_check_sysv_msgrcv(struct ucred *cred, struct msg *msgptr,
1640140628Srwatson    struct label *msglabel)
1641140628Srwatson{
1642140628Srwatson	struct mac_biba *subj, *obj;
1643140628Srwatson
1644140628Srwatson	if (!mac_biba_enabled)
1645140628Srwatson		return (0);
1646140628Srwatson
1647140628Srwatson	subj = SLOT(cred->cr_label);
1648140628Srwatson	obj = SLOT(msglabel);
1649140628Srwatson
1650140628Srwatson	if (!mac_biba_dominate_effective(obj, subj))
1651140628Srwatson		return (EACCES);
1652140628Srwatson
1653140628Srwatson	return (0);
1654140628Srwatson}
1655140628Srwatson
1656140628Srwatsonstatic int
1657140628Srwatsonmac_biba_check_sysv_msgrmid(struct ucred *cred, struct msg *msgptr,
1658140628Srwatson    struct label *msglabel)
1659140628Srwatson{
1660140628Srwatson	struct mac_biba *subj, *obj;
1661140628Srwatson
1662140628Srwatson	if (!mac_biba_enabled)
1663140628Srwatson		return (0);
1664140628Srwatson
1665140628Srwatson	subj = SLOT(cred->cr_label);
1666140628Srwatson	obj = SLOT(msglabel);
1667140628Srwatson
1668140628Srwatson	if (!mac_biba_dominate_effective(subj, obj))
1669140628Srwatson		return (EACCES);
1670140628Srwatson
1671140628Srwatson	return (0);
1672140628Srwatson}
1673140628Srwatson
1674140628Srwatsonstatic int
1675140628Srwatsonmac_biba_check_sysv_msqget(struct ucred *cred, struct msqid_kernel *msqkptr,
1676140628Srwatson    struct label *msqklabel)
1677140628Srwatson{
1678140628Srwatson	struct mac_biba *subj, *obj;
1679140628Srwatson
1680140628Srwatson	if (!mac_biba_enabled)
1681140628Srwatson		return (0);
1682140628Srwatson
1683140628Srwatson	subj = SLOT(cred->cr_label);
1684140628Srwatson	obj = SLOT(msqklabel);
1685140628Srwatson
1686140628Srwatson	if (!mac_biba_dominate_effective(obj, subj))
1687140628Srwatson		return (EACCES);
1688140628Srwatson
1689140628Srwatson	return (0);
1690140628Srwatson}
1691140628Srwatson
1692140628Srwatsonstatic int
1693140628Srwatsonmac_biba_check_sysv_msqsnd(struct ucred *cred, struct msqid_kernel *msqkptr,
1694140628Srwatson    struct label *msqklabel)
1695140628Srwatson{
1696140628Srwatson	struct mac_biba *subj, *obj;
1697140628Srwatson
1698140628Srwatson	if (!mac_biba_enabled)
1699140628Srwatson		return (0);
1700140628Srwatson
1701140628Srwatson	subj = SLOT(cred->cr_label);
1702140628Srwatson	obj = SLOT(msqklabel);
1703140628Srwatson
1704140628Srwatson	if (!mac_biba_dominate_effective(subj, obj))
1705140628Srwatson		return (EACCES);
1706140628Srwatson
1707140628Srwatson	return (0);
1708140628Srwatson}
1709140628Srwatson
1710140628Srwatsonstatic int
1711140628Srwatsonmac_biba_check_sysv_msqrcv(struct ucred *cred, struct msqid_kernel *msqkptr,
1712140628Srwatson    struct label *msqklabel)
1713140628Srwatson{
1714140628Srwatson	struct mac_biba *subj, *obj;
1715140628Srwatson
1716140628Srwatson	if (!mac_biba_enabled)
1717140628Srwatson		return (0);
1718140628Srwatson
1719140628Srwatson	subj = SLOT(cred->cr_label);
1720140628Srwatson	obj = SLOT(msqklabel);
1721140628Srwatson
1722140628Srwatson	if (!mac_biba_dominate_effective(obj, subj))
1723140628Srwatson		return (EACCES);
1724140628Srwatson
1725140628Srwatson	return (0);
1726140628Srwatson}
1727140628Srwatson
1728140628Srwatson
1729140628Srwatsonstatic int
1730140628Srwatsonmac_biba_check_sysv_msqctl(struct ucred *cred, struct msqid_kernel *msqkptr,
1731140628Srwatson    struct label *msqklabel, int cmd)
1732140628Srwatson{
1733140628Srwatson	struct mac_biba *subj, *obj;
1734140628Srwatson
1735140628Srwatson	if (!mac_biba_enabled)
1736140628Srwatson		return (0);
1737140628Srwatson
1738140628Srwatson	subj = SLOT(cred->cr_label);
1739140628Srwatson	obj = SLOT(msqklabel);
1740140628Srwatson
1741140628Srwatson	switch(cmd) {
1742140628Srwatson	case IPC_RMID:
1743140628Srwatson	case IPC_SET:
1744140628Srwatson		if (!mac_biba_dominate_effective(subj, obj))
1745140628Srwatson			return (EACCES);
1746140628Srwatson		break;
1747140628Srwatson
1748140628Srwatson	case IPC_STAT:
1749140628Srwatson		if (!mac_biba_dominate_effective(obj, subj))
1750140628Srwatson			return (EACCES);
1751140628Srwatson		break;
1752140628Srwatson
1753140628Srwatson	default:
1754140628Srwatson		return (EACCES);
1755140628Srwatson	}
1756140628Srwatson
1757140628Srwatson	return (0);
1758140628Srwatson}
1759140628Srwatson
1760140628Srwatsonstatic int
1761140628Srwatsonmac_biba_check_sysv_semctl(struct ucred *cred, struct semid_kernel *semakptr,
1762140628Srwatson    struct label *semaklabel, int cmd)
1763140628Srwatson{
1764140628Srwatson	struct mac_biba *subj, *obj;
1765140628Srwatson
1766140628Srwatson	if (!mac_biba_enabled)
1767140628Srwatson		return (0);
1768140628Srwatson
1769140628Srwatson	subj = SLOT(cred->cr_label);
1770140628Srwatson	obj = SLOT(semaklabel);
1771140628Srwatson
1772140628Srwatson	switch(cmd) {
1773140628Srwatson	case IPC_RMID:
1774140628Srwatson	case IPC_SET:
1775140628Srwatson	case SETVAL:
1776140628Srwatson	case SETALL:
1777140628Srwatson		if (!mac_biba_dominate_effective(subj, obj))
1778140628Srwatson			return (EACCES);
1779140628Srwatson		break;
1780140628Srwatson
1781140628Srwatson	case IPC_STAT:
1782140628Srwatson	case GETVAL:
1783140628Srwatson	case GETPID:
1784140628Srwatson	case GETNCNT:
1785140628Srwatson	case GETZCNT:
1786140628Srwatson	case GETALL:
1787140628Srwatson		if (!mac_biba_dominate_effective(obj, subj))
1788140628Srwatson			return (EACCES);
1789140628Srwatson		break;
1790140628Srwatson
1791140628Srwatson	default:
1792140628Srwatson		return (EACCES);
1793140628Srwatson	}
1794140628Srwatson
1795140628Srwatson	return (0);
1796140628Srwatson}
1797140628Srwatson
1798140628Srwatson
1799140628Srwatsonstatic int
1800140628Srwatsonmac_biba_check_sysv_semget(struct ucred *cred, struct semid_kernel *semakptr,
1801140628Srwatson    struct label *semaklabel)
1802140628Srwatson{
1803140628Srwatson	struct mac_biba *subj, *obj;
1804140628Srwatson
1805140628Srwatson	if (!mac_biba_enabled)
1806140628Srwatson		return (0);
1807140628Srwatson
1808140628Srwatson	subj = SLOT(cred->cr_label);
1809140628Srwatson	obj = SLOT(semaklabel);
1810140628Srwatson
1811140628Srwatson	if (!mac_biba_dominate_effective(obj, subj))
1812140628Srwatson		return (EACCES);
1813140628Srwatson
1814140628Srwatson	return (0);
1815140628Srwatson}
1816140628Srwatson
1817140628Srwatson
1818140628Srwatsonstatic int
1819140628Srwatsonmac_biba_check_sysv_semop(struct ucred *cred, struct semid_kernel *semakptr,
1820140628Srwatson    struct label *semaklabel, size_t accesstype)
1821140628Srwatson{
1822140628Srwatson	struct mac_biba *subj, *obj;
1823140628Srwatson
1824140628Srwatson	if (!mac_biba_enabled)
1825140628Srwatson		return (0);
1826140628Srwatson
1827140628Srwatson	subj = SLOT(cred->cr_label);
1828140628Srwatson	obj = SLOT(semaklabel);
1829140628Srwatson
1830140628Srwatson	if (accesstype & SEM_R)
1831140628Srwatson		if (!mac_biba_dominate_effective(obj, subj))
1832140628Srwatson			return (EACCES);
1833140628Srwatson
1834140628Srwatson	if (accesstype & SEM_A)
1835140628Srwatson		if (!mac_biba_dominate_effective(subj, obj))
1836140628Srwatson			return (EACCES);
1837140628Srwatson
1838140628Srwatson	return (0);
1839140628Srwatson}
1840140628Srwatson
1841140628Srwatsonstatic int
1842140628Srwatsonmac_biba_check_sysv_shmat(struct ucred *cred, struct shmid_kernel *shmsegptr,
1843140628Srwatson    struct label *shmseglabel, int shmflg)
1844140628Srwatson{
1845140628Srwatson	struct mac_biba *subj, *obj;
1846140628Srwatson
1847140628Srwatson	if (!mac_biba_enabled)
1848140628Srwatson		return (0);
1849140628Srwatson
1850140628Srwatson	subj = SLOT(cred->cr_label);
1851140628Srwatson	obj = SLOT(shmseglabel);
1852140628Srwatson
1853140628Srwatson	if (!mac_biba_dominate_effective(obj, subj))
1854140628Srwatson		return (EACCES);
1855140628Srwatson	if ((shmflg & SHM_RDONLY) == 0) {
1856140628Srwatson		if (!mac_biba_dominate_effective(subj, obj))
1857140628Srwatson			return (EACCES);
1858140628Srwatson	}
1859140628Srwatson
1860140628Srwatson	return (0);
1861140628Srwatson}
1862140628Srwatson
1863140628Srwatsonstatic int
1864140628Srwatsonmac_biba_check_sysv_shmctl(struct ucred *cred, struct shmid_kernel *shmsegptr,
1865140628Srwatson    struct label *shmseglabel, int cmd)
1866140628Srwatson{
1867140628Srwatson	struct mac_biba *subj, *obj;
1868140628Srwatson
1869140628Srwatson	if (!mac_biba_enabled)
1870140628Srwatson		return (0);
1871140628Srwatson
1872140628Srwatson	subj = SLOT(cred->cr_label);
1873140628Srwatson	obj = SLOT(shmseglabel);
1874140628Srwatson
1875140628Srwatson	switch(cmd) {
1876140628Srwatson	case IPC_RMID:
1877140628Srwatson	case IPC_SET:
1878140628Srwatson		if (!mac_biba_dominate_effective(subj, obj))
1879140628Srwatson			return (EACCES);
1880140628Srwatson		break;
1881140628Srwatson
1882140628Srwatson	case IPC_STAT:
1883140628Srwatson	case SHM_STAT:
1884140628Srwatson		if (!mac_biba_dominate_effective(obj, subj))
1885140628Srwatson			return (EACCES);
1886140628Srwatson		break;
1887140628Srwatson
1888140628Srwatson	default:
1889140628Srwatson		return (EACCES);
1890140628Srwatson	}
1891140628Srwatson
1892140628Srwatson	return (0);
1893140628Srwatson}
1894140628Srwatson
1895140628Srwatsonstatic int
1896140628Srwatsonmac_biba_check_sysv_shmget(struct ucred *cred, struct shmid_kernel *shmsegptr,
1897140628Srwatson    struct label *shmseglabel, int shmflg)
1898140628Srwatson{
1899140628Srwatson	struct mac_biba *subj, *obj;
1900140628Srwatson
1901140628Srwatson	if (!mac_biba_enabled)
1902140628Srwatson		return (0);
1903140628Srwatson
1904140628Srwatson	subj = SLOT(cred->cr_label);
1905140628Srwatson	obj = SLOT(shmseglabel);
1906140628Srwatson
1907140628Srwatson	if (!mac_biba_dominate_effective(obj, subj))
1908140628Srwatson		return (EACCES);
1909140628Srwatson
1910140628Srwatson	return (0);
1911140628Srwatson}
1912140628Srwatson
1913140628Srwatsonstatic int
1914110354Srwatsonmac_biba_check_kld_load(struct ucred *cred, struct vnode *vp,
1915110354Srwatson    struct label *label)
1916110354Srwatson{
1917110354Srwatson	struct mac_biba *subj, *obj;
1918110354Srwatson	int error;
1919110354Srwatson
1920110354Srwatson	if (!mac_biba_enabled)
1921110354Srwatson		return (0);
1922110354Srwatson
1923122524Srwatson	subj = SLOT(cred->cr_label);
1924110354Srwatson
1925110354Srwatson	error = mac_biba_subject_privileged(subj);
1926110354Srwatson	if (error)
1927110354Srwatson		return (error);
1928110354Srwatson
1929110354Srwatson	obj = SLOT(label);
1930132232Srwatson	if (!mac_biba_high_effective(obj))
1931110354Srwatson		return (EACCES);
1932110354Srwatson
1933110354Srwatson	return (0);
1934110354Srwatson}
1935110354Srwatson
1936110354Srwatson
1937110354Srwatsonstatic int
1938110354Srwatsonmac_biba_check_kld_unload(struct ucred *cred)
1939110354Srwatson{
1940110354Srwatson	struct mac_biba *subj;
1941110354Srwatson
1942110354Srwatson	if (!mac_biba_enabled)
1943110354Srwatson		return (0);
1944110354Srwatson
1945122524Srwatson	subj = SLOT(cred->cr_label);
1946110354Srwatson
1947110354Srwatson	return (mac_biba_subject_privileged(subj));
1948110354Srwatson}
1949110354Srwatson
1950110354Srwatsonstatic int
1951101099Srwatsonmac_biba_check_mount_stat(struct ucred *cred, struct mount *mp,
1952101099Srwatson    struct label *mntlabel)
1953101099Srwatson{
1954101099Srwatson	struct mac_biba *subj, *obj;
1955101099Srwatson
1956101099Srwatson	if (!mac_biba_enabled)
1957101099Srwatson		return (0);
1958101099Srwatson
1959122524Srwatson	subj = SLOT(cred->cr_label);
1960101099Srwatson	obj = SLOT(mntlabel);
1961101099Srwatson
1962132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
1963101099Srwatson		return (EACCES);
1964101099Srwatson
1965101099Srwatson	return (0);
1966101099Srwatson}
1967101099Srwatson
1968101099Srwatsonstatic int
1969125293Srwatsonmac_biba_check_pipe_ioctl(struct ucred *cred, struct pipepair *pp,
1970101099Srwatson    struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data)
1971101099Srwatson{
1972103759Srwatson
1973101099Srwatson	if(!mac_biba_enabled)
1974101099Srwatson		return (0);
1975101099Srwatson
1976101099Srwatson	/* XXX: This will be implemented soon... */
1977101099Srwatson
1978101099Srwatson	return (0);
1979101099Srwatson}
1980101099Srwatson
1981101099Srwatsonstatic int
1982125293Srwatsonmac_biba_check_pipe_poll(struct ucred *cred, struct pipepair *pp,
1983102115Srwatson    struct label *pipelabel)
1984101099Srwatson{
1985101099Srwatson	struct mac_biba *subj, *obj;
1986101099Srwatson
1987101099Srwatson	if (!mac_biba_enabled)
1988101099Srwatson		return (0);
1989101099Srwatson
1990122524Srwatson	subj = SLOT(cred->cr_label);
1991101099Srwatson	obj = SLOT((pipelabel));
1992101099Srwatson
1993132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
1994102115Srwatson		return (EACCES);
1995101099Srwatson
1996101099Srwatson	return (0);
1997101099Srwatson}
1998101099Srwatson
1999101099Srwatsonstatic int
2000125293Srwatsonmac_biba_check_pipe_read(struct ucred *cred, struct pipepair *pp,
2001102115Srwatson    struct label *pipelabel)
2002102115Srwatson{
2003102115Srwatson	struct mac_biba *subj, *obj;
2004102115Srwatson
2005102115Srwatson	if (!mac_biba_enabled)
2006102115Srwatson		return (0);
2007102115Srwatson
2008122524Srwatson	subj = SLOT(cred->cr_label);
2009102115Srwatson	obj = SLOT((pipelabel));
2010102115Srwatson
2011132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2012102115Srwatson		return (EACCES);
2013102115Srwatson
2014102115Srwatson	return (0);
2015102115Srwatson}
2016102115Srwatson
2017102115Srwatsonstatic int
2018125293Srwatsonmac_biba_check_pipe_relabel(struct ucred *cred, struct pipepair *pp,
2019101099Srwatson    struct label *pipelabel, struct label *newlabel)
2020101099Srwatson{
2021101099Srwatson	struct mac_biba *subj, *obj, *new;
2022105634Srwatson	int error;
2023101099Srwatson
2024101099Srwatson	new = SLOT(newlabel);
2025122524Srwatson	subj = SLOT(cred->cr_label);
2026101099Srwatson	obj = SLOT(pipelabel);
2027101099Srwatson
2028101099Srwatson	/*
2029105634Srwatson	 * If there is a Biba label update for a pipe, it must be a
2030132232Srwatson	 * effective update.
2031101099Srwatson	 */
2032132232Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE);
2033105634Srwatson	if (error)
2034105634Srwatson		return (error);
2035101099Srwatson
2036101099Srwatson	/*
2037105634Srwatson	 * To perform a relabel of a pipe (Biba label or not), Biba must
2038105634Srwatson	 * authorize the relabel.
2039101099Srwatson	 */
2040132232Srwatson	if (!mac_biba_effective_in_range(obj, subj))
2041101099Srwatson		return (EPERM);
2042101099Srwatson
2043101099Srwatson	/*
2044105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
2045101099Srwatson	 */
2046132232Srwatson	if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
2047105634Srwatson		/*
2048105634Srwatson		 * To change the Biba label on a pipe, the new pipe label
2049105634Srwatson		 * must be in the subject range.
2050105634Srwatson		 */
2051132232Srwatson		if (!mac_biba_effective_in_range(new, subj))
2052105634Srwatson			return (EPERM);
2053101099Srwatson
2054105634Srwatson		/*
2055105634Srwatson		 * To change the Biba label on a pipe to be EQUAL, the
2056105634Srwatson		 * subject must have appropriate privilege.
2057105634Srwatson		 */
2058105634Srwatson		if (mac_biba_contains_equal(new)) {
2059106090Srwatson			error = mac_biba_subject_privileged(subj);
2060105634Srwatson			if (error)
2061105634Srwatson				return (error);
2062105634Srwatson		}
2063105634Srwatson	}
2064105634Srwatson
2065101099Srwatson	return (0);
2066101099Srwatson}
2067101099Srwatson
2068101099Srwatsonstatic int
2069125293Srwatsonmac_biba_check_pipe_stat(struct ucred *cred, struct pipepair *pp,
2070102115Srwatson    struct label *pipelabel)
2071102115Srwatson{
2072102115Srwatson	struct mac_biba *subj, *obj;
2073102115Srwatson
2074102115Srwatson	if (!mac_biba_enabled)
2075102115Srwatson		return (0);
2076102115Srwatson
2077122524Srwatson	subj = SLOT(cred->cr_label);
2078102115Srwatson	obj = SLOT((pipelabel));
2079102115Srwatson
2080132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2081102115Srwatson		return (EACCES);
2082102115Srwatson
2083102115Srwatson	return (0);
2084102115Srwatson}
2085102115Srwatson
2086102115Srwatsonstatic int
2087125293Srwatsonmac_biba_check_pipe_write(struct ucred *cred, struct pipepair *pp,
2088102115Srwatson    struct label *pipelabel)
2089102115Srwatson{
2090102115Srwatson	struct mac_biba *subj, *obj;
2091102115Srwatson
2092102115Srwatson	if (!mac_biba_enabled)
2093102115Srwatson		return (0);
2094102115Srwatson
2095122524Srwatson	subj = SLOT(cred->cr_label);
2096102115Srwatson	obj = SLOT((pipelabel));
2097102115Srwatson
2098132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2099102115Srwatson		return (EACCES);
2100102115Srwatson
2101102115Srwatson	return (0);
2102102115Srwatson}
2103102115Srwatson
2104102115Srwatsonstatic int
2105145855Srwatsonmac_biba_check_posix_sem_write(struct ucred *cred, struct ksem *ksemptr,
2106145855Srwatson    struct label *ks_label)
2107145855Srwatson{
2108145855Srwatson	struct mac_biba *subj, *obj;
2109145855Srwatson
2110145855Srwatson	if (!mac_biba_enabled)
2111145855Srwatson		return (0);
2112145855Srwatson
2113145855Srwatson	subj = SLOT(cred->cr_label);
2114145855Srwatson	obj = SLOT(ks_label);
2115145855Srwatson
2116145855Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2117145855Srwatson		return (EACCES);
2118145855Srwatson
2119145855Srwatson	return (0);
2120145855Srwatson}
2121145855Srwatson
2122145855Srwatsonstatic int
2123145855Srwatsonmac_biba_check_posix_sem_rdonly(struct ucred *cred, struct ksem *ksemptr,
2124145855Srwatson    struct label *ks_label)
2125145855Srwatson{
2126145855Srwatson	struct mac_biba *subj, *obj;
2127145855Srwatson
2128145855Srwatson	if (!mac_biba_enabled)
2129145855Srwatson		return (0);
2130145855Srwatson
2131145855Srwatson	subj = SLOT(cred->cr_label);
2132145855Srwatson	obj = SLOT(ks_label);
2133145855Srwatson
2134145855Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2135145855Srwatson		return (EACCES);
2136145855Srwatson
2137145855Srwatson	return (0);
2138145855Srwatson}
2139145855Srwatson
2140145855Srwatsonstatic int
2141101099Srwatsonmac_biba_check_proc_debug(struct ucred *cred, struct proc *proc)
2142101099Srwatson{
2143101099Srwatson	struct mac_biba *subj, *obj;
2144101099Srwatson
2145101099Srwatson	if (!mac_biba_enabled)
2146101099Srwatson		return (0);
2147101099Srwatson
2148122524Srwatson	subj = SLOT(cred->cr_label);
2149122524Srwatson	obj = SLOT(proc->p_ucred->cr_label);
2150101099Srwatson
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_sched(struct ucred *cred, struct proc *proc)
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
2181101099Srwatsonmac_biba_check_proc_signal(struct ucred *cred, struct proc *proc, int signum)
2182101099Srwatson{
2183101099Srwatson	struct mac_biba *subj, *obj;
2184103759Srwatson
2185101099Srwatson	if (!mac_biba_enabled)
2186101099Srwatson		return (0);
2187101099Srwatson
2188122524Srwatson	subj = SLOT(cred->cr_label);
2189122524Srwatson	obj = SLOT(proc->p_ucred->cr_label);
2190103759Srwatson
2191101099Srwatson	/* XXX: range checks */
2192132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2193101099Srwatson		return (ESRCH);
2194132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2195101099Srwatson		return (EACCES);
2196101099Srwatson
2197101099Srwatson	return (0);
2198101099Srwatson}
2199101099Srwatson
2200101099Srwatsonstatic int
2201101934Srwatsonmac_biba_check_socket_deliver(struct socket *so, struct label *socketlabel,
2202101099Srwatson    struct mbuf *m, struct label *mbuflabel)
2203101099Srwatson{
2204101099Srwatson	struct mac_biba *p, *s;
2205101099Srwatson
2206101099Srwatson	if (!mac_biba_enabled)
2207101099Srwatson		return (0);
2208101099Srwatson
2209101099Srwatson	p = SLOT(mbuflabel);
2210101099Srwatson	s = SLOT(socketlabel);
2211101099Srwatson
2212132232Srwatson	return (mac_biba_equal_effective(p, s) ? 0 : EACCES);
2213101099Srwatson}
2214101099Srwatson
2215101099Srwatsonstatic int
2216106214Srwatsonmac_biba_check_socket_relabel(struct ucred *cred, struct socket *so,
2217101099Srwatson    struct label *socketlabel, struct label *newlabel)
2218101099Srwatson{
2219101099Srwatson	struct mac_biba *subj, *obj, *new;
2220105634Srwatson	int error;
2221101099Srwatson
2222101099Srwatson	new = SLOT(newlabel);
2223122524Srwatson	subj = SLOT(cred->cr_label);
2224101099Srwatson	obj = SLOT(socketlabel);
2225101099Srwatson
2226101099Srwatson	/*
2227105634Srwatson	 * If there is a Biba label update for the socket, it may be
2228132232Srwatson	 * an update of effective.
2229101099Srwatson	 */
2230132232Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE);
2231105634Srwatson	if (error)
2232105634Srwatson		return (error);
2233101099Srwatson
2234101099Srwatson	/*
2235132232Srwatson	 * To relabel a socket, the old socket effective must be in the subject
2236101099Srwatson	 * range.
2237101099Srwatson	 */
2238132232Srwatson	if (!mac_biba_effective_in_range(obj, subj))
2239101099Srwatson		return (EPERM);
2240101099Srwatson
2241101099Srwatson	/*
2242105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
2243101099Srwatson	 */
2244132232Srwatson	if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
2245105634Srwatson		/*
2246132232Srwatson		 * To relabel a socket, the new socket effective must be in
2247105634Srwatson		 * the subject range.
2248105634Srwatson		 */
2249132232Srwatson		if (!mac_biba_effective_in_range(new, subj))
2250105634Srwatson			return (EPERM);
2251101099Srwatson
2252105634Srwatson		/*
2253105634Srwatson		 * To change the Biba label on the socket to contain EQUAL,
2254105634Srwatson		 * the subject must have appropriate privilege.
2255105634Srwatson		 */
2256105634Srwatson		if (mac_biba_contains_equal(new)) {
2257106090Srwatson			error = mac_biba_subject_privileged(subj);
2258105634Srwatson			if (error)
2259105634Srwatson				return (error);
2260105634Srwatson		}
2261105634Srwatson	}
2262105634Srwatson
2263101099Srwatson	return (0);
2264101099Srwatson}
2265101099Srwatson
2266101099Srwatsonstatic int
2267101099Srwatsonmac_biba_check_socket_visible(struct ucred *cred, struct socket *socket,
2268101099Srwatson    struct label *socketlabel)
2269101099Srwatson{
2270101099Srwatson	struct mac_biba *subj, *obj;
2271101099Srwatson
2272105722Srwatson	if (!mac_biba_enabled)
2273105722Srwatson		return (0);
2274105722Srwatson
2275122524Srwatson	subj = SLOT(cred->cr_label);
2276101099Srwatson	obj = SLOT(socketlabel);
2277101099Srwatson
2278132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2279101099Srwatson		return (ENOENT);
2280101099Srwatson
2281101099Srwatson	return (0);
2282101099Srwatson}
2283101099Srwatson
2284101099Srwatsonstatic int
2285112574Srwatsonmac_biba_check_sysarch_ioperm(struct ucred *cred)
2286112574Srwatson{
2287112574Srwatson	struct mac_biba *subj;
2288112574Srwatson	int error;
2289112574Srwatson
2290112574Srwatson	if (!mac_biba_enabled)
2291112574Srwatson		return (0);
2292112574Srwatson
2293122524Srwatson	subj = SLOT(cred->cr_label);
2294112574Srwatson
2295112574Srwatson	error = mac_biba_subject_privileged(subj);
2296112574Srwatson	if (error)
2297112574Srwatson		return (error);
2298112574Srwatson
2299112574Srwatson	return (0);
2300112574Srwatson}
2301112574Srwatson
2302112574Srwatsonstatic int
2303106418Srwatsonmac_biba_check_system_acct(struct ucred *cred, struct vnode *vp,
2304106418Srwatson    struct label *label)
2305106418Srwatson{
2306106418Srwatson	struct mac_biba *subj, *obj;
2307106418Srwatson	int error;
2308106418Srwatson
2309106418Srwatson	if (!mac_biba_enabled)
2310106418Srwatson		return (0);
2311106418Srwatson
2312122524Srwatson	subj = SLOT(cred->cr_label);
2313106418Srwatson
2314106418Srwatson	error = mac_biba_subject_privileged(subj);
2315106418Srwatson	if (error)
2316106418Srwatson		return (error);
2317106418Srwatson
2318106418Srwatson	if (label == NULL)
2319106418Srwatson		return (0);
2320106418Srwatson
2321106418Srwatson	obj = SLOT(label);
2322132232Srwatson	if (!mac_biba_high_effective(obj))
2323106418Srwatson		return (EACCES);
2324106418Srwatson
2325106418Srwatson	return (0);
2326106418Srwatson}
2327106418Srwatson
2328106418Srwatsonstatic int
2329106418Srwatsonmac_biba_check_system_settime(struct ucred *cred)
2330106418Srwatson{
2331106418Srwatson	struct mac_biba *subj;
2332106418Srwatson	int error;
2333106418Srwatson
2334106418Srwatson	if (!mac_biba_enabled)
2335106418Srwatson		return (0);
2336106418Srwatson
2337122524Srwatson	subj = SLOT(cred->cr_label);
2338106418Srwatson
2339106418Srwatson	error = mac_biba_subject_privileged(subj);
2340106418Srwatson	if (error)
2341106418Srwatson		return (error);
2342106418Srwatson
2343106418Srwatson	return (0);
2344106418Srwatson}
2345106418Srwatson
2346106418Srwatsonstatic int
2347106161Srwatsonmac_biba_check_system_swapon(struct ucred *cred, struct vnode *vp,
2348106161Srwatson    struct label *label)
2349106161Srwatson{
2350106161Srwatson	struct mac_biba *subj, *obj;
2351106416Srwatson	int error;
2352106161Srwatson
2353106161Srwatson	if (!mac_biba_enabled)
2354106161Srwatson		return (0);
2355106161Srwatson
2356122524Srwatson	subj = SLOT(cred->cr_label);
2357106161Srwatson	obj = SLOT(label);
2358106161Srwatson
2359106416Srwatson	error = mac_biba_subject_privileged(subj);
2360106416Srwatson	if (error)
2361106416Srwatson		return (error);
2362106161Srwatson
2363132232Srwatson	if (!mac_biba_high_effective(obj))
2364106161Srwatson		return (EACCES);
2365106161Srwatson
2366106161Srwatson	return (0);
2367106161Srwatson}
2368106161Srwatson
2369106161Srwatsonstatic int
2370112574Srwatsonmac_biba_check_system_swapoff(struct ucred *cred, struct vnode *vp,
2371112574Srwatson    struct label *label)
2372112574Srwatson{
2373112574Srwatson	struct mac_biba *subj, *obj;
2374112574Srwatson	int error;
2375112574Srwatson
2376112574Srwatson	if (!mac_biba_enabled)
2377112574Srwatson		return (0);
2378112574Srwatson
2379122524Srwatson	subj = SLOT(cred->cr_label);
2380112574Srwatson	obj = SLOT(label);
2381112574Srwatson
2382112574Srwatson	error = mac_biba_subject_privileged(subj);
2383112574Srwatson	if (error)
2384112574Srwatson		return (error);
2385112574Srwatson
2386112574Srwatson	return (0);
2387112574Srwatson}
2388112574Srwatson
2389112574Srwatsonstatic int
2390126121Spjdmac_biba_check_system_sysctl(struct ucred *cred, struct sysctl_oid *oidp,
2391126121Spjd    void *arg1, int arg2, struct sysctl_req *req)
2392106161Srwatson{
2393106161Srwatson	struct mac_biba *subj;
2394106161Srwatson	int error;
2395106161Srwatson
2396106161Srwatson	if (!mac_biba_enabled)
2397106161Srwatson		return (0);
2398106161Srwatson
2399122524Srwatson	subj = SLOT(cred->cr_label);
2400106161Srwatson
2401106161Srwatson	/*
2402126121Spjd	 * Treat sysctl variables without CTLFLAG_ANYBODY flag as
2403126121Spjd	 * biba/high, but also require privilege to change them.
2404106161Srwatson	 */
2405126121Spjd	if (req->newptr != NULL && (oidp->oid_kind & CTLFLAG_ANYBODY) == 0) {
2406106161Srwatson		if (!mac_biba_subject_dominate_high(subj))
2407106161Srwatson			return (EACCES);
2408106161Srwatson
2409106161Srwatson		error = mac_biba_subject_privileged(subj);
2410106161Srwatson		if (error)
2411106161Srwatson			return (error);
2412106161Srwatson	}
2413106161Srwatson
2414106161Srwatson	return (0);
2415106161Srwatson}
2416106161Srwatson
2417106161Srwatsonstatic int
2418101099Srwatsonmac_biba_check_vnode_chdir(struct ucred *cred, struct vnode *dvp,
2419101099Srwatson    struct label *dlabel)
2420101099Srwatson{
2421101099Srwatson	struct mac_biba *subj, *obj;
2422101099Srwatson
2423101099Srwatson	if (!mac_biba_enabled)
2424101099Srwatson		return (0);
2425101099Srwatson
2426122524Srwatson	subj = SLOT(cred->cr_label);
2427101099Srwatson	obj = SLOT(dlabel);
2428101099Srwatson
2429132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2430101099Srwatson		return (EACCES);
2431101099Srwatson
2432101099Srwatson	return (0);
2433101099Srwatson}
2434101099Srwatson
2435101099Srwatsonstatic int
2436101099Srwatsonmac_biba_check_vnode_chroot(struct ucred *cred, struct vnode *dvp,
2437101099Srwatson    struct label *dlabel)
2438101099Srwatson{
2439101099Srwatson	struct mac_biba *subj, *obj;
2440101099Srwatson
2441101099Srwatson	if (!mac_biba_enabled)
2442101099Srwatson		return (0);
2443101099Srwatson
2444122524Srwatson	subj = SLOT(cred->cr_label);
2445101099Srwatson	obj = SLOT(dlabel);
2446101099Srwatson
2447132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2448101099Srwatson		return (EACCES);
2449101099Srwatson
2450101099Srwatson	return (0);
2451101099Srwatson}
2452101099Srwatson
2453101099Srwatsonstatic int
2454101099Srwatsonmac_biba_check_vnode_create(struct ucred *cred, struct vnode *dvp,
2455101099Srwatson    struct label *dlabel, struct componentname *cnp, struct vattr *vap)
2456101099Srwatson{
2457101099Srwatson	struct mac_biba *subj, *obj;
2458101099Srwatson
2459101099Srwatson	if (!mac_biba_enabled)
2460101099Srwatson		return (0);
2461101099Srwatson
2462122524Srwatson	subj = SLOT(cred->cr_label);
2463101099Srwatson	obj = SLOT(dlabel);
2464101099Srwatson
2465132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2466101099Srwatson		return (EACCES);
2467101099Srwatson
2468101099Srwatson	return (0);
2469101099Srwatson}
2470101099Srwatson
2471101099Srwatsonstatic int
2472101099Srwatsonmac_biba_check_vnode_delete(struct ucred *cred, struct vnode *dvp,
2473101099Srwatson    struct label *dlabel, struct vnode *vp, struct label *label,
2474101099Srwatson    struct componentname *cnp)
2475101099Srwatson{
2476101099Srwatson	struct mac_biba *subj, *obj;
2477101099Srwatson
2478101099Srwatson	if (!mac_biba_enabled)
2479101099Srwatson		return (0);
2480101099Srwatson
2481122524Srwatson	subj = SLOT(cred->cr_label);
2482101099Srwatson	obj = SLOT(dlabel);
2483101099Srwatson
2484132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2485101099Srwatson		return (EACCES);
2486101099Srwatson
2487101099Srwatson	obj = SLOT(label);
2488101099Srwatson
2489132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2490101099Srwatson		return (EACCES);
2491101099Srwatson
2492101099Srwatson	return (0);
2493101099Srwatson}
2494101099Srwatson
2495101099Srwatsonstatic int
2496101099Srwatsonmac_biba_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
2497101099Srwatson    struct label *label, acl_type_t type)
2498101099Srwatson{
2499101099Srwatson	struct mac_biba *subj, *obj;
2500101099Srwatson
2501101099Srwatson	if (!mac_biba_enabled)
2502101099Srwatson		return (0);
2503101099Srwatson
2504122524Srwatson	subj = SLOT(cred->cr_label);
2505101099Srwatson	obj = SLOT(label);
2506101099Srwatson
2507132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2508101099Srwatson		return (EACCES);
2509101099Srwatson
2510101099Srwatson	return (0);
2511101099Srwatson}
2512101099Srwatson
2513101099Srwatsonstatic int
2514119202Srwatsonmac_biba_check_vnode_deleteextattr(struct ucred *cred, struct vnode *vp,
2515119202Srwatson    struct label *label, int attrnamespace, const char *name)
2516119202Srwatson{
2517119202Srwatson	struct mac_biba *subj, *obj;
2518119202Srwatson
2519119202Srwatson	if (!mac_biba_enabled)
2520119202Srwatson		return (0);
2521119202Srwatson
2522122524Srwatson	subj = SLOT(cred->cr_label);
2523119202Srwatson	obj = SLOT(label);
2524119202Srwatson
2525132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2526119202Srwatson		return (EACCES);
2527119202Srwatson
2528119202Srwatson	return (0);
2529119202Srwatson}
2530119202Srwatson
2531119202Srwatsonstatic int
2532101099Srwatsonmac_biba_check_vnode_exec(struct ucred *cred, struct vnode *vp,
2533106648Srwatson    struct label *label, struct image_params *imgp,
2534106648Srwatson    struct label *execlabel)
2535101099Srwatson{
2536106648Srwatson	struct mac_biba *subj, *obj, *exec;
2537106648Srwatson	int error;
2538101099Srwatson
2539106648Srwatson	if (execlabel != NULL) {
2540106648Srwatson		/*
2541106648Srwatson		 * We currently don't permit labels to be changed at
2542106648Srwatson		 * exec-time as part of Biba, so disallow non-NULL
2543106648Srwatson		 * Biba label elements in the execlabel.
2544106648Srwatson		 */
2545106648Srwatson		exec = SLOT(execlabel);
2546106648Srwatson		error = biba_atmostflags(exec, 0);
2547106648Srwatson		if (error)
2548106648Srwatson			return (error);
2549106648Srwatson	}
2550106648Srwatson
2551101099Srwatson	if (!mac_biba_enabled)
2552101099Srwatson		return (0);
2553101099Srwatson
2554122524Srwatson	subj = SLOT(cred->cr_label);
2555101099Srwatson	obj = SLOT(label);
2556101099Srwatson
2557132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2558101099Srwatson		return (EACCES);
2559101099Srwatson
2560101099Srwatson	return (0);
2561101099Srwatson}
2562101099Srwatson
2563101099Srwatsonstatic int
2564101099Srwatsonmac_biba_check_vnode_getacl(struct ucred *cred, struct vnode *vp,
2565101099Srwatson    struct label *label, acl_type_t type)
2566101099Srwatson{
2567101099Srwatson	struct mac_biba *subj, *obj;
2568101099Srwatson
2569101099Srwatson	if (!mac_biba_enabled)
2570101099Srwatson		return (0);
2571101099Srwatson
2572122524Srwatson	subj = SLOT(cred->cr_label);
2573101099Srwatson	obj = SLOT(label);
2574101099Srwatson
2575132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2576101099Srwatson		return (EACCES);
2577101099Srwatson
2578101099Srwatson	return (0);
2579101099Srwatson}
2580101099Srwatson
2581101099Srwatsonstatic int
2582101099Srwatsonmac_biba_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
2583101099Srwatson    struct label *label, int attrnamespace, const char *name, struct uio *uio)
2584101099Srwatson{
2585101099Srwatson	struct mac_biba *subj, *obj;
2586101099Srwatson
2587101099Srwatson	if (!mac_biba_enabled)
2588101099Srwatson		return (0);
2589101099Srwatson
2590122524Srwatson	subj = SLOT(cred->cr_label);
2591101099Srwatson	obj = SLOT(label);
2592101099Srwatson
2593132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2594101099Srwatson		return (EACCES);
2595101099Srwatson
2596101099Srwatson	return (0);
2597101099Srwatson}
2598101099Srwatson
2599101099Srwatsonstatic int
2600104530Srwatsonmac_biba_check_vnode_link(struct ucred *cred, struct vnode *dvp,
2601104530Srwatson    struct label *dlabel, struct vnode *vp, struct label *label,
2602104530Srwatson    struct componentname *cnp)
2603104530Srwatson{
2604104530Srwatson	struct mac_biba *subj, *obj;
2605104530Srwatson
2606104530Srwatson	if (!mac_biba_enabled)
2607104530Srwatson		return (0);
2608104530Srwatson
2609122524Srwatson	subj = SLOT(cred->cr_label);
2610104530Srwatson	obj = SLOT(dlabel);
2611104530Srwatson
2612132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2613104530Srwatson		return (EACCES);
2614104530Srwatson
2615104530Srwatson	obj = SLOT(label);
2616104530Srwatson
2617132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2618104530Srwatson		return (EACCES);
2619104530Srwatson
2620104530Srwatson	return (0);
2621104530Srwatson}
2622104530Srwatson
2623104530Srwatsonstatic int
2624119202Srwatsonmac_biba_check_vnode_listextattr(struct ucred *cred, struct vnode *vp,
2625119202Srwatson    struct label *label, int attrnamespace)
2626119202Srwatson{
2627119202Srwatson	struct mac_biba *subj, *obj;
2628119202Srwatson
2629119202Srwatson	if (!mac_biba_enabled)
2630119202Srwatson		return (0);
2631119202Srwatson
2632122524Srwatson	subj = SLOT(cred->cr_label);
2633119202Srwatson	obj = SLOT(label);
2634119202Srwatson
2635132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2636119202Srwatson		return (EACCES);
2637119202Srwatson
2638119202Srwatson	return (0);
2639119202Srwatson}
2640119202Srwatson
2641119202Srwatsonstatic int
2642103759Srwatsonmac_biba_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
2643101099Srwatson    struct label *dlabel, struct componentname *cnp)
2644101099Srwatson{
2645101099Srwatson	struct mac_biba *subj, *obj;
2646103759Srwatson
2647101099Srwatson	if (!mac_biba_enabled)
2648101099Srwatson		return (0);
2649103759Srwatson
2650122524Srwatson	subj = SLOT(cred->cr_label);
2651101099Srwatson	obj = SLOT(dlabel);
2652103759Srwatson
2653132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2654101099Srwatson		return (EACCES);
2655101099Srwatson
2656103759Srwatson	return (0);
2657101099Srwatson}
2658101099Srwatson
2659101099Srwatsonstatic int
2660104546Srwatsonmac_biba_check_vnode_mmap(struct ucred *cred, struct vnode *vp,
2661145076Scsjp    struct label *label, int prot, int flags)
2662104546Srwatson{
2663104546Srwatson	struct mac_biba *subj, *obj;
2664104546Srwatson
2665104546Srwatson	/*
2666104546Srwatson	 * Rely on the use of open()-time protections to handle
2667104546Srwatson	 * non-revocation cases.
2668104546Srwatson	 */
2669105637Srwatson	if (!mac_biba_enabled || !revocation_enabled)
2670104546Srwatson		return (0);
2671104546Srwatson
2672122524Srwatson	subj = SLOT(cred->cr_label);
2673104546Srwatson	obj = SLOT(label);
2674104546Srwatson
2675104546Srwatson	if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
2676132232Srwatson		if (!mac_biba_dominate_effective(obj, subj))
2677104546Srwatson			return (EACCES);
2678104546Srwatson	}
2679145076Scsjp	if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) {
2680132232Srwatson		if (!mac_biba_dominate_effective(subj, obj))
2681104546Srwatson			return (EACCES);
2682104546Srwatson	}
2683104546Srwatson
2684104569Srwatson	return (0);
2685104546Srwatson}
2686104546Srwatson
2687104546Srwatsonstatic int
2688101099Srwatsonmac_biba_check_vnode_open(struct ucred *cred, struct vnode *vp,
2689106212Srwatson    struct label *vnodelabel, int acc_mode)
2690101099Srwatson{
2691101099Srwatson	struct mac_biba *subj, *obj;
2692101099Srwatson
2693101099Srwatson	if (!mac_biba_enabled)
2694101099Srwatson		return (0);
2695101099Srwatson
2696122524Srwatson	subj = SLOT(cred->cr_label);
2697101099Srwatson	obj = SLOT(vnodelabel);
2698101099Srwatson
2699101099Srwatson	/* XXX privilege override for admin? */
2700101099Srwatson	if (acc_mode & (VREAD | VEXEC | VSTAT)) {
2701132232Srwatson		if (!mac_biba_dominate_effective(obj, subj))
2702101099Srwatson			return (EACCES);
2703101099Srwatson	}
2704101099Srwatson	if (acc_mode & (VWRITE | VAPPEND | VADMIN)) {
2705132232Srwatson		if (!mac_biba_dominate_effective(subj, obj))
2706101099Srwatson			return (EACCES);
2707101099Srwatson	}
2708101099Srwatson
2709101099Srwatson	return (0);
2710101099Srwatson}
2711101099Srwatson
2712101099Srwatsonstatic int
2713102129Srwatsonmac_biba_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred,
2714102129Srwatson    struct vnode *vp, struct label *label)
2715102112Srwatson{
2716102112Srwatson	struct mac_biba *subj, *obj;
2717102112Srwatson
2718105637Srwatson	if (!mac_biba_enabled || !revocation_enabled)
2719102112Srwatson		return (0);
2720102112Srwatson
2721122524Srwatson	subj = SLOT(active_cred->cr_label);
2722102112Srwatson	obj = SLOT(label);
2723102112Srwatson
2724132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2725102112Srwatson		return (EACCES);
2726102112Srwatson
2727102112Srwatson	return (0);
2728102112Srwatson}
2729102112Srwatson
2730102112Srwatsonstatic int
2731102129Srwatsonmac_biba_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
2732102129Srwatson    struct vnode *vp, struct label *label)
2733102112Srwatson{
2734102112Srwatson	struct mac_biba *subj, *obj;
2735102112Srwatson
2736105637Srwatson	if (!mac_biba_enabled || !revocation_enabled)
2737102112Srwatson		return (0);
2738102112Srwatson
2739122524Srwatson	subj = SLOT(active_cred->cr_label);
2740102112Srwatson	obj = SLOT(label);
2741102112Srwatson
2742132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2743102112Srwatson		return (EACCES);
2744102112Srwatson
2745102112Srwatson	return (0);
2746102112Srwatson}
2747102112Srwatson
2748102112Srwatsonstatic int
2749101099Srwatsonmac_biba_check_vnode_readdir(struct ucred *cred, struct vnode *dvp,
2750101099Srwatson    struct label *dlabel)
2751101099Srwatson{
2752101099Srwatson	struct mac_biba *subj, *obj;
2753101099Srwatson
2754101099Srwatson	if (!mac_biba_enabled)
2755101099Srwatson		return (0);
2756101099Srwatson
2757122524Srwatson	subj = SLOT(cred->cr_label);
2758101099Srwatson	obj = SLOT(dlabel);
2759101099Srwatson
2760132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2761101099Srwatson		return (EACCES);
2762101099Srwatson
2763101099Srwatson	return (0);
2764101099Srwatson}
2765101099Srwatson
2766101099Srwatsonstatic int
2767101099Srwatsonmac_biba_check_vnode_readlink(struct ucred *cred, struct vnode *vp,
2768101099Srwatson    struct label *label)
2769101099Srwatson{
2770101099Srwatson	struct mac_biba *subj, *obj;
2771101099Srwatson
2772101099Srwatson	if (!mac_biba_enabled)
2773101099Srwatson		return (0);
2774101099Srwatson
2775122524Srwatson	subj = SLOT(cred->cr_label);
2776101099Srwatson	obj = SLOT(label);
2777101099Srwatson
2778132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2779101099Srwatson		return (EACCES);
2780101099Srwatson
2781101099Srwatson	return (0);
2782101099Srwatson}
2783101099Srwatson
2784101099Srwatsonstatic int
2785101099Srwatsonmac_biba_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
2786101099Srwatson    struct label *vnodelabel, struct label *newlabel)
2787101099Srwatson{
2788101099Srwatson	struct mac_biba *old, *new, *subj;
2789105634Srwatson	int error;
2790101099Srwatson
2791101099Srwatson	old = SLOT(vnodelabel);
2792101099Srwatson	new = SLOT(newlabel);
2793122524Srwatson	subj = SLOT(cred->cr_label);
2794101099Srwatson
2795101099Srwatson	/*
2796105634Srwatson	 * If there is a Biba label update for the vnode, it must be a
2797132232Srwatson	 * effective label.
2798101099Srwatson	 */
2799132232Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE);
2800105634Srwatson	if (error)
2801105634Srwatson		return (error);
2802101099Srwatson
2803101099Srwatson	/*
2804105634Srwatson	 * To perform a relabel of the vnode (Biba label or not), Biba must
2805105634Srwatson	 * authorize the relabel.
2806101099Srwatson	 */
2807132232Srwatson	if (!mac_biba_effective_in_range(old, subj))
2808101099Srwatson		return (EPERM);
2809101099Srwatson
2810101099Srwatson	/*
2811105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
2812101099Srwatson	 */
2813132232Srwatson	if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
2814105634Srwatson		/*
2815105634Srwatson		 * To change the Biba label on a vnode, the new vnode label
2816105634Srwatson		 * must be in the subject range.
2817105634Srwatson		 */
2818132232Srwatson		if (!mac_biba_effective_in_range(new, subj))
2819105634Srwatson			return (EPERM);
2820101099Srwatson
2821105634Srwatson		/*
2822105634Srwatson		 * To change the Biba label on the vnode to be EQUAL,
2823105634Srwatson		 * the subject must have appropriate privilege.
2824105634Srwatson		 */
2825105634Srwatson		if (mac_biba_contains_equal(new)) {
2826106090Srwatson			error = mac_biba_subject_privileged(subj);
2827105634Srwatson			if (error)
2828105634Srwatson				return (error);
2829105634Srwatson		}
2830105634Srwatson	}
2831105634Srwatson
2832105634Srwatson	return (0);
2833101099Srwatson}
2834101099Srwatson
2835101099Srwatsonstatic int
2836101099Srwatsonmac_biba_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
2837101099Srwatson    struct label *dlabel, struct vnode *vp, struct label *label,
2838101099Srwatson    struct componentname *cnp)
2839101099Srwatson{
2840101099Srwatson	struct mac_biba *subj, *obj;
2841101099Srwatson
2842101099Srwatson	if (!mac_biba_enabled)
2843101099Srwatson		return (0);
2844101099Srwatson
2845122524Srwatson	subj = SLOT(cred->cr_label);
2846101099Srwatson	obj = SLOT(dlabel);
2847101099Srwatson
2848132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2849101099Srwatson		return (EACCES);
2850101099Srwatson
2851101099Srwatson	obj = SLOT(label);
2852101099Srwatson
2853132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2854101099Srwatson		return (EACCES);
2855101099Srwatson
2856101099Srwatson	return (0);
2857101099Srwatson}
2858101099Srwatson
2859101099Srwatsonstatic int
2860101099Srwatsonmac_biba_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
2861101099Srwatson    struct label *dlabel, struct vnode *vp, struct label *label, int samedir,
2862101099Srwatson    struct componentname *cnp)
2863101099Srwatson{
2864101099Srwatson	struct mac_biba *subj, *obj;
2865101099Srwatson
2866101099Srwatson	if (!mac_biba_enabled)
2867101099Srwatson		return (0);
2868101099Srwatson
2869122524Srwatson	subj = SLOT(cred->cr_label);
2870101099Srwatson	obj = SLOT(dlabel);
2871101099Srwatson
2872132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2873101099Srwatson		return (EACCES);
2874101099Srwatson
2875101099Srwatson	if (vp != NULL) {
2876101099Srwatson		obj = SLOT(label);
2877101099Srwatson
2878132232Srwatson		if (!mac_biba_dominate_effective(subj, obj))
2879101099Srwatson			return (EACCES);
2880101099Srwatson	}
2881101099Srwatson
2882101099Srwatson	return (0);
2883101099Srwatson}
2884101099Srwatson
2885101099Srwatsonstatic int
2886101099Srwatsonmac_biba_check_vnode_revoke(struct ucred *cred, struct vnode *vp,
2887101099Srwatson    struct label *label)
2888101099Srwatson{
2889101099Srwatson	struct mac_biba *subj, *obj;
2890101099Srwatson
2891101099Srwatson	if (!mac_biba_enabled)
2892101099Srwatson		return (0);
2893101099Srwatson
2894122524Srwatson	subj = SLOT(cred->cr_label);
2895101099Srwatson	obj = SLOT(label);
2896101099Srwatson
2897132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2898101099Srwatson		return (EACCES);
2899101099Srwatson
2900101099Srwatson	return (0);
2901101099Srwatson}
2902101099Srwatson
2903101099Srwatsonstatic int
2904101099Srwatsonmac_biba_check_vnode_setacl(struct ucred *cred, struct vnode *vp,
2905101099Srwatson    struct label *label, acl_type_t type, struct acl *acl)
2906101099Srwatson{
2907101099Srwatson	struct mac_biba *subj, *obj;
2908101099Srwatson
2909101099Srwatson	if (!mac_biba_enabled)
2910101099Srwatson		return (0);
2911101099Srwatson
2912122524Srwatson	subj = SLOT(cred->cr_label);
2913101099Srwatson	obj = SLOT(label);
2914101099Srwatson
2915132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2916101099Srwatson		return (EACCES);
2917101099Srwatson
2918101099Srwatson	return (0);
2919101099Srwatson}
2920101099Srwatson
2921101099Srwatsonstatic int
2922101099Srwatsonmac_biba_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
2923101099Srwatson    struct label *vnodelabel, int attrnamespace, const char *name,
2924101099Srwatson    struct uio *uio)
2925101099Srwatson{
2926101099Srwatson	struct mac_biba *subj, *obj;
2927101099Srwatson
2928101099Srwatson	if (!mac_biba_enabled)
2929101099Srwatson		return (0);
2930101099Srwatson
2931122524Srwatson	subj = SLOT(cred->cr_label);
2932101099Srwatson	obj = SLOT(vnodelabel);
2933101099Srwatson
2934132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2935101099Srwatson		return (EACCES);
2936101099Srwatson
2937101099Srwatson	/* XXX: protect the MAC EA in a special way? */
2938101099Srwatson
2939101099Srwatson	return (0);
2940101099Srwatson}
2941101099Srwatson
2942101099Srwatsonstatic int
2943101099Srwatsonmac_biba_check_vnode_setflags(struct ucred *cred, struct vnode *vp,
2944101099Srwatson    struct label *vnodelabel, u_long flags)
2945101099Srwatson{
2946101099Srwatson	struct mac_biba *subj, *obj;
2947101099Srwatson
2948101099Srwatson	if (!mac_biba_enabled)
2949101099Srwatson		return (0);
2950101099Srwatson
2951122524Srwatson	subj = SLOT(cred->cr_label);
2952101099Srwatson	obj = SLOT(vnodelabel);
2953101099Srwatson
2954132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2955101099Srwatson		return (EACCES);
2956101099Srwatson
2957101099Srwatson	return (0);
2958101099Srwatson}
2959101099Srwatson
2960101099Srwatsonstatic int
2961101099Srwatsonmac_biba_check_vnode_setmode(struct ucred *cred, struct vnode *vp,
2962101099Srwatson    struct label *vnodelabel, mode_t mode)
2963101099Srwatson{
2964101099Srwatson	struct mac_biba *subj, *obj;
2965101099Srwatson
2966101099Srwatson	if (!mac_biba_enabled)
2967101099Srwatson		return (0);
2968101099Srwatson
2969122524Srwatson	subj = SLOT(cred->cr_label);
2970101099Srwatson	obj = SLOT(vnodelabel);
2971101099Srwatson
2972132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2973101099Srwatson		return (EACCES);
2974101099Srwatson
2975101099Srwatson	return (0);
2976101099Srwatson}
2977101099Srwatson
2978101099Srwatsonstatic int
2979101099Srwatsonmac_biba_check_vnode_setowner(struct ucred *cred, struct vnode *vp,
2980101099Srwatson    struct label *vnodelabel, uid_t uid, gid_t gid)
2981101099Srwatson{
2982101099Srwatson	struct mac_biba *subj, *obj;
2983101099Srwatson
2984101099Srwatson	if (!mac_biba_enabled)
2985101099Srwatson		return (0);
2986101099Srwatson
2987122524Srwatson	subj = SLOT(cred->cr_label);
2988101099Srwatson	obj = SLOT(vnodelabel);
2989101099Srwatson
2990132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2991101099Srwatson		return (EACCES);
2992101099Srwatson
2993101099Srwatson	return (0);
2994101099Srwatson}
2995101099Srwatson
2996101099Srwatsonstatic int
2997101099Srwatsonmac_biba_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
2998101099Srwatson    struct label *vnodelabel, struct timespec atime, struct timespec mtime)
2999101099Srwatson{
3000101099Srwatson	struct mac_biba *subj, *obj;
3001101099Srwatson
3002101099Srwatson	if (!mac_biba_enabled)
3003101099Srwatson		return (0);
3004101099Srwatson
3005122524Srwatson	subj = SLOT(cred->cr_label);
3006101099Srwatson	obj = SLOT(vnodelabel);
3007101099Srwatson
3008132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
3009101099Srwatson		return (EACCES);
3010101099Srwatson
3011101099Srwatson	return (0);
3012101099Srwatson}
3013101099Srwatson
3014101099Srwatsonstatic int
3015102129Srwatsonmac_biba_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
3016102129Srwatson    struct vnode *vp, struct label *vnodelabel)
3017101099Srwatson{
3018101099Srwatson	struct mac_biba *subj, *obj;
3019101099Srwatson
3020101099Srwatson	if (!mac_biba_enabled)
3021101099Srwatson		return (0);
3022101099Srwatson
3023122524Srwatson	subj = SLOT(active_cred->cr_label);
3024101099Srwatson	obj = SLOT(vnodelabel);
3025101099Srwatson
3026132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
3027101099Srwatson		return (EACCES);
3028101099Srwatson
3029101099Srwatson	return (0);
3030101099Srwatson}
3031101099Srwatson
3032102112Srwatsonstatic int
3033102129Srwatsonmac_biba_check_vnode_write(struct ucred *active_cred,
3034102129Srwatson    struct ucred *file_cred, struct vnode *vp, struct label *label)
3035102112Srwatson{
3036102112Srwatson	struct mac_biba *subj, *obj;
3037102112Srwatson
3038105637Srwatson	if (!mac_biba_enabled || !revocation_enabled)
3039102112Srwatson		return (0);
3040102112Srwatson
3041122524Srwatson	subj = SLOT(active_cred->cr_label);
3042102112Srwatson	obj = SLOT(label);
3043102112Srwatson
3044132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
3045102112Srwatson		return (EACCES);
3046102112Srwatson
3047102112Srwatson	return (0);
3048102112Srwatson}
3049102112Srwatson
3050106217Srwatsonstatic struct mac_policy_ops mac_biba_ops =
3051101099Srwatson{
3052106217Srwatson	.mpo_init = mac_biba_init,
3053106217Srwatson	.mpo_init_bpfdesc_label = mac_biba_init_label,
3054106217Srwatson	.mpo_init_cred_label = mac_biba_init_label,
3055106217Srwatson	.mpo_init_devfsdirent_label = mac_biba_init_label,
3056106217Srwatson	.mpo_init_ifnet_label = mac_biba_init_label,
3057122875Srwatson	.mpo_init_inpcb_label = mac_biba_init_label_waitcheck,
3058140628Srwatson	.mpo_init_sysv_msgmsg_label = mac_biba_init_label,
3059140628Srwatson	.mpo_init_sysv_msgqueue_label = mac_biba_init_label,
3060147091Srwatson	.mpo_init_sysv_sem_label = mac_biba_init_label,
3061140628Srwatson	.mpo_init_sysv_shm_label = mac_biba_init_label,
3062112675Srwatson	.mpo_init_ipq_label = mac_biba_init_label_waitcheck,
3063106217Srwatson	.mpo_init_mbuf_label = mac_biba_init_label_waitcheck,
3064106217Srwatson	.mpo_init_mount_label = mac_biba_init_label,
3065106217Srwatson	.mpo_init_mount_fs_label = mac_biba_init_label,
3066106217Srwatson	.mpo_init_pipe_label = mac_biba_init_label,
3067145855Srwatson	.mpo_init_posix_sem_label = mac_biba_init_label,
3068106217Srwatson	.mpo_init_socket_label = mac_biba_init_label_waitcheck,
3069106217Srwatson	.mpo_init_socket_peer_label = mac_biba_init_label_waitcheck,
3070106217Srwatson	.mpo_init_vnode_label = mac_biba_init_label,
3071106217Srwatson	.mpo_destroy_bpfdesc_label = mac_biba_destroy_label,
3072106217Srwatson	.mpo_destroy_cred_label = mac_biba_destroy_label,
3073106217Srwatson	.mpo_destroy_devfsdirent_label = mac_biba_destroy_label,
3074106217Srwatson	.mpo_destroy_ifnet_label = mac_biba_destroy_label,
3075122875Srwatson	.mpo_destroy_inpcb_label = mac_biba_destroy_label,
3076140628Srwatson	.mpo_destroy_sysv_msgmsg_label = mac_biba_destroy_label,
3077140628Srwatson	.mpo_destroy_sysv_msgqueue_label = mac_biba_destroy_label,
3078147091Srwatson	.mpo_destroy_sysv_sem_label = mac_biba_destroy_label,
3079140628Srwatson	.mpo_destroy_sysv_shm_label = mac_biba_destroy_label,
3080106217Srwatson	.mpo_destroy_ipq_label = mac_biba_destroy_label,
3081106217Srwatson	.mpo_destroy_mbuf_label = mac_biba_destroy_label,
3082106217Srwatson	.mpo_destroy_mount_label = mac_biba_destroy_label,
3083106217Srwatson	.mpo_destroy_mount_fs_label = mac_biba_destroy_label,
3084106217Srwatson	.mpo_destroy_pipe_label = mac_biba_destroy_label,
3085145855Srwatson	.mpo_destroy_posix_sem_label = mac_biba_destroy_label,
3086106217Srwatson	.mpo_destroy_socket_label = mac_biba_destroy_label,
3087106217Srwatson	.mpo_destroy_socket_peer_label = mac_biba_destroy_label,
3088106217Srwatson	.mpo_destroy_vnode_label = mac_biba_destroy_label,
3089123173Srwatson	.mpo_copy_cred_label = mac_biba_copy_label,
3090131025Srwatson	.mpo_copy_ifnet_label = mac_biba_copy_label,
3091115707Srwatson	.mpo_copy_mbuf_label = mac_biba_copy_label,
3092106217Srwatson	.mpo_copy_pipe_label = mac_biba_copy_label,
3093122820Srwatson	.mpo_copy_socket_label = mac_biba_copy_label,
3094106217Srwatson	.mpo_copy_vnode_label = mac_biba_copy_label,
3095106217Srwatson	.mpo_externalize_cred_label = mac_biba_externalize_label,
3096106217Srwatson	.mpo_externalize_ifnet_label = mac_biba_externalize_label,
3097106217Srwatson	.mpo_externalize_pipe_label = mac_biba_externalize_label,
3098106217Srwatson	.mpo_externalize_socket_label = mac_biba_externalize_label,
3099106217Srwatson	.mpo_externalize_socket_peer_label = mac_biba_externalize_label,
3100106217Srwatson	.mpo_externalize_vnode_label = mac_biba_externalize_label,
3101106217Srwatson	.mpo_internalize_cred_label = mac_biba_internalize_label,
3102106217Srwatson	.mpo_internalize_ifnet_label = mac_biba_internalize_label,
3103106217Srwatson	.mpo_internalize_pipe_label = mac_biba_internalize_label,
3104106217Srwatson	.mpo_internalize_socket_label = mac_biba_internalize_label,
3105106217Srwatson	.mpo_internalize_vnode_label = mac_biba_internalize_label,
3106106217Srwatson	.mpo_create_devfs_device = mac_biba_create_devfs_device,
3107106217Srwatson	.mpo_create_devfs_directory = mac_biba_create_devfs_directory,
3108106217Srwatson	.mpo_create_devfs_symlink = mac_biba_create_devfs_symlink,
3109106217Srwatson	.mpo_create_mount = mac_biba_create_mount,
3110106217Srwatson	.mpo_create_root_mount = mac_biba_create_root_mount,
3111106217Srwatson	.mpo_relabel_vnode = mac_biba_relabel_vnode,
3112106217Srwatson	.mpo_update_devfsdirent = mac_biba_update_devfsdirent,
3113106217Srwatson	.mpo_associate_vnode_devfs = mac_biba_associate_vnode_devfs,
3114106217Srwatson	.mpo_associate_vnode_extattr = mac_biba_associate_vnode_extattr,
3115106217Srwatson	.mpo_associate_vnode_singlelabel = mac_biba_associate_vnode_singlelabel,
3116106217Srwatson	.mpo_create_vnode_extattr = mac_biba_create_vnode_extattr,
3117106217Srwatson	.mpo_setlabel_vnode_extattr = mac_biba_setlabel_vnode_extattr,
3118106217Srwatson	.mpo_create_mbuf_from_socket = mac_biba_create_mbuf_from_socket,
3119106217Srwatson	.mpo_create_pipe = mac_biba_create_pipe,
3120145855Srwatson	.mpo_create_posix_sem = mac_biba_create_posix_sem,
3121106217Srwatson	.mpo_create_socket = mac_biba_create_socket,
3122106217Srwatson	.mpo_create_socket_from_socket = mac_biba_create_socket_from_socket,
3123106217Srwatson	.mpo_relabel_pipe = mac_biba_relabel_pipe,
3124106217Srwatson	.mpo_relabel_socket = mac_biba_relabel_socket,
3125106217Srwatson	.mpo_set_socket_peer_from_mbuf = mac_biba_set_socket_peer_from_mbuf,
3126106217Srwatson	.mpo_set_socket_peer_from_socket = mac_biba_set_socket_peer_from_socket,
3127106217Srwatson	.mpo_create_bpfdesc = mac_biba_create_bpfdesc,
3128106217Srwatson	.mpo_create_datagram_from_ipq = mac_biba_create_datagram_from_ipq,
3129106217Srwatson	.mpo_create_fragment = mac_biba_create_fragment,
3130106217Srwatson	.mpo_create_ifnet = mac_biba_create_ifnet,
3131122875Srwatson	.mpo_create_inpcb_from_socket = mac_biba_create_inpcb_from_socket,
3132140628Srwatson	.mpo_create_sysv_msgmsg = mac_biba_create_sysv_msgmsg,
3133140628Srwatson	.mpo_create_sysv_msgqueue = mac_biba_create_sysv_msgqueue,
3134147091Srwatson	.mpo_create_sysv_sem = mac_biba_create_sysv_sem,
3135140628Srwatson	.mpo_create_sysv_shm = mac_biba_create_sysv_shm,
3136106217Srwatson	.mpo_create_ipq = mac_biba_create_ipq,
3137123607Srwatson	.mpo_create_mbuf_from_inpcb = mac_biba_create_mbuf_from_inpcb,
3138106217Srwatson	.mpo_create_mbuf_from_mbuf = mac_biba_create_mbuf_from_mbuf,
3139106217Srwatson	.mpo_create_mbuf_linklayer = mac_biba_create_mbuf_linklayer,
3140106217Srwatson	.mpo_create_mbuf_from_bpfdesc = mac_biba_create_mbuf_from_bpfdesc,
3141106217Srwatson	.mpo_create_mbuf_from_ifnet = mac_biba_create_mbuf_from_ifnet,
3142106217Srwatson	.mpo_create_mbuf_multicast_encap = mac_biba_create_mbuf_multicast_encap,
3143106217Srwatson	.mpo_create_mbuf_netlayer = mac_biba_create_mbuf_netlayer,
3144106217Srwatson	.mpo_fragment_match = mac_biba_fragment_match,
3145106217Srwatson	.mpo_relabel_ifnet = mac_biba_relabel_ifnet,
3146106217Srwatson	.mpo_update_ipq = mac_biba_update_ipq,
3147122875Srwatson	.mpo_inpcb_sosetlabel = mac_biba_inpcb_sosetlabel,
3148106217Srwatson	.mpo_create_proc0 = mac_biba_create_proc0,
3149106217Srwatson	.mpo_create_proc1 = mac_biba_create_proc1,
3150106217Srwatson	.mpo_relabel_cred = mac_biba_relabel_cred,
3151140628Srwatson	.mpo_cleanup_sysv_msgmsg = mac_biba_cleanup_sysv_msgmsg,
3152140628Srwatson	.mpo_cleanup_sysv_msgqueue = mac_biba_cleanup_sysv_msgqueue,
3153147091Srwatson	.mpo_cleanup_sysv_sem = mac_biba_cleanup_sysv_sem,
3154140628Srwatson	.mpo_cleanup_sysv_shm = mac_biba_cleanup_sysv_shm,
3155106217Srwatson	.mpo_check_bpfdesc_receive = mac_biba_check_bpfdesc_receive,
3156106217Srwatson	.mpo_check_cred_relabel = mac_biba_check_cred_relabel,
3157106217Srwatson	.mpo_check_cred_visible = mac_biba_check_cred_visible,
3158106217Srwatson	.mpo_check_ifnet_relabel = mac_biba_check_ifnet_relabel,
3159106217Srwatson	.mpo_check_ifnet_transmit = mac_biba_check_ifnet_transmit,
3160122875Srwatson	.mpo_check_inpcb_deliver = mac_biba_check_inpcb_deliver,
3161140628Srwatson	.mpo_check_sysv_msgrcv = mac_biba_check_sysv_msgrcv,
3162140628Srwatson	.mpo_check_sysv_msgrmid = mac_biba_check_sysv_msgrmid,
3163140628Srwatson	.mpo_check_sysv_msqget = mac_biba_check_sysv_msqget,
3164140628Srwatson	.mpo_check_sysv_msqsnd = mac_biba_check_sysv_msqsnd,
3165140628Srwatson	.mpo_check_sysv_msqrcv = mac_biba_check_sysv_msqrcv,
3166140628Srwatson	.mpo_check_sysv_msqctl = mac_biba_check_sysv_msqctl,
3167140628Srwatson	.mpo_check_sysv_semctl = mac_biba_check_sysv_semctl,
3168140628Srwatson	.mpo_check_sysv_semget = mac_biba_check_sysv_semget,
3169140628Srwatson	.mpo_check_sysv_semop = mac_biba_check_sysv_semop,
3170140628Srwatson	.mpo_check_sysv_shmat = mac_biba_check_sysv_shmat,
3171140628Srwatson	.mpo_check_sysv_shmctl = mac_biba_check_sysv_shmctl,
3172140628Srwatson	.mpo_check_sysv_shmget = mac_biba_check_sysv_shmget,
3173110354Srwatson	.mpo_check_kld_load = mac_biba_check_kld_load,
3174110354Srwatson	.mpo_check_kld_unload = mac_biba_check_kld_unload,
3175106217Srwatson	.mpo_check_mount_stat = mac_biba_check_mount_stat,
3176106217Srwatson	.mpo_check_pipe_ioctl = mac_biba_check_pipe_ioctl,
3177106217Srwatson	.mpo_check_pipe_poll = mac_biba_check_pipe_poll,
3178106217Srwatson	.mpo_check_pipe_read = mac_biba_check_pipe_read,
3179106217Srwatson	.mpo_check_pipe_relabel = mac_biba_check_pipe_relabel,
3180106217Srwatson	.mpo_check_pipe_stat = mac_biba_check_pipe_stat,
3181106217Srwatson	.mpo_check_pipe_write = mac_biba_check_pipe_write,
3182145855Srwatson	.mpo_check_posix_sem_destroy = mac_biba_check_posix_sem_write,
3183145855Srwatson	.mpo_check_posix_sem_getvalue = mac_biba_check_posix_sem_rdonly,
3184145855Srwatson	.mpo_check_posix_sem_open = mac_biba_check_posix_sem_write,
3185145855Srwatson	.mpo_check_posix_sem_post = mac_biba_check_posix_sem_write,
3186145855Srwatson	.mpo_check_posix_sem_unlink = mac_biba_check_posix_sem_write,
3187145855Srwatson	.mpo_check_posix_sem_wait = mac_biba_check_posix_sem_write,
3188106217Srwatson	.mpo_check_proc_debug = mac_biba_check_proc_debug,
3189106217Srwatson	.mpo_check_proc_sched = mac_biba_check_proc_sched,
3190106217Srwatson	.mpo_check_proc_signal = mac_biba_check_proc_signal,
3191106217Srwatson	.mpo_check_socket_deliver = mac_biba_check_socket_deliver,
3192106217Srwatson	.mpo_check_socket_relabel = mac_biba_check_socket_relabel,
3193106217Srwatson	.mpo_check_socket_visible = mac_biba_check_socket_visible,
3194112574Srwatson	.mpo_check_sysarch_ioperm = mac_biba_check_sysarch_ioperm,
3195106418Srwatson	.mpo_check_system_acct = mac_biba_check_system_acct,
3196106418Srwatson	.mpo_check_system_settime = mac_biba_check_system_settime,
3197106217Srwatson	.mpo_check_system_swapon = mac_biba_check_system_swapon,
3198112574Srwatson	.mpo_check_system_swapoff = mac_biba_check_system_swapoff,
3199106217Srwatson	.mpo_check_system_sysctl = mac_biba_check_system_sysctl,
3200106217Srwatson	.mpo_check_vnode_access = mac_biba_check_vnode_open,
3201106217Srwatson	.mpo_check_vnode_chdir = mac_biba_check_vnode_chdir,
3202106217Srwatson	.mpo_check_vnode_chroot = mac_biba_check_vnode_chroot,
3203106217Srwatson	.mpo_check_vnode_create = mac_biba_check_vnode_create,
3204106217Srwatson	.mpo_check_vnode_delete = mac_biba_check_vnode_delete,
3205106217Srwatson	.mpo_check_vnode_deleteacl = mac_biba_check_vnode_deleteacl,
3206119202Srwatson	.mpo_check_vnode_deleteextattr = mac_biba_check_vnode_deleteextattr,
3207106217Srwatson	.mpo_check_vnode_exec = mac_biba_check_vnode_exec,
3208106217Srwatson	.mpo_check_vnode_getacl = mac_biba_check_vnode_getacl,
3209106217Srwatson	.mpo_check_vnode_getextattr = mac_biba_check_vnode_getextattr,
3210106217Srwatson	.mpo_check_vnode_link = mac_biba_check_vnode_link,
3211119202Srwatson	.mpo_check_vnode_listextattr = mac_biba_check_vnode_listextattr,
3212106217Srwatson	.mpo_check_vnode_lookup = mac_biba_check_vnode_lookup,
3213106217Srwatson	.mpo_check_vnode_mmap = mac_biba_check_vnode_mmap,
3214106217Srwatson	.mpo_check_vnode_open = mac_biba_check_vnode_open,
3215106217Srwatson	.mpo_check_vnode_poll = mac_biba_check_vnode_poll,
3216106217Srwatson	.mpo_check_vnode_read = mac_biba_check_vnode_read,
3217106217Srwatson	.mpo_check_vnode_readdir = mac_biba_check_vnode_readdir,
3218106217Srwatson	.mpo_check_vnode_readlink = mac_biba_check_vnode_readlink,
3219106217Srwatson	.mpo_check_vnode_relabel = mac_biba_check_vnode_relabel,
3220106217Srwatson	.mpo_check_vnode_rename_from = mac_biba_check_vnode_rename_from,
3221106217Srwatson	.mpo_check_vnode_rename_to = mac_biba_check_vnode_rename_to,
3222106217Srwatson	.mpo_check_vnode_revoke = mac_biba_check_vnode_revoke,
3223106217Srwatson	.mpo_check_vnode_setacl = mac_biba_check_vnode_setacl,
3224106217Srwatson	.mpo_check_vnode_setextattr = mac_biba_check_vnode_setextattr,
3225106217Srwatson	.mpo_check_vnode_setflags = mac_biba_check_vnode_setflags,
3226106217Srwatson	.mpo_check_vnode_setmode = mac_biba_check_vnode_setmode,
3227106217Srwatson	.mpo_check_vnode_setowner = mac_biba_check_vnode_setowner,
3228106217Srwatson	.mpo_check_vnode_setutimes = mac_biba_check_vnode_setutimes,
3229106217Srwatson	.mpo_check_vnode_stat = mac_biba_check_vnode_stat,
3230106217Srwatson	.mpo_check_vnode_write = mac_biba_check_vnode_write,
3231101099Srwatson};
3232101099Srwatson
3233112717SrwatsonMAC_POLICY_SET(&mac_biba_ops, mac_biba, "TrustedBSD MAC/Biba",
3234113531Srwatson    MPC_LOADTIME_FLAG_NOTLATE | MPC_LOADTIME_FLAG_LABELMBUFS, &mac_biba_slot);
3235