1101099Srwatson/*-
2225344Srwatson * Copyright (c) 1999-2002, 2007-2011 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 *
17225344Srwatson * This software was developed at the University of Cambridge Computer
18225344Srwatson * Laboratory with support from a grant from Google, Inc.
19225344Srwatson *
20101099Srwatson * Redistribution and use in source and binary forms, with or without
21101099Srwatson * modification, are permitted provided that the following conditions
22101099Srwatson * are met:
23101099Srwatson * 1. Redistributions of source code must retain the above copyright
24101099Srwatson *    notice, this list of conditions and the following disclaimer.
25101099Srwatson * 2. Redistributions in binary form must reproduce the above copyright
26101099Srwatson *    notice, this list of conditions and the following disclaimer in the
27101099Srwatson *    documentation and/or other materials provided with the distribution.
28101099Srwatson *
29101099Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
30101099Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31101099Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32101099Srwatson * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
33101099Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34101099Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35101099Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36101099Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37101099Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
38101099Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
39101099Srwatson * SUCH DAMAGE.
40101099Srwatson *
41101099Srwatson * $FreeBSD$
42101099Srwatson */
43101099Srwatson
44101099Srwatson/*
45101099Srwatson * Developed by the TrustedBSD Project.
46168951Srwatson *
47101099Srwatson * Biba fixed label mandatory integrity policy.
48101099Srwatson */
49101099Srwatson
50101099Srwatson#include <sys/param.h>
51101099Srwatson#include <sys/conf.h>
52105988Srwatson#include <sys/extattr.h>
53101099Srwatson#include <sys/kernel.h>
54164184Strhodes#include <sys/ksem.h>
55103183Sbde#include <sys/malloc.h>
56145076Scsjp#include <sys/mman.h>
57101099Srwatson#include <sys/mount.h>
58168951Srwatson#include <sys/priv.h>
59101099Srwatson#include <sys/proc.h>
60115497Srwatson#include <sys/sbuf.h>
61101099Srwatson#include <sys/systm.h>
62101099Srwatson#include <sys/sysproto.h>
63101099Srwatson#include <sys/sysent.h>
64105696Srwatson#include <sys/systm.h>
65101099Srwatson#include <sys/vnode.h>
66101099Srwatson#include <sys/file.h>
67101099Srwatson#include <sys/socket.h>
68101099Srwatson#include <sys/socketvar.h>
69101099Srwatson#include <sys/pipe.h>
70150340Sphk#include <sys/sx.h>
71101099Srwatson#include <sys/sysctl.h>
72140628Srwatson#include <sys/msg.h>
73140628Srwatson#include <sys/sem.h>
74140628Srwatson#include <sys/shm.h>
75101099Srwatson
76101099Srwatson#include <fs/devfs/devfs.h>
77101099Srwatson
78101099Srwatson#include <net/bpfdesc.h>
79101099Srwatson#include <net/if.h>
80101099Srwatson#include <net/if_types.h>
81101099Srwatson#include <net/if_var.h>
82101099Srwatson
83101099Srwatson#include <netinet/in.h>
84122875Srwatson#include <netinet/in_pcb.h>
85101099Srwatson#include <netinet/ip_var.h>
86101099Srwatson
87122879Srwatson#include <vm/uma.h>
88101099Srwatson#include <vm/vm.h>
89101099Srwatson
90165469Srwatson#include <security/mac/mac_policy.h>
91101099Srwatson#include <security/mac_biba/mac_biba.h>
92101099Srwatson
93101099SrwatsonSYSCTL_DECL(_security_mac);
94101099Srwatson
95227309Sedstatic SYSCTL_NODE(_security_mac, OID_AUTO, biba, CTLFLAG_RW, 0,
96101099Srwatson    "TrustedBSD mac_biba policy controls");
97101099Srwatson
98172955Srwatsonstatic int	biba_label_size = sizeof(struct mac_biba);
99105988SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, label_size, CTLFLAG_RD,
100172955Srwatson    &biba_label_size, 0, "Size of struct mac_biba");
101105988Srwatson
102172955Srwatsonstatic int	biba_enabled = 1;
103267992ShselaskySYSCTL_INT(_security_mac_biba, OID_AUTO, enabled, CTLFLAG_RWTUN, &biba_enabled,
104172955Srwatson    0, "Enforce MAC/Biba policy");
105101099Srwatson
106101099Srwatsonstatic int	destroyed_not_inited;
107101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, destroyed_not_inited, CTLFLAG_RD,
108101099Srwatson    &destroyed_not_inited, 0, "Count of labels destroyed but not inited");
109101099Srwatson
110101099Srwatsonstatic int	trust_all_interfaces = 0;
111267992ShselaskySYSCTL_INT(_security_mac_biba, OID_AUTO, trust_all_interfaces, CTLFLAG_RDTUN,
112101099Srwatson    &trust_all_interfaces, 0, "Consider all interfaces 'trusted' by MAC/Biba");
113101099Srwatson
114101099Srwatsonstatic char	trusted_interfaces[128];
115267992ShselaskySYSCTL_STRING(_security_mac_biba, OID_AUTO, trusted_interfaces, CTLFLAG_RDTUN,
116101099Srwatson    trusted_interfaces, 0, "Interfaces considered 'trusted' by MAC/Biba");
117101099Srwatson
118105643Srwatsonstatic int	max_compartments = MAC_BIBA_MAX_COMPARTMENTS;
119105643SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, max_compartments, CTLFLAG_RD,
120105643Srwatson    &max_compartments, 0, "Maximum supported compartments");
121105643Srwatson
122105606Srwatsonstatic int	ptys_equal = 0;
123267992ShselaskySYSCTL_INT(_security_mac_biba, OID_AUTO, ptys_equal, CTLFLAG_RWTUN, &ptys_equal,
124181217Srwatson    0, "Label pty devices as biba/equal on create");
125105606Srwatson
126193371Srwatsonstatic int	interfaces_equal = 1;
127267992ShselaskySYSCTL_INT(_security_mac_biba, OID_AUTO, interfaces_equal, CTLFLAG_RWTUN,
128153927Scsjp    &interfaces_equal, 0, "Label network interfaces as biba/equal on create");
129153927Scsjp
130105637Srwatsonstatic int	revocation_enabled = 0;
131267992ShselaskySYSCTL_INT(_security_mac_biba, OID_AUTO, revocation_enabled, CTLFLAG_RWTUN,
132105637Srwatson    &revocation_enabled, 0, "Revoke access to objects on relabel");
133101099Srwatson
134172955Srwatsonstatic int	biba_slot;
135172955Srwatson#define	SLOT(l)	((struct mac_biba *)mac_label_get((l), biba_slot))
136172955Srwatson#define	SLOT_SET(l, val) mac_label_set((l), biba_slot, (uintptr_t)(val))
137101099Srwatson
138122879Srwatsonstatic uma_zone_t	zone_biba;
139101099Srwatson
140105643Srwatsonstatic __inline int
141105643Srwatsonbiba_bit_set_empty(u_char *set) {
142105643Srwatson	int i;
143105643Srwatson
144105643Srwatson	for (i = 0; i < MAC_BIBA_MAX_COMPARTMENTS >> 3; i++)
145105643Srwatson		if (set[i] != 0)
146105643Srwatson			return (0);
147105643Srwatson	return (1);
148105643Srwatson}
149105643Srwatson
150101099Srwatsonstatic struct mac_biba *
151104514Srwatsonbiba_alloc(int flag)
152101099Srwatson{
153101099Srwatson
154122879Srwatson	return (uma_zalloc(zone_biba, flag | M_ZERO));
155101099Srwatson}
156101099Srwatson
157101099Srwatsonstatic void
158172955Srwatsonbiba_free(struct mac_biba *mb)
159101099Srwatson{
160101099Srwatson
161172955Srwatson	if (mb != NULL)
162172955Srwatson		uma_zfree(zone_biba, mb);
163101099Srwatson	else
164101099Srwatson		atomic_add_int(&destroyed_not_inited, 1);
165101099Srwatson}
166101099Srwatson
167101099Srwatsonstatic int
168172955Srwatsonbiba_atmostflags(struct mac_biba *mb, int flags)
169105634Srwatson{
170105634Srwatson
171172955Srwatson	if ((mb->mb_flags & flags) != mb->mb_flags)
172105634Srwatson		return (EINVAL);
173105634Srwatson	return (0);
174105634Srwatson}
175105634Srwatson
176105634Srwatsonstatic int
177172955Srwatsonbiba_dominate_element(struct mac_biba_element *a, struct mac_biba_element *b)
178101099Srwatson{
179105643Srwatson	int bit;
180101099Srwatson
181105736Srwatson	switch (a->mbe_type) {
182101099Srwatson	case MAC_BIBA_TYPE_EQUAL:
183101099Srwatson	case MAC_BIBA_TYPE_HIGH:
184101099Srwatson		return (1);
185101099Srwatson
186101099Srwatson	case MAC_BIBA_TYPE_LOW:
187101099Srwatson		switch (b->mbe_type) {
188101099Srwatson		case MAC_BIBA_TYPE_GRADE:
189101099Srwatson		case MAC_BIBA_TYPE_HIGH:
190101099Srwatson			return (0);
191101099Srwatson
192101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
193101099Srwatson		case MAC_BIBA_TYPE_LOW:
194101099Srwatson			return (1);
195101099Srwatson
196101099Srwatson		default:
197172955Srwatson			panic("biba_dominate_element: b->mbe_type invalid");
198101099Srwatson		}
199101099Srwatson
200101099Srwatson	case MAC_BIBA_TYPE_GRADE:
201101099Srwatson		switch (b->mbe_type) {
202101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
203101099Srwatson		case MAC_BIBA_TYPE_LOW:
204101099Srwatson			return (1);
205101099Srwatson
206101099Srwatson		case MAC_BIBA_TYPE_HIGH:
207101099Srwatson			return (0);
208101099Srwatson
209101099Srwatson		case MAC_BIBA_TYPE_GRADE:
210105643Srwatson			for (bit = 1; bit <= MAC_BIBA_MAX_COMPARTMENTS; bit++)
211105643Srwatson				if (!MAC_BIBA_BIT_TEST(bit,
212105643Srwatson				    a->mbe_compartments) &&
213105643Srwatson				    MAC_BIBA_BIT_TEST(bit, b->mbe_compartments))
214105643Srwatson					return (0);
215101099Srwatson			return (a->mbe_grade >= b->mbe_grade);
216101099Srwatson
217101099Srwatson		default:
218172955Srwatson			panic("biba_dominate_element: b->mbe_type invalid");
219101099Srwatson		}
220101099Srwatson
221101099Srwatson	default:
222172955Srwatson		panic("biba_dominate_element: a->mbe_type invalid");
223101099Srwatson	}
224101099Srwatson
225101099Srwatson	return (0);
226101099Srwatson}
227101099Srwatson
228101099Srwatsonstatic int
229172955Srwatsonbiba_subject_dominate_high(struct mac_biba *mb)
230105988Srwatson{
231105988Srwatson	struct mac_biba_element *element;
232105988Srwatson
233172955Srwatson	KASSERT((mb->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
234172955Srwatson	    ("biba_effective_in_range: mb not effective"));
235172955Srwatson	element = &mb->mb_effective;
236105988Srwatson
237105988Srwatson	return (element->mbe_type == MAC_BIBA_TYPE_EQUAL ||
238105988Srwatson	    element->mbe_type == MAC_BIBA_TYPE_HIGH);
239105988Srwatson}
240105988Srwatson
241105988Srwatsonstatic int
242172955Srwatsonbiba_range_in_range(struct mac_biba *rangea, struct mac_biba *rangeb)
243101099Srwatson{
244101099Srwatson
245172955Srwatson	return (biba_dominate_element(&rangeb->mb_rangehigh,
246101099Srwatson	    &rangea->mb_rangehigh) &&
247172955Srwatson	    biba_dominate_element(&rangea->mb_rangelow,
248101099Srwatson	    &rangeb->mb_rangelow));
249101099Srwatson}
250101099Srwatson
251101099Srwatsonstatic int
252172955Srwatsonbiba_effective_in_range(struct mac_biba *effective, struct mac_biba *range)
253101099Srwatson{
254101099Srwatson
255132232Srwatson	KASSERT((effective->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
256172955Srwatson	    ("biba_effective_in_range: a not effective"));
257103750Srwatson	KASSERT((range->mb_flags & MAC_BIBA_FLAG_RANGE) != 0,
258172955Srwatson	    ("biba_effective_in_range: b not range"));
259101099Srwatson
260172955Srwatson	return (biba_dominate_element(&range->mb_rangehigh,
261132232Srwatson	    &effective->mb_effective) &&
262172955Srwatson	    biba_dominate_element(&effective->mb_effective,
263101099Srwatson	    &range->mb_rangelow));
264101099Srwatson
265101099Srwatson	return (1);
266101099Srwatson}
267101099Srwatson
268101099Srwatsonstatic int
269172955Srwatsonbiba_dominate_effective(struct mac_biba *a, struct mac_biba *b)
270101099Srwatson{
271132232Srwatson	KASSERT((a->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
272172955Srwatson	    ("biba_dominate_effective: a not effective"));
273132232Srwatson	KASSERT((b->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
274172955Srwatson	    ("biba_dominate_effective: b not effective"));
275101099Srwatson
276172955Srwatson	return (biba_dominate_element(&a->mb_effective, &b->mb_effective));
277101099Srwatson}
278101099Srwatson
279101099Srwatsonstatic int
280172955Srwatsonbiba_equal_element(struct mac_biba_element *a, struct mac_biba_element *b)
281101099Srwatson{
282101099Srwatson
283101099Srwatson	if (a->mbe_type == MAC_BIBA_TYPE_EQUAL ||
284101099Srwatson	    b->mbe_type == MAC_BIBA_TYPE_EQUAL)
285101099Srwatson		return (1);
286101099Srwatson
287101099Srwatson	return (a->mbe_type == b->mbe_type && a->mbe_grade == b->mbe_grade);
288101099Srwatson}
289101099Srwatson
290101099Srwatsonstatic int
291172955Srwatsonbiba_equal_effective(struct mac_biba *a, struct mac_biba *b)
292101099Srwatson{
293101099Srwatson
294132232Srwatson	KASSERT((a->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
295172955Srwatson	    ("biba_equal_effective: a not effective"));
296132232Srwatson	KASSERT((b->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
297172955Srwatson	    ("biba_equal_effective: b not effective"));
298101099Srwatson
299172955Srwatson	return (biba_equal_element(&a->mb_effective, &b->mb_effective));
300101099Srwatson}
301101099Srwatson
302101099Srwatsonstatic int
303172955Srwatsonbiba_contains_equal(struct mac_biba *mb)
304105634Srwatson{
305105634Srwatson
306172955Srwatson	if (mb->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
307172955Srwatson		if (mb->mb_effective.mbe_type == MAC_BIBA_TYPE_EQUAL)
308105634Srwatson			return (1);
309172955Srwatson	}
310105634Srwatson
311172955Srwatson	if (mb->mb_flags & MAC_BIBA_FLAG_RANGE) {
312172955Srwatson		if (mb->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL)
313105634Srwatson			return (1);
314172955Srwatson		if (mb->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL)
315105637Srwatson			return (1);
316105634Srwatson	}
317105634Srwatson
318105634Srwatson	return (0);
319105634Srwatson}
320105634Srwatson
321105634Srwatsonstatic int
322172955Srwatsonbiba_subject_privileged(struct mac_biba *mb)
323105634Srwatson{
324105634Srwatson
325172955Srwatson	KASSERT((mb->mb_flags & MAC_BIBA_FLAGS_BOTH) == MAC_BIBA_FLAGS_BOTH,
326172955Srwatson	    ("biba_subject_privileged: subject doesn't have both labels"));
327105634Srwatson
328132232Srwatson	/* If the effective is EQUAL, it's ok. */
329172955Srwatson	if (mb->mb_effective.mbe_type == MAC_BIBA_TYPE_EQUAL)
330105634Srwatson		return (0);
331105634Srwatson
332105634Srwatson	/* If either range endpoint is EQUAL, it's ok. */
333172955Srwatson	if (mb->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL ||
334172955Srwatson	    mb->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL)
335105634Srwatson		return (0);
336105634Srwatson
337105634Srwatson	/* If the range is low-high, it's ok. */
338172955Srwatson	if (mb->mb_rangelow.mbe_type == MAC_BIBA_TYPE_LOW &&
339172955Srwatson	    mb->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_HIGH)
340105634Srwatson		return (0);
341105634Srwatson
342105634Srwatson	/* It's not ok. */
343105634Srwatson	return (EPERM);
344105634Srwatson}
345105634Srwatson
346106091Srwatsonstatic int
347172955Srwatsonbiba_high_effective(struct mac_biba *mb)
348105988Srwatson{
349105988Srwatson
350172955Srwatson	KASSERT((mb->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
351172955Srwatson	    ("biba_equal_effective: mb not effective"));
352105988Srwatson
353172955Srwatson	return (mb->mb_effective.mbe_type == MAC_BIBA_TYPE_HIGH);
354105988Srwatson}
355105988Srwatson
356105634Srwatsonstatic int
357172955Srwatsonbiba_valid(struct mac_biba *mb)
358101099Srwatson{
359101099Srwatson
360172955Srwatson	if (mb->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
361172955Srwatson		switch (mb->mb_effective.mbe_type) {
362101099Srwatson		case MAC_BIBA_TYPE_GRADE:
363101099Srwatson			break;
364101099Srwatson
365101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
366101099Srwatson		case MAC_BIBA_TYPE_HIGH:
367101099Srwatson		case MAC_BIBA_TYPE_LOW:
368172955Srwatson			if (mb->mb_effective.mbe_grade != 0 ||
369105643Srwatson			    !MAC_BIBA_BIT_SET_EMPTY(
370172955Srwatson			    mb->mb_effective.mbe_compartments))
371101099Srwatson				return (EINVAL);
372101099Srwatson			break;
373101099Srwatson
374101099Srwatson		default:
375101099Srwatson			return (EINVAL);
376101099Srwatson		}
377101099Srwatson	} else {
378172955Srwatson		if (mb->mb_effective.mbe_type != MAC_BIBA_TYPE_UNDEF)
379101099Srwatson			return (EINVAL);
380101099Srwatson	}
381101099Srwatson
382172955Srwatson	if (mb->mb_flags & MAC_BIBA_FLAG_RANGE) {
383172955Srwatson		switch (mb->mb_rangelow.mbe_type) {
384101099Srwatson		case MAC_BIBA_TYPE_GRADE:
385101099Srwatson			break;
386101099Srwatson
387101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
388101099Srwatson		case MAC_BIBA_TYPE_HIGH:
389101099Srwatson		case MAC_BIBA_TYPE_LOW:
390172955Srwatson			if (mb->mb_rangelow.mbe_grade != 0 ||
391105643Srwatson			    !MAC_BIBA_BIT_SET_EMPTY(
392172955Srwatson			    mb->mb_rangelow.mbe_compartments))
393101099Srwatson				return (EINVAL);
394101099Srwatson			break;
395101099Srwatson
396101099Srwatson		default:
397101099Srwatson			return (EINVAL);
398101099Srwatson		}
399101099Srwatson
400172955Srwatson		switch (mb->mb_rangehigh.mbe_type) {
401101099Srwatson		case MAC_BIBA_TYPE_GRADE:
402101099Srwatson			break;
403101099Srwatson
404101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
405101099Srwatson		case MAC_BIBA_TYPE_HIGH:
406101099Srwatson		case MAC_BIBA_TYPE_LOW:
407172955Srwatson			if (mb->mb_rangehigh.mbe_grade != 0 ||
408105643Srwatson			    !MAC_BIBA_BIT_SET_EMPTY(
409172955Srwatson			    mb->mb_rangehigh.mbe_compartments))
410101099Srwatson				return (EINVAL);
411101099Srwatson			break;
412101099Srwatson
413101099Srwatson		default:
414101099Srwatson			return (EINVAL);
415101099Srwatson		}
416172955Srwatson		if (!biba_dominate_element(&mb->mb_rangehigh,
417172955Srwatson		    &mb->mb_rangelow))
418101099Srwatson			return (EINVAL);
419101099Srwatson	} else {
420172955Srwatson		if (mb->mb_rangelow.mbe_type != MAC_BIBA_TYPE_UNDEF ||
421172955Srwatson		    mb->mb_rangehigh.mbe_type != MAC_BIBA_TYPE_UNDEF)
422101099Srwatson			return (EINVAL);
423101099Srwatson	}
424101099Srwatson
425101099Srwatson	return (0);
426101099Srwatson}
427101099Srwatson
428101099Srwatsonstatic void
429172955Srwatsonbiba_set_range(struct mac_biba *mb, u_short typelow, u_short gradelow,
430172955Srwatson    u_char *compartmentslow, u_short typehigh, u_short gradehigh,
431172955Srwatson    u_char *compartmentshigh)
432101099Srwatson{
433101099Srwatson
434172955Srwatson	mb->mb_rangelow.mbe_type = typelow;
435172955Srwatson	mb->mb_rangelow.mbe_grade = gradelow;
436105643Srwatson	if (compartmentslow != NULL)
437172955Srwatson		memcpy(mb->mb_rangelow.mbe_compartments, compartmentslow,
438172955Srwatson		    sizeof(mb->mb_rangelow.mbe_compartments));
439172955Srwatson	mb->mb_rangehigh.mbe_type = typehigh;
440172955Srwatson	mb->mb_rangehigh.mbe_grade = gradehigh;
441105643Srwatson	if (compartmentshigh != NULL)
442172955Srwatson		memcpy(mb->mb_rangehigh.mbe_compartments, compartmentshigh,
443172955Srwatson		    sizeof(mb->mb_rangehigh.mbe_compartments));
444172955Srwatson	mb->mb_flags |= MAC_BIBA_FLAG_RANGE;
445101099Srwatson}
446101099Srwatson
447101099Srwatsonstatic void
448172955Srwatsonbiba_set_effective(struct mac_biba *mb, u_short type, u_short grade,
449105643Srwatson    u_char *compartments)
450101099Srwatson{
451101099Srwatson
452172955Srwatson	mb->mb_effective.mbe_type = type;
453172955Srwatson	mb->mb_effective.mbe_grade = grade;
454105643Srwatson	if (compartments != NULL)
455172955Srwatson		memcpy(mb->mb_effective.mbe_compartments, compartments,
456172955Srwatson		    sizeof(mb->mb_effective.mbe_compartments));
457172955Srwatson	mb->mb_flags |= MAC_BIBA_FLAG_EFFECTIVE;
458101099Srwatson}
459101099Srwatson
460101099Srwatsonstatic void
461172955Srwatsonbiba_copy_range(struct mac_biba *labelfrom, struct mac_biba *labelto)
462101099Srwatson{
463105643Srwatson
464101099Srwatson	KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_RANGE) != 0,
465172955Srwatson	    ("biba_copy_range: labelfrom not range"));
466101099Srwatson
467101099Srwatson	labelto->mb_rangelow = labelfrom->mb_rangelow;
468101099Srwatson	labelto->mb_rangehigh = labelfrom->mb_rangehigh;
469101099Srwatson	labelto->mb_flags |= MAC_BIBA_FLAG_RANGE;
470101099Srwatson}
471101099Srwatson
472101099Srwatsonstatic void
473172955Srwatsonbiba_copy_effective(struct mac_biba *labelfrom, struct mac_biba *labelto)
474101099Srwatson{
475101099Srwatson
476132232Srwatson	KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
477172955Srwatson	    ("biba_copy_effective: labelfrom not effective"));
478101099Srwatson
479132232Srwatson	labelto->mb_effective = labelfrom->mb_effective;
480132232Srwatson	labelto->mb_flags |= MAC_BIBA_FLAG_EFFECTIVE;
481101099Srwatson}
482101099Srwatson
483105656Srwatsonstatic void
484172955Srwatsonbiba_copy(struct mac_biba *source, struct mac_biba *dest)
485105656Srwatson{
486105656Srwatson
487132232Srwatson	if (source->mb_flags & MAC_BIBA_FLAG_EFFECTIVE)
488172955Srwatson		biba_copy_effective(source, dest);
489105656Srwatson	if (source->mb_flags & MAC_BIBA_FLAG_RANGE)
490172955Srwatson		biba_copy_range(source, dest);
491105656Srwatson}
492105656Srwatson
493101099Srwatson/*
494101099Srwatson * Policy module operations.
495101099Srwatson */
496101099Srwatsonstatic void
497172955Srwatsonbiba_init(struct mac_policy_conf *conf)
498101099Srwatson{
499101099Srwatson
500122879Srwatson	zone_biba = uma_zcreate("mac_biba", sizeof(struct mac_biba), NULL,
501122879Srwatson	    NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
502101099Srwatson}
503101099Srwatson
504101099Srwatson/*
505101099Srwatson * Label operations.
506101099Srwatson */
507101099Srwatsonstatic void
508172955Srwatsonbiba_init_label(struct label *label)
509101099Srwatson{
510101099Srwatson
511132781Skan	SLOT_SET(label, biba_alloc(M_WAITOK));
512101099Srwatson}
513101099Srwatson
514101099Srwatsonstatic int
515172955Srwatsonbiba_init_label_waitcheck(struct label *label, int flag)
516101099Srwatson{
517101099Srwatson
518132781Skan	SLOT_SET(label, biba_alloc(flag));
519101099Srwatson	if (SLOT(label) == NULL)
520101099Srwatson		return (ENOMEM);
521101099Srwatson
522101099Srwatson	return (0);
523101099Srwatson}
524101099Srwatson
525101099Srwatsonstatic void
526172955Srwatsonbiba_destroy_label(struct label *label)
527101099Srwatson{
528101099Srwatson
529101099Srwatson	biba_free(SLOT(label));
530132781Skan	SLOT_SET(label, NULL);
531101099Srwatson}
532101099Srwatson
533105696Srwatson/*
534172955Srwatson * biba_element_to_string() accepts an sbuf and Biba element.  It converts
535172955Srwatson * the Biba element to a string and stores the result in the sbuf; if there
536172955Srwatson * isn't space in the sbuf, -1 is returned.
537105696Srwatson */
538115497Srwatsonstatic int
539172955Srwatsonbiba_element_to_string(struct sbuf *sb, struct mac_biba_element *element)
540105696Srwatson{
541115497Srwatson	int i, first;
542105696Srwatson
543105696Srwatson	switch (element->mbe_type) {
544105696Srwatson	case MAC_BIBA_TYPE_HIGH:
545115497Srwatson		return (sbuf_printf(sb, "high"));
546105696Srwatson
547105696Srwatson	case MAC_BIBA_TYPE_LOW:
548115497Srwatson		return (sbuf_printf(sb, "low"));
549105696Srwatson
550105696Srwatson	case MAC_BIBA_TYPE_EQUAL:
551115497Srwatson		return (sbuf_printf(sb, "equal"));
552105696Srwatson
553105696Srwatson	case MAC_BIBA_TYPE_GRADE:
554115497Srwatson		if (sbuf_printf(sb, "%d", element->mbe_grade) == -1)
555115497Srwatson			return (-1);
556115497Srwatson
557115497Srwatson		first = 1;
558115497Srwatson		for (i = 1; i <= MAC_BIBA_MAX_COMPARTMENTS; i++) {
559115497Srwatson			if (MAC_BIBA_BIT_TEST(i, element->mbe_compartments)) {
560115497Srwatson				if (first) {
561115497Srwatson					if (sbuf_putc(sb, ':') == -1)
562115497Srwatson						return (-1);
563115497Srwatson					if (sbuf_printf(sb, "%d", i) == -1)
564115497Srwatson						return (-1);
565115497Srwatson					first = 0;
566115497Srwatson				} else {
567115497Srwatson					if (sbuf_printf(sb, "+%d", i) == -1)
568115497Srwatson						return (-1);
569115497Srwatson				}
570115497Srwatson			}
571105696Srwatson		}
572115497Srwatson		return (0);
573105696Srwatson
574105696Srwatson	default:
575172955Srwatson		panic("biba_element_to_string: invalid type (%d)",
576105696Srwatson		    element->mbe_type);
577105696Srwatson	}
578105696Srwatson}
579105696Srwatson
580115497Srwatson/*
581172955Srwatson * biba_to_string() converts a Biba label to a string, and places the results
582172955Srwatson * in the passed sbuf.  It returns 0 on success, or EINVAL if there isn't
583172955Srwatson * room in the sbuf.  Note: the sbuf will be modified even in a failure case,
584172955Srwatson * so the caller may need to revert the sbuf by restoring the offset if
585172955Srwatson * that's undesired.
586115497Srwatson */
587101099Srwatsonstatic int
588172955Srwatsonbiba_to_string(struct sbuf *sb, struct mac_biba *mb)
589101099Srwatson{
590105696Srwatson
591172955Srwatson	if (mb->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
592172955Srwatson		if (biba_element_to_string(sb, &mb->mb_effective) == -1)
593105696Srwatson			return (EINVAL);
594105696Srwatson	}
595105696Srwatson
596172955Srwatson	if (mb->mb_flags & MAC_BIBA_FLAG_RANGE) {
597116701Srwatson		if (sbuf_putc(sb, '(') == -1)
598105696Srwatson			return (EINVAL);
599105696Srwatson
600172955Srwatson		if (biba_element_to_string(sb, &mb->mb_rangelow) == -1)
601105696Srwatson			return (EINVAL);
602105696Srwatson
603116701Srwatson		if (sbuf_putc(sb, '-') == -1)
604105696Srwatson			return (EINVAL);
605105696Srwatson
606172955Srwatson		if (biba_element_to_string(sb, &mb->mb_rangehigh) == -1)
607105696Srwatson			return (EINVAL);
608105696Srwatson
609116701Srwatson		if (sbuf_putc(sb, ')') == -1)
610105696Srwatson			return (EINVAL);
611105696Srwatson	}
612105696Srwatson
613105696Srwatson	return (0);
614105696Srwatson}
615105696Srwatson
616105696Srwatsonstatic int
617172955Srwatsonbiba_externalize_label(struct label *label, char *element_name,
618116701Srwatson    struct sbuf *sb, int *claimed)
619105696Srwatson{
620172955Srwatson	struct mac_biba *mb;
621101099Srwatson
622105696Srwatson	if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0)
623105696Srwatson		return (0);
624105696Srwatson
625105696Srwatson	(*claimed)++;
626105696Srwatson
627172955Srwatson	mb = SLOT(label);
628172955Srwatson	return (biba_to_string(sb, mb));
629105696Srwatson}
630105696Srwatson
631105696Srwatsonstatic int
632172955Srwatsonbiba_parse_element(struct mac_biba_element *element, char *string)
633101099Srwatson{
634115395Srwatson	char *compartment, *end, *grade;
635115395Srwatson	int value;
636105696Srwatson
637181217Srwatson	if (strcmp(string, "high") == 0 || strcmp(string, "hi") == 0) {
638105696Srwatson		element->mbe_type = MAC_BIBA_TYPE_HIGH;
639105696Srwatson		element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
640181217Srwatson	} else if (strcmp(string, "low") == 0 || strcmp(string, "lo") == 0) {
641105696Srwatson		element->mbe_type = MAC_BIBA_TYPE_LOW;
642105696Srwatson		element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
643105696Srwatson	} else if (strcmp(string, "equal") == 0 ||
644105696Srwatson	    strcmp(string, "eq") == 0) {
645105696Srwatson		element->mbe_type = MAC_BIBA_TYPE_EQUAL;
646105696Srwatson		element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
647105696Srwatson	} else {
648115395Srwatson		element->mbe_type = MAC_BIBA_TYPE_GRADE;
649105696Srwatson
650115395Srwatson		/*
651115395Srwatson		 * Numeric grade piece of the element.
652115395Srwatson		 */
653115395Srwatson		grade = strsep(&string, ":");
654115395Srwatson		value = strtol(grade, &end, 10);
655115395Srwatson		if (end == grade || *end != '\0')
656105696Srwatson			return (EINVAL);
657115395Srwatson		if (value < 0 || value > 65535)
658115395Srwatson			return (EINVAL);
659115395Srwatson		element->mbe_grade = value;
660105696Srwatson
661115395Srwatson		/*
662181217Srwatson		 * Optional compartment piece of the element.  If none are
663181217Srwatson		 * included, we assume that the label has no compartments.
664115395Srwatson		 */
665115395Srwatson		if (string == NULL)
666115395Srwatson			return (0);
667115395Srwatson		if (*string == '\0')
668115395Srwatson			return (0);
669105696Srwatson
670115395Srwatson		while ((compartment = strsep(&string, "+")) != NULL) {
671115395Srwatson			value = strtol(compartment, &end, 10);
672115395Srwatson			if (compartment == end || *end != '\0')
673105696Srwatson				return (EINVAL);
674115395Srwatson			if (value < 1 || value > MAC_BIBA_MAX_COMPARTMENTS)
675105696Srwatson				return (EINVAL);
676115395Srwatson			MAC_BIBA_BIT_SET(value, element->mbe_compartments);
677105696Srwatson		}
678105696Srwatson	}
679105696Srwatson
680105696Srwatson	return (0);
681105696Srwatson}
682105696Srwatson
683105696Srwatson/*
684181217Srwatson * Note: destructively consumes the string, make a local copy before calling
685181217Srwatson * if that's a problem.
686105696Srwatson */
687105696Srwatsonstatic int
688172955Srwatsonbiba_parse(struct mac_biba *mb, char *string)
689105696Srwatson{
690132232Srwatson	char *rangehigh, *rangelow, *effective;
691101099Srwatson	int error;
692101099Srwatson
693132232Srwatson	effective = strsep(&string, "(");
694132232Srwatson	if (*effective == '\0')
695132232Srwatson		effective = NULL;
696115395Srwatson
697115395Srwatson	if (string != NULL) {
698115395Srwatson		rangelow = strsep(&string, "-");
699115395Srwatson		if (string == NULL)
700105696Srwatson			return (EINVAL);
701115395Srwatson		rangehigh = strsep(&string, ")");
702115395Srwatson		if (string == NULL)
703105696Srwatson			return (EINVAL);
704115395Srwatson		if (*string != '\0')
705105696Srwatson			return (EINVAL);
706115395Srwatson	} else {
707115395Srwatson		rangelow = NULL;
708115395Srwatson		rangehigh = NULL;
709105696Srwatson	}
710115395Srwatson
711105696Srwatson	KASSERT((rangelow != NULL && rangehigh != NULL) ||
712105696Srwatson	    (rangelow == NULL && rangehigh == NULL),
713172955Srwatson	    ("biba_parse: range mismatch"));
714101099Srwatson
715172955Srwatson	bzero(mb, sizeof(*mb));
716132232Srwatson	if (effective != NULL) {
717172955Srwatson		error = biba_parse_element(&mb->mb_effective, effective);
718105696Srwatson		if (error)
719105696Srwatson			return (error);
720172955Srwatson		mb->mb_flags |= MAC_BIBA_FLAG_EFFECTIVE;
721105696Srwatson	}
722105696Srwatson
723105696Srwatson	if (rangelow != NULL) {
724172955Srwatson		error = biba_parse_element(&mb->mb_rangelow, rangelow);
725105696Srwatson		if (error)
726105696Srwatson			return (error);
727172955Srwatson		error = biba_parse_element(&mb->mb_rangehigh, rangehigh);
728105696Srwatson		if (error)
729105696Srwatson			return (error);
730172955Srwatson		mb->mb_flags |= MAC_BIBA_FLAG_RANGE;
731105696Srwatson	}
732105696Srwatson
733172955Srwatson	error = biba_valid(mb);
734101099Srwatson	if (error)
735101099Srwatson		return (error);
736101099Srwatson
737105696Srwatson	return (0);
738105696Srwatson}
739101099Srwatson
740105696Srwatsonstatic int
741172955Srwatsonbiba_internalize_label(struct label *label, char *element_name,
742105696Srwatson    char *element_data, int *claimed)
743105696Srwatson{
744172955Srwatson	struct mac_biba *mb, mb_temp;
745105696Srwatson	int error;
746105696Srwatson
747105696Srwatson	if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0)
748105696Srwatson		return (0);
749105696Srwatson
750105696Srwatson	(*claimed)++;
751105696Srwatson
752172955Srwatson	error = biba_parse(&mb_temp, element_data);
753105696Srwatson	if (error)
754105696Srwatson		return (error);
755105696Srwatson
756172955Srwatson	mb = SLOT(label);
757172955Srwatson	*mb = mb_temp;
758105696Srwatson
759101099Srwatson	return (0);
760101099Srwatson}
761101099Srwatson
762105696Srwatsonstatic void
763172955Srwatsonbiba_copy_label(struct label *src, struct label *dest)
764105696Srwatson{
765105696Srwatson
766105696Srwatson	*SLOT(dest) = *SLOT(src);
767105696Srwatson}
768105696Srwatson
769101099Srwatson/*
770173138Srwatson * Object-specific entry point implementations are sorted alphabetically by
771173138Srwatson * object type name and then by operation.
772101099Srwatson */
773173138Srwatsonstatic int
774173138Srwatsonbiba_bpfdesc_check_receive(struct bpf_d *d, struct label *dlabel,
775173138Srwatson    struct ifnet *ifp, struct label *ifplabel)
776101099Srwatson{
777173138Srwatson	struct mac_biba *a, *b;
778101099Srwatson
779173138Srwatson	if (!biba_enabled)
780173138Srwatson		return (0);
781101099Srwatson
782173138Srwatson	a = SLOT(dlabel);
783173138Srwatson	b = SLOT(ifplabel);
784101099Srwatson
785173138Srwatson	if (biba_equal_effective(a, b))
786173138Srwatson		return (0);
787173138Srwatson	return (EACCES);
788101099Srwatson}
789101099Srwatson
790101099Srwatsonstatic void
791173138Srwatsonbiba_bpfdesc_create(struct ucred *cred, struct bpf_d *d,
792173138Srwatson    struct label *dlabel)
793104535Srwatson{
794104535Srwatson	struct mac_biba *source, *dest;
795104535Srwatson
796122524Srwatson	source = SLOT(cred->cr_label);
797173138Srwatson	dest = SLOT(dlabel);
798104535Srwatson
799172955Srwatson	biba_copy_effective(source, dest);
800104535Srwatson}
801104535Srwatson
802104535Srwatsonstatic void
803173138Srwatsonbiba_bpfdesc_create_mbuf(struct bpf_d *d, struct label *dlabel,
804173138Srwatson    struct mbuf *m, struct label *mlabel)
805101099Srwatson{
806101099Srwatson	struct mac_biba *source, *dest;
807101099Srwatson
808173138Srwatson	source = SLOT(dlabel);
809173138Srwatson	dest = SLOT(mlabel);
810172955Srwatson
811172955Srwatson	biba_copy_effective(source, dest);
812101099Srwatson}
813101099Srwatson
814184407Srwatsonstatic void
815184407Srwatsonbiba_cred_associate_nfsd(struct ucred *cred)
816184407Srwatson{
817184407Srwatson	struct mac_biba *label;
818184407Srwatson
819184407Srwatson	label = SLOT(cred->cr_label);
820184407Srwatson	biba_set_effective(label, MAC_BIBA_TYPE_LOW, 0, NULL);
821184407Srwatson	biba_set_range(label, MAC_BIBA_TYPE_LOW, 0, NULL, MAC_BIBA_TYPE_HIGH,
822184407Srwatson	    0, NULL);
823184407Srwatson}
824184407Srwatson
825173138Srwatsonstatic int
826173138Srwatsonbiba_cred_check_relabel(struct ucred *cred, struct label *newlabel)
827101099Srwatson{
828173138Srwatson	struct mac_biba *subj, *new;
829173138Srwatson	int error;
830101099Srwatson
831173138Srwatson	subj = SLOT(cred->cr_label);
832173138Srwatson	new = SLOT(newlabel);
833101099Srwatson
834173138Srwatson	/*
835173138Srwatson	 * If there is a Biba label update for the credential, it may
836173138Srwatson	 * be an update of the effective, range, or both.
837173138Srwatson	 */
838173138Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
839173138Srwatson	if (error)
840173138Srwatson		return (error);
841101099Srwatson
842173138Srwatson	/*
843173138Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
844173138Srwatson	 */
845173138Srwatson	if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) {
846173138Srwatson		/*
847173138Srwatson		 * If the change request modifies both the Biba label
848173138Srwatson		 * effective and range, check that the new effective will be
849173138Srwatson		 * in the new range.
850173138Srwatson		 */
851173138Srwatson		if ((new->mb_flags & MAC_BIBA_FLAGS_BOTH) ==
852173138Srwatson		    MAC_BIBA_FLAGS_BOTH &&
853173138Srwatson		    !biba_effective_in_range(new, new))
854173138Srwatson			return (EINVAL);
855101099Srwatson
856173138Srwatson		/*
857173138Srwatson		 * To change the Biba effective label on a credential, the
858173138Srwatson		 * new effective label must be in the current range.
859173138Srwatson		 */
860173138Srwatson		if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE &&
861173138Srwatson		    !biba_effective_in_range(new, subj))
862173138Srwatson			return (EPERM);
863101099Srwatson
864173138Srwatson		/*
865173138Srwatson		 * To change the Biba range on a credential, the new range
866173138Srwatson		 * label must be in the current range.
867173138Srwatson		 */
868173138Srwatson		if (new->mb_flags & MAC_BIBA_FLAG_RANGE &&
869173138Srwatson		    !biba_range_in_range(new, subj))
870173138Srwatson			return (EPERM);
871101099Srwatson
872173138Srwatson		/*
873173138Srwatson		 * To have EQUAL in any component of the new credential Biba
874173138Srwatson		 * label, the subject must already have EQUAL in their label.
875173138Srwatson		 */
876173138Srwatson		if (biba_contains_equal(new)) {
877173138Srwatson			error = biba_subject_privileged(subj);
878173138Srwatson			if (error)
879173138Srwatson				return (error);
880173138Srwatson		}
881105988Srwatson	}
882101099Srwatson
883101099Srwatson	return (0);
884101099Srwatson}
885101099Srwatson
886105988Srwatsonstatic int
887173138Srwatsonbiba_cred_check_visible(struct ucred *u1, struct ucred *u2)
888105988Srwatson{
889173138Srwatson	struct mac_biba *subj, *obj;
890105988Srwatson
891173138Srwatson	if (!biba_enabled)
892105988Srwatson		return (0);
893105988Srwatson
894173138Srwatson	subj = SLOT(u1->cr_label);
895173138Srwatson	obj = SLOT(u2->cr_label);
896105988Srwatson
897173138Srwatson	/* XXX: range */
898173138Srwatson	if (!biba_dominate_effective(obj, subj))
899173138Srwatson		return (ESRCH);
900105988Srwatson
901173138Srwatson	return (0);
902122875Srwatson}
903122875Srwatson
904122875Srwatsonstatic void
905184407Srwatsonbiba_cred_create_init(struct ucred *cred)
906184407Srwatson{
907184407Srwatson	struct mac_biba *dest;
908184407Srwatson
909184407Srwatson	dest = SLOT(cred->cr_label);
910184407Srwatson
911184407Srwatson	biba_set_effective(dest, MAC_BIBA_TYPE_HIGH, 0, NULL);
912184407Srwatson	biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL, MAC_BIBA_TYPE_HIGH,
913184407Srwatson	    0, NULL);
914184407Srwatson}
915184407Srwatson
916184407Srwatsonstatic void
917184407Srwatsonbiba_cred_create_swapper(struct ucred *cred)
918184407Srwatson{
919184407Srwatson	struct mac_biba *dest;
920184407Srwatson
921184407Srwatson	dest = SLOT(cred->cr_label);
922184407Srwatson
923184407Srwatson	biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
924184407Srwatson	biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL, MAC_BIBA_TYPE_HIGH,
925184407Srwatson	    0, NULL);
926184407Srwatson}
927184407Srwatson
928184407Srwatsonstatic void
929173138Srwatsonbiba_cred_relabel(struct ucred *cred, struct label *newlabel)
930101099Srwatson{
931101099Srwatson	struct mac_biba *source, *dest;
932101099Srwatson
933173138Srwatson	source = SLOT(newlabel);
934173138Srwatson	dest = SLOT(cred->cr_label);
935101099Srwatson
936173138Srwatson	biba_copy(source, dest);
937101099Srwatson}
938101099Srwatson
939101099Srwatsonstatic void
940173138Srwatsonbiba_devfs_create_device(struct ucred *cred, struct mount *mp,
941173138Srwatson    struct cdev *dev, struct devfs_dirent *de, struct label *delabel)
942101099Srwatson{
943173138Srwatson	struct mac_biba *mb;
944231378Sed	const char *dn;
945173138Srwatson	int biba_type;
946101099Srwatson
947173138Srwatson	mb = SLOT(delabel);
948231378Sed	dn = devtoname(dev);
949231378Sed	if (strcmp(dn, "null") == 0 ||
950231378Sed	    strcmp(dn, "zero") == 0 ||
951231378Sed	    strcmp(dn, "random") == 0 ||
952231378Sed	    strncmp(dn, "fd/", strlen("fd/")) == 0)
953173138Srwatson		biba_type = MAC_BIBA_TYPE_EQUAL;
954173138Srwatson	else if (ptys_equal &&
955231378Sed	    (strncmp(dn, "ttyp", strlen("ttyp")) == 0 ||
956231378Sed	    strncmp(dn, "pts/", strlen("pts/")) == 0 ||
957231378Sed	    strncmp(dn, "ptyp", strlen("ptyp")) == 0))
958173138Srwatson		biba_type = MAC_BIBA_TYPE_EQUAL;
959173138Srwatson	else
960173138Srwatson		biba_type = MAC_BIBA_TYPE_HIGH;
961173138Srwatson	biba_set_effective(mb, biba_type, 0, NULL);
962101099Srwatson}
963101099Srwatson
964101099Srwatsonstatic void
965173138Srwatsonbiba_devfs_create_directory(struct mount *mp, char *dirname, int dirnamelen,
966173138Srwatson    struct devfs_dirent *de, struct label *delabel)
967101099Srwatson{
968173138Srwatson	struct mac_biba *mb;
969101099Srwatson
970173138Srwatson	mb = SLOT(delabel);
971101099Srwatson
972173138Srwatson	biba_set_effective(mb, MAC_BIBA_TYPE_HIGH, 0, NULL);
973101099Srwatson}
974101099Srwatson
975101099Srwatsonstatic void
976173138Srwatsonbiba_devfs_create_symlink(struct ucred *cred, struct mount *mp,
977173138Srwatson    struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de,
978173138Srwatson    struct label *delabel)
979145855Srwatson{
980145855Srwatson	struct mac_biba *source, *dest;
981145855Srwatson
982145855Srwatson	source = SLOT(cred->cr_label);
983173138Srwatson	dest = SLOT(delabel);
984145855Srwatson
985172955Srwatson	biba_copy_effective(source, dest);
986145855Srwatson}
987145855Srwatson
988145855Srwatsonstatic void
989173138Srwatsonbiba_devfs_update(struct mount *mp, struct devfs_dirent *de,
990173138Srwatson    struct label *delabel, struct vnode *vp, struct label *vplabel)
991101099Srwatson{
992101099Srwatson	struct mac_biba *source, *dest;
993101099Srwatson
994173138Srwatson	source = SLOT(vplabel);
995173138Srwatson	dest = SLOT(delabel);
996101099Srwatson
997172955Srwatson	biba_copy(source, dest);
998101099Srwatson}
999101099Srwatson
1000101099Srwatsonstatic void
1001173138Srwatsonbiba_devfs_vnode_associate(struct mount *mp, struct label *mntlabel,
1002173138Srwatson    struct devfs_dirent *de, struct label *delabel, struct vnode *vp,
1003173138Srwatson    struct label *vplabel)
1004101099Srwatson{
1005101099Srwatson	struct mac_biba *source, *dest;
1006101099Srwatson
1007173138Srwatson	source = SLOT(delabel);
1008173138Srwatson	dest = SLOT(vplabel);
1009101099Srwatson
1010172955Srwatson	biba_copy_effective(source, dest);
1011101099Srwatson}
1012101099Srwatson
1013173138Srwatsonstatic int
1014173138Srwatsonbiba_ifnet_check_relabel(struct ucred *cred, struct ifnet *ifp,
1015173138Srwatson    struct label *ifplabel, struct label *newlabel)
1016140628Srwatson{
1017173138Srwatson	struct mac_biba *subj, *new;
1018173138Srwatson	int error;
1019140628Srwatson
1020173138Srwatson	subj = SLOT(cred->cr_label);
1021173138Srwatson	new = SLOT(newlabel);
1022140628Srwatson
1023173138Srwatson	/*
1024173138Srwatson	 * If there is a Biba label update for the interface, it may be an
1025173138Srwatson	 * update of the effective, range, or both.
1026173138Srwatson	 */
1027173138Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
1028173138Srwatson	if (error)
1029173138Srwatson		return (error);
1030140628Srwatson
1031173138Srwatson	/*
1032173138Srwatson	 * Relabling network interfaces requires Biba privilege.
1033173138Srwatson	 */
1034173138Srwatson	error = biba_subject_privileged(subj);
1035173138Srwatson	if (error)
1036173138Srwatson		return (error);
1037140628Srwatson
1038173138Srwatson	return (0);
1039140628Srwatson}
1040140628Srwatson
1041173138Srwatsonstatic int
1042173138Srwatsonbiba_ifnet_check_transmit(struct ifnet *ifp, struct label *ifplabel,
1043173138Srwatson    struct mbuf *m, struct label *mlabel)
1044140628Srwatson{
1045173138Srwatson	struct mac_biba *p, *i;
1046140628Srwatson
1047173138Srwatson	if (!biba_enabled)
1048173138Srwatson		return (0);
1049140628Srwatson
1050173138Srwatson	p = SLOT(mlabel);
1051173138Srwatson	i = SLOT(ifplabel);
1052140628Srwatson
1053173138Srwatson	return (biba_effective_in_range(p, i) ? 0 : EACCES);
1054140628Srwatson}
1055140628Srwatson
1056101099Srwatsonstatic void
1057172955Srwatsonbiba_ifnet_create(struct ifnet *ifp, struct label *ifplabel)
1058101099Srwatson{
1059121816Sbrooks	char tifname[IFNAMSIZ], *p, *q;
1060101099Srwatson	char tiflist[sizeof(trusted_interfaces)];
1061101099Srwatson	struct mac_biba *dest;
1062110350Srwatson	int len, type;
1063101099Srwatson
1064168976Srwatson	dest = SLOT(ifplabel);
1065101099Srwatson
1066168976Srwatson	if (ifp->if_type == IFT_LOOP || interfaces_equal != 0) {
1067110350Srwatson		type = MAC_BIBA_TYPE_EQUAL;
1068101099Srwatson		goto set;
1069101099Srwatson	}
1070101099Srwatson
1071101099Srwatson	if (trust_all_interfaces) {
1072110350Srwatson		type = MAC_BIBA_TYPE_HIGH;
1073101099Srwatson		goto set;
1074101099Srwatson	}
1075101099Srwatson
1076110350Srwatson	type = MAC_BIBA_TYPE_LOW;
1077101099Srwatson
1078101099Srwatson	if (trusted_interfaces[0] == '\0' ||
1079101099Srwatson	    !strvalid(trusted_interfaces, sizeof(trusted_interfaces)))
1080101099Srwatson		goto set;
1081101099Srwatson
1082106089Srwatson	bzero(tiflist, sizeof(tiflist));
1083101099Srwatson	for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++)
1084101099Srwatson		if(*p != ' ' && *p != '\t')
1085101099Srwatson			*q = *p;
1086101099Srwatson
1087101099Srwatson	for (p = q = tiflist;; p++) {
1088101099Srwatson		if (*p == ',' || *p == '\0') {
1089101099Srwatson			len = p - q;
1090101099Srwatson			if (len < IFNAMSIZ) {
1091101099Srwatson				bzero(tifname, sizeof(tifname));
1092101099Srwatson				bcopy(q, tifname, len);
1093168976Srwatson				if (strcmp(tifname, ifp->if_xname) == 0) {
1094110350Srwatson					type = MAC_BIBA_TYPE_HIGH;
1095101099Srwatson					break;
1096101099Srwatson				}
1097106089Srwatson			} else {
1098106089Srwatson				*p = '\0';
1099106089Srwatson				printf("mac_biba warning: interface name "
1100106089Srwatson				    "\"%s\" is too long (must be < %d)\n",
1101106089Srwatson				    q, IFNAMSIZ);
1102101099Srwatson			}
1103101099Srwatson			if (*p == '\0')
1104101099Srwatson				break;
1105101099Srwatson			q = p + 1;
1106101099Srwatson		}
1107101099Srwatson	}
1108101099Srwatsonset:
1109172955Srwatson	biba_set_effective(dest, type, 0, NULL);
1110172955Srwatson	biba_set_range(dest, type, 0, NULL, type, 0, NULL);
1111101099Srwatson}
1112101099Srwatson
1113101099Srwatsonstatic void
1114173138Srwatsonbiba_ifnet_create_mbuf(struct ifnet *ifp, struct label *ifplabel,
1115173138Srwatson    struct mbuf *m, struct label *mlabel)
1116101099Srwatson{
1117101099Srwatson	struct mac_biba *source, *dest;
1118101099Srwatson
1119173138Srwatson	source = SLOT(ifplabel);
1120173138Srwatson	dest = SLOT(mlabel);
1121101099Srwatson
1122172955Srwatson	biba_copy_effective(source, dest);
1123101099Srwatson}
1124101099Srwatson
1125101099Srwatsonstatic void
1126173138Srwatsonbiba_ifnet_relabel(struct ucred *cred, struct ifnet *ifp,
1127173138Srwatson    struct label *ifplabel, struct label *newlabel)
1128101099Srwatson{
1129101099Srwatson	struct mac_biba *source, *dest;
1130101099Srwatson
1131173138Srwatson	source = SLOT(newlabel);
1132173138Srwatson	dest = SLOT(ifplabel);
1133101099Srwatson
1134173138Srwatson	biba_copy(source, dest);
1135101099Srwatson}
1136101099Srwatson
1137173138Srwatsonstatic int
1138173138Srwatsonbiba_inpcb_check_deliver(struct inpcb *inp, struct label *inplabel,
1139173138Srwatson    struct mbuf *m, struct label *mlabel)
1140173138Srwatson{
1141173138Srwatson	struct mac_biba *p, *i;
1142173138Srwatson
1143173138Srwatson	if (!biba_enabled)
1144173138Srwatson		return (0);
1145173138Srwatson
1146173138Srwatson	p = SLOT(mlabel);
1147173138Srwatson	i = SLOT(inplabel);
1148173138Srwatson
1149173138Srwatson	return (biba_equal_effective(p, i) ? 0 : EACCES);
1150173138Srwatson}
1151173138Srwatson
1152183980Sbzstatic int
1153183980Sbzbiba_inpcb_check_visible(struct ucred *cred, struct inpcb *inp,
1154183980Sbz    struct label *inplabel)
1155183980Sbz{
1156183980Sbz	struct mac_biba *subj, *obj;
1157183980Sbz
1158183980Sbz	if (!biba_enabled)
1159183980Sbz		return (0);
1160183980Sbz
1161183980Sbz	subj = SLOT(cred->cr_label);
1162183980Sbz	obj = SLOT(inplabel);
1163183980Sbz
1164183980Sbz	if (!biba_dominate_effective(obj, subj))
1165183980Sbz		return (ENOENT);
1166183980Sbz
1167183980Sbz	return (0);
1168183980Sbz}
1169183980Sbz
1170101099Srwatsonstatic void
1171173138Srwatsonbiba_inpcb_create(struct socket *so, struct label *solabel,
1172173138Srwatson    struct inpcb *inp, struct label *inplabel)
1173101099Srwatson{
1174101099Srwatson	struct mac_biba *source, *dest;
1175101099Srwatson
1176173138Srwatson	source = SLOT(solabel);
1177173138Srwatson	dest = SLOT(inplabel);
1178101099Srwatson
1179193391Srwatson	SOCK_LOCK(so);
1180172955Srwatson	biba_copy_effective(source, dest);
1181193391Srwatson	SOCK_UNLOCK(so);
1182101099Srwatson}
1183101099Srwatson
1184101099Srwatsonstatic void
1185172955Srwatsonbiba_inpcb_create_mbuf(struct inpcb *inp, struct label *inplabel,
1186123607Srwatson    struct mbuf *m, struct label *mlabel)
1187123607Srwatson{
1188123607Srwatson	struct mac_biba *source, *dest;
1189123607Srwatson
1190123607Srwatson	source = SLOT(inplabel);
1191123607Srwatson	dest = SLOT(mlabel);
1192123607Srwatson
1193172955Srwatson	biba_copy_effective(source, dest);
1194123607Srwatson}
1195123607Srwatson
1196123607Srwatsonstatic void
1197173138Srwatsonbiba_inpcb_sosetlabel(struct socket *so, struct label *solabel,
1198173138Srwatson    struct inpcb *inp, struct label *inplabel)
1199101099Srwatson{
1200101099Srwatson	struct mac_biba *source, *dest;
1201101099Srwatson
1202193391Srwatson	SOCK_LOCK_ASSERT(so);
1203193391Srwatson
1204173138Srwatson	source = SLOT(solabel);
1205173138Srwatson	dest = SLOT(inplabel);
1206101099Srwatson
1207173138Srwatson	biba_copy(source, dest);
1208101099Srwatson}
1209101099Srwatson
1210101099Srwatsonstatic void
1211184308Srwatsonbiba_ip6q_create(struct mbuf *m, struct label *mlabel, struct ip6q *q6,
1212184308Srwatson    struct label *q6label)
1213184308Srwatson{
1214184308Srwatson	struct mac_biba *source, *dest;
1215184308Srwatson
1216184308Srwatson	source = SLOT(mlabel);
1217184308Srwatson	dest = SLOT(q6label);
1218184308Srwatson
1219184308Srwatson	biba_copy_effective(source, dest);
1220184308Srwatson}
1221184308Srwatson
1222184308Srwatsonstatic int
1223184308Srwatsonbiba_ip6q_match(struct mbuf *m, struct label *mlabel, struct ip6q *q6,
1224184308Srwatson    struct label *q6label)
1225184308Srwatson{
1226184308Srwatson	struct mac_biba *a, *b;
1227184308Srwatson
1228184308Srwatson	a = SLOT(q6label);
1229184308Srwatson	b = SLOT(mlabel);
1230184308Srwatson
1231184308Srwatson	return (biba_equal_effective(a, b));
1232184308Srwatson}
1233184308Srwatson
1234184308Srwatsonstatic void
1235184308Srwatsonbiba_ip6q_reassemble(struct ip6q *q6, struct label *q6label, struct mbuf *m,
1236184308Srwatson    struct label *mlabel)
1237184308Srwatson{
1238184308Srwatson	struct mac_biba *source, *dest;
1239184308Srwatson
1240184308Srwatson	source = SLOT(q6label);
1241184308Srwatson	dest = SLOT(mlabel);
1242184308Srwatson
1243184308Srwatson	/* Just use the head, since we require them all to match. */
1244184308Srwatson	biba_copy_effective(source, dest);
1245184308Srwatson}
1246184308Srwatson
1247184308Srwatsonstatic void
1248184308Srwatsonbiba_ip6q_update(struct mbuf *m, struct label *mlabel, struct ip6q *q6,
1249184308Srwatson    struct label *q6label)
1250184308Srwatson{
1251184308Srwatson
1252184308Srwatson	/* NOOP: we only accept matching labels, so no need to update */
1253184308Srwatson}
1254184308Srwatson
1255184308Srwatsonstatic void
1256179781Srwatsonbiba_ipq_create(struct mbuf *m, struct label *mlabel, struct ipq *q,
1257179781Srwatson    struct label *qlabel)
1258101099Srwatson{
1259101099Srwatson	struct mac_biba *source, *dest;
1260101099Srwatson
1261173138Srwatson	source = SLOT(mlabel);
1262179781Srwatson	dest = SLOT(qlabel);
1263101099Srwatson
1264172955Srwatson	biba_copy_effective(source, dest);
1265101099Srwatson}
1266101099Srwatson
1267101099Srwatsonstatic int
1268179781Srwatsonbiba_ipq_match(struct mbuf *m, struct label *mlabel, struct ipq *q,
1269179781Srwatson    struct label *qlabel)
1270101099Srwatson{
1271101099Srwatson	struct mac_biba *a, *b;
1272101099Srwatson
1273179781Srwatson	a = SLOT(qlabel);
1274168976Srwatson	b = SLOT(mlabel);
1275101099Srwatson
1276172955Srwatson	return (biba_equal_effective(a, b));
1277101099Srwatson}
1278101099Srwatson
1279101099Srwatsonstatic void
1280179781Srwatsonbiba_ipq_reassemble(struct ipq *q, struct label *qlabel, struct mbuf *m,
1281173138Srwatson    struct label *mlabel)
1282101099Srwatson{
1283101099Srwatson	struct mac_biba *source, *dest;
1284101099Srwatson
1285179781Srwatson	source = SLOT(qlabel);
1286173138Srwatson	dest = SLOT(mlabel);
1287101099Srwatson
1288173138Srwatson	/* Just use the head, since we require them all to match. */
1289173138Srwatson	biba_copy_effective(source, dest);
1290101099Srwatson}
1291101099Srwatson
1292101099Srwatsonstatic void
1293179781Srwatsonbiba_ipq_update(struct mbuf *m, struct label *mlabel, struct ipq *q,
1294179781Srwatson    struct label *qlabel)
1295101099Srwatson{
1296101099Srwatson
1297101099Srwatson	/* NOOP: we only accept matching labels, so no need to update */
1298101099Srwatson}
1299101099Srwatson
1300173138Srwatsonstatic int
1301173138Srwatsonbiba_kld_check_load(struct ucred *cred, struct vnode *vp,
1302173138Srwatson    struct label *vplabel)
1303173138Srwatson{
1304173138Srwatson	struct mac_biba *subj, *obj;
1305173138Srwatson	int error;
1306173138Srwatson
1307173138Srwatson	if (!biba_enabled)
1308173138Srwatson		return (0);
1309173138Srwatson
1310173138Srwatson	subj = SLOT(cred->cr_label);
1311173138Srwatson
1312173138Srwatson	error = biba_subject_privileged(subj);
1313173138Srwatson	if (error)
1314173138Srwatson		return (error);
1315173138Srwatson
1316173138Srwatson	obj = SLOT(vplabel);
1317173138Srwatson	if (!biba_high_effective(obj))
1318173138Srwatson		return (EACCES);
1319173138Srwatson
1320173138Srwatson	return (0);
1321173138Srwatson}
1322173138Srwatson
1323173138Srwatsonstatic int
1324173138Srwatsonbiba_mount_check_stat(struct ucred *cred, struct mount *mp,
1325173138Srwatson    struct label *mplabel)
1326173138Srwatson{
1327173138Srwatson	struct mac_biba *subj, *obj;
1328173138Srwatson
1329173138Srwatson	if (!biba_enabled)
1330173138Srwatson		return (0);
1331173138Srwatson
1332173138Srwatson	subj = SLOT(cred->cr_label);
1333173138Srwatson	obj = SLOT(mplabel);
1334173138Srwatson
1335173138Srwatson	if (!biba_dominate_effective(obj, subj))
1336173138Srwatson		return (EACCES);
1337173138Srwatson
1338173138Srwatson	return (0);
1339173138Srwatson}
1340173138Srwatson
1341122875Srwatsonstatic void
1342173138Srwatsonbiba_mount_create(struct ucred *cred, struct mount *mp,
1343173138Srwatson    struct label *mplabel)
1344122875Srwatson{
1345122875Srwatson	struct mac_biba *source, *dest;
1346122875Srwatson
1347173138Srwatson	source = SLOT(cred->cr_label);
1348173138Srwatson	dest = SLOT(mplabel);
1349122875Srwatson
1350173138Srwatson	biba_copy_effective(source, dest);
1351122875Srwatson}
1352122875Srwatson
1353162238Scsjpstatic void
1354173095Srwatsonbiba_netinet_arp_send(struct ifnet *ifp, struct label *ifplabel,
1355173095Srwatson    struct mbuf *m, struct label *mlabel)
1356173095Srwatson{
1357173095Srwatson	struct mac_biba *dest;
1358173095Srwatson
1359173095Srwatson	dest = SLOT(mlabel);
1360173095Srwatson
1361173095Srwatson	biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1362173095Srwatson}
1363173095Srwatson
1364173095Srwatsonstatic void
1365173102Srwatsonbiba_netinet_firewall_reply(struct mbuf *mrecv, struct label *mrecvlabel,
1366173102Srwatson    struct mbuf *msend, struct label *msendlabel)
1367173102Srwatson{
1368173102Srwatson	struct mac_biba *source, *dest;
1369173102Srwatson
1370173102Srwatson	source = SLOT(mrecvlabel);
1371173102Srwatson	dest = SLOT(msendlabel);
1372173102Srwatson
1373173102Srwatson	biba_copy_effective(source, dest);
1374173102Srwatson}
1375173102Srwatson
1376173102Srwatsonstatic void
1377173018Srwatsonbiba_netinet_firewall_send(struct mbuf *m, struct label *mlabel)
1378162238Scsjp{
1379162238Scsjp	struct mac_biba *dest;
1380162238Scsjp
1381173018Srwatson	dest = SLOT(mlabel);
1382162238Scsjp
1383173018Srwatson	/* XXX: where is the label for the firewall really coming from? */
1384172955Srwatson	biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1385162238Scsjp}
1386162238Scsjp
1387173095Srwatsonstatic void
1388173138Srwatsonbiba_netinet_fragment(struct mbuf *m, struct label *mlabel,
1389173138Srwatson    struct mbuf *frag, struct label *fraglabel)
1390173138Srwatson{
1391173138Srwatson	struct mac_biba *source, *dest;
1392173138Srwatson
1393173138Srwatson	source = SLOT(mlabel);
1394173138Srwatson	dest = SLOT(fraglabel);
1395173138Srwatson
1396173138Srwatson	biba_copy_effective(source, dest);
1397173138Srwatson}
1398173138Srwatson
1399173138Srwatsonstatic void
1400173102Srwatsonbiba_netinet_icmp_reply(struct mbuf *mrecv, struct label *mrecvlabel,
1401173102Srwatson    struct mbuf *msend, struct label *msendlabel)
1402173102Srwatson{
1403173102Srwatson	struct mac_biba *source, *dest;
1404173102Srwatson
1405173102Srwatson	source = SLOT(mrecvlabel);
1406173102Srwatson	dest = SLOT(msendlabel);
1407173102Srwatson
1408173102Srwatson	biba_copy_effective(source, dest);
1409173102Srwatson}
1410173102Srwatson
1411173102Srwatsonstatic void
1412173095Srwatsonbiba_netinet_igmp_send(struct ifnet *ifp, struct label *ifplabel,
1413173095Srwatson    struct mbuf *m, struct label *mlabel)
1414173095Srwatson{
1415173095Srwatson	struct mac_biba *dest;
1416173095Srwatson
1417173095Srwatson	dest = SLOT(mlabel);
1418173095Srwatson
1419173095Srwatson	biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1420173095Srwatson}
1421173095Srwatson
1422173095Srwatsonstatic void
1423173095Srwatsonbiba_netinet6_nd6_send(struct ifnet *ifp, struct label *ifplabel,
1424173095Srwatson    struct mbuf *m, struct label *mlabel)
1425173095Srwatson{
1426173095Srwatson	struct mac_biba *dest;
1427173095Srwatson
1428173095Srwatson	dest = SLOT(mlabel);
1429173095Srwatson
1430173095Srwatson	biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1431173095Srwatson}
1432173095Srwatson
1433173138Srwatsonstatic int
1434173138Srwatsonbiba_pipe_check_ioctl(struct ucred *cred, struct pipepair *pp,
1435173138Srwatson    struct label *pplabel, unsigned long cmd, void /* caddr_t */ *data)
1436101099Srwatson{
1437101099Srwatson
1438173138Srwatson	if(!biba_enabled)
1439173138Srwatson		return (0);
1440101099Srwatson
1441173138Srwatson	/* XXX: This will be implemented soon... */
1442101099Srwatson
1443173138Srwatson	return (0);
1444101099Srwatson}
1445101099Srwatson
1446173138Srwatsonstatic int
1447173138Srwatsonbiba_pipe_check_poll(struct ucred *cred, struct pipepair *pp,
1448173138Srwatson    struct label *pplabel)
1449172957Srwatson{
1450173138Srwatson	struct mac_biba *subj, *obj;
1451172957Srwatson
1452173138Srwatson	if (!biba_enabled)
1453173138Srwatson		return (0);
1454172957Srwatson
1455173138Srwatson	subj = SLOT(cred->cr_label);
1456173138Srwatson	obj = SLOT(pplabel);
1457101099Srwatson
1458173138Srwatson	if (!biba_dominate_effective(obj, subj))
1459173138Srwatson		return (EACCES);
1460101099Srwatson
1461173138Srwatson	return (0);
1462101099Srwatson}
1463101099Srwatson
1464101099Srwatsonstatic int
1465173138Srwatsonbiba_pipe_check_read(struct ucred *cred, struct pipepair *pp,
1466173138Srwatson    struct label *pplabel)
1467101099Srwatson{
1468173138Srwatson	struct mac_biba *subj, *obj;
1469101099Srwatson
1470172955Srwatson	if (!biba_enabled)
1471101099Srwatson		return (0);
1472101099Srwatson
1473173138Srwatson	subj = SLOT(cred->cr_label);
1474173138Srwatson	obj = SLOT(pplabel);
1475101099Srwatson
1476173138Srwatson	if (!biba_dominate_effective(obj, subj))
1477173138Srwatson		return (EACCES);
1478173138Srwatson
1479173138Srwatson	return (0);
1480101099Srwatson}
1481101099Srwatson
1482101099Srwatsonstatic int
1483173138Srwatsonbiba_pipe_check_relabel(struct ucred *cred, struct pipepair *pp,
1484173138Srwatson    struct label *pplabel, struct label *newlabel)
1485101099Srwatson{
1486173138Srwatson	struct mac_biba *subj, *obj, *new;
1487105634Srwatson	int error;
1488101099Srwatson
1489173138Srwatson	new = SLOT(newlabel);
1490122524Srwatson	subj = SLOT(cred->cr_label);
1491173138Srwatson	obj = SLOT(pplabel);
1492101099Srwatson
1493101099Srwatson	/*
1494173138Srwatson	 * If there is a Biba label update for a pipe, it must be a effective
1495173138Srwatson	 * update.
1496101099Srwatson	 */
1497173138Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE);
1498105634Srwatson	if (error)
1499105634Srwatson		return (error);
1500101099Srwatson
1501101099Srwatson	/*
1502173138Srwatson	 * To perform a relabel of a pipe (Biba label or not), Biba must
1503173138Srwatson	 * authorize the relabel.
1504173138Srwatson	 */
1505173138Srwatson	if (!biba_effective_in_range(obj, subj))
1506173138Srwatson		return (EPERM);
1507173138Srwatson
1508173138Srwatson	/*
1509105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
1510101099Srwatson	 */
1511173138Srwatson	if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
1512105634Srwatson		/*
1513173138Srwatson		 * To change the Biba label on a pipe, the new pipe label
1514173138Srwatson		 * must be in the subject range.
1515110351Srwatson		 */
1516173138Srwatson		if (!biba_effective_in_range(new, subj))
1517105634Srwatson			return (EPERM);
1518101099Srwatson
1519105634Srwatson		/*
1520173138Srwatson		 * To change the Biba label on a pipe to be EQUAL, the
1521173138Srwatson		 * subject must have appropriate privilege.
1522105634Srwatson		 */
1523172955Srwatson		if (biba_contains_equal(new)) {
1524172955Srwatson			error = biba_subject_privileged(subj);
1525105634Srwatson			if (error)
1526105634Srwatson				return (error);
1527105634Srwatson		}
1528105634Srwatson	}
1529105634Srwatson
1530101099Srwatson	return (0);
1531101099Srwatson}
1532101099Srwatson
1533101099Srwatsonstatic int
1534173138Srwatsonbiba_pipe_check_stat(struct ucred *cred, struct pipepair *pp,
1535173138Srwatson    struct label *pplabel)
1536101099Srwatson{
1537101099Srwatson	struct mac_biba *subj, *obj;
1538101099Srwatson
1539172955Srwatson	if (!biba_enabled)
1540101099Srwatson		return (0);
1541101099Srwatson
1542173138Srwatson	subj = SLOT(cred->cr_label);
1543173138Srwatson	obj = SLOT(pplabel);
1544101099Srwatson
1545172955Srwatson	if (!biba_dominate_effective(obj, subj))
1546173138Srwatson		return (EACCES);
1547101099Srwatson
1548101099Srwatson	return (0);
1549101099Srwatson}
1550101099Srwatson
1551101099Srwatsonstatic int
1552173138Srwatsonbiba_pipe_check_write(struct ucred *cred, struct pipepair *pp,
1553173138Srwatson    struct label *pplabel)
1554101099Srwatson{
1555173138Srwatson	struct mac_biba *subj, *obj;
1556101099Srwatson
1557173138Srwatson	if (!biba_enabled)
1558173138Srwatson		return (0);
1559173138Srwatson
1560122524Srwatson	subj = SLOT(cred->cr_label);
1561173138Srwatson	obj = SLOT(pplabel);
1562101099Srwatson
1563173138Srwatson	if (!biba_dominate_effective(subj, obj))
1564173138Srwatson		return (EACCES);
1565101099Srwatson
1566105634Srwatson	return (0);
1567101099Srwatson}
1568101099Srwatson
1569173138Srwatsonstatic void
1570173138Srwatsonbiba_pipe_create(struct ucred *cred, struct pipepair *pp,
1571173138Srwatson    struct label *pplabel)
1572101099Srwatson{
1573173138Srwatson	struct mac_biba *source, *dest;
1574103761Srwatson
1575173138Srwatson	source = SLOT(cred->cr_label);
1576173138Srwatson	dest = SLOT(pplabel);
1577101099Srwatson
1578173138Srwatson	biba_copy_effective(source, dest);
1579173138Srwatson}
1580103759Srwatson
1581173138Srwatsonstatic void
1582173138Srwatsonbiba_pipe_relabel(struct ucred *cred, struct pipepair *pp,
1583173138Srwatson    struct label *pplabel, struct label *newlabel)
1584173138Srwatson{
1585173138Srwatson	struct mac_biba *source, *dest;
1586173138Srwatson
1587173138Srwatson	source = SLOT(newlabel);
1588173138Srwatson	dest = SLOT(pplabel);
1589173138Srwatson
1590173138Srwatson	biba_copy(source, dest);
1591101099Srwatson}
1592101099Srwatson
1593101099Srwatsonstatic int
1594180059Sjhbbiba_posixsem_check_openunlink(struct ucred *cred, struct ksem *ks,
1595173138Srwatson    struct label *kslabel)
1596122875Srwatson{
1597173138Srwatson	struct mac_biba *subj, *obj;
1598122875Srwatson
1599172955Srwatson	if (!biba_enabled)
1600122875Srwatson		return (0);
1601122875Srwatson
1602173138Srwatson	subj = SLOT(cred->cr_label);
1603173138Srwatson	obj = SLOT(kslabel);
1604122875Srwatson
1605173138Srwatson	if (!biba_dominate_effective(subj, obj))
1606173138Srwatson		return (EACCES);
1607173138Srwatson
1608173138Srwatson	return (0);
1609122875Srwatson}
1610122875Srwatson
1611122875Srwatsonstatic int
1612225344Srwatsonbiba_posixsem_check_setmode(struct ucred *cred, struct ksem *ks,
1613225344Srwatson    struct label *kslabel, mode_t mode)
1614225344Srwatson{
1615225344Srwatson	struct mac_biba *subj, *obj;
1616225344Srwatson
1617225344Srwatson	if (!biba_enabled)
1618225344Srwatson		return (0);
1619225344Srwatson
1620225344Srwatson	subj = SLOT(cred->cr_label);
1621225344Srwatson	obj = SLOT(kslabel);
1622225344Srwatson
1623225344Srwatson	if (!biba_dominate_effective(subj, obj))
1624225344Srwatson		return (EACCES);
1625225344Srwatson
1626225344Srwatson	return (0);
1627225344Srwatson}
1628225344Srwatson
1629225344Srwatsonstatic int
1630225344Srwatsonbiba_posixsem_check_setowner(struct ucred *cred, struct ksem *ks,
1631225344Srwatson    struct label *kslabel, uid_t uid, gid_t gid)
1632225344Srwatson{
1633225344Srwatson	struct mac_biba *subj, *obj;
1634225344Srwatson
1635225344Srwatson	if (!biba_enabled)
1636225344Srwatson		return (0);
1637225344Srwatson
1638225344Srwatson	subj = SLOT(cred->cr_label);
1639225344Srwatson	obj = SLOT(kslabel);
1640225344Srwatson
1641225344Srwatson	if (!biba_dominate_effective(subj, obj))
1642225344Srwatson		return (EACCES);
1643225344Srwatson
1644225344Srwatson	return (0);
1645225344Srwatson}
1646225344Srwatson
1647225344Srwatsonstatic int
1648180059Sjhbbiba_posixsem_check_write(struct ucred *active_cred, struct ucred *file_cred,
1649180059Sjhb    struct ksem *ks, struct label *kslabel)
1650140628Srwatson{
1651140628Srwatson	struct mac_biba *subj, *obj;
1652140628Srwatson
1653172955Srwatson	if (!biba_enabled)
1654140628Srwatson		return (0);
1655140628Srwatson
1656180059Sjhb	subj = SLOT(active_cred->cr_label);
1657173138Srwatson	obj = SLOT(kslabel);
1658140628Srwatson
1659180059Sjhb	if (!biba_dominate_effective(subj, obj))
1660180059Sjhb		return (EACCES);
1661180059Sjhb
1662180059Sjhb	return (0);
1663180059Sjhb}
1664180059Sjhb
1665180059Sjhbstatic int
1666180059Sjhbbiba_posixsem_check_rdonly(struct ucred *active_cred, struct ucred *file_cred,
1667180059Sjhb    struct ksem *ks, struct label *kslabel)
1668180059Sjhb{
1669180059Sjhb	struct mac_biba *subj, *obj;
1670180059Sjhb
1671180059Sjhb	if (!biba_enabled)
1672180059Sjhb		return (0);
1673180059Sjhb
1674180059Sjhb	subj = SLOT(active_cred->cr_label);
1675180059Sjhb	obj = SLOT(kslabel);
1676180059Sjhb
1677172955Srwatson	if (!biba_dominate_effective(obj, subj))
1678140628Srwatson		return (EACCES);
1679140628Srwatson
1680140628Srwatson	return (0);
1681140628Srwatson}
1682140628Srwatson
1683173138Srwatsonstatic void
1684173138Srwatsonbiba_posixsem_create(struct ucred *cred, struct ksem *ks,
1685173138Srwatson    struct label *kslabel)
1686173138Srwatson{
1687173138Srwatson	struct mac_biba *source, *dest;
1688173138Srwatson
1689173138Srwatson	source = SLOT(cred->cr_label);
1690173138Srwatson	dest = SLOT(kslabel);
1691173138Srwatson
1692173138Srwatson	biba_copy_effective(source, dest);
1693173138Srwatson}
1694173138Srwatson
1695225344Srwatsonstatic int
1696225344Srwatsonbiba_posixshm_check_mmap(struct ucred *cred, struct shmfd *shmfd,
1697225344Srwatson    struct label *shmlabel, int prot, int flags)
1698225344Srwatson{
1699225344Srwatson	struct mac_biba *subj, *obj;
1700225344Srwatson
1701225344Srwatson	if (!biba_enabled || !revocation_enabled)
1702225344Srwatson		return (0);
1703225344Srwatson
1704225344Srwatson	subj = SLOT(cred->cr_label);
1705225344Srwatson	obj = SLOT(shmlabel);
1706225344Srwatson
1707225344Srwatson	if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
1708225344Srwatson		if (!biba_dominate_effective(obj, subj))
1709225344Srwatson			return (EACCES);
1710225344Srwatson	}
1711225344Srwatson	if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) {
1712225344Srwatson		if (!biba_dominate_effective(subj, obj))
1713225344Srwatson			return (EACCES);
1714225344Srwatson	}
1715225344Srwatson
1716225344Srwatson	return (0);
1717225344Srwatson}
1718225344Srwatson
1719225344Srwatsonstatic int
1720225344Srwatsonbiba_posixshm_check_open(struct ucred *cred, struct shmfd *shmfd,
1721225344Srwatson    struct label *shmlabel, accmode_t accmode)
1722225344Srwatson{
1723225344Srwatson	struct mac_biba *subj, *obj;
1724225344Srwatson
1725225344Srwatson	if (!biba_enabled)
1726225344Srwatson		return (0);
1727225344Srwatson
1728225344Srwatson	subj = SLOT(cred->cr_label);
1729225344Srwatson	obj = SLOT(shmlabel);
1730225344Srwatson
1731225344Srwatson	if (accmode & (VREAD | VEXEC | VSTAT_PERMS)) {
1732225344Srwatson		if (!biba_dominate_effective(obj, subj))
1733225344Srwatson			return (EACCES);
1734225344Srwatson	}
1735225344Srwatson	if (accmode & VMODIFY_PERMS) {
1736225344Srwatson		if (!biba_dominate_effective(subj, obj))
1737225344Srwatson			return (EACCES);
1738225344Srwatson	}
1739225344Srwatson
1740225344Srwatson	return (0);
1741225344Srwatson}
1742225344Srwatson
1743225344Srwatsonstatic int
1744254603Skibbiba_posixshm_check_read(struct ucred *active_cred, struct ucred *file_cred,
1745254603Skib    struct shmfd *vp, struct label *shmlabel)
1746254603Skib{
1747254603Skib	struct mac_biba *subj, *obj;
1748254603Skib
1749254603Skib	if (!biba_enabled || !revocation_enabled)
1750254603Skib		return (0);
1751254603Skib
1752254603Skib	subj = SLOT(active_cred->cr_label);
1753254603Skib	obj = SLOT(shmlabel);
1754254603Skib
1755254603Skib	if (!biba_dominate_effective(obj, subj))
1756254603Skib		return (EACCES);
1757254603Skib
1758254603Skib	return (0);
1759254603Skib}
1760254603Skib
1761254603Skibstatic int
1762225344Srwatsonbiba_posixshm_check_setmode(struct ucred *cred, struct shmfd *shmfd,
1763225344Srwatson    struct label *shmlabel, mode_t mode)
1764225344Srwatson{
1765225344Srwatson	struct mac_biba *subj, *obj;
1766225344Srwatson
1767225344Srwatson	if (!biba_enabled)
1768225344Srwatson		return (0);
1769225344Srwatson
1770225344Srwatson	subj = SLOT(cred->cr_label);
1771225344Srwatson	obj = SLOT(shmlabel);
1772225344Srwatson
1773225344Srwatson	if (!biba_dominate_effective(subj, obj))
1774225344Srwatson		return (EACCES);
1775225344Srwatson
1776225344Srwatson	return (0);
1777225344Srwatson}
1778225344Srwatson
1779225344Srwatsonstatic int
1780225344Srwatsonbiba_posixshm_check_setowner(struct ucred *cred, struct shmfd *shmfd,
1781225344Srwatson    struct label *shmlabel, uid_t uid, gid_t gid)
1782225344Srwatson{
1783225344Srwatson	struct mac_biba *subj, *obj;
1784225344Srwatson
1785225344Srwatson	if (!biba_enabled)
1786225344Srwatson		return (0);
1787225344Srwatson
1788225344Srwatson	subj = SLOT(cred->cr_label);
1789225344Srwatson	obj = SLOT(shmlabel);
1790225344Srwatson
1791225344Srwatson	if (!biba_dominate_effective(subj, obj))
1792225344Srwatson		return (EACCES);
1793225344Srwatson
1794225344Srwatson	return (0);
1795225344Srwatson}
1796225344Srwatson
1797225344Srwatsonstatic int
1798225344Srwatsonbiba_posixshm_check_stat(struct ucred *active_cred, struct ucred *file_cred,
1799225344Srwatson    struct shmfd *shmfd, struct label *shmlabel)
1800225344Srwatson{
1801225344Srwatson	struct mac_biba *subj, *obj;
1802225344Srwatson
1803225344Srwatson	if (!biba_enabled)
1804225344Srwatson		return (0);
1805225344Srwatson
1806225344Srwatson	subj = SLOT(active_cred->cr_label);
1807225344Srwatson	obj = SLOT(shmlabel);
1808225344Srwatson
1809225344Srwatson	if (!biba_dominate_effective(obj, subj))
1810225344Srwatson		return (EACCES);
1811225344Srwatson
1812225344Srwatson	return (0);
1813225344Srwatson}
1814225344Srwatson
1815225344Srwatsonstatic int
1816225344Srwatsonbiba_posixshm_check_truncate(struct ucred *active_cred,
1817225344Srwatson    struct ucred *file_cred, struct shmfd *shmfd, struct label *shmlabel)
1818225344Srwatson{
1819225344Srwatson	struct mac_biba *subj, *obj;
1820225344Srwatson
1821225344Srwatson	if (!biba_enabled)
1822225344Srwatson		return (0);
1823225344Srwatson
1824225344Srwatson	subj = SLOT(active_cred->cr_label);
1825225344Srwatson	obj = SLOT(shmlabel);
1826225344Srwatson
1827225344Srwatson	if (!biba_dominate_effective(subj, obj))
1828225344Srwatson		return (EACCES);
1829225344Srwatson
1830225344Srwatson	return (0);
1831225344Srwatson}
1832225344Srwatson
1833225344Srwatsonstatic int
1834225344Srwatsonbiba_posixshm_check_unlink(struct ucred *cred, struct shmfd *shmfd,
1835225344Srwatson    struct label *shmlabel)
1836225344Srwatson{
1837225344Srwatson	struct mac_biba *subj, *obj;
1838225344Srwatson
1839225344Srwatson	if (!biba_enabled)
1840225344Srwatson		return (0);
1841225344Srwatson
1842225344Srwatson	subj = SLOT(cred->cr_label);
1843225344Srwatson	obj = SLOT(shmlabel);
1844225344Srwatson
1845225344Srwatson	if (!biba_dominate_effective(subj, obj))
1846225344Srwatson		return (EACCES);
1847225344Srwatson
1848225344Srwatson	return (0);
1849225344Srwatson}
1850225344Srwatson
1851254603Skibstatic int
1852254603Skibbiba_posixshm_check_write(struct ucred *active_cred, struct ucred *file_cred,
1853254603Skib    struct shmfd *vp, struct label *shmlabel)
1854254603Skib{
1855254603Skib	struct mac_biba *subj, *obj;
1856254603Skib
1857254603Skib	if (!biba_enabled || !revocation_enabled)
1858254603Skib		return (0);
1859254603Skib
1860254603Skib	subj = SLOT(active_cred->cr_label);
1861254603Skib	obj = SLOT(shmlabel);
1862254603Skib
1863254603Skib	if (!biba_dominate_effective(obj, subj))
1864254603Skib		return (EACCES);
1865254603Skib
1866254603Skib	return (0);
1867254603Skib}
1868254603Skib
1869225344Srwatsonstatic void
1870225344Srwatsonbiba_posixshm_create(struct ucred *cred, struct shmfd *shmfd,
1871225344Srwatson    struct label *shmlabel)
1872225344Srwatson{
1873225344Srwatson	struct mac_biba *source, *dest;
1874225344Srwatson
1875225344Srwatson	source = SLOT(cred->cr_label);
1876225344Srwatson	dest = SLOT(shmlabel);
1877225344Srwatson
1878225344Srwatson	biba_copy_effective(source, dest);
1879225344Srwatson}
1880225344Srwatson
1881173138Srwatson/*
1882173138Srwatson * Some system privileges are allowed regardless of integrity grade; others
1883173138Srwatson * are allowed only when running with privilege with respect to the Biba
1884173138Srwatson * policy as they might otherwise allow bypassing of the integrity policy.
1885173138Srwatson */
1886140628Srwatsonstatic int
1887173138Srwatsonbiba_priv_check(struct ucred *cred, int priv)
1888140628Srwatson{
1889173138Srwatson	struct mac_biba *subj;
1890173138Srwatson	int error;
1891140628Srwatson
1892172955Srwatson	if (!biba_enabled)
1893140628Srwatson		return (0);
1894140628Srwatson
1895173138Srwatson	/*
1896173138Srwatson	 * Exempt only specific privileges from the Biba integrity policy.
1897173138Srwatson	 */
1898173138Srwatson	switch (priv) {
1899173138Srwatson	case PRIV_KTRACE:
1900173138Srwatson	case PRIV_MSGBUF:
1901140628Srwatson
1902173138Srwatson	/*
1903173138Srwatson	 * Allow processes to manipulate basic process audit properties, and
1904173138Srwatson	 * to submit audit records.
1905173138Srwatson	 */
1906173138Srwatson	case PRIV_AUDIT_GETAUDIT:
1907173138Srwatson	case PRIV_AUDIT_SETAUDIT:
1908173138Srwatson	case PRIV_AUDIT_SUBMIT:
1909140628Srwatson
1910173138Srwatson	/*
1911173138Srwatson	 * Allow processes to manipulate their regular UNIX credentials.
1912173138Srwatson	 */
1913173138Srwatson	case PRIV_CRED_SETUID:
1914173138Srwatson	case PRIV_CRED_SETEUID:
1915173138Srwatson	case PRIV_CRED_SETGID:
1916173138Srwatson	case PRIV_CRED_SETEGID:
1917173138Srwatson	case PRIV_CRED_SETGROUPS:
1918173138Srwatson	case PRIV_CRED_SETREUID:
1919173138Srwatson	case PRIV_CRED_SETREGID:
1920173138Srwatson	case PRIV_CRED_SETRESUID:
1921173138Srwatson	case PRIV_CRED_SETRESGID:
1922173138Srwatson
1923173138Srwatson	/*
1924173138Srwatson	 * Allow processes to perform system monitoring.
1925173138Srwatson	 */
1926173138Srwatson	case PRIV_SEEOTHERGIDS:
1927173138Srwatson	case PRIV_SEEOTHERUIDS:
1928173138Srwatson		break;
1929173138Srwatson
1930173138Srwatson	/*
1931173138Srwatson	 * Allow access to general process debugging facilities.  We
1932173138Srwatson	 * separately control debugging based on MAC label.
1933173138Srwatson	 */
1934173138Srwatson	case PRIV_DEBUG_DIFFCRED:
1935173138Srwatson	case PRIV_DEBUG_SUGID:
1936173138Srwatson	case PRIV_DEBUG_UNPRIV:
1937173138Srwatson
1938173138Srwatson	/*
1939173138Srwatson	 * Allow manipulating jails.
1940173138Srwatson	 */
1941173138Srwatson	case PRIV_JAIL_ATTACH:
1942173138Srwatson
1943173138Srwatson	/*
1944173138Srwatson	 * Allow privilege with respect to the Partition policy, but not the
1945173138Srwatson	 * Privs policy.
1946173138Srwatson	 */
1947173138Srwatson	case PRIV_MAC_PARTITION:
1948173138Srwatson
1949173138Srwatson	/*
1950173138Srwatson	 * Allow privilege with respect to process resource limits and login
1951173138Srwatson	 * context.
1952173138Srwatson	 */
1953173138Srwatson	case PRIV_PROC_LIMIT:
1954173138Srwatson	case PRIV_PROC_SETLOGIN:
1955173138Srwatson	case PRIV_PROC_SETRLIMIT:
1956173138Srwatson
1957173138Srwatson	/*
1958173138Srwatson	 * Allow System V and POSIX IPC privileges.
1959173138Srwatson	 */
1960173138Srwatson	case PRIV_IPC_READ:
1961173138Srwatson	case PRIV_IPC_WRITE:
1962173138Srwatson	case PRIV_IPC_ADMIN:
1963173138Srwatson	case PRIV_IPC_MSGSIZE:
1964173138Srwatson	case PRIV_MQ_ADMIN:
1965173138Srwatson
1966173138Srwatson	/*
1967173138Srwatson	 * Allow certain scheduler manipulations -- possibly this should be
1968173138Srwatson	 * controlled by more fine-grained policy, as potentially low
1969173138Srwatson	 * integrity processes can deny CPU to higher integrity ones.
1970173138Srwatson	 */
1971173138Srwatson	case PRIV_SCHED_DIFFCRED:
1972173138Srwatson	case PRIV_SCHED_SETPRIORITY:
1973173138Srwatson	case PRIV_SCHED_RTPRIO:
1974173138Srwatson	case PRIV_SCHED_SETPOLICY:
1975173138Srwatson	case PRIV_SCHED_SET:
1976173138Srwatson	case PRIV_SCHED_SETPARAM:
1977173138Srwatson
1978173138Srwatson	/*
1979173138Srwatson	 * More IPC privileges.
1980173138Srwatson	 */
1981173138Srwatson	case PRIV_SEM_WRITE:
1982173138Srwatson
1983173138Srwatson	/*
1984173138Srwatson	 * Allow signaling privileges subject to integrity policy.
1985173138Srwatson	 */
1986173138Srwatson	case PRIV_SIGNAL_DIFFCRED:
1987173138Srwatson	case PRIV_SIGNAL_SUGID:
1988173138Srwatson
1989173138Srwatson	/*
1990173138Srwatson	 * Allow access to only limited sysctls from lower integrity levels;
1991173138Srwatson	 * piggy-back on the Jail definition.
1992173138Srwatson	 */
1993173138Srwatson	case PRIV_SYSCTL_WRITEJAIL:
1994173138Srwatson
1995173138Srwatson	/*
1996173138Srwatson	 * Allow TTY-based privileges, subject to general device access using
1997173138Srwatson	 * labels on TTY device nodes, but not console privilege.
1998173138Srwatson	 */
1999173138Srwatson	case PRIV_TTY_DRAINWAIT:
2000173138Srwatson	case PRIV_TTY_DTRWAIT:
2001173138Srwatson	case PRIV_TTY_EXCLUSIVE:
2002173138Srwatson	case PRIV_TTY_STI:
2003173138Srwatson	case PRIV_TTY_SETA:
2004173138Srwatson
2005173138Srwatson	/*
2006173138Srwatson	 * Grant most VFS privileges, as almost all are in practice bounded
2007173138Srwatson	 * by more specific checks using labels.
2008173138Srwatson	 */
2009173138Srwatson	case PRIV_VFS_READ:
2010173138Srwatson	case PRIV_VFS_WRITE:
2011173138Srwatson	case PRIV_VFS_ADMIN:
2012173138Srwatson	case PRIV_VFS_EXEC:
2013173138Srwatson	case PRIV_VFS_LOOKUP:
2014173138Srwatson	case PRIV_VFS_CHFLAGS_DEV:
2015173138Srwatson	case PRIV_VFS_CHOWN:
2016173138Srwatson	case PRIV_VFS_CHROOT:
2017173138Srwatson	case PRIV_VFS_RETAINSUGID:
2018173138Srwatson	case PRIV_VFS_EXCEEDQUOTA:
2019173138Srwatson	case PRIV_VFS_FCHROOT:
2020173138Srwatson	case PRIV_VFS_FHOPEN:
2021173138Srwatson	case PRIV_VFS_FHSTATFS:
2022173138Srwatson	case PRIV_VFS_GENERATION:
2023173138Srwatson	case PRIV_VFS_GETFH:
2024173138Srwatson	case PRIV_VFS_GETQUOTA:
2025173138Srwatson	case PRIV_VFS_LINK:
2026173138Srwatson	case PRIV_VFS_MOUNT:
2027173138Srwatson	case PRIV_VFS_MOUNT_OWNER:
2028173138Srwatson	case PRIV_VFS_MOUNT_PERM:
2029173138Srwatson	case PRIV_VFS_MOUNT_SUIDDIR:
2030173138Srwatson	case PRIV_VFS_MOUNT_NONUSER:
2031173138Srwatson	case PRIV_VFS_SETGID:
2032173138Srwatson	case PRIV_VFS_STICKYFILE:
2033173138Srwatson	case PRIV_VFS_SYSFLAGS:
2034173138Srwatson	case PRIV_VFS_UNMOUNT:
2035173138Srwatson
2036173138Srwatson	/*
2037173138Srwatson	 * Allow VM privileges; it would be nice if these were subject to
2038173138Srwatson	 * resource limits.
2039173138Srwatson	 */
2040173138Srwatson	case PRIV_VM_MADV_PROTECT:
2041173138Srwatson	case PRIV_VM_MLOCK:
2042173138Srwatson	case PRIV_VM_MUNLOCK:
2043194766Skib	case PRIV_VM_SWAP_NOQUOTA:
2044194766Skib	case PRIV_VM_SWAP_NORLIMIT:
2045173138Srwatson
2046173138Srwatson	/*
2047173138Srwatson	 * Allow some but not all network privileges.  In general, dont allow
2048173138Srwatson	 * reconfiguring the network stack, just normal use.
2049173138Srwatson	 */
2050173138Srwatson	case PRIV_NETINET_RESERVEDPORT:
2051173138Srwatson	case PRIV_NETINET_RAW:
2052173138Srwatson	case PRIV_NETINET_REUSEPORT:
2053173138Srwatson		break;
2054173138Srwatson
2055173138Srwatson	/*
2056173138Srwatson	 * All remaining system privileges are allow only if the process
2057173138Srwatson	 * holds privilege with respect to the Biba policy.
2058173138Srwatson	 */
2059173138Srwatson	default:
2060173138Srwatson		subj = SLOT(cred->cr_label);
2061173138Srwatson		error = biba_subject_privileged(subj);
2062173138Srwatson		if (error)
2063173138Srwatson			return (error);
2064173138Srwatson	}
2065140628Srwatson	return (0);
2066140628Srwatson}
2067140628Srwatson
2068140628Srwatsonstatic int
2069173138Srwatsonbiba_proc_check_debug(struct ucred *cred, struct proc *p)
2070140628Srwatson{
2071140628Srwatson	struct mac_biba *subj, *obj;
2072140628Srwatson
2073172955Srwatson	if (!biba_enabled)
2074140628Srwatson		return (0);
2075140628Srwatson
2076140628Srwatson	subj = SLOT(cred->cr_label);
2077173138Srwatson	obj = SLOT(p->p_ucred->cr_label);
2078140628Srwatson
2079173138Srwatson	/* XXX: range checks */
2080172955Srwatson	if (!biba_dominate_effective(obj, subj))
2081173138Srwatson		return (ESRCH);
2082173138Srwatson	if (!biba_dominate_effective(subj, obj))
2083140628Srwatson		return (EACCES);
2084140628Srwatson
2085140628Srwatson	return (0);
2086140628Srwatson}
2087140628Srwatson
2088140628Srwatsonstatic int
2089173138Srwatsonbiba_proc_check_sched(struct ucred *cred, struct proc *p)
2090140628Srwatson{
2091140628Srwatson	struct mac_biba *subj, *obj;
2092140628Srwatson
2093172955Srwatson	if (!biba_enabled)
2094140628Srwatson		return (0);
2095140628Srwatson
2096140628Srwatson	subj = SLOT(cred->cr_label);
2097173138Srwatson	obj = SLOT(p->p_ucred->cr_label);
2098140628Srwatson
2099173138Srwatson	/* XXX: range checks */
2100173138Srwatson	if (!biba_dominate_effective(obj, subj))
2101173138Srwatson		return (ESRCH);
2102172955Srwatson	if (!biba_dominate_effective(subj, obj))
2103140628Srwatson		return (EACCES);
2104140628Srwatson
2105140628Srwatson	return (0);
2106140628Srwatson}
2107140628Srwatson
2108140628Srwatsonstatic int
2109173138Srwatsonbiba_proc_check_signal(struct ucred *cred, struct proc *p, int signum)
2110140628Srwatson{
2111140628Srwatson	struct mac_biba *subj, *obj;
2112140628Srwatson
2113172955Srwatson	if (!biba_enabled)
2114140628Srwatson		return (0);
2115140628Srwatson
2116140628Srwatson	subj = SLOT(cred->cr_label);
2117173138Srwatson	obj = SLOT(p->p_ucred->cr_label);
2118140628Srwatson
2119173138Srwatson	/* XXX: range checks */
2120172955Srwatson	if (!biba_dominate_effective(obj, subj))
2121173138Srwatson		return (ESRCH);
2122173138Srwatson	if (!biba_dominate_effective(subj, obj))
2123140628Srwatson		return (EACCES);
2124140628Srwatson
2125140628Srwatson	return (0);
2126140628Srwatson}
2127140628Srwatson
2128140628Srwatsonstatic int
2129173138Srwatsonbiba_socket_check_deliver(struct socket *so, struct label *solabel,
2130173138Srwatson    struct mbuf *m, struct label *mlabel)
2131140628Srwatson{
2132173138Srwatson	struct mac_biba *p, *s;
2133193391Srwatson	int error;
2134140628Srwatson
2135172955Srwatson	if (!biba_enabled)
2136140628Srwatson		return (0);
2137140628Srwatson
2138173138Srwatson	p = SLOT(mlabel);
2139173138Srwatson	s = SLOT(solabel);
2140140628Srwatson
2141193391Srwatson	SOCK_LOCK(so);
2142193391Srwatson	error = biba_equal_effective(p, s) ? 0 : EACCES;
2143193391Srwatson	SOCK_UNLOCK(so);
2144193391Srwatson	return (error);
2145173138Srwatson}
2146140628Srwatson
2147140628Srwatsonstatic int
2148173138Srwatsonbiba_socket_check_relabel(struct ucred *cred, struct socket *so,
2149173138Srwatson    struct label *solabel, struct label *newlabel)
2150140628Srwatson{
2151173138Srwatson	struct mac_biba *subj, *obj, *new;
2152173138Srwatson	int error;
2153140628Srwatson
2154193391Srwatson	SOCK_LOCK_ASSERT(so);
2155193391Srwatson
2156173138Srwatson	new = SLOT(newlabel);
2157140628Srwatson	subj = SLOT(cred->cr_label);
2158173138Srwatson	obj = SLOT(solabel);
2159140628Srwatson
2160173138Srwatson	/*
2161173138Srwatson	 * If there is a Biba label update for the socket, it may be an
2162173138Srwatson	 * update of effective.
2163173138Srwatson	 */
2164173138Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE);
2165173138Srwatson	if (error)
2166173138Srwatson		return (error);
2167140628Srwatson
2168173138Srwatson	/*
2169173138Srwatson	 * To relabel a socket, the old socket effective must be in the
2170173138Srwatson	 * subject range.
2171173138Srwatson	 */
2172173138Srwatson	if (!biba_effective_in_range(obj, subj))
2173173138Srwatson		return (EPERM);
2174140628Srwatson
2175173138Srwatson	/*
2176173138Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
2177173138Srwatson	 */
2178173138Srwatson	if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
2179173138Srwatson		/*
2180173138Srwatson		 * To relabel a socket, the new socket effective must be in
2181173138Srwatson		 * the subject range.
2182173138Srwatson		 */
2183173138Srwatson		if (!biba_effective_in_range(new, subj))
2184173138Srwatson			return (EPERM);
2185173138Srwatson
2186173138Srwatson		/*
2187173138Srwatson		 * To change the Biba label on the socket to contain EQUAL,
2188173138Srwatson		 * the subject must have appropriate privilege.
2189173138Srwatson		 */
2190173138Srwatson		if (biba_contains_equal(new)) {
2191173138Srwatson			error = biba_subject_privileged(subj);
2192173138Srwatson			if (error)
2193173138Srwatson				return (error);
2194173138Srwatson		}
2195140628Srwatson	}
2196140628Srwatson
2197140628Srwatson	return (0);
2198140628Srwatson}
2199140628Srwatson
2200140628Srwatsonstatic int
2201173138Srwatsonbiba_socket_check_visible(struct ucred *cred, struct socket *so,
2202173138Srwatson    struct label *solabel)
2203140628Srwatson{
2204140628Srwatson	struct mac_biba *subj, *obj;
2205140628Srwatson
2206172955Srwatson	if (!biba_enabled)
2207140628Srwatson		return (0);
2208140628Srwatson
2209140628Srwatson	subj = SLOT(cred->cr_label);
2210173138Srwatson	obj = SLOT(solabel);
2211140628Srwatson
2212193391Srwatson	SOCK_LOCK(so);
2213193391Srwatson	if (!biba_dominate_effective(obj, subj)) {
2214193391Srwatson		SOCK_UNLOCK(so);
2215173138Srwatson		return (ENOENT);
2216193391Srwatson	}
2217193391Srwatson	SOCK_UNLOCK(so);
2218140628Srwatson
2219140628Srwatson	return (0);
2220140628Srwatson}
2221140628Srwatson
2222173138Srwatsonstatic void
2223173138Srwatsonbiba_socket_create(struct ucred *cred, struct socket *so,
2224173138Srwatson    struct label *solabel)
2225140628Srwatson{
2226173138Srwatson	struct mac_biba *source, *dest;
2227140628Srwatson
2228173138Srwatson	source = SLOT(cred->cr_label);
2229173138Srwatson	dest = SLOT(solabel);
2230140628Srwatson
2231173138Srwatson	biba_copy_effective(source, dest);
2232173138Srwatson}
2233140628Srwatson
2234173138Srwatsonstatic void
2235173138Srwatsonbiba_socket_create_mbuf(struct socket *so, struct label *solabel,
2236173138Srwatson    struct mbuf *m, struct label *mlabel)
2237173138Srwatson{
2238173138Srwatson	struct mac_biba *source, *dest;
2239140628Srwatson
2240173138Srwatson	source = SLOT(solabel);
2241173138Srwatson	dest = SLOT(mlabel);
2242140628Srwatson
2243193391Srwatson	SOCK_LOCK(so);
2244173138Srwatson	biba_copy_effective(source, dest);
2245193391Srwatson	SOCK_UNLOCK(so);
2246140628Srwatson}
2247140628Srwatson
2248173138Srwatsonstatic void
2249173138Srwatsonbiba_socket_newconn(struct socket *oldso, struct label *oldsolabel,
2250173138Srwatson    struct socket *newso, struct label *newsolabel)
2251140628Srwatson{
2252193391Srwatson	struct mac_biba source, *dest;
2253140628Srwatson
2254193391Srwatson	SOCK_LOCK(oldso);
2255193391Srwatson	source = *SLOT(oldsolabel);
2256193391Srwatson	SOCK_UNLOCK(oldso);
2257193391Srwatson
2258173138Srwatson	dest = SLOT(newsolabel);
2259140628Srwatson
2260193391Srwatson	SOCK_LOCK(newso);
2261193391Srwatson	biba_copy_effective(&source, dest);
2262193391Srwatson	SOCK_UNLOCK(newso);
2263140628Srwatson}
2264140628Srwatson
2265173138Srwatsonstatic void
2266173138Srwatsonbiba_socket_relabel(struct ucred *cred, struct socket *so,
2267173138Srwatson    struct label *solabel, struct label *newlabel)
2268140628Srwatson{
2269173138Srwatson	struct mac_biba *source, *dest;
2270140628Srwatson
2271193391Srwatson	SOCK_LOCK_ASSERT(so);
2272193391Srwatson
2273173138Srwatson	source = SLOT(newlabel);
2274173138Srwatson	dest = SLOT(solabel);
2275140628Srwatson
2276173138Srwatson	biba_copy(source, dest);
2277173138Srwatson}
2278140628Srwatson
2279173138Srwatsonstatic void
2280173138Srwatsonbiba_socketpeer_set_from_mbuf(struct mbuf *m, struct label *mlabel,
2281173138Srwatson    struct socket *so, struct label *sopeerlabel)
2282173138Srwatson{
2283173138Srwatson	struct mac_biba *source, *dest;
2284140628Srwatson
2285173138Srwatson	source = SLOT(mlabel);
2286173138Srwatson	dest = SLOT(sopeerlabel);
2287140628Srwatson
2288193391Srwatson	SOCK_LOCK(so);
2289173138Srwatson	biba_copy_effective(source, dest);
2290193391Srwatson	SOCK_UNLOCK(so);
2291140628Srwatson}
2292140628Srwatson
2293173138Srwatsonstatic void
2294173138Srwatsonbiba_socketpeer_set_from_socket(struct socket *oldso,
2295173138Srwatson    struct label *oldsolabel, struct socket *newso,
2296173138Srwatson    struct label *newsopeerlabel)
2297140628Srwatson{
2298193391Srwatson	struct mac_biba source, *dest;
2299140628Srwatson
2300193391Srwatson	SOCK_LOCK(oldso);
2301193391Srwatson	source = *SLOT(oldsolabel);
2302193391Srwatson	SOCK_UNLOCK(oldso);
2303173138Srwatson	dest = SLOT(newsopeerlabel);
2304140628Srwatson
2305193391Srwatson	SOCK_LOCK(newso);
2306193391Srwatson	biba_copy_effective(&source, dest);
2307193391Srwatson	SOCK_UNLOCK(newso);
2308173138Srwatson}
2309140628Srwatson
2310173138Srwatsonstatic void
2311173138Srwatsonbiba_syncache_create(struct label *label, struct inpcb *inp)
2312173138Srwatson{
2313173138Srwatson	struct mac_biba *source, *dest;
2314140628Srwatson
2315173138Srwatson	source = SLOT(inp->inp_label);
2316173138Srwatson	dest = SLOT(label);
2317173138Srwatson	biba_copy_effective(source, dest);
2318140628Srwatson}
2319140628Srwatson
2320173138Srwatsonstatic void
2321173138Srwatsonbiba_syncache_create_mbuf(struct label *sc_label, struct mbuf *m,
2322173138Srwatson    struct label *mlabel)
2323173138Srwatson{
2324173138Srwatson	struct mac_biba *source, *dest;
2325173138Srwatson
2326173138Srwatson	source = SLOT(sc_label);
2327173138Srwatson	dest = SLOT(mlabel);
2328173138Srwatson	biba_copy_effective(source, dest);
2329173138Srwatson}
2330173138Srwatson
2331140628Srwatsonstatic int
2332173138Srwatsonbiba_system_check_acct(struct ucred *cred, struct vnode *vp,
2333168976Srwatson    struct label *vplabel)
2334110354Srwatson{
2335110354Srwatson	struct mac_biba *subj, *obj;
2336110354Srwatson	int error;
2337110354Srwatson
2338172955Srwatson	if (!biba_enabled)
2339110354Srwatson		return (0);
2340110354Srwatson
2341122524Srwatson	subj = SLOT(cred->cr_label);
2342110354Srwatson
2343172955Srwatson	error = biba_subject_privileged(subj);
2344110354Srwatson	if (error)
2345110354Srwatson		return (error);
2346110354Srwatson
2347173138Srwatson	if (vplabel == NULL)
2348173138Srwatson		return (0);
2349173138Srwatson
2350168976Srwatson	obj = SLOT(vplabel);
2351172955Srwatson	if (!biba_high_effective(obj))
2352110354Srwatson		return (EACCES);
2353110354Srwatson
2354110354Srwatson	return (0);
2355110354Srwatson}
2356110354Srwatson
2357110354Srwatsonstatic int
2358173138Srwatsonbiba_system_check_auditctl(struct ucred *cred, struct vnode *vp,
2359173138Srwatson    struct label *vplabel)
2360101099Srwatson{
2361101099Srwatson	struct mac_biba *subj, *obj;
2362173138Srwatson	int error;
2363101099Srwatson
2364172955Srwatson	if (!biba_enabled)
2365101099Srwatson		return (0);
2366101099Srwatson
2367122524Srwatson	subj = SLOT(cred->cr_label);
2368101099Srwatson
2369173138Srwatson	error = biba_subject_privileged(subj);
2370173138Srwatson	if (error)
2371173138Srwatson		return (error);
2372173138Srwatson
2373173138Srwatson	if (vplabel == NULL)
2374173138Srwatson		return (0);
2375173138Srwatson
2376173138Srwatson	obj = SLOT(vplabel);
2377173138Srwatson	if (!biba_high_effective(obj))
2378101099Srwatson		return (EACCES);
2379101099Srwatson
2380101099Srwatson	return (0);
2381101099Srwatson}
2382101099Srwatson
2383101099Srwatsonstatic int
2384173138Srwatsonbiba_system_check_auditon(struct ucred *cred, int cmd)
2385101099Srwatson{
2386173138Srwatson	struct mac_biba *subj;
2387173138Srwatson	int error;
2388103759Srwatson
2389173138Srwatson	if (!biba_enabled)
2390101099Srwatson		return (0);
2391101099Srwatson
2392173138Srwatson	subj = SLOT(cred->cr_label);
2393101099Srwatson
2394173138Srwatson	error = biba_subject_privileged(subj);
2395173138Srwatson	if (error)
2396173138Srwatson		return (error);
2397173138Srwatson
2398101099Srwatson	return (0);
2399101099Srwatson}
2400101099Srwatson
2401101099Srwatsonstatic int
2402173138Srwatsonbiba_system_check_swapoff(struct ucred *cred, struct vnode *vp,
2403173138Srwatson    struct label *label)
2404101099Srwatson{
2405173138Srwatson	struct mac_biba *subj;
2406173138Srwatson	int error;
2407101099Srwatson
2408172955Srwatson	if (!biba_enabled)
2409101099Srwatson		return (0);
2410101099Srwatson
2411122524Srwatson	subj = SLOT(cred->cr_label);
2412101099Srwatson
2413173138Srwatson	error = biba_subject_privileged(subj);
2414173138Srwatson	if (error)
2415173138Srwatson		return (error);
2416101099Srwatson
2417101099Srwatson	return (0);
2418101099Srwatson}
2419101099Srwatson
2420101099Srwatsonstatic int
2421173138Srwatsonbiba_system_check_swapon(struct ucred *cred, struct vnode *vp,
2422173138Srwatson    struct label *vplabel)
2423102115Srwatson{
2424102115Srwatson	struct mac_biba *subj, *obj;
2425173138Srwatson	int error;
2426102115Srwatson
2427172955Srwatson	if (!biba_enabled)
2428102115Srwatson		return (0);
2429102115Srwatson
2430122524Srwatson	subj = SLOT(cred->cr_label);
2431173138Srwatson	obj = SLOT(vplabel);
2432102115Srwatson
2433173138Srwatson	error = biba_subject_privileged(subj);
2434173138Srwatson	if (error)
2435173138Srwatson		return (error);
2436173138Srwatson
2437173138Srwatson	if (!biba_high_effective(obj))
2438102115Srwatson		return (EACCES);
2439102115Srwatson
2440102115Srwatson	return (0);
2441102115Srwatson}
2442102115Srwatson
2443102115Srwatsonstatic int
2444173138Srwatsonbiba_system_check_sysctl(struct ucred *cred, struct sysctl_oid *oidp,
2445173138Srwatson    void *arg1, int arg2, struct sysctl_req *req)
2446101099Srwatson{
2447173138Srwatson	struct mac_biba *subj;
2448105634Srwatson	int error;
2449101099Srwatson
2450173138Srwatson	if (!biba_enabled)
2451173138Srwatson		return (0);
2452173138Srwatson
2453122524Srwatson	subj = SLOT(cred->cr_label);
2454101099Srwatson
2455101099Srwatson	/*
2456173138Srwatson	 * Treat sysctl variables without CTLFLAG_ANYBODY flag as biba/high,
2457173138Srwatson	 * but also require privilege to change them.
2458101099Srwatson	 */
2459173138Srwatson	if (req->newptr != NULL && (oidp->oid_kind & CTLFLAG_ANYBODY) == 0) {
2460173138Srwatson		if (!biba_subject_dominate_high(subj))
2461173138Srwatson			return (EACCES);
2462101099Srwatson
2463173138Srwatson		error = biba_subject_privileged(subj);
2464173138Srwatson		if (error)
2465173138Srwatson			return (error);
2466105634Srwatson	}
2467105634Srwatson
2468101099Srwatson	return (0);
2469101099Srwatson}
2470101099Srwatson
2471173138Srwatsonstatic void
2472173138Srwatsonbiba_sysvmsg_cleanup(struct label *msglabel)
2473102115Srwatson{
2474102115Srwatson
2475173138Srwatson	bzero(SLOT(msglabel), sizeof(struct mac_biba));
2476173138Srwatson}
2477102115Srwatson
2478173138Srwatsonstatic void
2479173138Srwatsonbiba_sysvmsg_create(struct ucred *cred, struct msqid_kernel *msqkptr,
2480173138Srwatson    struct label *msqlabel, struct msg *msgptr, struct label *msglabel)
2481173138Srwatson{
2482173138Srwatson	struct mac_biba *source, *dest;
2483102115Srwatson
2484173138Srwatson	/* Ignore the msgq label */
2485173138Srwatson	source = SLOT(cred->cr_label);
2486173138Srwatson	dest = SLOT(msglabel);
2487102115Srwatson
2488173138Srwatson	biba_copy_effective(source, dest);
2489102115Srwatson}
2490102115Srwatson
2491102115Srwatsonstatic int
2492173138Srwatsonbiba_sysvmsq_check_msgrcv(struct ucred *cred, struct msg *msgptr,
2493173138Srwatson    struct label *msglabel)
2494102115Srwatson{
2495102115Srwatson	struct mac_biba *subj, *obj;
2496102115Srwatson
2497172955Srwatson	if (!biba_enabled)
2498102115Srwatson		return (0);
2499102115Srwatson
2500122524Srwatson	subj = SLOT(cred->cr_label);
2501173138Srwatson	obj = SLOT(msglabel);
2502102115Srwatson
2503173138Srwatson	if (!biba_dominate_effective(obj, subj))
2504102115Srwatson		return (EACCES);
2505102115Srwatson
2506102115Srwatson	return (0);
2507102115Srwatson}
2508102115Srwatson
2509102115Srwatsonstatic int
2510173138Srwatsonbiba_sysvmsq_check_msgrmid(struct ucred *cred, struct msg *msgptr,
2511173138Srwatson    struct label *msglabel)
2512145855Srwatson{
2513145855Srwatson	struct mac_biba *subj, *obj;
2514145855Srwatson
2515172955Srwatson	if (!biba_enabled)
2516145855Srwatson		return (0);
2517145855Srwatson
2518145855Srwatson	subj = SLOT(cred->cr_label);
2519173138Srwatson	obj = SLOT(msglabel);
2520145855Srwatson
2521172955Srwatson	if (!biba_dominate_effective(subj, obj))
2522145855Srwatson		return (EACCES);
2523145855Srwatson
2524145855Srwatson	return (0);
2525145855Srwatson}
2526145855Srwatson
2527145855Srwatsonstatic int
2528173138Srwatsonbiba_sysvmsq_check_msqget(struct ucred *cred, struct msqid_kernel *msqkptr,
2529173138Srwatson    struct label *msqklabel)
2530145855Srwatson{
2531145855Srwatson	struct mac_biba *subj, *obj;
2532145855Srwatson
2533172955Srwatson	if (!biba_enabled)
2534145855Srwatson		return (0);
2535145855Srwatson
2536145855Srwatson	subj = SLOT(cred->cr_label);
2537173138Srwatson	obj = SLOT(msqklabel);
2538145855Srwatson
2539172955Srwatson	if (!biba_dominate_effective(obj, subj))
2540145855Srwatson		return (EACCES);
2541145855Srwatson
2542145855Srwatson	return (0);
2543145855Srwatson}
2544145855Srwatson
2545145855Srwatsonstatic int
2546173138Srwatsonbiba_sysvmsq_check_msqsnd(struct ucred *cred, struct msqid_kernel *msqkptr,
2547173138Srwatson    struct label *msqklabel)
2548101099Srwatson{
2549101099Srwatson	struct mac_biba *subj, *obj;
2550101099Srwatson
2551172955Srwatson	if (!biba_enabled)
2552101099Srwatson		return (0);
2553101099Srwatson
2554122524Srwatson	subj = SLOT(cred->cr_label);
2555173138Srwatson	obj = SLOT(msqklabel);
2556101099Srwatson
2557172955Srwatson	if (!biba_dominate_effective(subj, obj))
2558101099Srwatson		return (EACCES);
2559101099Srwatson
2560101099Srwatson	return (0);
2561101099Srwatson}
2562101099Srwatson
2563101099Srwatsonstatic int
2564173138Srwatsonbiba_sysvmsq_check_msqrcv(struct ucred *cred, struct msqid_kernel *msqkptr,
2565173138Srwatson    struct label *msqklabel)
2566101099Srwatson{
2567101099Srwatson	struct mac_biba *subj, *obj;
2568103759Srwatson
2569172955Srwatson	if (!biba_enabled)
2570101099Srwatson		return (0);
2571101099Srwatson
2572122524Srwatson	subj = SLOT(cred->cr_label);
2573173138Srwatson	obj = SLOT(msqklabel);
2574103759Srwatson
2575172955Srwatson	if (!biba_dominate_effective(obj, subj))
2576101099Srwatson		return (EACCES);
2577101099Srwatson
2578101099Srwatson	return (0);
2579101099Srwatson}
2580101099Srwatson
2581101099Srwatsonstatic int
2582173138Srwatsonbiba_sysvmsq_check_msqctl(struct ucred *cred, struct msqid_kernel *msqkptr,
2583173138Srwatson    struct label *msqklabel, int cmd)
2584101099Srwatson{
2585101099Srwatson	struct mac_biba *subj, *obj;
2586103759Srwatson
2587172955Srwatson	if (!biba_enabled)
2588101099Srwatson		return (0);
2589101099Srwatson
2590122524Srwatson	subj = SLOT(cred->cr_label);
2591173138Srwatson	obj = SLOT(msqklabel);
2592103759Srwatson
2593173138Srwatson	switch(cmd) {
2594173138Srwatson	case IPC_RMID:
2595173138Srwatson	case IPC_SET:
2596173138Srwatson		if (!biba_dominate_effective(subj, obj))
2597173138Srwatson			return (EACCES);
2598173138Srwatson		break;
2599173138Srwatson
2600173138Srwatson	case IPC_STAT:
2601173138Srwatson		if (!biba_dominate_effective(obj, subj))
2602173138Srwatson			return (EACCES);
2603173138Srwatson		break;
2604173138Srwatson
2605173138Srwatson	default:
2606101099Srwatson		return (EACCES);
2607173138Srwatson	}
2608101099Srwatson
2609101099Srwatson	return (0);
2610101099Srwatson}
2611101099Srwatson
2612173138Srwatsonstatic void
2613173138Srwatsonbiba_sysvmsq_cleanup(struct label *msqlabel)
2614101099Srwatson{
2615101099Srwatson
2616173138Srwatson	bzero(SLOT(msqlabel), sizeof(struct mac_biba));
2617173138Srwatson}
2618101099Srwatson
2619173138Srwatsonstatic void
2620173138Srwatsonbiba_sysvmsq_create(struct ucred *cred, struct msqid_kernel *msqkptr,
2621173138Srwatson    struct label *msqlabel)
2622173138Srwatson{
2623173138Srwatson	struct mac_biba *source, *dest;
2624101099Srwatson
2625173138Srwatson	source = SLOT(cred->cr_label);
2626173138Srwatson	dest = SLOT(msqlabel);
2627173138Srwatson
2628173138Srwatson	biba_copy_effective(source, dest);
2629101099Srwatson}
2630101099Srwatson
2631101099Srwatsonstatic int
2632173138Srwatsonbiba_sysvsem_check_semctl(struct ucred *cred, struct semid_kernel *semakptr,
2633173138Srwatson    struct label *semaklabel, int cmd)
2634101099Srwatson{
2635173138Srwatson	struct mac_biba *subj, *obj;
2636101099Srwatson
2637173138Srwatson	if (!biba_enabled)
2638173138Srwatson		return (0);
2639173138Srwatson
2640122524Srwatson	subj = SLOT(cred->cr_label);
2641173138Srwatson	obj = SLOT(semaklabel);
2642101099Srwatson
2643173138Srwatson	switch(cmd) {
2644173138Srwatson	case IPC_RMID:
2645173138Srwatson	case IPC_SET:
2646173138Srwatson	case SETVAL:
2647173138Srwatson	case SETALL:
2648173138Srwatson		if (!biba_dominate_effective(subj, obj))
2649173138Srwatson			return (EACCES);
2650173138Srwatson		break;
2651101099Srwatson
2652173138Srwatson	case IPC_STAT:
2653173138Srwatson	case GETVAL:
2654173138Srwatson	case GETPID:
2655173138Srwatson	case GETNCNT:
2656173138Srwatson	case GETZCNT:
2657173138Srwatson	case GETALL:
2658173138Srwatson		if (!biba_dominate_effective(obj, subj))
2659173138Srwatson			return (EACCES);
2660173138Srwatson		break;
2661101099Srwatson
2662173138Srwatson	default:
2663173138Srwatson		return (EACCES);
2664105634Srwatson	}
2665105634Srwatson
2666101099Srwatson	return (0);
2667101099Srwatson}
2668101099Srwatson
2669101099Srwatsonstatic int
2670173138Srwatsonbiba_sysvsem_check_semget(struct ucred *cred, struct semid_kernel *semakptr,
2671173138Srwatson    struct label *semaklabel)
2672101099Srwatson{
2673101099Srwatson	struct mac_biba *subj, *obj;
2674101099Srwatson
2675172955Srwatson	if (!biba_enabled)
2676105722Srwatson		return (0);
2677105722Srwatson
2678122524Srwatson	subj = SLOT(cred->cr_label);
2679173138Srwatson	obj = SLOT(semaklabel);
2680101099Srwatson
2681172955Srwatson	if (!biba_dominate_effective(obj, subj))
2682173138Srwatson		return (EACCES);
2683101099Srwatson
2684101099Srwatson	return (0);
2685101099Srwatson}
2686101099Srwatson
2687101099Srwatsonstatic int
2688173138Srwatsonbiba_sysvsem_check_semop(struct ucred *cred, struct semid_kernel *semakptr,
2689173138Srwatson    struct label *semaklabel, size_t accesstype)
2690112574Srwatson{
2691173138Srwatson	struct mac_biba *subj, *obj;
2692112574Srwatson
2693172955Srwatson	if (!biba_enabled)
2694112574Srwatson		return (0);
2695112574Srwatson
2696173138Srwatson	subj = SLOT(cred->cr_label);
2697173138Srwatson	obj = SLOT(semaklabel);
2698112574Srwatson
2699173138Srwatson	if (accesstype & SEM_R)
2700173138Srwatson		if (!biba_dominate_effective(obj, subj))
2701173138Srwatson			return (EACCES);
2702112574Srwatson
2703173138Srwatson	if (accesstype & SEM_A)
2704173138Srwatson		if (!biba_dominate_effective(subj, obj))
2705173138Srwatson			return (EACCES);
2706168951Srwatson
2707173138Srwatson	return (0);
2708173138Srwatson}
2709168951Srwatson
2710173138Srwatsonstatic void
2711173138Srwatsonbiba_sysvsem_cleanup(struct label *semalabel)
2712173138Srwatson{
2713168951Srwatson
2714173138Srwatson	bzero(SLOT(semalabel), sizeof(struct mac_biba));
2715173138Srwatson}
2716168951Srwatson
2717173138Srwatsonstatic void
2718173138Srwatsonbiba_sysvsem_create(struct ucred *cred, struct semid_kernel *semakptr,
2719173138Srwatson    struct label *semalabel)
2720173138Srwatson{
2721173138Srwatson	struct mac_biba *source, *dest;
2722168951Srwatson
2723173138Srwatson	source = SLOT(cred->cr_label);
2724173138Srwatson	dest = SLOT(semalabel);
2725168951Srwatson
2726173138Srwatson	biba_copy_effective(source, dest);
2727112574Srwatson}
2728112574Srwatson
2729112574Srwatsonstatic int
2730173138Srwatsonbiba_sysvshm_check_shmat(struct ucred *cred, struct shmid_kernel *shmsegptr,
2731173138Srwatson    struct label *shmseglabel, int shmflg)
2732106418Srwatson{
2733106418Srwatson	struct mac_biba *subj, *obj;
2734106418Srwatson
2735172955Srwatson	if (!biba_enabled)
2736106418Srwatson		return (0);
2737106418Srwatson
2738122524Srwatson	subj = SLOT(cred->cr_label);
2739173138Srwatson	obj = SLOT(shmseglabel);
2740106418Srwatson
2741173138Srwatson	if (!biba_dominate_effective(obj, subj))
2742106418Srwatson		return (EACCES);
2743173138Srwatson	if ((shmflg & SHM_RDONLY) == 0) {
2744173138Srwatson		if (!biba_dominate_effective(subj, obj))
2745173138Srwatson			return (EACCES);
2746173138Srwatson	}
2747173138Srwatson
2748106418Srwatson	return (0);
2749106418Srwatson}
2750106418Srwatson
2751106418Srwatsonstatic int
2752173138Srwatsonbiba_sysvshm_check_shmctl(struct ucred *cred, struct shmid_kernel *shmsegptr,
2753173138Srwatson    struct label *shmseglabel, int cmd)
2754168933Srwatson{
2755168933Srwatson	struct mac_biba *subj, *obj;
2756168933Srwatson
2757172955Srwatson	if (!biba_enabled)
2758168933Srwatson		return (0);
2759168933Srwatson
2760168933Srwatson	subj = SLOT(cred->cr_label);
2761173138Srwatson	obj = SLOT(shmseglabel);
2762168933Srwatson
2763173138Srwatson	switch(cmd) {
2764173138Srwatson	case IPC_RMID:
2765173138Srwatson	case IPC_SET:
2766173138Srwatson		if (!biba_dominate_effective(subj, obj))
2767173138Srwatson			return (EACCES);
2768173138Srwatson		break;
2769168933Srwatson
2770173138Srwatson	case IPC_STAT:
2771173138Srwatson	case SHM_STAT:
2772173138Srwatson		if (!biba_dominate_effective(obj, subj))
2773173138Srwatson			return (EACCES);
2774173138Srwatson		break;
2775168933Srwatson
2776173138Srwatson	default:
2777168933Srwatson		return (EACCES);
2778173138Srwatson	}
2779168933Srwatson
2780168933Srwatson	return (0);
2781168933Srwatson}
2782168933Srwatson
2783168933Srwatsonstatic int
2784173138Srwatsonbiba_sysvshm_check_shmget(struct ucred *cred, struct shmid_kernel *shmsegptr,
2785173138Srwatson    struct label *shmseglabel, int shmflg)
2786168933Srwatson{
2787173138Srwatson	struct mac_biba *subj, *obj;
2788168933Srwatson
2789172955Srwatson	if (!biba_enabled)
2790168933Srwatson		return (0);
2791168933Srwatson
2792168933Srwatson	subj = SLOT(cred->cr_label);
2793173138Srwatson	obj = SLOT(shmseglabel);
2794168933Srwatson
2795173138Srwatson	if (!biba_dominate_effective(obj, subj))
2796173138Srwatson		return (EACCES);
2797168933Srwatson
2798168933Srwatson	return (0);
2799168933Srwatson}
2800168933Srwatson
2801173138Srwatsonstatic void
2802173138Srwatsonbiba_sysvshm_cleanup(struct label *shmlabel)
2803106161Srwatson{
2804106161Srwatson
2805173138Srwatson	bzero(SLOT(shmlabel), sizeof(struct mac_biba));
2806173138Srwatson}
2807106161Srwatson
2808173138Srwatsonstatic void
2809173138Srwatsonbiba_sysvshm_create(struct ucred *cred, struct shmid_kernel *shmsegptr,
2810173138Srwatson    struct label *shmlabel)
2811173138Srwatson{
2812173138Srwatson	struct mac_biba *source, *dest;
2813106161Srwatson
2814173138Srwatson	source = SLOT(cred->cr_label);
2815173138Srwatson	dest = SLOT(shmlabel);
2816106161Srwatson
2817173138Srwatson	biba_copy_effective(source, dest);
2818106161Srwatson}
2819106161Srwatson
2820106161Srwatsonstatic int
2821173138Srwatsonbiba_vnode_associate_extattr(struct mount *mp, struct label *mplabel,
2822173138Srwatson    struct vnode *vp, struct label *vplabel)
2823112574Srwatson{
2824173138Srwatson	struct mac_biba mb_temp, *source, *dest;
2825173138Srwatson	int buflen, error;
2826112574Srwatson
2827173138Srwatson	source = SLOT(mplabel);
2828173138Srwatson	dest = SLOT(vplabel);
2829112574Srwatson
2830173138Srwatson	buflen = sizeof(mb_temp);
2831173138Srwatson	bzero(&mb_temp, buflen);
2832112574Srwatson
2833173138Srwatson	error = vn_extattr_get(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
2834173138Srwatson	    MAC_BIBA_EXTATTR_NAME, &buflen, (char *) &mb_temp, curthread);
2835173138Srwatson	if (error == ENOATTR || error == EOPNOTSUPP) {
2836173138Srwatson		/* Fall back to the mntlabel. */
2837173138Srwatson		biba_copy_effective(source, dest);
2838173138Srwatson		return (0);
2839173138Srwatson	} else if (error)
2840112574Srwatson		return (error);
2841112574Srwatson
2842173138Srwatson	if (buflen != sizeof(mb_temp)) {
2843173138Srwatson		printf("biba_vnode_associate_extattr: bad size %d\n",
2844173138Srwatson		    buflen);
2845173138Srwatson		return (EPERM);
2846173138Srwatson	}
2847173138Srwatson	if (biba_valid(&mb_temp) != 0) {
2848173138Srwatson		printf("biba_vnode_associate_extattr: invalid\n");
2849173138Srwatson		return (EPERM);
2850173138Srwatson	}
2851173138Srwatson	if ((mb_temp.mb_flags & MAC_BIBA_FLAGS_BOTH) !=
2852173138Srwatson	    MAC_BIBA_FLAG_EFFECTIVE) {
2853173138Srwatson		printf("biba_vnode_associate_extattr: not effective\n");
2854173138Srwatson		return (EPERM);
2855173138Srwatson	}
2856173138Srwatson
2857173138Srwatson	biba_copy_effective(&mb_temp, dest);
2858112574Srwatson	return (0);
2859112574Srwatson}
2860112574Srwatson
2861173138Srwatsonstatic void
2862173138Srwatsonbiba_vnode_associate_singlelabel(struct mount *mp, struct label *mplabel,
2863173138Srwatson    struct vnode *vp, struct label *vplabel)
2864106161Srwatson{
2865173138Srwatson	struct mac_biba *source, *dest;
2866106161Srwatson
2867173138Srwatson	source = SLOT(mplabel);
2868173138Srwatson	dest = SLOT(vplabel);
2869106161Srwatson
2870173138Srwatson	biba_copy_effective(source, dest);
2871106161Srwatson}
2872106161Srwatson
2873106161Srwatsonstatic int
2874172955Srwatsonbiba_vnode_check_chdir(struct ucred *cred, struct vnode *dvp,
2875168976Srwatson    struct label *dvplabel)
2876101099Srwatson{
2877101099Srwatson	struct mac_biba *subj, *obj;
2878101099Srwatson
2879172955Srwatson	if (!biba_enabled)
2880101099Srwatson		return (0);
2881101099Srwatson
2882122524Srwatson	subj = SLOT(cred->cr_label);
2883168976Srwatson	obj = SLOT(dvplabel);
2884101099Srwatson
2885172955Srwatson	if (!biba_dominate_effective(obj, subj))
2886101099Srwatson		return (EACCES);
2887101099Srwatson
2888101099Srwatson	return (0);
2889101099Srwatson}
2890101099Srwatson
2891101099Srwatsonstatic int
2892172955Srwatsonbiba_vnode_check_chroot(struct ucred *cred, struct vnode *dvp,
2893168976Srwatson    struct label *dvplabel)
2894101099Srwatson{
2895101099Srwatson	struct mac_biba *subj, *obj;
2896101099Srwatson
2897172955Srwatson	if (!biba_enabled)
2898101099Srwatson		return (0);
2899101099Srwatson
2900122524Srwatson	subj = SLOT(cred->cr_label);
2901168976Srwatson	obj = SLOT(dvplabel);
2902101099Srwatson
2903172955Srwatson	if (!biba_dominate_effective(obj, subj))
2904101099Srwatson		return (EACCES);
2905101099Srwatson
2906101099Srwatson	return (0);
2907101099Srwatson}
2908101099Srwatson
2909101099Srwatsonstatic int
2910172955Srwatsonbiba_vnode_check_create(struct ucred *cred, struct vnode *dvp,
2911168976Srwatson    struct label *dvplabel, struct componentname *cnp, struct vattr *vap)
2912101099Srwatson{
2913101099Srwatson	struct mac_biba *subj, *obj;
2914101099Srwatson
2915172955Srwatson	if (!biba_enabled)
2916101099Srwatson		return (0);
2917101099Srwatson
2918122524Srwatson	subj = SLOT(cred->cr_label);
2919168976Srwatson	obj = SLOT(dvplabel);
2920101099Srwatson
2921172955Srwatson	if (!biba_dominate_effective(subj, obj))
2922101099Srwatson		return (EACCES);
2923101099Srwatson
2924101099Srwatson	return (0);
2925101099Srwatson}
2926101099Srwatson
2927101099Srwatsonstatic int
2928172955Srwatsonbiba_vnode_check_deleteacl(struct ucred *cred, struct vnode *vp,
2929168976Srwatson    struct label *vplabel, acl_type_t type)
2930101099Srwatson{
2931101099Srwatson	struct mac_biba *subj, *obj;
2932101099Srwatson
2933172955Srwatson	if (!biba_enabled)
2934101099Srwatson		return (0);
2935101099Srwatson
2936122524Srwatson	subj = SLOT(cred->cr_label);
2937168976Srwatson	obj = SLOT(vplabel);
2938101099Srwatson
2939172955Srwatson	if (!biba_dominate_effective(subj, obj))
2940101099Srwatson		return (EACCES);
2941101099Srwatson
2942101099Srwatson	return (0);
2943101099Srwatson}
2944101099Srwatson
2945101099Srwatsonstatic int
2946172955Srwatsonbiba_vnode_check_deleteextattr(struct ucred *cred, struct vnode *vp,
2947168976Srwatson    struct label *vplabel, int attrnamespace, const char *name)
2948119202Srwatson{
2949119202Srwatson	struct mac_biba *subj, *obj;
2950119202Srwatson
2951172955Srwatson	if (!biba_enabled)
2952119202Srwatson		return (0);
2953119202Srwatson
2954122524Srwatson	subj = SLOT(cred->cr_label);
2955168976Srwatson	obj = SLOT(vplabel);
2956119202Srwatson
2957172955Srwatson	if (!biba_dominate_effective(subj, obj))
2958119202Srwatson		return (EACCES);
2959119202Srwatson
2960119202Srwatson	return (0);
2961119202Srwatson}
2962119202Srwatson
2963119202Srwatsonstatic int
2964172955Srwatsonbiba_vnode_check_exec(struct ucred *cred, struct vnode *vp,
2965168976Srwatson    struct label *vplabel, struct image_params *imgp,
2966106648Srwatson    struct label *execlabel)
2967101099Srwatson{
2968106648Srwatson	struct mac_biba *subj, *obj, *exec;
2969106648Srwatson	int error;
2970101099Srwatson
2971106648Srwatson	if (execlabel != NULL) {
2972106648Srwatson		/*
2973106648Srwatson		 * We currently don't permit labels to be changed at
2974172955Srwatson		 * exec-time as part of Biba, so disallow non-NULL Biba label
2975172955Srwatson		 * elements in the execlabel.
2976106648Srwatson		 */
2977106648Srwatson		exec = SLOT(execlabel);
2978106648Srwatson		error = biba_atmostflags(exec, 0);
2979106648Srwatson		if (error)
2980106648Srwatson			return (error);
2981106648Srwatson	}
2982106648Srwatson
2983172955Srwatson	if (!biba_enabled)
2984101099Srwatson		return (0);
2985101099Srwatson
2986122524Srwatson	subj = SLOT(cred->cr_label);
2987168976Srwatson	obj = SLOT(vplabel);
2988101099Srwatson
2989172955Srwatson	if (!biba_dominate_effective(obj, subj))
2990101099Srwatson		return (EACCES);
2991101099Srwatson
2992101099Srwatson	return (0);
2993101099Srwatson}
2994101099Srwatson
2995101099Srwatsonstatic int
2996172955Srwatsonbiba_vnode_check_getacl(struct ucred *cred, struct vnode *vp,
2997168976Srwatson    struct label *vplabel, acl_type_t type)
2998101099Srwatson{
2999101099Srwatson	struct mac_biba *subj, *obj;
3000101099Srwatson
3001172955Srwatson	if (!biba_enabled)
3002101099Srwatson		return (0);
3003101099Srwatson
3004122524Srwatson	subj = SLOT(cred->cr_label);
3005168976Srwatson	obj = SLOT(vplabel);
3006101099Srwatson
3007172955Srwatson	if (!biba_dominate_effective(obj, subj))
3008101099Srwatson		return (EACCES);
3009101099Srwatson
3010101099Srwatson	return (0);
3011101099Srwatson}
3012101099Srwatson
3013101099Srwatsonstatic int
3014172955Srwatsonbiba_vnode_check_getextattr(struct ucred *cred, struct vnode *vp,
3015189533Srwatson    struct label *vplabel, int attrnamespace, const char *name)
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(obj, subj))
3026101099Srwatson		return (EACCES);
3027101099Srwatson
3028101099Srwatson	return (0);
3029101099Srwatson}
3030101099Srwatson
3031101099Srwatsonstatic int
3032172955Srwatsonbiba_vnode_check_link(struct ucred *cred, struct vnode *dvp,
3033168976Srwatson    struct label *dvplabel, struct vnode *vp, struct label *vplabel,
3034104530Srwatson    struct componentname *cnp)
3035104530Srwatson{
3036104530Srwatson	struct mac_biba *subj, *obj;
3037104530Srwatson
3038172955Srwatson	if (!biba_enabled)
3039104530Srwatson		return (0);
3040104530Srwatson
3041122524Srwatson	subj = SLOT(cred->cr_label);
3042168976Srwatson	obj = SLOT(dvplabel);
3043104530Srwatson
3044172955Srwatson	if (!biba_dominate_effective(subj, obj))
3045104530Srwatson		return (EACCES);
3046104530Srwatson
3047168976Srwatson	obj = SLOT(vplabel);
3048104530Srwatson
3049172955Srwatson	if (!biba_dominate_effective(subj, obj))
3050104530Srwatson		return (EACCES);
3051104530Srwatson
3052104530Srwatson	return (0);
3053104530Srwatson}
3054104530Srwatson
3055104530Srwatsonstatic int
3056172955Srwatsonbiba_vnode_check_listextattr(struct ucred *cred, struct vnode *vp,
3057168976Srwatson    struct label *vplabel, int attrnamespace)
3058119202Srwatson{
3059119202Srwatson	struct mac_biba *subj, *obj;
3060119202Srwatson
3061172955Srwatson	if (!biba_enabled)
3062119202Srwatson		return (0);
3063119202Srwatson
3064122524Srwatson	subj = SLOT(cred->cr_label);
3065168976Srwatson	obj = SLOT(vplabel);
3066119202Srwatson
3067172955Srwatson	if (!biba_dominate_effective(obj, subj))
3068119202Srwatson		return (EACCES);
3069119202Srwatson
3070119202Srwatson	return (0);
3071119202Srwatson}
3072119202Srwatson
3073119202Srwatsonstatic int
3074172955Srwatsonbiba_vnode_check_lookup(struct ucred *cred, struct vnode *dvp,
3075168976Srwatson    struct label *dvplabel, struct componentname *cnp)
3076101099Srwatson{
3077101099Srwatson	struct mac_biba *subj, *obj;
3078103759Srwatson
3079172955Srwatson	if (!biba_enabled)
3080101099Srwatson		return (0);
3081103759Srwatson
3082122524Srwatson	subj = SLOT(cred->cr_label);
3083168976Srwatson	obj = SLOT(dvplabel);
3084103759Srwatson
3085172955Srwatson	if (!biba_dominate_effective(obj, subj))
3086101099Srwatson		return (EACCES);
3087101099Srwatson
3088103759Srwatson	return (0);
3089101099Srwatson}
3090101099Srwatson
3091101099Srwatsonstatic int
3092172955Srwatsonbiba_vnode_check_mmap(struct ucred *cred, struct vnode *vp,
3093168976Srwatson    struct label *vplabel, int prot, int flags)
3094104546Srwatson{
3095104546Srwatson	struct mac_biba *subj, *obj;
3096104546Srwatson
3097104546Srwatson	/*
3098104546Srwatson	 * Rely on the use of open()-time protections to handle
3099104546Srwatson	 * non-revocation cases.
3100104546Srwatson	 */
3101172955Srwatson	if (!biba_enabled || !revocation_enabled)
3102104546Srwatson		return (0);
3103104546Srwatson
3104122524Srwatson	subj = SLOT(cred->cr_label);
3105168976Srwatson	obj = SLOT(vplabel);
3106104546Srwatson
3107104546Srwatson	if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
3108172955Srwatson		if (!biba_dominate_effective(obj, subj))
3109104546Srwatson			return (EACCES);
3110104546Srwatson	}
3111145076Scsjp	if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) {
3112172955Srwatson		if (!biba_dominate_effective(subj, obj))
3113104546Srwatson			return (EACCES);
3114104546Srwatson	}
3115104546Srwatson
3116104569Srwatson	return (0);
3117104546Srwatson}
3118104546Srwatson
3119104546Srwatsonstatic int
3120172955Srwatsonbiba_vnode_check_open(struct ucred *cred, struct vnode *vp,
3121184413Strasz    struct label *vplabel, accmode_t accmode)
3122101099Srwatson{
3123101099Srwatson	struct mac_biba *subj, *obj;
3124101099Srwatson
3125172955Srwatson	if (!biba_enabled)
3126101099Srwatson		return (0);
3127101099Srwatson
3128122524Srwatson	subj = SLOT(cred->cr_label);
3129168976Srwatson	obj = SLOT(vplabel);
3130101099Srwatson
3131101099Srwatson	/* XXX privilege override for admin? */
3132190524Strasz	if (accmode & (VREAD | VEXEC | VSTAT_PERMS)) {
3133172955Srwatson		if (!biba_dominate_effective(obj, subj))
3134101099Srwatson			return (EACCES);
3135101099Srwatson	}
3136190524Strasz	if (accmode & VMODIFY_PERMS) {
3137172955Srwatson		if (!biba_dominate_effective(subj, obj))
3138101099Srwatson			return (EACCES);
3139101099Srwatson	}
3140101099Srwatson
3141101099Srwatson	return (0);
3142101099Srwatson}
3143101099Srwatson
3144101099Srwatsonstatic int
3145172955Srwatsonbiba_vnode_check_poll(struct ucred *active_cred, struct ucred *file_cred,
3146168976Srwatson    struct vnode *vp, struct label *vplabel)
3147102112Srwatson{
3148102112Srwatson	struct mac_biba *subj, *obj;
3149102112Srwatson
3150172955Srwatson	if (!biba_enabled || !revocation_enabled)
3151102112Srwatson		return (0);
3152102112Srwatson
3153122524Srwatson	subj = SLOT(active_cred->cr_label);
3154168976Srwatson	obj = SLOT(vplabel);
3155102112Srwatson
3156172955Srwatson	if (!biba_dominate_effective(obj, subj))
3157102112Srwatson		return (EACCES);
3158102112Srwatson
3159102112Srwatson	return (0);
3160102112Srwatson}
3161102112Srwatson
3162102112Srwatsonstatic int
3163172955Srwatsonbiba_vnode_check_read(struct ucred *active_cred, struct ucred *file_cred,
3164168976Srwatson    struct vnode *vp, struct label *vplabel)
3165102112Srwatson{
3166102112Srwatson	struct mac_biba *subj, *obj;
3167102112Srwatson
3168172955Srwatson	if (!biba_enabled || !revocation_enabled)
3169102112Srwatson		return (0);
3170102112Srwatson
3171122524Srwatson	subj = SLOT(active_cred->cr_label);
3172168976Srwatson	obj = SLOT(vplabel);
3173102112Srwatson
3174172955Srwatson	if (!biba_dominate_effective(obj, subj))
3175102112Srwatson		return (EACCES);
3176102112Srwatson
3177102112Srwatson	return (0);
3178102112Srwatson}
3179102112Srwatson
3180102112Srwatsonstatic int
3181172955Srwatsonbiba_vnode_check_readdir(struct ucred *cred, struct vnode *dvp,
3182168976Srwatson    struct label *dvplabel)
3183101099Srwatson{
3184101099Srwatson	struct mac_biba *subj, *obj;
3185101099Srwatson
3186172955Srwatson	if (!biba_enabled)
3187101099Srwatson		return (0);
3188101099Srwatson
3189122524Srwatson	subj = SLOT(cred->cr_label);
3190168976Srwatson	obj = SLOT(dvplabel);
3191101099Srwatson
3192172955Srwatson	if (!biba_dominate_effective(obj, subj))
3193101099Srwatson		return (EACCES);
3194101099Srwatson
3195101099Srwatson	return (0);
3196101099Srwatson}
3197101099Srwatson
3198101099Srwatsonstatic int
3199172955Srwatsonbiba_vnode_check_readlink(struct ucred *cred, struct vnode *vp,
3200168976Srwatson    struct label *vplabel)
3201101099Srwatson{
3202101099Srwatson	struct mac_biba *subj, *obj;
3203101099Srwatson
3204172955Srwatson	if (!biba_enabled)
3205101099Srwatson		return (0);
3206101099Srwatson
3207122524Srwatson	subj = SLOT(cred->cr_label);
3208168976Srwatson	obj = SLOT(vplabel);
3209101099Srwatson
3210172955Srwatson	if (!biba_dominate_effective(obj, subj))
3211101099Srwatson		return (EACCES);
3212101099Srwatson
3213101099Srwatson	return (0);
3214101099Srwatson}
3215101099Srwatson
3216101099Srwatsonstatic int
3217172955Srwatsonbiba_vnode_check_relabel(struct ucred *cred, struct vnode *vp,
3218168976Srwatson    struct label *vplabel, struct label *newlabel)
3219101099Srwatson{
3220101099Srwatson	struct mac_biba *old, *new, *subj;
3221105634Srwatson	int error;
3222101099Srwatson
3223168976Srwatson	old = SLOT(vplabel);
3224101099Srwatson	new = SLOT(newlabel);
3225122524Srwatson	subj = SLOT(cred->cr_label);
3226101099Srwatson
3227101099Srwatson	/*
3228105634Srwatson	 * If there is a Biba label update for the vnode, it must be a
3229132232Srwatson	 * effective label.
3230101099Srwatson	 */
3231132232Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE);
3232105634Srwatson	if (error)
3233105634Srwatson		return (error);
3234101099Srwatson
3235101099Srwatson	/*
3236105634Srwatson	 * To perform a relabel of the vnode (Biba label or not), Biba must
3237105634Srwatson	 * authorize the relabel.
3238101099Srwatson	 */
3239172955Srwatson	if (!biba_effective_in_range(old, subj))
3240101099Srwatson		return (EPERM);
3241101099Srwatson
3242101099Srwatson	/*
3243105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
3244101099Srwatson	 */
3245132232Srwatson	if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
3246105634Srwatson		/*
3247105634Srwatson		 * To change the Biba label on a vnode, the new vnode label
3248105634Srwatson		 * must be in the subject range.
3249105634Srwatson		 */
3250172955Srwatson		if (!biba_effective_in_range(new, subj))
3251105634Srwatson			return (EPERM);
3252101099Srwatson
3253105634Srwatson		/*
3254172955Srwatson		 * To change the Biba label on the vnode to be EQUAL, the
3255172955Srwatson		 * subject must have appropriate privilege.
3256105634Srwatson		 */
3257172955Srwatson		if (biba_contains_equal(new)) {
3258172955Srwatson			error = biba_subject_privileged(subj);
3259105634Srwatson			if (error)
3260105634Srwatson				return (error);
3261105634Srwatson		}
3262105634Srwatson	}
3263105634Srwatson
3264105634Srwatson	return (0);
3265101099Srwatson}
3266101099Srwatson
3267101099Srwatsonstatic int
3268172955Srwatsonbiba_vnode_check_rename_from(struct ucred *cred, struct vnode *dvp,
3269168976Srwatson    struct label *dvplabel, struct vnode *vp, struct label *vplabel,
3270101099Srwatson    struct componentname *cnp)
3271101099Srwatson{
3272101099Srwatson	struct mac_biba *subj, *obj;
3273101099Srwatson
3274172955Srwatson	if (!biba_enabled)
3275101099Srwatson		return (0);
3276101099Srwatson
3277122524Srwatson	subj = SLOT(cred->cr_label);
3278168976Srwatson	obj = SLOT(dvplabel);
3279101099Srwatson
3280172955Srwatson	if (!biba_dominate_effective(subj, obj))
3281101099Srwatson		return (EACCES);
3282101099Srwatson
3283168976Srwatson	obj = SLOT(vplabel);
3284101099Srwatson
3285172955Srwatson	if (!biba_dominate_effective(subj, obj))
3286101099Srwatson		return (EACCES);
3287101099Srwatson
3288101099Srwatson	return (0);
3289101099Srwatson}
3290101099Srwatson
3291101099Srwatsonstatic int
3292172955Srwatsonbiba_vnode_check_rename_to(struct ucred *cred, struct vnode *dvp,
3293168976Srwatson    struct label *dvplabel, struct vnode *vp, struct label *vplabel,
3294168976Srwatson    int samedir, struct componentname *cnp)
3295101099Srwatson{
3296101099Srwatson	struct mac_biba *subj, *obj;
3297101099Srwatson
3298172955Srwatson	if (!biba_enabled)
3299101099Srwatson		return (0);
3300101099Srwatson
3301122524Srwatson	subj = SLOT(cred->cr_label);
3302168976Srwatson	obj = SLOT(dvplabel);
3303101099Srwatson
3304172955Srwatson	if (!biba_dominate_effective(subj, obj))
3305101099Srwatson		return (EACCES);
3306101099Srwatson
3307101099Srwatson	if (vp != NULL) {
3308168976Srwatson		obj = SLOT(vplabel);
3309101099Srwatson
3310172955Srwatson		if (!biba_dominate_effective(subj, obj))
3311101099Srwatson			return (EACCES);
3312101099Srwatson	}
3313101099Srwatson
3314101099Srwatson	return (0);
3315101099Srwatson}
3316101099Srwatson
3317101099Srwatsonstatic int
3318172955Srwatsonbiba_vnode_check_revoke(struct ucred *cred, struct vnode *vp,
3319168976Srwatson    struct label *vplabel)
3320101099Srwatson{
3321101099Srwatson	struct mac_biba *subj, *obj;
3322101099Srwatson
3323172955Srwatson	if (!biba_enabled)
3324101099Srwatson		return (0);
3325101099Srwatson
3326122524Srwatson	subj = SLOT(cred->cr_label);
3327168976Srwatson	obj = SLOT(vplabel);
3328101099Srwatson
3329172955Srwatson	if (!biba_dominate_effective(subj, obj))
3330101099Srwatson		return (EACCES);
3331101099Srwatson
3332101099Srwatson	return (0);
3333101099Srwatson}
3334101099Srwatson
3335101099Srwatsonstatic int
3336172955Srwatsonbiba_vnode_check_setacl(struct ucred *cred, struct vnode *vp,
3337168976Srwatson    struct label *vplabel, acl_type_t type, struct acl *acl)
3338101099Srwatson{
3339101099Srwatson	struct mac_biba *subj, *obj;
3340101099Srwatson
3341172955Srwatson	if (!biba_enabled)
3342101099Srwatson		return (0);
3343101099Srwatson
3344122524Srwatson	subj = SLOT(cred->cr_label);
3345168976Srwatson	obj = SLOT(vplabel);
3346101099Srwatson
3347172955Srwatson	if (!biba_dominate_effective(subj, obj))
3348101099Srwatson		return (EACCES);
3349101099Srwatson
3350101099Srwatson	return (0);
3351101099Srwatson}
3352101099Srwatson
3353101099Srwatsonstatic int
3354172955Srwatsonbiba_vnode_check_setextattr(struct ucred *cred, struct vnode *vp,
3355189533Srwatson    struct label *vplabel, int attrnamespace, const char *name)
3356101099Srwatson{
3357101099Srwatson	struct mac_biba *subj, *obj;
3358101099Srwatson
3359172955Srwatson	if (!biba_enabled)
3360101099Srwatson		return (0);
3361101099Srwatson
3362122524Srwatson	subj = SLOT(cred->cr_label);
3363168976Srwatson	obj = SLOT(vplabel);
3364101099Srwatson
3365172955Srwatson	if (!biba_dominate_effective(subj, obj))
3366101099Srwatson		return (EACCES);
3367101099Srwatson
3368101099Srwatson	/* XXX: protect the MAC EA in a special way? */
3369101099Srwatson
3370101099Srwatson	return (0);
3371101099Srwatson}
3372101099Srwatson
3373101099Srwatsonstatic int
3374172955Srwatsonbiba_vnode_check_setflags(struct ucred *cred, struct vnode *vp,
3375168976Srwatson    struct label *vplabel, u_long flags)
3376101099Srwatson{
3377101099Srwatson	struct mac_biba *subj, *obj;
3378101099Srwatson
3379172955Srwatson	if (!biba_enabled)
3380101099Srwatson		return (0);
3381101099Srwatson
3382122524Srwatson	subj = SLOT(cred->cr_label);
3383168976Srwatson	obj = SLOT(vplabel);
3384101099Srwatson
3385172955Srwatson	if (!biba_dominate_effective(subj, obj))
3386101099Srwatson		return (EACCES);
3387101099Srwatson
3388101099Srwatson	return (0);
3389101099Srwatson}
3390101099Srwatson
3391101099Srwatsonstatic int
3392172955Srwatsonbiba_vnode_check_setmode(struct ucred *cred, struct vnode *vp,
3393168976Srwatson    struct label *vplabel, mode_t mode)
3394101099Srwatson{
3395101099Srwatson	struct mac_biba *subj, *obj;
3396101099Srwatson
3397172955Srwatson	if (!biba_enabled)
3398101099Srwatson		return (0);
3399101099Srwatson
3400122524Srwatson	subj = SLOT(cred->cr_label);
3401168976Srwatson	obj = SLOT(vplabel);
3402101099Srwatson
3403172955Srwatson	if (!biba_dominate_effective(subj, obj))
3404101099Srwatson		return (EACCES);
3405101099Srwatson
3406101099Srwatson	return (0);
3407101099Srwatson}
3408101099Srwatson
3409101099Srwatsonstatic int
3410172955Srwatsonbiba_vnode_check_setowner(struct ucred *cred, struct vnode *vp,
3411168976Srwatson    struct label *vplabel, uid_t uid, gid_t gid)
3412101099Srwatson{
3413101099Srwatson	struct mac_biba *subj, *obj;
3414101099Srwatson
3415172955Srwatson	if (!biba_enabled)
3416101099Srwatson		return (0);
3417101099Srwatson
3418122524Srwatson	subj = SLOT(cred->cr_label);
3419168976Srwatson	obj = SLOT(vplabel);
3420101099Srwatson
3421172955Srwatson	if (!biba_dominate_effective(subj, obj))
3422101099Srwatson		return (EACCES);
3423101099Srwatson
3424101099Srwatson	return (0);
3425101099Srwatson}
3426101099Srwatson
3427101099Srwatsonstatic int
3428172955Srwatsonbiba_vnode_check_setutimes(struct ucred *cred, struct vnode *vp,
3429168976Srwatson    struct label *vplabel, struct timespec atime, struct timespec mtime)
3430101099Srwatson{
3431101099Srwatson	struct mac_biba *subj, *obj;
3432101099Srwatson
3433172955Srwatson	if (!biba_enabled)
3434101099Srwatson		return (0);
3435101099Srwatson
3436122524Srwatson	subj = SLOT(cred->cr_label);
3437168976Srwatson	obj = SLOT(vplabel);
3438101099Srwatson
3439172955Srwatson	if (!biba_dominate_effective(subj, obj))
3440101099Srwatson		return (EACCES);
3441101099Srwatson
3442101099Srwatson	return (0);
3443101099Srwatson}
3444101099Srwatson
3445101099Srwatsonstatic int
3446172955Srwatsonbiba_vnode_check_stat(struct ucred *active_cred, struct ucred *file_cred,
3447168976Srwatson    struct vnode *vp, struct label *vplabel)
3448101099Srwatson{
3449101099Srwatson	struct mac_biba *subj, *obj;
3450101099Srwatson
3451172955Srwatson	if (!biba_enabled)
3452101099Srwatson		return (0);
3453101099Srwatson
3454122524Srwatson	subj = SLOT(active_cred->cr_label);
3455168976Srwatson	obj = SLOT(vplabel);
3456101099Srwatson
3457172955Srwatson	if (!biba_dominate_effective(obj, subj))
3458101099Srwatson		return (EACCES);
3459101099Srwatson
3460101099Srwatson	return (0);
3461101099Srwatson}
3462101099Srwatson
3463102112Srwatsonstatic int
3464172955Srwatsonbiba_vnode_check_unlink(struct ucred *cred, struct vnode *dvp,
3465172107Srwatson    struct label *dvplabel, struct vnode *vp, struct label *vplabel,
3466172107Srwatson    struct componentname *cnp)
3467172107Srwatson{
3468172107Srwatson	struct mac_biba *subj, *obj;
3469172107Srwatson
3470172955Srwatson	if (!biba_enabled)
3471172107Srwatson		return (0);
3472172107Srwatson
3473172107Srwatson	subj = SLOT(cred->cr_label);
3474172107Srwatson	obj = SLOT(dvplabel);
3475172107Srwatson
3476172955Srwatson	if (!biba_dominate_effective(subj, obj))
3477172107Srwatson		return (EACCES);
3478172107Srwatson
3479172107Srwatson	obj = SLOT(vplabel);
3480172107Srwatson
3481172955Srwatson	if (!biba_dominate_effective(subj, obj))
3482172107Srwatson		return (EACCES);
3483172107Srwatson
3484172107Srwatson	return (0);
3485172107Srwatson}
3486172107Srwatson
3487172107Srwatsonstatic int
3488172955Srwatsonbiba_vnode_check_write(struct ucred *active_cred,
3489168976Srwatson    struct ucred *file_cred, struct vnode *vp, struct label *vplabel)
3490102112Srwatson{
3491102112Srwatson	struct mac_biba *subj, *obj;
3492102112Srwatson
3493172955Srwatson	if (!biba_enabled || !revocation_enabled)
3494102112Srwatson		return (0);
3495102112Srwatson
3496122524Srwatson	subj = SLOT(active_cred->cr_label);
3497168976Srwatson	obj = SLOT(vplabel);
3498102112Srwatson
3499172955Srwatson	if (!biba_dominate_effective(subj, obj))
3500102112Srwatson		return (EACCES);
3501102112Srwatson
3502102112Srwatson	return (0);
3503102112Srwatson}
3504102112Srwatson
3505173138Srwatsonstatic int
3506173138Srwatsonbiba_vnode_create_extattr(struct ucred *cred, struct mount *mp,
3507173138Srwatson    struct label *mplabel, struct vnode *dvp, struct label *dvplabel,
3508173138Srwatson    struct vnode *vp, struct label *vplabel, struct componentname *cnp)
3509165150Scsjp{
3510173138Srwatson	struct mac_biba *source, *dest, mb_temp;
3511173138Srwatson	size_t buflen;
3512173138Srwatson	int error;
3513165150Scsjp
3514173138Srwatson	buflen = sizeof(mb_temp);
3515173138Srwatson	bzero(&mb_temp, buflen);
3516173138Srwatson
3517173138Srwatson	source = SLOT(cred->cr_label);
3518173138Srwatson	dest = SLOT(vplabel);
3519173138Srwatson	biba_copy_effective(source, &mb_temp);
3520173138Srwatson
3521173138Srwatson	error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
3522173138Srwatson	    MAC_BIBA_EXTATTR_NAME, buflen, (char *) &mb_temp, curthread);
3523173138Srwatson	if (error == 0)
3524173138Srwatson		biba_copy_effective(source, dest);
3525173138Srwatson	return (error);
3526165150Scsjp}
3527165150Scsjp
3528165150Scsjpstatic void
3529173138Srwatsonbiba_vnode_relabel(struct ucred *cred, struct vnode *vp,
3530173138Srwatson    struct label *vplabel, struct label *newlabel)
3531165150Scsjp{
3532165150Scsjp	struct mac_biba *source, *dest;
3533165150Scsjp
3534173138Srwatson	source = SLOT(newlabel);
3535173138Srwatson	dest = SLOT(vplabel);
3536173138Srwatson
3537173138Srwatson	biba_copy(source, dest);
3538165150Scsjp}
3539165150Scsjp
3540173138Srwatsonstatic int
3541173138Srwatsonbiba_vnode_setlabel_extattr(struct ucred *cred, struct vnode *vp,
3542173138Srwatson    struct label *vplabel, struct label *intlabel)
3543173138Srwatson{
3544173138Srwatson	struct mac_biba *source, mb_temp;
3545173138Srwatson	size_t buflen;
3546173138Srwatson	int error;
3547173138Srwatson
3548173138Srwatson	buflen = sizeof(mb_temp);
3549173138Srwatson	bzero(&mb_temp, buflen);
3550173138Srwatson
3551173138Srwatson	source = SLOT(intlabel);
3552173138Srwatson	if ((source->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) == 0)
3553173138Srwatson		return (0);
3554173138Srwatson
3555173138Srwatson	biba_copy_effective(source, &mb_temp);
3556173138Srwatson
3557173138Srwatson	error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
3558173138Srwatson	    MAC_BIBA_EXTATTR_NAME, buflen, (char *) &mb_temp, curthread);
3559173138Srwatson	return (error);
3560173138Srwatson}
3561173138Srwatson
3562106217Srwatsonstatic struct mac_policy_ops mac_biba_ops =
3563101099Srwatson{
3564172955Srwatson	.mpo_init = biba_init,
3565173138Srwatson
3566173138Srwatson	.mpo_bpfdesc_check_receive = biba_bpfdesc_check_receive,
3567173138Srwatson	.mpo_bpfdesc_create = biba_bpfdesc_create,
3568173138Srwatson	.mpo_bpfdesc_create_mbuf = biba_bpfdesc_create_mbuf,
3569173138Srwatson	.mpo_bpfdesc_destroy_label = biba_destroy_label,
3570172955Srwatson	.mpo_bpfdesc_init_label = biba_init_label,
3571173138Srwatson
3572184407Srwatson	.mpo_cred_associate_nfsd = biba_cred_associate_nfsd,
3573173138Srwatson	.mpo_cred_check_relabel = biba_cred_check_relabel,
3574173138Srwatson	.mpo_cred_check_visible = biba_cred_check_visible,
3575173138Srwatson	.mpo_cred_copy_label = biba_copy_label,
3576184407Srwatson	.mpo_cred_create_init = biba_cred_create_init,
3577184407Srwatson	.mpo_cred_create_swapper = biba_cred_create_swapper,
3578172955Srwatson	.mpo_cred_destroy_label = biba_destroy_label,
3579172955Srwatson	.mpo_cred_externalize_label = biba_externalize_label,
3580173138Srwatson	.mpo_cred_init_label = biba_init_label,
3581172955Srwatson	.mpo_cred_internalize_label = biba_internalize_label,
3582173138Srwatson	.mpo_cred_relabel = biba_cred_relabel,
3583173138Srwatson
3584172955Srwatson	.mpo_devfs_create_device = biba_devfs_create_device,
3585172955Srwatson	.mpo_devfs_create_directory = biba_devfs_create_directory,
3586172955Srwatson	.mpo_devfs_create_symlink = biba_devfs_create_symlink,
3587173138Srwatson	.mpo_devfs_destroy_label = biba_destroy_label,
3588173138Srwatson	.mpo_devfs_init_label = biba_init_label,
3589172955Srwatson	.mpo_devfs_update = biba_devfs_update,
3590172955Srwatson	.mpo_devfs_vnode_associate = biba_devfs_vnode_associate,
3591173138Srwatson
3592173138Srwatson	.mpo_ifnet_check_relabel = biba_ifnet_check_relabel,
3593173138Srwatson	.mpo_ifnet_check_transmit = biba_ifnet_check_transmit,
3594173138Srwatson	.mpo_ifnet_copy_label = biba_copy_label,
3595172955Srwatson	.mpo_ifnet_create = biba_ifnet_create,
3596173138Srwatson	.mpo_ifnet_create_mbuf = biba_ifnet_create_mbuf,
3597173138Srwatson	.mpo_ifnet_destroy_label = biba_destroy_label,
3598173138Srwatson	.mpo_ifnet_externalize_label = biba_externalize_label,
3599173138Srwatson	.mpo_ifnet_init_label = biba_init_label,
3600173138Srwatson	.mpo_ifnet_internalize_label = biba_internalize_label,
3601173138Srwatson	.mpo_ifnet_relabel = biba_ifnet_relabel,
3602173138Srwatson
3603173138Srwatson	.mpo_inpcb_check_deliver = biba_inpcb_check_deliver,
3604183980Sbz	.mpo_inpcb_check_visible = biba_inpcb_check_visible,
3605172955Srwatson	.mpo_inpcb_create = biba_inpcb_create,
3606173138Srwatson	.mpo_inpcb_create_mbuf = biba_inpcb_create_mbuf,
3607173138Srwatson	.mpo_inpcb_destroy_label = biba_destroy_label,
3608173138Srwatson	.mpo_inpcb_init_label = biba_init_label_waitcheck,
3609173138Srwatson	.mpo_inpcb_sosetlabel = biba_inpcb_sosetlabel,
3610173138Srwatson
3611184308Srwatson	.mpo_ip6q_create = biba_ip6q_create,
3612184308Srwatson	.mpo_ip6q_destroy_label = biba_destroy_label,
3613184308Srwatson	.mpo_ip6q_init_label = biba_init_label_waitcheck,
3614184308Srwatson	.mpo_ip6q_match = biba_ip6q_match,
3615184308Srwatson	.mpo_ip6q_reassemble = biba_ip6q_reassemble,
3616184308Srwatson	.mpo_ip6q_update = biba_ip6q_update,
3617184308Srwatson
3618172955Srwatson	.mpo_ipq_create = biba_ipq_create,
3619173138Srwatson	.mpo_ipq_destroy_label = biba_destroy_label,
3620173138Srwatson	.mpo_ipq_init_label = biba_init_label_waitcheck,
3621172955Srwatson	.mpo_ipq_match = biba_ipq_match,
3622173138Srwatson	.mpo_ipq_reassemble = biba_ipq_reassemble,
3623172955Srwatson	.mpo_ipq_update = biba_ipq_update,
3624173138Srwatson
3625172955Srwatson	.mpo_kld_check_load = biba_kld_check_load,
3626173138Srwatson
3627173138Srwatson	.mpo_mbuf_copy_label = biba_copy_label,
3628173138Srwatson	.mpo_mbuf_destroy_label = biba_destroy_label,
3629173138Srwatson	.mpo_mbuf_init_label = biba_init_label_waitcheck,
3630173138Srwatson
3631172955Srwatson	.mpo_mount_check_stat = biba_mount_check_stat,
3632173138Srwatson	.mpo_mount_create = biba_mount_create,
3633173138Srwatson	.mpo_mount_destroy_label = biba_destroy_label,
3634173138Srwatson	.mpo_mount_init_label = biba_init_label,
3635173138Srwatson
3636173138Srwatson	.mpo_netinet_arp_send = biba_netinet_arp_send,
3637173138Srwatson	.mpo_netinet_firewall_reply = biba_netinet_firewall_reply,
3638173138Srwatson	.mpo_netinet_firewall_send = biba_netinet_firewall_send,
3639173138Srwatson	.mpo_netinet_fragment = biba_netinet_fragment,
3640173138Srwatson	.mpo_netinet_icmp_reply = biba_netinet_icmp_reply,
3641173138Srwatson	.mpo_netinet_igmp_send = biba_netinet_igmp_send,
3642173138Srwatson
3643173138Srwatson	.mpo_netinet6_nd6_send = biba_netinet6_nd6_send,
3644173138Srwatson
3645172955Srwatson	.mpo_pipe_check_ioctl = biba_pipe_check_ioctl,
3646172955Srwatson	.mpo_pipe_check_poll = biba_pipe_check_poll,
3647172955Srwatson	.mpo_pipe_check_read = biba_pipe_check_read,
3648172955Srwatson	.mpo_pipe_check_relabel = biba_pipe_check_relabel,
3649172955Srwatson	.mpo_pipe_check_stat = biba_pipe_check_stat,
3650172955Srwatson	.mpo_pipe_check_write = biba_pipe_check_write,
3651173138Srwatson	.mpo_pipe_copy_label = biba_copy_label,
3652173138Srwatson	.mpo_pipe_create = biba_pipe_create,
3653173138Srwatson	.mpo_pipe_destroy_label = biba_destroy_label,
3654173138Srwatson	.mpo_pipe_externalize_label = biba_externalize_label,
3655173138Srwatson	.mpo_pipe_init_label = biba_init_label,
3656173138Srwatson	.mpo_pipe_internalize_label = biba_internalize_label,
3657173138Srwatson	.mpo_pipe_relabel = biba_pipe_relabel,
3658173138Srwatson
3659172955Srwatson	.mpo_posixsem_check_getvalue = biba_posixsem_check_rdonly,
3660180059Sjhb	.mpo_posixsem_check_open = biba_posixsem_check_openunlink,
3661172955Srwatson	.mpo_posixsem_check_post = biba_posixsem_check_write,
3662225344Srwatson	.mpo_posixsem_check_setmode = biba_posixsem_check_setmode,
3663225344Srwatson	.mpo_posixsem_check_setowner = biba_posixsem_check_setowner,
3664180059Sjhb	.mpo_posixsem_check_stat = biba_posixsem_check_rdonly,
3665180059Sjhb	.mpo_posixsem_check_unlink = biba_posixsem_check_openunlink,
3666172955Srwatson	.mpo_posixsem_check_wait = biba_posixsem_check_write,
3667173138Srwatson	.mpo_posixsem_create = biba_posixsem_create,
3668173138Srwatson	.mpo_posixsem_destroy_label = biba_destroy_label,
3669173138Srwatson	.mpo_posixsem_init_label = biba_init_label,
3670173138Srwatson
3671225344Srwatson	.mpo_posixshm_check_mmap = biba_posixshm_check_mmap,
3672225344Srwatson	.mpo_posixshm_check_open = biba_posixshm_check_open,
3673254603Skib	.mpo_posixshm_check_read = biba_posixshm_check_read,
3674225344Srwatson	.mpo_posixshm_check_setmode = biba_posixshm_check_setmode,
3675225344Srwatson	.mpo_posixshm_check_setowner = biba_posixshm_check_setowner,
3676225344Srwatson	.mpo_posixshm_check_stat = biba_posixshm_check_stat,
3677225344Srwatson	.mpo_posixshm_check_truncate = biba_posixshm_check_truncate,
3678225344Srwatson	.mpo_posixshm_check_unlink = biba_posixshm_check_unlink,
3679254603Skib	.mpo_posixshm_check_write = biba_posixshm_check_write,
3680225344Srwatson	.mpo_posixshm_create = biba_posixshm_create,
3681225344Srwatson	.mpo_posixshm_destroy_label = biba_destroy_label,
3682225344Srwatson	.mpo_posixshm_init_label = biba_init_label,
3683225344Srwatson
3684173138Srwatson	.mpo_priv_check = biba_priv_check,
3685173138Srwatson
3686172955Srwatson	.mpo_proc_check_debug = biba_proc_check_debug,
3687172955Srwatson	.mpo_proc_check_sched = biba_proc_check_sched,
3688172955Srwatson	.mpo_proc_check_signal = biba_proc_check_signal,
3689173138Srwatson
3690172955Srwatson	.mpo_socket_check_deliver = biba_socket_check_deliver,
3691172955Srwatson	.mpo_socket_check_relabel = biba_socket_check_relabel,
3692172955Srwatson	.mpo_socket_check_visible = biba_socket_check_visible,
3693173138Srwatson	.mpo_socket_copy_label = biba_copy_label,
3694173138Srwatson	.mpo_socket_create = biba_socket_create,
3695173138Srwatson	.mpo_socket_create_mbuf = biba_socket_create_mbuf,
3696173138Srwatson	.mpo_socket_destroy_label = biba_destroy_label,
3697173138Srwatson	.mpo_socket_externalize_label = biba_externalize_label,
3698173138Srwatson	.mpo_socket_init_label = biba_init_label_waitcheck,
3699173138Srwatson	.mpo_socket_internalize_label = biba_internalize_label,
3700173138Srwatson	.mpo_socket_newconn = biba_socket_newconn,
3701173138Srwatson	.mpo_socket_relabel = biba_socket_relabel,
3702173138Srwatson
3703173138Srwatson	.mpo_socketpeer_destroy_label = biba_destroy_label,
3704173138Srwatson	.mpo_socketpeer_externalize_label = biba_externalize_label,
3705173138Srwatson	.mpo_socketpeer_init_label = biba_init_label_waitcheck,
3706173138Srwatson	.mpo_socketpeer_set_from_mbuf = biba_socketpeer_set_from_mbuf,
3707173138Srwatson	.mpo_socketpeer_set_from_socket = biba_socketpeer_set_from_socket,
3708173138Srwatson
3709173138Srwatson	.mpo_syncache_create = biba_syncache_create,
3710173138Srwatson	.mpo_syncache_create_mbuf = biba_syncache_create_mbuf,
3711173138Srwatson	.mpo_syncache_destroy_label = biba_destroy_label,
3712173138Srwatson	.mpo_syncache_init_label = biba_init_label_waitcheck,
3713173138Srwatson
3714172955Srwatson	.mpo_system_check_acct = biba_system_check_acct,
3715172955Srwatson	.mpo_system_check_auditctl = biba_system_check_auditctl,
3716172955Srwatson	.mpo_system_check_auditon = biba_system_check_auditon,
3717173138Srwatson	.mpo_system_check_swapoff = biba_system_check_swapoff,
3718172955Srwatson	.mpo_system_check_swapon = biba_system_check_swapon,
3719172955Srwatson	.mpo_system_check_sysctl = biba_system_check_sysctl,
3720173138Srwatson
3721173138Srwatson	.mpo_sysvmsg_cleanup = biba_sysvmsg_cleanup,
3722173138Srwatson	.mpo_sysvmsg_create = biba_sysvmsg_create,
3723173138Srwatson	.mpo_sysvmsg_destroy_label = biba_destroy_label,
3724173138Srwatson	.mpo_sysvmsg_init_label = biba_init_label,
3725173138Srwatson
3726173138Srwatson	.mpo_sysvmsq_check_msgrcv = biba_sysvmsq_check_msgrcv,
3727173138Srwatson	.mpo_sysvmsq_check_msgrmid = biba_sysvmsq_check_msgrmid,
3728173138Srwatson	.mpo_sysvmsq_check_msqget = biba_sysvmsq_check_msqget,
3729173138Srwatson	.mpo_sysvmsq_check_msqsnd = biba_sysvmsq_check_msqsnd,
3730173138Srwatson	.mpo_sysvmsq_check_msqrcv = biba_sysvmsq_check_msqrcv,
3731173138Srwatson	.mpo_sysvmsq_check_msqctl = biba_sysvmsq_check_msqctl,
3732173138Srwatson	.mpo_sysvmsq_cleanup = biba_sysvmsq_cleanup,
3733173138Srwatson	.mpo_sysvmsq_create = biba_sysvmsq_create,
3734173138Srwatson	.mpo_sysvmsq_destroy_label = biba_destroy_label,
3735173138Srwatson	.mpo_sysvmsq_init_label = biba_init_label,
3736173138Srwatson
3737173138Srwatson	.mpo_sysvsem_check_semctl = biba_sysvsem_check_semctl,
3738173138Srwatson	.mpo_sysvsem_check_semget = biba_sysvsem_check_semget,
3739173138Srwatson	.mpo_sysvsem_check_semop = biba_sysvsem_check_semop,
3740173138Srwatson	.mpo_sysvsem_cleanup = biba_sysvsem_cleanup,
3741173138Srwatson	.mpo_sysvsem_create = biba_sysvsem_create,
3742173138Srwatson	.mpo_sysvsem_destroy_label = biba_destroy_label,
3743173138Srwatson	.mpo_sysvsem_init_label = biba_init_label,
3744173138Srwatson
3745173138Srwatson	.mpo_sysvshm_check_shmat = biba_sysvshm_check_shmat,
3746173138Srwatson	.mpo_sysvshm_check_shmctl = biba_sysvshm_check_shmctl,
3747173138Srwatson	.mpo_sysvshm_check_shmget = biba_sysvshm_check_shmget,
3748173138Srwatson	.mpo_sysvshm_cleanup = biba_sysvshm_cleanup,
3749173138Srwatson	.mpo_sysvshm_create = biba_sysvshm_create,
3750173138Srwatson	.mpo_sysvshm_destroy_label = biba_destroy_label,
3751173138Srwatson	.mpo_sysvshm_init_label = biba_init_label,
3752173138Srwatson
3753173138Srwatson	.mpo_vnode_associate_extattr = biba_vnode_associate_extattr,
3754173138Srwatson	.mpo_vnode_associate_singlelabel = biba_vnode_associate_singlelabel,
3755172955Srwatson	.mpo_vnode_check_access = biba_vnode_check_open,
3756172955Srwatson	.mpo_vnode_check_chdir = biba_vnode_check_chdir,
3757172955Srwatson	.mpo_vnode_check_chroot = biba_vnode_check_chroot,
3758172955Srwatson	.mpo_vnode_check_create = biba_vnode_check_create,
3759172955Srwatson	.mpo_vnode_check_deleteacl = biba_vnode_check_deleteacl,
3760172955Srwatson	.mpo_vnode_check_deleteextattr = biba_vnode_check_deleteextattr,
3761172955Srwatson	.mpo_vnode_check_exec = biba_vnode_check_exec,
3762172955Srwatson	.mpo_vnode_check_getacl = biba_vnode_check_getacl,
3763172955Srwatson	.mpo_vnode_check_getextattr = biba_vnode_check_getextattr,
3764172955Srwatson	.mpo_vnode_check_link = biba_vnode_check_link,
3765172955Srwatson	.mpo_vnode_check_listextattr = biba_vnode_check_listextattr,
3766172955Srwatson	.mpo_vnode_check_lookup = biba_vnode_check_lookup,
3767172955Srwatson	.mpo_vnode_check_mmap = biba_vnode_check_mmap,
3768172955Srwatson	.mpo_vnode_check_open = biba_vnode_check_open,
3769172955Srwatson	.mpo_vnode_check_poll = biba_vnode_check_poll,
3770172955Srwatson	.mpo_vnode_check_read = biba_vnode_check_read,
3771172955Srwatson	.mpo_vnode_check_readdir = biba_vnode_check_readdir,
3772172955Srwatson	.mpo_vnode_check_readlink = biba_vnode_check_readlink,
3773172955Srwatson	.mpo_vnode_check_relabel = biba_vnode_check_relabel,
3774172955Srwatson	.mpo_vnode_check_rename_from = biba_vnode_check_rename_from,
3775172955Srwatson	.mpo_vnode_check_rename_to = biba_vnode_check_rename_to,
3776172955Srwatson	.mpo_vnode_check_revoke = biba_vnode_check_revoke,
3777172955Srwatson	.mpo_vnode_check_setacl = biba_vnode_check_setacl,
3778172955Srwatson	.mpo_vnode_check_setextattr = biba_vnode_check_setextattr,
3779172955Srwatson	.mpo_vnode_check_setflags = biba_vnode_check_setflags,
3780172955Srwatson	.mpo_vnode_check_setmode = biba_vnode_check_setmode,
3781172955Srwatson	.mpo_vnode_check_setowner = biba_vnode_check_setowner,
3782172955Srwatson	.mpo_vnode_check_setutimes = biba_vnode_check_setutimes,
3783172955Srwatson	.mpo_vnode_check_stat = biba_vnode_check_stat,
3784172955Srwatson	.mpo_vnode_check_unlink = biba_vnode_check_unlink,
3785172955Srwatson	.mpo_vnode_check_write = biba_vnode_check_write,
3786173138Srwatson	.mpo_vnode_create_extattr = biba_vnode_create_extattr,
3787173138Srwatson	.mpo_vnode_copy_label = biba_copy_label,
3788173138Srwatson	.mpo_vnode_destroy_label = biba_destroy_label,
3789173138Srwatson	.mpo_vnode_externalize_label = biba_externalize_label,
3790173138Srwatson	.mpo_vnode_init_label = biba_init_label,
3791173138Srwatson	.mpo_vnode_internalize_label = biba_internalize_label,
3792173138Srwatson	.mpo_vnode_relabel = biba_vnode_relabel,
3793173138Srwatson	.mpo_vnode_setlabel_extattr = biba_vnode_setlabel_extattr,
3794101099Srwatson};
3795101099Srwatson
3796112717SrwatsonMAC_POLICY_SET(&mac_biba_ops, mac_biba, "TrustedBSD MAC/Biba",
3797187016Srwatson    MPC_LOADTIME_FLAG_NOTLATE, &biba_slot);
3798