mac_biba.c revision 172955
1101099Srwatson/*-
2166533Srwatson * Copyright (c) 1999-2002, 2007 Robert N. M. Watson
3140628Srwatson * Copyright (c) 2001-2005 McAfee, Inc.
4172930Srwatson * Copyright (c) 2006 SPARTA, Inc.
5101099Srwatson * All rights reserved.
6101099Srwatson *
7101099Srwatson * This software was developed by Robert Watson for the TrustedBSD Project.
8101099Srwatson *
9140628Srwatson * This software was developed for the FreeBSD Project in part by McAfee
10140628Srwatson * Research, the Security Research Division of McAfee, Inc. under
11140628Srwatson * DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA
12140628Srwatson * CHATS research program.
13101099Srwatson *
14172930Srwatson * This software was enhanced by SPARTA ISSO under SPAWAR contract
15172930Srwatson * N66001-04-C-6019 ("SEFOS").
16172930Srwatson *
17101099Srwatson * Redistribution and use in source and binary forms, with or without
18101099Srwatson * modification, are permitted provided that the following conditions
19101099Srwatson * are met:
20101099Srwatson * 1. Redistributions of source code must retain the above copyright
21101099Srwatson *    notice, this list of conditions and the following disclaimer.
22101099Srwatson * 2. Redistributions in binary form must reproduce the above copyright
23101099Srwatson *    notice, this list of conditions and the following disclaimer in the
24101099Srwatson *    documentation and/or other materials provided with the distribution.
25101099Srwatson *
26101099Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
27101099Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28101099Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29101099Srwatson * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
30101099Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31101099Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32101099Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33101099Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34101099Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35101099Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36101099Srwatson * SUCH DAMAGE.
37101099Srwatson *
38101099Srwatson * $FreeBSD: head/sys/security/mac_biba/mac_biba.c 172955 2007-10-25 11:31:11Z rwatson $
39101099Srwatson */
40101099Srwatson
41101099Srwatson/*
42101099Srwatson * Developed by the TrustedBSD Project.
43168951Srwatson *
44101099Srwatson * Biba fixed label mandatory integrity policy.
45101099Srwatson */
46101099Srwatson
47101099Srwatson#include <sys/param.h>
48101099Srwatson#include <sys/conf.h>
49105988Srwatson#include <sys/extattr.h>
50101099Srwatson#include <sys/kernel.h>
51164184Strhodes#include <sys/ksem.h>
52103183Sbde#include <sys/malloc.h>
53145076Scsjp#include <sys/mman.h>
54101099Srwatson#include <sys/mount.h>
55168951Srwatson#include <sys/priv.h>
56101099Srwatson#include <sys/proc.h>
57115497Srwatson#include <sys/sbuf.h>
58101099Srwatson#include <sys/systm.h>
59101099Srwatson#include <sys/sysproto.h>
60101099Srwatson#include <sys/sysent.h>
61105696Srwatson#include <sys/systm.h>
62101099Srwatson#include <sys/vnode.h>
63101099Srwatson#include <sys/file.h>
64101099Srwatson#include <sys/socket.h>
65101099Srwatson#include <sys/socketvar.h>
66101099Srwatson#include <sys/pipe.h>
67150340Sphk#include <sys/sx.h>
68101099Srwatson#include <sys/sysctl.h>
69140628Srwatson#include <sys/msg.h>
70140628Srwatson#include <sys/sem.h>
71140628Srwatson#include <sys/shm.h>
72101099Srwatson
73101099Srwatson#include <fs/devfs/devfs.h>
74101099Srwatson
75101099Srwatson#include <net/bpfdesc.h>
76101099Srwatson#include <net/if.h>
77101099Srwatson#include <net/if_types.h>
78101099Srwatson#include <net/if_var.h>
79101099Srwatson
80101099Srwatson#include <netinet/in.h>
81122875Srwatson#include <netinet/in_pcb.h>
82101099Srwatson#include <netinet/ip_var.h>
83101099Srwatson
84122879Srwatson#include <vm/uma.h>
85101099Srwatson#include <vm/vm.h>
86101099Srwatson
87165469Srwatson#include <security/mac/mac_policy.h>
88101099Srwatson#include <security/mac_biba/mac_biba.h>
89101099Srwatson
90101099SrwatsonSYSCTL_DECL(_security_mac);
91101099Srwatson
92101099SrwatsonSYSCTL_NODE(_security_mac, OID_AUTO, biba, CTLFLAG_RW, 0,
93101099Srwatson    "TrustedBSD mac_biba policy controls");
94101099Srwatson
95172955Srwatsonstatic int	biba_label_size = sizeof(struct mac_biba);
96105988SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, label_size, CTLFLAG_RD,
97172955Srwatson    &biba_label_size, 0, "Size of struct mac_biba");
98105988Srwatson
99172955Srwatsonstatic int	biba_enabled = 1;
100172955SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, enabled, CTLFLAG_RW, &biba_enabled,
101172955Srwatson    0, "Enforce MAC/Biba policy");
102172955SrwatsonTUNABLE_INT("security.mac.biba.enabled", &biba_enabled);
103101099Srwatson
104101099Srwatsonstatic int	destroyed_not_inited;
105101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, destroyed_not_inited, CTLFLAG_RD,
106101099Srwatson    &destroyed_not_inited, 0, "Count of labels destroyed but not inited");
107101099Srwatson
108101099Srwatsonstatic int	trust_all_interfaces = 0;
109101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, trust_all_interfaces, CTLFLAG_RD,
110101099Srwatson    &trust_all_interfaces, 0, "Consider all interfaces 'trusted' by MAC/Biba");
111101099SrwatsonTUNABLE_INT("security.mac.biba.trust_all_interfaces", &trust_all_interfaces);
112101099Srwatson
113101099Srwatsonstatic char	trusted_interfaces[128];
114101099SrwatsonSYSCTL_STRING(_security_mac_biba, OID_AUTO, trusted_interfaces, CTLFLAG_RD,
115101099Srwatson    trusted_interfaces, 0, "Interfaces considered 'trusted' by MAC/Biba");
116101099SrwatsonTUNABLE_STR("security.mac.biba.trusted_interfaces", trusted_interfaces,
117101099Srwatson    sizeof(trusted_interfaces));
118101099Srwatson
119105643Srwatsonstatic int	max_compartments = MAC_BIBA_MAX_COMPARTMENTS;
120105643SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, max_compartments, CTLFLAG_RD,
121105643Srwatson    &max_compartments, 0, "Maximum supported compartments");
122105643Srwatson
123105606Srwatsonstatic int	ptys_equal = 0;
124105606SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, ptys_equal, CTLFLAG_RW,
125105606Srwatson    &ptys_equal, 0, "Label pty devices as biba/equal on create");
126105606SrwatsonTUNABLE_INT("security.mac.biba.ptys_equal", &ptys_equal);
127105606Srwatson
128153927Scsjpstatic int	interfaces_equal;
129153927ScsjpSYSCTL_INT(_security_mac_biba, OID_AUTO, interfaces_equal, CTLFLAG_RW,
130153927Scsjp    &interfaces_equal, 0, "Label network interfaces as biba/equal on create");
131153927ScsjpTUNABLE_INT("security.mac.biba.interfaces_equal", &interfaces_equal);
132153927Scsjp
133105637Srwatsonstatic int	revocation_enabled = 0;
134101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, revocation_enabled, CTLFLAG_RW,
135105637Srwatson    &revocation_enabled, 0, "Revoke access to objects on relabel");
136105637SrwatsonTUNABLE_INT("security.mac.biba.revocation_enabled", &revocation_enabled);
137101099Srwatson
138172955Srwatsonstatic int	biba_slot;
139172955Srwatson#define	SLOT(l)	((struct mac_biba *)mac_label_get((l), biba_slot))
140172955Srwatson#define	SLOT_SET(l, val) mac_label_set((l), biba_slot, (uintptr_t)(val))
141101099Srwatson
142122879Srwatsonstatic uma_zone_t	zone_biba;
143101099Srwatson
144105643Srwatsonstatic __inline int
145105643Srwatsonbiba_bit_set_empty(u_char *set) {
146105643Srwatson	int i;
147105643Srwatson
148105643Srwatson	for (i = 0; i < MAC_BIBA_MAX_COMPARTMENTS >> 3; i++)
149105643Srwatson		if (set[i] != 0)
150105643Srwatson			return (0);
151105643Srwatson	return (1);
152105643Srwatson}
153105643Srwatson
154101099Srwatsonstatic struct mac_biba *
155104514Srwatsonbiba_alloc(int flag)
156101099Srwatson{
157101099Srwatson
158122879Srwatson	return (uma_zalloc(zone_biba, flag | M_ZERO));
159101099Srwatson}
160101099Srwatson
161101099Srwatsonstatic void
162172955Srwatsonbiba_free(struct mac_biba *mb)
163101099Srwatson{
164101099Srwatson
165172955Srwatson	if (mb != NULL)
166172955Srwatson		uma_zfree(zone_biba, mb);
167101099Srwatson	else
168101099Srwatson		atomic_add_int(&destroyed_not_inited, 1);
169101099Srwatson}
170101099Srwatson
171101099Srwatsonstatic int
172172955Srwatsonbiba_atmostflags(struct mac_biba *mb, int flags)
173105634Srwatson{
174105634Srwatson
175172955Srwatson	if ((mb->mb_flags & flags) != mb->mb_flags)
176105634Srwatson		return (EINVAL);
177105634Srwatson	return (0);
178105634Srwatson}
179105634Srwatson
180105634Srwatsonstatic int
181172955Srwatsonbiba_dominate_element(struct mac_biba_element *a, struct mac_biba_element *b)
182101099Srwatson{
183105643Srwatson	int bit;
184101099Srwatson
185105736Srwatson	switch (a->mbe_type) {
186101099Srwatson	case MAC_BIBA_TYPE_EQUAL:
187101099Srwatson	case MAC_BIBA_TYPE_HIGH:
188101099Srwatson		return (1);
189101099Srwatson
190101099Srwatson	case MAC_BIBA_TYPE_LOW:
191101099Srwatson		switch (b->mbe_type) {
192101099Srwatson		case MAC_BIBA_TYPE_GRADE:
193101099Srwatson		case MAC_BIBA_TYPE_HIGH:
194101099Srwatson			return (0);
195101099Srwatson
196101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
197101099Srwatson		case MAC_BIBA_TYPE_LOW:
198101099Srwatson			return (1);
199101099Srwatson
200101099Srwatson		default:
201172955Srwatson			panic("biba_dominate_element: b->mbe_type invalid");
202101099Srwatson		}
203101099Srwatson
204101099Srwatson	case MAC_BIBA_TYPE_GRADE:
205101099Srwatson		switch (b->mbe_type) {
206101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
207101099Srwatson		case MAC_BIBA_TYPE_LOW:
208101099Srwatson			return (1);
209101099Srwatson
210101099Srwatson		case MAC_BIBA_TYPE_HIGH:
211101099Srwatson			return (0);
212101099Srwatson
213101099Srwatson		case MAC_BIBA_TYPE_GRADE:
214105643Srwatson			for (bit = 1; bit <= MAC_BIBA_MAX_COMPARTMENTS; bit++)
215105643Srwatson				if (!MAC_BIBA_BIT_TEST(bit,
216105643Srwatson				    a->mbe_compartments) &&
217105643Srwatson				    MAC_BIBA_BIT_TEST(bit, b->mbe_compartments))
218105643Srwatson					return (0);
219101099Srwatson			return (a->mbe_grade >= b->mbe_grade);
220101099Srwatson
221101099Srwatson		default:
222172955Srwatson			panic("biba_dominate_element: b->mbe_type invalid");
223101099Srwatson		}
224101099Srwatson
225101099Srwatson	default:
226172955Srwatson		panic("biba_dominate_element: a->mbe_type invalid");
227101099Srwatson	}
228101099Srwatson
229101099Srwatson	return (0);
230101099Srwatson}
231101099Srwatson
232101099Srwatsonstatic int
233172955Srwatsonbiba_subject_dominate_high(struct mac_biba *mb)
234105988Srwatson{
235105988Srwatson	struct mac_biba_element *element;
236105988Srwatson
237172955Srwatson	KASSERT((mb->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
238172955Srwatson	    ("biba_effective_in_range: mb not effective"));
239172955Srwatson	element = &mb->mb_effective;
240105988Srwatson
241105988Srwatson	return (element->mbe_type == MAC_BIBA_TYPE_EQUAL ||
242105988Srwatson	    element->mbe_type == MAC_BIBA_TYPE_HIGH);
243105988Srwatson}
244105988Srwatson
245105988Srwatsonstatic int
246172955Srwatsonbiba_range_in_range(struct mac_biba *rangea, struct mac_biba *rangeb)
247101099Srwatson{
248101099Srwatson
249172955Srwatson	return (biba_dominate_element(&rangeb->mb_rangehigh,
250101099Srwatson	    &rangea->mb_rangehigh) &&
251172955Srwatson	    biba_dominate_element(&rangea->mb_rangelow,
252101099Srwatson	    &rangeb->mb_rangelow));
253101099Srwatson}
254101099Srwatson
255101099Srwatsonstatic int
256172955Srwatsonbiba_effective_in_range(struct mac_biba *effective, struct mac_biba *range)
257101099Srwatson{
258101099Srwatson
259132232Srwatson	KASSERT((effective->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
260172955Srwatson	    ("biba_effective_in_range: a not effective"));
261103750Srwatson	KASSERT((range->mb_flags & MAC_BIBA_FLAG_RANGE) != 0,
262172955Srwatson	    ("biba_effective_in_range: b not range"));
263101099Srwatson
264172955Srwatson	return (biba_dominate_element(&range->mb_rangehigh,
265132232Srwatson	    &effective->mb_effective) &&
266172955Srwatson	    biba_dominate_element(&effective->mb_effective,
267101099Srwatson	    &range->mb_rangelow));
268101099Srwatson
269101099Srwatson	return (1);
270101099Srwatson}
271101099Srwatson
272101099Srwatsonstatic int
273172955Srwatsonbiba_dominate_effective(struct mac_biba *a, struct mac_biba *b)
274101099Srwatson{
275132232Srwatson	KASSERT((a->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
276172955Srwatson	    ("biba_dominate_effective: a not effective"));
277132232Srwatson	KASSERT((b->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
278172955Srwatson	    ("biba_dominate_effective: b not effective"));
279101099Srwatson
280172955Srwatson	return (biba_dominate_element(&a->mb_effective, &b->mb_effective));
281101099Srwatson}
282101099Srwatson
283101099Srwatsonstatic int
284172955Srwatsonbiba_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
295172955Srwatsonbiba_equal_effective(struct mac_biba *a, struct mac_biba *b)
296101099Srwatson{
297101099Srwatson
298132232Srwatson	KASSERT((a->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
299172955Srwatson	    ("biba_equal_effective: a not effective"));
300132232Srwatson	KASSERT((b->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
301172955Srwatson	    ("biba_equal_effective: b not effective"));
302101099Srwatson
303172955Srwatson	return (biba_equal_element(&a->mb_effective, &b->mb_effective));
304101099Srwatson}
305101099Srwatson
306101099Srwatsonstatic int
307172955Srwatsonbiba_contains_equal(struct mac_biba *mb)
308105634Srwatson{
309105634Srwatson
310172955Srwatson	if (mb->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
311172955Srwatson		if (mb->mb_effective.mbe_type == MAC_BIBA_TYPE_EQUAL)
312105634Srwatson			return (1);
313172955Srwatson	}
314105634Srwatson
315172955Srwatson	if (mb->mb_flags & MAC_BIBA_FLAG_RANGE) {
316172955Srwatson		if (mb->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL)
317105634Srwatson			return (1);
318172955Srwatson		if (mb->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL)
319105637Srwatson			return (1);
320105634Srwatson	}
321105634Srwatson
322105634Srwatson	return (0);
323105634Srwatson}
324105634Srwatson
325105634Srwatsonstatic int
326172955Srwatsonbiba_subject_privileged(struct mac_biba *mb)
327105634Srwatson{
328105634Srwatson
329172955Srwatson	KASSERT((mb->mb_flags & MAC_BIBA_FLAGS_BOTH) == MAC_BIBA_FLAGS_BOTH,
330172955Srwatson	    ("biba_subject_privileged: subject doesn't have both labels"));
331105634Srwatson
332132232Srwatson	/* If the effective is EQUAL, it's ok. */
333172955Srwatson	if (mb->mb_effective.mbe_type == MAC_BIBA_TYPE_EQUAL)
334105634Srwatson		return (0);
335105634Srwatson
336105634Srwatson	/* If either range endpoint is EQUAL, it's ok. */
337172955Srwatson	if (mb->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL ||
338172955Srwatson	    mb->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL)
339105634Srwatson		return (0);
340105634Srwatson
341105634Srwatson	/* If the range is low-high, it's ok. */
342172955Srwatson	if (mb->mb_rangelow.mbe_type == MAC_BIBA_TYPE_LOW &&
343172955Srwatson	    mb->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_HIGH)
344105634Srwatson		return (0);
345105634Srwatson
346105634Srwatson	/* It's not ok. */
347105634Srwatson	return (EPERM);
348105634Srwatson}
349105634Srwatson
350106091Srwatsonstatic int
351172955Srwatsonbiba_high_effective(struct mac_biba *mb)
352105988Srwatson{
353105988Srwatson
354172955Srwatson	KASSERT((mb->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
355172955Srwatson	    ("biba_equal_effective: mb not effective"));
356105988Srwatson
357172955Srwatson	return (mb->mb_effective.mbe_type == MAC_BIBA_TYPE_HIGH);
358105988Srwatson}
359105988Srwatson
360105634Srwatsonstatic int
361172955Srwatsonbiba_valid(struct mac_biba *mb)
362101099Srwatson{
363101099Srwatson
364172955Srwatson	if (mb->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
365172955Srwatson		switch (mb->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:
372172955Srwatson			if (mb->mb_effective.mbe_grade != 0 ||
373105643Srwatson			    !MAC_BIBA_BIT_SET_EMPTY(
374172955Srwatson			    mb->mb_effective.mbe_compartments))
375101099Srwatson				return (EINVAL);
376101099Srwatson			break;
377101099Srwatson
378101099Srwatson		default:
379101099Srwatson			return (EINVAL);
380101099Srwatson		}
381101099Srwatson	} else {
382172955Srwatson		if (mb->mb_effective.mbe_type != MAC_BIBA_TYPE_UNDEF)
383101099Srwatson			return (EINVAL);
384101099Srwatson	}
385101099Srwatson
386172955Srwatson	if (mb->mb_flags & MAC_BIBA_FLAG_RANGE) {
387172955Srwatson		switch (mb->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:
394172955Srwatson			if (mb->mb_rangelow.mbe_grade != 0 ||
395105643Srwatson			    !MAC_BIBA_BIT_SET_EMPTY(
396172955Srwatson			    mb->mb_rangelow.mbe_compartments))
397101099Srwatson				return (EINVAL);
398101099Srwatson			break;
399101099Srwatson
400101099Srwatson		default:
401101099Srwatson			return (EINVAL);
402101099Srwatson		}
403101099Srwatson
404172955Srwatson		switch (mb->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:
411172955Srwatson			if (mb->mb_rangehigh.mbe_grade != 0 ||
412105643Srwatson			    !MAC_BIBA_BIT_SET_EMPTY(
413172955Srwatson			    mb->mb_rangehigh.mbe_compartments))
414101099Srwatson				return (EINVAL);
415101099Srwatson			break;
416101099Srwatson
417101099Srwatson		default:
418101099Srwatson			return (EINVAL);
419101099Srwatson		}
420172955Srwatson		if (!biba_dominate_element(&mb->mb_rangehigh,
421172955Srwatson		    &mb->mb_rangelow))
422101099Srwatson			return (EINVAL);
423101099Srwatson	} else {
424172955Srwatson		if (mb->mb_rangelow.mbe_type != MAC_BIBA_TYPE_UNDEF ||
425172955Srwatson		    mb->mb_rangehigh.mbe_type != MAC_BIBA_TYPE_UNDEF)
426101099Srwatson			return (EINVAL);
427101099Srwatson	}
428101099Srwatson
429101099Srwatson	return (0);
430101099Srwatson}
431101099Srwatson
432101099Srwatsonstatic void
433172955Srwatsonbiba_set_range(struct mac_biba *mb, u_short typelow, u_short gradelow,
434172955Srwatson    u_char *compartmentslow, u_short typehigh, u_short gradehigh,
435172955Srwatson    u_char *compartmentshigh)
436101099Srwatson{
437101099Srwatson
438172955Srwatson	mb->mb_rangelow.mbe_type = typelow;
439172955Srwatson	mb->mb_rangelow.mbe_grade = gradelow;
440105643Srwatson	if (compartmentslow != NULL)
441172955Srwatson		memcpy(mb->mb_rangelow.mbe_compartments, compartmentslow,
442172955Srwatson		    sizeof(mb->mb_rangelow.mbe_compartments));
443172955Srwatson	mb->mb_rangehigh.mbe_type = typehigh;
444172955Srwatson	mb->mb_rangehigh.mbe_grade = gradehigh;
445105643Srwatson	if (compartmentshigh != NULL)
446172955Srwatson		memcpy(mb->mb_rangehigh.mbe_compartments, compartmentshigh,
447172955Srwatson		    sizeof(mb->mb_rangehigh.mbe_compartments));
448172955Srwatson	mb->mb_flags |= MAC_BIBA_FLAG_RANGE;
449101099Srwatson}
450101099Srwatson
451101099Srwatsonstatic void
452172955Srwatsonbiba_set_effective(struct mac_biba *mb, u_short type, u_short grade,
453105643Srwatson    u_char *compartments)
454101099Srwatson{
455101099Srwatson
456172955Srwatson	mb->mb_effective.mbe_type = type;
457172955Srwatson	mb->mb_effective.mbe_grade = grade;
458105643Srwatson	if (compartments != NULL)
459172955Srwatson		memcpy(mb->mb_effective.mbe_compartments, compartments,
460172955Srwatson		    sizeof(mb->mb_effective.mbe_compartments));
461172955Srwatson	mb->mb_flags |= MAC_BIBA_FLAG_EFFECTIVE;
462101099Srwatson}
463101099Srwatson
464101099Srwatsonstatic void
465172955Srwatsonbiba_copy_range(struct mac_biba *labelfrom, struct mac_biba *labelto)
466101099Srwatson{
467105643Srwatson
468101099Srwatson	KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_RANGE) != 0,
469172955Srwatson	    ("biba_copy_range: labelfrom not range"));
470101099Srwatson
471101099Srwatson	labelto->mb_rangelow = labelfrom->mb_rangelow;
472101099Srwatson	labelto->mb_rangehigh = labelfrom->mb_rangehigh;
473101099Srwatson	labelto->mb_flags |= MAC_BIBA_FLAG_RANGE;
474101099Srwatson}
475101099Srwatson
476101099Srwatsonstatic void
477172955Srwatsonbiba_copy_effective(struct mac_biba *labelfrom, struct mac_biba *labelto)
478101099Srwatson{
479101099Srwatson
480132232Srwatson	KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
481172955Srwatson	    ("biba_copy_effective: labelfrom not effective"));
482101099Srwatson
483132232Srwatson	labelto->mb_effective = labelfrom->mb_effective;
484132232Srwatson	labelto->mb_flags |= MAC_BIBA_FLAG_EFFECTIVE;
485101099Srwatson}
486101099Srwatson
487105656Srwatsonstatic void
488172955Srwatsonbiba_copy(struct mac_biba *source, struct mac_biba *dest)
489105656Srwatson{
490105656Srwatson
491132232Srwatson	if (source->mb_flags & MAC_BIBA_FLAG_EFFECTIVE)
492172955Srwatson		biba_copy_effective(source, dest);
493105656Srwatson	if (source->mb_flags & MAC_BIBA_FLAG_RANGE)
494172955Srwatson		biba_copy_range(source, dest);
495105656Srwatson}
496105656Srwatson
497101099Srwatson/*
498101099Srwatson * Policy module operations.
499101099Srwatson */
500101099Srwatsonstatic void
501172955Srwatsonbiba_init(struct mac_policy_conf *conf)
502101099Srwatson{
503101099Srwatson
504122879Srwatson	zone_biba = uma_zcreate("mac_biba", sizeof(struct mac_biba), NULL,
505122879Srwatson	    NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
506101099Srwatson}
507101099Srwatson
508101099Srwatson/*
509101099Srwatson * Label operations.
510101099Srwatson */
511101099Srwatsonstatic void
512172955Srwatsonbiba_init_label(struct label *label)
513101099Srwatson{
514101099Srwatson
515132781Skan	SLOT_SET(label, biba_alloc(M_WAITOK));
516101099Srwatson}
517101099Srwatson
518101099Srwatsonstatic int
519172955Srwatsonbiba_init_label_waitcheck(struct label *label, int flag)
520101099Srwatson{
521101099Srwatson
522132781Skan	SLOT_SET(label, biba_alloc(flag));
523101099Srwatson	if (SLOT(label) == NULL)
524101099Srwatson		return (ENOMEM);
525101099Srwatson
526101099Srwatson	return (0);
527101099Srwatson}
528101099Srwatson
529101099Srwatsonstatic void
530172955Srwatsonbiba_destroy_label(struct label *label)
531101099Srwatson{
532101099Srwatson
533101099Srwatson	biba_free(SLOT(label));
534132781Skan	SLOT_SET(label, NULL);
535101099Srwatson}
536101099Srwatson
537105696Srwatson/*
538172955Srwatson * biba_element_to_string() accepts an sbuf and Biba element.  It converts
539172955Srwatson * the Biba element to a string and stores the result in the sbuf; if there
540172955Srwatson * isn't space in the sbuf, -1 is returned.
541105696Srwatson */
542115497Srwatsonstatic int
543172955Srwatsonbiba_element_to_string(struct sbuf *sb, struct mac_biba_element *element)
544105696Srwatson{
545115497Srwatson	int i, first;
546105696Srwatson
547105696Srwatson	switch (element->mbe_type) {
548105696Srwatson	case MAC_BIBA_TYPE_HIGH:
549115497Srwatson		return (sbuf_printf(sb, "high"));
550105696Srwatson
551105696Srwatson	case MAC_BIBA_TYPE_LOW:
552115497Srwatson		return (sbuf_printf(sb, "low"));
553105696Srwatson
554105696Srwatson	case MAC_BIBA_TYPE_EQUAL:
555115497Srwatson		return (sbuf_printf(sb, "equal"));
556105696Srwatson
557105696Srwatson	case MAC_BIBA_TYPE_GRADE:
558115497Srwatson		if (sbuf_printf(sb, "%d", element->mbe_grade) == -1)
559115497Srwatson			return (-1);
560115497Srwatson
561115497Srwatson		first = 1;
562115497Srwatson		for (i = 1; i <= MAC_BIBA_MAX_COMPARTMENTS; i++) {
563115497Srwatson			if (MAC_BIBA_BIT_TEST(i, element->mbe_compartments)) {
564115497Srwatson				if (first) {
565115497Srwatson					if (sbuf_putc(sb, ':') == -1)
566115497Srwatson						return (-1);
567115497Srwatson					if (sbuf_printf(sb, "%d", i) == -1)
568115497Srwatson						return (-1);
569115497Srwatson					first = 0;
570115497Srwatson				} else {
571115497Srwatson					if (sbuf_printf(sb, "+%d", i) == -1)
572115497Srwatson						return (-1);
573115497Srwatson				}
574115497Srwatson			}
575105696Srwatson		}
576115497Srwatson		return (0);
577105696Srwatson
578105696Srwatson	default:
579172955Srwatson		panic("biba_element_to_string: invalid type (%d)",
580105696Srwatson		    element->mbe_type);
581105696Srwatson	}
582105696Srwatson}
583105696Srwatson
584115497Srwatson/*
585172955Srwatson * biba_to_string() converts a Biba label to a string, and places the results
586172955Srwatson * in the passed sbuf.  It returns 0 on success, or EINVAL if there isn't
587172955Srwatson * room in the sbuf.  Note: the sbuf will be modified even in a failure case,
588172955Srwatson * so the caller may need to revert the sbuf by restoring the offset if
589172955Srwatson * that's undesired.
590115497Srwatson */
591101099Srwatsonstatic int
592172955Srwatsonbiba_to_string(struct sbuf *sb, struct mac_biba *mb)
593101099Srwatson{
594105696Srwatson
595172955Srwatson	if (mb->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
596172955Srwatson		if (biba_element_to_string(sb, &mb->mb_effective) == -1)
597105696Srwatson			return (EINVAL);
598105696Srwatson	}
599105696Srwatson
600172955Srwatson	if (mb->mb_flags & MAC_BIBA_FLAG_RANGE) {
601116701Srwatson		if (sbuf_putc(sb, '(') == -1)
602105696Srwatson			return (EINVAL);
603105696Srwatson
604172955Srwatson		if (biba_element_to_string(sb, &mb->mb_rangelow) == -1)
605105696Srwatson			return (EINVAL);
606105696Srwatson
607116701Srwatson		if (sbuf_putc(sb, '-') == -1)
608105696Srwatson			return (EINVAL);
609105696Srwatson
610172955Srwatson		if (biba_element_to_string(sb, &mb->mb_rangehigh) == -1)
611105696Srwatson			return (EINVAL);
612105696Srwatson
613116701Srwatson		if (sbuf_putc(sb, ')') == -1)
614105696Srwatson			return (EINVAL);
615105696Srwatson	}
616105696Srwatson
617105696Srwatson	return (0);
618105696Srwatson}
619105696Srwatson
620105696Srwatsonstatic int
621172955Srwatsonbiba_externalize_label(struct label *label, char *element_name,
622116701Srwatson    struct sbuf *sb, int *claimed)
623105696Srwatson{
624172955Srwatson	struct mac_biba *mb;
625101099Srwatson
626105696Srwatson	if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0)
627105696Srwatson		return (0);
628105696Srwatson
629105696Srwatson	(*claimed)++;
630105696Srwatson
631172955Srwatson	mb = SLOT(label);
632172955Srwatson	return (biba_to_string(sb, mb));
633105696Srwatson}
634105696Srwatson
635105696Srwatsonstatic int
636172955Srwatsonbiba_parse_element(struct mac_biba_element *element, char *string)
637101099Srwatson{
638115395Srwatson	char *compartment, *end, *grade;
639115395Srwatson	int value;
640105696Srwatson
641105696Srwatson	if (strcmp(string, "high") == 0 ||
642105696Srwatson	    strcmp(string, "hi") == 0) {
643105696Srwatson		element->mbe_type = MAC_BIBA_TYPE_HIGH;
644105696Srwatson		element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
645105696Srwatson	} else if (strcmp(string, "low") == 0 ||
646105696Srwatson	    strcmp(string, "lo") == 0) {
647105696Srwatson		element->mbe_type = MAC_BIBA_TYPE_LOW;
648105696Srwatson		element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
649105696Srwatson	} else if (strcmp(string, "equal") == 0 ||
650105696Srwatson	    strcmp(string, "eq") == 0) {
651105696Srwatson		element->mbe_type = MAC_BIBA_TYPE_EQUAL;
652105696Srwatson		element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
653105696Srwatson	} else {
654115395Srwatson		element->mbe_type = MAC_BIBA_TYPE_GRADE;
655105696Srwatson
656115395Srwatson		/*
657115395Srwatson		 * Numeric grade piece of the element.
658115395Srwatson		 */
659115395Srwatson		grade = strsep(&string, ":");
660115395Srwatson		value = strtol(grade, &end, 10);
661115395Srwatson		if (end == grade || *end != '\0')
662105696Srwatson			return (EINVAL);
663115395Srwatson		if (value < 0 || value > 65535)
664115395Srwatson			return (EINVAL);
665115395Srwatson		element->mbe_grade = value;
666105696Srwatson
667115395Srwatson		/*
668115395Srwatson		 * Optional compartment piece of the element.  If none
669115395Srwatson		 * are included, we assume that the label has no
670115395Srwatson		 * compartments.
671115395Srwatson		 */
672115395Srwatson		if (string == NULL)
673115395Srwatson			return (0);
674115395Srwatson		if (*string == '\0')
675115395Srwatson			return (0);
676105696Srwatson
677115395Srwatson		while ((compartment = strsep(&string, "+")) != NULL) {
678115395Srwatson			value = strtol(compartment, &end, 10);
679115395Srwatson			if (compartment == end || *end != '\0')
680105696Srwatson				return (EINVAL);
681115395Srwatson			if (value < 1 || value > MAC_BIBA_MAX_COMPARTMENTS)
682105696Srwatson				return (EINVAL);
683115395Srwatson			MAC_BIBA_BIT_SET(value, element->mbe_compartments);
684105696Srwatson		}
685105696Srwatson	}
686105696Srwatson
687105696Srwatson	return (0);
688105696Srwatson}
689105696Srwatson
690105696Srwatson/*
691105696Srwatson * Note: destructively consumes the string, make a local copy before
692105696Srwatson * calling if that's a problem.
693105696Srwatson */
694105696Srwatsonstatic int
695172955Srwatsonbiba_parse(struct mac_biba *mb, char *string)
696105696Srwatson{
697132232Srwatson	char *rangehigh, *rangelow, *effective;
698101099Srwatson	int error;
699101099Srwatson
700132232Srwatson	effective = strsep(&string, "(");
701132232Srwatson	if (*effective == '\0')
702132232Srwatson		effective = NULL;
703115395Srwatson
704115395Srwatson	if (string != NULL) {
705115395Srwatson		rangelow = strsep(&string, "-");
706115395Srwatson		if (string == NULL)
707105696Srwatson			return (EINVAL);
708115395Srwatson		rangehigh = strsep(&string, ")");
709115395Srwatson		if (string == NULL)
710105696Srwatson			return (EINVAL);
711115395Srwatson		if (*string != '\0')
712105696Srwatson			return (EINVAL);
713115395Srwatson	} else {
714115395Srwatson		rangelow = NULL;
715115395Srwatson		rangehigh = NULL;
716105696Srwatson	}
717115395Srwatson
718105696Srwatson	KASSERT((rangelow != NULL && rangehigh != NULL) ||
719105696Srwatson	    (rangelow == NULL && rangehigh == NULL),
720172955Srwatson	    ("biba_parse: range mismatch"));
721101099Srwatson
722172955Srwatson	bzero(mb, sizeof(*mb));
723132232Srwatson	if (effective != NULL) {
724172955Srwatson		error = biba_parse_element(&mb->mb_effective, effective);
725105696Srwatson		if (error)
726105696Srwatson			return (error);
727172955Srwatson		mb->mb_flags |= MAC_BIBA_FLAG_EFFECTIVE;
728105696Srwatson	}
729105696Srwatson
730105696Srwatson	if (rangelow != NULL) {
731172955Srwatson		error = biba_parse_element(&mb->mb_rangelow, rangelow);
732105696Srwatson		if (error)
733105696Srwatson			return (error);
734172955Srwatson		error = biba_parse_element(&mb->mb_rangehigh, rangehigh);
735105696Srwatson		if (error)
736105696Srwatson			return (error);
737172955Srwatson		mb->mb_flags |= MAC_BIBA_FLAG_RANGE;
738105696Srwatson	}
739105696Srwatson
740172955Srwatson	error = biba_valid(mb);
741101099Srwatson	if (error)
742101099Srwatson		return (error);
743101099Srwatson
744105696Srwatson	return (0);
745105696Srwatson}
746101099Srwatson
747105696Srwatsonstatic int
748172955Srwatsonbiba_internalize_label(struct label *label, char *element_name,
749105696Srwatson    char *element_data, int *claimed)
750105696Srwatson{
751172955Srwatson	struct mac_biba *mb, mb_temp;
752105696Srwatson	int error;
753105696Srwatson
754105696Srwatson	if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0)
755105696Srwatson		return (0);
756105696Srwatson
757105696Srwatson	(*claimed)++;
758105696Srwatson
759172955Srwatson	error = biba_parse(&mb_temp, element_data);
760105696Srwatson	if (error)
761105696Srwatson		return (error);
762105696Srwatson
763172955Srwatson	mb = SLOT(label);
764172955Srwatson	*mb = mb_temp;
765105696Srwatson
766101099Srwatson	return (0);
767101099Srwatson}
768101099Srwatson
769105696Srwatsonstatic void
770172955Srwatsonbiba_copy_label(struct label *src, struct label *dest)
771105696Srwatson{
772105696Srwatson
773105696Srwatson	*SLOT(dest) = *SLOT(src);
774105696Srwatson}
775105696Srwatson
776101099Srwatson/*
777172955Srwatson * Labeling event operations: file system objects, and things that look a lot
778172955Srwatson * like file system objects.
779101099Srwatson */
780101099Srwatsonstatic void
781172955Srwatsonbiba_devfs_create_device(struct ucred *cred, struct mount *mp,
782168976Srwatson    struct cdev *dev, struct devfs_dirent *de, struct label *delabel)
783101099Srwatson{
784172955Srwatson	struct mac_biba *mb;
785101099Srwatson	int biba_type;
786101099Srwatson
787172955Srwatson	mb = SLOT(delabel);
788101099Srwatson	if (strcmp(dev->si_name, "null") == 0 ||
789101099Srwatson	    strcmp(dev->si_name, "zero") == 0 ||
790101099Srwatson	    strcmp(dev->si_name, "random") == 0 ||
791101099Srwatson	    strncmp(dev->si_name, "fd/", strlen("fd/")) == 0)
792101099Srwatson		biba_type = MAC_BIBA_TYPE_EQUAL;
793105606Srwatson	else if (ptys_equal &&
794105606Srwatson	    (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 ||
795105606Srwatson	    strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0))
796105606Srwatson		biba_type = MAC_BIBA_TYPE_EQUAL;
797101099Srwatson	else
798101099Srwatson		biba_type = MAC_BIBA_TYPE_HIGH;
799172955Srwatson	biba_set_effective(mb, biba_type, 0, NULL);
800101099Srwatson}
801101099Srwatson
802101099Srwatsonstatic void
803172955Srwatsonbiba_devfs_create_directory(struct mount *mp, char *dirname, int dirnamelen,
804172955Srwatson    struct devfs_dirent *de, struct label *delabel)
805101099Srwatson{
806172955Srwatson	struct mac_biba *mb;
807101099Srwatson
808172955Srwatson	mb = SLOT(delabel);
809172955Srwatson
810172955Srwatson	biba_set_effective(mb, MAC_BIBA_TYPE_HIGH, 0, NULL);
811101099Srwatson}
812101099Srwatson
813101099Srwatsonstatic void
814172955Srwatsonbiba_devfs_create_symlink(struct ucred *cred, struct mount *mp,
815107698Srwatson    struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de,
816122563Srwatson    struct label *delabel)
817104535Srwatson{
818104535Srwatson	struct mac_biba *source, *dest;
819104535Srwatson
820122524Srwatson	source = SLOT(cred->cr_label);
821104535Srwatson	dest = SLOT(delabel);
822104535Srwatson
823172955Srwatson	biba_copy_effective(source, dest);
824104535Srwatson}
825104535Srwatson
826104535Srwatsonstatic void
827172955Srwatsonbiba_mount_create(struct ucred *cred, struct mount *mp,
828168976Srwatson    struct label *mplabel)
829101099Srwatson{
830101099Srwatson	struct mac_biba *source, *dest;
831101099Srwatson
832122524Srwatson	source = SLOT(cred->cr_label);
833168976Srwatson	dest = SLOT(mplabel);
834172955Srwatson
835172955Srwatson	biba_copy_effective(source, dest);
836101099Srwatson}
837101099Srwatson
838101099Srwatsonstatic void
839172955Srwatsonbiba_vnode_relabel(struct ucred *cred, struct vnode *vp,
840168976Srwatson    struct label *vplabel, struct label *newlabel)
841101099Srwatson{
842101099Srwatson	struct mac_biba *source, *dest;
843101099Srwatson
844168976Srwatson	source = SLOT(newlabel);
845168976Srwatson	dest = SLOT(vplabel);
846101099Srwatson
847172955Srwatson	biba_copy(source, dest);
848101099Srwatson}
849101099Srwatson
850101099Srwatsonstatic void
851172955Srwatsonbiba_devfs_update(struct mount *mp, struct devfs_dirent *de,
852168976Srwatson    struct label *delabel, struct vnode *vp, struct label *vplabel)
853101099Srwatson{
854101099Srwatson	struct mac_biba *source, *dest;
855101099Srwatson
856168976Srwatson	source = SLOT(vplabel);
857168976Srwatson	dest = SLOT(delabel);
858101099Srwatson
859172955Srwatson	biba_copy(source, dest);
860101099Srwatson}
861101099Srwatson
862101099Srwatsonstatic void
863172955Srwatsonbiba_devfs_vnode_associate(struct mount *mp, struct label *mntlabel,
864105988Srwatson    struct devfs_dirent *de, struct label *delabel, struct vnode *vp,
865168976Srwatson    struct label *vplabel)
866101099Srwatson{
867101099Srwatson	struct mac_biba *source, *dest;
868101099Srwatson
869105988Srwatson	source = SLOT(delabel);
870168976Srwatson	dest = SLOT(vplabel);
871101099Srwatson
872172955Srwatson	biba_copy_effective(source, dest);
873101099Srwatson}
874101099Srwatson
875101099Srwatsonstatic int
876172955Srwatsonbiba_vnode_associate_extattr(struct mount *mp, struct label *mplabel,
877168976Srwatson    struct vnode *vp, struct label *vplabel)
878101099Srwatson{
879172955Srwatson	struct mac_biba mb_temp, *source, *dest;
880106354Smux	int buflen, error;
881101099Srwatson
882168976Srwatson	source = SLOT(mplabel);
883168976Srwatson	dest = SLOT(vplabel);
884101099Srwatson
885172955Srwatson	buflen = sizeof(mb_temp);
886172955Srwatson	bzero(&mb_temp, buflen);
887105988Srwatson
888105988Srwatson	error = vn_extattr_get(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
889172955Srwatson	    MAC_BIBA_EXTATTR_NAME, &buflen, (char *) &mb_temp, curthread);
890105988Srwatson	if (error == ENOATTR || error == EOPNOTSUPP) {
891168954Srwatson		/* Fall back to the mntlabel. */
892172955Srwatson		biba_copy_effective(source, dest);
893105988Srwatson		return (0);
894105988Srwatson	} else if (error)
895101099Srwatson		return (error);
896101099Srwatson
897172955Srwatson	if (buflen != sizeof(mb_temp)) {
898172955Srwatson		printf("biba_vnode_associate_extattr: bad size %d\n",
899105988Srwatson		    buflen);
900105988Srwatson		return (EPERM);
901105988Srwatson	}
902172955Srwatson	if (biba_valid(&mb_temp) != 0) {
903172955Srwatson		printf("biba_vnode_associate_extattr: invalid\n");
904105988Srwatson		return (EPERM);
905105988Srwatson	}
906172955Srwatson	if ((mb_temp.mb_flags & MAC_BIBA_FLAGS_BOTH) !=
907172955Srwatson	    MAC_BIBA_FLAG_EFFECTIVE) {
908172955Srwatson		printf("biba_vnode_associate_extattr: not effective\n");
909105988Srwatson		return (EPERM);
910105988Srwatson	}
911101099Srwatson
912172955Srwatson	biba_copy_effective(&mb_temp, dest);
913101099Srwatson	return (0);
914101099Srwatson}
915101099Srwatson
916101099Srwatsonstatic void
917172955Srwatsonbiba_vnode_associate_singlelabel(struct mount *mp, struct label *mplabel,
918172955Srwatson    struct vnode *vp, struct label *vplabel)
919101099Srwatson{
920101099Srwatson	struct mac_biba *source, *dest;
921101099Srwatson
922168976Srwatson	source = SLOT(mplabel);
923168976Srwatson	dest = SLOT(vplabel);
924101099Srwatson
925172955Srwatson	biba_copy_effective(source, dest);
926101099Srwatson}
927101099Srwatson
928105988Srwatsonstatic int
929172955Srwatsonbiba_vnode_create_extattr(struct ucred *cred, struct mount *mp,
930168976Srwatson    struct label *mplabel, struct vnode *dvp, struct label *dvplabel,
931168976Srwatson    struct vnode *vp, struct label *vplabel, struct componentname *cnp)
932105988Srwatson{
933172955Srwatson	struct mac_biba *source, *dest, mb_temp;
934105988Srwatson	size_t buflen;
935105988Srwatson	int error;
936105988Srwatson
937172955Srwatson	buflen = sizeof(mb_temp);
938172955Srwatson	bzero(&mb_temp, buflen);
939105988Srwatson
940122524Srwatson	source = SLOT(cred->cr_label);
941168976Srwatson	dest = SLOT(vplabel);
942172955Srwatson	biba_copy_effective(source, &mb_temp);
943105988Srwatson
944105988Srwatson	error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
945172955Srwatson	    MAC_BIBA_EXTATTR_NAME, buflen, (char *) &mb_temp, curthread);
946105988Srwatson	if (error == 0)
947172955Srwatson		biba_copy_effective(source, dest);
948105988Srwatson	return (error);
949105988Srwatson}
950105988Srwatson
951105988Srwatsonstatic int
952172955Srwatsonbiba_vnode_setlabel_extattr(struct ucred *cred, struct vnode *vp,
953168976Srwatson    struct label *vplabel, struct label *intlabel)
954105988Srwatson{
955172955Srwatson	struct mac_biba *source, mb_temp;
956105988Srwatson	size_t buflen;
957105988Srwatson	int error;
958105988Srwatson
959172955Srwatson	buflen = sizeof(mb_temp);
960172955Srwatson	bzero(&mb_temp, buflen);
961105988Srwatson
962105988Srwatson	source = SLOT(intlabel);
963132232Srwatson	if ((source->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) == 0)
964105988Srwatson		return (0);
965105988Srwatson
966172955Srwatson	biba_copy_effective(source, &mb_temp);
967105988Srwatson
968105988Srwatson	error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
969172955Srwatson	    MAC_BIBA_EXTATTR_NAME, buflen, (char *) &mb_temp, curthread);
970105988Srwatson	return (error);
971105988Srwatson}
972105988Srwatson
973101099Srwatson/*
974101099Srwatson * Labeling event operations: IPC object.
975101099Srwatson */
976101099Srwatsonstatic void
977172955Srwatsonbiba_inpcb_create(struct socket *so, struct label *solabel,
978122875Srwatson    struct inpcb *inp, struct label *inplabel)
979122875Srwatson{
980122875Srwatson	struct mac_biba *source, *dest;
981122875Srwatson
982122875Srwatson	source = SLOT(solabel);
983122875Srwatson	dest = SLOT(inplabel);
984122875Srwatson
985172955Srwatson	biba_copy_effective(source, dest);
986122875Srwatson}
987122875Srwatson
988122875Srwatsonstatic void
989172955Srwatsonbiba_socket_create_mbuf(struct socket *so, struct label *solabel,
990168976Srwatson    struct mbuf *m, struct label *mlabel)
991101099Srwatson{
992101099Srwatson	struct mac_biba *source, *dest;
993101099Srwatson
994168976Srwatson	source = SLOT(solabel);
995168976Srwatson	dest = SLOT(mlabel);
996101099Srwatson
997172955Srwatson	biba_copy_effective(source, dest);
998101099Srwatson}
999101099Srwatson
1000101099Srwatsonstatic void
1001172955Srwatsonbiba_socket_create(struct ucred *cred, struct socket *so,
1002168976Srwatson    struct label *solabel)
1003101099Srwatson{
1004101099Srwatson	struct mac_biba *source, *dest;
1005101099Srwatson
1006122524Srwatson	source = SLOT(cred->cr_label);
1007168976Srwatson	dest = SLOT(solabel);
1008101099Srwatson
1009172955Srwatson	biba_copy_effective(source, dest);
1010101099Srwatson}
1011101099Srwatson
1012101099Srwatsonstatic void
1013172955Srwatsonbiba_pipe_create(struct ucred *cred, struct pipepair *pp,
1014168976Srwatson    struct label *pplabel)
1015101099Srwatson{
1016101099Srwatson	struct mac_biba *source, *dest;
1017101099Srwatson
1018122524Srwatson	source = SLOT(cred->cr_label);
1019168976Srwatson	dest = SLOT(pplabel);
1020101099Srwatson
1021172955Srwatson	biba_copy_effective(source, dest);
1022101099Srwatson}
1023101099Srwatson
1024101099Srwatsonstatic void
1025172955Srwatsonbiba_posixsem_create(struct ucred *cred, struct ksem *ks,
1026172850Srwatson    struct label *kslabel)
1027145855Srwatson{
1028145855Srwatson	struct mac_biba *source, *dest;
1029145855Srwatson
1030145855Srwatson	source = SLOT(cred->cr_label);
1031172850Srwatson	dest = SLOT(kslabel);
1032145855Srwatson
1033172955Srwatson	biba_copy_effective(source, dest);
1034145855Srwatson}
1035145855Srwatson
1036145855Srwatsonstatic void
1037172955Srwatsonbiba_socket_newconn(struct socket *oldso, struct label *oldsolabel,
1038172930Srwatson    struct socket *newso, struct label *newsolabel)
1039101099Srwatson{
1040101099Srwatson	struct mac_biba *source, *dest;
1041101099Srwatson
1042168976Srwatson	source = SLOT(oldsolabel);
1043168976Srwatson	dest = SLOT(newsolabel);
1044101099Srwatson
1045172955Srwatson	biba_copy_effective(source, dest);
1046101099Srwatson}
1047101099Srwatson
1048101099Srwatsonstatic void
1049172955Srwatsonbiba_socket_relabel(struct ucred *cred, struct socket *so,
1050168976Srwatson    struct label *solabel, struct label *newlabel)
1051101099Srwatson{
1052101099Srwatson	struct mac_biba *source, *dest;
1053101099Srwatson
1054101099Srwatson	source = SLOT(newlabel);
1055168976Srwatson	dest = SLOT(solabel);
1056101099Srwatson
1057172955Srwatson	biba_copy(source, dest);
1058101099Srwatson}
1059101099Srwatson
1060101099Srwatsonstatic void
1061172955Srwatsonbiba_pipe_relabel(struct ucred *cred, struct pipepair *pp,
1062168976Srwatson    struct label *pplabel, struct label *newlabel)
1063101099Srwatson{
1064101099Srwatson	struct mac_biba *source, *dest;
1065101099Srwatson
1066101099Srwatson	source = SLOT(newlabel);
1067168976Srwatson	dest = SLOT(pplabel);
1068101099Srwatson
1069172955Srwatson	biba_copy(source, dest);
1070101099Srwatson}
1071101099Srwatson
1072101099Srwatsonstatic void
1073172955Srwatsonbiba_socketpeer_set_from_mbuf(struct mbuf *m, struct label *mlabel,
1074168976Srwatson    struct socket *so, struct label *sopeerlabel)
1075101099Srwatson{
1076101099Srwatson	struct mac_biba *source, *dest;
1077101099Srwatson
1078168976Srwatson	source = SLOT(mlabel);
1079168976Srwatson	dest = SLOT(sopeerlabel);
1080101099Srwatson
1081172955Srwatson	biba_copy_effective(source, dest);
1082101099Srwatson}
1083101099Srwatson
1084101099Srwatson/*
1085140628Srwatson * Labeling event operations: System V IPC objects.
1086140628Srwatson */
1087140628Srwatsonstatic void
1088172955Srwatsonbiba_sysvmsg_create(struct ucred *cred, struct msqid_kernel *msqkptr,
1089140628Srwatson    struct label *msqlabel, struct msg *msgptr, struct label *msglabel)
1090140628Srwatson{
1091140628Srwatson	struct mac_biba *source, *dest;
1092140628Srwatson
1093140628Srwatson	/* Ignore the msgq label */
1094140628Srwatson	source = SLOT(cred->cr_label);
1095140628Srwatson	dest = SLOT(msglabel);
1096140628Srwatson
1097172955Srwatson	biba_copy_effective(source, dest);
1098140628Srwatson}
1099140628Srwatson
1100140628Srwatsonstatic void
1101172955Srwatsonbiba_sysvmsq_create(struct ucred *cred, struct msqid_kernel *msqkptr,
1102172955Srwatson    struct label *msqlabel)
1103140628Srwatson{
1104140628Srwatson	struct mac_biba *source, *dest;
1105140628Srwatson
1106140628Srwatson	source = SLOT(cred->cr_label);
1107140628Srwatson	dest = SLOT(msqlabel);
1108140628Srwatson
1109172955Srwatson	biba_copy_effective(source, dest);
1110140628Srwatson}
1111140628Srwatson
1112140628Srwatsonstatic void
1113172955Srwatsonbiba_sysvsem_create(struct ucred *cred, struct semid_kernel *semakptr,
1114140628Srwatson    struct label *semalabel)
1115140628Srwatson{
1116140628Srwatson	struct mac_biba *source, *dest;
1117140628Srwatson
1118140628Srwatson	source = SLOT(cred->cr_label);
1119140628Srwatson	dest = SLOT(semalabel);
1120140628Srwatson
1121172955Srwatson	biba_copy_effective(source, dest);
1122140628Srwatson}
1123140628Srwatson
1124140628Srwatsonstatic void
1125172955Srwatsonbiba_sysvshm_create(struct ucred *cred, struct shmid_kernel *shmsegptr,
1126140628Srwatson    struct label *shmlabel)
1127140628Srwatson{
1128140628Srwatson	struct mac_biba *source, *dest;
1129140628Srwatson
1130140628Srwatson	source = SLOT(cred->cr_label);
1131140628Srwatson	dest = SLOT(shmlabel);
1132140628Srwatson
1133172955Srwatson	biba_copy_effective(source, dest);
1134140628Srwatson}
1135140628Srwatson
1136140628Srwatson/*
1137101099Srwatson * Labeling event operations: network objects.
1138101099Srwatson */
1139101099Srwatsonstatic void
1140172955Srwatsonbiba_socketpeer_set_from_socket(struct socket *oldso,
1141168976Srwatson    struct label *oldsolabel, struct socket *newso,
1142168976Srwatson    struct label *newsopeerlabel)
1143101099Srwatson{
1144101099Srwatson	struct mac_biba *source, *dest;
1145101099Srwatson
1146168976Srwatson	source = SLOT(oldsolabel);
1147168976Srwatson	dest = SLOT(newsopeerlabel);
1148101099Srwatson
1149172955Srwatson	biba_copy_effective(source, dest);
1150101099Srwatson}
1151101099Srwatson
1152101099Srwatsonstatic void
1153172955Srwatsonbiba_bpfdesc_create(struct ucred *cred, struct bpf_d *d,
1154168976Srwatson    struct label *dlabel)
1155101099Srwatson{
1156101099Srwatson	struct mac_biba *source, *dest;
1157101099Srwatson
1158122524Srwatson	source = SLOT(cred->cr_label);
1159168976Srwatson	dest = SLOT(dlabel);
1160101099Srwatson
1161172955Srwatson	biba_copy_effective(source, dest);
1162101099Srwatson}
1163101099Srwatson
1164101099Srwatsonstatic void
1165172955Srwatsonbiba_ifnet_create(struct ifnet *ifp, struct label *ifplabel)
1166101099Srwatson{
1167121816Sbrooks	char tifname[IFNAMSIZ], *p, *q;
1168101099Srwatson	char tiflist[sizeof(trusted_interfaces)];
1169101099Srwatson	struct mac_biba *dest;
1170110350Srwatson	int len, type;
1171101099Srwatson
1172168976Srwatson	dest = SLOT(ifplabel);
1173101099Srwatson
1174168976Srwatson	if (ifp->if_type == IFT_LOOP || interfaces_equal != 0) {
1175110350Srwatson		type = MAC_BIBA_TYPE_EQUAL;
1176101099Srwatson		goto set;
1177101099Srwatson	}
1178101099Srwatson
1179101099Srwatson	if (trust_all_interfaces) {
1180110350Srwatson		type = MAC_BIBA_TYPE_HIGH;
1181101099Srwatson		goto set;
1182101099Srwatson	}
1183101099Srwatson
1184110350Srwatson	type = MAC_BIBA_TYPE_LOW;
1185101099Srwatson
1186101099Srwatson	if (trusted_interfaces[0] == '\0' ||
1187101099Srwatson	    !strvalid(trusted_interfaces, sizeof(trusted_interfaces)))
1188101099Srwatson		goto set;
1189101099Srwatson
1190106089Srwatson	bzero(tiflist, sizeof(tiflist));
1191101099Srwatson	for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++)
1192101099Srwatson		if(*p != ' ' && *p != '\t')
1193101099Srwatson			*q = *p;
1194101099Srwatson
1195101099Srwatson	for (p = q = tiflist;; p++) {
1196101099Srwatson		if (*p == ',' || *p == '\0') {
1197101099Srwatson			len = p - q;
1198101099Srwatson			if (len < IFNAMSIZ) {
1199101099Srwatson				bzero(tifname, sizeof(tifname));
1200101099Srwatson				bcopy(q, tifname, len);
1201168976Srwatson				if (strcmp(tifname, ifp->if_xname) == 0) {
1202110350Srwatson					type = MAC_BIBA_TYPE_HIGH;
1203101099Srwatson					break;
1204101099Srwatson				}
1205106089Srwatson			} else {
1206106089Srwatson				*p = '\0';
1207106089Srwatson				printf("mac_biba warning: interface name "
1208106089Srwatson				    "\"%s\" is too long (must be < %d)\n",
1209106089Srwatson				    q, IFNAMSIZ);
1210101099Srwatson			}
1211101099Srwatson			if (*p == '\0')
1212101099Srwatson				break;
1213101099Srwatson			q = p + 1;
1214101099Srwatson		}
1215101099Srwatson	}
1216101099Srwatsonset:
1217172955Srwatson	biba_set_effective(dest, type, 0, NULL);
1218172955Srwatson	biba_set_range(dest, type, 0, NULL, type, 0, NULL);
1219101099Srwatson}
1220101099Srwatson
1221101099Srwatsonstatic void
1222172955Srwatsonbiba_ipq_create(struct mbuf *m, struct label *mlabel, struct ipq *ipq,
1223168976Srwatson    struct label *ipqlabel)
1224101099Srwatson{
1225101099Srwatson	struct mac_biba *source, *dest;
1226101099Srwatson
1227168976Srwatson	source = SLOT(mlabel);
1228101099Srwatson	dest = SLOT(ipqlabel);
1229101099Srwatson
1230172955Srwatson	biba_copy_effective(source, dest);
1231101099Srwatson}
1232101099Srwatson
1233101099Srwatsonstatic void
1234172955Srwatsonbiba_ipq_reassemble(struct ipq *ipq, struct label *ipqlabel, struct mbuf *m,
1235172955Srwatson    struct label *mlabel)
1236101099Srwatson{
1237101099Srwatson	struct mac_biba *source, *dest;
1238101099Srwatson
1239101099Srwatson	source = SLOT(ipqlabel);
1240168976Srwatson	dest = SLOT(mlabel);
1241101099Srwatson
1242101099Srwatson	/* Just use the head, since we require them all to match. */
1243172955Srwatson	biba_copy_effective(source, dest);
1244101099Srwatson}
1245101099Srwatson
1246101099Srwatsonstatic void
1247172955Srwatsonbiba_netinet_fragment(struct mbuf *m, struct label *mlabel,
1248168976Srwatson    struct mbuf *frag, struct label *fraglabel)
1249101099Srwatson{
1250101099Srwatson	struct mac_biba *source, *dest;
1251101099Srwatson
1252168976Srwatson	source = SLOT(mlabel);
1253168976Srwatson	dest = SLOT(fraglabel);
1254101099Srwatson
1255172955Srwatson	biba_copy_effective(source, dest);
1256101099Srwatson}
1257101099Srwatson
1258101099Srwatsonstatic void
1259172955Srwatsonbiba_inpcb_create_mbuf(struct inpcb *inp, struct label *inplabel,
1260123607Srwatson    struct mbuf *m, struct label *mlabel)
1261123607Srwatson{
1262123607Srwatson	struct mac_biba *source, *dest;
1263123607Srwatson
1264123607Srwatson	source = SLOT(inplabel);
1265123607Srwatson	dest = SLOT(mlabel);
1266123607Srwatson
1267172955Srwatson	biba_copy_effective(source, dest);
1268123607Srwatson}
1269123607Srwatson
1270123607Srwatsonstatic void
1271172955Srwatsonbiba_create_mbuf_linklayer(struct ifnet *ifp, struct label *ifplabel,
1272168976Srwatson    struct mbuf *m, struct label *mlabel)
1273101099Srwatson{
1274101099Srwatson	struct mac_biba *dest;
1275101099Srwatson
1276168976Srwatson	dest = SLOT(mlabel);
1277101099Srwatson
1278172955Srwatson	biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1279101099Srwatson}
1280101099Srwatson
1281101099Srwatsonstatic void
1282172955Srwatsonbiba_bpfdesc_create_mbuf(struct bpf_d *d, struct label *dlabel,
1283168976Srwatson    struct mbuf *m, struct label *mlabel)
1284101099Srwatson{
1285101099Srwatson	struct mac_biba *source, *dest;
1286101099Srwatson
1287168976Srwatson	source = SLOT(dlabel);
1288168976Srwatson	dest = SLOT(mlabel);
1289101099Srwatson
1290172955Srwatson	biba_copy_effective(source, dest);
1291101099Srwatson}
1292101099Srwatson
1293101099Srwatsonstatic void
1294172955Srwatsonbiba_ifnet_create_mbuf(struct ifnet *ifp, struct label *ifplabel,
1295168976Srwatson    struct mbuf *m, struct label *mlabel)
1296101099Srwatson{
1297101099Srwatson	struct mac_biba *source, *dest;
1298101099Srwatson
1299168976Srwatson	source = SLOT(ifplabel);
1300168976Srwatson	dest = SLOT(mlabel);
1301101099Srwatson
1302172955Srwatson	biba_copy_effective(source, dest);
1303101099Srwatson}
1304101099Srwatson
1305101099Srwatsonstatic void
1306172955Srwatsonbiba_mbuf_create_multicast_encap(struct mbuf *m, struct label *mlabel,
1307168976Srwatson    struct ifnet *ifp, struct label *ifplabel, struct mbuf *mnew,
1308168976Srwatson    struct label *mnewlabel)
1309101099Srwatson{
1310101099Srwatson	struct mac_biba *source, *dest;
1311101099Srwatson
1312168976Srwatson	source = SLOT(mlabel);
1313168976Srwatson	dest = SLOT(mnewlabel);
1314101099Srwatson
1315172955Srwatson	biba_copy_effective(source, dest);
1316101099Srwatson}
1317101099Srwatson
1318101099Srwatsonstatic void
1319172955Srwatsonbiba_mbuf_create_netlayer(struct mbuf *m, struct label *mlabel,
1320168976Srwatson    struct mbuf *newm, struct label *mnewlabel)
1321101099Srwatson{
1322101099Srwatson	struct mac_biba *source, *dest;
1323101099Srwatson
1324168976Srwatson	source = SLOT(mlabel);
1325168976Srwatson	dest = SLOT(mnewlabel);
1326101099Srwatson
1327172955Srwatson	biba_copy_effective(source, dest);
1328101099Srwatson}
1329101099Srwatson
1330101099Srwatsonstatic int
1331172955Srwatsonbiba_ipq_match(struct mbuf *m, struct label *mlabel, struct ipq *ipq,
1332172930Srwatson    struct label *ipqlabel)
1333101099Srwatson{
1334101099Srwatson	struct mac_biba *a, *b;
1335101099Srwatson
1336101099Srwatson	a = SLOT(ipqlabel);
1337168976Srwatson	b = SLOT(mlabel);
1338101099Srwatson
1339172955Srwatson	return (biba_equal_effective(a, b));
1340101099Srwatson}
1341101099Srwatson
1342101099Srwatsonstatic void
1343172955Srwatsonbiba_ifnet_relabel(struct ucred *cred, struct ifnet *ifp,
1344168976Srwatson    struct label *ifplabel, struct label *newlabel)
1345101099Srwatson{
1346101099Srwatson	struct mac_biba *source, *dest;
1347101099Srwatson
1348101099Srwatson	source = SLOT(newlabel);
1349168976Srwatson	dest = SLOT(ifplabel);
1350101099Srwatson
1351172955Srwatson	biba_copy(source, dest);
1352101099Srwatson}
1353101099Srwatson
1354101099Srwatsonstatic void
1355172955Srwatsonbiba_ipq_update(struct mbuf *m, struct label *mlabel, struct ipq *ipq,
1356168976Srwatson    struct label *ipqlabel)
1357101099Srwatson{
1358101099Srwatson
1359101099Srwatson	/* NOOP: we only accept matching labels, so no need to update */
1360101099Srwatson}
1361101099Srwatson
1362122875Srwatsonstatic void
1363172955Srwatsonbiba_inpcb_sosetlabel(struct socket *so, struct label *solabel,
1364122875Srwatson    struct inpcb *inp, struct label *inplabel)
1365122875Srwatson{
1366122875Srwatson	struct mac_biba *source, *dest;
1367122875Srwatson
1368122875Srwatson	source = SLOT(solabel);
1369122875Srwatson	dest = SLOT(inplabel);
1370122875Srwatson
1371172955Srwatson	biba_copy(source, dest);
1372122875Srwatson}
1373122875Srwatson
1374162238Scsjpstatic void
1375172955Srwatsonbiba_mbuf_create_from_firewall(struct mbuf *m, struct label *label)
1376162238Scsjp{
1377162238Scsjp	struct mac_biba *dest;
1378162238Scsjp
1379162238Scsjp	dest = SLOT(label);
1380162238Scsjp
1381162238Scsjp	/* XXX: where is the label for the firewall really comming from? */
1382172955Srwatson	biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1383162238Scsjp}
1384162238Scsjp
1385101099Srwatson/*
1386101099Srwatson * Labeling event operations: processes.
1387101099Srwatson */
1388101099Srwatsonstatic void
1389172955Srwatsonbiba_proc_create_swapper(struct ucred *cred)
1390101099Srwatson{
1391101099Srwatson	struct mac_biba *dest;
1392101099Srwatson
1393122524Srwatson	dest = SLOT(cred->cr_label);
1394101099Srwatson
1395172955Srwatson	biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1396172955Srwatson	biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL, MAC_BIBA_TYPE_HIGH,
1397172955Srwatson	    0, NULL);
1398101099Srwatson}
1399101099Srwatson
1400101099Srwatsonstatic void
1401172955Srwatsonbiba_proc_create_init(struct ucred *cred)
1402101099Srwatson{
1403101099Srwatson	struct mac_biba *dest;
1404101099Srwatson
1405122524Srwatson	dest = SLOT(cred->cr_label);
1406101099Srwatson
1407172955Srwatson	biba_set_effective(dest, MAC_BIBA_TYPE_HIGH, 0, NULL);
1408172955Srwatson	biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL, MAC_BIBA_TYPE_HIGH,
1409172955Srwatson	    0, NULL);
1410101099Srwatson}
1411101099Srwatson
1412101099Srwatsonstatic void
1413172955Srwatsonbiba_cred_relabel(struct ucred *cred, struct label *newlabel)
1414101099Srwatson{
1415101099Srwatson	struct mac_biba *source, *dest;
1416101099Srwatson
1417101099Srwatson	source = SLOT(newlabel);
1418122524Srwatson	dest = SLOT(cred->cr_label);
1419101099Srwatson
1420172955Srwatson	biba_copy(source, dest);
1421101099Srwatson}
1422101099Srwatson
1423101099Srwatson/*
1424140628Srwatson * Label cleanup/flush operations
1425140628Srwatson */
1426140628Srwatsonstatic void
1427172955Srwatsonbiba_sysvmsg_cleanup(struct label *msglabel)
1428140628Srwatson{
1429140628Srwatson
1430140628Srwatson	bzero(SLOT(msglabel), sizeof(struct mac_biba));
1431140628Srwatson}
1432140628Srwatson
1433140628Srwatsonstatic void
1434172955Srwatsonbiba_sysvmsq_cleanup(struct label *msqlabel)
1435140628Srwatson{
1436140628Srwatson
1437140628Srwatson	bzero(SLOT(msqlabel), sizeof(struct mac_biba));
1438140628Srwatson}
1439140628Srwatson
1440140628Srwatsonstatic void
1441172955Srwatsonbiba_sysvsem_cleanup(struct label *semalabel)
1442140628Srwatson{
1443140628Srwatson
1444140628Srwatson	bzero(SLOT(semalabel), sizeof(struct mac_biba));
1445140628Srwatson}
1446140628Srwatson
1447140628Srwatsonstatic void
1448172955Srwatsonbiba_sysvshm_cleanup(struct label *shmlabel)
1449140628Srwatson{
1450140628Srwatson	bzero(SLOT(shmlabel), sizeof(struct mac_biba));
1451140628Srwatson}
1452140628Srwatson
1453140628Srwatson/*
1454101099Srwatson * Access control checks.
1455101099Srwatson */
1456101099Srwatsonstatic int
1457172955Srwatsonbiba_bpfdesc_check_receive(struct bpf_d *d, struct label *dlabel,
1458168976Srwatson    struct ifnet *ifp, struct label *ifplabel)
1459101099Srwatson{
1460101099Srwatson	struct mac_biba *a, *b;
1461101099Srwatson
1462172955Srwatson	if (!biba_enabled)
1463101099Srwatson		return (0);
1464101099Srwatson
1465168976Srwatson	a = SLOT(dlabel);
1466168976Srwatson	b = SLOT(ifplabel);
1467101099Srwatson
1468172955Srwatson	if (biba_equal_effective(a, b))
1469101099Srwatson		return (0);
1470101099Srwatson	return (EACCES);
1471101099Srwatson}
1472101099Srwatson
1473101099Srwatsonstatic int
1474172955Srwatsonbiba_cred_check_relabel(struct ucred *cred, struct label *newlabel)
1475101099Srwatson{
1476101099Srwatson	struct mac_biba *subj, *new;
1477105634Srwatson	int error;
1478101099Srwatson
1479122524Srwatson	subj = SLOT(cred->cr_label);
1480101099Srwatson	new = SLOT(newlabel);
1481101099Srwatson
1482101099Srwatson	/*
1483105634Srwatson	 * If there is a Biba label update for the credential, it may
1484132232Srwatson	 * be an update of the effective, range, or both.
1485101099Srwatson	 */
1486105634Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
1487105634Srwatson	if (error)
1488105634Srwatson		return (error);
1489101099Srwatson
1490101099Srwatson	/*
1491105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
1492101099Srwatson	 */
1493105634Srwatson	if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) {
1494105634Srwatson		/*
1495110351Srwatson		 * If the change request modifies both the Biba label
1496132232Srwatson		 * effective and range, check that the new effective will be
1497110351Srwatson		 * in the new range.
1498110351Srwatson		 */
1499110351Srwatson		if ((new->mb_flags & MAC_BIBA_FLAGS_BOTH) ==
1500110351Srwatson		    MAC_BIBA_FLAGS_BOTH &&
1501172955Srwatson		    !biba_effective_in_range(new, new))
1502110351Srwatson			return (EINVAL);
1503110351Srwatson
1504110351Srwatson		/*
1505132232Srwatson		 * To change the Biba effective label on a credential, the
1506132232Srwatson		 * new effective label must be in the current range.
1507105634Srwatson		 */
1508132232Srwatson		if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE &&
1509172955Srwatson		    !biba_effective_in_range(new, subj))
1510105634Srwatson			return (EPERM);
1511101099Srwatson
1512105634Srwatson		/*
1513172955Srwatson		 * To change the Biba range on a credential, the new range
1514172955Srwatson		 * label must be in the current range.
1515105634Srwatson		 */
1516105634Srwatson		if (new->mb_flags & MAC_BIBA_FLAG_RANGE &&
1517172955Srwatson		    !biba_range_in_range(new, subj))
1518105634Srwatson			return (EPERM);
1519101099Srwatson
1520105634Srwatson		/*
1521172955Srwatson		 * To have EQUAL in any component of the new credential Biba
1522172955Srwatson		 * label, the subject must already have EQUAL in their label.
1523105634Srwatson		 */
1524172955Srwatson		if (biba_contains_equal(new)) {
1525172955Srwatson			error = biba_subject_privileged(subj);
1526105634Srwatson			if (error)
1527105634Srwatson				return (error);
1528105634Srwatson		}
1529105634Srwatson	}
1530105634Srwatson
1531101099Srwatson	return (0);
1532101099Srwatson}
1533101099Srwatson
1534101099Srwatsonstatic int
1535172955Srwatsonbiba_cred_check_visible(struct ucred *u1, struct ucred *u2)
1536101099Srwatson{
1537101099Srwatson	struct mac_biba *subj, *obj;
1538101099Srwatson
1539172955Srwatson	if (!biba_enabled)
1540101099Srwatson		return (0);
1541101099Srwatson
1542122524Srwatson	subj = SLOT(u1->cr_label);
1543122524Srwatson	obj = SLOT(u2->cr_label);
1544101099Srwatson
1545101099Srwatson	/* XXX: range */
1546172955Srwatson	if (!biba_dominate_effective(obj, subj))
1547101099Srwatson		return (ESRCH);
1548101099Srwatson
1549101099Srwatson	return (0);
1550101099Srwatson}
1551101099Srwatson
1552101099Srwatsonstatic int
1553172955Srwatsonbiba_ifnet_check_relabel(struct ucred *cred, struct ifnet *ifp,
1554168976Srwatson    struct label *ifplabel, struct label *newlabel)
1555101099Srwatson{
1556101099Srwatson	struct mac_biba *subj, *new;
1557105634Srwatson	int error;
1558101099Srwatson
1559122524Srwatson	subj = SLOT(cred->cr_label);
1560101099Srwatson	new = SLOT(newlabel);
1561101099Srwatson
1562105634Srwatson	/*
1563172955Srwatson	 * If there is a Biba label update for the interface, it may be an
1564172955Srwatson	 * update of the effective, range, or both.
1565105634Srwatson	 */
1566105634Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
1567105634Srwatson	if (error)
1568105634Srwatson		return (error);
1569101099Srwatson
1570105634Srwatson	/*
1571106160Srwatson	 * Relabling network interfaces requires Biba privilege.
1572106160Srwatson	 */
1573172955Srwatson	error = biba_subject_privileged(subj);
1574106160Srwatson	if (error)
1575106160Srwatson		return (error);
1576106160Srwatson
1577105634Srwatson	return (0);
1578101099Srwatson}
1579101099Srwatson
1580103759Srwatsonstatic int
1581172955Srwatsonbiba_ifnet_check_transmit(struct ifnet *ifp, struct label *ifplabel,
1582168976Srwatson    struct mbuf *m, struct label *mlabel)
1583101099Srwatson{
1584101099Srwatson	struct mac_biba *p, *i;
1585103761Srwatson
1586172955Srwatson	if (!biba_enabled)
1587101099Srwatson		return (0);
1588101099Srwatson
1589168976Srwatson	p = SLOT(mlabel);
1590168976Srwatson	i = SLOT(ifplabel);
1591103759Srwatson
1592172955Srwatson	return (biba_effective_in_range(p, i) ? 0 : EACCES);
1593101099Srwatson}
1594101099Srwatson
1595101099Srwatsonstatic int
1596172955Srwatsonbiba_inpcb_check_deliver(struct inpcb *inp, struct label *inplabel,
1597122875Srwatson    struct mbuf *m, struct label *mlabel)
1598122875Srwatson{
1599122875Srwatson	struct mac_biba *p, *i;
1600122875Srwatson
1601172955Srwatson	if (!biba_enabled)
1602122875Srwatson		return (0);
1603122875Srwatson
1604122875Srwatson	p = SLOT(mlabel);
1605122875Srwatson	i = SLOT(inplabel);
1606122875Srwatson
1607172955Srwatson	return (biba_equal_effective(p, i) ? 0 : EACCES);
1608122875Srwatson}
1609122875Srwatson
1610122875Srwatsonstatic int
1611172955Srwatsonbiba_sysvmsq_check_msgrcv(struct ucred *cred, struct msg *msgptr,
1612140628Srwatson    struct label *msglabel)
1613140628Srwatson{
1614140628Srwatson	struct mac_biba *subj, *obj;
1615140628Srwatson
1616172955Srwatson	if (!biba_enabled)
1617140628Srwatson		return (0);
1618140628Srwatson
1619140628Srwatson	subj = SLOT(cred->cr_label);
1620140628Srwatson	obj = SLOT(msglabel);
1621140628Srwatson
1622172955Srwatson	if (!biba_dominate_effective(obj, subj))
1623140628Srwatson		return (EACCES);
1624140628Srwatson
1625140628Srwatson	return (0);
1626140628Srwatson}
1627140628Srwatson
1628140628Srwatsonstatic int
1629172955Srwatsonbiba_sysvmsq_check_msgrmid(struct ucred *cred, struct msg *msgptr,
1630140628Srwatson    struct label *msglabel)
1631140628Srwatson{
1632140628Srwatson	struct mac_biba *subj, *obj;
1633140628Srwatson
1634172955Srwatson	if (!biba_enabled)
1635140628Srwatson		return (0);
1636140628Srwatson
1637140628Srwatson	subj = SLOT(cred->cr_label);
1638140628Srwatson	obj = SLOT(msglabel);
1639140628Srwatson
1640172955Srwatson	if (!biba_dominate_effective(subj, obj))
1641140628Srwatson		return (EACCES);
1642140628Srwatson
1643140628Srwatson	return (0);
1644140628Srwatson}
1645140628Srwatson
1646140628Srwatsonstatic int
1647172955Srwatsonbiba_sysvmsq_check_msqget(struct ucred *cred, struct msqid_kernel *msqkptr,
1648172955Srwatson    struct label *msqklabel)
1649140628Srwatson{
1650140628Srwatson	struct mac_biba *subj, *obj;
1651140628Srwatson
1652172955Srwatson	if (!biba_enabled)
1653140628Srwatson		return (0);
1654140628Srwatson
1655140628Srwatson	subj = SLOT(cred->cr_label);
1656140628Srwatson	obj = SLOT(msqklabel);
1657140628Srwatson
1658172955Srwatson	if (!biba_dominate_effective(obj, subj))
1659140628Srwatson		return (EACCES);
1660140628Srwatson
1661140628Srwatson	return (0);
1662140628Srwatson}
1663140628Srwatson
1664140628Srwatsonstatic int
1665172955Srwatsonbiba_sysvmsq_check_msqsnd(struct ucred *cred, struct msqid_kernel *msqkptr,
1666172955Srwatson    struct label *msqklabel)
1667140628Srwatson{
1668140628Srwatson	struct mac_biba *subj, *obj;
1669140628Srwatson
1670172955Srwatson	if (!biba_enabled)
1671140628Srwatson		return (0);
1672140628Srwatson
1673140628Srwatson	subj = SLOT(cred->cr_label);
1674140628Srwatson	obj = SLOT(msqklabel);
1675140628Srwatson
1676172955Srwatson	if (!biba_dominate_effective(subj, obj))
1677140628Srwatson		return (EACCES);
1678140628Srwatson
1679140628Srwatson	return (0);
1680140628Srwatson}
1681140628Srwatson
1682140628Srwatsonstatic int
1683172955Srwatsonbiba_sysvmsq_check_msqrcv(struct ucred *cred, struct msqid_kernel *msqkptr,
1684172955Srwatson    struct label *msqklabel)
1685140628Srwatson{
1686140628Srwatson	struct mac_biba *subj, *obj;
1687140628Srwatson
1688172955Srwatson	if (!biba_enabled)
1689140628Srwatson		return (0);
1690140628Srwatson
1691140628Srwatson	subj = SLOT(cred->cr_label);
1692140628Srwatson	obj = SLOT(msqklabel);
1693140628Srwatson
1694172955Srwatson	if (!biba_dominate_effective(obj, subj))
1695140628Srwatson		return (EACCES);
1696140628Srwatson
1697140628Srwatson	return (0);
1698140628Srwatson}
1699140628Srwatson
1700140628Srwatsonstatic int
1701172955Srwatsonbiba_sysvmsq_check_msqctl(struct ucred *cred, struct msqid_kernel *msqkptr,
1702172955Srwatson    struct label *msqklabel, int cmd)
1703140628Srwatson{
1704140628Srwatson	struct mac_biba *subj, *obj;
1705140628Srwatson
1706172955Srwatson	if (!biba_enabled)
1707140628Srwatson		return (0);
1708140628Srwatson
1709140628Srwatson	subj = SLOT(cred->cr_label);
1710140628Srwatson	obj = SLOT(msqklabel);
1711140628Srwatson
1712140628Srwatson	switch(cmd) {
1713140628Srwatson	case IPC_RMID:
1714140628Srwatson	case IPC_SET:
1715172955Srwatson		if (!biba_dominate_effective(subj, obj))
1716140628Srwatson			return (EACCES);
1717140628Srwatson		break;
1718140628Srwatson
1719140628Srwatson	case IPC_STAT:
1720172955Srwatson		if (!biba_dominate_effective(obj, subj))
1721140628Srwatson			return (EACCES);
1722140628Srwatson		break;
1723140628Srwatson
1724140628Srwatson	default:
1725140628Srwatson		return (EACCES);
1726140628Srwatson	}
1727140628Srwatson
1728140628Srwatson	return (0);
1729140628Srwatson}
1730140628Srwatson
1731140628Srwatsonstatic int
1732172955Srwatsonbiba_sysvsem_check_semctl(struct ucred *cred, struct semid_kernel *semakptr,
1733172955Srwatson    struct label *semaklabel, int cmd)
1734140628Srwatson{
1735140628Srwatson	struct mac_biba *subj, *obj;
1736140628Srwatson
1737172955Srwatson	if (!biba_enabled)
1738140628Srwatson		return (0);
1739140628Srwatson
1740140628Srwatson	subj = SLOT(cred->cr_label);
1741140628Srwatson	obj = SLOT(semaklabel);
1742140628Srwatson
1743140628Srwatson	switch(cmd) {
1744140628Srwatson	case IPC_RMID:
1745140628Srwatson	case IPC_SET:
1746140628Srwatson	case SETVAL:
1747140628Srwatson	case SETALL:
1748172955Srwatson		if (!biba_dominate_effective(subj, obj))
1749140628Srwatson			return (EACCES);
1750140628Srwatson		break;
1751140628Srwatson
1752140628Srwatson	case IPC_STAT:
1753140628Srwatson	case GETVAL:
1754140628Srwatson	case GETPID:
1755140628Srwatson	case GETNCNT:
1756140628Srwatson	case GETZCNT:
1757140628Srwatson	case GETALL:
1758172955Srwatson		if (!biba_dominate_effective(obj, subj))
1759140628Srwatson			return (EACCES);
1760140628Srwatson		break;
1761140628Srwatson
1762140628Srwatson	default:
1763140628Srwatson		return (EACCES);
1764140628Srwatson	}
1765140628Srwatson
1766140628Srwatson	return (0);
1767140628Srwatson}
1768140628Srwatson
1769140628Srwatsonstatic int
1770172955Srwatsonbiba_sysvsem_check_semget(struct ucred *cred, struct semid_kernel *semakptr,
1771172955Srwatson    struct label *semaklabel)
1772140628Srwatson{
1773140628Srwatson	struct mac_biba *subj, *obj;
1774140628Srwatson
1775172955Srwatson	if (!biba_enabled)
1776140628Srwatson		return (0);
1777140628Srwatson
1778140628Srwatson	subj = SLOT(cred->cr_label);
1779140628Srwatson	obj = SLOT(semaklabel);
1780140628Srwatson
1781172955Srwatson	if (!biba_dominate_effective(obj, subj))
1782140628Srwatson		return (EACCES);
1783140628Srwatson
1784140628Srwatson	return (0);
1785140628Srwatson}
1786140628Srwatson
1787140628Srwatsonstatic int
1788172955Srwatsonbiba_sysvsem_check_semop(struct ucred *cred, struct semid_kernel *semakptr,
1789172955Srwatson    struct label *semaklabel, size_t accesstype)
1790140628Srwatson{
1791140628Srwatson	struct mac_biba *subj, *obj;
1792140628Srwatson
1793172955Srwatson	if (!biba_enabled)
1794140628Srwatson		return (0);
1795140628Srwatson
1796140628Srwatson	subj = SLOT(cred->cr_label);
1797140628Srwatson	obj = SLOT(semaklabel);
1798140628Srwatson
1799140628Srwatson	if (accesstype & SEM_R)
1800172955Srwatson		if (!biba_dominate_effective(obj, subj))
1801140628Srwatson			return (EACCES);
1802140628Srwatson
1803140628Srwatson	if (accesstype & SEM_A)
1804172955Srwatson		if (!biba_dominate_effective(subj, obj))
1805140628Srwatson			return (EACCES);
1806140628Srwatson
1807140628Srwatson	return (0);
1808140628Srwatson}
1809140628Srwatson
1810140628Srwatsonstatic int
1811172955Srwatsonbiba_sysvshm_check_shmat(struct ucred *cred, struct shmid_kernel *shmsegptr,
1812172955Srwatson    struct label *shmseglabel, int shmflg)
1813140628Srwatson{
1814140628Srwatson	struct mac_biba *subj, *obj;
1815140628Srwatson
1816172955Srwatson	if (!biba_enabled)
1817140628Srwatson		return (0);
1818140628Srwatson
1819140628Srwatson	subj = SLOT(cred->cr_label);
1820140628Srwatson	obj = SLOT(shmseglabel);
1821140628Srwatson
1822172955Srwatson	if (!biba_dominate_effective(obj, subj))
1823140628Srwatson		return (EACCES);
1824140628Srwatson	if ((shmflg & SHM_RDONLY) == 0) {
1825172955Srwatson		if (!biba_dominate_effective(subj, obj))
1826140628Srwatson			return (EACCES);
1827140628Srwatson	}
1828140628Srwatson
1829140628Srwatson	return (0);
1830140628Srwatson}
1831140628Srwatson
1832140628Srwatsonstatic int
1833172955Srwatsonbiba_sysvshm_check_shmctl(struct ucred *cred, struct shmid_kernel *shmsegptr,
1834172955Srwatson    struct label *shmseglabel, int cmd)
1835140628Srwatson{
1836140628Srwatson	struct mac_biba *subj, *obj;
1837140628Srwatson
1838172955Srwatson	if (!biba_enabled)
1839140628Srwatson		return (0);
1840140628Srwatson
1841140628Srwatson	subj = SLOT(cred->cr_label);
1842140628Srwatson	obj = SLOT(shmseglabel);
1843140628Srwatson
1844140628Srwatson	switch(cmd) {
1845140628Srwatson	case IPC_RMID:
1846140628Srwatson	case IPC_SET:
1847172955Srwatson		if (!biba_dominate_effective(subj, obj))
1848140628Srwatson			return (EACCES);
1849140628Srwatson		break;
1850140628Srwatson
1851140628Srwatson	case IPC_STAT:
1852140628Srwatson	case SHM_STAT:
1853172955Srwatson		if (!biba_dominate_effective(obj, subj))
1854140628Srwatson			return (EACCES);
1855140628Srwatson		break;
1856140628Srwatson
1857140628Srwatson	default:
1858140628Srwatson		return (EACCES);
1859140628Srwatson	}
1860140628Srwatson
1861140628Srwatson	return (0);
1862140628Srwatson}
1863140628Srwatson
1864140628Srwatsonstatic int
1865172955Srwatsonbiba_sysvshm_check_shmget(struct ucred *cred, struct shmid_kernel *shmsegptr,
1866172955Srwatson    struct label *shmseglabel, int shmflg)
1867140628Srwatson{
1868140628Srwatson	struct mac_biba *subj, *obj;
1869140628Srwatson
1870172955Srwatson	if (!biba_enabled)
1871140628Srwatson		return (0);
1872140628Srwatson
1873140628Srwatson	subj = SLOT(cred->cr_label);
1874140628Srwatson	obj = SLOT(shmseglabel);
1875140628Srwatson
1876172955Srwatson	if (!biba_dominate_effective(obj, subj))
1877140628Srwatson		return (EACCES);
1878140628Srwatson
1879140628Srwatson	return (0);
1880140628Srwatson}
1881140628Srwatson
1882140628Srwatsonstatic int
1883172955Srwatsonbiba_kld_check_load(struct ucred *cred, struct vnode *vp,
1884168976Srwatson    struct label *vplabel)
1885110354Srwatson{
1886110354Srwatson	struct mac_biba *subj, *obj;
1887110354Srwatson	int error;
1888110354Srwatson
1889172955Srwatson	if (!biba_enabled)
1890110354Srwatson		return (0);
1891110354Srwatson
1892122524Srwatson	subj = SLOT(cred->cr_label);
1893110354Srwatson
1894172955Srwatson	error = biba_subject_privileged(subj);
1895110354Srwatson	if (error)
1896110354Srwatson		return (error);
1897110354Srwatson
1898168976Srwatson	obj = SLOT(vplabel);
1899172955Srwatson	if (!biba_high_effective(obj))
1900110354Srwatson		return (EACCES);
1901110354Srwatson
1902110354Srwatson	return (0);
1903110354Srwatson}
1904110354Srwatson
1905110354Srwatsonstatic int
1906172955Srwatsonbiba_mount_check_stat(struct ucred *cred, struct mount *mp,
1907168976Srwatson    struct label *mplabel)
1908101099Srwatson{
1909101099Srwatson	struct mac_biba *subj, *obj;
1910101099Srwatson
1911172955Srwatson	if (!biba_enabled)
1912101099Srwatson		return (0);
1913101099Srwatson
1914122524Srwatson	subj = SLOT(cred->cr_label);
1915168976Srwatson	obj = SLOT(mplabel);
1916101099Srwatson
1917172955Srwatson	if (!biba_dominate_effective(obj, subj))
1918101099Srwatson		return (EACCES);
1919101099Srwatson
1920101099Srwatson	return (0);
1921101099Srwatson}
1922101099Srwatson
1923101099Srwatsonstatic int
1924172955Srwatsonbiba_pipe_check_ioctl(struct ucred *cred, struct pipepair *pp,
1925168976Srwatson    struct label *pplabel, unsigned long cmd, void /* caddr_t */ *data)
1926101099Srwatson{
1927103759Srwatson
1928172955Srwatson	if(!biba_enabled)
1929101099Srwatson		return (0);
1930101099Srwatson
1931101099Srwatson	/* XXX: This will be implemented soon... */
1932101099Srwatson
1933101099Srwatson	return (0);
1934101099Srwatson}
1935101099Srwatson
1936101099Srwatsonstatic int
1937172955Srwatsonbiba_pipe_check_poll(struct ucred *cred, struct pipepair *pp,
1938168976Srwatson    struct label *pplabel)
1939101099Srwatson{
1940101099Srwatson	struct mac_biba *subj, *obj;
1941101099Srwatson
1942172955Srwatson	if (!biba_enabled)
1943101099Srwatson		return (0);
1944101099Srwatson
1945122524Srwatson	subj = SLOT(cred->cr_label);
1946168976Srwatson	obj = SLOT(pplabel);
1947101099Srwatson
1948172955Srwatson	if (!biba_dominate_effective(obj, subj))
1949102115Srwatson		return (EACCES);
1950101099Srwatson
1951101099Srwatson	return (0);
1952101099Srwatson}
1953101099Srwatson
1954101099Srwatsonstatic int
1955172955Srwatsonbiba_pipe_check_read(struct ucred *cred, struct pipepair *pp,
1956168976Srwatson    struct label *pplabel)
1957102115Srwatson{
1958102115Srwatson	struct mac_biba *subj, *obj;
1959102115Srwatson
1960172955Srwatson	if (!biba_enabled)
1961102115Srwatson		return (0);
1962102115Srwatson
1963122524Srwatson	subj = SLOT(cred->cr_label);
1964168976Srwatson	obj = SLOT(pplabel);
1965102115Srwatson
1966172955Srwatson	if (!biba_dominate_effective(obj, subj))
1967102115Srwatson		return (EACCES);
1968102115Srwatson
1969102115Srwatson	return (0);
1970102115Srwatson}
1971102115Srwatson
1972102115Srwatsonstatic int
1973172955Srwatsonbiba_pipe_check_relabel(struct ucred *cred, struct pipepair *pp,
1974168976Srwatson    struct label *pplabel, struct label *newlabel)
1975101099Srwatson{
1976101099Srwatson	struct mac_biba *subj, *obj, *new;
1977105634Srwatson	int error;
1978101099Srwatson
1979101099Srwatson	new = SLOT(newlabel);
1980122524Srwatson	subj = SLOT(cred->cr_label);
1981168976Srwatson	obj = SLOT(pplabel);
1982101099Srwatson
1983101099Srwatson	/*
1984172955Srwatson	 * If there is a Biba label update for a pipe, it must be a effective
1985172955Srwatson	 * update.
1986101099Srwatson	 */
1987132232Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE);
1988105634Srwatson	if (error)
1989105634Srwatson		return (error);
1990101099Srwatson
1991101099Srwatson	/*
1992105634Srwatson	 * To perform a relabel of a pipe (Biba label or not), Biba must
1993105634Srwatson	 * authorize the relabel.
1994101099Srwatson	 */
1995172955Srwatson	if (!biba_effective_in_range(obj, subj))
1996101099Srwatson		return (EPERM);
1997101099Srwatson
1998101099Srwatson	/*
1999105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
2000101099Srwatson	 */
2001132232Srwatson	if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
2002105634Srwatson		/*
2003105634Srwatson		 * To change the Biba label on a pipe, the new pipe label
2004105634Srwatson		 * must be in the subject range.
2005105634Srwatson		 */
2006172955Srwatson		if (!biba_effective_in_range(new, subj))
2007105634Srwatson			return (EPERM);
2008101099Srwatson
2009105634Srwatson		/*
2010105634Srwatson		 * To change the Biba label on a pipe to be EQUAL, the
2011105634Srwatson		 * subject must have appropriate privilege.
2012105634Srwatson		 */
2013172955Srwatson		if (biba_contains_equal(new)) {
2014172955Srwatson			error = biba_subject_privileged(subj);
2015105634Srwatson			if (error)
2016105634Srwatson				return (error);
2017105634Srwatson		}
2018105634Srwatson	}
2019105634Srwatson
2020101099Srwatson	return (0);
2021101099Srwatson}
2022101099Srwatson
2023101099Srwatsonstatic int
2024172955Srwatsonbiba_pipe_check_stat(struct ucred *cred, struct pipepair *pp,
2025168976Srwatson    struct label *pplabel)
2026102115Srwatson{
2027102115Srwatson	struct mac_biba *subj, *obj;
2028102115Srwatson
2029172955Srwatson	if (!biba_enabled)
2030102115Srwatson		return (0);
2031102115Srwatson
2032122524Srwatson	subj = SLOT(cred->cr_label);
2033168976Srwatson	obj = SLOT(pplabel);
2034102115Srwatson
2035172955Srwatson	if (!biba_dominate_effective(obj, subj))
2036102115Srwatson		return (EACCES);
2037102115Srwatson
2038102115Srwatson	return (0);
2039102115Srwatson}
2040102115Srwatson
2041102115Srwatsonstatic int
2042172955Srwatsonbiba_pipe_check_write(struct ucred *cred, struct pipepair *pp,
2043168976Srwatson    struct label *pplabel)
2044102115Srwatson{
2045102115Srwatson	struct mac_biba *subj, *obj;
2046102115Srwatson
2047172955Srwatson	if (!biba_enabled)
2048102115Srwatson		return (0);
2049102115Srwatson
2050122524Srwatson	subj = SLOT(cred->cr_label);
2051168976Srwatson	obj = SLOT(pplabel);
2052102115Srwatson
2053172955Srwatson	if (!biba_dominate_effective(subj, obj))
2054102115Srwatson		return (EACCES);
2055102115Srwatson
2056102115Srwatson	return (0);
2057102115Srwatson}
2058102115Srwatson
2059102115Srwatsonstatic int
2060172955Srwatsonbiba_posixsem_check_write(struct ucred *cred, struct ksem *ks,
2061172850Srwatson    struct label *kslabel)
2062145855Srwatson{
2063145855Srwatson	struct mac_biba *subj, *obj;
2064145855Srwatson
2065172955Srwatson	if (!biba_enabled)
2066145855Srwatson		return (0);
2067145855Srwatson
2068145855Srwatson	subj = SLOT(cred->cr_label);
2069172850Srwatson	obj = SLOT(kslabel);
2070145855Srwatson
2071172955Srwatson	if (!biba_dominate_effective(subj, obj))
2072145855Srwatson		return (EACCES);
2073145855Srwatson
2074145855Srwatson	return (0);
2075145855Srwatson}
2076145855Srwatson
2077145855Srwatsonstatic int
2078172955Srwatsonbiba_posixsem_check_rdonly(struct ucred *cred, struct ksem *ks,
2079172850Srwatson    struct label *kslabel)
2080145855Srwatson{
2081145855Srwatson	struct mac_biba *subj, *obj;
2082145855Srwatson
2083172955Srwatson	if (!biba_enabled)
2084145855Srwatson		return (0);
2085145855Srwatson
2086145855Srwatson	subj = SLOT(cred->cr_label);
2087172850Srwatson	obj = SLOT(kslabel);
2088145855Srwatson
2089172955Srwatson	if (!biba_dominate_effective(obj, subj))
2090145855Srwatson		return (EACCES);
2091145855Srwatson
2092145855Srwatson	return (0);
2093145855Srwatson}
2094145855Srwatson
2095145855Srwatsonstatic int
2096172955Srwatsonbiba_proc_check_debug(struct ucred *cred, struct proc *p)
2097101099Srwatson{
2098101099Srwatson	struct mac_biba *subj, *obj;
2099101099Srwatson
2100172955Srwatson	if (!biba_enabled)
2101101099Srwatson		return (0);
2102101099Srwatson
2103122524Srwatson	subj = SLOT(cred->cr_label);
2104168976Srwatson	obj = SLOT(p->p_ucred->cr_label);
2105101099Srwatson
2106101099Srwatson	/* XXX: range checks */
2107172955Srwatson	if (!biba_dominate_effective(obj, subj))
2108101099Srwatson		return (ESRCH);
2109172955Srwatson	if (!biba_dominate_effective(subj, obj))
2110101099Srwatson		return (EACCES);
2111101099Srwatson
2112101099Srwatson	return (0);
2113101099Srwatson}
2114101099Srwatson
2115101099Srwatsonstatic int
2116172955Srwatsonbiba_proc_check_sched(struct ucred *cred, struct proc *p)
2117101099Srwatson{
2118101099Srwatson	struct mac_biba *subj, *obj;
2119103759Srwatson
2120172955Srwatson	if (!biba_enabled)
2121101099Srwatson		return (0);
2122101099Srwatson
2123122524Srwatson	subj = SLOT(cred->cr_label);
2124168976Srwatson	obj = SLOT(p->p_ucred->cr_label);
2125103759Srwatson
2126101099Srwatson	/* XXX: range checks */
2127172955Srwatson	if (!biba_dominate_effective(obj, subj))
2128101099Srwatson		return (ESRCH);
2129172955Srwatson	if (!biba_dominate_effective(subj, obj))
2130101099Srwatson		return (EACCES);
2131101099Srwatson
2132101099Srwatson	return (0);
2133101099Srwatson}
2134101099Srwatson
2135101099Srwatsonstatic int
2136172955Srwatsonbiba_proc_check_signal(struct ucred *cred, struct proc *p, int signum)
2137101099Srwatson{
2138101099Srwatson	struct mac_biba *subj, *obj;
2139103759Srwatson
2140172955Srwatson	if (!biba_enabled)
2141101099Srwatson		return (0);
2142101099Srwatson
2143122524Srwatson	subj = SLOT(cred->cr_label);
2144168976Srwatson	obj = SLOT(p->p_ucred->cr_label);
2145103759Srwatson
2146101099Srwatson	/* XXX: range checks */
2147172955Srwatson	if (!biba_dominate_effective(obj, subj))
2148101099Srwatson		return (ESRCH);
2149172955Srwatson	if (!biba_dominate_effective(subj, obj))
2150101099Srwatson		return (EACCES);
2151101099Srwatson
2152101099Srwatson	return (0);
2153101099Srwatson}
2154101099Srwatson
2155101099Srwatsonstatic int
2156172955Srwatsonbiba_socket_check_deliver(struct socket *so, struct label *solabel,
2157168976Srwatson    struct mbuf *m, struct label *mlabel)
2158101099Srwatson{
2159101099Srwatson	struct mac_biba *p, *s;
2160101099Srwatson
2161172955Srwatson	if (!biba_enabled)
2162101099Srwatson		return (0);
2163101099Srwatson
2164168976Srwatson	p = SLOT(mlabel);
2165168976Srwatson	s = SLOT(solabel);
2166101099Srwatson
2167172955Srwatson	return (biba_equal_effective(p, s) ? 0 : EACCES);
2168101099Srwatson}
2169101099Srwatson
2170101099Srwatsonstatic int
2171172955Srwatsonbiba_socket_check_relabel(struct ucred *cred, struct socket *so,
2172168976Srwatson    struct label *solabel, struct label *newlabel)
2173101099Srwatson{
2174101099Srwatson	struct mac_biba *subj, *obj, *new;
2175105634Srwatson	int error;
2176101099Srwatson
2177101099Srwatson	new = SLOT(newlabel);
2178122524Srwatson	subj = SLOT(cred->cr_label);
2179168976Srwatson	obj = SLOT(solabel);
2180101099Srwatson
2181101099Srwatson	/*
2182172955Srwatson	 * If there is a Biba label update for the socket, it may be an
2183172955Srwatson	 * update of effective.
2184101099Srwatson	 */
2185132232Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE);
2186105634Srwatson	if (error)
2187105634Srwatson		return (error);
2188101099Srwatson
2189101099Srwatson	/*
2190172955Srwatson	 * To relabel a socket, the old socket effective must be in the
2191172955Srwatson	 * subject range.
2192101099Srwatson	 */
2193172955Srwatson	if (!biba_effective_in_range(obj, subj))
2194101099Srwatson		return (EPERM);
2195101099Srwatson
2196101099Srwatson	/*
2197105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
2198101099Srwatson	 */
2199132232Srwatson	if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
2200105634Srwatson		/*
2201132232Srwatson		 * To relabel a socket, the new socket effective must be in
2202105634Srwatson		 * the subject range.
2203105634Srwatson		 */
2204172955Srwatson		if (!biba_effective_in_range(new, subj))
2205105634Srwatson			return (EPERM);
2206101099Srwatson
2207105634Srwatson		/*
2208105634Srwatson		 * To change the Biba label on the socket to contain EQUAL,
2209105634Srwatson		 * the subject must have appropriate privilege.
2210105634Srwatson		 */
2211172955Srwatson		if (biba_contains_equal(new)) {
2212172955Srwatson			error = biba_subject_privileged(subj);
2213105634Srwatson			if (error)
2214105634Srwatson				return (error);
2215105634Srwatson		}
2216105634Srwatson	}
2217105634Srwatson
2218101099Srwatson	return (0);
2219101099Srwatson}
2220101099Srwatson
2221101099Srwatsonstatic int
2222172955Srwatsonbiba_socket_check_visible(struct ucred *cred, struct socket *so,
2223168976Srwatson    struct label *solabel)
2224101099Srwatson{
2225101099Srwatson	struct mac_biba *subj, *obj;
2226101099Srwatson
2227172955Srwatson	if (!biba_enabled)
2228105722Srwatson		return (0);
2229105722Srwatson
2230122524Srwatson	subj = SLOT(cred->cr_label);
2231168976Srwatson	obj = SLOT(solabel);
2232101099Srwatson
2233172955Srwatson	if (!biba_dominate_effective(obj, subj))
2234101099Srwatson		return (ENOENT);
2235101099Srwatson
2236101099Srwatson	return (0);
2237101099Srwatson}
2238101099Srwatson
2239168951Srwatson/*
2240168951Srwatson * Some system privileges are allowed regardless of integrity grade; others
2241168951Srwatson * are allowed only when running with privilege with respect to the Biba
2242168951Srwatson * policy as they might otherwise allow bypassing of the integrity policy.
2243168951Srwatson */
2244101099Srwatsonstatic int
2245172955Srwatsonbiba_priv_check(struct ucred *cred, int priv)
2246112574Srwatson{
2247112574Srwatson	struct mac_biba *subj;
2248112574Srwatson	int error;
2249112574Srwatson
2250172955Srwatson	if (!biba_enabled)
2251112574Srwatson		return (0);
2252112574Srwatson
2253168951Srwatson	/*
2254168951Srwatson	 * Exempt only specific privileges from the Biba integrity policy.
2255168951Srwatson	 */
2256168951Srwatson	switch (priv) {
2257168951Srwatson	case PRIV_KTRACE:
2258168951Srwatson	case PRIV_MSGBUF:
2259112574Srwatson
2260168951Srwatson	/*
2261168951Srwatson	 * Allow processes to manipulate basic process audit properties, and
2262168951Srwatson	 * to submit audit records.
2263168951Srwatson	 */
2264168951Srwatson	case PRIV_AUDIT_GETAUDIT:
2265168951Srwatson	case PRIV_AUDIT_SETAUDIT:
2266168951Srwatson	case PRIV_AUDIT_SUBMIT:
2267112574Srwatson
2268168951Srwatson	/*
2269168951Srwatson	 * Allow processes to manipulate their regular UNIX credentials.
2270168951Srwatson	 */
2271168951Srwatson	case PRIV_CRED_SETUID:
2272168951Srwatson	case PRIV_CRED_SETEUID:
2273168951Srwatson	case PRIV_CRED_SETGID:
2274168951Srwatson	case PRIV_CRED_SETEGID:
2275168951Srwatson	case PRIV_CRED_SETGROUPS:
2276168951Srwatson	case PRIV_CRED_SETREUID:
2277168951Srwatson	case PRIV_CRED_SETREGID:
2278168951Srwatson	case PRIV_CRED_SETRESUID:
2279168951Srwatson	case PRIV_CRED_SETRESGID:
2280168951Srwatson
2281168951Srwatson	/*
2282168951Srwatson	 * Allow processes to perform system monitoring.
2283168951Srwatson	 */
2284168951Srwatson	case PRIV_SEEOTHERGIDS:
2285168951Srwatson	case PRIV_SEEOTHERUIDS:
2286168951Srwatson		break;
2287168951Srwatson
2288168951Srwatson	/*
2289168951Srwatson	 * Allow access to general process debugging facilities.  We
2290168951Srwatson	 * separately control debugging based on MAC label.
2291168951Srwatson	 */
2292168951Srwatson	case PRIV_DEBUG_DIFFCRED:
2293168951Srwatson	case PRIV_DEBUG_SUGID:
2294168951Srwatson	case PRIV_DEBUG_UNPRIV:
2295168951Srwatson
2296168951Srwatson	/*
2297168951Srwatson	 * Allow manipulating jails.
2298168951Srwatson	 */
2299168951Srwatson	case PRIV_JAIL_ATTACH:
2300168951Srwatson
2301168951Srwatson	/*
2302168951Srwatson	 * Allow privilege with respect to the Partition policy, but not the
2303168951Srwatson	 * Privs policy.
2304168951Srwatson	 */
2305168951Srwatson	case PRIV_MAC_PARTITION:
2306168951Srwatson
2307168951Srwatson	/*
2308168951Srwatson	 * Allow privilege with respect to process resource limits and login
2309168951Srwatson	 * context.
2310168951Srwatson	 */
2311168951Srwatson	case PRIV_PROC_LIMIT:
2312168951Srwatson	case PRIV_PROC_SETLOGIN:
2313168951Srwatson	case PRIV_PROC_SETRLIMIT:
2314168951Srwatson
2315168951Srwatson	/*
2316168951Srwatson	 * Allow System V and POSIX IPC privileges.
2317168951Srwatson	 */
2318168951Srwatson	case PRIV_IPC_READ:
2319168951Srwatson	case PRIV_IPC_WRITE:
2320168951Srwatson	case PRIV_IPC_ADMIN:
2321168951Srwatson	case PRIV_IPC_MSGSIZE:
2322168951Srwatson	case PRIV_MQ_ADMIN:
2323168951Srwatson
2324168951Srwatson	/*
2325168951Srwatson	 * Allow certain scheduler manipulations -- possibly this should be
2326168951Srwatson	 * controlled by more fine-grained policy, as potentially low
2327168951Srwatson	 * integrity processes can deny CPU to higher integrity ones.
2328168951Srwatson	 */
2329168951Srwatson	case PRIV_SCHED_DIFFCRED:
2330168951Srwatson	case PRIV_SCHED_SETPRIORITY:
2331168951Srwatson	case PRIV_SCHED_RTPRIO:
2332168951Srwatson	case PRIV_SCHED_SETPOLICY:
2333168951Srwatson	case PRIV_SCHED_SET:
2334168951Srwatson	case PRIV_SCHED_SETPARAM:
2335168951Srwatson
2336168951Srwatson	/*
2337168951Srwatson	 * More IPC privileges.
2338168951Srwatson	 */
2339168951Srwatson	case PRIV_SEM_WRITE:
2340168951Srwatson
2341168951Srwatson	/*
2342168951Srwatson	 * Allow signaling privileges subject to integrity policy.
2343168951Srwatson	 */
2344168951Srwatson	case PRIV_SIGNAL_DIFFCRED:
2345168951Srwatson	case PRIV_SIGNAL_SUGID:
2346168951Srwatson
2347168951Srwatson	/*
2348168951Srwatson	 * Allow access to only limited sysctls from lower integrity levels;
2349168951Srwatson	 * piggy-back on the Jail definition.
2350168951Srwatson	 */
2351168951Srwatson	case PRIV_SYSCTL_WRITEJAIL:
2352168951Srwatson
2353168951Srwatson	/*
2354168951Srwatson	 * Allow TTY-based privileges, subject to general device access using
2355168951Srwatson	 * labels on TTY device nodes, but not console privilege.
2356168951Srwatson	 */
2357168951Srwatson	case PRIV_TTY_DRAINWAIT:
2358168951Srwatson	case PRIV_TTY_DTRWAIT:
2359168951Srwatson	case PRIV_TTY_EXCLUSIVE:
2360168951Srwatson	case PRIV_TTY_PRISON:
2361168951Srwatson	case PRIV_TTY_STI:
2362168951Srwatson	case PRIV_TTY_SETA:
2363168951Srwatson
2364168951Srwatson	/*
2365168951Srwatson	 * Grant most VFS privileges, as almost all are in practice bounded
2366168951Srwatson	 * by more specific checks using labels.
2367168951Srwatson	 */
2368168951Srwatson	case PRIV_VFS_READ:
2369168951Srwatson	case PRIV_VFS_WRITE:
2370168951Srwatson	case PRIV_VFS_ADMIN:
2371168951Srwatson	case PRIV_VFS_EXEC:
2372168951Srwatson	case PRIV_VFS_LOOKUP:
2373168951Srwatson	case PRIV_VFS_CHFLAGS_DEV:
2374168951Srwatson	case PRIV_VFS_CHOWN:
2375168951Srwatson	case PRIV_VFS_CHROOT:
2376168951Srwatson	case PRIV_VFS_RETAINSUGID:
2377168951Srwatson	case PRIV_VFS_EXCEEDQUOTA:
2378168951Srwatson	case PRIV_VFS_FCHROOT:
2379168951Srwatson	case PRIV_VFS_FHOPEN:
2380168951Srwatson	case PRIV_VFS_FHSTATFS:
2381168951Srwatson	case PRIV_VFS_GENERATION:
2382168951Srwatson	case PRIV_VFS_GETFH:
2383168951Srwatson	case PRIV_VFS_GETQUOTA:
2384168951Srwatson	case PRIV_VFS_LINK:
2385168951Srwatson	case PRIV_VFS_MOUNT:
2386168951Srwatson	case PRIV_VFS_MOUNT_OWNER:
2387168951Srwatson	case PRIV_VFS_MOUNT_PERM:
2388168951Srwatson	case PRIV_VFS_MOUNT_SUIDDIR:
2389168951Srwatson	case PRIV_VFS_MOUNT_NONUSER:
2390168951Srwatson	case PRIV_VFS_SETGID:
2391168951Srwatson	case PRIV_VFS_STICKYFILE:
2392168951Srwatson	case PRIV_VFS_SYSFLAGS:
2393168951Srwatson	case PRIV_VFS_UNMOUNT:
2394168951Srwatson
2395168951Srwatson	/*
2396168951Srwatson	 * Allow VM privileges; it would be nice if these were subject to
2397168951Srwatson	 * resource limits.
2398168951Srwatson	 */
2399168951Srwatson	case PRIV_VM_MADV_PROTECT:
2400168951Srwatson	case PRIV_VM_MLOCK:
2401168951Srwatson	case PRIV_VM_MUNLOCK:
2402168951Srwatson
2403168951Srwatson	/*
2404168951Srwatson	 * Allow some but not all network privileges.  In general, dont allow
2405168951Srwatson	 * reconfiguring the network stack, just normal use.
2406168951Srwatson	 */
2407168951Srwatson	case PRIV_NETATALK_RESERVEDPORT:
2408168951Srwatson	case PRIV_NETINET_RESERVEDPORT:
2409168951Srwatson	case PRIV_NETINET_RAW:
2410168951Srwatson	case PRIV_NETINET_REUSEPORT:
2411168951Srwatson	case PRIV_NETIPX_RESERVEDPORT:
2412168951Srwatson	case PRIV_NETIPX_RAW:
2413168951Srwatson		break;
2414168951Srwatson
2415168951Srwatson	/*
2416168951Srwatson	 * All remaining system privileges are allow only if the process
2417168951Srwatson	 * holds privilege with respect to the Biba policy.
2418168951Srwatson	 */
2419168951Srwatson	default:
2420168951Srwatson		subj = SLOT(cred->cr_label);
2421172955Srwatson		error = biba_subject_privileged(subj);
2422168951Srwatson		if (error)
2423168951Srwatson			return (error);
2424168951Srwatson	}
2425112574Srwatson	return (0);
2426112574Srwatson}
2427112574Srwatson
2428112574Srwatsonstatic int
2429172955Srwatsonbiba_system_check_acct(struct ucred *cred, struct vnode *vp,
2430168976Srwatson    struct label *vplabel)
2431106418Srwatson{
2432106418Srwatson	struct mac_biba *subj, *obj;
2433106418Srwatson	int error;
2434106418Srwatson
2435172955Srwatson	if (!biba_enabled)
2436106418Srwatson		return (0);
2437106418Srwatson
2438122524Srwatson	subj = SLOT(cred->cr_label);
2439106418Srwatson
2440172955Srwatson	error = biba_subject_privileged(subj);
2441106418Srwatson	if (error)
2442106418Srwatson		return (error);
2443106418Srwatson
2444168976Srwatson	if (vplabel == NULL)
2445106418Srwatson		return (0);
2446106418Srwatson
2447168976Srwatson	obj = SLOT(vplabel);
2448172955Srwatson	if (!biba_high_effective(obj))
2449106418Srwatson		return (EACCES);
2450106418Srwatson
2451106418Srwatson	return (0);
2452106418Srwatson}
2453106418Srwatson
2454106418Srwatsonstatic int
2455172955Srwatsonbiba_system_check_auditctl(struct ucred *cred, struct vnode *vp,
2456168933Srwatson    struct label *vplabel)
2457168933Srwatson{
2458168933Srwatson	struct mac_biba *subj, *obj;
2459168933Srwatson	int error;
2460168933Srwatson
2461172955Srwatson	if (!biba_enabled)
2462168933Srwatson		return (0);
2463168933Srwatson
2464168933Srwatson	subj = SLOT(cred->cr_label);
2465168933Srwatson
2466172955Srwatson	error = biba_subject_privileged(subj);
2467168933Srwatson	if (error)
2468168933Srwatson		return (error);
2469168933Srwatson
2470168933Srwatson	if (vplabel == NULL)
2471168933Srwatson		return (0);
2472168933Srwatson
2473168933Srwatson	obj = SLOT(vplabel);
2474172955Srwatson	if (!biba_high_effective(obj))
2475168933Srwatson		return (EACCES);
2476168933Srwatson
2477168933Srwatson	return (0);
2478168933Srwatson}
2479168933Srwatson
2480168933Srwatsonstatic int
2481172955Srwatsonbiba_system_check_auditon(struct ucred *cred, int cmd)
2482168933Srwatson{
2483168933Srwatson	struct mac_biba *subj;
2484168933Srwatson	int error;
2485168933Srwatson
2486172955Srwatson	if (!biba_enabled)
2487168933Srwatson		return (0);
2488168933Srwatson
2489168933Srwatson	subj = SLOT(cred->cr_label);
2490168933Srwatson
2491172955Srwatson	error = biba_subject_privileged(subj);
2492168933Srwatson	if (error)
2493168933Srwatson		return (error);
2494168933Srwatson
2495168933Srwatson	return (0);
2496168933Srwatson}
2497168933Srwatson
2498168933Srwatsonstatic int
2499172955Srwatsonbiba_system_check_swapon(struct ucred *cred, struct vnode *vp,
2500168976Srwatson    struct label *vplabel)
2501106161Srwatson{
2502106161Srwatson	struct mac_biba *subj, *obj;
2503106416Srwatson	int error;
2504106161Srwatson
2505172955Srwatson	if (!biba_enabled)
2506106161Srwatson		return (0);
2507106161Srwatson
2508122524Srwatson	subj = SLOT(cred->cr_label);
2509168976Srwatson	obj = SLOT(vplabel);
2510106161Srwatson
2511172955Srwatson	error = biba_subject_privileged(subj);
2512106416Srwatson	if (error)
2513106416Srwatson		return (error);
2514106161Srwatson
2515172955Srwatson	if (!biba_high_effective(obj))
2516106161Srwatson		return (EACCES);
2517106161Srwatson
2518106161Srwatson	return (0);
2519106161Srwatson}
2520106161Srwatson
2521106161Srwatsonstatic int
2522172955Srwatsonbiba_system_check_swapoff(struct ucred *cred, struct vnode *vp,
2523112574Srwatson    struct label *label)
2524112574Srwatson{
2525166617Srwatson	struct mac_biba *subj;
2526112574Srwatson	int error;
2527112574Srwatson
2528172955Srwatson	if (!biba_enabled)
2529112574Srwatson		return (0);
2530112574Srwatson
2531122524Srwatson	subj = SLOT(cred->cr_label);
2532112574Srwatson
2533172955Srwatson	error = biba_subject_privileged(subj);
2534112574Srwatson	if (error)
2535112574Srwatson		return (error);
2536112574Srwatson
2537112574Srwatson	return (0);
2538112574Srwatson}
2539112574Srwatson
2540112574Srwatsonstatic int
2541172955Srwatsonbiba_system_check_sysctl(struct ucred *cred, struct sysctl_oid *oidp,
2542126121Spjd    void *arg1, int arg2, struct sysctl_req *req)
2543106161Srwatson{
2544106161Srwatson	struct mac_biba *subj;
2545106161Srwatson	int error;
2546106161Srwatson
2547172955Srwatson	if (!biba_enabled)
2548106161Srwatson		return (0);
2549106161Srwatson
2550122524Srwatson	subj = SLOT(cred->cr_label);
2551106161Srwatson
2552106161Srwatson	/*
2553172955Srwatson	 * Treat sysctl variables without CTLFLAG_ANYBODY flag as biba/high,
2554172955Srwatson	 * but also require privilege to change them.
2555106161Srwatson	 */
2556126121Spjd	if (req->newptr != NULL && (oidp->oid_kind & CTLFLAG_ANYBODY) == 0) {
2557172955Srwatson		if (!biba_subject_dominate_high(subj))
2558106161Srwatson			return (EACCES);
2559106161Srwatson
2560172955Srwatson		error = biba_subject_privileged(subj);
2561106161Srwatson		if (error)
2562106161Srwatson			return (error);
2563106161Srwatson	}
2564106161Srwatson
2565106161Srwatson	return (0);
2566106161Srwatson}
2567106161Srwatson
2568106161Srwatsonstatic int
2569172955Srwatsonbiba_vnode_check_chdir(struct ucred *cred, struct vnode *dvp,
2570168976Srwatson    struct label *dvplabel)
2571101099Srwatson{
2572101099Srwatson	struct mac_biba *subj, *obj;
2573101099Srwatson
2574172955Srwatson	if (!biba_enabled)
2575101099Srwatson		return (0);
2576101099Srwatson
2577122524Srwatson	subj = SLOT(cred->cr_label);
2578168976Srwatson	obj = SLOT(dvplabel);
2579101099Srwatson
2580172955Srwatson	if (!biba_dominate_effective(obj, subj))
2581101099Srwatson		return (EACCES);
2582101099Srwatson
2583101099Srwatson	return (0);
2584101099Srwatson}
2585101099Srwatson
2586101099Srwatsonstatic int
2587172955Srwatsonbiba_vnode_check_chroot(struct ucred *cred, struct vnode *dvp,
2588168976Srwatson    struct label *dvplabel)
2589101099Srwatson{
2590101099Srwatson	struct mac_biba *subj, *obj;
2591101099Srwatson
2592172955Srwatson	if (!biba_enabled)
2593101099Srwatson		return (0);
2594101099Srwatson
2595122524Srwatson	subj = SLOT(cred->cr_label);
2596168976Srwatson	obj = SLOT(dvplabel);
2597101099Srwatson
2598172955Srwatson	if (!biba_dominate_effective(obj, subj))
2599101099Srwatson		return (EACCES);
2600101099Srwatson
2601101099Srwatson	return (0);
2602101099Srwatson}
2603101099Srwatson
2604101099Srwatsonstatic int
2605172955Srwatsonbiba_vnode_check_create(struct ucred *cred, struct vnode *dvp,
2606168976Srwatson    struct label *dvplabel, struct componentname *cnp, struct vattr *vap)
2607101099Srwatson{
2608101099Srwatson	struct mac_biba *subj, *obj;
2609101099Srwatson
2610172955Srwatson	if (!biba_enabled)
2611101099Srwatson		return (0);
2612101099Srwatson
2613122524Srwatson	subj = SLOT(cred->cr_label);
2614168976Srwatson	obj = SLOT(dvplabel);
2615101099Srwatson
2616172955Srwatson	if (!biba_dominate_effective(subj, obj))
2617101099Srwatson		return (EACCES);
2618101099Srwatson
2619101099Srwatson	return (0);
2620101099Srwatson}
2621101099Srwatson
2622101099Srwatsonstatic int
2623172955Srwatsonbiba_vnode_check_deleteacl(struct ucred *cred, struct vnode *vp,
2624168976Srwatson    struct label *vplabel, acl_type_t type)
2625101099Srwatson{
2626101099Srwatson	struct mac_biba *subj, *obj;
2627101099Srwatson
2628172955Srwatson	if (!biba_enabled)
2629101099Srwatson		return (0);
2630101099Srwatson
2631122524Srwatson	subj = SLOT(cred->cr_label);
2632168976Srwatson	obj = SLOT(vplabel);
2633101099Srwatson
2634172955Srwatson	if (!biba_dominate_effective(subj, obj))
2635101099Srwatson		return (EACCES);
2636101099Srwatson
2637101099Srwatson	return (0);
2638101099Srwatson}
2639101099Srwatson
2640101099Srwatsonstatic int
2641172955Srwatsonbiba_vnode_check_deleteextattr(struct ucred *cred, struct vnode *vp,
2642168976Srwatson    struct label *vplabel, int attrnamespace, const char *name)
2643119202Srwatson{
2644119202Srwatson	struct mac_biba *subj, *obj;
2645119202Srwatson
2646172955Srwatson	if (!biba_enabled)
2647119202Srwatson		return (0);
2648119202Srwatson
2649122524Srwatson	subj = SLOT(cred->cr_label);
2650168976Srwatson	obj = SLOT(vplabel);
2651119202Srwatson
2652172955Srwatson	if (!biba_dominate_effective(subj, obj))
2653119202Srwatson		return (EACCES);
2654119202Srwatson
2655119202Srwatson	return (0);
2656119202Srwatson}
2657119202Srwatson
2658119202Srwatsonstatic int
2659172955Srwatsonbiba_vnode_check_exec(struct ucred *cred, struct vnode *vp,
2660168976Srwatson    struct label *vplabel, struct image_params *imgp,
2661106648Srwatson    struct label *execlabel)
2662101099Srwatson{
2663106648Srwatson	struct mac_biba *subj, *obj, *exec;
2664106648Srwatson	int error;
2665101099Srwatson
2666106648Srwatson	if (execlabel != NULL) {
2667106648Srwatson		/*
2668106648Srwatson		 * We currently don't permit labels to be changed at
2669172955Srwatson		 * exec-time as part of Biba, so disallow non-NULL Biba label
2670172955Srwatson		 * elements in the execlabel.
2671106648Srwatson		 */
2672106648Srwatson		exec = SLOT(execlabel);
2673106648Srwatson		error = biba_atmostflags(exec, 0);
2674106648Srwatson		if (error)
2675106648Srwatson			return (error);
2676106648Srwatson	}
2677106648Srwatson
2678172955Srwatson	if (!biba_enabled)
2679101099Srwatson		return (0);
2680101099Srwatson
2681122524Srwatson	subj = SLOT(cred->cr_label);
2682168976Srwatson	obj = SLOT(vplabel);
2683101099Srwatson
2684172955Srwatson	if (!biba_dominate_effective(obj, subj))
2685101099Srwatson		return (EACCES);
2686101099Srwatson
2687101099Srwatson	return (0);
2688101099Srwatson}
2689101099Srwatson
2690101099Srwatsonstatic int
2691172955Srwatsonbiba_vnode_check_getacl(struct ucred *cred, struct vnode *vp,
2692168976Srwatson    struct label *vplabel, acl_type_t type)
2693101099Srwatson{
2694101099Srwatson	struct mac_biba *subj, *obj;
2695101099Srwatson
2696172955Srwatson	if (!biba_enabled)
2697101099Srwatson		return (0);
2698101099Srwatson
2699122524Srwatson	subj = SLOT(cred->cr_label);
2700168976Srwatson	obj = SLOT(vplabel);
2701101099Srwatson
2702172955Srwatson	if (!biba_dominate_effective(obj, subj))
2703101099Srwatson		return (EACCES);
2704101099Srwatson
2705101099Srwatson	return (0);
2706101099Srwatson}
2707101099Srwatson
2708101099Srwatsonstatic int
2709172955Srwatsonbiba_vnode_check_getextattr(struct ucred *cred, struct vnode *vp,
2710168976Srwatson    struct label *vplabel, int attrnamespace, const char *name,
2711168976Srwatson    struct uio *uio)
2712101099Srwatson{
2713101099Srwatson	struct mac_biba *subj, *obj;
2714101099Srwatson
2715172955Srwatson	if (!biba_enabled)
2716101099Srwatson		return (0);
2717101099Srwatson
2718122524Srwatson	subj = SLOT(cred->cr_label);
2719168976Srwatson	obj = SLOT(vplabel);
2720101099Srwatson
2721172955Srwatson	if (!biba_dominate_effective(obj, subj))
2722101099Srwatson		return (EACCES);
2723101099Srwatson
2724101099Srwatson	return (0);
2725101099Srwatson}
2726101099Srwatson
2727101099Srwatsonstatic int
2728172955Srwatsonbiba_vnode_check_link(struct ucred *cred, struct vnode *dvp,
2729168976Srwatson    struct label *dvplabel, struct vnode *vp, struct label *vplabel,
2730104530Srwatson    struct componentname *cnp)
2731104530Srwatson{
2732104530Srwatson	struct mac_biba *subj, *obj;
2733104530Srwatson
2734172955Srwatson	if (!biba_enabled)
2735104530Srwatson		return (0);
2736104530Srwatson
2737122524Srwatson	subj = SLOT(cred->cr_label);
2738168976Srwatson	obj = SLOT(dvplabel);
2739104530Srwatson
2740172955Srwatson	if (!biba_dominate_effective(subj, obj))
2741104530Srwatson		return (EACCES);
2742104530Srwatson
2743168976Srwatson	obj = SLOT(vplabel);
2744104530Srwatson
2745172955Srwatson	if (!biba_dominate_effective(subj, obj))
2746104530Srwatson		return (EACCES);
2747104530Srwatson
2748104530Srwatson	return (0);
2749104530Srwatson}
2750104530Srwatson
2751104530Srwatsonstatic int
2752172955Srwatsonbiba_vnode_check_listextattr(struct ucred *cred, struct vnode *vp,
2753168976Srwatson    struct label *vplabel, int attrnamespace)
2754119202Srwatson{
2755119202Srwatson	struct mac_biba *subj, *obj;
2756119202Srwatson
2757172955Srwatson	if (!biba_enabled)
2758119202Srwatson		return (0);
2759119202Srwatson
2760122524Srwatson	subj = SLOT(cred->cr_label);
2761168976Srwatson	obj = SLOT(vplabel);
2762119202Srwatson
2763172955Srwatson	if (!biba_dominate_effective(obj, subj))
2764119202Srwatson		return (EACCES);
2765119202Srwatson
2766119202Srwatson	return (0);
2767119202Srwatson}
2768119202Srwatson
2769119202Srwatsonstatic int
2770172955Srwatsonbiba_vnode_check_lookup(struct ucred *cred, struct vnode *dvp,
2771168976Srwatson    struct label *dvplabel, struct componentname *cnp)
2772101099Srwatson{
2773101099Srwatson	struct mac_biba *subj, *obj;
2774103759Srwatson
2775172955Srwatson	if (!biba_enabled)
2776101099Srwatson		return (0);
2777103759Srwatson
2778122524Srwatson	subj = SLOT(cred->cr_label);
2779168976Srwatson	obj = SLOT(dvplabel);
2780103759Srwatson
2781172955Srwatson	if (!biba_dominate_effective(obj, subj))
2782101099Srwatson		return (EACCES);
2783101099Srwatson
2784103759Srwatson	return (0);
2785101099Srwatson}
2786101099Srwatson
2787101099Srwatsonstatic int
2788172955Srwatsonbiba_vnode_check_mmap(struct ucred *cred, struct vnode *vp,
2789168976Srwatson    struct label *vplabel, int prot, int flags)
2790104546Srwatson{
2791104546Srwatson	struct mac_biba *subj, *obj;
2792104546Srwatson
2793104546Srwatson	/*
2794104546Srwatson	 * Rely on the use of open()-time protections to handle
2795104546Srwatson	 * non-revocation cases.
2796104546Srwatson	 */
2797172955Srwatson	if (!biba_enabled || !revocation_enabled)
2798104546Srwatson		return (0);
2799104546Srwatson
2800122524Srwatson	subj = SLOT(cred->cr_label);
2801168976Srwatson	obj = SLOT(vplabel);
2802104546Srwatson
2803104546Srwatson	if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
2804172955Srwatson		if (!biba_dominate_effective(obj, subj))
2805104546Srwatson			return (EACCES);
2806104546Srwatson	}
2807145076Scsjp	if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) {
2808172955Srwatson		if (!biba_dominate_effective(subj, obj))
2809104546Srwatson			return (EACCES);
2810104546Srwatson	}
2811104546Srwatson
2812104569Srwatson	return (0);
2813104546Srwatson}
2814104546Srwatson
2815104546Srwatsonstatic int
2816172955Srwatsonbiba_vnode_check_open(struct ucred *cred, struct vnode *vp,
2817168976Srwatson    struct label *vplabel, int acc_mode)
2818101099Srwatson{
2819101099Srwatson	struct mac_biba *subj, *obj;
2820101099Srwatson
2821172955Srwatson	if (!biba_enabled)
2822101099Srwatson		return (0);
2823101099Srwatson
2824122524Srwatson	subj = SLOT(cred->cr_label);
2825168976Srwatson	obj = SLOT(vplabel);
2826101099Srwatson
2827101099Srwatson	/* XXX privilege override for admin? */
2828101099Srwatson	if (acc_mode & (VREAD | VEXEC | VSTAT)) {
2829172955Srwatson		if (!biba_dominate_effective(obj, subj))
2830101099Srwatson			return (EACCES);
2831101099Srwatson	}
2832101099Srwatson	if (acc_mode & (VWRITE | VAPPEND | VADMIN)) {
2833172955Srwatson		if (!biba_dominate_effective(subj, obj))
2834101099Srwatson			return (EACCES);
2835101099Srwatson	}
2836101099Srwatson
2837101099Srwatson	return (0);
2838101099Srwatson}
2839101099Srwatson
2840101099Srwatsonstatic int
2841172955Srwatsonbiba_vnode_check_poll(struct ucred *active_cred, struct ucred *file_cred,
2842168976Srwatson    struct vnode *vp, struct label *vplabel)
2843102112Srwatson{
2844102112Srwatson	struct mac_biba *subj, *obj;
2845102112Srwatson
2846172955Srwatson	if (!biba_enabled || !revocation_enabled)
2847102112Srwatson		return (0);
2848102112Srwatson
2849122524Srwatson	subj = SLOT(active_cred->cr_label);
2850168976Srwatson	obj = SLOT(vplabel);
2851102112Srwatson
2852172955Srwatson	if (!biba_dominate_effective(obj, subj))
2853102112Srwatson		return (EACCES);
2854102112Srwatson
2855102112Srwatson	return (0);
2856102112Srwatson}
2857102112Srwatson
2858102112Srwatsonstatic int
2859172955Srwatsonbiba_vnode_check_read(struct ucred *active_cred, struct ucred *file_cred,
2860168976Srwatson    struct vnode *vp, struct label *vplabel)
2861102112Srwatson{
2862102112Srwatson	struct mac_biba *subj, *obj;
2863102112Srwatson
2864172955Srwatson	if (!biba_enabled || !revocation_enabled)
2865102112Srwatson		return (0);
2866102112Srwatson
2867122524Srwatson	subj = SLOT(active_cred->cr_label);
2868168976Srwatson	obj = SLOT(vplabel);
2869102112Srwatson
2870172955Srwatson	if (!biba_dominate_effective(obj, subj))
2871102112Srwatson		return (EACCES);
2872102112Srwatson
2873102112Srwatson	return (0);
2874102112Srwatson}
2875102112Srwatson
2876102112Srwatsonstatic int
2877172955Srwatsonbiba_vnode_check_readdir(struct ucred *cred, struct vnode *dvp,
2878168976Srwatson    struct label *dvplabel)
2879101099Srwatson{
2880101099Srwatson	struct mac_biba *subj, *obj;
2881101099Srwatson
2882172955Srwatson	if (!biba_enabled)
2883101099Srwatson		return (0);
2884101099Srwatson
2885122524Srwatson	subj = SLOT(cred->cr_label);
2886168976Srwatson	obj = SLOT(dvplabel);
2887101099Srwatson
2888172955Srwatson	if (!biba_dominate_effective(obj, subj))
2889101099Srwatson		return (EACCES);
2890101099Srwatson
2891101099Srwatson	return (0);
2892101099Srwatson}
2893101099Srwatson
2894101099Srwatsonstatic int
2895172955Srwatsonbiba_vnode_check_readlink(struct ucred *cred, struct vnode *vp,
2896168976Srwatson    struct label *vplabel)
2897101099Srwatson{
2898101099Srwatson	struct mac_biba *subj, *obj;
2899101099Srwatson
2900172955Srwatson	if (!biba_enabled)
2901101099Srwatson		return (0);
2902101099Srwatson
2903122524Srwatson	subj = SLOT(cred->cr_label);
2904168976Srwatson	obj = SLOT(vplabel);
2905101099Srwatson
2906172955Srwatson	if (!biba_dominate_effective(obj, subj))
2907101099Srwatson		return (EACCES);
2908101099Srwatson
2909101099Srwatson	return (0);
2910101099Srwatson}
2911101099Srwatson
2912101099Srwatsonstatic int
2913172955Srwatsonbiba_vnode_check_relabel(struct ucred *cred, struct vnode *vp,
2914168976Srwatson    struct label *vplabel, struct label *newlabel)
2915101099Srwatson{
2916101099Srwatson	struct mac_biba *old, *new, *subj;
2917105634Srwatson	int error;
2918101099Srwatson
2919168976Srwatson	old = SLOT(vplabel);
2920101099Srwatson	new = SLOT(newlabel);
2921122524Srwatson	subj = SLOT(cred->cr_label);
2922101099Srwatson
2923101099Srwatson	/*
2924105634Srwatson	 * If there is a Biba label update for the vnode, it must be a
2925132232Srwatson	 * effective label.
2926101099Srwatson	 */
2927132232Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE);
2928105634Srwatson	if (error)
2929105634Srwatson		return (error);
2930101099Srwatson
2931101099Srwatson	/*
2932105634Srwatson	 * To perform a relabel of the vnode (Biba label or not), Biba must
2933105634Srwatson	 * authorize the relabel.
2934101099Srwatson	 */
2935172955Srwatson	if (!biba_effective_in_range(old, subj))
2936101099Srwatson		return (EPERM);
2937101099Srwatson
2938101099Srwatson	/*
2939105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
2940101099Srwatson	 */
2941132232Srwatson	if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
2942105634Srwatson		/*
2943105634Srwatson		 * To change the Biba label on a vnode, the new vnode label
2944105634Srwatson		 * must be in the subject range.
2945105634Srwatson		 */
2946172955Srwatson		if (!biba_effective_in_range(new, subj))
2947105634Srwatson			return (EPERM);
2948101099Srwatson
2949105634Srwatson		/*
2950172955Srwatson		 * To change the Biba label on the vnode to be EQUAL, the
2951172955Srwatson		 * subject must have appropriate privilege.
2952105634Srwatson		 */
2953172955Srwatson		if (biba_contains_equal(new)) {
2954172955Srwatson			error = biba_subject_privileged(subj);
2955105634Srwatson			if (error)
2956105634Srwatson				return (error);
2957105634Srwatson		}
2958105634Srwatson	}
2959105634Srwatson
2960105634Srwatson	return (0);
2961101099Srwatson}
2962101099Srwatson
2963101099Srwatsonstatic int
2964172955Srwatsonbiba_vnode_check_rename_from(struct ucred *cred, struct vnode *dvp,
2965168976Srwatson    struct label *dvplabel, struct vnode *vp, struct label *vplabel,
2966101099Srwatson    struct componentname *cnp)
2967101099Srwatson{
2968101099Srwatson	struct mac_biba *subj, *obj;
2969101099Srwatson
2970172955Srwatson	if (!biba_enabled)
2971101099Srwatson		return (0);
2972101099Srwatson
2973122524Srwatson	subj = SLOT(cred->cr_label);
2974168976Srwatson	obj = SLOT(dvplabel);
2975101099Srwatson
2976172955Srwatson	if (!biba_dominate_effective(subj, obj))
2977101099Srwatson		return (EACCES);
2978101099Srwatson
2979168976Srwatson	obj = SLOT(vplabel);
2980101099Srwatson
2981172955Srwatson	if (!biba_dominate_effective(subj, obj))
2982101099Srwatson		return (EACCES);
2983101099Srwatson
2984101099Srwatson	return (0);
2985101099Srwatson}
2986101099Srwatson
2987101099Srwatsonstatic int
2988172955Srwatsonbiba_vnode_check_rename_to(struct ucred *cred, struct vnode *dvp,
2989168976Srwatson    struct label *dvplabel, struct vnode *vp, struct label *vplabel,
2990168976Srwatson    int samedir, struct componentname *cnp)
2991101099Srwatson{
2992101099Srwatson	struct mac_biba *subj, *obj;
2993101099Srwatson
2994172955Srwatson	if (!biba_enabled)
2995101099Srwatson		return (0);
2996101099Srwatson
2997122524Srwatson	subj = SLOT(cred->cr_label);
2998168976Srwatson	obj = SLOT(dvplabel);
2999101099Srwatson
3000172955Srwatson	if (!biba_dominate_effective(subj, obj))
3001101099Srwatson		return (EACCES);
3002101099Srwatson
3003101099Srwatson	if (vp != NULL) {
3004168976Srwatson		obj = SLOT(vplabel);
3005101099Srwatson
3006172955Srwatson		if (!biba_dominate_effective(subj, obj))
3007101099Srwatson			return (EACCES);
3008101099Srwatson	}
3009101099Srwatson
3010101099Srwatson	return (0);
3011101099Srwatson}
3012101099Srwatson
3013101099Srwatsonstatic int
3014172955Srwatsonbiba_vnode_check_revoke(struct ucred *cred, struct vnode *vp,
3015168976Srwatson    struct label *vplabel)
3016101099Srwatson{
3017101099Srwatson	struct mac_biba *subj, *obj;
3018101099Srwatson
3019172955Srwatson	if (!biba_enabled)
3020101099Srwatson		return (0);
3021101099Srwatson
3022122524Srwatson	subj = SLOT(cred->cr_label);
3023168976Srwatson	obj = SLOT(vplabel);
3024101099Srwatson
3025172955Srwatson	if (!biba_dominate_effective(subj, obj))
3026101099Srwatson		return (EACCES);
3027101099Srwatson
3028101099Srwatson	return (0);
3029101099Srwatson}
3030101099Srwatson
3031101099Srwatsonstatic int
3032172955Srwatsonbiba_vnode_check_setacl(struct ucred *cred, struct vnode *vp,
3033168976Srwatson    struct label *vplabel, acl_type_t type, struct acl *acl)
3034101099Srwatson{
3035101099Srwatson	struct mac_biba *subj, *obj;
3036101099Srwatson
3037172955Srwatson	if (!biba_enabled)
3038101099Srwatson		return (0);
3039101099Srwatson
3040122524Srwatson	subj = SLOT(cred->cr_label);
3041168976Srwatson	obj = SLOT(vplabel);
3042101099Srwatson
3043172955Srwatson	if (!biba_dominate_effective(subj, obj))
3044101099Srwatson		return (EACCES);
3045101099Srwatson
3046101099Srwatson	return (0);
3047101099Srwatson}
3048101099Srwatson
3049101099Srwatsonstatic int
3050172955Srwatsonbiba_vnode_check_setextattr(struct ucred *cred, struct vnode *vp,
3051168976Srwatson    struct label *vplabel, int attrnamespace, const char *name,
3052101099Srwatson    struct uio *uio)
3053101099Srwatson{
3054101099Srwatson	struct mac_biba *subj, *obj;
3055101099Srwatson
3056172955Srwatson	if (!biba_enabled)
3057101099Srwatson		return (0);
3058101099Srwatson
3059122524Srwatson	subj = SLOT(cred->cr_label);
3060168976Srwatson	obj = SLOT(vplabel);
3061101099Srwatson
3062172955Srwatson	if (!biba_dominate_effective(subj, obj))
3063101099Srwatson		return (EACCES);
3064101099Srwatson
3065101099Srwatson	/* XXX: protect the MAC EA in a special way? */
3066101099Srwatson
3067101099Srwatson	return (0);
3068101099Srwatson}
3069101099Srwatson
3070101099Srwatsonstatic int
3071172955Srwatsonbiba_vnode_check_setflags(struct ucred *cred, struct vnode *vp,
3072168976Srwatson    struct label *vplabel, u_long flags)
3073101099Srwatson{
3074101099Srwatson	struct mac_biba *subj, *obj;
3075101099Srwatson
3076172955Srwatson	if (!biba_enabled)
3077101099Srwatson		return (0);
3078101099Srwatson
3079122524Srwatson	subj = SLOT(cred->cr_label);
3080168976Srwatson	obj = SLOT(vplabel);
3081101099Srwatson
3082172955Srwatson	if (!biba_dominate_effective(subj, obj))
3083101099Srwatson		return (EACCES);
3084101099Srwatson
3085101099Srwatson	return (0);
3086101099Srwatson}
3087101099Srwatson
3088101099Srwatsonstatic int
3089172955Srwatsonbiba_vnode_check_setmode(struct ucred *cred, struct vnode *vp,
3090168976Srwatson    struct label *vplabel, mode_t mode)
3091101099Srwatson{
3092101099Srwatson	struct mac_biba *subj, *obj;
3093101099Srwatson
3094172955Srwatson	if (!biba_enabled)
3095101099Srwatson		return (0);
3096101099Srwatson
3097122524Srwatson	subj = SLOT(cred->cr_label);
3098168976Srwatson	obj = SLOT(vplabel);
3099101099Srwatson
3100172955Srwatson	if (!biba_dominate_effective(subj, obj))
3101101099Srwatson		return (EACCES);
3102101099Srwatson
3103101099Srwatson	return (0);
3104101099Srwatson}
3105101099Srwatson
3106101099Srwatsonstatic int
3107172955Srwatsonbiba_vnode_check_setowner(struct ucred *cred, struct vnode *vp,
3108168976Srwatson    struct label *vplabel, uid_t uid, gid_t gid)
3109101099Srwatson{
3110101099Srwatson	struct mac_biba *subj, *obj;
3111101099Srwatson
3112172955Srwatson	if (!biba_enabled)
3113101099Srwatson		return (0);
3114101099Srwatson
3115122524Srwatson	subj = SLOT(cred->cr_label);
3116168976Srwatson	obj = SLOT(vplabel);
3117101099Srwatson
3118172955Srwatson	if (!biba_dominate_effective(subj, obj))
3119101099Srwatson		return (EACCES);
3120101099Srwatson
3121101099Srwatson	return (0);
3122101099Srwatson}
3123101099Srwatson
3124101099Srwatsonstatic int
3125172955Srwatsonbiba_vnode_check_setutimes(struct ucred *cred, struct vnode *vp,
3126168976Srwatson    struct label *vplabel, struct timespec atime, struct timespec mtime)
3127101099Srwatson{
3128101099Srwatson	struct mac_biba *subj, *obj;
3129101099Srwatson
3130172955Srwatson	if (!biba_enabled)
3131101099Srwatson		return (0);
3132101099Srwatson
3133122524Srwatson	subj = SLOT(cred->cr_label);
3134168976Srwatson	obj = SLOT(vplabel);
3135101099Srwatson
3136172955Srwatson	if (!biba_dominate_effective(subj, obj))
3137101099Srwatson		return (EACCES);
3138101099Srwatson
3139101099Srwatson	return (0);
3140101099Srwatson}
3141101099Srwatson
3142101099Srwatsonstatic int
3143172955Srwatsonbiba_vnode_check_stat(struct ucred *active_cred, struct ucred *file_cred,
3144168976Srwatson    struct vnode *vp, struct label *vplabel)
3145101099Srwatson{
3146101099Srwatson	struct mac_biba *subj, *obj;
3147101099Srwatson
3148172955Srwatson	if (!biba_enabled)
3149101099Srwatson		return (0);
3150101099Srwatson
3151122524Srwatson	subj = SLOT(active_cred->cr_label);
3152168976Srwatson	obj = SLOT(vplabel);
3153101099Srwatson
3154172955Srwatson	if (!biba_dominate_effective(obj, subj))
3155101099Srwatson		return (EACCES);
3156101099Srwatson
3157101099Srwatson	return (0);
3158101099Srwatson}
3159101099Srwatson
3160102112Srwatsonstatic int
3161172955Srwatsonbiba_vnode_check_unlink(struct ucred *cred, struct vnode *dvp,
3162172107Srwatson    struct label *dvplabel, struct vnode *vp, struct label *vplabel,
3163172107Srwatson    struct componentname *cnp)
3164172107Srwatson{
3165172107Srwatson	struct mac_biba *subj, *obj;
3166172107Srwatson
3167172955Srwatson	if (!biba_enabled)
3168172107Srwatson		return (0);
3169172107Srwatson
3170172107Srwatson	subj = SLOT(cred->cr_label);
3171172107Srwatson	obj = SLOT(dvplabel);
3172172107Srwatson
3173172955Srwatson	if (!biba_dominate_effective(subj, obj))
3174172107Srwatson		return (EACCES);
3175172107Srwatson
3176172107Srwatson	obj = SLOT(vplabel);
3177172107Srwatson
3178172955Srwatson	if (!biba_dominate_effective(subj, obj))
3179172107Srwatson		return (EACCES);
3180172107Srwatson
3181172107Srwatson	return (0);
3182172107Srwatson}
3183172107Srwatson
3184172107Srwatsonstatic int
3185172955Srwatsonbiba_vnode_check_write(struct ucred *active_cred,
3186168976Srwatson    struct ucred *file_cred, struct vnode *vp, struct label *vplabel)
3187102112Srwatson{
3188102112Srwatson	struct mac_biba *subj, *obj;
3189102112Srwatson
3190172955Srwatson	if (!biba_enabled || !revocation_enabled)
3191102112Srwatson		return (0);
3192102112Srwatson
3193122524Srwatson	subj = SLOT(active_cred->cr_label);
3194168976Srwatson	obj = SLOT(vplabel);
3195102112Srwatson
3196172955Srwatson	if (!biba_dominate_effective(subj, obj))
3197102112Srwatson		return (EACCES);
3198102112Srwatson
3199102112Srwatson	return (0);
3200102112Srwatson}
3201102112Srwatson
3202161026Srwatsonstatic void
3203172955Srwatsonbiba_associate_nfsd_label(struct ucred *cred)
3204160243Scsjp{
3205160243Scsjp	struct mac_biba *label;
3206160243Scsjp
3207160243Scsjp	label = SLOT(cred->cr_label);
3208172955Srwatson	biba_set_effective(label, MAC_BIBA_TYPE_LOW, 0, NULL);
3209172955Srwatson	biba_set_range(label, MAC_BIBA_TYPE_LOW, 0, NULL, MAC_BIBA_TYPE_HIGH,
3210172955Srwatson	    0, NULL);
3211160243Scsjp}
3212160243Scsjp
3213165150Scsjpstatic void
3214172955Srwatsonbiba_init_syncache_from_inpcb(struct label *label, struct inpcb *inp)
3215165150Scsjp{
3216165150Scsjp	struct mac_biba *source, *dest;
3217165150Scsjp
3218165150Scsjp	source = SLOT(inp->inp_label);
3219165150Scsjp	dest = SLOT(label);
3220172955Srwatson	biba_copy_effective(source, dest);
3221165150Scsjp}
3222165150Scsjp
3223165150Scsjpstatic void
3224172955Srwatsonbiba_create_mbuf_from_syncache(struct label *sc_label, struct mbuf *m,
3225168976Srwatson    struct label *mlabel)
3226165150Scsjp{
3227165150Scsjp	struct mac_biba *source, *dest;
3228165150Scsjp
3229165150Scsjp	source = SLOT(sc_label);
3230168976Srwatson	dest = SLOT(mlabel);
3231172955Srwatson	biba_copy_effective(source, dest);
3232165150Scsjp}
3233165150Scsjp
3234106217Srwatsonstatic struct mac_policy_ops mac_biba_ops =
3235101099Srwatson{
3236172955Srwatson	.mpo_init = biba_init,
3237172955Srwatson	.mpo_bpfdesc_init_label = biba_init_label,
3238172955Srwatson	.mpo_cred_init_label = biba_init_label,
3239172955Srwatson	.mpo_devfs_init_label = biba_init_label,
3240172955Srwatson	.mpo_ifnet_init_label = biba_init_label,
3241172955Srwatson	.mpo_inpcb_init_label = biba_init_label_waitcheck,
3242172955Srwatson	.mpo_init_syncache_label = biba_init_label_waitcheck,
3243172955Srwatson	.mpo_sysvmsg_init_label = biba_init_label,
3244172955Srwatson	.mpo_sysvmsq_init_label = biba_init_label,
3245172955Srwatson	.mpo_sysvsem_init_label = biba_init_label,
3246172955Srwatson	.mpo_sysvshm_init_label = biba_init_label,
3247172955Srwatson	.mpo_ipq_init_label = biba_init_label_waitcheck,
3248172955Srwatson	.mpo_mbuf_init_label = biba_init_label_waitcheck,
3249172955Srwatson	.mpo_mount_init_label = biba_init_label,
3250172955Srwatson	.mpo_pipe_init_label = biba_init_label,
3251172955Srwatson	.mpo_posixsem_init_label = biba_init_label,
3252172955Srwatson	.mpo_socket_init_label = biba_init_label_waitcheck,
3253172955Srwatson	.mpo_socketpeer_init_label = biba_init_label_waitcheck,
3254172955Srwatson	.mpo_init_syncache_from_inpcb = biba_init_syncache_from_inpcb,
3255172955Srwatson	.mpo_vnode_init_label = biba_init_label,
3256172955Srwatson	.mpo_bpfdesc_destroy_label = biba_destroy_label,
3257172955Srwatson	.mpo_cred_destroy_label = biba_destroy_label,
3258172955Srwatson	.mpo_devfs_destroy_label = biba_destroy_label,
3259172955Srwatson	.mpo_ifnet_destroy_label = biba_destroy_label,
3260172955Srwatson	.mpo_inpcb_destroy_label = biba_destroy_label,
3261172955Srwatson	.mpo_destroy_syncache_label = biba_destroy_label,
3262172955Srwatson	.mpo_sysvmsg_destroy_label = biba_destroy_label,
3263172955Srwatson	.mpo_sysvmsq_destroy_label = biba_destroy_label,
3264172955Srwatson	.mpo_sysvsem_destroy_label = biba_destroy_label,
3265172955Srwatson	.mpo_sysvshm_destroy_label = biba_destroy_label,
3266172955Srwatson	.mpo_ipq_destroy_label = biba_destroy_label,
3267172955Srwatson	.mpo_mbuf_destroy_label = biba_destroy_label,
3268172955Srwatson	.mpo_mount_destroy_label = biba_destroy_label,
3269172955Srwatson	.mpo_pipe_destroy_label = biba_destroy_label,
3270172955Srwatson	.mpo_posixsem_destroy_label = biba_destroy_label,
3271172955Srwatson	.mpo_socket_destroy_label = biba_destroy_label,
3272172955Srwatson	.mpo_socketpeer_destroy_label = biba_destroy_label,
3273172955Srwatson	.mpo_vnode_destroy_label = biba_destroy_label,
3274172955Srwatson	.mpo_cred_copy_label = biba_copy_label,
3275172955Srwatson	.mpo_ifnet_copy_label = biba_copy_label,
3276172955Srwatson	.mpo_mbuf_copy_label = biba_copy_label,
3277172955Srwatson	.mpo_pipe_copy_label = biba_copy_label,
3278172955Srwatson	.mpo_socket_copy_label = biba_copy_label,
3279172955Srwatson	.mpo_vnode_copy_label = biba_copy_label,
3280172955Srwatson	.mpo_cred_externalize_label = biba_externalize_label,
3281172955Srwatson	.mpo_ifnet_externalize_label = biba_externalize_label,
3282172955Srwatson	.mpo_pipe_externalize_label = biba_externalize_label,
3283172955Srwatson	.mpo_socket_externalize_label = biba_externalize_label,
3284172955Srwatson	.mpo_socketpeer_externalize_label = biba_externalize_label,
3285172955Srwatson	.mpo_vnode_externalize_label = biba_externalize_label,
3286172955Srwatson	.mpo_cred_internalize_label = biba_internalize_label,
3287172955Srwatson	.mpo_ifnet_internalize_label = biba_internalize_label,
3288172955Srwatson	.mpo_pipe_internalize_label = biba_internalize_label,
3289172955Srwatson	.mpo_socket_internalize_label = biba_internalize_label,
3290172955Srwatson	.mpo_vnode_internalize_label = biba_internalize_label,
3291172955Srwatson	.mpo_devfs_create_device = biba_devfs_create_device,
3292172955Srwatson	.mpo_devfs_create_directory = biba_devfs_create_directory,
3293172955Srwatson	.mpo_devfs_create_symlink = biba_devfs_create_symlink,
3294172955Srwatson	.mpo_mount_create = biba_mount_create,
3295172955Srwatson	.mpo_vnode_relabel = biba_vnode_relabel,
3296172955Srwatson	.mpo_devfs_update = biba_devfs_update,
3297172955Srwatson	.mpo_devfs_vnode_associate = biba_devfs_vnode_associate,
3298172955Srwatson	.mpo_vnode_associate_extattr = biba_vnode_associate_extattr,
3299172955Srwatson	.mpo_vnode_associate_singlelabel = biba_vnode_associate_singlelabel,
3300172955Srwatson	.mpo_vnode_create_extattr = biba_vnode_create_extattr,
3301172955Srwatson	.mpo_vnode_setlabel_extattr = biba_vnode_setlabel_extattr,
3302172955Srwatson	.mpo_socket_create_mbuf = biba_socket_create_mbuf,
3303172955Srwatson	.mpo_create_mbuf_from_syncache = biba_create_mbuf_from_syncache,
3304172955Srwatson	.mpo_pipe_create = biba_pipe_create,
3305172955Srwatson	.mpo_posixsem_create = biba_posixsem_create,
3306172955Srwatson	.mpo_socket_create = biba_socket_create,
3307172955Srwatson	.mpo_socket_newconn = biba_socket_newconn,
3308172955Srwatson	.mpo_pipe_relabel = biba_pipe_relabel,
3309172955Srwatson	.mpo_socket_relabel = biba_socket_relabel,
3310172955Srwatson	.mpo_socketpeer_set_from_mbuf = biba_socketpeer_set_from_mbuf,
3311172955Srwatson	.mpo_socketpeer_set_from_socket = biba_socketpeer_set_from_socket,
3312172955Srwatson	.mpo_bpfdesc_create = biba_bpfdesc_create,
3313172955Srwatson	.mpo_ipq_reassemble = biba_ipq_reassemble,
3314172955Srwatson	.mpo_netinet_fragment = biba_netinet_fragment,
3315172955Srwatson	.mpo_ifnet_create = biba_ifnet_create,
3316172955Srwatson	.mpo_inpcb_create = biba_inpcb_create,
3317172955Srwatson	.mpo_sysvmsg_create = biba_sysvmsg_create,
3318172955Srwatson	.mpo_sysvmsq_create = biba_sysvmsq_create,
3319172955Srwatson	.mpo_sysvsem_create = biba_sysvsem_create,
3320172955Srwatson	.mpo_sysvshm_create = biba_sysvshm_create,
3321172955Srwatson	.mpo_ipq_create = biba_ipq_create,
3322172955Srwatson	.mpo_inpcb_create_mbuf = biba_inpcb_create_mbuf,
3323172955Srwatson	.mpo_create_mbuf_linklayer = biba_create_mbuf_linklayer,
3324172955Srwatson	.mpo_bpfdesc_create_mbuf = biba_bpfdesc_create_mbuf,
3325172955Srwatson	.mpo_ifnet_create_mbuf = biba_ifnet_create_mbuf,
3326172955Srwatson	.mpo_mbuf_create_multicast_encap = biba_mbuf_create_multicast_encap,
3327172955Srwatson	.mpo_mbuf_create_netlayer = biba_mbuf_create_netlayer,
3328172955Srwatson	.mpo_ipq_match = biba_ipq_match,
3329172955Srwatson	.mpo_ifnet_relabel = biba_ifnet_relabel,
3330172955Srwatson	.mpo_ipq_update = biba_ipq_update,
3331172955Srwatson	.mpo_inpcb_sosetlabel = biba_inpcb_sosetlabel,
3332172955Srwatson	.mpo_proc_create_swapper = biba_proc_create_swapper,
3333172955Srwatson	.mpo_proc_create_init = biba_proc_create_init,
3334172955Srwatson	.mpo_cred_relabel = biba_cred_relabel,
3335172955Srwatson	.mpo_sysvmsg_cleanup = biba_sysvmsg_cleanup,
3336172955Srwatson	.mpo_sysvmsq_cleanup = biba_sysvmsq_cleanup,
3337172955Srwatson	.mpo_sysvsem_cleanup = biba_sysvsem_cleanup,
3338172955Srwatson	.mpo_sysvshm_cleanup = biba_sysvshm_cleanup,
3339172955Srwatson	.mpo_bpfdesc_check_receive = biba_bpfdesc_check_receive,
3340172955Srwatson	.mpo_cred_check_relabel = biba_cred_check_relabel,
3341172955Srwatson	.mpo_cred_check_visible = biba_cred_check_visible,
3342172955Srwatson	.mpo_ifnet_check_relabel = biba_ifnet_check_relabel,
3343172955Srwatson	.mpo_ifnet_check_transmit = biba_ifnet_check_transmit,
3344172955Srwatson	.mpo_inpcb_check_deliver = biba_inpcb_check_deliver,
3345172955Srwatson	.mpo_sysvmsq_check_msgrcv = biba_sysvmsq_check_msgrcv,
3346172955Srwatson	.mpo_sysvmsq_check_msgrmid = biba_sysvmsq_check_msgrmid,
3347172955Srwatson	.mpo_sysvmsq_check_msqget = biba_sysvmsq_check_msqget,
3348172955Srwatson	.mpo_sysvmsq_check_msqsnd = biba_sysvmsq_check_msqsnd,
3349172955Srwatson	.mpo_sysvmsq_check_msqrcv = biba_sysvmsq_check_msqrcv,
3350172955Srwatson	.mpo_sysvmsq_check_msqctl = biba_sysvmsq_check_msqctl,
3351172955Srwatson	.mpo_sysvsem_check_semctl = biba_sysvsem_check_semctl,
3352172955Srwatson	.mpo_sysvsem_check_semget = biba_sysvsem_check_semget,
3353172955Srwatson	.mpo_sysvsem_check_semop = biba_sysvsem_check_semop,
3354172955Srwatson	.mpo_sysvshm_check_shmat = biba_sysvshm_check_shmat,
3355172955Srwatson	.mpo_sysvshm_check_shmctl = biba_sysvshm_check_shmctl,
3356172955Srwatson	.mpo_sysvshm_check_shmget = biba_sysvshm_check_shmget,
3357172955Srwatson	.mpo_kld_check_load = biba_kld_check_load,
3358172955Srwatson	.mpo_mount_check_stat = biba_mount_check_stat,
3359172955Srwatson	.mpo_pipe_check_ioctl = biba_pipe_check_ioctl,
3360172955Srwatson	.mpo_pipe_check_poll = biba_pipe_check_poll,
3361172955Srwatson	.mpo_pipe_check_read = biba_pipe_check_read,
3362172955Srwatson	.mpo_pipe_check_relabel = biba_pipe_check_relabel,
3363172955Srwatson	.mpo_pipe_check_stat = biba_pipe_check_stat,
3364172955Srwatson	.mpo_pipe_check_write = biba_pipe_check_write,
3365172955Srwatson	.mpo_posixsem_check_destroy = biba_posixsem_check_write,
3366172955Srwatson	.mpo_posixsem_check_getvalue = biba_posixsem_check_rdonly,
3367172955Srwatson	.mpo_posixsem_check_open = biba_posixsem_check_write,
3368172955Srwatson	.mpo_posixsem_check_post = biba_posixsem_check_write,
3369172955Srwatson	.mpo_posixsem_check_unlink = biba_posixsem_check_write,
3370172955Srwatson	.mpo_posixsem_check_wait = biba_posixsem_check_write,
3371172955Srwatson	.mpo_proc_check_debug = biba_proc_check_debug,
3372172955Srwatson	.mpo_proc_check_sched = biba_proc_check_sched,
3373172955Srwatson	.mpo_proc_check_signal = biba_proc_check_signal,
3374172955Srwatson	.mpo_socket_check_deliver = biba_socket_check_deliver,
3375172955Srwatson	.mpo_socket_check_relabel = biba_socket_check_relabel,
3376172955Srwatson	.mpo_socket_check_visible = biba_socket_check_visible,
3377172955Srwatson	.mpo_system_check_acct = biba_system_check_acct,
3378172955Srwatson	.mpo_system_check_auditctl = biba_system_check_auditctl,
3379172955Srwatson	.mpo_system_check_auditon = biba_system_check_auditon,
3380172955Srwatson	.mpo_system_check_swapon = biba_system_check_swapon,
3381172955Srwatson	.mpo_system_check_swapoff = biba_system_check_swapoff,
3382172955Srwatson	.mpo_system_check_sysctl = biba_system_check_sysctl,
3383172955Srwatson	.mpo_vnode_check_access = biba_vnode_check_open,
3384172955Srwatson	.mpo_vnode_check_chdir = biba_vnode_check_chdir,
3385172955Srwatson	.mpo_vnode_check_chroot = biba_vnode_check_chroot,
3386172955Srwatson	.mpo_vnode_check_create = biba_vnode_check_create,
3387172955Srwatson	.mpo_vnode_check_deleteacl = biba_vnode_check_deleteacl,
3388172955Srwatson	.mpo_vnode_check_deleteextattr = biba_vnode_check_deleteextattr,
3389172955Srwatson	.mpo_vnode_check_exec = biba_vnode_check_exec,
3390172955Srwatson	.mpo_vnode_check_getacl = biba_vnode_check_getacl,
3391172955Srwatson	.mpo_vnode_check_getextattr = biba_vnode_check_getextattr,
3392172955Srwatson	.mpo_vnode_check_link = biba_vnode_check_link,
3393172955Srwatson	.mpo_vnode_check_listextattr = biba_vnode_check_listextattr,
3394172955Srwatson	.mpo_vnode_check_lookup = biba_vnode_check_lookup,
3395172955Srwatson	.mpo_vnode_check_mmap = biba_vnode_check_mmap,
3396172955Srwatson	.mpo_vnode_check_open = biba_vnode_check_open,
3397172955Srwatson	.mpo_vnode_check_poll = biba_vnode_check_poll,
3398172955Srwatson	.mpo_vnode_check_read = biba_vnode_check_read,
3399172955Srwatson	.mpo_vnode_check_readdir = biba_vnode_check_readdir,
3400172955Srwatson	.mpo_vnode_check_readlink = biba_vnode_check_readlink,
3401172955Srwatson	.mpo_vnode_check_relabel = biba_vnode_check_relabel,
3402172955Srwatson	.mpo_vnode_check_rename_from = biba_vnode_check_rename_from,
3403172955Srwatson	.mpo_vnode_check_rename_to = biba_vnode_check_rename_to,
3404172955Srwatson	.mpo_vnode_check_revoke = biba_vnode_check_revoke,
3405172955Srwatson	.mpo_vnode_check_setacl = biba_vnode_check_setacl,
3406172955Srwatson	.mpo_vnode_check_setextattr = biba_vnode_check_setextattr,
3407172955Srwatson	.mpo_vnode_check_setflags = biba_vnode_check_setflags,
3408172955Srwatson	.mpo_vnode_check_setmode = biba_vnode_check_setmode,
3409172955Srwatson	.mpo_vnode_check_setowner = biba_vnode_check_setowner,
3410172955Srwatson	.mpo_vnode_check_setutimes = biba_vnode_check_setutimes,
3411172955Srwatson	.mpo_vnode_check_stat = biba_vnode_check_stat,
3412172955Srwatson	.mpo_vnode_check_unlink = biba_vnode_check_unlink,
3413172955Srwatson	.mpo_vnode_check_write = biba_vnode_check_write,
3414172955Srwatson	.mpo_associate_nfsd_label = biba_associate_nfsd_label,
3415172955Srwatson	.mpo_mbuf_create_from_firewall = biba_mbuf_create_from_firewall,
3416172955Srwatson	.mpo_priv_check = biba_priv_check,
3417101099Srwatson};
3418101099Srwatson
3419112717SrwatsonMAC_POLICY_SET(&mac_biba_ops, mac_biba, "TrustedBSD MAC/Biba",
3420172955Srwatson    MPC_LOADTIME_FLAG_NOTLATE | MPC_LOADTIME_FLAG_LABELMBUFS, &biba_slot);
3421