mac_biba.c revision 165150
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 165150 2006-12-13 06:03:22Z csjp $
35101099Srwatson */
36101099Srwatson
37101099Srwatson/*
38101099Srwatson * Developed by the TrustedBSD Project.
39101099Srwatson * Biba fixed label mandatory integrity policy.
40101099Srwatson */
41101099Srwatson
42101099Srwatson#include <sys/types.h>
43101099Srwatson#include <sys/param.h>
44101099Srwatson#include <sys/acl.h>
45101099Srwatson#include <sys/conf.h>
46105988Srwatson#include <sys/extattr.h>
47101099Srwatson#include <sys/kernel.h>
48164184Strhodes#include <sys/ksem.h>
49101099Srwatson#include <sys/mac.h>
50103183Sbde#include <sys/malloc.h>
51145076Scsjp#include <sys/mman.h>
52101099Srwatson#include <sys/mount.h>
53101099Srwatson#include <sys/proc.h>
54115497Srwatson#include <sys/sbuf.h>
55101099Srwatson#include <sys/systm.h>
56101099Srwatson#include <sys/sysproto.h>
57101099Srwatson#include <sys/sysent.h>
58105696Srwatson#include <sys/systm.h>
59101099Srwatson#include <sys/vnode.h>
60101099Srwatson#include <sys/file.h>
61101099Srwatson#include <sys/socket.h>
62101099Srwatson#include <sys/socketvar.h>
63101099Srwatson#include <sys/pipe.h>
64150340Sphk#include <sys/sx.h>
65101099Srwatson#include <sys/sysctl.h>
66140628Srwatson#include <sys/msg.h>
67140628Srwatson#include <sys/sem.h>
68140628Srwatson#include <sys/shm.h>
69101099Srwatson
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
126153927Scsjpstatic int	interfaces_equal;
127153927ScsjpSYSCTL_INT(_security_mac_biba, OID_AUTO, interfaces_equal, CTLFLAG_RW,
128153927Scsjp    &interfaces_equal, 0, "Label network interfaces as biba/equal on create");
129153927ScsjpTUNABLE_INT("security.mac.biba.interfaces_equal", &interfaces_equal);
130153927Scsjp
131105637Srwatsonstatic int	revocation_enabled = 0;
132101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, revocation_enabled, CTLFLAG_RW,
133105637Srwatson    &revocation_enabled, 0, "Revoke access to objects on relabel");
134105637SrwatsonTUNABLE_INT("security.mac.biba.revocation_enabled", &revocation_enabled);
135101099Srwatson
136101099Srwatsonstatic int	mac_biba_slot;
137101099Srwatson#define	SLOT(l)	((struct mac_biba *)LABEL_TO_SLOT((l), mac_biba_slot).l_ptr)
138132781Skan#define	SLOT_SET(l, val) (LABEL_TO_SLOT((l), mac_biba_slot).l_ptr = (val))
139101099Srwatson
140122879Srwatsonstatic uma_zone_t	zone_biba;
141101099Srwatson
142105643Srwatsonstatic __inline int
143105643Srwatsonbiba_bit_set_empty(u_char *set) {
144105643Srwatson	int i;
145105643Srwatson
146105643Srwatson	for (i = 0; i < MAC_BIBA_MAX_COMPARTMENTS >> 3; i++)
147105643Srwatson		if (set[i] != 0)
148105643Srwatson			return (0);
149105643Srwatson	return (1);
150105643Srwatson}
151105643Srwatson
152101099Srwatsonstatic struct mac_biba *
153104514Srwatsonbiba_alloc(int flag)
154101099Srwatson{
155101099Srwatson
156122879Srwatson	return (uma_zalloc(zone_biba, flag | M_ZERO));
157101099Srwatson}
158101099Srwatson
159101099Srwatsonstatic void
160101099Srwatsonbiba_free(struct mac_biba *mac_biba)
161101099Srwatson{
162101099Srwatson
163101099Srwatson	if (mac_biba != NULL)
164122879Srwatson		uma_zfree(zone_biba, mac_biba);
165101099Srwatson	else
166101099Srwatson		atomic_add_int(&destroyed_not_inited, 1);
167101099Srwatson}
168101099Srwatson
169101099Srwatsonstatic int
170105634Srwatsonbiba_atmostflags(struct mac_biba *mac_biba, int flags)
171105634Srwatson{
172105634Srwatson
173105634Srwatson	if ((mac_biba->mb_flags & flags) != mac_biba->mb_flags)
174105634Srwatson		return (EINVAL);
175105634Srwatson	return (0);
176105634Srwatson}
177105634Srwatson
178105634Srwatsonstatic int
179101099Srwatsonmac_biba_dominate_element(struct mac_biba_element *a,
180101099Srwatson    struct mac_biba_element *b)
181101099Srwatson{
182105643Srwatson	int bit;
183101099Srwatson
184105736Srwatson	switch (a->mbe_type) {
185101099Srwatson	case MAC_BIBA_TYPE_EQUAL:
186101099Srwatson	case MAC_BIBA_TYPE_HIGH:
187101099Srwatson		return (1);
188101099Srwatson
189101099Srwatson	case MAC_BIBA_TYPE_LOW:
190101099Srwatson		switch (b->mbe_type) {
191101099Srwatson		case MAC_BIBA_TYPE_GRADE:
192101099Srwatson		case MAC_BIBA_TYPE_HIGH:
193101099Srwatson			return (0);
194101099Srwatson
195101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
196101099Srwatson		case MAC_BIBA_TYPE_LOW:
197101099Srwatson			return (1);
198101099Srwatson
199101099Srwatson		default:
200101099Srwatson			panic("mac_biba_dominate_element: b->mbe_type invalid");
201101099Srwatson		}
202101099Srwatson
203101099Srwatson	case MAC_BIBA_TYPE_GRADE:
204101099Srwatson		switch (b->mbe_type) {
205101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
206101099Srwatson		case MAC_BIBA_TYPE_LOW:
207101099Srwatson			return (1);
208101099Srwatson
209101099Srwatson		case MAC_BIBA_TYPE_HIGH:
210101099Srwatson			return (0);
211101099Srwatson
212101099Srwatson		case MAC_BIBA_TYPE_GRADE:
213105643Srwatson			for (bit = 1; bit <= MAC_BIBA_MAX_COMPARTMENTS; bit++)
214105643Srwatson				if (!MAC_BIBA_BIT_TEST(bit,
215105643Srwatson				    a->mbe_compartments) &&
216105643Srwatson				    MAC_BIBA_BIT_TEST(bit, b->mbe_compartments))
217105643Srwatson					return (0);
218101099Srwatson			return (a->mbe_grade >= b->mbe_grade);
219101099Srwatson
220101099Srwatson		default:
221101099Srwatson			panic("mac_biba_dominate_element: b->mbe_type invalid");
222101099Srwatson		}
223101099Srwatson
224101099Srwatson	default:
225101099Srwatson		panic("mac_biba_dominate_element: a->mbe_type invalid");
226101099Srwatson	}
227101099Srwatson
228101099Srwatson	return (0);
229101099Srwatson}
230101099Srwatson
231101099Srwatsonstatic int
232105988Srwatsonmac_biba_subject_dominate_high(struct mac_biba *mac_biba)
233105988Srwatson{
234105988Srwatson	struct mac_biba_element *element;
235105988Srwatson
236132232Srwatson	KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
237132232Srwatson	    ("mac_biba_effective_in_range: mac_biba not effective"));
238132232Srwatson	element = &mac_biba->mb_effective;
239105988Srwatson
240105988Srwatson	return (element->mbe_type == MAC_BIBA_TYPE_EQUAL ||
241105988Srwatson	    element->mbe_type == MAC_BIBA_TYPE_HIGH);
242105988Srwatson}
243105988Srwatson
244105988Srwatsonstatic int
245101099Srwatsonmac_biba_range_in_range(struct mac_biba *rangea, struct mac_biba *rangeb)
246101099Srwatson{
247101099Srwatson
248101099Srwatson	return (mac_biba_dominate_element(&rangeb->mb_rangehigh,
249101099Srwatson	    &rangea->mb_rangehigh) &&
250101099Srwatson	    mac_biba_dominate_element(&rangea->mb_rangelow,
251101099Srwatson	    &rangeb->mb_rangelow));
252101099Srwatson}
253101099Srwatson
254101099Srwatsonstatic int
255136774Srwatsonmac_biba_effective_in_range(struct mac_biba *effective,
256136774Srwatson    struct mac_biba *range)
257101099Srwatson{
258101099Srwatson
259132232Srwatson	KASSERT((effective->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
260132232Srwatson	    ("mac_biba_effective_in_range: a not effective"));
261103750Srwatson	KASSERT((range->mb_flags & MAC_BIBA_FLAG_RANGE) != 0,
262132232Srwatson	    ("mac_biba_effective_in_range: b not range"));
263101099Srwatson
264101099Srwatson	return (mac_biba_dominate_element(&range->mb_rangehigh,
265132232Srwatson	    &effective->mb_effective) &&
266132232Srwatson	    mac_biba_dominate_element(&effective->mb_effective,
267101099Srwatson	    &range->mb_rangelow));
268101099Srwatson
269101099Srwatson	return (1);
270101099Srwatson}
271101099Srwatson
272101099Srwatsonstatic int
273132232Srwatsonmac_biba_dominate_effective(struct mac_biba *a, struct mac_biba *b)
274101099Srwatson{
275132232Srwatson	KASSERT((a->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
276132232Srwatson	    ("mac_biba_dominate_effective: a not effective"));
277132232Srwatson	KASSERT((b->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
278132232Srwatson	    ("mac_biba_dominate_effective: b not effective"));
279101099Srwatson
280132232Srwatson	return (mac_biba_dominate_element(&a->mb_effective, &b->mb_effective));
281101099Srwatson}
282101099Srwatson
283101099Srwatsonstatic int
284101099Srwatsonmac_biba_equal_element(struct mac_biba_element *a, struct mac_biba_element *b)
285101099Srwatson{
286101099Srwatson
287101099Srwatson	if (a->mbe_type == MAC_BIBA_TYPE_EQUAL ||
288101099Srwatson	    b->mbe_type == MAC_BIBA_TYPE_EQUAL)
289101099Srwatson		return (1);
290101099Srwatson
291101099Srwatson	return (a->mbe_type == b->mbe_type && a->mbe_grade == b->mbe_grade);
292101099Srwatson}
293101099Srwatson
294101099Srwatsonstatic int
295132232Srwatsonmac_biba_equal_effective(struct mac_biba *a, struct mac_biba *b)
296101099Srwatson{
297101099Srwatson
298132232Srwatson	KASSERT((a->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
299132232Srwatson	    ("mac_biba_equal_effective: a not effective"));
300132232Srwatson	KASSERT((b->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
301132232Srwatson	    ("mac_biba_equal_effective: b not effective"));
302101099Srwatson
303132232Srwatson	return (mac_biba_equal_element(&a->mb_effective, &b->mb_effective));
304101099Srwatson}
305101099Srwatson
306101099Srwatsonstatic int
307105634Srwatsonmac_biba_contains_equal(struct mac_biba *mac_biba)
308105634Srwatson{
309105634Srwatson
310132232Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_EFFECTIVE)
311132232Srwatson		if (mac_biba->mb_effective.mbe_type == MAC_BIBA_TYPE_EQUAL)
312105634Srwatson			return (1);
313105634Srwatson
314105634Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
315105634Srwatson		if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL)
316105634Srwatson			return (1);
317105634Srwatson		if (mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL)
318105637Srwatson			return (1);
319105634Srwatson	}
320105634Srwatson
321105634Srwatson	return (0);
322105634Srwatson}
323105634Srwatson
324105634Srwatsonstatic int
325106090Srwatsonmac_biba_subject_privileged(struct mac_biba *mac_biba)
326105634Srwatson{
327105634Srwatson
328105634Srwatson	KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAGS_BOTH) ==
329105634Srwatson	    MAC_BIBA_FLAGS_BOTH,
330106090Srwatson	    ("mac_biba_subject_privileged: subject doesn't have both labels"));
331105634Srwatson
332132232Srwatson	/* If the effective is EQUAL, it's ok. */
333132232Srwatson	if (mac_biba->mb_effective.mbe_type == MAC_BIBA_TYPE_EQUAL)
334105634Srwatson		return (0);
335105634Srwatson
336105634Srwatson	/* If either range endpoint is EQUAL, it's ok. */
337105634Srwatson	if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL ||
338105634Srwatson	    mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL)
339105634Srwatson		return (0);
340105634Srwatson
341105634Srwatson	/* If the range is low-high, it's ok. */
342105634Srwatson	if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_LOW &&
343105634Srwatson	    mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_HIGH)
344105634Srwatson		return (0);
345105634Srwatson
346105634Srwatson	/* It's not ok. */
347105634Srwatson	return (EPERM);
348105634Srwatson}
349105634Srwatson
350106091Srwatsonstatic int
351132232Srwatsonmac_biba_high_effective(struct mac_biba *mac_biba)
352105988Srwatson{
353105988Srwatson
354132232Srwatson	KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
355132232Srwatson	    ("mac_biba_equal_effective: mac_biba not effective"));
356105988Srwatson
357132232Srwatson	return (mac_biba->mb_effective.mbe_type == MAC_BIBA_TYPE_HIGH);
358105988Srwatson}
359105988Srwatson
360105634Srwatsonstatic int
361101099Srwatsonmac_biba_valid(struct mac_biba *mac_biba)
362101099Srwatson{
363101099Srwatson
364132232Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
365132232Srwatson		switch (mac_biba->mb_effective.mbe_type) {
366101099Srwatson		case MAC_BIBA_TYPE_GRADE:
367101099Srwatson			break;
368101099Srwatson
369101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
370101099Srwatson		case MAC_BIBA_TYPE_HIGH:
371101099Srwatson		case MAC_BIBA_TYPE_LOW:
372132232Srwatson			if (mac_biba->mb_effective.mbe_grade != 0 ||
373105643Srwatson			    !MAC_BIBA_BIT_SET_EMPTY(
374132232Srwatson			    mac_biba->mb_effective.mbe_compartments))
375101099Srwatson				return (EINVAL);
376101099Srwatson			break;
377101099Srwatson
378101099Srwatson		default:
379101099Srwatson			return (EINVAL);
380101099Srwatson		}
381101099Srwatson	} else {
382132232Srwatson		if (mac_biba->mb_effective.mbe_type != MAC_BIBA_TYPE_UNDEF)
383101099Srwatson			return (EINVAL);
384101099Srwatson	}
385101099Srwatson
386101099Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
387101099Srwatson		switch (mac_biba->mb_rangelow.mbe_type) {
388101099Srwatson		case MAC_BIBA_TYPE_GRADE:
389101099Srwatson			break;
390101099Srwatson
391101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
392101099Srwatson		case MAC_BIBA_TYPE_HIGH:
393101099Srwatson		case MAC_BIBA_TYPE_LOW:
394105643Srwatson			if (mac_biba->mb_rangelow.mbe_grade != 0 ||
395105643Srwatson			    !MAC_BIBA_BIT_SET_EMPTY(
396105643Srwatson			    mac_biba->mb_rangelow.mbe_compartments))
397101099Srwatson				return (EINVAL);
398101099Srwatson			break;
399101099Srwatson
400101099Srwatson		default:
401101099Srwatson			return (EINVAL);
402101099Srwatson		}
403101099Srwatson
404101099Srwatson		switch (mac_biba->mb_rangehigh.mbe_type) {
405101099Srwatson		case MAC_BIBA_TYPE_GRADE:
406101099Srwatson			break;
407101099Srwatson
408101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
409101099Srwatson		case MAC_BIBA_TYPE_HIGH:
410101099Srwatson		case MAC_BIBA_TYPE_LOW:
411105643Srwatson			if (mac_biba->mb_rangehigh.mbe_grade != 0 ||
412105643Srwatson			    !MAC_BIBA_BIT_SET_EMPTY(
413105643Srwatson			    mac_biba->mb_rangehigh.mbe_compartments))
414101099Srwatson				return (EINVAL);
415101099Srwatson			break;
416101099Srwatson
417101099Srwatson		default:
418101099Srwatson			return (EINVAL);
419101099Srwatson		}
420101099Srwatson		if (!mac_biba_dominate_element(&mac_biba->mb_rangehigh,
421101099Srwatson		    &mac_biba->mb_rangelow))
422101099Srwatson			return (EINVAL);
423101099Srwatson	} else {
424101099Srwatson		if (mac_biba->mb_rangelow.mbe_type != MAC_BIBA_TYPE_UNDEF ||
425101099Srwatson		    mac_biba->mb_rangehigh.mbe_type != MAC_BIBA_TYPE_UNDEF)
426101099Srwatson			return (EINVAL);
427101099Srwatson	}
428101099Srwatson
429101099Srwatson	return (0);
430101099Srwatson}
431101099Srwatson
432101099Srwatsonstatic void
433101099Srwatsonmac_biba_set_range(struct mac_biba *mac_biba, u_short typelow,
434105643Srwatson    u_short gradelow, u_char *compartmentslow, u_short typehigh,
435105643Srwatson    u_short gradehigh, u_char *compartmentshigh)
436101099Srwatson{
437101099Srwatson
438101099Srwatson	mac_biba->mb_rangelow.mbe_type = typelow;
439101099Srwatson	mac_biba->mb_rangelow.mbe_grade = gradelow;
440105643Srwatson	if (compartmentslow != NULL)
441105643Srwatson		memcpy(mac_biba->mb_rangelow.mbe_compartments,
442105643Srwatson		    compartmentslow,
443105643Srwatson		    sizeof(mac_biba->mb_rangelow.mbe_compartments));
444101099Srwatson	mac_biba->mb_rangehigh.mbe_type = typehigh;
445101099Srwatson	mac_biba->mb_rangehigh.mbe_grade = gradehigh;
446105643Srwatson	if (compartmentshigh != NULL)
447105643Srwatson		memcpy(mac_biba->mb_rangehigh.mbe_compartments,
448105643Srwatson		    compartmentshigh,
449105643Srwatson		    sizeof(mac_biba->mb_rangehigh.mbe_compartments));
450101099Srwatson	mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE;
451101099Srwatson}
452101099Srwatson
453101099Srwatsonstatic void
454132232Srwatsonmac_biba_set_effective(struct mac_biba *mac_biba, u_short type, u_short grade,
455105643Srwatson    u_char *compartments)
456101099Srwatson{
457101099Srwatson
458132232Srwatson	mac_biba->mb_effective.mbe_type = type;
459132232Srwatson	mac_biba->mb_effective.mbe_grade = grade;
460105643Srwatson	if (compartments != NULL)
461132232Srwatson		memcpy(mac_biba->mb_effective.mbe_compartments, compartments,
462132232Srwatson		    sizeof(mac_biba->mb_effective.mbe_compartments));
463132232Srwatson	mac_biba->mb_flags |= MAC_BIBA_FLAG_EFFECTIVE;
464101099Srwatson}
465101099Srwatson
466101099Srwatsonstatic void
467101099Srwatsonmac_biba_copy_range(struct mac_biba *labelfrom, struct mac_biba *labelto)
468101099Srwatson{
469105643Srwatson
470101099Srwatson	KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_RANGE) != 0,
471101099Srwatson	    ("mac_biba_copy_range: labelfrom not range"));
472101099Srwatson
473101099Srwatson	labelto->mb_rangelow = labelfrom->mb_rangelow;
474101099Srwatson	labelto->mb_rangehigh = labelfrom->mb_rangehigh;
475101099Srwatson	labelto->mb_flags |= MAC_BIBA_FLAG_RANGE;
476101099Srwatson}
477101099Srwatson
478101099Srwatsonstatic void
479132232Srwatsonmac_biba_copy_effective(struct mac_biba *labelfrom, struct mac_biba *labelto)
480101099Srwatson{
481101099Srwatson
482132232Srwatson	KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
483132232Srwatson	    ("mac_biba_copy_effective: labelfrom not effective"));
484101099Srwatson
485132232Srwatson	labelto->mb_effective = labelfrom->mb_effective;
486132232Srwatson	labelto->mb_flags |= MAC_BIBA_FLAG_EFFECTIVE;
487101099Srwatson}
488101099Srwatson
489105656Srwatsonstatic void
490105656Srwatsonmac_biba_copy(struct mac_biba *source, struct mac_biba *dest)
491105656Srwatson{
492105656Srwatson
493132232Srwatson	if (source->mb_flags & MAC_BIBA_FLAG_EFFECTIVE)
494132232Srwatson		mac_biba_copy_effective(source, dest);
495105656Srwatson	if (source->mb_flags & MAC_BIBA_FLAG_RANGE)
496105656Srwatson		mac_biba_copy_range(source, dest);
497105656Srwatson}
498105656Srwatson
499101099Srwatson/*
500101099Srwatson * Policy module operations.
501101099Srwatson */
502101099Srwatsonstatic void
503101099Srwatsonmac_biba_init(struct mac_policy_conf *conf)
504101099Srwatson{
505101099Srwatson
506122879Srwatson	zone_biba = uma_zcreate("mac_biba", sizeof(struct mac_biba), NULL,
507122879Srwatson	    NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
508101099Srwatson}
509101099Srwatson
510101099Srwatson/*
511101099Srwatson * Label operations.
512101099Srwatson */
513101099Srwatsonstatic void
514104514Srwatsonmac_biba_init_label(struct label *label)
515101099Srwatson{
516101099Srwatson
517132781Skan	SLOT_SET(label, biba_alloc(M_WAITOK));
518101099Srwatson}
519101099Srwatson
520101099Srwatsonstatic int
521104514Srwatsonmac_biba_init_label_waitcheck(struct label *label, int flag)
522101099Srwatson{
523101099Srwatson
524132781Skan	SLOT_SET(label, biba_alloc(flag));
525101099Srwatson	if (SLOT(label) == NULL)
526101099Srwatson		return (ENOMEM);
527101099Srwatson
528101099Srwatson	return (0);
529101099Srwatson}
530101099Srwatson
531101099Srwatsonstatic void
532104514Srwatsonmac_biba_destroy_label(struct label *label)
533101099Srwatson{
534101099Srwatson
535101099Srwatson	biba_free(SLOT(label));
536132781Skan	SLOT_SET(label, NULL);
537101099Srwatson}
538101099Srwatson
539105696Srwatson/*
540115497Srwatson * mac_biba_element_to_string() accepts an sbuf and Biba element.  It
541115497Srwatson * converts the Biba element to a string and stores the result in the
542115497Srwatson * sbuf; if there isn't space in the sbuf, -1 is returned.
543105696Srwatson */
544115497Srwatsonstatic int
545115497Srwatsonmac_biba_element_to_string(struct sbuf *sb, struct mac_biba_element *element)
546105696Srwatson{
547115497Srwatson	int i, first;
548105696Srwatson
549105696Srwatson	switch (element->mbe_type) {
550105696Srwatson	case MAC_BIBA_TYPE_HIGH:
551115497Srwatson		return (sbuf_printf(sb, "high"));
552105696Srwatson
553105696Srwatson	case MAC_BIBA_TYPE_LOW:
554115497Srwatson		return (sbuf_printf(sb, "low"));
555105696Srwatson
556105696Srwatson	case MAC_BIBA_TYPE_EQUAL:
557115497Srwatson		return (sbuf_printf(sb, "equal"));
558105696Srwatson
559105696Srwatson	case MAC_BIBA_TYPE_GRADE:
560115497Srwatson		if (sbuf_printf(sb, "%d", element->mbe_grade) == -1)
561115497Srwatson			return (-1);
562115497Srwatson
563115497Srwatson		first = 1;
564115497Srwatson		for (i = 1; i <= MAC_BIBA_MAX_COMPARTMENTS; i++) {
565115497Srwatson			if (MAC_BIBA_BIT_TEST(i, element->mbe_compartments)) {
566115497Srwatson				if (first) {
567115497Srwatson					if (sbuf_putc(sb, ':') == -1)
568115497Srwatson						return (-1);
569115497Srwatson					if (sbuf_printf(sb, "%d", i) == -1)
570115497Srwatson						return (-1);
571115497Srwatson					first = 0;
572115497Srwatson				} else {
573115497Srwatson					if (sbuf_printf(sb, "+%d", i) == -1)
574115497Srwatson						return (-1);
575115497Srwatson				}
576115497Srwatson			}
577105696Srwatson		}
578115497Srwatson		return (0);
579105696Srwatson
580105696Srwatson	default:
581105696Srwatson		panic("mac_biba_element_to_string: invalid type (%d)",
582105696Srwatson		    element->mbe_type);
583105696Srwatson	}
584105696Srwatson}
585105696Srwatson
586115497Srwatson/*
587116701Srwatson * mac_biba_to_string() converts a Biba label to a string, and places
588116701Srwatson * the results in the passed sbuf.  It returns 0 on success, or EINVAL
589116701Srwatson * if there isn't room in the sbuf.  Note: the sbuf will be modified
590116701Srwatson * even in a failure case, so the caller may need to revert the sbuf
591116701Srwatson * by restoring the offset if that's undesired.
592115497Srwatson */
593101099Srwatsonstatic int
594116701Srwatsonmac_biba_to_string(struct sbuf *sb, struct mac_biba *mac_biba)
595101099Srwatson{
596105696Srwatson
597132232Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
598132232Srwatson		if (mac_biba_element_to_string(sb, &mac_biba->mb_effective)
599115497Srwatson		    == -1)
600105696Srwatson			return (EINVAL);
601105696Srwatson	}
602105696Srwatson
603105696Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
604116701Srwatson		if (sbuf_putc(sb, '(') == -1)
605105696Srwatson			return (EINVAL);
606105696Srwatson
607116701Srwatson		if (mac_biba_element_to_string(sb, &mac_biba->mb_rangelow)
608115497Srwatson		    == -1)
609105696Srwatson			return (EINVAL);
610105696Srwatson
611116701Srwatson		if (sbuf_putc(sb, '-') == -1)
612105696Srwatson			return (EINVAL);
613105696Srwatson
614116701Srwatson		if (mac_biba_element_to_string(sb, &mac_biba->mb_rangehigh)
615115497Srwatson		    == -1)
616105696Srwatson			return (EINVAL);
617105696Srwatson
618116701Srwatson		if (sbuf_putc(sb, ')') == -1)
619105696Srwatson			return (EINVAL);
620105696Srwatson	}
621105696Srwatson
622105696Srwatson	return (0);
623105696Srwatson}
624105696Srwatson
625105696Srwatsonstatic int
626105696Srwatsonmac_biba_externalize_label(struct label *label, char *element_name,
627116701Srwatson    struct sbuf *sb, int *claimed)
628105696Srwatson{
629101099Srwatson	struct mac_biba *mac_biba;
630101099Srwatson
631105696Srwatson	if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0)
632105696Srwatson		return (0);
633105696Srwatson
634105696Srwatson	(*claimed)++;
635105696Srwatson
636101099Srwatson	mac_biba = SLOT(label);
637116701Srwatson	return (mac_biba_to_string(sb, mac_biba));
638105696Srwatson}
639105696Srwatson
640105696Srwatsonstatic int
641105696Srwatsonmac_biba_parse_element(struct mac_biba_element *element, char *string)
642101099Srwatson{
643115395Srwatson	char *compartment, *end, *grade;
644115395Srwatson	int value;
645105696Srwatson
646105696Srwatson	if (strcmp(string, "high") == 0 ||
647105696Srwatson	    strcmp(string, "hi") == 0) {
648105696Srwatson		element->mbe_type = MAC_BIBA_TYPE_HIGH;
649105696Srwatson		element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
650105696Srwatson	} else if (strcmp(string, "low") == 0 ||
651105696Srwatson	    strcmp(string, "lo") == 0) {
652105696Srwatson		element->mbe_type = MAC_BIBA_TYPE_LOW;
653105696Srwatson		element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
654105696Srwatson	} else if (strcmp(string, "equal") == 0 ||
655105696Srwatson	    strcmp(string, "eq") == 0) {
656105696Srwatson		element->mbe_type = MAC_BIBA_TYPE_EQUAL;
657105696Srwatson		element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
658105696Srwatson	} else {
659115395Srwatson		element->mbe_type = MAC_BIBA_TYPE_GRADE;
660105696Srwatson
661115395Srwatson		/*
662115395Srwatson		 * Numeric grade piece of the element.
663115395Srwatson		 */
664115395Srwatson		grade = strsep(&string, ":");
665115395Srwatson		value = strtol(grade, &end, 10);
666115395Srwatson		if (end == grade || *end != '\0')
667105696Srwatson			return (EINVAL);
668115395Srwatson		if (value < 0 || value > 65535)
669115395Srwatson			return (EINVAL);
670115395Srwatson		element->mbe_grade = value;
671105696Srwatson
672115395Srwatson		/*
673115395Srwatson		 * Optional compartment piece of the element.  If none
674115395Srwatson		 * are included, we assume that the label has no
675115395Srwatson		 * compartments.
676115395Srwatson		 */
677115395Srwatson		if (string == NULL)
678115395Srwatson			return (0);
679115395Srwatson		if (*string == '\0')
680115395Srwatson			return (0);
681105696Srwatson
682115395Srwatson		while ((compartment = strsep(&string, "+")) != NULL) {
683115395Srwatson			value = strtol(compartment, &end, 10);
684115395Srwatson			if (compartment == end || *end != '\0')
685105696Srwatson				return (EINVAL);
686115395Srwatson			if (value < 1 || value > MAC_BIBA_MAX_COMPARTMENTS)
687105696Srwatson				return (EINVAL);
688115395Srwatson			MAC_BIBA_BIT_SET(value, element->mbe_compartments);
689105696Srwatson		}
690105696Srwatson	}
691105696Srwatson
692105696Srwatson	return (0);
693105696Srwatson}
694105696Srwatson
695105696Srwatson/*
696105696Srwatson * Note: destructively consumes the string, make a local copy before
697105696Srwatson * calling if that's a problem.
698105696Srwatson */
699105696Srwatsonstatic int
700105696Srwatsonmac_biba_parse(struct mac_biba *mac_biba, char *string)
701105696Srwatson{
702132232Srwatson	char *rangehigh, *rangelow, *effective;
703101099Srwatson	int error;
704101099Srwatson
705132232Srwatson	effective = strsep(&string, "(");
706132232Srwatson	if (*effective == '\0')
707132232Srwatson		effective = NULL;
708115395Srwatson
709115395Srwatson	if (string != NULL) {
710115395Srwatson		rangelow = strsep(&string, "-");
711115395Srwatson		if (string == NULL)
712105696Srwatson			return (EINVAL);
713115395Srwatson		rangehigh = strsep(&string, ")");
714115395Srwatson		if (string == NULL)
715105696Srwatson			return (EINVAL);
716115395Srwatson		if (*string != '\0')
717105696Srwatson			return (EINVAL);
718115395Srwatson	} else {
719115395Srwatson		rangelow = NULL;
720115395Srwatson		rangehigh = NULL;
721105696Srwatson	}
722115395Srwatson
723105696Srwatson	KASSERT((rangelow != NULL && rangehigh != NULL) ||
724105696Srwatson	    (rangelow == NULL && rangehigh == NULL),
725115395Srwatson	    ("mac_biba_parse: range mismatch"));
726101099Srwatson
727105696Srwatson	bzero(mac_biba, sizeof(*mac_biba));
728132232Srwatson	if (effective != NULL) {
729132232Srwatson		error = mac_biba_parse_element(&mac_biba->mb_effective, effective);
730105696Srwatson		if (error)
731105696Srwatson			return (error);
732132232Srwatson		mac_biba->mb_flags |= MAC_BIBA_FLAG_EFFECTIVE;
733105696Srwatson	}
734105696Srwatson
735105696Srwatson	if (rangelow != NULL) {
736105696Srwatson		error = mac_biba_parse_element(&mac_biba->mb_rangelow,
737105696Srwatson		    rangelow);
738105696Srwatson		if (error)
739105696Srwatson			return (error);
740105696Srwatson		error = mac_biba_parse_element(&mac_biba->mb_rangehigh,
741105696Srwatson		    rangehigh);
742105696Srwatson		if (error)
743105696Srwatson			return (error);
744105696Srwatson		mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE;
745105696Srwatson	}
746105696Srwatson
747101099Srwatson	error = mac_biba_valid(mac_biba);
748101099Srwatson	if (error)
749101099Srwatson		return (error);
750101099Srwatson
751105696Srwatson	return (0);
752105696Srwatson}
753101099Srwatson
754105696Srwatsonstatic int
755105696Srwatsonmac_biba_internalize_label(struct label *label, char *element_name,
756105696Srwatson    char *element_data, int *claimed)
757105696Srwatson{
758105696Srwatson	struct mac_biba *mac_biba, mac_biba_temp;
759105696Srwatson	int error;
760105696Srwatson
761105696Srwatson	if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0)
762105696Srwatson		return (0);
763105696Srwatson
764105696Srwatson	(*claimed)++;
765105696Srwatson
766105696Srwatson	error = mac_biba_parse(&mac_biba_temp, element_data);
767105696Srwatson	if (error)
768105696Srwatson		return (error);
769105696Srwatson
770105696Srwatson	mac_biba = SLOT(label);
771105696Srwatson	*mac_biba = mac_biba_temp;
772105696Srwatson
773101099Srwatson	return (0);
774101099Srwatson}
775101099Srwatson
776105696Srwatsonstatic void
777105696Srwatsonmac_biba_copy_label(struct label *src, struct label *dest)
778105696Srwatson{
779105696Srwatson
780105696Srwatson	*SLOT(dest) = *SLOT(src);
781105696Srwatson}
782105696Srwatson
783101099Srwatson/*
784101099Srwatson * Labeling event operations: file system objects, and things that look
785101099Srwatson * a lot like file system objects.
786101099Srwatson */
787101099Srwatsonstatic void
788147982Srwatsonmac_biba_create_devfs_device(struct ucred *cred, struct mount *mp,
789147982Srwatson    struct cdev *dev, struct devfs_dirent *devfs_dirent, struct label *label)
790101099Srwatson{
791101099Srwatson	struct mac_biba *mac_biba;
792101099Srwatson	int biba_type;
793101099Srwatson
794101099Srwatson	mac_biba = SLOT(label);
795101099Srwatson	if (strcmp(dev->si_name, "null") == 0 ||
796101099Srwatson	    strcmp(dev->si_name, "zero") == 0 ||
797101099Srwatson	    strcmp(dev->si_name, "random") == 0 ||
798101099Srwatson	    strncmp(dev->si_name, "fd/", strlen("fd/")) == 0)
799101099Srwatson		biba_type = MAC_BIBA_TYPE_EQUAL;
800105606Srwatson	else if (ptys_equal &&
801105606Srwatson	    (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 ||
802105606Srwatson	    strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0))
803105606Srwatson		biba_type = MAC_BIBA_TYPE_EQUAL;
804101099Srwatson	else
805101099Srwatson		biba_type = MAC_BIBA_TYPE_HIGH;
806132232Srwatson	mac_biba_set_effective(mac_biba, biba_type, 0, NULL);
807101099Srwatson}
808101099Srwatson
809101099Srwatsonstatic void
810107698Srwatsonmac_biba_create_devfs_directory(struct mount *mp, char *dirname,
811107698Srwatson    int dirnamelen, struct devfs_dirent *devfs_dirent, struct label *label)
812101099Srwatson{
813101099Srwatson	struct mac_biba *mac_biba;
814101099Srwatson
815101099Srwatson	mac_biba = SLOT(label);
816132232Srwatson	mac_biba_set_effective(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
817101099Srwatson}
818101099Srwatson
819101099Srwatsonstatic void
820107698Srwatsonmac_biba_create_devfs_symlink(struct ucred *cred, struct mount *mp,
821107698Srwatson    struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de,
822122563Srwatson    struct label *delabel)
823104535Srwatson{
824104535Srwatson	struct mac_biba *source, *dest;
825104535Srwatson
826122524Srwatson	source = SLOT(cred->cr_label);
827104535Srwatson	dest = SLOT(delabel);
828104535Srwatson
829132232Srwatson	mac_biba_copy_effective(source, dest);
830104535Srwatson}
831104535Srwatson
832104535Srwatsonstatic void
833101099Srwatsonmac_biba_create_mount(struct ucred *cred, struct mount *mp,
834101099Srwatson    struct label *mntlabel, struct label *fslabel)
835101099Srwatson{
836101099Srwatson	struct mac_biba *source, *dest;
837101099Srwatson
838122524Srwatson	source = SLOT(cred->cr_label);
839101099Srwatson	dest = SLOT(mntlabel);
840132232Srwatson	mac_biba_copy_effective(source, dest);
841101099Srwatson	dest = SLOT(fslabel);
842132232Srwatson	mac_biba_copy_effective(source, dest);
843101099Srwatson}
844101099Srwatson
845101099Srwatsonstatic void
846101099Srwatsonmac_biba_relabel_vnode(struct ucred *cred, struct vnode *vp,
847101099Srwatson    struct label *vnodelabel, struct label *label)
848101099Srwatson{
849101099Srwatson	struct mac_biba *source, *dest;
850101099Srwatson
851101099Srwatson	source = SLOT(label);
852101099Srwatson	dest = SLOT(vnodelabel);
853101099Srwatson
854105656Srwatson	mac_biba_copy(source, dest);
855101099Srwatson}
856101099Srwatson
857101099Srwatsonstatic void
858107698Srwatsonmac_biba_update_devfsdirent(struct mount *mp,
859107698Srwatson    struct devfs_dirent *devfs_dirent, struct label *direntlabel,
860107698Srwatson    struct vnode *vp, struct label *vnodelabel)
861101099Srwatson{
862101099Srwatson	struct mac_biba *source, *dest;
863101099Srwatson
864101099Srwatson	source = SLOT(vnodelabel);
865101099Srwatson	dest = SLOT(direntlabel);
866101099Srwatson
867105656Srwatson	mac_biba_copy(source, dest);
868101099Srwatson}
869101099Srwatson
870101099Srwatsonstatic void
871105988Srwatsonmac_biba_associate_vnode_devfs(struct mount *mp, struct label *fslabel,
872105988Srwatson    struct devfs_dirent *de, struct label *delabel, struct vnode *vp,
873105988Srwatson    struct label *vlabel)
874101099Srwatson{
875101099Srwatson	struct mac_biba *source, *dest;
876101099Srwatson
877105988Srwatson	source = SLOT(delabel);
878105988Srwatson	dest = SLOT(vlabel);
879101099Srwatson
880132232Srwatson	mac_biba_copy_effective(source, dest);
881101099Srwatson}
882101099Srwatson
883101099Srwatsonstatic int
884105988Srwatsonmac_biba_associate_vnode_extattr(struct mount *mp, struct label *fslabel,
885105988Srwatson    struct vnode *vp, struct label *vlabel)
886101099Srwatson{
887105988Srwatson	struct mac_biba temp, *source, *dest;
888106354Smux	int buflen, error;
889101099Srwatson
890105988Srwatson	source = SLOT(fslabel);
891105988Srwatson	dest = SLOT(vlabel);
892101099Srwatson
893105988Srwatson	buflen = sizeof(temp);
894105988Srwatson	bzero(&temp, buflen);
895105988Srwatson
896105988Srwatson	error = vn_extattr_get(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
897105988Srwatson	    MAC_BIBA_EXTATTR_NAME, &buflen, (char *) &temp, curthread);
898105988Srwatson	if (error == ENOATTR || error == EOPNOTSUPP) {
899105988Srwatson		/* Fall back to the fslabel. */
900132232Srwatson		mac_biba_copy_effective(source, dest);
901105988Srwatson		return (0);
902105988Srwatson	} else if (error)
903101099Srwatson		return (error);
904101099Srwatson
905105988Srwatson	if (buflen != sizeof(temp)) {
906105988Srwatson		printf("mac_biba_associate_vnode_extattr: bad size %d\n",
907105988Srwatson		    buflen);
908105988Srwatson		return (EPERM);
909105988Srwatson	}
910105988Srwatson	if (mac_biba_valid(&temp) != 0) {
911105988Srwatson		printf("mac_biba_associate_vnode_extattr: invalid\n");
912105988Srwatson		return (EPERM);
913105988Srwatson	}
914132232Srwatson	if ((temp.mb_flags & MAC_BIBA_FLAGS_BOTH) != MAC_BIBA_FLAG_EFFECTIVE) {
915132232Srwatson		printf("mac_biba_associate_vnode_extattr: not effective\n");
916105988Srwatson		return (EPERM);
917105988Srwatson	}
918101099Srwatson
919132232Srwatson	mac_biba_copy_effective(&temp, dest);
920101099Srwatson	return (0);
921101099Srwatson}
922101099Srwatson
923101099Srwatsonstatic void
924105988Srwatsonmac_biba_associate_vnode_singlelabel(struct mount *mp,
925105988Srwatson    struct label *fslabel, struct vnode *vp, struct label *vlabel)
926101099Srwatson{
927101099Srwatson	struct mac_biba *source, *dest;
928101099Srwatson
929101099Srwatson	source = SLOT(fslabel);
930105988Srwatson	dest = SLOT(vlabel);
931101099Srwatson
932132232Srwatson	mac_biba_copy_effective(source, dest);
933101099Srwatson}
934101099Srwatson
935105988Srwatsonstatic int
936105988Srwatsonmac_biba_create_vnode_extattr(struct ucred *cred, struct mount *mp,
937105988Srwatson    struct label *fslabel, struct vnode *dvp, struct label *dlabel,
938105988Srwatson    struct vnode *vp, struct label *vlabel, struct componentname *cnp)
939105988Srwatson{
940105988Srwatson	struct mac_biba *source, *dest, temp;
941105988Srwatson	size_t buflen;
942105988Srwatson	int error;
943105988Srwatson
944105988Srwatson	buflen = sizeof(temp);
945105988Srwatson	bzero(&temp, buflen);
946105988Srwatson
947122524Srwatson	source = SLOT(cred->cr_label);
948105988Srwatson	dest = SLOT(vlabel);
949132232Srwatson	mac_biba_copy_effective(source, &temp);
950105988Srwatson
951105988Srwatson	error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
952105988Srwatson	    MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread);
953105988Srwatson	if (error == 0)
954132232Srwatson		mac_biba_copy_effective(source, dest);
955105988Srwatson	return (error);
956105988Srwatson}
957105988Srwatson
958105988Srwatsonstatic int
959105988Srwatsonmac_biba_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp,
960105988Srwatson    struct label *vlabel, struct label *intlabel)
961105988Srwatson{
962105988Srwatson	struct mac_biba *source, temp;
963105988Srwatson	size_t buflen;
964105988Srwatson	int error;
965105988Srwatson
966105988Srwatson	buflen = sizeof(temp);
967105988Srwatson	bzero(&temp, buflen);
968105988Srwatson
969105988Srwatson	source = SLOT(intlabel);
970132232Srwatson	if ((source->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) == 0)
971105988Srwatson		return (0);
972105988Srwatson
973132232Srwatson	mac_biba_copy_effective(source, &temp);
974105988Srwatson
975105988Srwatson	error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
976105988Srwatson	    MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread);
977105988Srwatson	return (error);
978105988Srwatson}
979105988Srwatson
980101099Srwatson/*
981101099Srwatson * Labeling event operations: IPC object.
982101099Srwatson */
983101099Srwatsonstatic void
984122875Srwatsonmac_biba_create_inpcb_from_socket(struct socket *so, struct label *solabel,
985122875Srwatson    struct inpcb *inp, struct label *inplabel)
986122875Srwatson{
987122875Srwatson	struct mac_biba *source, *dest;
988122875Srwatson
989122875Srwatson	source = SLOT(solabel);
990122875Srwatson	dest = SLOT(inplabel);
991122875Srwatson
992132232Srwatson	mac_biba_copy_effective(source, dest);
993122875Srwatson}
994122875Srwatson
995122875Srwatsonstatic void
996101099Srwatsonmac_biba_create_mbuf_from_socket(struct socket *so, struct label *socketlabel,
997101099Srwatson    struct mbuf *m, struct label *mbuflabel)
998101099Srwatson{
999101099Srwatson	struct mac_biba *source, *dest;
1000101099Srwatson
1001101099Srwatson	source = SLOT(socketlabel);
1002101099Srwatson	dest = SLOT(mbuflabel);
1003101099Srwatson
1004132232Srwatson	mac_biba_copy_effective(source, dest);
1005101099Srwatson}
1006101099Srwatson
1007101099Srwatsonstatic void
1008101099Srwatsonmac_biba_create_socket(struct ucred *cred, struct socket *socket,
1009101099Srwatson    struct label *socketlabel)
1010101099Srwatson{
1011101099Srwatson	struct mac_biba *source, *dest;
1012101099Srwatson
1013122524Srwatson	source = SLOT(cred->cr_label);
1014101099Srwatson	dest = SLOT(socketlabel);
1015101099Srwatson
1016132232Srwatson	mac_biba_copy_effective(source, dest);
1017101099Srwatson}
1018101099Srwatson
1019101099Srwatsonstatic void
1020125293Srwatsonmac_biba_create_pipe(struct ucred *cred, struct pipepair *pp,
1021101099Srwatson    struct label *pipelabel)
1022101099Srwatson{
1023101099Srwatson	struct mac_biba *source, *dest;
1024101099Srwatson
1025122524Srwatson	source = SLOT(cred->cr_label);
1026101099Srwatson	dest = SLOT(pipelabel);
1027101099Srwatson
1028132232Srwatson	mac_biba_copy_effective(source, dest);
1029101099Srwatson}
1030101099Srwatson
1031101099Srwatsonstatic void
1032145855Srwatsonmac_biba_create_posix_sem(struct ucred *cred, struct ksem *ksemptr,
1033145855Srwatson    struct label *ks_label)
1034145855Srwatson{
1035145855Srwatson	struct mac_biba *source, *dest;
1036145855Srwatson
1037145855Srwatson	source = SLOT(cred->cr_label);
1038145855Srwatson	dest = SLOT(ks_label);
1039145855Srwatson
1040145855Srwatson	mac_biba_copy_effective(source, dest);
1041145855Srwatson}
1042145855Srwatson
1043145855Srwatsonstatic void
1044101099Srwatsonmac_biba_create_socket_from_socket(struct socket *oldsocket,
1045101099Srwatson    struct label *oldsocketlabel, struct socket *newsocket,
1046101099Srwatson    struct label *newsocketlabel)
1047101099Srwatson{
1048101099Srwatson	struct mac_biba *source, *dest;
1049101099Srwatson
1050101099Srwatson	source = SLOT(oldsocketlabel);
1051101099Srwatson	dest = SLOT(newsocketlabel);
1052101099Srwatson
1053132232Srwatson	mac_biba_copy_effective(source, dest);
1054101099Srwatson}
1055101099Srwatson
1056101099Srwatsonstatic void
1057101099Srwatsonmac_biba_relabel_socket(struct ucred *cred, struct socket *socket,
1058101099Srwatson    struct label *socketlabel, struct label *newlabel)
1059101099Srwatson{
1060101099Srwatson	struct mac_biba *source, *dest;
1061101099Srwatson
1062101099Srwatson	source = SLOT(newlabel);
1063101099Srwatson	dest = SLOT(socketlabel);
1064101099Srwatson
1065105656Srwatson	mac_biba_copy(source, dest);
1066101099Srwatson}
1067101099Srwatson
1068101099Srwatsonstatic void
1069125293Srwatsonmac_biba_relabel_pipe(struct ucred *cred, struct pipepair *pp,
1070101099Srwatson    struct label *pipelabel, struct label *newlabel)
1071101099Srwatson{
1072101099Srwatson	struct mac_biba *source, *dest;
1073101099Srwatson
1074101099Srwatson	source = SLOT(newlabel);
1075101099Srwatson	dest = SLOT(pipelabel);
1076101099Srwatson
1077105656Srwatson	mac_biba_copy(source, dest);
1078101099Srwatson}
1079101099Srwatson
1080101099Srwatsonstatic void
1081101099Srwatsonmac_biba_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel,
1082101099Srwatson    struct socket *socket, struct label *socketpeerlabel)
1083101099Srwatson{
1084101099Srwatson	struct mac_biba *source, *dest;
1085101099Srwatson
1086101099Srwatson	source = SLOT(mbuflabel);
1087101099Srwatson	dest = SLOT(socketpeerlabel);
1088101099Srwatson
1089132232Srwatson	mac_biba_copy_effective(source, dest);
1090101099Srwatson}
1091101099Srwatson
1092101099Srwatson/*
1093140628Srwatson * Labeling event operations: System V IPC objects.
1094140628Srwatson */
1095140628Srwatson
1096140628Srwatsonstatic void
1097140628Srwatsonmac_biba_create_sysv_msgmsg(struct ucred *cred, struct msqid_kernel *msqkptr,
1098140628Srwatson    struct label *msqlabel, struct msg *msgptr, struct label *msglabel)
1099140628Srwatson{
1100140628Srwatson	struct mac_biba *source, *dest;
1101140628Srwatson
1102140628Srwatson	/* Ignore the msgq label */
1103140628Srwatson	source = SLOT(cred->cr_label);
1104140628Srwatson	dest = SLOT(msglabel);
1105140628Srwatson
1106140628Srwatson	mac_biba_copy_effective(source, dest);
1107140628Srwatson}
1108140628Srwatson
1109140628Srwatsonstatic void
1110140628Srwatsonmac_biba_create_sysv_msgqueue(struct ucred *cred,
1111140628Srwatson    struct msqid_kernel *msqkptr, struct label *msqlabel)
1112140628Srwatson{
1113140628Srwatson	struct mac_biba *source, *dest;
1114140628Srwatson
1115140628Srwatson	source = SLOT(cred->cr_label);
1116140628Srwatson	dest = SLOT(msqlabel);
1117140628Srwatson
1118140628Srwatson	mac_biba_copy_effective(source, dest);
1119140628Srwatson}
1120140628Srwatson
1121140628Srwatsonstatic void
1122147091Srwatsonmac_biba_create_sysv_sem(struct ucred *cred, struct semid_kernel *semakptr,
1123140628Srwatson    struct label *semalabel)
1124140628Srwatson{
1125140628Srwatson	struct mac_biba *source, *dest;
1126140628Srwatson
1127140628Srwatson	source = SLOT(cred->cr_label);
1128140628Srwatson	dest = SLOT(semalabel);
1129140628Srwatson
1130140628Srwatson	mac_biba_copy_effective(source, dest);
1131140628Srwatson}
1132140628Srwatson
1133140628Srwatsonstatic void
1134140628Srwatsonmac_biba_create_sysv_shm(struct ucred *cred, struct shmid_kernel *shmsegptr,
1135140628Srwatson    struct label *shmlabel)
1136140628Srwatson{
1137140628Srwatson	struct mac_biba *source, *dest;
1138140628Srwatson
1139140628Srwatson	source = SLOT(cred->cr_label);
1140140628Srwatson	dest = SLOT(shmlabel);
1141140628Srwatson
1142140628Srwatson	mac_biba_copy_effective(source, dest);
1143140628Srwatson}
1144140628Srwatson
1145140628Srwatson/*
1146101099Srwatson * Labeling event operations: network objects.
1147101099Srwatson */
1148101099Srwatsonstatic void
1149101099Srwatsonmac_biba_set_socket_peer_from_socket(struct socket *oldsocket,
1150101099Srwatson    struct label *oldsocketlabel, struct socket *newsocket,
1151101099Srwatson    struct label *newsocketpeerlabel)
1152101099Srwatson{
1153101099Srwatson	struct mac_biba *source, *dest;
1154101099Srwatson
1155101099Srwatson	source = SLOT(oldsocketlabel);
1156101099Srwatson	dest = SLOT(newsocketpeerlabel);
1157101099Srwatson
1158132232Srwatson	mac_biba_copy_effective(source, dest);
1159101099Srwatson}
1160101099Srwatson
1161101099Srwatsonstatic void
1162101099Srwatsonmac_biba_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d,
1163101099Srwatson    struct label *bpflabel)
1164101099Srwatson{
1165101099Srwatson	struct mac_biba *source, *dest;
1166101099Srwatson
1167122524Srwatson	source = SLOT(cred->cr_label);
1168101099Srwatson	dest = SLOT(bpflabel);
1169101099Srwatson
1170132232Srwatson	mac_biba_copy_effective(source, dest);
1171101099Srwatson}
1172101099Srwatson
1173101099Srwatsonstatic void
1174101099Srwatsonmac_biba_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel)
1175101099Srwatson{
1176121816Sbrooks	char tifname[IFNAMSIZ], *p, *q;
1177101099Srwatson	char tiflist[sizeof(trusted_interfaces)];
1178101099Srwatson	struct mac_biba *dest;
1179110350Srwatson	int len, type;
1180101099Srwatson
1181101099Srwatson	dest = SLOT(ifnetlabel);
1182101099Srwatson
1183153927Scsjp	if (ifnet->if_type == IFT_LOOP || interfaces_equal != 0) {
1184110350Srwatson		type = MAC_BIBA_TYPE_EQUAL;
1185101099Srwatson		goto set;
1186101099Srwatson	}
1187101099Srwatson
1188101099Srwatson	if (trust_all_interfaces) {
1189110350Srwatson		type = MAC_BIBA_TYPE_HIGH;
1190101099Srwatson		goto set;
1191101099Srwatson	}
1192101099Srwatson
1193110350Srwatson	type = MAC_BIBA_TYPE_LOW;
1194101099Srwatson
1195101099Srwatson	if (trusted_interfaces[0] == '\0' ||
1196101099Srwatson	    !strvalid(trusted_interfaces, sizeof(trusted_interfaces)))
1197101099Srwatson		goto set;
1198101099Srwatson
1199106089Srwatson	bzero(tiflist, sizeof(tiflist));
1200101099Srwatson	for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++)
1201101099Srwatson		if(*p != ' ' && *p != '\t')
1202101099Srwatson			*q = *p;
1203101099Srwatson
1204101099Srwatson	for (p = q = tiflist;; p++) {
1205101099Srwatson		if (*p == ',' || *p == '\0') {
1206101099Srwatson			len = p - q;
1207101099Srwatson			if (len < IFNAMSIZ) {
1208101099Srwatson				bzero(tifname, sizeof(tifname));
1209101099Srwatson				bcopy(q, tifname, len);
1210121816Sbrooks				if (strcmp(tifname, ifnet->if_xname) == 0) {
1211110350Srwatson					type = MAC_BIBA_TYPE_HIGH;
1212101099Srwatson					break;
1213101099Srwatson				}
1214106089Srwatson			} else {
1215106089Srwatson				*p = '\0';
1216106089Srwatson				printf("mac_biba warning: interface name "
1217106089Srwatson				    "\"%s\" is too long (must be < %d)\n",
1218106089Srwatson				    q, IFNAMSIZ);
1219101099Srwatson			}
1220101099Srwatson			if (*p == '\0')
1221101099Srwatson				break;
1222101099Srwatson			q = p + 1;
1223101099Srwatson		}
1224101099Srwatson	}
1225101099Srwatsonset:
1226132232Srwatson	mac_biba_set_effective(dest, type, 0, NULL);
1227110350Srwatson	mac_biba_set_range(dest, type, 0, NULL, type, 0, NULL);
1228101099Srwatson}
1229101099Srwatson
1230101099Srwatsonstatic void
1231101099Srwatsonmac_biba_create_ipq(struct mbuf *fragment, struct label *fragmentlabel,
1232101099Srwatson    struct ipq *ipq, struct label *ipqlabel)
1233101099Srwatson{
1234101099Srwatson	struct mac_biba *source, *dest;
1235101099Srwatson
1236101099Srwatson	source = SLOT(fragmentlabel);
1237101099Srwatson	dest = SLOT(ipqlabel);
1238101099Srwatson
1239132232Srwatson	mac_biba_copy_effective(source, dest);
1240101099Srwatson}
1241101099Srwatson
1242101099Srwatsonstatic void
1243101099Srwatsonmac_biba_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel,
1244101099Srwatson    struct mbuf *datagram, struct label *datagramlabel)
1245101099Srwatson{
1246101099Srwatson	struct mac_biba *source, *dest;
1247101099Srwatson
1248101099Srwatson	source = SLOT(ipqlabel);
1249101099Srwatson	dest = SLOT(datagramlabel);
1250101099Srwatson
1251101099Srwatson	/* Just use the head, since we require them all to match. */
1252132232Srwatson	mac_biba_copy_effective(source, dest);
1253101099Srwatson}
1254101099Srwatson
1255101099Srwatsonstatic void
1256101099Srwatsonmac_biba_create_fragment(struct mbuf *datagram, struct label *datagramlabel,
1257101099Srwatson    struct mbuf *fragment, struct label *fragmentlabel)
1258101099Srwatson{
1259101099Srwatson	struct mac_biba *source, *dest;
1260101099Srwatson
1261101099Srwatson	source = SLOT(datagramlabel);
1262101099Srwatson	dest = SLOT(fragmentlabel);
1263101099Srwatson
1264132232Srwatson	mac_biba_copy_effective(source, dest);
1265101099Srwatson}
1266101099Srwatson
1267101099Srwatsonstatic void
1268123607Srwatsonmac_biba_create_mbuf_from_inpcb(struct inpcb *inp, struct label *inplabel,
1269123607Srwatson    struct mbuf *m, struct label *mlabel)
1270123607Srwatson{
1271123607Srwatson	struct mac_biba *source, *dest;
1272123607Srwatson
1273123607Srwatson	source = SLOT(inplabel);
1274123607Srwatson	dest = SLOT(mlabel);
1275123607Srwatson
1276132232Srwatson	mac_biba_copy_effective(source, dest);
1277123607Srwatson}
1278123607Srwatson
1279123607Srwatsonstatic void
1280101099Srwatsonmac_biba_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel,
1281101099Srwatson    struct mbuf *mbuf, struct label *mbuflabel)
1282101099Srwatson{
1283101099Srwatson	struct mac_biba *dest;
1284101099Srwatson
1285101099Srwatson	dest = SLOT(mbuflabel);
1286101099Srwatson
1287132232Srwatson	mac_biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1288101099Srwatson}
1289101099Srwatson
1290101099Srwatsonstatic void
1291101099Srwatsonmac_biba_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel,
1292101099Srwatson    struct mbuf *mbuf, struct label *mbuflabel)
1293101099Srwatson{
1294101099Srwatson	struct mac_biba *source, *dest;
1295101099Srwatson
1296101099Srwatson	source = SLOT(bpflabel);
1297101099Srwatson	dest = SLOT(mbuflabel);
1298101099Srwatson
1299132232Srwatson	mac_biba_copy_effective(source, dest);
1300101099Srwatson}
1301101099Srwatson
1302101099Srwatsonstatic void
1303101099Srwatsonmac_biba_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel,
1304101099Srwatson    struct mbuf *m, struct label *mbuflabel)
1305101099Srwatson{
1306101099Srwatson	struct mac_biba *source, *dest;
1307101099Srwatson
1308101099Srwatson	source = SLOT(ifnetlabel);
1309101099Srwatson	dest = SLOT(mbuflabel);
1310101099Srwatson
1311132232Srwatson	mac_biba_copy_effective(source, dest);
1312101099Srwatson}
1313101099Srwatson
1314101099Srwatsonstatic void
1315101099Srwatsonmac_biba_create_mbuf_multicast_encap(struct mbuf *oldmbuf,
1316101099Srwatson    struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel,
1317101099Srwatson    struct mbuf *newmbuf, struct label *newmbuflabel)
1318101099Srwatson{
1319101099Srwatson	struct mac_biba *source, *dest;
1320101099Srwatson
1321101099Srwatson	source = SLOT(oldmbuflabel);
1322101099Srwatson	dest = SLOT(newmbuflabel);
1323101099Srwatson
1324132232Srwatson	mac_biba_copy_effective(source, dest);
1325101099Srwatson}
1326101099Srwatson
1327101099Srwatsonstatic void
1328101099Srwatsonmac_biba_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel,
1329101099Srwatson    struct mbuf *newmbuf, struct label *newmbuflabel)
1330101099Srwatson{
1331101099Srwatson	struct mac_biba *source, *dest;
1332101099Srwatson
1333101099Srwatson	source = SLOT(oldmbuflabel);
1334101099Srwatson	dest = SLOT(newmbuflabel);
1335101099Srwatson
1336132232Srwatson	mac_biba_copy_effective(source, dest);
1337101099Srwatson}
1338101099Srwatson
1339101099Srwatsonstatic int
1340101099Srwatsonmac_biba_fragment_match(struct mbuf *fragment, struct label *fragmentlabel,
1341101099Srwatson    struct ipq *ipq, struct label *ipqlabel)
1342101099Srwatson{
1343101099Srwatson	struct mac_biba *a, *b;
1344101099Srwatson
1345101099Srwatson	a = SLOT(ipqlabel);
1346101099Srwatson	b = SLOT(fragmentlabel);
1347101099Srwatson
1348132232Srwatson	return (mac_biba_equal_effective(a, b));
1349101099Srwatson}
1350101099Srwatson
1351101099Srwatsonstatic void
1352101099Srwatsonmac_biba_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet,
1353101099Srwatson    struct label *ifnetlabel, struct label *newlabel)
1354101099Srwatson{
1355101099Srwatson	struct mac_biba *source, *dest;
1356101099Srwatson
1357101099Srwatson	source = SLOT(newlabel);
1358101099Srwatson	dest = SLOT(ifnetlabel);
1359101099Srwatson
1360105656Srwatson	mac_biba_copy(source, dest);
1361101099Srwatson}
1362101099Srwatson
1363101099Srwatsonstatic void
1364101099Srwatsonmac_biba_update_ipq(struct mbuf *fragment, struct label *fragmentlabel,
1365101099Srwatson    struct ipq *ipq, struct label *ipqlabel)
1366101099Srwatson{
1367101099Srwatson
1368101099Srwatson	/* NOOP: we only accept matching labels, so no need to update */
1369101099Srwatson}
1370101099Srwatson
1371122875Srwatsonstatic void
1372122875Srwatsonmac_biba_inpcb_sosetlabel(struct socket *so, struct label *solabel,
1373122875Srwatson    struct inpcb *inp, struct label *inplabel)
1374122875Srwatson{
1375122875Srwatson	struct mac_biba *source, *dest;
1376122875Srwatson
1377122875Srwatson	source = SLOT(solabel);
1378122875Srwatson	dest = SLOT(inplabel);
1379122875Srwatson
1380122875Srwatson	mac_biba_copy(source, dest);
1381122875Srwatson}
1382122875Srwatson
1383162238Scsjpstatic void
1384162238Scsjpmac_biba_create_mbuf_from_firewall(struct mbuf *m, struct label *label)
1385162238Scsjp{
1386162238Scsjp	struct mac_biba *dest;
1387162238Scsjp
1388162238Scsjp	dest = SLOT(label);
1389162238Scsjp
1390162238Scsjp	/* XXX: where is the label for the firewall really comming from? */
1391162238Scsjp	mac_biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1392162238Scsjp}
1393162238Scsjp
1394101099Srwatson/*
1395101099Srwatson * Labeling event operations: processes.
1396101099Srwatson */
1397101099Srwatsonstatic void
1398101099Srwatsonmac_biba_create_proc0(struct ucred *cred)
1399101099Srwatson{
1400101099Srwatson	struct mac_biba *dest;
1401101099Srwatson
1402122524Srwatson	dest = SLOT(cred->cr_label);
1403101099Srwatson
1404132232Srwatson	mac_biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1405105643Srwatson	mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL,
1406105643Srwatson	    MAC_BIBA_TYPE_HIGH, 0, NULL);
1407101099Srwatson}
1408101099Srwatson
1409101099Srwatsonstatic void
1410101099Srwatsonmac_biba_create_proc1(struct ucred *cred)
1411101099Srwatson{
1412101099Srwatson	struct mac_biba *dest;
1413101099Srwatson
1414122524Srwatson	dest = SLOT(cred->cr_label);
1415101099Srwatson
1416132232Srwatson	mac_biba_set_effective(dest, MAC_BIBA_TYPE_HIGH, 0, NULL);
1417105643Srwatson	mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL,
1418105643Srwatson	    MAC_BIBA_TYPE_HIGH, 0, NULL);
1419101099Srwatson}
1420101099Srwatson
1421101099Srwatsonstatic void
1422101099Srwatsonmac_biba_relabel_cred(struct ucred *cred, struct label *newlabel)
1423101099Srwatson{
1424101099Srwatson	struct mac_biba *source, *dest;
1425101099Srwatson
1426101099Srwatson	source = SLOT(newlabel);
1427122524Srwatson	dest = SLOT(cred->cr_label);
1428101099Srwatson
1429105656Srwatson	mac_biba_copy(source, dest);
1430101099Srwatson}
1431101099Srwatson
1432101099Srwatson/*
1433140628Srwatson * Label cleanup/flush operations
1434140628Srwatson */
1435140628Srwatsonstatic void
1436140628Srwatsonmac_biba_cleanup_sysv_msgmsg(struct label *msglabel)
1437140628Srwatson{
1438140628Srwatson
1439140628Srwatson	bzero(SLOT(msglabel), sizeof(struct mac_biba));
1440140628Srwatson}
1441140628Srwatson
1442140628Srwatsonstatic void
1443140628Srwatsonmac_biba_cleanup_sysv_msgqueue(struct label *msqlabel)
1444140628Srwatson{
1445140628Srwatson
1446140628Srwatson	bzero(SLOT(msqlabel), sizeof(struct mac_biba));
1447140628Srwatson}
1448140628Srwatson
1449140628Srwatsonstatic void
1450147091Srwatsonmac_biba_cleanup_sysv_sem(struct label *semalabel)
1451140628Srwatson{
1452140628Srwatson
1453140628Srwatson	bzero(SLOT(semalabel), sizeof(struct mac_biba));
1454140628Srwatson}
1455140628Srwatson
1456140628Srwatsonstatic void
1457140628Srwatsonmac_biba_cleanup_sysv_shm(struct label *shmlabel)
1458140628Srwatson{
1459140628Srwatson	bzero(SLOT(shmlabel), sizeof(struct mac_biba));
1460140628Srwatson}
1461140628Srwatson
1462140628Srwatson/*
1463101099Srwatson * Access control checks.
1464101099Srwatson */
1465101099Srwatsonstatic int
1466101099Srwatsonmac_biba_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel,
1467101099Srwatson    struct ifnet *ifnet, struct label *ifnetlabel)
1468101099Srwatson{
1469101099Srwatson	struct mac_biba *a, *b;
1470101099Srwatson
1471101099Srwatson	if (!mac_biba_enabled)
1472101099Srwatson		return (0);
1473101099Srwatson
1474101099Srwatson	a = SLOT(bpflabel);
1475101099Srwatson	b = SLOT(ifnetlabel);
1476101099Srwatson
1477132232Srwatson	if (mac_biba_equal_effective(a, b))
1478101099Srwatson		return (0);
1479101099Srwatson	return (EACCES);
1480101099Srwatson}
1481101099Srwatson
1482101099Srwatsonstatic int
1483101099Srwatsonmac_biba_check_cred_relabel(struct ucred *cred, struct label *newlabel)
1484101099Srwatson{
1485101099Srwatson	struct mac_biba *subj, *new;
1486105634Srwatson	int error;
1487101099Srwatson
1488122524Srwatson	subj = SLOT(cred->cr_label);
1489101099Srwatson	new = SLOT(newlabel);
1490101099Srwatson
1491101099Srwatson	/*
1492105634Srwatson	 * If there is a Biba label update for the credential, it may
1493132232Srwatson	 * be an update of the effective, range, or both.
1494101099Srwatson	 */
1495105634Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
1496105634Srwatson	if (error)
1497105634Srwatson		return (error);
1498101099Srwatson
1499101099Srwatson	/*
1500105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
1501101099Srwatson	 */
1502105634Srwatson	if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) {
1503105634Srwatson		/*
1504110351Srwatson		 * If the change request modifies both the Biba label
1505132232Srwatson		 * effective and range, check that the new effective will be
1506110351Srwatson		 * in the new range.
1507110351Srwatson		 */
1508110351Srwatson		if ((new->mb_flags & MAC_BIBA_FLAGS_BOTH) ==
1509110351Srwatson		    MAC_BIBA_FLAGS_BOTH &&
1510132232Srwatson		    !mac_biba_effective_in_range(new, new))
1511110351Srwatson			return (EINVAL);
1512110351Srwatson
1513110351Srwatson		/*
1514132232Srwatson		 * To change the Biba effective label on a credential, the
1515132232Srwatson		 * new effective label must be in the current range.
1516105634Srwatson		 */
1517132232Srwatson		if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE &&
1518132232Srwatson		    !mac_biba_effective_in_range(new, subj))
1519105634Srwatson			return (EPERM);
1520101099Srwatson
1521105634Srwatson		/*
1522105634Srwatson		 * To change the Biba range on a credential, the new
1523105634Srwatson		 * range label must be in the current range.
1524105634Srwatson		 */
1525105634Srwatson		if (new->mb_flags & MAC_BIBA_FLAG_RANGE &&
1526105634Srwatson		    !mac_biba_range_in_range(new, subj))
1527105634Srwatson			return (EPERM);
1528101099Srwatson
1529105634Srwatson		/*
1530105634Srwatson		 * To have EQUAL in any component of the new credential
1531105634Srwatson		 * Biba label, the subject must already have EQUAL in
1532105634Srwatson		 * their label.
1533105634Srwatson		 */
1534105634Srwatson		if (mac_biba_contains_equal(new)) {
1535106090Srwatson			error = mac_biba_subject_privileged(subj);
1536105634Srwatson			if (error)
1537105634Srwatson				return (error);
1538105634Srwatson		}
1539105634Srwatson	}
1540105634Srwatson
1541101099Srwatson	return (0);
1542101099Srwatson}
1543101099Srwatson
1544101099Srwatsonstatic int
1545101099Srwatsonmac_biba_check_cred_visible(struct ucred *u1, struct ucred *u2)
1546101099Srwatson{
1547101099Srwatson	struct mac_biba *subj, *obj;
1548101099Srwatson
1549101099Srwatson	if (!mac_biba_enabled)
1550101099Srwatson		return (0);
1551101099Srwatson
1552122524Srwatson	subj = SLOT(u1->cr_label);
1553122524Srwatson	obj = SLOT(u2->cr_label);
1554101099Srwatson
1555101099Srwatson	/* XXX: range */
1556132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
1557101099Srwatson		return (ESRCH);
1558101099Srwatson
1559101099Srwatson	return (0);
1560101099Srwatson}
1561101099Srwatson
1562101099Srwatsonstatic int
1563101099Srwatsonmac_biba_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet,
1564101099Srwatson    struct label *ifnetlabel, struct label *newlabel)
1565101099Srwatson{
1566101099Srwatson	struct mac_biba *subj, *new;
1567105634Srwatson	int error;
1568101099Srwatson
1569122524Srwatson	subj = SLOT(cred->cr_label);
1570101099Srwatson	new = SLOT(newlabel);
1571101099Srwatson
1572105634Srwatson	/*
1573105634Srwatson	 * If there is a Biba label update for the interface, it may
1574132232Srwatson	 * be an update of the effective, range, or both.
1575105634Srwatson	 */
1576105634Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
1577105634Srwatson	if (error)
1578105634Srwatson		return (error);
1579101099Srwatson
1580105634Srwatson	/*
1581106160Srwatson	 * Relabling network interfaces requires Biba privilege.
1582106160Srwatson	 */
1583106160Srwatson	error = mac_biba_subject_privileged(subj);
1584106160Srwatson	if (error)
1585106160Srwatson		return (error);
1586106160Srwatson
1587105634Srwatson	return (0);
1588101099Srwatson}
1589101099Srwatson
1590103759Srwatsonstatic int
1591101099Srwatsonmac_biba_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel,
1592101099Srwatson    struct mbuf *m, struct label *mbuflabel)
1593101099Srwatson{
1594101099Srwatson	struct mac_biba *p, *i;
1595103761Srwatson
1596101099Srwatson	if (!mac_biba_enabled)
1597101099Srwatson		return (0);
1598101099Srwatson
1599101099Srwatson	p = SLOT(mbuflabel);
1600101099Srwatson	i = SLOT(ifnetlabel);
1601103759Srwatson
1602132232Srwatson	return (mac_biba_effective_in_range(p, i) ? 0 : EACCES);
1603101099Srwatson}
1604101099Srwatson
1605101099Srwatsonstatic int
1606122875Srwatsonmac_biba_check_inpcb_deliver(struct inpcb *inp, struct label *inplabel,
1607122875Srwatson    struct mbuf *m, struct label *mlabel)
1608122875Srwatson{
1609122875Srwatson	struct mac_biba *p, *i;
1610122875Srwatson
1611122875Srwatson	if (!mac_biba_enabled)
1612122875Srwatson		return (0);
1613122875Srwatson
1614122875Srwatson	p = SLOT(mlabel);
1615122875Srwatson	i = SLOT(inplabel);
1616122875Srwatson
1617132232Srwatson	return (mac_biba_equal_effective(p, i) ? 0 : EACCES);
1618122875Srwatson}
1619122875Srwatson
1620122875Srwatsonstatic int
1621140628Srwatsonmac_biba_check_sysv_msgrcv(struct ucred *cred, struct msg *msgptr,
1622140628Srwatson    struct label *msglabel)
1623140628Srwatson{
1624140628Srwatson	struct mac_biba *subj, *obj;
1625140628Srwatson
1626140628Srwatson	if (!mac_biba_enabled)
1627140628Srwatson		return (0);
1628140628Srwatson
1629140628Srwatson	subj = SLOT(cred->cr_label);
1630140628Srwatson	obj = SLOT(msglabel);
1631140628Srwatson
1632140628Srwatson	if (!mac_biba_dominate_effective(obj, subj))
1633140628Srwatson		return (EACCES);
1634140628Srwatson
1635140628Srwatson	return (0);
1636140628Srwatson}
1637140628Srwatson
1638140628Srwatsonstatic int
1639140628Srwatsonmac_biba_check_sysv_msgrmid(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(subj, obj))
1651140628Srwatson		return (EACCES);
1652140628Srwatson
1653140628Srwatson	return (0);
1654140628Srwatson}
1655140628Srwatson
1656140628Srwatsonstatic int
1657140628Srwatsonmac_biba_check_sysv_msqget(struct ucred *cred, struct msqid_kernel *msqkptr,
1658140628Srwatson    struct label *msqklabel)
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(msqklabel);
1667140628Srwatson
1668140628Srwatson	if (!mac_biba_dominate_effective(obj, subj))
1669140628Srwatson		return (EACCES);
1670140628Srwatson
1671140628Srwatson	return (0);
1672140628Srwatson}
1673140628Srwatson
1674140628Srwatsonstatic int
1675140628Srwatsonmac_biba_check_sysv_msqsnd(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(subj, obj))
1687140628Srwatson		return (EACCES);
1688140628Srwatson
1689140628Srwatson	return (0);
1690140628Srwatson}
1691140628Srwatson
1692140628Srwatsonstatic int
1693140628Srwatsonmac_biba_check_sysv_msqrcv(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(obj, subj))
1705140628Srwatson		return (EACCES);
1706140628Srwatson
1707140628Srwatson	return (0);
1708140628Srwatson}
1709140628Srwatson
1710140628Srwatson
1711140628Srwatsonstatic int
1712140628Srwatsonmac_biba_check_sysv_msqctl(struct ucred *cred, struct msqid_kernel *msqkptr,
1713140628Srwatson    struct label *msqklabel, int cmd)
1714140628Srwatson{
1715140628Srwatson	struct mac_biba *subj, *obj;
1716140628Srwatson
1717140628Srwatson	if (!mac_biba_enabled)
1718140628Srwatson		return (0);
1719140628Srwatson
1720140628Srwatson	subj = SLOT(cred->cr_label);
1721140628Srwatson	obj = SLOT(msqklabel);
1722140628Srwatson
1723140628Srwatson	switch(cmd) {
1724140628Srwatson	case IPC_RMID:
1725140628Srwatson	case IPC_SET:
1726140628Srwatson		if (!mac_biba_dominate_effective(subj, obj))
1727140628Srwatson			return (EACCES);
1728140628Srwatson		break;
1729140628Srwatson
1730140628Srwatson	case IPC_STAT:
1731140628Srwatson		if (!mac_biba_dominate_effective(obj, subj))
1732140628Srwatson			return (EACCES);
1733140628Srwatson		break;
1734140628Srwatson
1735140628Srwatson	default:
1736140628Srwatson		return (EACCES);
1737140628Srwatson	}
1738140628Srwatson
1739140628Srwatson	return (0);
1740140628Srwatson}
1741140628Srwatson
1742140628Srwatsonstatic int
1743140628Srwatsonmac_biba_check_sysv_semctl(struct ucred *cred, struct semid_kernel *semakptr,
1744140628Srwatson    struct label *semaklabel, int cmd)
1745140628Srwatson{
1746140628Srwatson	struct mac_biba *subj, *obj;
1747140628Srwatson
1748140628Srwatson	if (!mac_biba_enabled)
1749140628Srwatson		return (0);
1750140628Srwatson
1751140628Srwatson	subj = SLOT(cred->cr_label);
1752140628Srwatson	obj = SLOT(semaklabel);
1753140628Srwatson
1754140628Srwatson	switch(cmd) {
1755140628Srwatson	case IPC_RMID:
1756140628Srwatson	case IPC_SET:
1757140628Srwatson	case SETVAL:
1758140628Srwatson	case SETALL:
1759140628Srwatson		if (!mac_biba_dominate_effective(subj, obj))
1760140628Srwatson			return (EACCES);
1761140628Srwatson		break;
1762140628Srwatson
1763140628Srwatson	case IPC_STAT:
1764140628Srwatson	case GETVAL:
1765140628Srwatson	case GETPID:
1766140628Srwatson	case GETNCNT:
1767140628Srwatson	case GETZCNT:
1768140628Srwatson	case GETALL:
1769140628Srwatson		if (!mac_biba_dominate_effective(obj, subj))
1770140628Srwatson			return (EACCES);
1771140628Srwatson		break;
1772140628Srwatson
1773140628Srwatson	default:
1774140628Srwatson		return (EACCES);
1775140628Srwatson	}
1776140628Srwatson
1777140628Srwatson	return (0);
1778140628Srwatson}
1779140628Srwatson
1780140628Srwatson
1781140628Srwatsonstatic int
1782140628Srwatsonmac_biba_check_sysv_semget(struct ucred *cred, struct semid_kernel *semakptr,
1783140628Srwatson    struct label *semaklabel)
1784140628Srwatson{
1785140628Srwatson	struct mac_biba *subj, *obj;
1786140628Srwatson
1787140628Srwatson	if (!mac_biba_enabled)
1788140628Srwatson		return (0);
1789140628Srwatson
1790140628Srwatson	subj = SLOT(cred->cr_label);
1791140628Srwatson	obj = SLOT(semaklabel);
1792140628Srwatson
1793140628Srwatson	if (!mac_biba_dominate_effective(obj, subj))
1794140628Srwatson		return (EACCES);
1795140628Srwatson
1796140628Srwatson	return (0);
1797140628Srwatson}
1798140628Srwatson
1799140628Srwatson
1800140628Srwatsonstatic int
1801140628Srwatsonmac_biba_check_sysv_semop(struct ucred *cred, struct semid_kernel *semakptr,
1802140628Srwatson    struct label *semaklabel, size_t accesstype)
1803140628Srwatson{
1804140628Srwatson	struct mac_biba *subj, *obj;
1805140628Srwatson
1806140628Srwatson	if (!mac_biba_enabled)
1807140628Srwatson		return (0);
1808140628Srwatson
1809140628Srwatson	subj = SLOT(cred->cr_label);
1810140628Srwatson	obj = SLOT(semaklabel);
1811140628Srwatson
1812140628Srwatson	if (accesstype & SEM_R)
1813140628Srwatson		if (!mac_biba_dominate_effective(obj, subj))
1814140628Srwatson			return (EACCES);
1815140628Srwatson
1816140628Srwatson	if (accesstype & SEM_A)
1817140628Srwatson		if (!mac_biba_dominate_effective(subj, obj))
1818140628Srwatson			return (EACCES);
1819140628Srwatson
1820140628Srwatson	return (0);
1821140628Srwatson}
1822140628Srwatson
1823140628Srwatsonstatic int
1824140628Srwatsonmac_biba_check_sysv_shmat(struct ucred *cred, struct shmid_kernel *shmsegptr,
1825140628Srwatson    struct label *shmseglabel, int shmflg)
1826140628Srwatson{
1827140628Srwatson	struct mac_biba *subj, *obj;
1828140628Srwatson
1829140628Srwatson	if (!mac_biba_enabled)
1830140628Srwatson		return (0);
1831140628Srwatson
1832140628Srwatson	subj = SLOT(cred->cr_label);
1833140628Srwatson	obj = SLOT(shmseglabel);
1834140628Srwatson
1835140628Srwatson	if (!mac_biba_dominate_effective(obj, subj))
1836140628Srwatson		return (EACCES);
1837140628Srwatson	if ((shmflg & SHM_RDONLY) == 0) {
1838140628Srwatson		if (!mac_biba_dominate_effective(subj, obj))
1839140628Srwatson			return (EACCES);
1840140628Srwatson	}
1841140628Srwatson
1842140628Srwatson	return (0);
1843140628Srwatson}
1844140628Srwatson
1845140628Srwatsonstatic int
1846140628Srwatsonmac_biba_check_sysv_shmctl(struct ucred *cred, struct shmid_kernel *shmsegptr,
1847140628Srwatson    struct label *shmseglabel, int cmd)
1848140628Srwatson{
1849140628Srwatson	struct mac_biba *subj, *obj;
1850140628Srwatson
1851140628Srwatson	if (!mac_biba_enabled)
1852140628Srwatson		return (0);
1853140628Srwatson
1854140628Srwatson	subj = SLOT(cred->cr_label);
1855140628Srwatson	obj = SLOT(shmseglabel);
1856140628Srwatson
1857140628Srwatson	switch(cmd) {
1858140628Srwatson	case IPC_RMID:
1859140628Srwatson	case IPC_SET:
1860140628Srwatson		if (!mac_biba_dominate_effective(subj, obj))
1861140628Srwatson			return (EACCES);
1862140628Srwatson		break;
1863140628Srwatson
1864140628Srwatson	case IPC_STAT:
1865140628Srwatson	case SHM_STAT:
1866140628Srwatson		if (!mac_biba_dominate_effective(obj, subj))
1867140628Srwatson			return (EACCES);
1868140628Srwatson		break;
1869140628Srwatson
1870140628Srwatson	default:
1871140628Srwatson		return (EACCES);
1872140628Srwatson	}
1873140628Srwatson
1874140628Srwatson	return (0);
1875140628Srwatson}
1876140628Srwatson
1877140628Srwatsonstatic int
1878140628Srwatsonmac_biba_check_sysv_shmget(struct ucred *cred, struct shmid_kernel *shmsegptr,
1879140628Srwatson    struct label *shmseglabel, int shmflg)
1880140628Srwatson{
1881140628Srwatson	struct mac_biba *subj, *obj;
1882140628Srwatson
1883140628Srwatson	if (!mac_biba_enabled)
1884140628Srwatson		return (0);
1885140628Srwatson
1886140628Srwatson	subj = SLOT(cred->cr_label);
1887140628Srwatson	obj = SLOT(shmseglabel);
1888140628Srwatson
1889140628Srwatson	if (!mac_biba_dominate_effective(obj, subj))
1890140628Srwatson		return (EACCES);
1891140628Srwatson
1892140628Srwatson	return (0);
1893140628Srwatson}
1894140628Srwatson
1895140628Srwatsonstatic int
1896110354Srwatsonmac_biba_check_kld_load(struct ucred *cred, struct vnode *vp,
1897110354Srwatson    struct label *label)
1898110354Srwatson{
1899110354Srwatson	struct mac_biba *subj, *obj;
1900110354Srwatson	int error;
1901110354Srwatson
1902110354Srwatson	if (!mac_biba_enabled)
1903110354Srwatson		return (0);
1904110354Srwatson
1905122524Srwatson	subj = SLOT(cred->cr_label);
1906110354Srwatson
1907110354Srwatson	error = mac_biba_subject_privileged(subj);
1908110354Srwatson	if (error)
1909110354Srwatson		return (error);
1910110354Srwatson
1911110354Srwatson	obj = SLOT(label);
1912132232Srwatson	if (!mac_biba_high_effective(obj))
1913110354Srwatson		return (EACCES);
1914110354Srwatson
1915110354Srwatson	return (0);
1916110354Srwatson}
1917110354Srwatson
1918110354Srwatson
1919110354Srwatsonstatic int
1920110354Srwatsonmac_biba_check_kld_unload(struct ucred *cred)
1921110354Srwatson{
1922110354Srwatson	struct mac_biba *subj;
1923110354Srwatson
1924110354Srwatson	if (!mac_biba_enabled)
1925110354Srwatson		return (0);
1926110354Srwatson
1927122524Srwatson	subj = SLOT(cred->cr_label);
1928110354Srwatson
1929110354Srwatson	return (mac_biba_subject_privileged(subj));
1930110354Srwatson}
1931110354Srwatson
1932110354Srwatsonstatic int
1933101099Srwatsonmac_biba_check_mount_stat(struct ucred *cred, struct mount *mp,
1934101099Srwatson    struct label *mntlabel)
1935101099Srwatson{
1936101099Srwatson	struct mac_biba *subj, *obj;
1937101099Srwatson
1938101099Srwatson	if (!mac_biba_enabled)
1939101099Srwatson		return (0);
1940101099Srwatson
1941122524Srwatson	subj = SLOT(cred->cr_label);
1942101099Srwatson	obj = SLOT(mntlabel);
1943101099Srwatson
1944132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
1945101099Srwatson		return (EACCES);
1946101099Srwatson
1947101099Srwatson	return (0);
1948101099Srwatson}
1949101099Srwatson
1950101099Srwatsonstatic int
1951125293Srwatsonmac_biba_check_pipe_ioctl(struct ucred *cred, struct pipepair *pp,
1952101099Srwatson    struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data)
1953101099Srwatson{
1954103759Srwatson
1955101099Srwatson	if(!mac_biba_enabled)
1956101099Srwatson		return (0);
1957101099Srwatson
1958101099Srwatson	/* XXX: This will be implemented soon... */
1959101099Srwatson
1960101099Srwatson	return (0);
1961101099Srwatson}
1962101099Srwatson
1963101099Srwatsonstatic int
1964125293Srwatsonmac_biba_check_pipe_poll(struct ucred *cred, struct pipepair *pp,
1965102115Srwatson    struct label *pipelabel)
1966101099Srwatson{
1967101099Srwatson	struct mac_biba *subj, *obj;
1968101099Srwatson
1969101099Srwatson	if (!mac_biba_enabled)
1970101099Srwatson		return (0);
1971101099Srwatson
1972122524Srwatson	subj = SLOT(cred->cr_label);
1973101099Srwatson	obj = SLOT((pipelabel));
1974101099Srwatson
1975132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
1976102115Srwatson		return (EACCES);
1977101099Srwatson
1978101099Srwatson	return (0);
1979101099Srwatson}
1980101099Srwatson
1981101099Srwatsonstatic int
1982125293Srwatsonmac_biba_check_pipe_read(struct ucred *cred, struct pipepair *pp,
1983102115Srwatson    struct label *pipelabel)
1984102115Srwatson{
1985102115Srwatson	struct mac_biba *subj, *obj;
1986102115Srwatson
1987102115Srwatson	if (!mac_biba_enabled)
1988102115Srwatson		return (0);
1989102115Srwatson
1990122524Srwatson	subj = SLOT(cred->cr_label);
1991102115Srwatson	obj = SLOT((pipelabel));
1992102115Srwatson
1993132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
1994102115Srwatson		return (EACCES);
1995102115Srwatson
1996102115Srwatson	return (0);
1997102115Srwatson}
1998102115Srwatson
1999102115Srwatsonstatic int
2000125293Srwatsonmac_biba_check_pipe_relabel(struct ucred *cred, struct pipepair *pp,
2001101099Srwatson    struct label *pipelabel, struct label *newlabel)
2002101099Srwatson{
2003101099Srwatson	struct mac_biba *subj, *obj, *new;
2004105634Srwatson	int error;
2005101099Srwatson
2006101099Srwatson	new = SLOT(newlabel);
2007122524Srwatson	subj = SLOT(cred->cr_label);
2008101099Srwatson	obj = SLOT(pipelabel);
2009101099Srwatson
2010101099Srwatson	/*
2011105634Srwatson	 * If there is a Biba label update for a pipe, it must be a
2012132232Srwatson	 * effective update.
2013101099Srwatson	 */
2014132232Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE);
2015105634Srwatson	if (error)
2016105634Srwatson		return (error);
2017101099Srwatson
2018101099Srwatson	/*
2019105634Srwatson	 * To perform a relabel of a pipe (Biba label or not), Biba must
2020105634Srwatson	 * authorize the relabel.
2021101099Srwatson	 */
2022132232Srwatson	if (!mac_biba_effective_in_range(obj, subj))
2023101099Srwatson		return (EPERM);
2024101099Srwatson
2025101099Srwatson	/*
2026105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
2027101099Srwatson	 */
2028132232Srwatson	if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
2029105634Srwatson		/*
2030105634Srwatson		 * To change the Biba label on a pipe, the new pipe label
2031105634Srwatson		 * must be in the subject range.
2032105634Srwatson		 */
2033132232Srwatson		if (!mac_biba_effective_in_range(new, subj))
2034105634Srwatson			return (EPERM);
2035101099Srwatson
2036105634Srwatson		/*
2037105634Srwatson		 * To change the Biba label on a pipe to be EQUAL, the
2038105634Srwatson		 * subject must have appropriate privilege.
2039105634Srwatson		 */
2040105634Srwatson		if (mac_biba_contains_equal(new)) {
2041106090Srwatson			error = mac_biba_subject_privileged(subj);
2042105634Srwatson			if (error)
2043105634Srwatson				return (error);
2044105634Srwatson		}
2045105634Srwatson	}
2046105634Srwatson
2047101099Srwatson	return (0);
2048101099Srwatson}
2049101099Srwatson
2050101099Srwatsonstatic int
2051125293Srwatsonmac_biba_check_pipe_stat(struct ucred *cred, struct pipepair *pp,
2052102115Srwatson    struct label *pipelabel)
2053102115Srwatson{
2054102115Srwatson	struct mac_biba *subj, *obj;
2055102115Srwatson
2056102115Srwatson	if (!mac_biba_enabled)
2057102115Srwatson		return (0);
2058102115Srwatson
2059122524Srwatson	subj = SLOT(cred->cr_label);
2060102115Srwatson	obj = SLOT((pipelabel));
2061102115Srwatson
2062132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2063102115Srwatson		return (EACCES);
2064102115Srwatson
2065102115Srwatson	return (0);
2066102115Srwatson}
2067102115Srwatson
2068102115Srwatsonstatic int
2069125293Srwatsonmac_biba_check_pipe_write(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(subj, obj))
2081102115Srwatson		return (EACCES);
2082102115Srwatson
2083102115Srwatson	return (0);
2084102115Srwatson}
2085102115Srwatson
2086102115Srwatsonstatic int
2087145855Srwatsonmac_biba_check_posix_sem_write(struct ucred *cred, struct ksem *ksemptr,
2088145855Srwatson    struct label *ks_label)
2089145855Srwatson{
2090145855Srwatson	struct mac_biba *subj, *obj;
2091145855Srwatson
2092145855Srwatson	if (!mac_biba_enabled)
2093145855Srwatson		return (0);
2094145855Srwatson
2095145855Srwatson	subj = SLOT(cred->cr_label);
2096145855Srwatson	obj = SLOT(ks_label);
2097145855Srwatson
2098145855Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2099145855Srwatson		return (EACCES);
2100145855Srwatson
2101145855Srwatson	return (0);
2102145855Srwatson}
2103145855Srwatson
2104145855Srwatsonstatic int
2105145855Srwatsonmac_biba_check_posix_sem_rdonly(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(obj, subj))
2117145855Srwatson		return (EACCES);
2118145855Srwatson
2119145855Srwatson	return (0);
2120145855Srwatson}
2121145855Srwatson
2122145855Srwatsonstatic int
2123101099Srwatsonmac_biba_check_proc_debug(struct ucred *cred, struct proc *proc)
2124101099Srwatson{
2125101099Srwatson	struct mac_biba *subj, *obj;
2126101099Srwatson
2127101099Srwatson	if (!mac_biba_enabled)
2128101099Srwatson		return (0);
2129101099Srwatson
2130122524Srwatson	subj = SLOT(cred->cr_label);
2131122524Srwatson	obj = SLOT(proc->p_ucred->cr_label);
2132101099Srwatson
2133101099Srwatson	/* XXX: range checks */
2134132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2135101099Srwatson		return (ESRCH);
2136132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2137101099Srwatson		return (EACCES);
2138101099Srwatson
2139101099Srwatson	return (0);
2140101099Srwatson}
2141101099Srwatson
2142101099Srwatsonstatic int
2143101099Srwatsonmac_biba_check_proc_sched(struct ucred *cred, struct proc *proc)
2144101099Srwatson{
2145101099Srwatson	struct mac_biba *subj, *obj;
2146103759Srwatson
2147101099Srwatson	if (!mac_biba_enabled)
2148101099Srwatson		return (0);
2149101099Srwatson
2150122524Srwatson	subj = SLOT(cred->cr_label);
2151122524Srwatson	obj = SLOT(proc->p_ucred->cr_label);
2152103759Srwatson
2153101099Srwatson	/* XXX: range checks */
2154132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2155101099Srwatson		return (ESRCH);
2156132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2157101099Srwatson		return (EACCES);
2158101099Srwatson
2159101099Srwatson	return (0);
2160101099Srwatson}
2161101099Srwatson
2162101099Srwatsonstatic int
2163101099Srwatsonmac_biba_check_proc_signal(struct ucred *cred, struct proc *proc, int signum)
2164101099Srwatson{
2165101099Srwatson	struct mac_biba *subj, *obj;
2166103759Srwatson
2167101099Srwatson	if (!mac_biba_enabled)
2168101099Srwatson		return (0);
2169101099Srwatson
2170122524Srwatson	subj = SLOT(cred->cr_label);
2171122524Srwatson	obj = SLOT(proc->p_ucred->cr_label);
2172103759Srwatson
2173101099Srwatson	/* XXX: range checks */
2174132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2175101099Srwatson		return (ESRCH);
2176132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2177101099Srwatson		return (EACCES);
2178101099Srwatson
2179101099Srwatson	return (0);
2180101099Srwatson}
2181101099Srwatson
2182101099Srwatsonstatic int
2183101934Srwatsonmac_biba_check_socket_deliver(struct socket *so, struct label *socketlabel,
2184101099Srwatson    struct mbuf *m, struct label *mbuflabel)
2185101099Srwatson{
2186101099Srwatson	struct mac_biba *p, *s;
2187101099Srwatson
2188101099Srwatson	if (!mac_biba_enabled)
2189101099Srwatson		return (0);
2190101099Srwatson
2191101099Srwatson	p = SLOT(mbuflabel);
2192101099Srwatson	s = SLOT(socketlabel);
2193101099Srwatson
2194132232Srwatson	return (mac_biba_equal_effective(p, s) ? 0 : EACCES);
2195101099Srwatson}
2196101099Srwatson
2197101099Srwatsonstatic int
2198106214Srwatsonmac_biba_check_socket_relabel(struct ucred *cred, struct socket *so,
2199101099Srwatson    struct label *socketlabel, struct label *newlabel)
2200101099Srwatson{
2201101099Srwatson	struct mac_biba *subj, *obj, *new;
2202105634Srwatson	int error;
2203101099Srwatson
2204101099Srwatson	new = SLOT(newlabel);
2205122524Srwatson	subj = SLOT(cred->cr_label);
2206101099Srwatson	obj = SLOT(socketlabel);
2207101099Srwatson
2208101099Srwatson	/*
2209105634Srwatson	 * If there is a Biba label update for the socket, it may be
2210132232Srwatson	 * an update of effective.
2211101099Srwatson	 */
2212132232Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE);
2213105634Srwatson	if (error)
2214105634Srwatson		return (error);
2215101099Srwatson
2216101099Srwatson	/*
2217132232Srwatson	 * To relabel a socket, the old socket effective must be in the subject
2218101099Srwatson	 * range.
2219101099Srwatson	 */
2220132232Srwatson	if (!mac_biba_effective_in_range(obj, subj))
2221101099Srwatson		return (EPERM);
2222101099Srwatson
2223101099Srwatson	/*
2224105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
2225101099Srwatson	 */
2226132232Srwatson	if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
2227105634Srwatson		/*
2228132232Srwatson		 * To relabel a socket, the new socket effective must be in
2229105634Srwatson		 * the subject range.
2230105634Srwatson		 */
2231132232Srwatson		if (!mac_biba_effective_in_range(new, subj))
2232105634Srwatson			return (EPERM);
2233101099Srwatson
2234105634Srwatson		/*
2235105634Srwatson		 * To change the Biba label on the socket to contain EQUAL,
2236105634Srwatson		 * the subject must have appropriate privilege.
2237105634Srwatson		 */
2238105634Srwatson		if (mac_biba_contains_equal(new)) {
2239106090Srwatson			error = mac_biba_subject_privileged(subj);
2240105634Srwatson			if (error)
2241105634Srwatson				return (error);
2242105634Srwatson		}
2243105634Srwatson	}
2244105634Srwatson
2245101099Srwatson	return (0);
2246101099Srwatson}
2247101099Srwatson
2248101099Srwatsonstatic int
2249101099Srwatsonmac_biba_check_socket_visible(struct ucred *cred, struct socket *socket,
2250101099Srwatson    struct label *socketlabel)
2251101099Srwatson{
2252101099Srwatson	struct mac_biba *subj, *obj;
2253101099Srwatson
2254105722Srwatson	if (!mac_biba_enabled)
2255105722Srwatson		return (0);
2256105722Srwatson
2257122524Srwatson	subj = SLOT(cred->cr_label);
2258101099Srwatson	obj = SLOT(socketlabel);
2259101099Srwatson
2260132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2261101099Srwatson		return (ENOENT);
2262101099Srwatson
2263101099Srwatson	return (0);
2264101099Srwatson}
2265101099Srwatson
2266101099Srwatsonstatic int
2267112574Srwatsonmac_biba_check_sysarch_ioperm(struct ucred *cred)
2268112574Srwatson{
2269112574Srwatson	struct mac_biba *subj;
2270112574Srwatson	int error;
2271112574Srwatson
2272112574Srwatson	if (!mac_biba_enabled)
2273112574Srwatson		return (0);
2274112574Srwatson
2275122524Srwatson	subj = SLOT(cred->cr_label);
2276112574Srwatson
2277112574Srwatson	error = mac_biba_subject_privileged(subj);
2278112574Srwatson	if (error)
2279112574Srwatson		return (error);
2280112574Srwatson
2281112574Srwatson	return (0);
2282112574Srwatson}
2283112574Srwatson
2284112574Srwatsonstatic int
2285106418Srwatsonmac_biba_check_system_acct(struct ucred *cred, struct vnode *vp,
2286106418Srwatson    struct label *label)
2287106418Srwatson{
2288106418Srwatson	struct mac_biba *subj, *obj;
2289106418Srwatson	int error;
2290106418Srwatson
2291106418Srwatson	if (!mac_biba_enabled)
2292106418Srwatson		return (0);
2293106418Srwatson
2294122524Srwatson	subj = SLOT(cred->cr_label);
2295106418Srwatson
2296106418Srwatson	error = mac_biba_subject_privileged(subj);
2297106418Srwatson	if (error)
2298106418Srwatson		return (error);
2299106418Srwatson
2300106418Srwatson	if (label == NULL)
2301106418Srwatson		return (0);
2302106418Srwatson
2303106418Srwatson	obj = SLOT(label);
2304132232Srwatson	if (!mac_biba_high_effective(obj))
2305106418Srwatson		return (EACCES);
2306106418Srwatson
2307106418Srwatson	return (0);
2308106418Srwatson}
2309106418Srwatson
2310106418Srwatsonstatic int
2311106418Srwatsonmac_biba_check_system_settime(struct ucred *cred)
2312106418Srwatson{
2313106418Srwatson	struct mac_biba *subj;
2314106418Srwatson	int error;
2315106418Srwatson
2316106418Srwatson	if (!mac_biba_enabled)
2317106418Srwatson		return (0);
2318106418Srwatson
2319122524Srwatson	subj = SLOT(cred->cr_label);
2320106418Srwatson
2321106418Srwatson	error = mac_biba_subject_privileged(subj);
2322106418Srwatson	if (error)
2323106418Srwatson		return (error);
2324106418Srwatson
2325106418Srwatson	return (0);
2326106418Srwatson}
2327106418Srwatson
2328106418Srwatsonstatic int
2329106161Srwatsonmac_biba_check_system_swapon(struct ucred *cred, struct vnode *vp,
2330106161Srwatson    struct label *label)
2331106161Srwatson{
2332106161Srwatson	struct mac_biba *subj, *obj;
2333106416Srwatson	int error;
2334106161Srwatson
2335106161Srwatson	if (!mac_biba_enabled)
2336106161Srwatson		return (0);
2337106161Srwatson
2338122524Srwatson	subj = SLOT(cred->cr_label);
2339106161Srwatson	obj = SLOT(label);
2340106161Srwatson
2341106416Srwatson	error = mac_biba_subject_privileged(subj);
2342106416Srwatson	if (error)
2343106416Srwatson		return (error);
2344106161Srwatson
2345132232Srwatson	if (!mac_biba_high_effective(obj))
2346106161Srwatson		return (EACCES);
2347106161Srwatson
2348106161Srwatson	return (0);
2349106161Srwatson}
2350106161Srwatson
2351106161Srwatsonstatic int
2352112574Srwatsonmac_biba_check_system_swapoff(struct ucred *cred, struct vnode *vp,
2353112574Srwatson    struct label *label)
2354112574Srwatson{
2355112574Srwatson	struct mac_biba *subj, *obj;
2356112574Srwatson	int error;
2357112574Srwatson
2358112574Srwatson	if (!mac_biba_enabled)
2359112574Srwatson		return (0);
2360112574Srwatson
2361122524Srwatson	subj = SLOT(cred->cr_label);
2362112574Srwatson	obj = SLOT(label);
2363112574Srwatson
2364112574Srwatson	error = mac_biba_subject_privileged(subj);
2365112574Srwatson	if (error)
2366112574Srwatson		return (error);
2367112574Srwatson
2368112574Srwatson	return (0);
2369112574Srwatson}
2370112574Srwatson
2371112574Srwatsonstatic int
2372126121Spjdmac_biba_check_system_sysctl(struct ucred *cred, struct sysctl_oid *oidp,
2373126121Spjd    void *arg1, int arg2, struct sysctl_req *req)
2374106161Srwatson{
2375106161Srwatson	struct mac_biba *subj;
2376106161Srwatson	int error;
2377106161Srwatson
2378106161Srwatson	if (!mac_biba_enabled)
2379106161Srwatson		return (0);
2380106161Srwatson
2381122524Srwatson	subj = SLOT(cred->cr_label);
2382106161Srwatson
2383106161Srwatson	/*
2384126121Spjd	 * Treat sysctl variables without CTLFLAG_ANYBODY flag as
2385126121Spjd	 * biba/high, but also require privilege to change them.
2386106161Srwatson	 */
2387126121Spjd	if (req->newptr != NULL && (oidp->oid_kind & CTLFLAG_ANYBODY) == 0) {
2388106161Srwatson		if (!mac_biba_subject_dominate_high(subj))
2389106161Srwatson			return (EACCES);
2390106161Srwatson
2391106161Srwatson		error = mac_biba_subject_privileged(subj);
2392106161Srwatson		if (error)
2393106161Srwatson			return (error);
2394106161Srwatson	}
2395106161Srwatson
2396106161Srwatson	return (0);
2397106161Srwatson}
2398106161Srwatson
2399106161Srwatsonstatic int
2400101099Srwatsonmac_biba_check_vnode_chdir(struct ucred *cred, struct vnode *dvp,
2401101099Srwatson    struct label *dlabel)
2402101099Srwatson{
2403101099Srwatson	struct mac_biba *subj, *obj;
2404101099Srwatson
2405101099Srwatson	if (!mac_biba_enabled)
2406101099Srwatson		return (0);
2407101099Srwatson
2408122524Srwatson	subj = SLOT(cred->cr_label);
2409101099Srwatson	obj = SLOT(dlabel);
2410101099Srwatson
2411132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2412101099Srwatson		return (EACCES);
2413101099Srwatson
2414101099Srwatson	return (0);
2415101099Srwatson}
2416101099Srwatson
2417101099Srwatsonstatic int
2418101099Srwatsonmac_biba_check_vnode_chroot(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_create(struct ucred *cred, struct vnode *dvp,
2437101099Srwatson    struct label *dlabel, struct componentname *cnp, struct vattr *vap)
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(subj, obj))
2448101099Srwatson		return (EACCES);
2449101099Srwatson
2450101099Srwatson	return (0);
2451101099Srwatson}
2452101099Srwatson
2453101099Srwatsonstatic int
2454101099Srwatsonmac_biba_check_vnode_delete(struct ucred *cred, struct vnode *dvp,
2455101099Srwatson    struct label *dlabel, struct vnode *vp, struct label *label,
2456101099Srwatson    struct componentname *cnp)
2457101099Srwatson{
2458101099Srwatson	struct mac_biba *subj, *obj;
2459101099Srwatson
2460101099Srwatson	if (!mac_biba_enabled)
2461101099Srwatson		return (0);
2462101099Srwatson
2463122524Srwatson	subj = SLOT(cred->cr_label);
2464101099Srwatson	obj = SLOT(dlabel);
2465101099Srwatson
2466132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2467101099Srwatson		return (EACCES);
2468101099Srwatson
2469101099Srwatson	obj = SLOT(label);
2470101099Srwatson
2471132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2472101099Srwatson		return (EACCES);
2473101099Srwatson
2474101099Srwatson	return (0);
2475101099Srwatson}
2476101099Srwatson
2477101099Srwatsonstatic int
2478101099Srwatsonmac_biba_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
2479101099Srwatson    struct label *label, acl_type_t type)
2480101099Srwatson{
2481101099Srwatson	struct mac_biba *subj, *obj;
2482101099Srwatson
2483101099Srwatson	if (!mac_biba_enabled)
2484101099Srwatson		return (0);
2485101099Srwatson
2486122524Srwatson	subj = SLOT(cred->cr_label);
2487101099Srwatson	obj = SLOT(label);
2488101099Srwatson
2489132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2490101099Srwatson		return (EACCES);
2491101099Srwatson
2492101099Srwatson	return (0);
2493101099Srwatson}
2494101099Srwatson
2495101099Srwatsonstatic int
2496119202Srwatsonmac_biba_check_vnode_deleteextattr(struct ucred *cred, struct vnode *vp,
2497119202Srwatson    struct label *label, int attrnamespace, const char *name)
2498119202Srwatson{
2499119202Srwatson	struct mac_biba *subj, *obj;
2500119202Srwatson
2501119202Srwatson	if (!mac_biba_enabled)
2502119202Srwatson		return (0);
2503119202Srwatson
2504122524Srwatson	subj = SLOT(cred->cr_label);
2505119202Srwatson	obj = SLOT(label);
2506119202Srwatson
2507132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2508119202Srwatson		return (EACCES);
2509119202Srwatson
2510119202Srwatson	return (0);
2511119202Srwatson}
2512119202Srwatson
2513119202Srwatsonstatic int
2514101099Srwatsonmac_biba_check_vnode_exec(struct ucred *cred, struct vnode *vp,
2515106648Srwatson    struct label *label, struct image_params *imgp,
2516106648Srwatson    struct label *execlabel)
2517101099Srwatson{
2518106648Srwatson	struct mac_biba *subj, *obj, *exec;
2519106648Srwatson	int error;
2520101099Srwatson
2521106648Srwatson	if (execlabel != NULL) {
2522106648Srwatson		/*
2523106648Srwatson		 * We currently don't permit labels to be changed at
2524106648Srwatson		 * exec-time as part of Biba, so disallow non-NULL
2525106648Srwatson		 * Biba label elements in the execlabel.
2526106648Srwatson		 */
2527106648Srwatson		exec = SLOT(execlabel);
2528106648Srwatson		error = biba_atmostflags(exec, 0);
2529106648Srwatson		if (error)
2530106648Srwatson			return (error);
2531106648Srwatson	}
2532106648Srwatson
2533101099Srwatson	if (!mac_biba_enabled)
2534101099Srwatson		return (0);
2535101099Srwatson
2536122524Srwatson	subj = SLOT(cred->cr_label);
2537101099Srwatson	obj = SLOT(label);
2538101099Srwatson
2539132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2540101099Srwatson		return (EACCES);
2541101099Srwatson
2542101099Srwatson	return (0);
2543101099Srwatson}
2544101099Srwatson
2545101099Srwatsonstatic int
2546101099Srwatsonmac_biba_check_vnode_getacl(struct ucred *cred, struct vnode *vp,
2547101099Srwatson    struct label *label, acl_type_t type)
2548101099Srwatson{
2549101099Srwatson	struct mac_biba *subj, *obj;
2550101099Srwatson
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_getextattr(struct ucred *cred, struct vnode *vp,
2565101099Srwatson    struct label *label, int attrnamespace, const char *name, struct uio *uio)
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
2582104530Srwatsonmac_biba_check_vnode_link(struct ucred *cred, struct vnode *dvp,
2583104530Srwatson    struct label *dlabel, struct vnode *vp, struct label *label,
2584104530Srwatson    struct componentname *cnp)
2585104530Srwatson{
2586104530Srwatson	struct mac_biba *subj, *obj;
2587104530Srwatson
2588104530Srwatson	if (!mac_biba_enabled)
2589104530Srwatson		return (0);
2590104530Srwatson
2591122524Srwatson	subj = SLOT(cred->cr_label);
2592104530Srwatson	obj = SLOT(dlabel);
2593104530Srwatson
2594132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2595104530Srwatson		return (EACCES);
2596104530Srwatson
2597104530Srwatson	obj = SLOT(label);
2598104530Srwatson
2599132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2600104530Srwatson		return (EACCES);
2601104530Srwatson
2602104530Srwatson	return (0);
2603104530Srwatson}
2604104530Srwatson
2605104530Srwatsonstatic int
2606119202Srwatsonmac_biba_check_vnode_listextattr(struct ucred *cred, struct vnode *vp,
2607119202Srwatson    struct label *label, int attrnamespace)
2608119202Srwatson{
2609119202Srwatson	struct mac_biba *subj, *obj;
2610119202Srwatson
2611119202Srwatson	if (!mac_biba_enabled)
2612119202Srwatson		return (0);
2613119202Srwatson
2614122524Srwatson	subj = SLOT(cred->cr_label);
2615119202Srwatson	obj = SLOT(label);
2616119202Srwatson
2617132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2618119202Srwatson		return (EACCES);
2619119202Srwatson
2620119202Srwatson	return (0);
2621119202Srwatson}
2622119202Srwatson
2623119202Srwatsonstatic int
2624103759Srwatsonmac_biba_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
2625101099Srwatson    struct label *dlabel, struct componentname *cnp)
2626101099Srwatson{
2627101099Srwatson	struct mac_biba *subj, *obj;
2628103759Srwatson
2629101099Srwatson	if (!mac_biba_enabled)
2630101099Srwatson		return (0);
2631103759Srwatson
2632122524Srwatson	subj = SLOT(cred->cr_label);
2633101099Srwatson	obj = SLOT(dlabel);
2634103759Srwatson
2635132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2636101099Srwatson		return (EACCES);
2637101099Srwatson
2638103759Srwatson	return (0);
2639101099Srwatson}
2640101099Srwatson
2641101099Srwatsonstatic int
2642104546Srwatsonmac_biba_check_vnode_mmap(struct ucred *cred, struct vnode *vp,
2643145076Scsjp    struct label *label, int prot, int flags)
2644104546Srwatson{
2645104546Srwatson	struct mac_biba *subj, *obj;
2646104546Srwatson
2647104546Srwatson	/*
2648104546Srwatson	 * Rely on the use of open()-time protections to handle
2649104546Srwatson	 * non-revocation cases.
2650104546Srwatson	 */
2651105637Srwatson	if (!mac_biba_enabled || !revocation_enabled)
2652104546Srwatson		return (0);
2653104546Srwatson
2654122524Srwatson	subj = SLOT(cred->cr_label);
2655104546Srwatson	obj = SLOT(label);
2656104546Srwatson
2657104546Srwatson	if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
2658132232Srwatson		if (!mac_biba_dominate_effective(obj, subj))
2659104546Srwatson			return (EACCES);
2660104546Srwatson	}
2661145076Scsjp	if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) {
2662132232Srwatson		if (!mac_biba_dominate_effective(subj, obj))
2663104546Srwatson			return (EACCES);
2664104546Srwatson	}
2665104546Srwatson
2666104569Srwatson	return (0);
2667104546Srwatson}
2668104546Srwatson
2669104546Srwatsonstatic int
2670101099Srwatsonmac_biba_check_vnode_open(struct ucred *cred, struct vnode *vp,
2671106212Srwatson    struct label *vnodelabel, int acc_mode)
2672101099Srwatson{
2673101099Srwatson	struct mac_biba *subj, *obj;
2674101099Srwatson
2675101099Srwatson	if (!mac_biba_enabled)
2676101099Srwatson		return (0);
2677101099Srwatson
2678122524Srwatson	subj = SLOT(cred->cr_label);
2679101099Srwatson	obj = SLOT(vnodelabel);
2680101099Srwatson
2681101099Srwatson	/* XXX privilege override for admin? */
2682101099Srwatson	if (acc_mode & (VREAD | VEXEC | VSTAT)) {
2683132232Srwatson		if (!mac_biba_dominate_effective(obj, subj))
2684101099Srwatson			return (EACCES);
2685101099Srwatson	}
2686101099Srwatson	if (acc_mode & (VWRITE | VAPPEND | VADMIN)) {
2687132232Srwatson		if (!mac_biba_dominate_effective(subj, obj))
2688101099Srwatson			return (EACCES);
2689101099Srwatson	}
2690101099Srwatson
2691101099Srwatson	return (0);
2692101099Srwatson}
2693101099Srwatson
2694101099Srwatsonstatic int
2695102129Srwatsonmac_biba_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred,
2696102129Srwatson    struct vnode *vp, struct label *label)
2697102112Srwatson{
2698102112Srwatson	struct mac_biba *subj, *obj;
2699102112Srwatson
2700105637Srwatson	if (!mac_biba_enabled || !revocation_enabled)
2701102112Srwatson		return (0);
2702102112Srwatson
2703122524Srwatson	subj = SLOT(active_cred->cr_label);
2704102112Srwatson	obj = SLOT(label);
2705102112Srwatson
2706132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2707102112Srwatson		return (EACCES);
2708102112Srwatson
2709102112Srwatson	return (0);
2710102112Srwatson}
2711102112Srwatson
2712102112Srwatsonstatic int
2713102129Srwatsonmac_biba_check_vnode_read(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
2731101099Srwatsonmac_biba_check_vnode_readdir(struct ucred *cred, struct vnode *dvp,
2732101099Srwatson    struct label *dlabel)
2733101099Srwatson{
2734101099Srwatson	struct mac_biba *subj, *obj;
2735101099Srwatson
2736101099Srwatson	if (!mac_biba_enabled)
2737101099Srwatson		return (0);
2738101099Srwatson
2739122524Srwatson	subj = SLOT(cred->cr_label);
2740101099Srwatson	obj = SLOT(dlabel);
2741101099Srwatson
2742132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2743101099Srwatson		return (EACCES);
2744101099Srwatson
2745101099Srwatson	return (0);
2746101099Srwatson}
2747101099Srwatson
2748101099Srwatsonstatic int
2749101099Srwatsonmac_biba_check_vnode_readlink(struct ucred *cred, struct vnode *vp,
2750101099Srwatson    struct label *label)
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(label);
2759101099Srwatson
2760132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
2761101099Srwatson		return (EACCES);
2762101099Srwatson
2763101099Srwatson	return (0);
2764101099Srwatson}
2765101099Srwatson
2766101099Srwatsonstatic int
2767101099Srwatsonmac_biba_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
2768101099Srwatson    struct label *vnodelabel, struct label *newlabel)
2769101099Srwatson{
2770101099Srwatson	struct mac_biba *old, *new, *subj;
2771105634Srwatson	int error;
2772101099Srwatson
2773101099Srwatson	old = SLOT(vnodelabel);
2774101099Srwatson	new = SLOT(newlabel);
2775122524Srwatson	subj = SLOT(cred->cr_label);
2776101099Srwatson
2777101099Srwatson	/*
2778105634Srwatson	 * If there is a Biba label update for the vnode, it must be a
2779132232Srwatson	 * effective label.
2780101099Srwatson	 */
2781132232Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE);
2782105634Srwatson	if (error)
2783105634Srwatson		return (error);
2784101099Srwatson
2785101099Srwatson	/*
2786105634Srwatson	 * To perform a relabel of the vnode (Biba label or not), Biba must
2787105634Srwatson	 * authorize the relabel.
2788101099Srwatson	 */
2789132232Srwatson	if (!mac_biba_effective_in_range(old, subj))
2790101099Srwatson		return (EPERM);
2791101099Srwatson
2792101099Srwatson	/*
2793105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
2794101099Srwatson	 */
2795132232Srwatson	if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
2796105634Srwatson		/*
2797105634Srwatson		 * To change the Biba label on a vnode, the new vnode label
2798105634Srwatson		 * must be in the subject range.
2799105634Srwatson		 */
2800132232Srwatson		if (!mac_biba_effective_in_range(new, subj))
2801105634Srwatson			return (EPERM);
2802101099Srwatson
2803105634Srwatson		/*
2804105634Srwatson		 * To change the Biba label on the vnode to be EQUAL,
2805105634Srwatson		 * the subject must have appropriate privilege.
2806105634Srwatson		 */
2807105634Srwatson		if (mac_biba_contains_equal(new)) {
2808106090Srwatson			error = mac_biba_subject_privileged(subj);
2809105634Srwatson			if (error)
2810105634Srwatson				return (error);
2811105634Srwatson		}
2812105634Srwatson	}
2813105634Srwatson
2814105634Srwatson	return (0);
2815101099Srwatson}
2816101099Srwatson
2817101099Srwatsonstatic int
2818101099Srwatsonmac_biba_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
2819101099Srwatson    struct label *dlabel, struct vnode *vp, struct label *label,
2820101099Srwatson    struct componentname *cnp)
2821101099Srwatson{
2822101099Srwatson	struct mac_biba *subj, *obj;
2823101099Srwatson
2824101099Srwatson	if (!mac_biba_enabled)
2825101099Srwatson		return (0);
2826101099Srwatson
2827122524Srwatson	subj = SLOT(cred->cr_label);
2828101099Srwatson	obj = SLOT(dlabel);
2829101099Srwatson
2830132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2831101099Srwatson		return (EACCES);
2832101099Srwatson
2833101099Srwatson	obj = SLOT(label);
2834101099Srwatson
2835132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2836101099Srwatson		return (EACCES);
2837101099Srwatson
2838101099Srwatson	return (0);
2839101099Srwatson}
2840101099Srwatson
2841101099Srwatsonstatic int
2842101099Srwatsonmac_biba_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
2843101099Srwatson    struct label *dlabel, struct vnode *vp, struct label *label, int samedir,
2844101099Srwatson    struct componentname *cnp)
2845101099Srwatson{
2846101099Srwatson	struct mac_biba *subj, *obj;
2847101099Srwatson
2848101099Srwatson	if (!mac_biba_enabled)
2849101099Srwatson		return (0);
2850101099Srwatson
2851122524Srwatson	subj = SLOT(cred->cr_label);
2852101099Srwatson	obj = SLOT(dlabel);
2853101099Srwatson
2854132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2855101099Srwatson		return (EACCES);
2856101099Srwatson
2857101099Srwatson	if (vp != NULL) {
2858101099Srwatson		obj = SLOT(label);
2859101099Srwatson
2860132232Srwatson		if (!mac_biba_dominate_effective(subj, obj))
2861101099Srwatson			return (EACCES);
2862101099Srwatson	}
2863101099Srwatson
2864101099Srwatson	return (0);
2865101099Srwatson}
2866101099Srwatson
2867101099Srwatsonstatic int
2868101099Srwatsonmac_biba_check_vnode_revoke(struct ucred *cred, struct vnode *vp,
2869101099Srwatson    struct label *label)
2870101099Srwatson{
2871101099Srwatson	struct mac_biba *subj, *obj;
2872101099Srwatson
2873101099Srwatson	if (!mac_biba_enabled)
2874101099Srwatson		return (0);
2875101099Srwatson
2876122524Srwatson	subj = SLOT(cred->cr_label);
2877101099Srwatson	obj = SLOT(label);
2878101099Srwatson
2879132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2880101099Srwatson		return (EACCES);
2881101099Srwatson
2882101099Srwatson	return (0);
2883101099Srwatson}
2884101099Srwatson
2885101099Srwatsonstatic int
2886101099Srwatsonmac_biba_check_vnode_setacl(struct ucred *cred, struct vnode *vp,
2887101099Srwatson    struct label *label, acl_type_t type, struct acl *acl)
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_setextattr(struct ucred *cred, struct vnode *vp,
2905101099Srwatson    struct label *vnodelabel, int attrnamespace, const char *name,
2906101099Srwatson    struct uio *uio)
2907101099Srwatson{
2908101099Srwatson	struct mac_biba *subj, *obj;
2909101099Srwatson
2910101099Srwatson	if (!mac_biba_enabled)
2911101099Srwatson		return (0);
2912101099Srwatson
2913122524Srwatson	subj = SLOT(cred->cr_label);
2914101099Srwatson	obj = SLOT(vnodelabel);
2915101099Srwatson
2916132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2917101099Srwatson		return (EACCES);
2918101099Srwatson
2919101099Srwatson	/* XXX: protect the MAC EA in a special way? */
2920101099Srwatson
2921101099Srwatson	return (0);
2922101099Srwatson}
2923101099Srwatson
2924101099Srwatsonstatic int
2925101099Srwatsonmac_biba_check_vnode_setflags(struct ucred *cred, struct vnode *vp,
2926101099Srwatson    struct label *vnodelabel, u_long flags)
2927101099Srwatson{
2928101099Srwatson	struct mac_biba *subj, *obj;
2929101099Srwatson
2930101099Srwatson	if (!mac_biba_enabled)
2931101099Srwatson		return (0);
2932101099Srwatson
2933122524Srwatson	subj = SLOT(cred->cr_label);
2934101099Srwatson	obj = SLOT(vnodelabel);
2935101099Srwatson
2936132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
2937101099Srwatson		return (EACCES);
2938101099Srwatson
2939101099Srwatson	return (0);
2940101099Srwatson}
2941101099Srwatson
2942101099Srwatsonstatic int
2943101099Srwatsonmac_biba_check_vnode_setmode(struct ucred *cred, struct vnode *vp,
2944101099Srwatson    struct label *vnodelabel, mode_t mode)
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_setowner(struct ucred *cred, struct vnode *vp,
2962101099Srwatson    struct label *vnodelabel, uid_t uid, gid_t gid)
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_setutimes(struct ucred *cred, struct vnode *vp,
2980101099Srwatson    struct label *vnodelabel, struct timespec atime, struct timespec mtime)
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
2997102129Srwatsonmac_biba_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
2998102129Srwatson    struct vnode *vp, struct label *vnodelabel)
2999101099Srwatson{
3000101099Srwatson	struct mac_biba *subj, *obj;
3001101099Srwatson
3002101099Srwatson	if (!mac_biba_enabled)
3003101099Srwatson		return (0);
3004101099Srwatson
3005122524Srwatson	subj = SLOT(active_cred->cr_label);
3006101099Srwatson	obj = SLOT(vnodelabel);
3007101099Srwatson
3008132232Srwatson	if (!mac_biba_dominate_effective(obj, subj))
3009101099Srwatson		return (EACCES);
3010101099Srwatson
3011101099Srwatson	return (0);
3012101099Srwatson}
3013101099Srwatson
3014102112Srwatsonstatic int
3015102129Srwatsonmac_biba_check_vnode_write(struct ucred *active_cred,
3016102129Srwatson    struct ucred *file_cred, struct vnode *vp, struct label *label)
3017102112Srwatson{
3018102112Srwatson	struct mac_biba *subj, *obj;
3019102112Srwatson
3020105637Srwatson	if (!mac_biba_enabled || !revocation_enabled)
3021102112Srwatson		return (0);
3022102112Srwatson
3023122524Srwatson	subj = SLOT(active_cred->cr_label);
3024102112Srwatson	obj = SLOT(label);
3025102112Srwatson
3026132232Srwatson	if (!mac_biba_dominate_effective(subj, obj))
3027102112Srwatson		return (EACCES);
3028102112Srwatson
3029102112Srwatson	return (0);
3030102112Srwatson}
3031102112Srwatson
3032161026Srwatsonstatic void
3033160243Scsjpmac_biba_associate_nfsd_label(struct ucred *cred)
3034160243Scsjp{
3035160243Scsjp	struct mac_biba *label;
3036160243Scsjp
3037160243Scsjp	label = SLOT(cred->cr_label);
3038160243Scsjp	mac_biba_set_effective(label, MAC_BIBA_TYPE_LOW, 0, NULL);
3039160243Scsjp	mac_biba_set_range(label, MAC_BIBA_TYPE_LOW, 0, NULL,
3040160243Scsjp	    MAC_BIBA_TYPE_HIGH, 0, NULL);
3041160243Scsjp}
3042160243Scsjp
3043165150Scsjpstatic void
3044165150Scsjpmac_biba_init_syncache_from_inpcb(struct label *label, struct inpcb *inp)
3045165150Scsjp{
3046165150Scsjp	struct mac_biba *source, *dest;
3047165150Scsjp
3048165150Scsjp	source = SLOT(inp->inp_label);
3049165150Scsjp	dest = SLOT(label);
3050165150Scsjp	mac_biba_copy_effective(source, dest);
3051165150Scsjp}
3052165150Scsjp
3053165150Scsjpstatic void
3054165150Scsjpmac_biba_create_mbuf_from_syncache(struct label *sc_label, struct mbuf *m,
3055165150Scsjp    struct label *mbuf_label)
3056165150Scsjp{
3057165150Scsjp	struct mac_biba *source, *dest;
3058165150Scsjp
3059165150Scsjp	source = SLOT(sc_label);
3060165150Scsjp	dest = SLOT(mbuf_label);
3061165150Scsjp	mac_biba_copy_effective(source, dest);
3062165150Scsjp}
3063165150Scsjp
3064106217Srwatsonstatic struct mac_policy_ops mac_biba_ops =
3065101099Srwatson{
3066106217Srwatson	.mpo_init = mac_biba_init,
3067106217Srwatson	.mpo_init_bpfdesc_label = mac_biba_init_label,
3068106217Srwatson	.mpo_init_cred_label = mac_biba_init_label,
3069106217Srwatson	.mpo_init_devfsdirent_label = mac_biba_init_label,
3070106217Srwatson	.mpo_init_ifnet_label = mac_biba_init_label,
3071122875Srwatson	.mpo_init_inpcb_label = mac_biba_init_label_waitcheck,
3072165150Scsjp	.mpo_init_syncache_label = mac_biba_init_label_waitcheck,
3073140628Srwatson	.mpo_init_sysv_msgmsg_label = mac_biba_init_label,
3074140628Srwatson	.mpo_init_sysv_msgqueue_label = mac_biba_init_label,
3075147091Srwatson	.mpo_init_sysv_sem_label = mac_biba_init_label,
3076140628Srwatson	.mpo_init_sysv_shm_label = mac_biba_init_label,
3077112675Srwatson	.mpo_init_ipq_label = mac_biba_init_label_waitcheck,
3078106217Srwatson	.mpo_init_mbuf_label = mac_biba_init_label_waitcheck,
3079106217Srwatson	.mpo_init_mount_label = mac_biba_init_label,
3080106217Srwatson	.mpo_init_mount_fs_label = mac_biba_init_label,
3081106217Srwatson	.mpo_init_pipe_label = mac_biba_init_label,
3082145855Srwatson	.mpo_init_posix_sem_label = mac_biba_init_label,
3083106217Srwatson	.mpo_init_socket_label = mac_biba_init_label_waitcheck,
3084106217Srwatson	.mpo_init_socket_peer_label = mac_biba_init_label_waitcheck,
3085165150Scsjp	.mpo_init_syncache_from_inpcb = mac_biba_init_syncache_from_inpcb,
3086106217Srwatson	.mpo_init_vnode_label = mac_biba_init_label,
3087106217Srwatson	.mpo_destroy_bpfdesc_label = mac_biba_destroy_label,
3088106217Srwatson	.mpo_destroy_cred_label = mac_biba_destroy_label,
3089106217Srwatson	.mpo_destroy_devfsdirent_label = mac_biba_destroy_label,
3090106217Srwatson	.mpo_destroy_ifnet_label = mac_biba_destroy_label,
3091122875Srwatson	.mpo_destroy_inpcb_label = mac_biba_destroy_label,
3092165150Scsjp	.mpo_destroy_syncache_label = mac_biba_destroy_label,
3093140628Srwatson	.mpo_destroy_sysv_msgmsg_label = mac_biba_destroy_label,
3094140628Srwatson	.mpo_destroy_sysv_msgqueue_label = mac_biba_destroy_label,
3095147091Srwatson	.mpo_destroy_sysv_sem_label = mac_biba_destroy_label,
3096140628Srwatson	.mpo_destroy_sysv_shm_label = mac_biba_destroy_label,
3097106217Srwatson	.mpo_destroy_ipq_label = mac_biba_destroy_label,
3098106217Srwatson	.mpo_destroy_mbuf_label = mac_biba_destroy_label,
3099106217Srwatson	.mpo_destroy_mount_label = mac_biba_destroy_label,
3100106217Srwatson	.mpo_destroy_mount_fs_label = mac_biba_destroy_label,
3101106217Srwatson	.mpo_destroy_pipe_label = mac_biba_destroy_label,
3102145855Srwatson	.mpo_destroy_posix_sem_label = mac_biba_destroy_label,
3103106217Srwatson	.mpo_destroy_socket_label = mac_biba_destroy_label,
3104106217Srwatson	.mpo_destroy_socket_peer_label = mac_biba_destroy_label,
3105106217Srwatson	.mpo_destroy_vnode_label = mac_biba_destroy_label,
3106123173Srwatson	.mpo_copy_cred_label = mac_biba_copy_label,
3107131025Srwatson	.mpo_copy_ifnet_label = mac_biba_copy_label,
3108115707Srwatson	.mpo_copy_mbuf_label = mac_biba_copy_label,
3109106217Srwatson	.mpo_copy_pipe_label = mac_biba_copy_label,
3110122820Srwatson	.mpo_copy_socket_label = mac_biba_copy_label,
3111106217Srwatson	.mpo_copy_vnode_label = mac_biba_copy_label,
3112106217Srwatson	.mpo_externalize_cred_label = mac_biba_externalize_label,
3113106217Srwatson	.mpo_externalize_ifnet_label = mac_biba_externalize_label,
3114106217Srwatson	.mpo_externalize_pipe_label = mac_biba_externalize_label,
3115106217Srwatson	.mpo_externalize_socket_label = mac_biba_externalize_label,
3116106217Srwatson	.mpo_externalize_socket_peer_label = mac_biba_externalize_label,
3117106217Srwatson	.mpo_externalize_vnode_label = mac_biba_externalize_label,
3118106217Srwatson	.mpo_internalize_cred_label = mac_biba_internalize_label,
3119106217Srwatson	.mpo_internalize_ifnet_label = mac_biba_internalize_label,
3120106217Srwatson	.mpo_internalize_pipe_label = mac_biba_internalize_label,
3121106217Srwatson	.mpo_internalize_socket_label = mac_biba_internalize_label,
3122106217Srwatson	.mpo_internalize_vnode_label = mac_biba_internalize_label,
3123106217Srwatson	.mpo_create_devfs_device = mac_biba_create_devfs_device,
3124106217Srwatson	.mpo_create_devfs_directory = mac_biba_create_devfs_directory,
3125106217Srwatson	.mpo_create_devfs_symlink = mac_biba_create_devfs_symlink,
3126106217Srwatson	.mpo_create_mount = mac_biba_create_mount,
3127106217Srwatson	.mpo_relabel_vnode = mac_biba_relabel_vnode,
3128106217Srwatson	.mpo_update_devfsdirent = mac_biba_update_devfsdirent,
3129106217Srwatson	.mpo_associate_vnode_devfs = mac_biba_associate_vnode_devfs,
3130106217Srwatson	.mpo_associate_vnode_extattr = mac_biba_associate_vnode_extattr,
3131106217Srwatson	.mpo_associate_vnode_singlelabel = mac_biba_associate_vnode_singlelabel,
3132106217Srwatson	.mpo_create_vnode_extattr = mac_biba_create_vnode_extattr,
3133106217Srwatson	.mpo_setlabel_vnode_extattr = mac_biba_setlabel_vnode_extattr,
3134106217Srwatson	.mpo_create_mbuf_from_socket = mac_biba_create_mbuf_from_socket,
3135165150Scsjp	.mpo_create_mbuf_from_syncache = mac_biba_create_mbuf_from_syncache,
3136106217Srwatson	.mpo_create_pipe = mac_biba_create_pipe,
3137145855Srwatson	.mpo_create_posix_sem = mac_biba_create_posix_sem,
3138106217Srwatson	.mpo_create_socket = mac_biba_create_socket,
3139106217Srwatson	.mpo_create_socket_from_socket = mac_biba_create_socket_from_socket,
3140106217Srwatson	.mpo_relabel_pipe = mac_biba_relabel_pipe,
3141106217Srwatson	.mpo_relabel_socket = mac_biba_relabel_socket,
3142106217Srwatson	.mpo_set_socket_peer_from_mbuf = mac_biba_set_socket_peer_from_mbuf,
3143106217Srwatson	.mpo_set_socket_peer_from_socket = mac_biba_set_socket_peer_from_socket,
3144106217Srwatson	.mpo_create_bpfdesc = mac_biba_create_bpfdesc,
3145106217Srwatson	.mpo_create_datagram_from_ipq = mac_biba_create_datagram_from_ipq,
3146106217Srwatson	.mpo_create_fragment = mac_biba_create_fragment,
3147106217Srwatson	.mpo_create_ifnet = mac_biba_create_ifnet,
3148122875Srwatson	.mpo_create_inpcb_from_socket = mac_biba_create_inpcb_from_socket,
3149140628Srwatson	.mpo_create_sysv_msgmsg = mac_biba_create_sysv_msgmsg,
3150140628Srwatson	.mpo_create_sysv_msgqueue = mac_biba_create_sysv_msgqueue,
3151147091Srwatson	.mpo_create_sysv_sem = mac_biba_create_sysv_sem,
3152140628Srwatson	.mpo_create_sysv_shm = mac_biba_create_sysv_shm,
3153106217Srwatson	.mpo_create_ipq = mac_biba_create_ipq,
3154123607Srwatson	.mpo_create_mbuf_from_inpcb = mac_biba_create_mbuf_from_inpcb,
3155106217Srwatson	.mpo_create_mbuf_linklayer = mac_biba_create_mbuf_linklayer,
3156106217Srwatson	.mpo_create_mbuf_from_bpfdesc = mac_biba_create_mbuf_from_bpfdesc,
3157106217Srwatson	.mpo_create_mbuf_from_ifnet = mac_biba_create_mbuf_from_ifnet,
3158106217Srwatson	.mpo_create_mbuf_multicast_encap = mac_biba_create_mbuf_multicast_encap,
3159106217Srwatson	.mpo_create_mbuf_netlayer = mac_biba_create_mbuf_netlayer,
3160106217Srwatson	.mpo_fragment_match = mac_biba_fragment_match,
3161106217Srwatson	.mpo_relabel_ifnet = mac_biba_relabel_ifnet,
3162106217Srwatson	.mpo_update_ipq = mac_biba_update_ipq,
3163122875Srwatson	.mpo_inpcb_sosetlabel = mac_biba_inpcb_sosetlabel,
3164106217Srwatson	.mpo_create_proc0 = mac_biba_create_proc0,
3165106217Srwatson	.mpo_create_proc1 = mac_biba_create_proc1,
3166106217Srwatson	.mpo_relabel_cred = mac_biba_relabel_cred,
3167140628Srwatson	.mpo_cleanup_sysv_msgmsg = mac_biba_cleanup_sysv_msgmsg,
3168140628Srwatson	.mpo_cleanup_sysv_msgqueue = mac_biba_cleanup_sysv_msgqueue,
3169147091Srwatson	.mpo_cleanup_sysv_sem = mac_biba_cleanup_sysv_sem,
3170140628Srwatson	.mpo_cleanup_sysv_shm = mac_biba_cleanup_sysv_shm,
3171106217Srwatson	.mpo_check_bpfdesc_receive = mac_biba_check_bpfdesc_receive,
3172106217Srwatson	.mpo_check_cred_relabel = mac_biba_check_cred_relabel,
3173106217Srwatson	.mpo_check_cred_visible = mac_biba_check_cred_visible,
3174106217Srwatson	.mpo_check_ifnet_relabel = mac_biba_check_ifnet_relabel,
3175106217Srwatson	.mpo_check_ifnet_transmit = mac_biba_check_ifnet_transmit,
3176122875Srwatson	.mpo_check_inpcb_deliver = mac_biba_check_inpcb_deliver,
3177140628Srwatson	.mpo_check_sysv_msgrcv = mac_biba_check_sysv_msgrcv,
3178140628Srwatson	.mpo_check_sysv_msgrmid = mac_biba_check_sysv_msgrmid,
3179140628Srwatson	.mpo_check_sysv_msqget = mac_biba_check_sysv_msqget,
3180140628Srwatson	.mpo_check_sysv_msqsnd = mac_biba_check_sysv_msqsnd,
3181140628Srwatson	.mpo_check_sysv_msqrcv = mac_biba_check_sysv_msqrcv,
3182140628Srwatson	.mpo_check_sysv_msqctl = mac_biba_check_sysv_msqctl,
3183140628Srwatson	.mpo_check_sysv_semctl = mac_biba_check_sysv_semctl,
3184140628Srwatson	.mpo_check_sysv_semget = mac_biba_check_sysv_semget,
3185140628Srwatson	.mpo_check_sysv_semop = mac_biba_check_sysv_semop,
3186140628Srwatson	.mpo_check_sysv_shmat = mac_biba_check_sysv_shmat,
3187140628Srwatson	.mpo_check_sysv_shmctl = mac_biba_check_sysv_shmctl,
3188140628Srwatson	.mpo_check_sysv_shmget = mac_biba_check_sysv_shmget,
3189110354Srwatson	.mpo_check_kld_load = mac_biba_check_kld_load,
3190110354Srwatson	.mpo_check_kld_unload = mac_biba_check_kld_unload,
3191106217Srwatson	.mpo_check_mount_stat = mac_biba_check_mount_stat,
3192106217Srwatson	.mpo_check_pipe_ioctl = mac_biba_check_pipe_ioctl,
3193106217Srwatson	.mpo_check_pipe_poll = mac_biba_check_pipe_poll,
3194106217Srwatson	.mpo_check_pipe_read = mac_biba_check_pipe_read,
3195106217Srwatson	.mpo_check_pipe_relabel = mac_biba_check_pipe_relabel,
3196106217Srwatson	.mpo_check_pipe_stat = mac_biba_check_pipe_stat,
3197106217Srwatson	.mpo_check_pipe_write = mac_biba_check_pipe_write,
3198145855Srwatson	.mpo_check_posix_sem_destroy = mac_biba_check_posix_sem_write,
3199145855Srwatson	.mpo_check_posix_sem_getvalue = mac_biba_check_posix_sem_rdonly,
3200145855Srwatson	.mpo_check_posix_sem_open = mac_biba_check_posix_sem_write,
3201145855Srwatson	.mpo_check_posix_sem_post = mac_biba_check_posix_sem_write,
3202145855Srwatson	.mpo_check_posix_sem_unlink = mac_biba_check_posix_sem_write,
3203145855Srwatson	.mpo_check_posix_sem_wait = mac_biba_check_posix_sem_write,
3204106217Srwatson	.mpo_check_proc_debug = mac_biba_check_proc_debug,
3205106217Srwatson	.mpo_check_proc_sched = mac_biba_check_proc_sched,
3206106217Srwatson	.mpo_check_proc_signal = mac_biba_check_proc_signal,
3207106217Srwatson	.mpo_check_socket_deliver = mac_biba_check_socket_deliver,
3208106217Srwatson	.mpo_check_socket_relabel = mac_biba_check_socket_relabel,
3209106217Srwatson	.mpo_check_socket_visible = mac_biba_check_socket_visible,
3210112574Srwatson	.mpo_check_sysarch_ioperm = mac_biba_check_sysarch_ioperm,
3211106418Srwatson	.mpo_check_system_acct = mac_biba_check_system_acct,
3212106418Srwatson	.mpo_check_system_settime = mac_biba_check_system_settime,
3213106217Srwatson	.mpo_check_system_swapon = mac_biba_check_system_swapon,
3214112574Srwatson	.mpo_check_system_swapoff = mac_biba_check_system_swapoff,
3215106217Srwatson	.mpo_check_system_sysctl = mac_biba_check_system_sysctl,
3216106217Srwatson	.mpo_check_vnode_access = mac_biba_check_vnode_open,
3217106217Srwatson	.mpo_check_vnode_chdir = mac_biba_check_vnode_chdir,
3218106217Srwatson	.mpo_check_vnode_chroot = mac_biba_check_vnode_chroot,
3219106217Srwatson	.mpo_check_vnode_create = mac_biba_check_vnode_create,
3220106217Srwatson	.mpo_check_vnode_delete = mac_biba_check_vnode_delete,
3221106217Srwatson	.mpo_check_vnode_deleteacl = mac_biba_check_vnode_deleteacl,
3222119202Srwatson	.mpo_check_vnode_deleteextattr = mac_biba_check_vnode_deleteextattr,
3223106217Srwatson	.mpo_check_vnode_exec = mac_biba_check_vnode_exec,
3224106217Srwatson	.mpo_check_vnode_getacl = mac_biba_check_vnode_getacl,
3225106217Srwatson	.mpo_check_vnode_getextattr = mac_biba_check_vnode_getextattr,
3226106217Srwatson	.mpo_check_vnode_link = mac_biba_check_vnode_link,
3227119202Srwatson	.mpo_check_vnode_listextattr = mac_biba_check_vnode_listextattr,
3228106217Srwatson	.mpo_check_vnode_lookup = mac_biba_check_vnode_lookup,
3229106217Srwatson	.mpo_check_vnode_mmap = mac_biba_check_vnode_mmap,
3230106217Srwatson	.mpo_check_vnode_open = mac_biba_check_vnode_open,
3231106217Srwatson	.mpo_check_vnode_poll = mac_biba_check_vnode_poll,
3232106217Srwatson	.mpo_check_vnode_read = mac_biba_check_vnode_read,
3233106217Srwatson	.mpo_check_vnode_readdir = mac_biba_check_vnode_readdir,
3234106217Srwatson	.mpo_check_vnode_readlink = mac_biba_check_vnode_readlink,
3235106217Srwatson	.mpo_check_vnode_relabel = mac_biba_check_vnode_relabel,
3236106217Srwatson	.mpo_check_vnode_rename_from = mac_biba_check_vnode_rename_from,
3237106217Srwatson	.mpo_check_vnode_rename_to = mac_biba_check_vnode_rename_to,
3238106217Srwatson	.mpo_check_vnode_revoke = mac_biba_check_vnode_revoke,
3239106217Srwatson	.mpo_check_vnode_setacl = mac_biba_check_vnode_setacl,
3240106217Srwatson	.mpo_check_vnode_setextattr = mac_biba_check_vnode_setextattr,
3241106217Srwatson	.mpo_check_vnode_setflags = mac_biba_check_vnode_setflags,
3242106217Srwatson	.mpo_check_vnode_setmode = mac_biba_check_vnode_setmode,
3243106217Srwatson	.mpo_check_vnode_setowner = mac_biba_check_vnode_setowner,
3244106217Srwatson	.mpo_check_vnode_setutimes = mac_biba_check_vnode_setutimes,
3245106217Srwatson	.mpo_check_vnode_stat = mac_biba_check_vnode_stat,
3246106217Srwatson	.mpo_check_vnode_write = mac_biba_check_vnode_write,
3247160243Scsjp	.mpo_associate_nfsd_label = mac_biba_associate_nfsd_label,
3248162238Scsjp	.mpo_create_mbuf_from_firewall = mac_biba_create_mbuf_from_firewall,
3249101099Srwatson};
3250101099Srwatson
3251112717SrwatsonMAC_POLICY_SET(&mac_biba_ops, mac_biba, "TrustedBSD MAC/Biba",
3252113531Srwatson    MPC_LOADTIME_FLAG_NOTLATE | MPC_LOADTIME_FLAG_LABELMBUFS, &mac_biba_slot);
3253