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
95248085Smariusstatic 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;
103172955SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, enabled, CTLFLAG_RW, &biba_enabled,
104172955Srwatson    0, "Enforce MAC/Biba policy");
105172955SrwatsonTUNABLE_INT("security.mac.biba.enabled", &biba_enabled);
106101099Srwatson
107101099Srwatsonstatic int	destroyed_not_inited;
108101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, destroyed_not_inited, CTLFLAG_RD,
109101099Srwatson    &destroyed_not_inited, 0, "Count of labels destroyed but not inited");
110101099Srwatson
111101099Srwatsonstatic int	trust_all_interfaces = 0;
112101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, trust_all_interfaces, CTLFLAG_RD,
113101099Srwatson    &trust_all_interfaces, 0, "Consider all interfaces 'trusted' by MAC/Biba");
114101099SrwatsonTUNABLE_INT("security.mac.biba.trust_all_interfaces", &trust_all_interfaces);
115101099Srwatson
116101099Srwatsonstatic char	trusted_interfaces[128];
117101099SrwatsonSYSCTL_STRING(_security_mac_biba, OID_AUTO, trusted_interfaces, CTLFLAG_RD,
118101099Srwatson    trusted_interfaces, 0, "Interfaces considered 'trusted' by MAC/Biba");
119101099SrwatsonTUNABLE_STR("security.mac.biba.trusted_interfaces", trusted_interfaces,
120101099Srwatson    sizeof(trusted_interfaces));
121101099Srwatson
122105643Srwatsonstatic int	max_compartments = MAC_BIBA_MAX_COMPARTMENTS;
123105643SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, max_compartments, CTLFLAG_RD,
124105643Srwatson    &max_compartments, 0, "Maximum supported compartments");
125105643Srwatson
126105606Srwatsonstatic int	ptys_equal = 0;
127181217SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, ptys_equal, CTLFLAG_RW, &ptys_equal,
128181217Srwatson    0, "Label pty devices as biba/equal on create");
129105606SrwatsonTUNABLE_INT("security.mac.biba.ptys_equal", &ptys_equal);
130105606Srwatson
131193371Srwatsonstatic int	interfaces_equal = 1;
132153927ScsjpSYSCTL_INT(_security_mac_biba, OID_AUTO, interfaces_equal, CTLFLAG_RW,
133153927Scsjp    &interfaces_equal, 0, "Label network interfaces as biba/equal on create");
134153927ScsjpTUNABLE_INT("security.mac.biba.interfaces_equal", &interfaces_equal);
135153927Scsjp
136105637Srwatsonstatic int	revocation_enabled = 0;
137101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, revocation_enabled, CTLFLAG_RW,
138105637Srwatson    &revocation_enabled, 0, "Revoke access to objects on relabel");
139105637SrwatsonTUNABLE_INT("security.mac.biba.revocation_enabled", &revocation_enabled);
140101099Srwatson
141172955Srwatsonstatic int	biba_slot;
142172955Srwatson#define	SLOT(l)	((struct mac_biba *)mac_label_get((l), biba_slot))
143172955Srwatson#define	SLOT_SET(l, val) mac_label_set((l), biba_slot, (uintptr_t)(val))
144101099Srwatson
145122879Srwatsonstatic uma_zone_t	zone_biba;
146101099Srwatson
147105643Srwatsonstatic __inline int
148105643Srwatsonbiba_bit_set_empty(u_char *set) {
149105643Srwatson	int i;
150105643Srwatson
151105643Srwatson	for (i = 0; i < MAC_BIBA_MAX_COMPARTMENTS >> 3; i++)
152105643Srwatson		if (set[i] != 0)
153105643Srwatson			return (0);
154105643Srwatson	return (1);
155105643Srwatson}
156105643Srwatson
157101099Srwatsonstatic struct mac_biba *
158104514Srwatsonbiba_alloc(int flag)
159101099Srwatson{
160101099Srwatson
161122879Srwatson	return (uma_zalloc(zone_biba, flag | M_ZERO));
162101099Srwatson}
163101099Srwatson
164101099Srwatsonstatic void
165172955Srwatsonbiba_free(struct mac_biba *mb)
166101099Srwatson{
167101099Srwatson
168172955Srwatson	if (mb != NULL)
169172955Srwatson		uma_zfree(zone_biba, mb);
170101099Srwatson	else
171101099Srwatson		atomic_add_int(&destroyed_not_inited, 1);
172101099Srwatson}
173101099Srwatson
174101099Srwatsonstatic int
175172955Srwatsonbiba_atmostflags(struct mac_biba *mb, int flags)
176105634Srwatson{
177105634Srwatson
178172955Srwatson	if ((mb->mb_flags & flags) != mb->mb_flags)
179105634Srwatson		return (EINVAL);
180105634Srwatson	return (0);
181105634Srwatson}
182105634Srwatson
183105634Srwatsonstatic int
184172955Srwatsonbiba_dominate_element(struct mac_biba_element *a, struct mac_biba_element *b)
185101099Srwatson{
186105643Srwatson	int bit;
187101099Srwatson
188105736Srwatson	switch (a->mbe_type) {
189101099Srwatson	case MAC_BIBA_TYPE_EQUAL:
190101099Srwatson	case MAC_BIBA_TYPE_HIGH:
191101099Srwatson		return (1);
192101099Srwatson
193101099Srwatson	case MAC_BIBA_TYPE_LOW:
194101099Srwatson		switch (b->mbe_type) {
195101099Srwatson		case MAC_BIBA_TYPE_GRADE:
196101099Srwatson		case MAC_BIBA_TYPE_HIGH:
197101099Srwatson			return (0);
198101099Srwatson
199101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
200101099Srwatson		case MAC_BIBA_TYPE_LOW:
201101099Srwatson			return (1);
202101099Srwatson
203101099Srwatson		default:
204172955Srwatson			panic("biba_dominate_element: b->mbe_type invalid");
205101099Srwatson		}
206101099Srwatson
207101099Srwatson	case MAC_BIBA_TYPE_GRADE:
208101099Srwatson		switch (b->mbe_type) {
209101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
210101099Srwatson		case MAC_BIBA_TYPE_LOW:
211101099Srwatson			return (1);
212101099Srwatson
213101099Srwatson		case MAC_BIBA_TYPE_HIGH:
214101099Srwatson			return (0);
215101099Srwatson
216101099Srwatson		case MAC_BIBA_TYPE_GRADE:
217105643Srwatson			for (bit = 1; bit <= MAC_BIBA_MAX_COMPARTMENTS; bit++)
218105643Srwatson				if (!MAC_BIBA_BIT_TEST(bit,
219105643Srwatson				    a->mbe_compartments) &&
220105643Srwatson				    MAC_BIBA_BIT_TEST(bit, b->mbe_compartments))
221105643Srwatson					return (0);
222101099Srwatson			return (a->mbe_grade >= b->mbe_grade);
223101099Srwatson
224101099Srwatson		default:
225172955Srwatson			panic("biba_dominate_element: b->mbe_type invalid");
226101099Srwatson		}
227101099Srwatson
228101099Srwatson	default:
229172955Srwatson		panic("biba_dominate_element: a->mbe_type invalid");
230101099Srwatson	}
231101099Srwatson
232101099Srwatson	return (0);
233101099Srwatson}
234101099Srwatson
235101099Srwatsonstatic int
236172955Srwatsonbiba_subject_dominate_high(struct mac_biba *mb)
237105988Srwatson{
238105988Srwatson	struct mac_biba_element *element;
239105988Srwatson
240172955Srwatson	KASSERT((mb->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
241172955Srwatson	    ("biba_effective_in_range: mb not effective"));
242172955Srwatson	element = &mb->mb_effective;
243105988Srwatson
244105988Srwatson	return (element->mbe_type == MAC_BIBA_TYPE_EQUAL ||
245105988Srwatson	    element->mbe_type == MAC_BIBA_TYPE_HIGH);
246105988Srwatson}
247105988Srwatson
248105988Srwatsonstatic int
249172955Srwatsonbiba_range_in_range(struct mac_biba *rangea, struct mac_biba *rangeb)
250101099Srwatson{
251101099Srwatson
252172955Srwatson	return (biba_dominate_element(&rangeb->mb_rangehigh,
253101099Srwatson	    &rangea->mb_rangehigh) &&
254172955Srwatson	    biba_dominate_element(&rangea->mb_rangelow,
255101099Srwatson	    &rangeb->mb_rangelow));
256101099Srwatson}
257101099Srwatson
258101099Srwatsonstatic int
259172955Srwatsonbiba_effective_in_range(struct mac_biba *effective, struct mac_biba *range)
260101099Srwatson{
261101099Srwatson
262132232Srwatson	KASSERT((effective->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
263172955Srwatson	    ("biba_effective_in_range: a not effective"));
264103750Srwatson	KASSERT((range->mb_flags & MAC_BIBA_FLAG_RANGE) != 0,
265172955Srwatson	    ("biba_effective_in_range: b not range"));
266101099Srwatson
267172955Srwatson	return (biba_dominate_element(&range->mb_rangehigh,
268132232Srwatson	    &effective->mb_effective) &&
269172955Srwatson	    biba_dominate_element(&effective->mb_effective,
270101099Srwatson	    &range->mb_rangelow));
271101099Srwatson
272101099Srwatson	return (1);
273101099Srwatson}
274101099Srwatson
275101099Srwatsonstatic int
276172955Srwatsonbiba_dominate_effective(struct mac_biba *a, struct mac_biba *b)
277101099Srwatson{
278132232Srwatson	KASSERT((a->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
279172955Srwatson	    ("biba_dominate_effective: a not effective"));
280132232Srwatson	KASSERT((b->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
281172955Srwatson	    ("biba_dominate_effective: b not effective"));
282101099Srwatson
283172955Srwatson	return (biba_dominate_element(&a->mb_effective, &b->mb_effective));
284101099Srwatson}
285101099Srwatson
286101099Srwatsonstatic int
287172955Srwatsonbiba_equal_element(struct mac_biba_element *a, struct mac_biba_element *b)
288101099Srwatson{
289101099Srwatson
290101099Srwatson	if (a->mbe_type == MAC_BIBA_TYPE_EQUAL ||
291101099Srwatson	    b->mbe_type == MAC_BIBA_TYPE_EQUAL)
292101099Srwatson		return (1);
293101099Srwatson
294101099Srwatson	return (a->mbe_type == b->mbe_type && a->mbe_grade == b->mbe_grade);
295101099Srwatson}
296101099Srwatson
297101099Srwatsonstatic int
298172955Srwatsonbiba_equal_effective(struct mac_biba *a, struct mac_biba *b)
299101099Srwatson{
300101099Srwatson
301132232Srwatson	KASSERT((a->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
302172955Srwatson	    ("biba_equal_effective: a not effective"));
303132232Srwatson	KASSERT((b->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
304172955Srwatson	    ("biba_equal_effective: b not effective"));
305101099Srwatson
306172955Srwatson	return (biba_equal_element(&a->mb_effective, &b->mb_effective));
307101099Srwatson}
308101099Srwatson
309101099Srwatsonstatic int
310172955Srwatsonbiba_contains_equal(struct mac_biba *mb)
311105634Srwatson{
312105634Srwatson
313172955Srwatson	if (mb->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
314172955Srwatson		if (mb->mb_effective.mbe_type == MAC_BIBA_TYPE_EQUAL)
315105634Srwatson			return (1);
316172955Srwatson	}
317105634Srwatson
318172955Srwatson	if (mb->mb_flags & MAC_BIBA_FLAG_RANGE) {
319172955Srwatson		if (mb->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL)
320105634Srwatson			return (1);
321172955Srwatson		if (mb->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL)
322105637Srwatson			return (1);
323105634Srwatson	}
324105634Srwatson
325105634Srwatson	return (0);
326105634Srwatson}
327105634Srwatson
328105634Srwatsonstatic int
329172955Srwatsonbiba_subject_privileged(struct mac_biba *mb)
330105634Srwatson{
331105634Srwatson
332172955Srwatson	KASSERT((mb->mb_flags & MAC_BIBA_FLAGS_BOTH) == MAC_BIBA_FLAGS_BOTH,
333172955Srwatson	    ("biba_subject_privileged: subject doesn't have both labels"));
334105634Srwatson
335132232Srwatson	/* If the effective is EQUAL, it's ok. */
336172955Srwatson	if (mb->mb_effective.mbe_type == MAC_BIBA_TYPE_EQUAL)
337105634Srwatson		return (0);
338105634Srwatson
339105634Srwatson	/* If either range endpoint is EQUAL, it's ok. */
340172955Srwatson	if (mb->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL ||
341172955Srwatson	    mb->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL)
342105634Srwatson		return (0);
343105634Srwatson
344105634Srwatson	/* If the range is low-high, it's ok. */
345172955Srwatson	if (mb->mb_rangelow.mbe_type == MAC_BIBA_TYPE_LOW &&
346172955Srwatson	    mb->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_HIGH)
347105634Srwatson		return (0);
348105634Srwatson
349105634Srwatson	/* It's not ok. */
350105634Srwatson	return (EPERM);
351105634Srwatson}
352105634Srwatson
353106091Srwatsonstatic int
354172955Srwatsonbiba_high_effective(struct mac_biba *mb)
355105988Srwatson{
356105988Srwatson
357172955Srwatson	KASSERT((mb->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
358172955Srwatson	    ("biba_equal_effective: mb not effective"));
359105988Srwatson
360172955Srwatson	return (mb->mb_effective.mbe_type == MAC_BIBA_TYPE_HIGH);
361105988Srwatson}
362105988Srwatson
363105634Srwatsonstatic int
364172955Srwatsonbiba_valid(struct mac_biba *mb)
365101099Srwatson{
366101099Srwatson
367172955Srwatson	if (mb->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
368172955Srwatson		switch (mb->mb_effective.mbe_type) {
369101099Srwatson		case MAC_BIBA_TYPE_GRADE:
370101099Srwatson			break;
371101099Srwatson
372101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
373101099Srwatson		case MAC_BIBA_TYPE_HIGH:
374101099Srwatson		case MAC_BIBA_TYPE_LOW:
375172955Srwatson			if (mb->mb_effective.mbe_grade != 0 ||
376105643Srwatson			    !MAC_BIBA_BIT_SET_EMPTY(
377172955Srwatson			    mb->mb_effective.mbe_compartments))
378101099Srwatson				return (EINVAL);
379101099Srwatson			break;
380101099Srwatson
381101099Srwatson		default:
382101099Srwatson			return (EINVAL);
383101099Srwatson		}
384101099Srwatson	} else {
385172955Srwatson		if (mb->mb_effective.mbe_type != MAC_BIBA_TYPE_UNDEF)
386101099Srwatson			return (EINVAL);
387101099Srwatson	}
388101099Srwatson
389172955Srwatson	if (mb->mb_flags & MAC_BIBA_FLAG_RANGE) {
390172955Srwatson		switch (mb->mb_rangelow.mbe_type) {
391101099Srwatson		case MAC_BIBA_TYPE_GRADE:
392101099Srwatson			break;
393101099Srwatson
394101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
395101099Srwatson		case MAC_BIBA_TYPE_HIGH:
396101099Srwatson		case MAC_BIBA_TYPE_LOW:
397172955Srwatson			if (mb->mb_rangelow.mbe_grade != 0 ||
398105643Srwatson			    !MAC_BIBA_BIT_SET_EMPTY(
399172955Srwatson			    mb->mb_rangelow.mbe_compartments))
400101099Srwatson				return (EINVAL);
401101099Srwatson			break;
402101099Srwatson
403101099Srwatson		default:
404101099Srwatson			return (EINVAL);
405101099Srwatson		}
406101099Srwatson
407172955Srwatson		switch (mb->mb_rangehigh.mbe_type) {
408101099Srwatson		case MAC_BIBA_TYPE_GRADE:
409101099Srwatson			break;
410101099Srwatson
411101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
412101099Srwatson		case MAC_BIBA_TYPE_HIGH:
413101099Srwatson		case MAC_BIBA_TYPE_LOW:
414172955Srwatson			if (mb->mb_rangehigh.mbe_grade != 0 ||
415105643Srwatson			    !MAC_BIBA_BIT_SET_EMPTY(
416172955Srwatson			    mb->mb_rangehigh.mbe_compartments))
417101099Srwatson				return (EINVAL);
418101099Srwatson			break;
419101099Srwatson
420101099Srwatson		default:
421101099Srwatson			return (EINVAL);
422101099Srwatson		}
423172955Srwatson		if (!biba_dominate_element(&mb->mb_rangehigh,
424172955Srwatson		    &mb->mb_rangelow))
425101099Srwatson			return (EINVAL);
426101099Srwatson	} else {
427172955Srwatson		if (mb->mb_rangelow.mbe_type != MAC_BIBA_TYPE_UNDEF ||
428172955Srwatson		    mb->mb_rangehigh.mbe_type != MAC_BIBA_TYPE_UNDEF)
429101099Srwatson			return (EINVAL);
430101099Srwatson	}
431101099Srwatson
432101099Srwatson	return (0);
433101099Srwatson}
434101099Srwatson
435101099Srwatsonstatic void
436172955Srwatsonbiba_set_range(struct mac_biba *mb, u_short typelow, u_short gradelow,
437172955Srwatson    u_char *compartmentslow, u_short typehigh, u_short gradehigh,
438172955Srwatson    u_char *compartmentshigh)
439101099Srwatson{
440101099Srwatson
441172955Srwatson	mb->mb_rangelow.mbe_type = typelow;
442172955Srwatson	mb->mb_rangelow.mbe_grade = gradelow;
443105643Srwatson	if (compartmentslow != NULL)
444172955Srwatson		memcpy(mb->mb_rangelow.mbe_compartments, compartmentslow,
445172955Srwatson		    sizeof(mb->mb_rangelow.mbe_compartments));
446172955Srwatson	mb->mb_rangehigh.mbe_type = typehigh;
447172955Srwatson	mb->mb_rangehigh.mbe_grade = gradehigh;
448105643Srwatson	if (compartmentshigh != NULL)
449172955Srwatson		memcpy(mb->mb_rangehigh.mbe_compartments, compartmentshigh,
450172955Srwatson		    sizeof(mb->mb_rangehigh.mbe_compartments));
451172955Srwatson	mb->mb_flags |= MAC_BIBA_FLAG_RANGE;
452101099Srwatson}
453101099Srwatson
454101099Srwatsonstatic void
455172955Srwatsonbiba_set_effective(struct mac_biba *mb, u_short type, u_short grade,
456105643Srwatson    u_char *compartments)
457101099Srwatson{
458101099Srwatson
459172955Srwatson	mb->mb_effective.mbe_type = type;
460172955Srwatson	mb->mb_effective.mbe_grade = grade;
461105643Srwatson	if (compartments != NULL)
462172955Srwatson		memcpy(mb->mb_effective.mbe_compartments, compartments,
463172955Srwatson		    sizeof(mb->mb_effective.mbe_compartments));
464172955Srwatson	mb->mb_flags |= MAC_BIBA_FLAG_EFFECTIVE;
465101099Srwatson}
466101099Srwatson
467101099Srwatsonstatic void
468172955Srwatsonbiba_copy_range(struct mac_biba *labelfrom, struct mac_biba *labelto)
469101099Srwatson{
470105643Srwatson
471101099Srwatson	KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_RANGE) != 0,
472172955Srwatson	    ("biba_copy_range: labelfrom not range"));
473101099Srwatson
474101099Srwatson	labelto->mb_rangelow = labelfrom->mb_rangelow;
475101099Srwatson	labelto->mb_rangehigh = labelfrom->mb_rangehigh;
476101099Srwatson	labelto->mb_flags |= MAC_BIBA_FLAG_RANGE;
477101099Srwatson}
478101099Srwatson
479101099Srwatsonstatic void
480172955Srwatsonbiba_copy_effective(struct mac_biba *labelfrom, struct mac_biba *labelto)
481101099Srwatson{
482101099Srwatson
483132232Srwatson	KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0,
484172955Srwatson	    ("biba_copy_effective: labelfrom not effective"));
485101099Srwatson
486132232Srwatson	labelto->mb_effective = labelfrom->mb_effective;
487132232Srwatson	labelto->mb_flags |= MAC_BIBA_FLAG_EFFECTIVE;
488101099Srwatson}
489101099Srwatson
490105656Srwatsonstatic void
491172955Srwatsonbiba_copy(struct mac_biba *source, struct mac_biba *dest)
492105656Srwatson{
493105656Srwatson
494132232Srwatson	if (source->mb_flags & MAC_BIBA_FLAG_EFFECTIVE)
495172955Srwatson		biba_copy_effective(source, dest);
496105656Srwatson	if (source->mb_flags & MAC_BIBA_FLAG_RANGE)
497172955Srwatson		biba_copy_range(source, dest);
498105656Srwatson}
499105656Srwatson
500101099Srwatson/*
501101099Srwatson * Policy module operations.
502101099Srwatson */
503101099Srwatsonstatic void
504172955Srwatsonbiba_init(struct mac_policy_conf *conf)
505101099Srwatson{
506101099Srwatson
507122879Srwatson	zone_biba = uma_zcreate("mac_biba", sizeof(struct mac_biba), NULL,
508122879Srwatson	    NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
509101099Srwatson}
510101099Srwatson
511101099Srwatson/*
512101099Srwatson * Label operations.
513101099Srwatson */
514101099Srwatsonstatic void
515172955Srwatsonbiba_init_label(struct label *label)
516101099Srwatson{
517101099Srwatson
518132781Skan	SLOT_SET(label, biba_alloc(M_WAITOK));
519101099Srwatson}
520101099Srwatson
521101099Srwatsonstatic int
522172955Srwatsonbiba_init_label_waitcheck(struct label *label, int flag)
523101099Srwatson{
524101099Srwatson
525132781Skan	SLOT_SET(label, biba_alloc(flag));
526101099Srwatson	if (SLOT(label) == NULL)
527101099Srwatson		return (ENOMEM);
528101099Srwatson
529101099Srwatson	return (0);
530101099Srwatson}
531101099Srwatson
532101099Srwatsonstatic void
533172955Srwatsonbiba_destroy_label(struct label *label)
534101099Srwatson{
535101099Srwatson
536101099Srwatson	biba_free(SLOT(label));
537132781Skan	SLOT_SET(label, NULL);
538101099Srwatson}
539101099Srwatson
540105696Srwatson/*
541172955Srwatson * biba_element_to_string() accepts an sbuf and Biba element.  It converts
542172955Srwatson * the Biba element to a string and stores the result in the sbuf; if there
543172955Srwatson * isn't space in the sbuf, -1 is returned.
544105696Srwatson */
545115497Srwatsonstatic int
546172955Srwatsonbiba_element_to_string(struct sbuf *sb, struct mac_biba_element *element)
547105696Srwatson{
548115497Srwatson	int i, first;
549105696Srwatson
550105696Srwatson	switch (element->mbe_type) {
551105696Srwatson	case MAC_BIBA_TYPE_HIGH:
552115497Srwatson		return (sbuf_printf(sb, "high"));
553105696Srwatson
554105696Srwatson	case MAC_BIBA_TYPE_LOW:
555115497Srwatson		return (sbuf_printf(sb, "low"));
556105696Srwatson
557105696Srwatson	case MAC_BIBA_TYPE_EQUAL:
558115497Srwatson		return (sbuf_printf(sb, "equal"));
559105696Srwatson
560105696Srwatson	case MAC_BIBA_TYPE_GRADE:
561115497Srwatson		if (sbuf_printf(sb, "%d", element->mbe_grade) == -1)
562115497Srwatson			return (-1);
563115497Srwatson
564115497Srwatson		first = 1;
565115497Srwatson		for (i = 1; i <= MAC_BIBA_MAX_COMPARTMENTS; i++) {
566115497Srwatson			if (MAC_BIBA_BIT_TEST(i, element->mbe_compartments)) {
567115497Srwatson				if (first) {
568115497Srwatson					if (sbuf_putc(sb, ':') == -1)
569115497Srwatson						return (-1);
570115497Srwatson					if (sbuf_printf(sb, "%d", i) == -1)
571115497Srwatson						return (-1);
572115497Srwatson					first = 0;
573115497Srwatson				} else {
574115497Srwatson					if (sbuf_printf(sb, "+%d", i) == -1)
575115497Srwatson						return (-1);
576115497Srwatson				}
577115497Srwatson			}
578105696Srwatson		}
579115497Srwatson		return (0);
580105696Srwatson
581105696Srwatson	default:
582172955Srwatson		panic("biba_element_to_string: invalid type (%d)",
583105696Srwatson		    element->mbe_type);
584105696Srwatson	}
585105696Srwatson}
586105696Srwatson
587115497Srwatson/*
588172955Srwatson * biba_to_string() converts a Biba label to a string, and places the results
589172955Srwatson * in the passed sbuf.  It returns 0 on success, or EINVAL if there isn't
590172955Srwatson * room in the sbuf.  Note: the sbuf will be modified even in a failure case,
591172955Srwatson * so the caller may need to revert the sbuf by restoring the offset if
592172955Srwatson * that's undesired.
593115497Srwatson */
594101099Srwatsonstatic int
595172955Srwatsonbiba_to_string(struct sbuf *sb, struct mac_biba *mb)
596101099Srwatson{
597105696Srwatson
598172955Srwatson	if (mb->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
599172955Srwatson		if (biba_element_to_string(sb, &mb->mb_effective) == -1)
600105696Srwatson			return (EINVAL);
601105696Srwatson	}
602105696Srwatson
603172955Srwatson	if (mb->mb_flags & MAC_BIBA_FLAG_RANGE) {
604116701Srwatson		if (sbuf_putc(sb, '(') == -1)
605105696Srwatson			return (EINVAL);
606105696Srwatson
607172955Srwatson		if (biba_element_to_string(sb, &mb->mb_rangelow) == -1)
608105696Srwatson			return (EINVAL);
609105696Srwatson
610116701Srwatson		if (sbuf_putc(sb, '-') == -1)
611105696Srwatson			return (EINVAL);
612105696Srwatson
613172955Srwatson		if (biba_element_to_string(sb, &mb->mb_rangehigh) == -1)
614105696Srwatson			return (EINVAL);
615105696Srwatson
616116701Srwatson		if (sbuf_putc(sb, ')') == -1)
617105696Srwatson			return (EINVAL);
618105696Srwatson	}
619105696Srwatson
620105696Srwatson	return (0);
621105696Srwatson}
622105696Srwatson
623105696Srwatsonstatic int
624172955Srwatsonbiba_externalize_label(struct label *label, char *element_name,
625116701Srwatson    struct sbuf *sb, int *claimed)
626105696Srwatson{
627172955Srwatson	struct mac_biba *mb;
628101099Srwatson
629105696Srwatson	if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0)
630105696Srwatson		return (0);
631105696Srwatson
632105696Srwatson	(*claimed)++;
633105696Srwatson
634172955Srwatson	mb = SLOT(label);
635172955Srwatson	return (biba_to_string(sb, mb));
636105696Srwatson}
637105696Srwatson
638105696Srwatsonstatic int
639172955Srwatsonbiba_parse_element(struct mac_biba_element *element, char *string)
640101099Srwatson{
641115395Srwatson	char *compartment, *end, *grade;
642115395Srwatson	int value;
643105696Srwatson
644181217Srwatson	if (strcmp(string, "high") == 0 || strcmp(string, "hi") == 0) {
645105696Srwatson		element->mbe_type = MAC_BIBA_TYPE_HIGH;
646105696Srwatson		element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
647181217Srwatson	} else if (strcmp(string, "low") == 0 || strcmp(string, "lo") == 0) {
648105696Srwatson		element->mbe_type = MAC_BIBA_TYPE_LOW;
649105696Srwatson		element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
650105696Srwatson	} else if (strcmp(string, "equal") == 0 ||
651105696Srwatson	    strcmp(string, "eq") == 0) {
652105696Srwatson		element->mbe_type = MAC_BIBA_TYPE_EQUAL;
653105696Srwatson		element->mbe_grade = MAC_BIBA_TYPE_UNDEF;
654105696Srwatson	} else {
655115395Srwatson		element->mbe_type = MAC_BIBA_TYPE_GRADE;
656105696Srwatson
657115395Srwatson		/*
658115395Srwatson		 * Numeric grade piece of the element.
659115395Srwatson		 */
660115395Srwatson		grade = strsep(&string, ":");
661115395Srwatson		value = strtol(grade, &end, 10);
662115395Srwatson		if (end == grade || *end != '\0')
663105696Srwatson			return (EINVAL);
664115395Srwatson		if (value < 0 || value > 65535)
665115395Srwatson			return (EINVAL);
666115395Srwatson		element->mbe_grade = value;
667105696Srwatson
668115395Srwatson		/*
669181217Srwatson		 * Optional compartment piece of the element.  If none are
670181217Srwatson		 * included, we assume that the label has no compartments.
671115395Srwatson		 */
672115395Srwatson		if (string == NULL)
673115395Srwatson			return (0);
674115395Srwatson		if (*string == '\0')
675115395Srwatson			return (0);
676105696Srwatson
677115395Srwatson		while ((compartment = strsep(&string, "+")) != NULL) {
678115395Srwatson			value = strtol(compartment, &end, 10);
679115395Srwatson			if (compartment == end || *end != '\0')
680105696Srwatson				return (EINVAL);
681115395Srwatson			if (value < 1 || value > MAC_BIBA_MAX_COMPARTMENTS)
682105696Srwatson				return (EINVAL);
683115395Srwatson			MAC_BIBA_BIT_SET(value, element->mbe_compartments);
684105696Srwatson		}
685105696Srwatson	}
686105696Srwatson
687105696Srwatson	return (0);
688105696Srwatson}
689105696Srwatson
690105696Srwatson/*
691181217Srwatson * Note: destructively consumes the string, make a local copy before calling
692181217Srwatson * if that's a problem.
693105696Srwatson */
694105696Srwatsonstatic int
695172955Srwatsonbiba_parse(struct mac_biba *mb, char *string)
696105696Srwatson{
697132232Srwatson	char *rangehigh, *rangelow, *effective;
698101099Srwatson	int error;
699101099Srwatson
700132232Srwatson	effective = strsep(&string, "(");
701132232Srwatson	if (*effective == '\0')
702132232Srwatson		effective = NULL;
703115395Srwatson
704115395Srwatson	if (string != NULL) {
705115395Srwatson		rangelow = strsep(&string, "-");
706115395Srwatson		if (string == NULL)
707105696Srwatson			return (EINVAL);
708115395Srwatson		rangehigh = strsep(&string, ")");
709115395Srwatson		if (string == NULL)
710105696Srwatson			return (EINVAL);
711115395Srwatson		if (*string != '\0')
712105696Srwatson			return (EINVAL);
713115395Srwatson	} else {
714115395Srwatson		rangelow = NULL;
715115395Srwatson		rangehigh = NULL;
716105696Srwatson	}
717115395Srwatson
718105696Srwatson	KASSERT((rangelow != NULL && rangehigh != NULL) ||
719105696Srwatson	    (rangelow == NULL && rangehigh == NULL),
720172955Srwatson	    ("biba_parse: range mismatch"));
721101099Srwatson
722172955Srwatson	bzero(mb, sizeof(*mb));
723132232Srwatson	if (effective != NULL) {
724172955Srwatson		error = biba_parse_element(&mb->mb_effective, effective);
725105696Srwatson		if (error)
726105696Srwatson			return (error);
727172955Srwatson		mb->mb_flags |= MAC_BIBA_FLAG_EFFECTIVE;
728105696Srwatson	}
729105696Srwatson
730105696Srwatson	if (rangelow != NULL) {
731172955Srwatson		error = biba_parse_element(&mb->mb_rangelow, rangelow);
732105696Srwatson		if (error)
733105696Srwatson			return (error);
734172955Srwatson		error = biba_parse_element(&mb->mb_rangehigh, rangehigh);
735105696Srwatson		if (error)
736105696Srwatson			return (error);
737172955Srwatson		mb->mb_flags |= MAC_BIBA_FLAG_RANGE;
738105696Srwatson	}
739105696Srwatson
740172955Srwatson	error = biba_valid(mb);
741101099Srwatson	if (error)
742101099Srwatson		return (error);
743101099Srwatson
744105696Srwatson	return (0);
745105696Srwatson}
746101099Srwatson
747105696Srwatsonstatic int
748172955Srwatsonbiba_internalize_label(struct label *label, char *element_name,
749105696Srwatson    char *element_data, int *claimed)
750105696Srwatson{
751172955Srwatson	struct mac_biba *mb, mb_temp;
752105696Srwatson	int error;
753105696Srwatson
754105696Srwatson	if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0)
755105696Srwatson		return (0);
756105696Srwatson
757105696Srwatson	(*claimed)++;
758105696Srwatson
759172955Srwatson	error = biba_parse(&mb_temp, element_data);
760105696Srwatson	if (error)
761105696Srwatson		return (error);
762105696Srwatson
763172955Srwatson	mb = SLOT(label);
764172955Srwatson	*mb = mb_temp;
765105696Srwatson
766101099Srwatson	return (0);
767101099Srwatson}
768101099Srwatson
769105696Srwatsonstatic void
770172955Srwatsonbiba_copy_label(struct label *src, struct label *dest)
771105696Srwatson{
772105696Srwatson
773105696Srwatson	*SLOT(dest) = *SLOT(src);
774105696Srwatson}
775105696Srwatson
776101099Srwatson/*
777173138Srwatson * Object-specific entry point implementations are sorted alphabetically by
778173138Srwatson * object type name and then by operation.
779101099Srwatson */
780173138Srwatsonstatic int
781173138Srwatsonbiba_bpfdesc_check_receive(struct bpf_d *d, struct label *dlabel,
782173138Srwatson    struct ifnet *ifp, struct label *ifplabel)
783101099Srwatson{
784173138Srwatson	struct mac_biba *a, *b;
785101099Srwatson
786173138Srwatson	if (!biba_enabled)
787173138Srwatson		return (0);
788101099Srwatson
789173138Srwatson	a = SLOT(dlabel);
790173138Srwatson	b = SLOT(ifplabel);
791101099Srwatson
792173138Srwatson	if (biba_equal_effective(a, b))
793173138Srwatson		return (0);
794173138Srwatson	return (EACCES);
795101099Srwatson}
796101099Srwatson
797101099Srwatsonstatic void
798173138Srwatsonbiba_bpfdesc_create(struct ucred *cred, struct bpf_d *d,
799173138Srwatson    struct label *dlabel)
800104535Srwatson{
801104535Srwatson	struct mac_biba *source, *dest;
802104535Srwatson
803122524Srwatson	source = SLOT(cred->cr_label);
804173138Srwatson	dest = SLOT(dlabel);
805104535Srwatson
806172955Srwatson	biba_copy_effective(source, dest);
807104535Srwatson}
808104535Srwatson
809104535Srwatsonstatic void
810173138Srwatsonbiba_bpfdesc_create_mbuf(struct bpf_d *d, struct label *dlabel,
811173138Srwatson    struct mbuf *m, struct label *mlabel)
812101099Srwatson{
813101099Srwatson	struct mac_biba *source, *dest;
814101099Srwatson
815173138Srwatson	source = SLOT(dlabel);
816173138Srwatson	dest = SLOT(mlabel);
817172955Srwatson
818172955Srwatson	biba_copy_effective(source, dest);
819101099Srwatson}
820101099Srwatson
821184407Srwatsonstatic void
822184407Srwatsonbiba_cred_associate_nfsd(struct ucred *cred)
823184407Srwatson{
824184407Srwatson	struct mac_biba *label;
825184407Srwatson
826184407Srwatson	label = SLOT(cred->cr_label);
827184407Srwatson	biba_set_effective(label, MAC_BIBA_TYPE_LOW, 0, NULL);
828184407Srwatson	biba_set_range(label, MAC_BIBA_TYPE_LOW, 0, NULL, MAC_BIBA_TYPE_HIGH,
829184407Srwatson	    0, NULL);
830184407Srwatson}
831184407Srwatson
832173138Srwatsonstatic int
833173138Srwatsonbiba_cred_check_relabel(struct ucred *cred, struct label *newlabel)
834101099Srwatson{
835173138Srwatson	struct mac_biba *subj, *new;
836173138Srwatson	int error;
837101099Srwatson
838173138Srwatson	subj = SLOT(cred->cr_label);
839173138Srwatson	new = SLOT(newlabel);
840101099Srwatson
841173138Srwatson	/*
842173138Srwatson	 * If there is a Biba label update for the credential, it may
843173138Srwatson	 * be an update of the effective, range, or both.
844173138Srwatson	 */
845173138Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
846173138Srwatson	if (error)
847173138Srwatson		return (error);
848101099Srwatson
849173138Srwatson	/*
850173138Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
851173138Srwatson	 */
852173138Srwatson	if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) {
853173138Srwatson		/*
854173138Srwatson		 * If the change request modifies both the Biba label
855173138Srwatson		 * effective and range, check that the new effective will be
856173138Srwatson		 * in the new range.
857173138Srwatson		 */
858173138Srwatson		if ((new->mb_flags & MAC_BIBA_FLAGS_BOTH) ==
859173138Srwatson		    MAC_BIBA_FLAGS_BOTH &&
860173138Srwatson		    !biba_effective_in_range(new, new))
861173138Srwatson			return (EINVAL);
862101099Srwatson
863173138Srwatson		/*
864173138Srwatson		 * To change the Biba effective label on a credential, the
865173138Srwatson		 * new effective label must be in the current range.
866173138Srwatson		 */
867173138Srwatson		if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE &&
868173138Srwatson		    !biba_effective_in_range(new, subj))
869173138Srwatson			return (EPERM);
870101099Srwatson
871173138Srwatson		/*
872173138Srwatson		 * To change the Biba range on a credential, the new range
873173138Srwatson		 * label must be in the current range.
874173138Srwatson		 */
875173138Srwatson		if (new->mb_flags & MAC_BIBA_FLAG_RANGE &&
876173138Srwatson		    !biba_range_in_range(new, subj))
877173138Srwatson			return (EPERM);
878101099Srwatson
879173138Srwatson		/*
880173138Srwatson		 * To have EQUAL in any component of the new credential Biba
881173138Srwatson		 * label, the subject must already have EQUAL in their label.
882173138Srwatson		 */
883173138Srwatson		if (biba_contains_equal(new)) {
884173138Srwatson			error = biba_subject_privileged(subj);
885173138Srwatson			if (error)
886173138Srwatson				return (error);
887173138Srwatson		}
888105988Srwatson	}
889101099Srwatson
890101099Srwatson	return (0);
891101099Srwatson}
892101099Srwatson
893105988Srwatsonstatic int
894173138Srwatsonbiba_cred_check_visible(struct ucred *u1, struct ucred *u2)
895105988Srwatson{
896173138Srwatson	struct mac_biba *subj, *obj;
897105988Srwatson
898173138Srwatson	if (!biba_enabled)
899105988Srwatson		return (0);
900105988Srwatson
901173138Srwatson	subj = SLOT(u1->cr_label);
902173138Srwatson	obj = SLOT(u2->cr_label);
903105988Srwatson
904173138Srwatson	/* XXX: range */
905173138Srwatson	if (!biba_dominate_effective(obj, subj))
906173138Srwatson		return (ESRCH);
907105988Srwatson
908173138Srwatson	return (0);
909122875Srwatson}
910122875Srwatson
911122875Srwatsonstatic void
912184407Srwatsonbiba_cred_create_init(struct ucred *cred)
913184407Srwatson{
914184407Srwatson	struct mac_biba *dest;
915184407Srwatson
916184407Srwatson	dest = SLOT(cred->cr_label);
917184407Srwatson
918184407Srwatson	biba_set_effective(dest, MAC_BIBA_TYPE_HIGH, 0, NULL);
919184407Srwatson	biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL, MAC_BIBA_TYPE_HIGH,
920184407Srwatson	    0, NULL);
921184407Srwatson}
922184407Srwatson
923184407Srwatsonstatic void
924184407Srwatsonbiba_cred_create_swapper(struct ucred *cred)
925184407Srwatson{
926184407Srwatson	struct mac_biba *dest;
927184407Srwatson
928184407Srwatson	dest = SLOT(cred->cr_label);
929184407Srwatson
930184407Srwatson	biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
931184407Srwatson	biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL, MAC_BIBA_TYPE_HIGH,
932184407Srwatson	    0, NULL);
933184407Srwatson}
934184407Srwatson
935184407Srwatsonstatic void
936173138Srwatsonbiba_cred_relabel(struct ucred *cred, struct label *newlabel)
937101099Srwatson{
938101099Srwatson	struct mac_biba *source, *dest;
939101099Srwatson
940173138Srwatson	source = SLOT(newlabel);
941173138Srwatson	dest = SLOT(cred->cr_label);
942101099Srwatson
943173138Srwatson	biba_copy(source, dest);
944101099Srwatson}
945101099Srwatson
946101099Srwatsonstatic void
947173138Srwatsonbiba_devfs_create_device(struct ucred *cred, struct mount *mp,
948173138Srwatson    struct cdev *dev, struct devfs_dirent *de, struct label *delabel)
949101099Srwatson{
950173138Srwatson	struct mac_biba *mb;
951232405Sed	const char *dn;
952173138Srwatson	int biba_type;
953101099Srwatson
954173138Srwatson	mb = SLOT(delabel);
955232405Sed	dn = devtoname(dev);
956232405Sed	if (strcmp(dn, "null") == 0 ||
957232405Sed	    strcmp(dn, "zero") == 0 ||
958232405Sed	    strcmp(dn, "random") == 0 ||
959232405Sed	    strncmp(dn, "fd/", strlen("fd/")) == 0)
960173138Srwatson		biba_type = MAC_BIBA_TYPE_EQUAL;
961173138Srwatson	else if (ptys_equal &&
962232405Sed	    (strncmp(dn, "ttyp", strlen("ttyp")) == 0 ||
963232405Sed	    strncmp(dn, "pts/", strlen("pts/")) == 0 ||
964232405Sed	    strncmp(dn, "ptyp", strlen("ptyp")) == 0))
965173138Srwatson		biba_type = MAC_BIBA_TYPE_EQUAL;
966173138Srwatson	else
967173138Srwatson		biba_type = MAC_BIBA_TYPE_HIGH;
968173138Srwatson	biba_set_effective(mb, biba_type, 0, NULL);
969101099Srwatson}
970101099Srwatson
971101099Srwatsonstatic void
972173138Srwatsonbiba_devfs_create_directory(struct mount *mp, char *dirname, int dirnamelen,
973173138Srwatson    struct devfs_dirent *de, struct label *delabel)
974101099Srwatson{
975173138Srwatson	struct mac_biba *mb;
976101099Srwatson
977173138Srwatson	mb = SLOT(delabel);
978101099Srwatson
979173138Srwatson	biba_set_effective(mb, MAC_BIBA_TYPE_HIGH, 0, NULL);
980101099Srwatson}
981101099Srwatson
982101099Srwatsonstatic void
983173138Srwatsonbiba_devfs_create_symlink(struct ucred *cred, struct mount *mp,
984173138Srwatson    struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de,
985173138Srwatson    struct label *delabel)
986145855Srwatson{
987145855Srwatson	struct mac_biba *source, *dest;
988145855Srwatson
989145855Srwatson	source = SLOT(cred->cr_label);
990173138Srwatson	dest = SLOT(delabel);
991145855Srwatson
992172955Srwatson	biba_copy_effective(source, dest);
993145855Srwatson}
994145855Srwatson
995145855Srwatsonstatic void
996173138Srwatsonbiba_devfs_update(struct mount *mp, struct devfs_dirent *de,
997173138Srwatson    struct label *delabel, struct vnode *vp, struct label *vplabel)
998101099Srwatson{
999101099Srwatson	struct mac_biba *source, *dest;
1000101099Srwatson
1001173138Srwatson	source = SLOT(vplabel);
1002173138Srwatson	dest = SLOT(delabel);
1003101099Srwatson
1004172955Srwatson	biba_copy(source, dest);
1005101099Srwatson}
1006101099Srwatson
1007101099Srwatsonstatic void
1008173138Srwatsonbiba_devfs_vnode_associate(struct mount *mp, struct label *mntlabel,
1009173138Srwatson    struct devfs_dirent *de, struct label *delabel, struct vnode *vp,
1010173138Srwatson    struct label *vplabel)
1011101099Srwatson{
1012101099Srwatson	struct mac_biba *source, *dest;
1013101099Srwatson
1014173138Srwatson	source = SLOT(delabel);
1015173138Srwatson	dest = SLOT(vplabel);
1016101099Srwatson
1017172955Srwatson	biba_copy_effective(source, dest);
1018101099Srwatson}
1019101099Srwatson
1020173138Srwatsonstatic int
1021173138Srwatsonbiba_ifnet_check_relabel(struct ucred *cred, struct ifnet *ifp,
1022173138Srwatson    struct label *ifplabel, struct label *newlabel)
1023140628Srwatson{
1024173138Srwatson	struct mac_biba *subj, *new;
1025173138Srwatson	int error;
1026140628Srwatson
1027173138Srwatson	subj = SLOT(cred->cr_label);
1028173138Srwatson	new = SLOT(newlabel);
1029140628Srwatson
1030173138Srwatson	/*
1031173138Srwatson	 * If there is a Biba label update for the interface, it may be an
1032173138Srwatson	 * update of the effective, range, or both.
1033173138Srwatson	 */
1034173138Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
1035173138Srwatson	if (error)
1036173138Srwatson		return (error);
1037140628Srwatson
1038173138Srwatson	/*
1039173138Srwatson	 * Relabling network interfaces requires Biba privilege.
1040173138Srwatson	 */
1041173138Srwatson	error = biba_subject_privileged(subj);
1042173138Srwatson	if (error)
1043173138Srwatson		return (error);
1044140628Srwatson
1045173138Srwatson	return (0);
1046140628Srwatson}
1047140628Srwatson
1048173138Srwatsonstatic int
1049173138Srwatsonbiba_ifnet_check_transmit(struct ifnet *ifp, struct label *ifplabel,
1050173138Srwatson    struct mbuf *m, struct label *mlabel)
1051140628Srwatson{
1052173138Srwatson	struct mac_biba *p, *i;
1053140628Srwatson
1054173138Srwatson	if (!biba_enabled)
1055173138Srwatson		return (0);
1056140628Srwatson
1057173138Srwatson	p = SLOT(mlabel);
1058173138Srwatson	i = SLOT(ifplabel);
1059140628Srwatson
1060173138Srwatson	return (biba_effective_in_range(p, i) ? 0 : EACCES);
1061140628Srwatson}
1062140628Srwatson
1063101099Srwatsonstatic void
1064172955Srwatsonbiba_ifnet_create(struct ifnet *ifp, struct label *ifplabel)
1065101099Srwatson{
1066121816Sbrooks	char tifname[IFNAMSIZ], *p, *q;
1067101099Srwatson	char tiflist[sizeof(trusted_interfaces)];
1068101099Srwatson	struct mac_biba *dest;
1069110350Srwatson	int len, type;
1070101099Srwatson
1071168976Srwatson	dest = SLOT(ifplabel);
1072101099Srwatson
1073168976Srwatson	if (ifp->if_type == IFT_LOOP || interfaces_equal != 0) {
1074110350Srwatson		type = MAC_BIBA_TYPE_EQUAL;
1075101099Srwatson		goto set;
1076101099Srwatson	}
1077101099Srwatson
1078101099Srwatson	if (trust_all_interfaces) {
1079110350Srwatson		type = MAC_BIBA_TYPE_HIGH;
1080101099Srwatson		goto set;
1081101099Srwatson	}
1082101099Srwatson
1083110350Srwatson	type = MAC_BIBA_TYPE_LOW;
1084101099Srwatson
1085101099Srwatson	if (trusted_interfaces[0] == '\0' ||
1086101099Srwatson	    !strvalid(trusted_interfaces, sizeof(trusted_interfaces)))
1087101099Srwatson		goto set;
1088101099Srwatson
1089106089Srwatson	bzero(tiflist, sizeof(tiflist));
1090101099Srwatson	for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++)
1091101099Srwatson		if(*p != ' ' && *p != '\t')
1092101099Srwatson			*q = *p;
1093101099Srwatson
1094101099Srwatson	for (p = q = tiflist;; p++) {
1095101099Srwatson		if (*p == ',' || *p == '\0') {
1096101099Srwatson			len = p - q;
1097101099Srwatson			if (len < IFNAMSIZ) {
1098101099Srwatson				bzero(tifname, sizeof(tifname));
1099101099Srwatson				bcopy(q, tifname, len);
1100168976Srwatson				if (strcmp(tifname, ifp->if_xname) == 0) {
1101110350Srwatson					type = MAC_BIBA_TYPE_HIGH;
1102101099Srwatson					break;
1103101099Srwatson				}
1104106089Srwatson			} else {
1105106089Srwatson				*p = '\0';
1106106089Srwatson				printf("mac_biba warning: interface name "
1107106089Srwatson				    "\"%s\" is too long (must be < %d)\n",
1108106089Srwatson				    q, IFNAMSIZ);
1109101099Srwatson			}
1110101099Srwatson			if (*p == '\0')
1111101099Srwatson				break;
1112101099Srwatson			q = p + 1;
1113101099Srwatson		}
1114101099Srwatson	}
1115101099Srwatsonset:
1116172955Srwatson	biba_set_effective(dest, type, 0, NULL);
1117172955Srwatson	biba_set_range(dest, type, 0, NULL, type, 0, NULL);
1118101099Srwatson}
1119101099Srwatson
1120101099Srwatsonstatic void
1121173138Srwatsonbiba_ifnet_create_mbuf(struct ifnet *ifp, struct label *ifplabel,
1122173138Srwatson    struct mbuf *m, struct label *mlabel)
1123101099Srwatson{
1124101099Srwatson	struct mac_biba *source, *dest;
1125101099Srwatson
1126173138Srwatson	source = SLOT(ifplabel);
1127173138Srwatson	dest = SLOT(mlabel);
1128101099Srwatson
1129172955Srwatson	biba_copy_effective(source, dest);
1130101099Srwatson}
1131101099Srwatson
1132101099Srwatsonstatic void
1133173138Srwatsonbiba_ifnet_relabel(struct ucred *cred, struct ifnet *ifp,
1134173138Srwatson    struct label *ifplabel, struct label *newlabel)
1135101099Srwatson{
1136101099Srwatson	struct mac_biba *source, *dest;
1137101099Srwatson
1138173138Srwatson	source = SLOT(newlabel);
1139173138Srwatson	dest = SLOT(ifplabel);
1140101099Srwatson
1141173138Srwatson	biba_copy(source, dest);
1142101099Srwatson}
1143101099Srwatson
1144173138Srwatsonstatic int
1145173138Srwatsonbiba_inpcb_check_deliver(struct inpcb *inp, struct label *inplabel,
1146173138Srwatson    struct mbuf *m, struct label *mlabel)
1147173138Srwatson{
1148173138Srwatson	struct mac_biba *p, *i;
1149173138Srwatson
1150173138Srwatson	if (!biba_enabled)
1151173138Srwatson		return (0);
1152173138Srwatson
1153173138Srwatson	p = SLOT(mlabel);
1154173138Srwatson	i = SLOT(inplabel);
1155173138Srwatson
1156173138Srwatson	return (biba_equal_effective(p, i) ? 0 : EACCES);
1157173138Srwatson}
1158173138Srwatson
1159183980Sbzstatic int
1160183980Sbzbiba_inpcb_check_visible(struct ucred *cred, struct inpcb *inp,
1161183980Sbz    struct label *inplabel)
1162183980Sbz{
1163183980Sbz	struct mac_biba *subj, *obj;
1164183980Sbz
1165183980Sbz	if (!biba_enabled)
1166183980Sbz		return (0);
1167183980Sbz
1168183980Sbz	subj = SLOT(cred->cr_label);
1169183980Sbz	obj = SLOT(inplabel);
1170183980Sbz
1171183980Sbz	if (!biba_dominate_effective(obj, subj))
1172183980Sbz		return (ENOENT);
1173183980Sbz
1174183980Sbz	return (0);
1175183980Sbz}
1176183980Sbz
1177101099Srwatsonstatic void
1178173138Srwatsonbiba_inpcb_create(struct socket *so, struct label *solabel,
1179173138Srwatson    struct inpcb *inp, struct label *inplabel)
1180101099Srwatson{
1181101099Srwatson	struct mac_biba *source, *dest;
1182101099Srwatson
1183173138Srwatson	source = SLOT(solabel);
1184173138Srwatson	dest = SLOT(inplabel);
1185101099Srwatson
1186193391Srwatson	SOCK_LOCK(so);
1187172955Srwatson	biba_copy_effective(source, dest);
1188193391Srwatson	SOCK_UNLOCK(so);
1189101099Srwatson}
1190101099Srwatson
1191101099Srwatsonstatic void
1192172955Srwatsonbiba_inpcb_create_mbuf(struct inpcb *inp, struct label *inplabel,
1193123607Srwatson    struct mbuf *m, struct label *mlabel)
1194123607Srwatson{
1195123607Srwatson	struct mac_biba *source, *dest;
1196123607Srwatson
1197123607Srwatson	source = SLOT(inplabel);
1198123607Srwatson	dest = SLOT(mlabel);
1199123607Srwatson
1200172955Srwatson	biba_copy_effective(source, dest);
1201123607Srwatson}
1202123607Srwatson
1203123607Srwatsonstatic void
1204173138Srwatsonbiba_inpcb_sosetlabel(struct socket *so, struct label *solabel,
1205173138Srwatson    struct inpcb *inp, struct label *inplabel)
1206101099Srwatson{
1207101099Srwatson	struct mac_biba *source, *dest;
1208101099Srwatson
1209193391Srwatson	SOCK_LOCK_ASSERT(so);
1210193391Srwatson
1211173138Srwatson	source = SLOT(solabel);
1212173138Srwatson	dest = SLOT(inplabel);
1213101099Srwatson
1214173138Srwatson	biba_copy(source, dest);
1215101099Srwatson}
1216101099Srwatson
1217101099Srwatsonstatic void
1218184308Srwatsonbiba_ip6q_create(struct mbuf *m, struct label *mlabel, struct ip6q *q6,
1219184308Srwatson    struct label *q6label)
1220184308Srwatson{
1221184308Srwatson	struct mac_biba *source, *dest;
1222184308Srwatson
1223184308Srwatson	source = SLOT(mlabel);
1224184308Srwatson	dest = SLOT(q6label);
1225184308Srwatson
1226184308Srwatson	biba_copy_effective(source, dest);
1227184308Srwatson}
1228184308Srwatson
1229184308Srwatsonstatic int
1230184308Srwatsonbiba_ip6q_match(struct mbuf *m, struct label *mlabel, struct ip6q *q6,
1231184308Srwatson    struct label *q6label)
1232184308Srwatson{
1233184308Srwatson	struct mac_biba *a, *b;
1234184308Srwatson
1235184308Srwatson	a = SLOT(q6label);
1236184308Srwatson	b = SLOT(mlabel);
1237184308Srwatson
1238184308Srwatson	return (biba_equal_effective(a, b));
1239184308Srwatson}
1240184308Srwatson
1241184308Srwatsonstatic void
1242184308Srwatsonbiba_ip6q_reassemble(struct ip6q *q6, struct label *q6label, struct mbuf *m,
1243184308Srwatson    struct label *mlabel)
1244184308Srwatson{
1245184308Srwatson	struct mac_biba *source, *dest;
1246184308Srwatson
1247184308Srwatson	source = SLOT(q6label);
1248184308Srwatson	dest = SLOT(mlabel);
1249184308Srwatson
1250184308Srwatson	/* Just use the head, since we require them all to match. */
1251184308Srwatson	biba_copy_effective(source, dest);
1252184308Srwatson}
1253184308Srwatson
1254184308Srwatsonstatic void
1255184308Srwatsonbiba_ip6q_update(struct mbuf *m, struct label *mlabel, struct ip6q *q6,
1256184308Srwatson    struct label *q6label)
1257184308Srwatson{
1258184308Srwatson
1259184308Srwatson	/* NOOP: we only accept matching labels, so no need to update */
1260184308Srwatson}
1261184308Srwatson
1262184308Srwatsonstatic void
1263179781Srwatsonbiba_ipq_create(struct mbuf *m, struct label *mlabel, struct ipq *q,
1264179781Srwatson    struct label *qlabel)
1265101099Srwatson{
1266101099Srwatson	struct mac_biba *source, *dest;
1267101099Srwatson
1268173138Srwatson	source = SLOT(mlabel);
1269179781Srwatson	dest = SLOT(qlabel);
1270101099Srwatson
1271172955Srwatson	biba_copy_effective(source, dest);
1272101099Srwatson}
1273101099Srwatson
1274101099Srwatsonstatic int
1275179781Srwatsonbiba_ipq_match(struct mbuf *m, struct label *mlabel, struct ipq *q,
1276179781Srwatson    struct label *qlabel)
1277101099Srwatson{
1278101099Srwatson	struct mac_biba *a, *b;
1279101099Srwatson
1280179781Srwatson	a = SLOT(qlabel);
1281168976Srwatson	b = SLOT(mlabel);
1282101099Srwatson
1283172955Srwatson	return (biba_equal_effective(a, b));
1284101099Srwatson}
1285101099Srwatson
1286101099Srwatsonstatic void
1287179781Srwatsonbiba_ipq_reassemble(struct ipq *q, struct label *qlabel, struct mbuf *m,
1288173138Srwatson    struct label *mlabel)
1289101099Srwatson{
1290101099Srwatson	struct mac_biba *source, *dest;
1291101099Srwatson
1292179781Srwatson	source = SLOT(qlabel);
1293173138Srwatson	dest = SLOT(mlabel);
1294101099Srwatson
1295173138Srwatson	/* Just use the head, since we require them all to match. */
1296173138Srwatson	biba_copy_effective(source, dest);
1297101099Srwatson}
1298101099Srwatson
1299101099Srwatsonstatic void
1300179781Srwatsonbiba_ipq_update(struct mbuf *m, struct label *mlabel, struct ipq *q,
1301179781Srwatson    struct label *qlabel)
1302101099Srwatson{
1303101099Srwatson
1304101099Srwatson	/* NOOP: we only accept matching labels, so no need to update */
1305101099Srwatson}
1306101099Srwatson
1307173138Srwatsonstatic int
1308173138Srwatsonbiba_kld_check_load(struct ucred *cred, struct vnode *vp,
1309173138Srwatson    struct label *vplabel)
1310173138Srwatson{
1311173138Srwatson	struct mac_biba *subj, *obj;
1312173138Srwatson	int error;
1313173138Srwatson
1314173138Srwatson	if (!biba_enabled)
1315173138Srwatson		return (0);
1316173138Srwatson
1317173138Srwatson	subj = SLOT(cred->cr_label);
1318173138Srwatson
1319173138Srwatson	error = biba_subject_privileged(subj);
1320173138Srwatson	if (error)
1321173138Srwatson		return (error);
1322173138Srwatson
1323173138Srwatson	obj = SLOT(vplabel);
1324173138Srwatson	if (!biba_high_effective(obj))
1325173138Srwatson		return (EACCES);
1326173138Srwatson
1327173138Srwatson	return (0);
1328173138Srwatson}
1329173138Srwatson
1330173138Srwatsonstatic int
1331173138Srwatsonbiba_mount_check_stat(struct ucred *cred, struct mount *mp,
1332173138Srwatson    struct label *mplabel)
1333173138Srwatson{
1334173138Srwatson	struct mac_biba *subj, *obj;
1335173138Srwatson
1336173138Srwatson	if (!biba_enabled)
1337173138Srwatson		return (0);
1338173138Srwatson
1339173138Srwatson	subj = SLOT(cred->cr_label);
1340173138Srwatson	obj = SLOT(mplabel);
1341173138Srwatson
1342173138Srwatson	if (!biba_dominate_effective(obj, subj))
1343173138Srwatson		return (EACCES);
1344173138Srwatson
1345173138Srwatson	return (0);
1346173138Srwatson}
1347173138Srwatson
1348122875Srwatsonstatic void
1349173138Srwatsonbiba_mount_create(struct ucred *cred, struct mount *mp,
1350173138Srwatson    struct label *mplabel)
1351122875Srwatson{
1352122875Srwatson	struct mac_biba *source, *dest;
1353122875Srwatson
1354173138Srwatson	source = SLOT(cred->cr_label);
1355173138Srwatson	dest = SLOT(mplabel);
1356122875Srwatson
1357173138Srwatson	biba_copy_effective(source, dest);
1358122875Srwatson}
1359122875Srwatson
1360162238Scsjpstatic void
1361173095Srwatsonbiba_netatalk_aarp_send(struct ifnet *ifp, struct label *ifplabel,
1362173095Srwatson    struct mbuf *m, struct label *mlabel)
1363173095Srwatson{
1364173095Srwatson	struct mac_biba *dest;
1365173095Srwatson
1366173095Srwatson	dest = SLOT(mlabel);
1367173095Srwatson
1368173095Srwatson	biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1369173095Srwatson}
1370173095Srwatson
1371173095Srwatsonstatic void
1372173095Srwatsonbiba_netinet_arp_send(struct ifnet *ifp, struct label *ifplabel,
1373173095Srwatson    struct mbuf *m, struct label *mlabel)
1374173095Srwatson{
1375173095Srwatson	struct mac_biba *dest;
1376173095Srwatson
1377173095Srwatson	dest = SLOT(mlabel);
1378173095Srwatson
1379173095Srwatson	biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1380173095Srwatson}
1381173095Srwatson
1382173095Srwatsonstatic void
1383173102Srwatsonbiba_netinet_firewall_reply(struct mbuf *mrecv, struct label *mrecvlabel,
1384173102Srwatson    struct mbuf *msend, struct label *msendlabel)
1385173102Srwatson{
1386173102Srwatson	struct mac_biba *source, *dest;
1387173102Srwatson
1388173102Srwatson	source = SLOT(mrecvlabel);
1389173102Srwatson	dest = SLOT(msendlabel);
1390173102Srwatson
1391173102Srwatson	biba_copy_effective(source, dest);
1392173102Srwatson}
1393173102Srwatson
1394173102Srwatsonstatic void
1395173018Srwatsonbiba_netinet_firewall_send(struct mbuf *m, struct label *mlabel)
1396162238Scsjp{
1397162238Scsjp	struct mac_biba *dest;
1398162238Scsjp
1399173018Srwatson	dest = SLOT(mlabel);
1400162238Scsjp
1401173018Srwatson	/* XXX: where is the label for the firewall really coming from? */
1402172955Srwatson	biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1403162238Scsjp}
1404162238Scsjp
1405173095Srwatsonstatic void
1406173138Srwatsonbiba_netinet_fragment(struct mbuf *m, struct label *mlabel,
1407173138Srwatson    struct mbuf *frag, struct label *fraglabel)
1408173138Srwatson{
1409173138Srwatson	struct mac_biba *source, *dest;
1410173138Srwatson
1411173138Srwatson	source = SLOT(mlabel);
1412173138Srwatson	dest = SLOT(fraglabel);
1413173138Srwatson
1414173138Srwatson	biba_copy_effective(source, dest);
1415173138Srwatson}
1416173138Srwatson
1417173138Srwatsonstatic void
1418173102Srwatsonbiba_netinet_icmp_reply(struct mbuf *mrecv, struct label *mrecvlabel,
1419173102Srwatson    struct mbuf *msend, struct label *msendlabel)
1420173102Srwatson{
1421173102Srwatson	struct mac_biba *source, *dest;
1422173102Srwatson
1423173102Srwatson	source = SLOT(mrecvlabel);
1424173102Srwatson	dest = SLOT(msendlabel);
1425173102Srwatson
1426173102Srwatson	biba_copy_effective(source, dest);
1427173102Srwatson}
1428173102Srwatson
1429173102Srwatsonstatic void
1430173095Srwatsonbiba_netinet_igmp_send(struct ifnet *ifp, struct label *ifplabel,
1431173095Srwatson    struct mbuf *m, struct label *mlabel)
1432173095Srwatson{
1433173095Srwatson	struct mac_biba *dest;
1434173095Srwatson
1435173095Srwatson	dest = SLOT(mlabel);
1436173095Srwatson
1437173095Srwatson	biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1438173095Srwatson}
1439173095Srwatson
1440173095Srwatsonstatic void
1441173095Srwatsonbiba_netinet6_nd6_send(struct ifnet *ifp, struct label *ifplabel,
1442173095Srwatson    struct mbuf *m, struct label *mlabel)
1443173095Srwatson{
1444173095Srwatson	struct mac_biba *dest;
1445173095Srwatson
1446173095Srwatson	dest = SLOT(mlabel);
1447173095Srwatson
1448173095Srwatson	biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1449173095Srwatson}
1450173095Srwatson
1451173138Srwatsonstatic int
1452173138Srwatsonbiba_pipe_check_ioctl(struct ucred *cred, struct pipepair *pp,
1453173138Srwatson    struct label *pplabel, unsigned long cmd, void /* caddr_t */ *data)
1454101099Srwatson{
1455101099Srwatson
1456173138Srwatson	if(!biba_enabled)
1457173138Srwatson		return (0);
1458101099Srwatson
1459173138Srwatson	/* XXX: This will be implemented soon... */
1460101099Srwatson
1461173138Srwatson	return (0);
1462101099Srwatson}
1463101099Srwatson
1464173138Srwatsonstatic int
1465173138Srwatsonbiba_pipe_check_poll(struct ucred *cred, struct pipepair *pp,
1466173138Srwatson    struct label *pplabel)
1467172957Srwatson{
1468173138Srwatson	struct mac_biba *subj, *obj;
1469172957Srwatson
1470173138Srwatson	if (!biba_enabled)
1471173138Srwatson		return (0);
1472172957Srwatson
1473173138Srwatson	subj = SLOT(cred->cr_label);
1474173138Srwatson	obj = SLOT(pplabel);
1475101099Srwatson
1476173138Srwatson	if (!biba_dominate_effective(obj, subj))
1477173138Srwatson		return (EACCES);
1478101099Srwatson
1479173138Srwatson	return (0);
1480101099Srwatson}
1481101099Srwatson
1482101099Srwatsonstatic int
1483173138Srwatsonbiba_pipe_check_read(struct ucred *cred, struct pipepair *pp,
1484173138Srwatson    struct label *pplabel)
1485101099Srwatson{
1486173138Srwatson	struct mac_biba *subj, *obj;
1487101099Srwatson
1488172955Srwatson	if (!biba_enabled)
1489101099Srwatson		return (0);
1490101099Srwatson
1491173138Srwatson	subj = SLOT(cred->cr_label);
1492173138Srwatson	obj = SLOT(pplabel);
1493101099Srwatson
1494173138Srwatson	if (!biba_dominate_effective(obj, subj))
1495173138Srwatson		return (EACCES);
1496173138Srwatson
1497173138Srwatson	return (0);
1498101099Srwatson}
1499101099Srwatson
1500101099Srwatsonstatic int
1501173138Srwatsonbiba_pipe_check_relabel(struct ucred *cred, struct pipepair *pp,
1502173138Srwatson    struct label *pplabel, struct label *newlabel)
1503101099Srwatson{
1504173138Srwatson	struct mac_biba *subj, *obj, *new;
1505105634Srwatson	int error;
1506101099Srwatson
1507173138Srwatson	new = SLOT(newlabel);
1508122524Srwatson	subj = SLOT(cred->cr_label);
1509173138Srwatson	obj = SLOT(pplabel);
1510101099Srwatson
1511101099Srwatson	/*
1512173138Srwatson	 * If there is a Biba label update for a pipe, it must be a effective
1513173138Srwatson	 * update.
1514101099Srwatson	 */
1515173138Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE);
1516105634Srwatson	if (error)
1517105634Srwatson		return (error);
1518101099Srwatson
1519101099Srwatson	/*
1520173138Srwatson	 * To perform a relabel of a pipe (Biba label or not), Biba must
1521173138Srwatson	 * authorize the relabel.
1522173138Srwatson	 */
1523173138Srwatson	if (!biba_effective_in_range(obj, subj))
1524173138Srwatson		return (EPERM);
1525173138Srwatson
1526173138Srwatson	/*
1527105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
1528101099Srwatson	 */
1529173138Srwatson	if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
1530105634Srwatson		/*
1531173138Srwatson		 * To change the Biba label on a pipe, the new pipe label
1532173138Srwatson		 * must be in the subject range.
1533110351Srwatson		 */
1534173138Srwatson		if (!biba_effective_in_range(new, subj))
1535105634Srwatson			return (EPERM);
1536101099Srwatson
1537105634Srwatson		/*
1538173138Srwatson		 * To change the Biba label on a pipe to be EQUAL, the
1539173138Srwatson		 * subject must have appropriate privilege.
1540105634Srwatson		 */
1541172955Srwatson		if (biba_contains_equal(new)) {
1542172955Srwatson			error = biba_subject_privileged(subj);
1543105634Srwatson			if (error)
1544105634Srwatson				return (error);
1545105634Srwatson		}
1546105634Srwatson	}
1547105634Srwatson
1548101099Srwatson	return (0);
1549101099Srwatson}
1550101099Srwatson
1551101099Srwatsonstatic int
1552173138Srwatsonbiba_pipe_check_stat(struct ucred *cred, struct pipepair *pp,
1553173138Srwatson    struct label *pplabel)
1554101099Srwatson{
1555101099Srwatson	struct mac_biba *subj, *obj;
1556101099Srwatson
1557172955Srwatson	if (!biba_enabled)
1558101099Srwatson		return (0);
1559101099Srwatson
1560173138Srwatson	subj = SLOT(cred->cr_label);
1561173138Srwatson	obj = SLOT(pplabel);
1562101099Srwatson
1563172955Srwatson	if (!biba_dominate_effective(obj, subj))
1564173138Srwatson		return (EACCES);
1565101099Srwatson
1566101099Srwatson	return (0);
1567101099Srwatson}
1568101099Srwatson
1569101099Srwatsonstatic int
1570173138Srwatsonbiba_pipe_check_write(struct ucred *cred, struct pipepair *pp,
1571173138Srwatson    struct label *pplabel)
1572101099Srwatson{
1573173138Srwatson	struct mac_biba *subj, *obj;
1574101099Srwatson
1575173138Srwatson	if (!biba_enabled)
1576173138Srwatson		return (0);
1577173138Srwatson
1578122524Srwatson	subj = SLOT(cred->cr_label);
1579173138Srwatson	obj = SLOT(pplabel);
1580101099Srwatson
1581173138Srwatson	if (!biba_dominate_effective(subj, obj))
1582173138Srwatson		return (EACCES);
1583101099Srwatson
1584105634Srwatson	return (0);
1585101099Srwatson}
1586101099Srwatson
1587173138Srwatsonstatic void
1588173138Srwatsonbiba_pipe_create(struct ucred *cred, struct pipepair *pp,
1589173138Srwatson    struct label *pplabel)
1590101099Srwatson{
1591173138Srwatson	struct mac_biba *source, *dest;
1592103761Srwatson
1593173138Srwatson	source = SLOT(cred->cr_label);
1594173138Srwatson	dest = SLOT(pplabel);
1595101099Srwatson
1596173138Srwatson	biba_copy_effective(source, dest);
1597173138Srwatson}
1598103759Srwatson
1599173138Srwatsonstatic void
1600173138Srwatsonbiba_pipe_relabel(struct ucred *cred, struct pipepair *pp,
1601173138Srwatson    struct label *pplabel, struct label *newlabel)
1602173138Srwatson{
1603173138Srwatson	struct mac_biba *source, *dest;
1604173138Srwatson
1605173138Srwatson	source = SLOT(newlabel);
1606173138Srwatson	dest = SLOT(pplabel);
1607173138Srwatson
1608173138Srwatson	biba_copy(source, dest);
1609101099Srwatson}
1610101099Srwatson
1611101099Srwatsonstatic int
1612180059Sjhbbiba_posixsem_check_openunlink(struct ucred *cred, struct ksem *ks,
1613173138Srwatson    struct label *kslabel)
1614122875Srwatson{
1615173138Srwatson	struct mac_biba *subj, *obj;
1616122875Srwatson
1617172955Srwatson	if (!biba_enabled)
1618122875Srwatson		return (0);
1619122875Srwatson
1620173138Srwatson	subj = SLOT(cred->cr_label);
1621173138Srwatson	obj = SLOT(kslabel);
1622122875Srwatson
1623173138Srwatson	if (!biba_dominate_effective(subj, obj))
1624173138Srwatson		return (EACCES);
1625173138Srwatson
1626173138Srwatson	return (0);
1627122875Srwatson}
1628122875Srwatson
1629122875Srwatsonstatic int
1630225344Srwatsonbiba_posixsem_check_setmode(struct ucred *cred, struct ksem *ks,
1631225344Srwatson    struct label *kslabel, mode_t mode)
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
1648225344Srwatsonbiba_posixsem_check_setowner(struct ucred *cred, struct ksem *ks,
1649225344Srwatson    struct label *kslabel, uid_t uid, gid_t gid)
1650225344Srwatson{
1651225344Srwatson	struct mac_biba *subj, *obj;
1652225344Srwatson
1653225344Srwatson	if (!biba_enabled)
1654225344Srwatson		return (0);
1655225344Srwatson
1656225344Srwatson	subj = SLOT(cred->cr_label);
1657225344Srwatson	obj = SLOT(kslabel);
1658225344Srwatson
1659225344Srwatson	if (!biba_dominate_effective(subj, obj))
1660225344Srwatson		return (EACCES);
1661225344Srwatson
1662225344Srwatson	return (0);
1663225344Srwatson}
1664225344Srwatson
1665225344Srwatsonstatic int
1666180059Sjhbbiba_posixsem_check_write(struct ucred *active_cred, struct ucred *file_cred,
1667180059Sjhb    struct ksem *ks, struct label *kslabel)
1668140628Srwatson{
1669140628Srwatson	struct mac_biba *subj, *obj;
1670140628Srwatson
1671172955Srwatson	if (!biba_enabled)
1672140628Srwatson		return (0);
1673140628Srwatson
1674180059Sjhb	subj = SLOT(active_cred->cr_label);
1675173138Srwatson	obj = SLOT(kslabel);
1676140628Srwatson
1677180059Sjhb	if (!biba_dominate_effective(subj, obj))
1678180059Sjhb		return (EACCES);
1679180059Sjhb
1680180059Sjhb	return (0);
1681180059Sjhb}
1682180059Sjhb
1683180059Sjhbstatic int
1684180059Sjhbbiba_posixsem_check_rdonly(struct ucred *active_cred, struct ucred *file_cred,
1685180059Sjhb    struct ksem *ks, struct label *kslabel)
1686180059Sjhb{
1687180059Sjhb	struct mac_biba *subj, *obj;
1688180059Sjhb
1689180059Sjhb	if (!biba_enabled)
1690180059Sjhb		return (0);
1691180059Sjhb
1692180059Sjhb	subj = SLOT(active_cred->cr_label);
1693180059Sjhb	obj = SLOT(kslabel);
1694180059Sjhb
1695172955Srwatson	if (!biba_dominate_effective(obj, subj))
1696140628Srwatson		return (EACCES);
1697140628Srwatson
1698140628Srwatson	return (0);
1699140628Srwatson}
1700140628Srwatson
1701173138Srwatsonstatic void
1702173138Srwatsonbiba_posixsem_create(struct ucred *cred, struct ksem *ks,
1703173138Srwatson    struct label *kslabel)
1704173138Srwatson{
1705173138Srwatson	struct mac_biba *source, *dest;
1706173138Srwatson
1707173138Srwatson	source = SLOT(cred->cr_label);
1708173138Srwatson	dest = SLOT(kslabel);
1709173138Srwatson
1710173138Srwatson	biba_copy_effective(source, dest);
1711173138Srwatson}
1712173138Srwatson
1713225344Srwatsonstatic int
1714225344Srwatsonbiba_posixshm_check_mmap(struct ucred *cred, struct shmfd *shmfd,
1715225344Srwatson    struct label *shmlabel, int prot, int flags)
1716225344Srwatson{
1717225344Srwatson	struct mac_biba *subj, *obj;
1718225344Srwatson
1719225344Srwatson	if (!biba_enabled || !revocation_enabled)
1720225344Srwatson		return (0);
1721225344Srwatson
1722225344Srwatson	subj = SLOT(cred->cr_label);
1723225344Srwatson	obj = SLOT(shmlabel);
1724225344Srwatson
1725225344Srwatson	if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
1726225344Srwatson		if (!biba_dominate_effective(obj, subj))
1727225344Srwatson			return (EACCES);
1728225344Srwatson	}
1729225344Srwatson	if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) {
1730225344Srwatson		if (!biba_dominate_effective(subj, obj))
1731225344Srwatson			return (EACCES);
1732225344Srwatson	}
1733225344Srwatson
1734225344Srwatson	return (0);
1735225344Srwatson}
1736225344Srwatson
1737225344Srwatsonstatic int
1738225344Srwatsonbiba_posixshm_check_open(struct ucred *cred, struct shmfd *shmfd,
1739225344Srwatson    struct label *shmlabel, accmode_t accmode)
1740225344Srwatson{
1741225344Srwatson	struct mac_biba *subj, *obj;
1742225344Srwatson
1743225344Srwatson	if (!biba_enabled)
1744225344Srwatson		return (0);
1745225344Srwatson
1746225344Srwatson	subj = SLOT(cred->cr_label);
1747225344Srwatson	obj = SLOT(shmlabel);
1748225344Srwatson
1749225344Srwatson	if (accmode & (VREAD | VEXEC | VSTAT_PERMS)) {
1750225344Srwatson		if (!biba_dominate_effective(obj, subj))
1751225344Srwatson			return (EACCES);
1752225344Srwatson	}
1753225344Srwatson	if (accmode & VMODIFY_PERMS) {
1754225344Srwatson		if (!biba_dominate_effective(subj, obj))
1755225344Srwatson			return (EACCES);
1756225344Srwatson	}
1757225344Srwatson
1758225344Srwatson	return (0);
1759225344Srwatson}
1760225344Srwatson
1761225344Srwatsonstatic 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
1851225344Srwatsonstatic void
1852225344Srwatsonbiba_posixshm_create(struct ucred *cred, struct shmfd *shmfd,
1853225344Srwatson    struct label *shmlabel)
1854225344Srwatson{
1855225344Srwatson	struct mac_biba *source, *dest;
1856225344Srwatson
1857225344Srwatson	source = SLOT(cred->cr_label);
1858225344Srwatson	dest = SLOT(shmlabel);
1859225344Srwatson
1860225344Srwatson	biba_copy_effective(source, dest);
1861225344Srwatson}
1862225344Srwatson
1863173138Srwatson/*
1864173138Srwatson * Some system privileges are allowed regardless of integrity grade; others
1865173138Srwatson * are allowed only when running with privilege with respect to the Biba
1866173138Srwatson * policy as they might otherwise allow bypassing of the integrity policy.
1867173138Srwatson */
1868140628Srwatsonstatic int
1869173138Srwatsonbiba_priv_check(struct ucred *cred, int priv)
1870140628Srwatson{
1871173138Srwatson	struct mac_biba *subj;
1872173138Srwatson	int error;
1873140628Srwatson
1874172955Srwatson	if (!biba_enabled)
1875140628Srwatson		return (0);
1876140628Srwatson
1877173138Srwatson	/*
1878173138Srwatson	 * Exempt only specific privileges from the Biba integrity policy.
1879173138Srwatson	 */
1880173138Srwatson	switch (priv) {
1881173138Srwatson	case PRIV_KTRACE:
1882173138Srwatson	case PRIV_MSGBUF:
1883140628Srwatson
1884173138Srwatson	/*
1885173138Srwatson	 * Allow processes to manipulate basic process audit properties, and
1886173138Srwatson	 * to submit audit records.
1887173138Srwatson	 */
1888173138Srwatson	case PRIV_AUDIT_GETAUDIT:
1889173138Srwatson	case PRIV_AUDIT_SETAUDIT:
1890173138Srwatson	case PRIV_AUDIT_SUBMIT:
1891140628Srwatson
1892173138Srwatson	/*
1893173138Srwatson	 * Allow processes to manipulate their regular UNIX credentials.
1894173138Srwatson	 */
1895173138Srwatson	case PRIV_CRED_SETUID:
1896173138Srwatson	case PRIV_CRED_SETEUID:
1897173138Srwatson	case PRIV_CRED_SETGID:
1898173138Srwatson	case PRIV_CRED_SETEGID:
1899173138Srwatson	case PRIV_CRED_SETGROUPS:
1900173138Srwatson	case PRIV_CRED_SETREUID:
1901173138Srwatson	case PRIV_CRED_SETREGID:
1902173138Srwatson	case PRIV_CRED_SETRESUID:
1903173138Srwatson	case PRIV_CRED_SETRESGID:
1904173138Srwatson
1905173138Srwatson	/*
1906173138Srwatson	 * Allow processes to perform system monitoring.
1907173138Srwatson	 */
1908173138Srwatson	case PRIV_SEEOTHERGIDS:
1909173138Srwatson	case PRIV_SEEOTHERUIDS:
1910173138Srwatson		break;
1911173138Srwatson
1912173138Srwatson	/*
1913173138Srwatson	 * Allow access to general process debugging facilities.  We
1914173138Srwatson	 * separately control debugging based on MAC label.
1915173138Srwatson	 */
1916173138Srwatson	case PRIV_DEBUG_DIFFCRED:
1917173138Srwatson	case PRIV_DEBUG_SUGID:
1918173138Srwatson	case PRIV_DEBUG_UNPRIV:
1919173138Srwatson
1920173138Srwatson	/*
1921173138Srwatson	 * Allow manipulating jails.
1922173138Srwatson	 */
1923173138Srwatson	case PRIV_JAIL_ATTACH:
1924173138Srwatson
1925173138Srwatson	/*
1926173138Srwatson	 * Allow privilege with respect to the Partition policy, but not the
1927173138Srwatson	 * Privs policy.
1928173138Srwatson	 */
1929173138Srwatson	case PRIV_MAC_PARTITION:
1930173138Srwatson
1931173138Srwatson	/*
1932173138Srwatson	 * Allow privilege with respect to process resource limits and login
1933173138Srwatson	 * context.
1934173138Srwatson	 */
1935173138Srwatson	case PRIV_PROC_LIMIT:
1936173138Srwatson	case PRIV_PROC_SETLOGIN:
1937173138Srwatson	case PRIV_PROC_SETRLIMIT:
1938173138Srwatson
1939173138Srwatson	/*
1940173138Srwatson	 * Allow System V and POSIX IPC privileges.
1941173138Srwatson	 */
1942173138Srwatson	case PRIV_IPC_READ:
1943173138Srwatson	case PRIV_IPC_WRITE:
1944173138Srwatson	case PRIV_IPC_ADMIN:
1945173138Srwatson	case PRIV_IPC_MSGSIZE:
1946173138Srwatson	case PRIV_MQ_ADMIN:
1947173138Srwatson
1948173138Srwatson	/*
1949173138Srwatson	 * Allow certain scheduler manipulations -- possibly this should be
1950173138Srwatson	 * controlled by more fine-grained policy, as potentially low
1951173138Srwatson	 * integrity processes can deny CPU to higher integrity ones.
1952173138Srwatson	 */
1953173138Srwatson	case PRIV_SCHED_DIFFCRED:
1954173138Srwatson	case PRIV_SCHED_SETPRIORITY:
1955173138Srwatson	case PRIV_SCHED_RTPRIO:
1956173138Srwatson	case PRIV_SCHED_SETPOLICY:
1957173138Srwatson	case PRIV_SCHED_SET:
1958173138Srwatson	case PRIV_SCHED_SETPARAM:
1959173138Srwatson
1960173138Srwatson	/*
1961173138Srwatson	 * More IPC privileges.
1962173138Srwatson	 */
1963173138Srwatson	case PRIV_SEM_WRITE:
1964173138Srwatson
1965173138Srwatson	/*
1966173138Srwatson	 * Allow signaling privileges subject to integrity policy.
1967173138Srwatson	 */
1968173138Srwatson	case PRIV_SIGNAL_DIFFCRED:
1969173138Srwatson	case PRIV_SIGNAL_SUGID:
1970173138Srwatson
1971173138Srwatson	/*
1972173138Srwatson	 * Allow access to only limited sysctls from lower integrity levels;
1973173138Srwatson	 * piggy-back on the Jail definition.
1974173138Srwatson	 */
1975173138Srwatson	case PRIV_SYSCTL_WRITEJAIL:
1976173138Srwatson
1977173138Srwatson	/*
1978173138Srwatson	 * Allow TTY-based privileges, subject to general device access using
1979173138Srwatson	 * labels on TTY device nodes, but not console privilege.
1980173138Srwatson	 */
1981173138Srwatson	case PRIV_TTY_DRAINWAIT:
1982173138Srwatson	case PRIV_TTY_DTRWAIT:
1983173138Srwatson	case PRIV_TTY_EXCLUSIVE:
1984173138Srwatson	case PRIV_TTY_STI:
1985173138Srwatson	case PRIV_TTY_SETA:
1986173138Srwatson
1987173138Srwatson	/*
1988173138Srwatson	 * Grant most VFS privileges, as almost all are in practice bounded
1989173138Srwatson	 * by more specific checks using labels.
1990173138Srwatson	 */
1991173138Srwatson	case PRIV_VFS_READ:
1992173138Srwatson	case PRIV_VFS_WRITE:
1993173138Srwatson	case PRIV_VFS_ADMIN:
1994173138Srwatson	case PRIV_VFS_EXEC:
1995173138Srwatson	case PRIV_VFS_LOOKUP:
1996173138Srwatson	case PRIV_VFS_CHFLAGS_DEV:
1997173138Srwatson	case PRIV_VFS_CHOWN:
1998173138Srwatson	case PRIV_VFS_CHROOT:
1999173138Srwatson	case PRIV_VFS_RETAINSUGID:
2000173138Srwatson	case PRIV_VFS_EXCEEDQUOTA:
2001173138Srwatson	case PRIV_VFS_FCHROOT:
2002173138Srwatson	case PRIV_VFS_FHOPEN:
2003173138Srwatson	case PRIV_VFS_FHSTATFS:
2004173138Srwatson	case PRIV_VFS_GENERATION:
2005173138Srwatson	case PRIV_VFS_GETFH:
2006173138Srwatson	case PRIV_VFS_GETQUOTA:
2007173138Srwatson	case PRIV_VFS_LINK:
2008173138Srwatson	case PRIV_VFS_MOUNT:
2009173138Srwatson	case PRIV_VFS_MOUNT_OWNER:
2010173138Srwatson	case PRIV_VFS_MOUNT_PERM:
2011173138Srwatson	case PRIV_VFS_MOUNT_SUIDDIR:
2012173138Srwatson	case PRIV_VFS_MOUNT_NONUSER:
2013173138Srwatson	case PRIV_VFS_SETGID:
2014173138Srwatson	case PRIV_VFS_STICKYFILE:
2015173138Srwatson	case PRIV_VFS_SYSFLAGS:
2016173138Srwatson	case PRIV_VFS_UNMOUNT:
2017173138Srwatson
2018173138Srwatson	/*
2019173138Srwatson	 * Allow VM privileges; it would be nice if these were subject to
2020173138Srwatson	 * resource limits.
2021173138Srwatson	 */
2022173138Srwatson	case PRIV_VM_MADV_PROTECT:
2023173138Srwatson	case PRIV_VM_MLOCK:
2024173138Srwatson	case PRIV_VM_MUNLOCK:
2025194766Skib	case PRIV_VM_SWAP_NOQUOTA:
2026194766Skib	case PRIV_VM_SWAP_NORLIMIT:
2027173138Srwatson
2028173138Srwatson	/*
2029173138Srwatson	 * Allow some but not all network privileges.  In general, dont allow
2030173138Srwatson	 * reconfiguring the network stack, just normal use.
2031173138Srwatson	 */
2032173138Srwatson	case PRIV_NETATALK_RESERVEDPORT:
2033173138Srwatson	case PRIV_NETINET_RESERVEDPORT:
2034173138Srwatson	case PRIV_NETINET_RAW:
2035173138Srwatson	case PRIV_NETINET_REUSEPORT:
2036173138Srwatson	case PRIV_NETIPX_RESERVEDPORT:
2037173138Srwatson	case PRIV_NETIPX_RAW:
2038173138Srwatson		break;
2039173138Srwatson
2040173138Srwatson	/*
2041173138Srwatson	 * All remaining system privileges are allow only if the process
2042173138Srwatson	 * holds privilege with respect to the Biba policy.
2043173138Srwatson	 */
2044173138Srwatson	default:
2045173138Srwatson		subj = SLOT(cred->cr_label);
2046173138Srwatson		error = biba_subject_privileged(subj);
2047173138Srwatson		if (error)
2048173138Srwatson			return (error);
2049173138Srwatson	}
2050140628Srwatson	return (0);
2051140628Srwatson}
2052140628Srwatson
2053140628Srwatsonstatic int
2054173138Srwatsonbiba_proc_check_debug(struct ucred *cred, struct proc *p)
2055140628Srwatson{
2056140628Srwatson	struct mac_biba *subj, *obj;
2057140628Srwatson
2058172955Srwatson	if (!biba_enabled)
2059140628Srwatson		return (0);
2060140628Srwatson
2061140628Srwatson	subj = SLOT(cred->cr_label);
2062173138Srwatson	obj = SLOT(p->p_ucred->cr_label);
2063140628Srwatson
2064173138Srwatson	/* XXX: range checks */
2065172955Srwatson	if (!biba_dominate_effective(obj, subj))
2066173138Srwatson		return (ESRCH);
2067173138Srwatson	if (!biba_dominate_effective(subj, obj))
2068140628Srwatson		return (EACCES);
2069140628Srwatson
2070140628Srwatson	return (0);
2071140628Srwatson}
2072140628Srwatson
2073140628Srwatsonstatic int
2074173138Srwatsonbiba_proc_check_sched(struct ucred *cred, struct proc *p)
2075140628Srwatson{
2076140628Srwatson	struct mac_biba *subj, *obj;
2077140628Srwatson
2078172955Srwatson	if (!biba_enabled)
2079140628Srwatson		return (0);
2080140628Srwatson
2081140628Srwatson	subj = SLOT(cred->cr_label);
2082173138Srwatson	obj = SLOT(p->p_ucred->cr_label);
2083140628Srwatson
2084173138Srwatson	/* XXX: range checks */
2085173138Srwatson	if (!biba_dominate_effective(obj, subj))
2086173138Srwatson		return (ESRCH);
2087172955Srwatson	if (!biba_dominate_effective(subj, obj))
2088140628Srwatson		return (EACCES);
2089140628Srwatson
2090140628Srwatson	return (0);
2091140628Srwatson}
2092140628Srwatson
2093140628Srwatsonstatic int
2094173138Srwatsonbiba_proc_check_signal(struct ucred *cred, struct proc *p, int signum)
2095140628Srwatson{
2096140628Srwatson	struct mac_biba *subj, *obj;
2097140628Srwatson
2098172955Srwatson	if (!biba_enabled)
2099140628Srwatson		return (0);
2100140628Srwatson
2101140628Srwatson	subj = SLOT(cred->cr_label);
2102173138Srwatson	obj = SLOT(p->p_ucred->cr_label);
2103140628Srwatson
2104173138Srwatson	/* XXX: range checks */
2105172955Srwatson	if (!biba_dominate_effective(obj, subj))
2106173138Srwatson		return (ESRCH);
2107173138Srwatson	if (!biba_dominate_effective(subj, obj))
2108140628Srwatson		return (EACCES);
2109140628Srwatson
2110140628Srwatson	return (0);
2111140628Srwatson}
2112140628Srwatson
2113140628Srwatsonstatic int
2114173138Srwatsonbiba_socket_check_deliver(struct socket *so, struct label *solabel,
2115173138Srwatson    struct mbuf *m, struct label *mlabel)
2116140628Srwatson{
2117173138Srwatson	struct mac_biba *p, *s;
2118193391Srwatson	int error;
2119140628Srwatson
2120172955Srwatson	if (!biba_enabled)
2121140628Srwatson		return (0);
2122140628Srwatson
2123173138Srwatson	p = SLOT(mlabel);
2124173138Srwatson	s = SLOT(solabel);
2125140628Srwatson
2126193391Srwatson	SOCK_LOCK(so);
2127193391Srwatson	error = biba_equal_effective(p, s) ? 0 : EACCES;
2128193391Srwatson	SOCK_UNLOCK(so);
2129193391Srwatson	return (error);
2130173138Srwatson}
2131140628Srwatson
2132140628Srwatsonstatic int
2133173138Srwatsonbiba_socket_check_relabel(struct ucred *cred, struct socket *so,
2134173138Srwatson    struct label *solabel, struct label *newlabel)
2135140628Srwatson{
2136173138Srwatson	struct mac_biba *subj, *obj, *new;
2137173138Srwatson	int error;
2138140628Srwatson
2139193391Srwatson	SOCK_LOCK_ASSERT(so);
2140193391Srwatson
2141173138Srwatson	new = SLOT(newlabel);
2142140628Srwatson	subj = SLOT(cred->cr_label);
2143173138Srwatson	obj = SLOT(solabel);
2144140628Srwatson
2145173138Srwatson	/*
2146173138Srwatson	 * If there is a Biba label update for the socket, it may be an
2147173138Srwatson	 * update of effective.
2148173138Srwatson	 */
2149173138Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE);
2150173138Srwatson	if (error)
2151173138Srwatson		return (error);
2152140628Srwatson
2153173138Srwatson	/*
2154173138Srwatson	 * To relabel a socket, the old socket effective must be in the
2155173138Srwatson	 * subject range.
2156173138Srwatson	 */
2157173138Srwatson	if (!biba_effective_in_range(obj, subj))
2158173138Srwatson		return (EPERM);
2159140628Srwatson
2160173138Srwatson	/*
2161173138Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
2162173138Srwatson	 */
2163173138Srwatson	if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
2164173138Srwatson		/*
2165173138Srwatson		 * To relabel a socket, the new socket effective must be in
2166173138Srwatson		 * the subject range.
2167173138Srwatson		 */
2168173138Srwatson		if (!biba_effective_in_range(new, subj))
2169173138Srwatson			return (EPERM);
2170173138Srwatson
2171173138Srwatson		/*
2172173138Srwatson		 * To change the Biba label on the socket to contain EQUAL,
2173173138Srwatson		 * the subject must have appropriate privilege.
2174173138Srwatson		 */
2175173138Srwatson		if (biba_contains_equal(new)) {
2176173138Srwatson			error = biba_subject_privileged(subj);
2177173138Srwatson			if (error)
2178173138Srwatson				return (error);
2179173138Srwatson		}
2180140628Srwatson	}
2181140628Srwatson
2182140628Srwatson	return (0);
2183140628Srwatson}
2184140628Srwatson
2185140628Srwatsonstatic int
2186173138Srwatsonbiba_socket_check_visible(struct ucred *cred, struct socket *so,
2187173138Srwatson    struct label *solabel)
2188140628Srwatson{
2189140628Srwatson	struct mac_biba *subj, *obj;
2190140628Srwatson
2191172955Srwatson	if (!biba_enabled)
2192140628Srwatson		return (0);
2193140628Srwatson
2194140628Srwatson	subj = SLOT(cred->cr_label);
2195173138Srwatson	obj = SLOT(solabel);
2196140628Srwatson
2197193391Srwatson	SOCK_LOCK(so);
2198193391Srwatson	if (!biba_dominate_effective(obj, subj)) {
2199193391Srwatson		SOCK_UNLOCK(so);
2200173138Srwatson		return (ENOENT);
2201193391Srwatson	}
2202193391Srwatson	SOCK_UNLOCK(so);
2203140628Srwatson
2204140628Srwatson	return (0);
2205140628Srwatson}
2206140628Srwatson
2207173138Srwatsonstatic void
2208173138Srwatsonbiba_socket_create(struct ucred *cred, struct socket *so,
2209173138Srwatson    struct label *solabel)
2210140628Srwatson{
2211173138Srwatson	struct mac_biba *source, *dest;
2212140628Srwatson
2213173138Srwatson	source = SLOT(cred->cr_label);
2214173138Srwatson	dest = SLOT(solabel);
2215140628Srwatson
2216173138Srwatson	biba_copy_effective(source, dest);
2217173138Srwatson}
2218140628Srwatson
2219173138Srwatsonstatic void
2220173138Srwatsonbiba_socket_create_mbuf(struct socket *so, struct label *solabel,
2221173138Srwatson    struct mbuf *m, struct label *mlabel)
2222173138Srwatson{
2223173138Srwatson	struct mac_biba *source, *dest;
2224140628Srwatson
2225173138Srwatson	source = SLOT(solabel);
2226173138Srwatson	dest = SLOT(mlabel);
2227140628Srwatson
2228193391Srwatson	SOCK_LOCK(so);
2229173138Srwatson	biba_copy_effective(source, dest);
2230193391Srwatson	SOCK_UNLOCK(so);
2231140628Srwatson}
2232140628Srwatson
2233173138Srwatsonstatic void
2234173138Srwatsonbiba_socket_newconn(struct socket *oldso, struct label *oldsolabel,
2235173138Srwatson    struct socket *newso, struct label *newsolabel)
2236140628Srwatson{
2237193391Srwatson	struct mac_biba source, *dest;
2238140628Srwatson
2239193391Srwatson	SOCK_LOCK(oldso);
2240193391Srwatson	source = *SLOT(oldsolabel);
2241193391Srwatson	SOCK_UNLOCK(oldso);
2242193391Srwatson
2243173138Srwatson	dest = SLOT(newsolabel);
2244140628Srwatson
2245193391Srwatson	SOCK_LOCK(newso);
2246193391Srwatson	biba_copy_effective(&source, dest);
2247193391Srwatson	SOCK_UNLOCK(newso);
2248140628Srwatson}
2249140628Srwatson
2250173138Srwatsonstatic void
2251173138Srwatsonbiba_socket_relabel(struct ucred *cred, struct socket *so,
2252173138Srwatson    struct label *solabel, struct label *newlabel)
2253140628Srwatson{
2254173138Srwatson	struct mac_biba *source, *dest;
2255140628Srwatson
2256193391Srwatson	SOCK_LOCK_ASSERT(so);
2257193391Srwatson
2258173138Srwatson	source = SLOT(newlabel);
2259173138Srwatson	dest = SLOT(solabel);
2260140628Srwatson
2261173138Srwatson	biba_copy(source, dest);
2262173138Srwatson}
2263140628Srwatson
2264173138Srwatsonstatic void
2265173138Srwatsonbiba_socketpeer_set_from_mbuf(struct mbuf *m, struct label *mlabel,
2266173138Srwatson    struct socket *so, struct label *sopeerlabel)
2267173138Srwatson{
2268173138Srwatson	struct mac_biba *source, *dest;
2269140628Srwatson
2270173138Srwatson	source = SLOT(mlabel);
2271173138Srwatson	dest = SLOT(sopeerlabel);
2272140628Srwatson
2273193391Srwatson	SOCK_LOCK(so);
2274173138Srwatson	biba_copy_effective(source, dest);
2275193391Srwatson	SOCK_UNLOCK(so);
2276140628Srwatson}
2277140628Srwatson
2278173138Srwatsonstatic void
2279173138Srwatsonbiba_socketpeer_set_from_socket(struct socket *oldso,
2280173138Srwatson    struct label *oldsolabel, struct socket *newso,
2281173138Srwatson    struct label *newsopeerlabel)
2282140628Srwatson{
2283193391Srwatson	struct mac_biba source, *dest;
2284140628Srwatson
2285193391Srwatson	SOCK_LOCK(oldso);
2286193391Srwatson	source = *SLOT(oldsolabel);
2287193391Srwatson	SOCK_UNLOCK(oldso);
2288173138Srwatson	dest = SLOT(newsopeerlabel);
2289140628Srwatson
2290193391Srwatson	SOCK_LOCK(newso);
2291193391Srwatson	biba_copy_effective(&source, dest);
2292193391Srwatson	SOCK_UNLOCK(newso);
2293173138Srwatson}
2294140628Srwatson
2295173138Srwatsonstatic void
2296173138Srwatsonbiba_syncache_create(struct label *label, struct inpcb *inp)
2297173138Srwatson{
2298173138Srwatson	struct mac_biba *source, *dest;
2299140628Srwatson
2300173138Srwatson	source = SLOT(inp->inp_label);
2301173138Srwatson	dest = SLOT(label);
2302173138Srwatson	biba_copy_effective(source, dest);
2303140628Srwatson}
2304140628Srwatson
2305173138Srwatsonstatic void
2306173138Srwatsonbiba_syncache_create_mbuf(struct label *sc_label, struct mbuf *m,
2307173138Srwatson    struct label *mlabel)
2308173138Srwatson{
2309173138Srwatson	struct mac_biba *source, *dest;
2310173138Srwatson
2311173138Srwatson	source = SLOT(sc_label);
2312173138Srwatson	dest = SLOT(mlabel);
2313173138Srwatson	biba_copy_effective(source, dest);
2314173138Srwatson}
2315173138Srwatson
2316140628Srwatsonstatic int
2317173138Srwatsonbiba_system_check_acct(struct ucred *cred, struct vnode *vp,
2318168976Srwatson    struct label *vplabel)
2319110354Srwatson{
2320110354Srwatson	struct mac_biba *subj, *obj;
2321110354Srwatson	int error;
2322110354Srwatson
2323172955Srwatson	if (!biba_enabled)
2324110354Srwatson		return (0);
2325110354Srwatson
2326122524Srwatson	subj = SLOT(cred->cr_label);
2327110354Srwatson
2328172955Srwatson	error = biba_subject_privileged(subj);
2329110354Srwatson	if (error)
2330110354Srwatson		return (error);
2331110354Srwatson
2332173138Srwatson	if (vplabel == NULL)
2333173138Srwatson		return (0);
2334173138Srwatson
2335168976Srwatson	obj = SLOT(vplabel);
2336172955Srwatson	if (!biba_high_effective(obj))
2337110354Srwatson		return (EACCES);
2338110354Srwatson
2339110354Srwatson	return (0);
2340110354Srwatson}
2341110354Srwatson
2342110354Srwatsonstatic int
2343173138Srwatsonbiba_system_check_auditctl(struct ucred *cred, struct vnode *vp,
2344173138Srwatson    struct label *vplabel)
2345101099Srwatson{
2346101099Srwatson	struct mac_biba *subj, *obj;
2347173138Srwatson	int error;
2348101099Srwatson
2349172955Srwatson	if (!biba_enabled)
2350101099Srwatson		return (0);
2351101099Srwatson
2352122524Srwatson	subj = SLOT(cred->cr_label);
2353101099Srwatson
2354173138Srwatson	error = biba_subject_privileged(subj);
2355173138Srwatson	if (error)
2356173138Srwatson		return (error);
2357173138Srwatson
2358173138Srwatson	if (vplabel == NULL)
2359173138Srwatson		return (0);
2360173138Srwatson
2361173138Srwatson	obj = SLOT(vplabel);
2362173138Srwatson	if (!biba_high_effective(obj))
2363101099Srwatson		return (EACCES);
2364101099Srwatson
2365101099Srwatson	return (0);
2366101099Srwatson}
2367101099Srwatson
2368101099Srwatsonstatic int
2369173138Srwatsonbiba_system_check_auditon(struct ucred *cred, int cmd)
2370101099Srwatson{
2371173138Srwatson	struct mac_biba *subj;
2372173138Srwatson	int error;
2373103759Srwatson
2374173138Srwatson	if (!biba_enabled)
2375101099Srwatson		return (0);
2376101099Srwatson
2377173138Srwatson	subj = SLOT(cred->cr_label);
2378101099Srwatson
2379173138Srwatson	error = biba_subject_privileged(subj);
2380173138Srwatson	if (error)
2381173138Srwatson		return (error);
2382173138Srwatson
2383101099Srwatson	return (0);
2384101099Srwatson}
2385101099Srwatson
2386101099Srwatsonstatic int
2387173138Srwatsonbiba_system_check_swapoff(struct ucred *cred, struct vnode *vp,
2388173138Srwatson    struct label *label)
2389101099Srwatson{
2390173138Srwatson	struct mac_biba *subj;
2391173138Srwatson	int error;
2392101099Srwatson
2393172955Srwatson	if (!biba_enabled)
2394101099Srwatson		return (0);
2395101099Srwatson
2396122524Srwatson	subj = SLOT(cred->cr_label);
2397101099Srwatson
2398173138Srwatson	error = biba_subject_privileged(subj);
2399173138Srwatson	if (error)
2400173138Srwatson		return (error);
2401101099Srwatson
2402101099Srwatson	return (0);
2403101099Srwatson}
2404101099Srwatson
2405101099Srwatsonstatic int
2406173138Srwatsonbiba_system_check_swapon(struct ucred *cred, struct vnode *vp,
2407173138Srwatson    struct label *vplabel)
2408102115Srwatson{
2409102115Srwatson	struct mac_biba *subj, *obj;
2410173138Srwatson	int error;
2411102115Srwatson
2412172955Srwatson	if (!biba_enabled)
2413102115Srwatson		return (0);
2414102115Srwatson
2415122524Srwatson	subj = SLOT(cred->cr_label);
2416173138Srwatson	obj = SLOT(vplabel);
2417102115Srwatson
2418173138Srwatson	error = biba_subject_privileged(subj);
2419173138Srwatson	if (error)
2420173138Srwatson		return (error);
2421173138Srwatson
2422173138Srwatson	if (!biba_high_effective(obj))
2423102115Srwatson		return (EACCES);
2424102115Srwatson
2425102115Srwatson	return (0);
2426102115Srwatson}
2427102115Srwatson
2428102115Srwatsonstatic int
2429173138Srwatsonbiba_system_check_sysctl(struct ucred *cred, struct sysctl_oid *oidp,
2430173138Srwatson    void *arg1, int arg2, struct sysctl_req *req)
2431101099Srwatson{
2432173138Srwatson	struct mac_biba *subj;
2433105634Srwatson	int error;
2434101099Srwatson
2435173138Srwatson	if (!biba_enabled)
2436173138Srwatson		return (0);
2437173138Srwatson
2438122524Srwatson	subj = SLOT(cred->cr_label);
2439101099Srwatson
2440101099Srwatson	/*
2441173138Srwatson	 * Treat sysctl variables without CTLFLAG_ANYBODY flag as biba/high,
2442173138Srwatson	 * but also require privilege to change them.
2443101099Srwatson	 */
2444173138Srwatson	if (req->newptr != NULL && (oidp->oid_kind & CTLFLAG_ANYBODY) == 0) {
2445173138Srwatson		if (!biba_subject_dominate_high(subj))
2446173138Srwatson			return (EACCES);
2447101099Srwatson
2448173138Srwatson		error = biba_subject_privileged(subj);
2449173138Srwatson		if (error)
2450173138Srwatson			return (error);
2451105634Srwatson	}
2452105634Srwatson
2453101099Srwatson	return (0);
2454101099Srwatson}
2455101099Srwatson
2456173138Srwatsonstatic void
2457173138Srwatsonbiba_sysvmsg_cleanup(struct label *msglabel)
2458102115Srwatson{
2459102115Srwatson
2460173138Srwatson	bzero(SLOT(msglabel), sizeof(struct mac_biba));
2461173138Srwatson}
2462102115Srwatson
2463173138Srwatsonstatic void
2464173138Srwatsonbiba_sysvmsg_create(struct ucred *cred, struct msqid_kernel *msqkptr,
2465173138Srwatson    struct label *msqlabel, struct msg *msgptr, struct label *msglabel)
2466173138Srwatson{
2467173138Srwatson	struct mac_biba *source, *dest;
2468102115Srwatson
2469173138Srwatson	/* Ignore the msgq label */
2470173138Srwatson	source = SLOT(cred->cr_label);
2471173138Srwatson	dest = SLOT(msglabel);
2472102115Srwatson
2473173138Srwatson	biba_copy_effective(source, dest);
2474102115Srwatson}
2475102115Srwatson
2476102115Srwatsonstatic int
2477173138Srwatsonbiba_sysvmsq_check_msgrcv(struct ucred *cred, struct msg *msgptr,
2478173138Srwatson    struct label *msglabel)
2479102115Srwatson{
2480102115Srwatson	struct mac_biba *subj, *obj;
2481102115Srwatson
2482172955Srwatson	if (!biba_enabled)
2483102115Srwatson		return (0);
2484102115Srwatson
2485122524Srwatson	subj = SLOT(cred->cr_label);
2486173138Srwatson	obj = SLOT(msglabel);
2487102115Srwatson
2488173138Srwatson	if (!biba_dominate_effective(obj, subj))
2489102115Srwatson		return (EACCES);
2490102115Srwatson
2491102115Srwatson	return (0);
2492102115Srwatson}
2493102115Srwatson
2494102115Srwatsonstatic int
2495173138Srwatsonbiba_sysvmsq_check_msgrmid(struct ucred *cred, struct msg *msgptr,
2496173138Srwatson    struct label *msglabel)
2497145855Srwatson{
2498145855Srwatson	struct mac_biba *subj, *obj;
2499145855Srwatson
2500172955Srwatson	if (!biba_enabled)
2501145855Srwatson		return (0);
2502145855Srwatson
2503145855Srwatson	subj = SLOT(cred->cr_label);
2504173138Srwatson	obj = SLOT(msglabel);
2505145855Srwatson
2506172955Srwatson	if (!biba_dominate_effective(subj, obj))
2507145855Srwatson		return (EACCES);
2508145855Srwatson
2509145855Srwatson	return (0);
2510145855Srwatson}
2511145855Srwatson
2512145855Srwatsonstatic int
2513173138Srwatsonbiba_sysvmsq_check_msqget(struct ucred *cred, struct msqid_kernel *msqkptr,
2514173138Srwatson    struct label *msqklabel)
2515145855Srwatson{
2516145855Srwatson	struct mac_biba *subj, *obj;
2517145855Srwatson
2518172955Srwatson	if (!biba_enabled)
2519145855Srwatson		return (0);
2520145855Srwatson
2521145855Srwatson	subj = SLOT(cred->cr_label);
2522173138Srwatson	obj = SLOT(msqklabel);
2523145855Srwatson
2524172955Srwatson	if (!biba_dominate_effective(obj, subj))
2525145855Srwatson		return (EACCES);
2526145855Srwatson
2527145855Srwatson	return (0);
2528145855Srwatson}
2529145855Srwatson
2530145855Srwatsonstatic int
2531173138Srwatsonbiba_sysvmsq_check_msqsnd(struct ucred *cred, struct msqid_kernel *msqkptr,
2532173138Srwatson    struct label *msqklabel)
2533101099Srwatson{
2534101099Srwatson	struct mac_biba *subj, *obj;
2535101099Srwatson
2536172955Srwatson	if (!biba_enabled)
2537101099Srwatson		return (0);
2538101099Srwatson
2539122524Srwatson	subj = SLOT(cred->cr_label);
2540173138Srwatson	obj = SLOT(msqklabel);
2541101099Srwatson
2542172955Srwatson	if (!biba_dominate_effective(subj, obj))
2543101099Srwatson		return (EACCES);
2544101099Srwatson
2545101099Srwatson	return (0);
2546101099Srwatson}
2547101099Srwatson
2548101099Srwatsonstatic int
2549173138Srwatsonbiba_sysvmsq_check_msqrcv(struct ucred *cred, struct msqid_kernel *msqkptr,
2550173138Srwatson    struct label *msqklabel)
2551101099Srwatson{
2552101099Srwatson	struct mac_biba *subj, *obj;
2553103759Srwatson
2554172955Srwatson	if (!biba_enabled)
2555101099Srwatson		return (0);
2556101099Srwatson
2557122524Srwatson	subj = SLOT(cred->cr_label);
2558173138Srwatson	obj = SLOT(msqklabel);
2559103759Srwatson
2560172955Srwatson	if (!biba_dominate_effective(obj, subj))
2561101099Srwatson		return (EACCES);
2562101099Srwatson
2563101099Srwatson	return (0);
2564101099Srwatson}
2565101099Srwatson
2566101099Srwatsonstatic int
2567173138Srwatsonbiba_sysvmsq_check_msqctl(struct ucred *cred, struct msqid_kernel *msqkptr,
2568173138Srwatson    struct label *msqklabel, int cmd)
2569101099Srwatson{
2570101099Srwatson	struct mac_biba *subj, *obj;
2571103759Srwatson
2572172955Srwatson	if (!biba_enabled)
2573101099Srwatson		return (0);
2574101099Srwatson
2575122524Srwatson	subj = SLOT(cred->cr_label);
2576173138Srwatson	obj = SLOT(msqklabel);
2577103759Srwatson
2578173138Srwatson	switch(cmd) {
2579173138Srwatson	case IPC_RMID:
2580173138Srwatson	case IPC_SET:
2581173138Srwatson		if (!biba_dominate_effective(subj, obj))
2582173138Srwatson			return (EACCES);
2583173138Srwatson		break;
2584173138Srwatson
2585173138Srwatson	case IPC_STAT:
2586173138Srwatson		if (!biba_dominate_effective(obj, subj))
2587173138Srwatson			return (EACCES);
2588173138Srwatson		break;
2589173138Srwatson
2590173138Srwatson	default:
2591101099Srwatson		return (EACCES);
2592173138Srwatson	}
2593101099Srwatson
2594101099Srwatson	return (0);
2595101099Srwatson}
2596101099Srwatson
2597173138Srwatsonstatic void
2598173138Srwatsonbiba_sysvmsq_cleanup(struct label *msqlabel)
2599101099Srwatson{
2600101099Srwatson
2601173138Srwatson	bzero(SLOT(msqlabel), sizeof(struct mac_biba));
2602173138Srwatson}
2603101099Srwatson
2604173138Srwatsonstatic void
2605173138Srwatsonbiba_sysvmsq_create(struct ucred *cred, struct msqid_kernel *msqkptr,
2606173138Srwatson    struct label *msqlabel)
2607173138Srwatson{
2608173138Srwatson	struct mac_biba *source, *dest;
2609101099Srwatson
2610173138Srwatson	source = SLOT(cred->cr_label);
2611173138Srwatson	dest = SLOT(msqlabel);
2612173138Srwatson
2613173138Srwatson	biba_copy_effective(source, dest);
2614101099Srwatson}
2615101099Srwatson
2616101099Srwatsonstatic int
2617173138Srwatsonbiba_sysvsem_check_semctl(struct ucred *cred, struct semid_kernel *semakptr,
2618173138Srwatson    struct label *semaklabel, int cmd)
2619101099Srwatson{
2620173138Srwatson	struct mac_biba *subj, *obj;
2621101099Srwatson
2622173138Srwatson	if (!biba_enabled)
2623173138Srwatson		return (0);
2624173138Srwatson
2625122524Srwatson	subj = SLOT(cred->cr_label);
2626173138Srwatson	obj = SLOT(semaklabel);
2627101099Srwatson
2628173138Srwatson	switch(cmd) {
2629173138Srwatson	case IPC_RMID:
2630173138Srwatson	case IPC_SET:
2631173138Srwatson	case SETVAL:
2632173138Srwatson	case SETALL:
2633173138Srwatson		if (!biba_dominate_effective(subj, obj))
2634173138Srwatson			return (EACCES);
2635173138Srwatson		break;
2636101099Srwatson
2637173138Srwatson	case IPC_STAT:
2638173138Srwatson	case GETVAL:
2639173138Srwatson	case GETPID:
2640173138Srwatson	case GETNCNT:
2641173138Srwatson	case GETZCNT:
2642173138Srwatson	case GETALL:
2643173138Srwatson		if (!biba_dominate_effective(obj, subj))
2644173138Srwatson			return (EACCES);
2645173138Srwatson		break;
2646101099Srwatson
2647173138Srwatson	default:
2648173138Srwatson		return (EACCES);
2649105634Srwatson	}
2650105634Srwatson
2651101099Srwatson	return (0);
2652101099Srwatson}
2653101099Srwatson
2654101099Srwatsonstatic int
2655173138Srwatsonbiba_sysvsem_check_semget(struct ucred *cred, struct semid_kernel *semakptr,
2656173138Srwatson    struct label *semaklabel)
2657101099Srwatson{
2658101099Srwatson	struct mac_biba *subj, *obj;
2659101099Srwatson
2660172955Srwatson	if (!biba_enabled)
2661105722Srwatson		return (0);
2662105722Srwatson
2663122524Srwatson	subj = SLOT(cred->cr_label);
2664173138Srwatson	obj = SLOT(semaklabel);
2665101099Srwatson
2666172955Srwatson	if (!biba_dominate_effective(obj, subj))
2667173138Srwatson		return (EACCES);
2668101099Srwatson
2669101099Srwatson	return (0);
2670101099Srwatson}
2671101099Srwatson
2672101099Srwatsonstatic int
2673173138Srwatsonbiba_sysvsem_check_semop(struct ucred *cred, struct semid_kernel *semakptr,
2674173138Srwatson    struct label *semaklabel, size_t accesstype)
2675112574Srwatson{
2676173138Srwatson	struct mac_biba *subj, *obj;
2677112574Srwatson
2678172955Srwatson	if (!biba_enabled)
2679112574Srwatson		return (0);
2680112574Srwatson
2681173138Srwatson	subj = SLOT(cred->cr_label);
2682173138Srwatson	obj = SLOT(semaklabel);
2683112574Srwatson
2684173138Srwatson	if (accesstype & SEM_R)
2685173138Srwatson		if (!biba_dominate_effective(obj, subj))
2686173138Srwatson			return (EACCES);
2687112574Srwatson
2688173138Srwatson	if (accesstype & SEM_A)
2689173138Srwatson		if (!biba_dominate_effective(subj, obj))
2690173138Srwatson			return (EACCES);
2691168951Srwatson
2692173138Srwatson	return (0);
2693173138Srwatson}
2694168951Srwatson
2695173138Srwatsonstatic void
2696173138Srwatsonbiba_sysvsem_cleanup(struct label *semalabel)
2697173138Srwatson{
2698168951Srwatson
2699173138Srwatson	bzero(SLOT(semalabel), sizeof(struct mac_biba));
2700173138Srwatson}
2701168951Srwatson
2702173138Srwatsonstatic void
2703173138Srwatsonbiba_sysvsem_create(struct ucred *cred, struct semid_kernel *semakptr,
2704173138Srwatson    struct label *semalabel)
2705173138Srwatson{
2706173138Srwatson	struct mac_biba *source, *dest;
2707168951Srwatson
2708173138Srwatson	source = SLOT(cred->cr_label);
2709173138Srwatson	dest = SLOT(semalabel);
2710168951Srwatson
2711173138Srwatson	biba_copy_effective(source, dest);
2712112574Srwatson}
2713112574Srwatson
2714112574Srwatsonstatic int
2715173138Srwatsonbiba_sysvshm_check_shmat(struct ucred *cred, struct shmid_kernel *shmsegptr,
2716173138Srwatson    struct label *shmseglabel, int shmflg)
2717106418Srwatson{
2718106418Srwatson	struct mac_biba *subj, *obj;
2719106418Srwatson
2720172955Srwatson	if (!biba_enabled)
2721106418Srwatson		return (0);
2722106418Srwatson
2723122524Srwatson	subj = SLOT(cred->cr_label);
2724173138Srwatson	obj = SLOT(shmseglabel);
2725106418Srwatson
2726173138Srwatson	if (!biba_dominate_effective(obj, subj))
2727106418Srwatson		return (EACCES);
2728173138Srwatson	if ((shmflg & SHM_RDONLY) == 0) {
2729173138Srwatson		if (!biba_dominate_effective(subj, obj))
2730173138Srwatson			return (EACCES);
2731173138Srwatson	}
2732173138Srwatson
2733106418Srwatson	return (0);
2734106418Srwatson}
2735106418Srwatson
2736106418Srwatsonstatic int
2737173138Srwatsonbiba_sysvshm_check_shmctl(struct ucred *cred, struct shmid_kernel *shmsegptr,
2738173138Srwatson    struct label *shmseglabel, int cmd)
2739168933Srwatson{
2740168933Srwatson	struct mac_biba *subj, *obj;
2741168933Srwatson
2742172955Srwatson	if (!biba_enabled)
2743168933Srwatson		return (0);
2744168933Srwatson
2745168933Srwatson	subj = SLOT(cred->cr_label);
2746173138Srwatson	obj = SLOT(shmseglabel);
2747168933Srwatson
2748173138Srwatson	switch(cmd) {
2749173138Srwatson	case IPC_RMID:
2750173138Srwatson	case IPC_SET:
2751173138Srwatson		if (!biba_dominate_effective(subj, obj))
2752173138Srwatson			return (EACCES);
2753173138Srwatson		break;
2754168933Srwatson
2755173138Srwatson	case IPC_STAT:
2756173138Srwatson	case SHM_STAT:
2757173138Srwatson		if (!biba_dominate_effective(obj, subj))
2758173138Srwatson			return (EACCES);
2759173138Srwatson		break;
2760168933Srwatson
2761173138Srwatson	default:
2762168933Srwatson		return (EACCES);
2763173138Srwatson	}
2764168933Srwatson
2765168933Srwatson	return (0);
2766168933Srwatson}
2767168933Srwatson
2768168933Srwatsonstatic int
2769173138Srwatsonbiba_sysvshm_check_shmget(struct ucred *cred, struct shmid_kernel *shmsegptr,
2770173138Srwatson    struct label *shmseglabel, int shmflg)
2771168933Srwatson{
2772173138Srwatson	struct mac_biba *subj, *obj;
2773168933Srwatson
2774172955Srwatson	if (!biba_enabled)
2775168933Srwatson		return (0);
2776168933Srwatson
2777168933Srwatson	subj = SLOT(cred->cr_label);
2778173138Srwatson	obj = SLOT(shmseglabel);
2779168933Srwatson
2780173138Srwatson	if (!biba_dominate_effective(obj, subj))
2781173138Srwatson		return (EACCES);
2782168933Srwatson
2783168933Srwatson	return (0);
2784168933Srwatson}
2785168933Srwatson
2786173138Srwatsonstatic void
2787173138Srwatsonbiba_sysvshm_cleanup(struct label *shmlabel)
2788106161Srwatson{
2789106161Srwatson
2790173138Srwatson	bzero(SLOT(shmlabel), sizeof(struct mac_biba));
2791173138Srwatson}
2792106161Srwatson
2793173138Srwatsonstatic void
2794173138Srwatsonbiba_sysvshm_create(struct ucred *cred, struct shmid_kernel *shmsegptr,
2795173138Srwatson    struct label *shmlabel)
2796173138Srwatson{
2797173138Srwatson	struct mac_biba *source, *dest;
2798106161Srwatson
2799173138Srwatson	source = SLOT(cred->cr_label);
2800173138Srwatson	dest = SLOT(shmlabel);
2801106161Srwatson
2802173138Srwatson	biba_copy_effective(source, dest);
2803106161Srwatson}
2804106161Srwatson
2805106161Srwatsonstatic int
2806173138Srwatsonbiba_vnode_associate_extattr(struct mount *mp, struct label *mplabel,
2807173138Srwatson    struct vnode *vp, struct label *vplabel)
2808112574Srwatson{
2809173138Srwatson	struct mac_biba mb_temp, *source, *dest;
2810173138Srwatson	int buflen, error;
2811112574Srwatson
2812173138Srwatson	source = SLOT(mplabel);
2813173138Srwatson	dest = SLOT(vplabel);
2814112574Srwatson
2815173138Srwatson	buflen = sizeof(mb_temp);
2816173138Srwatson	bzero(&mb_temp, buflen);
2817112574Srwatson
2818173138Srwatson	error = vn_extattr_get(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
2819173138Srwatson	    MAC_BIBA_EXTATTR_NAME, &buflen, (char *) &mb_temp, curthread);
2820173138Srwatson	if (error == ENOATTR || error == EOPNOTSUPP) {
2821173138Srwatson		/* Fall back to the mntlabel. */
2822173138Srwatson		biba_copy_effective(source, dest);
2823173138Srwatson		return (0);
2824173138Srwatson	} else if (error)
2825112574Srwatson		return (error);
2826112574Srwatson
2827173138Srwatson	if (buflen != sizeof(mb_temp)) {
2828173138Srwatson		printf("biba_vnode_associate_extattr: bad size %d\n",
2829173138Srwatson		    buflen);
2830173138Srwatson		return (EPERM);
2831173138Srwatson	}
2832173138Srwatson	if (biba_valid(&mb_temp) != 0) {
2833173138Srwatson		printf("biba_vnode_associate_extattr: invalid\n");
2834173138Srwatson		return (EPERM);
2835173138Srwatson	}
2836173138Srwatson	if ((mb_temp.mb_flags & MAC_BIBA_FLAGS_BOTH) !=
2837173138Srwatson	    MAC_BIBA_FLAG_EFFECTIVE) {
2838173138Srwatson		printf("biba_vnode_associate_extattr: not effective\n");
2839173138Srwatson		return (EPERM);
2840173138Srwatson	}
2841173138Srwatson
2842173138Srwatson	biba_copy_effective(&mb_temp, dest);
2843112574Srwatson	return (0);
2844112574Srwatson}
2845112574Srwatson
2846173138Srwatsonstatic void
2847173138Srwatsonbiba_vnode_associate_singlelabel(struct mount *mp, struct label *mplabel,
2848173138Srwatson    struct vnode *vp, struct label *vplabel)
2849106161Srwatson{
2850173138Srwatson	struct mac_biba *source, *dest;
2851106161Srwatson
2852173138Srwatson	source = SLOT(mplabel);
2853173138Srwatson	dest = SLOT(vplabel);
2854106161Srwatson
2855173138Srwatson	biba_copy_effective(source, dest);
2856106161Srwatson}
2857106161Srwatson
2858106161Srwatsonstatic int
2859172955Srwatsonbiba_vnode_check_chdir(struct ucred *cred, struct vnode *dvp,
2860168976Srwatson    struct label *dvplabel)
2861101099Srwatson{
2862101099Srwatson	struct mac_biba *subj, *obj;
2863101099Srwatson
2864172955Srwatson	if (!biba_enabled)
2865101099Srwatson		return (0);
2866101099Srwatson
2867122524Srwatson	subj = SLOT(cred->cr_label);
2868168976Srwatson	obj = SLOT(dvplabel);
2869101099Srwatson
2870172955Srwatson	if (!biba_dominate_effective(obj, subj))
2871101099Srwatson		return (EACCES);
2872101099Srwatson
2873101099Srwatson	return (0);
2874101099Srwatson}
2875101099Srwatson
2876101099Srwatsonstatic int
2877172955Srwatsonbiba_vnode_check_chroot(struct ucred *cred, struct vnode *dvp,
2878168976Srwatson    struct label *dvplabel)
2879101099Srwatson{
2880101099Srwatson	struct mac_biba *subj, *obj;
2881101099Srwatson
2882172955Srwatson	if (!biba_enabled)
2883101099Srwatson		return (0);
2884101099Srwatson
2885122524Srwatson	subj = SLOT(cred->cr_label);
2886168976Srwatson	obj = SLOT(dvplabel);
2887101099Srwatson
2888172955Srwatson	if (!biba_dominate_effective(obj, subj))
2889101099Srwatson		return (EACCES);
2890101099Srwatson
2891101099Srwatson	return (0);
2892101099Srwatson}
2893101099Srwatson
2894101099Srwatsonstatic int
2895172955Srwatsonbiba_vnode_check_create(struct ucred *cred, struct vnode *dvp,
2896168976Srwatson    struct label *dvplabel, struct componentname *cnp, struct vattr *vap)
2897101099Srwatson{
2898101099Srwatson	struct mac_biba *subj, *obj;
2899101099Srwatson
2900172955Srwatson	if (!biba_enabled)
2901101099Srwatson		return (0);
2902101099Srwatson
2903122524Srwatson	subj = SLOT(cred->cr_label);
2904168976Srwatson	obj = SLOT(dvplabel);
2905101099Srwatson
2906172955Srwatson	if (!biba_dominate_effective(subj, obj))
2907101099Srwatson		return (EACCES);
2908101099Srwatson
2909101099Srwatson	return (0);
2910101099Srwatson}
2911101099Srwatson
2912101099Srwatsonstatic int
2913172955Srwatsonbiba_vnode_check_deleteacl(struct ucred *cred, struct vnode *vp,
2914168976Srwatson    struct label *vplabel, acl_type_t type)
2915101099Srwatson{
2916101099Srwatson	struct mac_biba *subj, *obj;
2917101099Srwatson
2918172955Srwatson	if (!biba_enabled)
2919101099Srwatson		return (0);
2920101099Srwatson
2921122524Srwatson	subj = SLOT(cred->cr_label);
2922168976Srwatson	obj = SLOT(vplabel);
2923101099Srwatson
2924172955Srwatson	if (!biba_dominate_effective(subj, obj))
2925101099Srwatson		return (EACCES);
2926101099Srwatson
2927101099Srwatson	return (0);
2928101099Srwatson}
2929101099Srwatson
2930101099Srwatsonstatic int
2931172955Srwatsonbiba_vnode_check_deleteextattr(struct ucred *cred, struct vnode *vp,
2932168976Srwatson    struct label *vplabel, int attrnamespace, const char *name)
2933119202Srwatson{
2934119202Srwatson	struct mac_biba *subj, *obj;
2935119202Srwatson
2936172955Srwatson	if (!biba_enabled)
2937119202Srwatson		return (0);
2938119202Srwatson
2939122524Srwatson	subj = SLOT(cred->cr_label);
2940168976Srwatson	obj = SLOT(vplabel);
2941119202Srwatson
2942172955Srwatson	if (!biba_dominate_effective(subj, obj))
2943119202Srwatson		return (EACCES);
2944119202Srwatson
2945119202Srwatson	return (0);
2946119202Srwatson}
2947119202Srwatson
2948119202Srwatsonstatic int
2949172955Srwatsonbiba_vnode_check_exec(struct ucred *cred, struct vnode *vp,
2950168976Srwatson    struct label *vplabel, struct image_params *imgp,
2951106648Srwatson    struct label *execlabel)
2952101099Srwatson{
2953106648Srwatson	struct mac_biba *subj, *obj, *exec;
2954106648Srwatson	int error;
2955101099Srwatson
2956106648Srwatson	if (execlabel != NULL) {
2957106648Srwatson		/*
2958106648Srwatson		 * We currently don't permit labels to be changed at
2959172955Srwatson		 * exec-time as part of Biba, so disallow non-NULL Biba label
2960172955Srwatson		 * elements in the execlabel.
2961106648Srwatson		 */
2962106648Srwatson		exec = SLOT(execlabel);
2963106648Srwatson		error = biba_atmostflags(exec, 0);
2964106648Srwatson		if (error)
2965106648Srwatson			return (error);
2966106648Srwatson	}
2967106648Srwatson
2968172955Srwatson	if (!biba_enabled)
2969101099Srwatson		return (0);
2970101099Srwatson
2971122524Srwatson	subj = SLOT(cred->cr_label);
2972168976Srwatson	obj = SLOT(vplabel);
2973101099Srwatson
2974172955Srwatson	if (!biba_dominate_effective(obj, subj))
2975101099Srwatson		return (EACCES);
2976101099Srwatson
2977101099Srwatson	return (0);
2978101099Srwatson}
2979101099Srwatson
2980101099Srwatsonstatic int
2981172955Srwatsonbiba_vnode_check_getacl(struct ucred *cred, struct vnode *vp,
2982168976Srwatson    struct label *vplabel, acl_type_t type)
2983101099Srwatson{
2984101099Srwatson	struct mac_biba *subj, *obj;
2985101099Srwatson
2986172955Srwatson	if (!biba_enabled)
2987101099Srwatson		return (0);
2988101099Srwatson
2989122524Srwatson	subj = SLOT(cred->cr_label);
2990168976Srwatson	obj = SLOT(vplabel);
2991101099Srwatson
2992172955Srwatson	if (!biba_dominate_effective(obj, subj))
2993101099Srwatson		return (EACCES);
2994101099Srwatson
2995101099Srwatson	return (0);
2996101099Srwatson}
2997101099Srwatson
2998101099Srwatsonstatic int
2999172955Srwatsonbiba_vnode_check_getextattr(struct ucred *cred, struct vnode *vp,
3000189533Srwatson    struct label *vplabel, int attrnamespace, const char *name)
3001101099Srwatson{
3002101099Srwatson	struct mac_biba *subj, *obj;
3003101099Srwatson
3004172955Srwatson	if (!biba_enabled)
3005101099Srwatson		return (0);
3006101099Srwatson
3007122524Srwatson	subj = SLOT(cred->cr_label);
3008168976Srwatson	obj = SLOT(vplabel);
3009101099Srwatson
3010172955Srwatson	if (!biba_dominate_effective(obj, subj))
3011101099Srwatson		return (EACCES);
3012101099Srwatson
3013101099Srwatson	return (0);
3014101099Srwatson}
3015101099Srwatson
3016101099Srwatsonstatic int
3017172955Srwatsonbiba_vnode_check_link(struct ucred *cred, struct vnode *dvp,
3018168976Srwatson    struct label *dvplabel, struct vnode *vp, struct label *vplabel,
3019104530Srwatson    struct componentname *cnp)
3020104530Srwatson{
3021104530Srwatson	struct mac_biba *subj, *obj;
3022104530Srwatson
3023172955Srwatson	if (!biba_enabled)
3024104530Srwatson		return (0);
3025104530Srwatson
3026122524Srwatson	subj = SLOT(cred->cr_label);
3027168976Srwatson	obj = SLOT(dvplabel);
3028104530Srwatson
3029172955Srwatson	if (!biba_dominate_effective(subj, obj))
3030104530Srwatson		return (EACCES);
3031104530Srwatson
3032168976Srwatson	obj = SLOT(vplabel);
3033104530Srwatson
3034172955Srwatson	if (!biba_dominate_effective(subj, obj))
3035104530Srwatson		return (EACCES);
3036104530Srwatson
3037104530Srwatson	return (0);
3038104530Srwatson}
3039104530Srwatson
3040104530Srwatsonstatic int
3041172955Srwatsonbiba_vnode_check_listextattr(struct ucred *cred, struct vnode *vp,
3042168976Srwatson    struct label *vplabel, int attrnamespace)
3043119202Srwatson{
3044119202Srwatson	struct mac_biba *subj, *obj;
3045119202Srwatson
3046172955Srwatson	if (!biba_enabled)
3047119202Srwatson		return (0);
3048119202Srwatson
3049122524Srwatson	subj = SLOT(cred->cr_label);
3050168976Srwatson	obj = SLOT(vplabel);
3051119202Srwatson
3052172955Srwatson	if (!biba_dominate_effective(obj, subj))
3053119202Srwatson		return (EACCES);
3054119202Srwatson
3055119202Srwatson	return (0);
3056119202Srwatson}
3057119202Srwatson
3058119202Srwatsonstatic int
3059172955Srwatsonbiba_vnode_check_lookup(struct ucred *cred, struct vnode *dvp,
3060168976Srwatson    struct label *dvplabel, struct componentname *cnp)
3061101099Srwatson{
3062101099Srwatson	struct mac_biba *subj, *obj;
3063103759Srwatson
3064172955Srwatson	if (!biba_enabled)
3065101099Srwatson		return (0);
3066103759Srwatson
3067122524Srwatson	subj = SLOT(cred->cr_label);
3068168976Srwatson	obj = SLOT(dvplabel);
3069103759Srwatson
3070172955Srwatson	if (!biba_dominate_effective(obj, subj))
3071101099Srwatson		return (EACCES);
3072101099Srwatson
3073103759Srwatson	return (0);
3074101099Srwatson}
3075101099Srwatson
3076101099Srwatsonstatic int
3077172955Srwatsonbiba_vnode_check_mmap(struct ucred *cred, struct vnode *vp,
3078168976Srwatson    struct label *vplabel, int prot, int flags)
3079104546Srwatson{
3080104546Srwatson	struct mac_biba *subj, *obj;
3081104546Srwatson
3082104546Srwatson	/*
3083104546Srwatson	 * Rely on the use of open()-time protections to handle
3084104546Srwatson	 * non-revocation cases.
3085104546Srwatson	 */
3086172955Srwatson	if (!biba_enabled || !revocation_enabled)
3087104546Srwatson		return (0);
3088104546Srwatson
3089122524Srwatson	subj = SLOT(cred->cr_label);
3090168976Srwatson	obj = SLOT(vplabel);
3091104546Srwatson
3092104546Srwatson	if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
3093172955Srwatson		if (!biba_dominate_effective(obj, subj))
3094104546Srwatson			return (EACCES);
3095104546Srwatson	}
3096145076Scsjp	if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) {
3097172955Srwatson		if (!biba_dominate_effective(subj, obj))
3098104546Srwatson			return (EACCES);
3099104546Srwatson	}
3100104546Srwatson
3101104569Srwatson	return (0);
3102104546Srwatson}
3103104546Srwatson
3104104546Srwatsonstatic int
3105172955Srwatsonbiba_vnode_check_open(struct ucred *cred, struct vnode *vp,
3106184413Strasz    struct label *vplabel, accmode_t accmode)
3107101099Srwatson{
3108101099Srwatson	struct mac_biba *subj, *obj;
3109101099Srwatson
3110172955Srwatson	if (!biba_enabled)
3111101099Srwatson		return (0);
3112101099Srwatson
3113122524Srwatson	subj = SLOT(cred->cr_label);
3114168976Srwatson	obj = SLOT(vplabel);
3115101099Srwatson
3116101099Srwatson	/* XXX privilege override for admin? */
3117190524Strasz	if (accmode & (VREAD | VEXEC | VSTAT_PERMS)) {
3118172955Srwatson		if (!biba_dominate_effective(obj, subj))
3119101099Srwatson			return (EACCES);
3120101099Srwatson	}
3121190524Strasz	if (accmode & VMODIFY_PERMS) {
3122172955Srwatson		if (!biba_dominate_effective(subj, obj))
3123101099Srwatson			return (EACCES);
3124101099Srwatson	}
3125101099Srwatson
3126101099Srwatson	return (0);
3127101099Srwatson}
3128101099Srwatson
3129101099Srwatsonstatic int
3130172955Srwatsonbiba_vnode_check_poll(struct ucred *active_cred, struct ucred *file_cred,
3131168976Srwatson    struct vnode *vp, struct label *vplabel)
3132102112Srwatson{
3133102112Srwatson	struct mac_biba *subj, *obj;
3134102112Srwatson
3135172955Srwatson	if (!biba_enabled || !revocation_enabled)
3136102112Srwatson		return (0);
3137102112Srwatson
3138122524Srwatson	subj = SLOT(active_cred->cr_label);
3139168976Srwatson	obj = SLOT(vplabel);
3140102112Srwatson
3141172955Srwatson	if (!biba_dominate_effective(obj, subj))
3142102112Srwatson		return (EACCES);
3143102112Srwatson
3144102112Srwatson	return (0);
3145102112Srwatson}
3146102112Srwatson
3147102112Srwatsonstatic int
3148172955Srwatsonbiba_vnode_check_read(struct ucred *active_cred, struct ucred *file_cred,
3149168976Srwatson    struct vnode *vp, struct label *vplabel)
3150102112Srwatson{
3151102112Srwatson	struct mac_biba *subj, *obj;
3152102112Srwatson
3153172955Srwatson	if (!biba_enabled || !revocation_enabled)
3154102112Srwatson		return (0);
3155102112Srwatson
3156122524Srwatson	subj = SLOT(active_cred->cr_label);
3157168976Srwatson	obj = SLOT(vplabel);
3158102112Srwatson
3159172955Srwatson	if (!biba_dominate_effective(obj, subj))
3160102112Srwatson		return (EACCES);
3161102112Srwatson
3162102112Srwatson	return (0);
3163102112Srwatson}
3164102112Srwatson
3165102112Srwatsonstatic int
3166172955Srwatsonbiba_vnode_check_readdir(struct ucred *cred, struct vnode *dvp,
3167168976Srwatson    struct label *dvplabel)
3168101099Srwatson{
3169101099Srwatson	struct mac_biba *subj, *obj;
3170101099Srwatson
3171172955Srwatson	if (!biba_enabled)
3172101099Srwatson		return (0);
3173101099Srwatson
3174122524Srwatson	subj = SLOT(cred->cr_label);
3175168976Srwatson	obj = SLOT(dvplabel);
3176101099Srwatson
3177172955Srwatson	if (!biba_dominate_effective(obj, subj))
3178101099Srwatson		return (EACCES);
3179101099Srwatson
3180101099Srwatson	return (0);
3181101099Srwatson}
3182101099Srwatson
3183101099Srwatsonstatic int
3184172955Srwatsonbiba_vnode_check_readlink(struct ucred *cred, struct vnode *vp,
3185168976Srwatson    struct label *vplabel)
3186101099Srwatson{
3187101099Srwatson	struct mac_biba *subj, *obj;
3188101099Srwatson
3189172955Srwatson	if (!biba_enabled)
3190101099Srwatson		return (0);
3191101099Srwatson
3192122524Srwatson	subj = SLOT(cred->cr_label);
3193168976Srwatson	obj = SLOT(vplabel);
3194101099Srwatson
3195172955Srwatson	if (!biba_dominate_effective(obj, subj))
3196101099Srwatson		return (EACCES);
3197101099Srwatson
3198101099Srwatson	return (0);
3199101099Srwatson}
3200101099Srwatson
3201101099Srwatsonstatic int
3202172955Srwatsonbiba_vnode_check_relabel(struct ucred *cred, struct vnode *vp,
3203168976Srwatson    struct label *vplabel, struct label *newlabel)
3204101099Srwatson{
3205101099Srwatson	struct mac_biba *old, *new, *subj;
3206105634Srwatson	int error;
3207101099Srwatson
3208168976Srwatson	old = SLOT(vplabel);
3209101099Srwatson	new = SLOT(newlabel);
3210122524Srwatson	subj = SLOT(cred->cr_label);
3211101099Srwatson
3212101099Srwatson	/*
3213105634Srwatson	 * If there is a Biba label update for the vnode, it must be a
3214132232Srwatson	 * effective label.
3215101099Srwatson	 */
3216132232Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE);
3217105634Srwatson	if (error)
3218105634Srwatson		return (error);
3219101099Srwatson
3220101099Srwatson	/*
3221105634Srwatson	 * To perform a relabel of the vnode (Biba label or not), Biba must
3222105634Srwatson	 * authorize the relabel.
3223101099Srwatson	 */
3224172955Srwatson	if (!biba_effective_in_range(old, subj))
3225101099Srwatson		return (EPERM);
3226101099Srwatson
3227101099Srwatson	/*
3228105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
3229101099Srwatson	 */
3230132232Srwatson	if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) {
3231105634Srwatson		/*
3232105634Srwatson		 * To change the Biba label on a vnode, the new vnode label
3233105634Srwatson		 * must be in the subject range.
3234105634Srwatson		 */
3235172955Srwatson		if (!biba_effective_in_range(new, subj))
3236105634Srwatson			return (EPERM);
3237101099Srwatson
3238105634Srwatson		/*
3239172955Srwatson		 * To change the Biba label on the vnode to be EQUAL, the
3240172955Srwatson		 * subject must have appropriate privilege.
3241105634Srwatson		 */
3242172955Srwatson		if (biba_contains_equal(new)) {
3243172955Srwatson			error = biba_subject_privileged(subj);
3244105634Srwatson			if (error)
3245105634Srwatson				return (error);
3246105634Srwatson		}
3247105634Srwatson	}
3248105634Srwatson
3249105634Srwatson	return (0);
3250101099Srwatson}
3251101099Srwatson
3252101099Srwatsonstatic int
3253172955Srwatsonbiba_vnode_check_rename_from(struct ucred *cred, struct vnode *dvp,
3254168976Srwatson    struct label *dvplabel, struct vnode *vp, struct label *vplabel,
3255101099Srwatson    struct componentname *cnp)
3256101099Srwatson{
3257101099Srwatson	struct mac_biba *subj, *obj;
3258101099Srwatson
3259172955Srwatson	if (!biba_enabled)
3260101099Srwatson		return (0);
3261101099Srwatson
3262122524Srwatson	subj = SLOT(cred->cr_label);
3263168976Srwatson	obj = SLOT(dvplabel);
3264101099Srwatson
3265172955Srwatson	if (!biba_dominate_effective(subj, obj))
3266101099Srwatson		return (EACCES);
3267101099Srwatson
3268168976Srwatson	obj = SLOT(vplabel);
3269101099Srwatson
3270172955Srwatson	if (!biba_dominate_effective(subj, obj))
3271101099Srwatson		return (EACCES);
3272101099Srwatson
3273101099Srwatson	return (0);
3274101099Srwatson}
3275101099Srwatson
3276101099Srwatsonstatic int
3277172955Srwatsonbiba_vnode_check_rename_to(struct ucred *cred, struct vnode *dvp,
3278168976Srwatson    struct label *dvplabel, struct vnode *vp, struct label *vplabel,
3279168976Srwatson    int samedir, struct componentname *cnp)
3280101099Srwatson{
3281101099Srwatson	struct mac_biba *subj, *obj;
3282101099Srwatson
3283172955Srwatson	if (!biba_enabled)
3284101099Srwatson		return (0);
3285101099Srwatson
3286122524Srwatson	subj = SLOT(cred->cr_label);
3287168976Srwatson	obj = SLOT(dvplabel);
3288101099Srwatson
3289172955Srwatson	if (!biba_dominate_effective(subj, obj))
3290101099Srwatson		return (EACCES);
3291101099Srwatson
3292101099Srwatson	if (vp != NULL) {
3293168976Srwatson		obj = SLOT(vplabel);
3294101099Srwatson
3295172955Srwatson		if (!biba_dominate_effective(subj, obj))
3296101099Srwatson			return (EACCES);
3297101099Srwatson	}
3298101099Srwatson
3299101099Srwatson	return (0);
3300101099Srwatson}
3301101099Srwatson
3302101099Srwatsonstatic int
3303172955Srwatsonbiba_vnode_check_revoke(struct ucred *cred, struct vnode *vp,
3304168976Srwatson    struct label *vplabel)
3305101099Srwatson{
3306101099Srwatson	struct mac_biba *subj, *obj;
3307101099Srwatson
3308172955Srwatson	if (!biba_enabled)
3309101099Srwatson		return (0);
3310101099Srwatson
3311122524Srwatson	subj = SLOT(cred->cr_label);
3312168976Srwatson	obj = SLOT(vplabel);
3313101099Srwatson
3314172955Srwatson	if (!biba_dominate_effective(subj, obj))
3315101099Srwatson		return (EACCES);
3316101099Srwatson
3317101099Srwatson	return (0);
3318101099Srwatson}
3319101099Srwatson
3320101099Srwatsonstatic int
3321172955Srwatsonbiba_vnode_check_setacl(struct ucred *cred, struct vnode *vp,
3322168976Srwatson    struct label *vplabel, acl_type_t type, struct acl *acl)
3323101099Srwatson{
3324101099Srwatson	struct mac_biba *subj, *obj;
3325101099Srwatson
3326172955Srwatson	if (!biba_enabled)
3327101099Srwatson		return (0);
3328101099Srwatson
3329122524Srwatson	subj = SLOT(cred->cr_label);
3330168976Srwatson	obj = SLOT(vplabel);
3331101099Srwatson
3332172955Srwatson	if (!biba_dominate_effective(subj, obj))
3333101099Srwatson		return (EACCES);
3334101099Srwatson
3335101099Srwatson	return (0);
3336101099Srwatson}
3337101099Srwatson
3338101099Srwatsonstatic int
3339172955Srwatsonbiba_vnode_check_setextattr(struct ucred *cred, struct vnode *vp,
3340189533Srwatson    struct label *vplabel, int attrnamespace, const char *name)
3341101099Srwatson{
3342101099Srwatson	struct mac_biba *subj, *obj;
3343101099Srwatson
3344172955Srwatson	if (!biba_enabled)
3345101099Srwatson		return (0);
3346101099Srwatson
3347122524Srwatson	subj = SLOT(cred->cr_label);
3348168976Srwatson	obj = SLOT(vplabel);
3349101099Srwatson
3350172955Srwatson	if (!biba_dominate_effective(subj, obj))
3351101099Srwatson		return (EACCES);
3352101099Srwatson
3353101099Srwatson	/* XXX: protect the MAC EA in a special way? */
3354101099Srwatson
3355101099Srwatson	return (0);
3356101099Srwatson}
3357101099Srwatson
3358101099Srwatsonstatic int
3359172955Srwatsonbiba_vnode_check_setflags(struct ucred *cred, struct vnode *vp,
3360168976Srwatson    struct label *vplabel, u_long flags)
3361101099Srwatson{
3362101099Srwatson	struct mac_biba *subj, *obj;
3363101099Srwatson
3364172955Srwatson	if (!biba_enabled)
3365101099Srwatson		return (0);
3366101099Srwatson
3367122524Srwatson	subj = SLOT(cred->cr_label);
3368168976Srwatson	obj = SLOT(vplabel);
3369101099Srwatson
3370172955Srwatson	if (!biba_dominate_effective(subj, obj))
3371101099Srwatson		return (EACCES);
3372101099Srwatson
3373101099Srwatson	return (0);
3374101099Srwatson}
3375101099Srwatson
3376101099Srwatsonstatic int
3377172955Srwatsonbiba_vnode_check_setmode(struct ucred *cred, struct vnode *vp,
3378168976Srwatson    struct label *vplabel, mode_t mode)
3379101099Srwatson{
3380101099Srwatson	struct mac_biba *subj, *obj;
3381101099Srwatson
3382172955Srwatson	if (!biba_enabled)
3383101099Srwatson		return (0);
3384101099Srwatson
3385122524Srwatson	subj = SLOT(cred->cr_label);
3386168976Srwatson	obj = SLOT(vplabel);
3387101099Srwatson
3388172955Srwatson	if (!biba_dominate_effective(subj, obj))
3389101099Srwatson		return (EACCES);
3390101099Srwatson
3391101099Srwatson	return (0);
3392101099Srwatson}
3393101099Srwatson
3394101099Srwatsonstatic int
3395172955Srwatsonbiba_vnode_check_setowner(struct ucred *cred, struct vnode *vp,
3396168976Srwatson    struct label *vplabel, uid_t uid, gid_t gid)
3397101099Srwatson{
3398101099Srwatson	struct mac_biba *subj, *obj;
3399101099Srwatson
3400172955Srwatson	if (!biba_enabled)
3401101099Srwatson		return (0);
3402101099Srwatson
3403122524Srwatson	subj = SLOT(cred->cr_label);
3404168976Srwatson	obj = SLOT(vplabel);
3405101099Srwatson
3406172955Srwatson	if (!biba_dominate_effective(subj, obj))
3407101099Srwatson		return (EACCES);
3408101099Srwatson
3409101099Srwatson	return (0);
3410101099Srwatson}
3411101099Srwatson
3412101099Srwatsonstatic int
3413172955Srwatsonbiba_vnode_check_setutimes(struct ucred *cred, struct vnode *vp,
3414168976Srwatson    struct label *vplabel, struct timespec atime, struct timespec mtime)
3415101099Srwatson{
3416101099Srwatson	struct mac_biba *subj, *obj;
3417101099Srwatson
3418172955Srwatson	if (!biba_enabled)
3419101099Srwatson		return (0);
3420101099Srwatson
3421122524Srwatson	subj = SLOT(cred->cr_label);
3422168976Srwatson	obj = SLOT(vplabel);
3423101099Srwatson
3424172955Srwatson	if (!biba_dominate_effective(subj, obj))
3425101099Srwatson		return (EACCES);
3426101099Srwatson
3427101099Srwatson	return (0);
3428101099Srwatson}
3429101099Srwatson
3430101099Srwatsonstatic int
3431172955Srwatsonbiba_vnode_check_stat(struct ucred *active_cred, struct ucred *file_cred,
3432168976Srwatson    struct vnode *vp, struct label *vplabel)
3433101099Srwatson{
3434101099Srwatson	struct mac_biba *subj, *obj;
3435101099Srwatson
3436172955Srwatson	if (!biba_enabled)
3437101099Srwatson		return (0);
3438101099Srwatson
3439122524Srwatson	subj = SLOT(active_cred->cr_label);
3440168976Srwatson	obj = SLOT(vplabel);
3441101099Srwatson
3442172955Srwatson	if (!biba_dominate_effective(obj, subj))
3443101099Srwatson		return (EACCES);
3444101099Srwatson
3445101099Srwatson	return (0);
3446101099Srwatson}
3447101099Srwatson
3448102112Srwatsonstatic int
3449172955Srwatsonbiba_vnode_check_unlink(struct ucred *cred, struct vnode *dvp,
3450172107Srwatson    struct label *dvplabel, struct vnode *vp, struct label *vplabel,
3451172107Srwatson    struct componentname *cnp)
3452172107Srwatson{
3453172107Srwatson	struct mac_biba *subj, *obj;
3454172107Srwatson
3455172955Srwatson	if (!biba_enabled)
3456172107Srwatson		return (0);
3457172107Srwatson
3458172107Srwatson	subj = SLOT(cred->cr_label);
3459172107Srwatson	obj = SLOT(dvplabel);
3460172107Srwatson
3461172955Srwatson	if (!biba_dominate_effective(subj, obj))
3462172107Srwatson		return (EACCES);
3463172107Srwatson
3464172107Srwatson	obj = SLOT(vplabel);
3465172107Srwatson
3466172955Srwatson	if (!biba_dominate_effective(subj, obj))
3467172107Srwatson		return (EACCES);
3468172107Srwatson
3469172107Srwatson	return (0);
3470172107Srwatson}
3471172107Srwatson
3472172107Srwatsonstatic int
3473172955Srwatsonbiba_vnode_check_write(struct ucred *active_cred,
3474168976Srwatson    struct ucred *file_cred, struct vnode *vp, struct label *vplabel)
3475102112Srwatson{
3476102112Srwatson	struct mac_biba *subj, *obj;
3477102112Srwatson
3478172955Srwatson	if (!biba_enabled || !revocation_enabled)
3479102112Srwatson		return (0);
3480102112Srwatson
3481122524Srwatson	subj = SLOT(active_cred->cr_label);
3482168976Srwatson	obj = SLOT(vplabel);
3483102112Srwatson
3484172955Srwatson	if (!biba_dominate_effective(subj, obj))
3485102112Srwatson		return (EACCES);
3486102112Srwatson
3487102112Srwatson	return (0);
3488102112Srwatson}
3489102112Srwatson
3490173138Srwatsonstatic int
3491173138Srwatsonbiba_vnode_create_extattr(struct ucred *cred, struct mount *mp,
3492173138Srwatson    struct label *mplabel, struct vnode *dvp, struct label *dvplabel,
3493173138Srwatson    struct vnode *vp, struct label *vplabel, struct componentname *cnp)
3494165150Scsjp{
3495173138Srwatson	struct mac_biba *source, *dest, mb_temp;
3496173138Srwatson	size_t buflen;
3497173138Srwatson	int error;
3498165150Scsjp
3499173138Srwatson	buflen = sizeof(mb_temp);
3500173138Srwatson	bzero(&mb_temp, buflen);
3501173138Srwatson
3502173138Srwatson	source = SLOT(cred->cr_label);
3503173138Srwatson	dest = SLOT(vplabel);
3504173138Srwatson	biba_copy_effective(source, &mb_temp);
3505173138Srwatson
3506173138Srwatson	error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
3507173138Srwatson	    MAC_BIBA_EXTATTR_NAME, buflen, (char *) &mb_temp, curthread);
3508173138Srwatson	if (error == 0)
3509173138Srwatson		biba_copy_effective(source, dest);
3510173138Srwatson	return (error);
3511165150Scsjp}
3512165150Scsjp
3513165150Scsjpstatic void
3514173138Srwatsonbiba_vnode_relabel(struct ucred *cred, struct vnode *vp,
3515173138Srwatson    struct label *vplabel, struct label *newlabel)
3516165150Scsjp{
3517165150Scsjp	struct mac_biba *source, *dest;
3518165150Scsjp
3519173138Srwatson	source = SLOT(newlabel);
3520173138Srwatson	dest = SLOT(vplabel);
3521173138Srwatson
3522173138Srwatson	biba_copy(source, dest);
3523165150Scsjp}
3524165150Scsjp
3525173138Srwatsonstatic int
3526173138Srwatsonbiba_vnode_setlabel_extattr(struct ucred *cred, struct vnode *vp,
3527173138Srwatson    struct label *vplabel, struct label *intlabel)
3528173138Srwatson{
3529173138Srwatson	struct mac_biba *source, mb_temp;
3530173138Srwatson	size_t buflen;
3531173138Srwatson	int error;
3532173138Srwatson
3533173138Srwatson	buflen = sizeof(mb_temp);
3534173138Srwatson	bzero(&mb_temp, buflen);
3535173138Srwatson
3536173138Srwatson	source = SLOT(intlabel);
3537173138Srwatson	if ((source->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) == 0)
3538173138Srwatson		return (0);
3539173138Srwatson
3540173138Srwatson	biba_copy_effective(source, &mb_temp);
3541173138Srwatson
3542173138Srwatson	error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
3543173138Srwatson	    MAC_BIBA_EXTATTR_NAME, buflen, (char *) &mb_temp, curthread);
3544173138Srwatson	return (error);
3545173138Srwatson}
3546173138Srwatson
3547106217Srwatsonstatic struct mac_policy_ops mac_biba_ops =
3548101099Srwatson{
3549172955Srwatson	.mpo_init = biba_init,
3550173138Srwatson
3551173138Srwatson	.mpo_bpfdesc_check_receive = biba_bpfdesc_check_receive,
3552173138Srwatson	.mpo_bpfdesc_create = biba_bpfdesc_create,
3553173138Srwatson	.mpo_bpfdesc_create_mbuf = biba_bpfdesc_create_mbuf,
3554173138Srwatson	.mpo_bpfdesc_destroy_label = biba_destroy_label,
3555172955Srwatson	.mpo_bpfdesc_init_label = biba_init_label,
3556173138Srwatson
3557184407Srwatson	.mpo_cred_associate_nfsd = biba_cred_associate_nfsd,
3558173138Srwatson	.mpo_cred_check_relabel = biba_cred_check_relabel,
3559173138Srwatson	.mpo_cred_check_visible = biba_cred_check_visible,
3560173138Srwatson	.mpo_cred_copy_label = biba_copy_label,
3561184407Srwatson	.mpo_cred_create_init = biba_cred_create_init,
3562184407Srwatson	.mpo_cred_create_swapper = biba_cred_create_swapper,
3563172955Srwatson	.mpo_cred_destroy_label = biba_destroy_label,
3564172955Srwatson	.mpo_cred_externalize_label = biba_externalize_label,
3565173138Srwatson	.mpo_cred_init_label = biba_init_label,
3566172955Srwatson	.mpo_cred_internalize_label = biba_internalize_label,
3567173138Srwatson	.mpo_cred_relabel = biba_cred_relabel,
3568173138Srwatson
3569172955Srwatson	.mpo_devfs_create_device = biba_devfs_create_device,
3570172955Srwatson	.mpo_devfs_create_directory = biba_devfs_create_directory,
3571172955Srwatson	.mpo_devfs_create_symlink = biba_devfs_create_symlink,
3572173138Srwatson	.mpo_devfs_destroy_label = biba_destroy_label,
3573173138Srwatson	.mpo_devfs_init_label = biba_init_label,
3574172955Srwatson	.mpo_devfs_update = biba_devfs_update,
3575172955Srwatson	.mpo_devfs_vnode_associate = biba_devfs_vnode_associate,
3576173138Srwatson
3577173138Srwatson	.mpo_ifnet_check_relabel = biba_ifnet_check_relabel,
3578173138Srwatson	.mpo_ifnet_check_transmit = biba_ifnet_check_transmit,
3579173138Srwatson	.mpo_ifnet_copy_label = biba_copy_label,
3580172955Srwatson	.mpo_ifnet_create = biba_ifnet_create,
3581173138Srwatson	.mpo_ifnet_create_mbuf = biba_ifnet_create_mbuf,
3582173138Srwatson	.mpo_ifnet_destroy_label = biba_destroy_label,
3583173138Srwatson	.mpo_ifnet_externalize_label = biba_externalize_label,
3584173138Srwatson	.mpo_ifnet_init_label = biba_init_label,
3585173138Srwatson	.mpo_ifnet_internalize_label = biba_internalize_label,
3586173138Srwatson	.mpo_ifnet_relabel = biba_ifnet_relabel,
3587173138Srwatson
3588173138Srwatson	.mpo_inpcb_check_deliver = biba_inpcb_check_deliver,
3589183980Sbz	.mpo_inpcb_check_visible = biba_inpcb_check_visible,
3590172955Srwatson	.mpo_inpcb_create = biba_inpcb_create,
3591173138Srwatson	.mpo_inpcb_create_mbuf = biba_inpcb_create_mbuf,
3592173138Srwatson	.mpo_inpcb_destroy_label = biba_destroy_label,
3593173138Srwatson	.mpo_inpcb_init_label = biba_init_label_waitcheck,
3594173138Srwatson	.mpo_inpcb_sosetlabel = biba_inpcb_sosetlabel,
3595173138Srwatson
3596184308Srwatson	.mpo_ip6q_create = biba_ip6q_create,
3597184308Srwatson	.mpo_ip6q_destroy_label = biba_destroy_label,
3598184308Srwatson	.mpo_ip6q_init_label = biba_init_label_waitcheck,
3599184308Srwatson	.mpo_ip6q_match = biba_ip6q_match,
3600184308Srwatson	.mpo_ip6q_reassemble = biba_ip6q_reassemble,
3601184308Srwatson	.mpo_ip6q_update = biba_ip6q_update,
3602184308Srwatson
3603172955Srwatson	.mpo_ipq_create = biba_ipq_create,
3604173138Srwatson	.mpo_ipq_destroy_label = biba_destroy_label,
3605173138Srwatson	.mpo_ipq_init_label = biba_init_label_waitcheck,
3606172955Srwatson	.mpo_ipq_match = biba_ipq_match,
3607173138Srwatson	.mpo_ipq_reassemble = biba_ipq_reassemble,
3608172955Srwatson	.mpo_ipq_update = biba_ipq_update,
3609173138Srwatson
3610172955Srwatson	.mpo_kld_check_load = biba_kld_check_load,
3611173138Srwatson
3612173138Srwatson	.mpo_mbuf_copy_label = biba_copy_label,
3613173138Srwatson	.mpo_mbuf_destroy_label = biba_destroy_label,
3614173138Srwatson	.mpo_mbuf_init_label = biba_init_label_waitcheck,
3615173138Srwatson
3616172955Srwatson	.mpo_mount_check_stat = biba_mount_check_stat,
3617173138Srwatson	.mpo_mount_create = biba_mount_create,
3618173138Srwatson	.mpo_mount_destroy_label = biba_destroy_label,
3619173138Srwatson	.mpo_mount_init_label = biba_init_label,
3620173138Srwatson
3621173138Srwatson	.mpo_netatalk_aarp_send = biba_netatalk_aarp_send,
3622173138Srwatson
3623173138Srwatson	.mpo_netinet_arp_send = biba_netinet_arp_send,
3624173138Srwatson	.mpo_netinet_firewall_reply = biba_netinet_firewall_reply,
3625173138Srwatson	.mpo_netinet_firewall_send = biba_netinet_firewall_send,
3626173138Srwatson	.mpo_netinet_fragment = biba_netinet_fragment,
3627173138Srwatson	.mpo_netinet_icmp_reply = biba_netinet_icmp_reply,
3628173138Srwatson	.mpo_netinet_igmp_send = biba_netinet_igmp_send,
3629173138Srwatson
3630173138Srwatson	.mpo_netinet6_nd6_send = biba_netinet6_nd6_send,
3631173138Srwatson
3632172955Srwatson	.mpo_pipe_check_ioctl = biba_pipe_check_ioctl,
3633172955Srwatson	.mpo_pipe_check_poll = biba_pipe_check_poll,
3634172955Srwatson	.mpo_pipe_check_read = biba_pipe_check_read,
3635172955Srwatson	.mpo_pipe_check_relabel = biba_pipe_check_relabel,
3636172955Srwatson	.mpo_pipe_check_stat = biba_pipe_check_stat,
3637172955Srwatson	.mpo_pipe_check_write = biba_pipe_check_write,
3638173138Srwatson	.mpo_pipe_copy_label = biba_copy_label,
3639173138Srwatson	.mpo_pipe_create = biba_pipe_create,
3640173138Srwatson	.mpo_pipe_destroy_label = biba_destroy_label,
3641173138Srwatson	.mpo_pipe_externalize_label = biba_externalize_label,
3642173138Srwatson	.mpo_pipe_init_label = biba_init_label,
3643173138Srwatson	.mpo_pipe_internalize_label = biba_internalize_label,
3644173138Srwatson	.mpo_pipe_relabel = biba_pipe_relabel,
3645173138Srwatson
3646172955Srwatson	.mpo_posixsem_check_getvalue = biba_posixsem_check_rdonly,
3647180059Sjhb	.mpo_posixsem_check_open = biba_posixsem_check_openunlink,
3648172955Srwatson	.mpo_posixsem_check_post = biba_posixsem_check_write,
3649225344Srwatson	.mpo_posixsem_check_setmode = biba_posixsem_check_setmode,
3650225344Srwatson	.mpo_posixsem_check_setowner = biba_posixsem_check_setowner,
3651180059Sjhb	.mpo_posixsem_check_stat = biba_posixsem_check_rdonly,
3652180059Sjhb	.mpo_posixsem_check_unlink = biba_posixsem_check_openunlink,
3653172955Srwatson	.mpo_posixsem_check_wait = biba_posixsem_check_write,
3654173138Srwatson	.mpo_posixsem_create = biba_posixsem_create,
3655173138Srwatson	.mpo_posixsem_destroy_label = biba_destroy_label,
3656173138Srwatson	.mpo_posixsem_init_label = biba_init_label,
3657173138Srwatson
3658225344Srwatson	.mpo_posixshm_check_mmap = biba_posixshm_check_mmap,
3659225344Srwatson	.mpo_posixshm_check_open = biba_posixshm_check_open,
3660225344Srwatson	.mpo_posixshm_check_setmode = biba_posixshm_check_setmode,
3661225344Srwatson	.mpo_posixshm_check_setowner = biba_posixshm_check_setowner,
3662225344Srwatson	.mpo_posixshm_check_stat = biba_posixshm_check_stat,
3663225344Srwatson	.mpo_posixshm_check_truncate = biba_posixshm_check_truncate,
3664225344Srwatson	.mpo_posixshm_check_unlink = biba_posixshm_check_unlink,
3665225344Srwatson	.mpo_posixshm_create = biba_posixshm_create,
3666225344Srwatson	.mpo_posixshm_destroy_label = biba_destroy_label,
3667225344Srwatson	.mpo_posixshm_init_label = biba_init_label,
3668225344Srwatson
3669173138Srwatson	.mpo_priv_check = biba_priv_check,
3670173138Srwatson
3671172955Srwatson	.mpo_proc_check_debug = biba_proc_check_debug,
3672172955Srwatson	.mpo_proc_check_sched = biba_proc_check_sched,
3673172955Srwatson	.mpo_proc_check_signal = biba_proc_check_signal,
3674173138Srwatson
3675172955Srwatson	.mpo_socket_check_deliver = biba_socket_check_deliver,
3676172955Srwatson	.mpo_socket_check_relabel = biba_socket_check_relabel,
3677172955Srwatson	.mpo_socket_check_visible = biba_socket_check_visible,
3678173138Srwatson	.mpo_socket_copy_label = biba_copy_label,
3679173138Srwatson	.mpo_socket_create = biba_socket_create,
3680173138Srwatson	.mpo_socket_create_mbuf = biba_socket_create_mbuf,
3681173138Srwatson	.mpo_socket_destroy_label = biba_destroy_label,
3682173138Srwatson	.mpo_socket_externalize_label = biba_externalize_label,
3683173138Srwatson	.mpo_socket_init_label = biba_init_label_waitcheck,
3684173138Srwatson	.mpo_socket_internalize_label = biba_internalize_label,
3685173138Srwatson	.mpo_socket_newconn = biba_socket_newconn,
3686173138Srwatson	.mpo_socket_relabel = biba_socket_relabel,
3687173138Srwatson
3688173138Srwatson	.mpo_socketpeer_destroy_label = biba_destroy_label,
3689173138Srwatson	.mpo_socketpeer_externalize_label = biba_externalize_label,
3690173138Srwatson	.mpo_socketpeer_init_label = biba_init_label_waitcheck,
3691173138Srwatson	.mpo_socketpeer_set_from_mbuf = biba_socketpeer_set_from_mbuf,
3692173138Srwatson	.mpo_socketpeer_set_from_socket = biba_socketpeer_set_from_socket,
3693173138Srwatson
3694173138Srwatson	.mpo_syncache_create = biba_syncache_create,
3695173138Srwatson	.mpo_syncache_create_mbuf = biba_syncache_create_mbuf,
3696173138Srwatson	.mpo_syncache_destroy_label = biba_destroy_label,
3697173138Srwatson	.mpo_syncache_init_label = biba_init_label_waitcheck,
3698173138Srwatson
3699172955Srwatson	.mpo_system_check_acct = biba_system_check_acct,
3700172955Srwatson	.mpo_system_check_auditctl = biba_system_check_auditctl,
3701172955Srwatson	.mpo_system_check_auditon = biba_system_check_auditon,
3702173138Srwatson	.mpo_system_check_swapoff = biba_system_check_swapoff,
3703172955Srwatson	.mpo_system_check_swapon = biba_system_check_swapon,
3704172955Srwatson	.mpo_system_check_sysctl = biba_system_check_sysctl,
3705173138Srwatson
3706173138Srwatson	.mpo_sysvmsg_cleanup = biba_sysvmsg_cleanup,
3707173138Srwatson	.mpo_sysvmsg_create = biba_sysvmsg_create,
3708173138Srwatson	.mpo_sysvmsg_destroy_label = biba_destroy_label,
3709173138Srwatson	.mpo_sysvmsg_init_label = biba_init_label,
3710173138Srwatson
3711173138Srwatson	.mpo_sysvmsq_check_msgrcv = biba_sysvmsq_check_msgrcv,
3712173138Srwatson	.mpo_sysvmsq_check_msgrmid = biba_sysvmsq_check_msgrmid,
3713173138Srwatson	.mpo_sysvmsq_check_msqget = biba_sysvmsq_check_msqget,
3714173138Srwatson	.mpo_sysvmsq_check_msqsnd = biba_sysvmsq_check_msqsnd,
3715173138Srwatson	.mpo_sysvmsq_check_msqrcv = biba_sysvmsq_check_msqrcv,
3716173138Srwatson	.mpo_sysvmsq_check_msqctl = biba_sysvmsq_check_msqctl,
3717173138Srwatson	.mpo_sysvmsq_cleanup = biba_sysvmsq_cleanup,
3718173138Srwatson	.mpo_sysvmsq_create = biba_sysvmsq_create,
3719173138Srwatson	.mpo_sysvmsq_destroy_label = biba_destroy_label,
3720173138Srwatson	.mpo_sysvmsq_init_label = biba_init_label,
3721173138Srwatson
3722173138Srwatson	.mpo_sysvsem_check_semctl = biba_sysvsem_check_semctl,
3723173138Srwatson	.mpo_sysvsem_check_semget = biba_sysvsem_check_semget,
3724173138Srwatson	.mpo_sysvsem_check_semop = biba_sysvsem_check_semop,
3725173138Srwatson	.mpo_sysvsem_cleanup = biba_sysvsem_cleanup,
3726173138Srwatson	.mpo_sysvsem_create = biba_sysvsem_create,
3727173138Srwatson	.mpo_sysvsem_destroy_label = biba_destroy_label,
3728173138Srwatson	.mpo_sysvsem_init_label = biba_init_label,
3729173138Srwatson
3730173138Srwatson	.mpo_sysvshm_check_shmat = biba_sysvshm_check_shmat,
3731173138Srwatson	.mpo_sysvshm_check_shmctl = biba_sysvshm_check_shmctl,
3732173138Srwatson	.mpo_sysvshm_check_shmget = biba_sysvshm_check_shmget,
3733173138Srwatson	.mpo_sysvshm_cleanup = biba_sysvshm_cleanup,
3734173138Srwatson	.mpo_sysvshm_create = biba_sysvshm_create,
3735173138Srwatson	.mpo_sysvshm_destroy_label = biba_destroy_label,
3736173138Srwatson	.mpo_sysvshm_init_label = biba_init_label,
3737173138Srwatson
3738173138Srwatson	.mpo_vnode_associate_extattr = biba_vnode_associate_extattr,
3739173138Srwatson	.mpo_vnode_associate_singlelabel = biba_vnode_associate_singlelabel,
3740172955Srwatson	.mpo_vnode_check_access = biba_vnode_check_open,
3741172955Srwatson	.mpo_vnode_check_chdir = biba_vnode_check_chdir,
3742172955Srwatson	.mpo_vnode_check_chroot = biba_vnode_check_chroot,
3743172955Srwatson	.mpo_vnode_check_create = biba_vnode_check_create,
3744172955Srwatson	.mpo_vnode_check_deleteacl = biba_vnode_check_deleteacl,
3745172955Srwatson	.mpo_vnode_check_deleteextattr = biba_vnode_check_deleteextattr,
3746172955Srwatson	.mpo_vnode_check_exec = biba_vnode_check_exec,
3747172955Srwatson	.mpo_vnode_check_getacl = biba_vnode_check_getacl,
3748172955Srwatson	.mpo_vnode_check_getextattr = biba_vnode_check_getextattr,
3749172955Srwatson	.mpo_vnode_check_link = biba_vnode_check_link,
3750172955Srwatson	.mpo_vnode_check_listextattr = biba_vnode_check_listextattr,
3751172955Srwatson	.mpo_vnode_check_lookup = biba_vnode_check_lookup,
3752172955Srwatson	.mpo_vnode_check_mmap = biba_vnode_check_mmap,
3753172955Srwatson	.mpo_vnode_check_open = biba_vnode_check_open,
3754172955Srwatson	.mpo_vnode_check_poll = biba_vnode_check_poll,
3755172955Srwatson	.mpo_vnode_check_read = biba_vnode_check_read,
3756172955Srwatson	.mpo_vnode_check_readdir = biba_vnode_check_readdir,
3757172955Srwatson	.mpo_vnode_check_readlink = biba_vnode_check_readlink,
3758172955Srwatson	.mpo_vnode_check_relabel = biba_vnode_check_relabel,
3759172955Srwatson	.mpo_vnode_check_rename_from = biba_vnode_check_rename_from,
3760172955Srwatson	.mpo_vnode_check_rename_to = biba_vnode_check_rename_to,
3761172955Srwatson	.mpo_vnode_check_revoke = biba_vnode_check_revoke,
3762172955Srwatson	.mpo_vnode_check_setacl = biba_vnode_check_setacl,
3763172955Srwatson	.mpo_vnode_check_setextattr = biba_vnode_check_setextattr,
3764172955Srwatson	.mpo_vnode_check_setflags = biba_vnode_check_setflags,
3765172955Srwatson	.mpo_vnode_check_setmode = biba_vnode_check_setmode,
3766172955Srwatson	.mpo_vnode_check_setowner = biba_vnode_check_setowner,
3767172955Srwatson	.mpo_vnode_check_setutimes = biba_vnode_check_setutimes,
3768172955Srwatson	.mpo_vnode_check_stat = biba_vnode_check_stat,
3769172955Srwatson	.mpo_vnode_check_unlink = biba_vnode_check_unlink,
3770172955Srwatson	.mpo_vnode_check_write = biba_vnode_check_write,
3771173138Srwatson	.mpo_vnode_create_extattr = biba_vnode_create_extattr,
3772173138Srwatson	.mpo_vnode_copy_label = biba_copy_label,
3773173138Srwatson	.mpo_vnode_destroy_label = biba_destroy_label,
3774173138Srwatson	.mpo_vnode_externalize_label = biba_externalize_label,
3775173138Srwatson	.mpo_vnode_init_label = biba_init_label,
3776173138Srwatson	.mpo_vnode_internalize_label = biba_internalize_label,
3777173138Srwatson	.mpo_vnode_relabel = biba_vnode_relabel,
3778173138Srwatson	.mpo_vnode_setlabel_extattr = biba_vnode_setlabel_extattr,
3779101099Srwatson};
3780101099Srwatson
3781112717SrwatsonMAC_POLICY_SET(&mac_biba_ops, mac_biba, "TrustedBSD MAC/Biba",
3782187016Srwatson    MPC_LOADTIME_FLAG_NOTLATE, &biba_slot);
3783