mac_biba.c revision 105634
1101099Srwatson/*-
2101099Srwatson * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson
3101099Srwatson * Copyright (c) 2001, 2002 Networks Associates Technology, Inc.
4101099Srwatson * All rights reserved.
5101099Srwatson *
6101099Srwatson * This software was developed by Robert Watson for the TrustedBSD Project.
7101099Srwatson *
8101099Srwatson * This software was developed for the FreeBSD Project in part by NAI Labs,
9101099Srwatson * the Security Research Division of Network Associates, Inc. under
10101099Srwatson * DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA
11101099Srwatson * CHATS research program.
12101099Srwatson *
13101099Srwatson * Redistribution and use in source and binary forms, with or without
14101099Srwatson * modification, are permitted provided that the following conditions
15101099Srwatson * are met:
16101099Srwatson * 1. Redistributions of source code must retain the above copyright
17101099Srwatson *    notice, this list of conditions and the following disclaimer.
18101099Srwatson * 2. Redistributions in binary form must reproduce the above copyright
19101099Srwatson *    notice, this list of conditions and the following disclaimer in the
20101099Srwatson *    documentation and/or other materials provided with the distribution.
21101099Srwatson * 3. The names of the authors may not be used to endorse or promote
22101099Srwatson *    products derived from this software without specific prior written
23101099Srwatson *    permission.
24101099Srwatson *
25101099Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
26101099Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27101099Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28101099Srwatson * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
29101099Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30101099Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31101099Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32101099Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33101099Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34101099Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35101099Srwatson * SUCH DAMAGE.
36101099Srwatson *
37101099Srwatson * $FreeBSD: head/sys/security/mac_biba/mac_biba.c 105634 2002-10-21 16:35:54Z rwatson $
38101099Srwatson */
39101099Srwatson
40101099Srwatson/*
41101099Srwatson * Developed by the TrustedBSD Project.
42101099Srwatson * Biba fixed label mandatory integrity policy.
43101099Srwatson */
44101099Srwatson
45101099Srwatson#include <sys/types.h>
46101099Srwatson#include <sys/param.h>
47101099Srwatson#include <sys/acl.h>
48101099Srwatson#include <sys/conf.h>
49101099Srwatson#include <sys/kernel.h>
50101099Srwatson#include <sys/mac.h>
51103183Sbde#include <sys/malloc.h>
52101099Srwatson#include <sys/mount.h>
53101099Srwatson#include <sys/proc.h>
54101099Srwatson#include <sys/systm.h>
55101099Srwatson#include <sys/sysproto.h>
56101099Srwatson#include <sys/sysent.h>
57101099Srwatson#include <sys/vnode.h>
58101099Srwatson#include <sys/file.h>
59101099Srwatson#include <sys/socket.h>
60101099Srwatson#include <sys/socketvar.h>
61101099Srwatson#include <sys/pipe.h>
62101099Srwatson#include <sys/sysctl.h>
63101099Srwatson
64101099Srwatson#include <fs/devfs/devfs.h>
65101099Srwatson
66101099Srwatson#include <net/bpfdesc.h>
67101099Srwatson#include <net/if.h>
68101099Srwatson#include <net/if_types.h>
69101099Srwatson#include <net/if_var.h>
70101099Srwatson
71101099Srwatson#include <netinet/in.h>
72101099Srwatson#include <netinet/ip_var.h>
73101099Srwatson
74101099Srwatson#include <vm/vm.h>
75101099Srwatson
76101099Srwatson#include <sys/mac_policy.h>
77101099Srwatson
78101099Srwatson#include <security/mac_biba/mac_biba.h>
79101099Srwatson
80101099SrwatsonSYSCTL_DECL(_security_mac);
81101099Srwatson
82101099SrwatsonSYSCTL_NODE(_security_mac, OID_AUTO, biba, CTLFLAG_RW, 0,
83101099Srwatson    "TrustedBSD mac_biba policy controls");
84101099Srwatson
85101099Srwatsonstatic int	mac_biba_enabled = 0;
86101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, enabled, CTLFLAG_RW,
87101099Srwatson    &mac_biba_enabled, 0, "Enforce MAC/Biba policy");
88102980SrwatsonTUNABLE_INT("security.mac.biba.enabled", &mac_biba_enabled);
89101099Srwatson
90101099Srwatsonstatic int	destroyed_not_inited;
91101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, destroyed_not_inited, CTLFLAG_RD,
92101099Srwatson    &destroyed_not_inited, 0, "Count of labels destroyed but not inited");
93101099Srwatson
94101099Srwatsonstatic int	trust_all_interfaces = 0;
95101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, trust_all_interfaces, CTLFLAG_RD,
96101099Srwatson    &trust_all_interfaces, 0, "Consider all interfaces 'trusted' by MAC/Biba");
97101099SrwatsonTUNABLE_INT("security.mac.biba.trust_all_interfaces", &trust_all_interfaces);
98101099Srwatson
99101099Srwatsonstatic char	trusted_interfaces[128];
100101099SrwatsonSYSCTL_STRING(_security_mac_biba, OID_AUTO, trusted_interfaces, CTLFLAG_RD,
101101099Srwatson    trusted_interfaces, 0, "Interfaces considered 'trusted' by MAC/Biba");
102101099SrwatsonTUNABLE_STR("security.mac.biba.trusted_interfaces", trusted_interfaces,
103101099Srwatson    sizeof(trusted_interfaces));
104101099Srwatson
105105606Srwatsonstatic int	ptys_equal = 0;
106105606SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, ptys_equal, CTLFLAG_RW,
107105606Srwatson    &ptys_equal, 0, "Label pty devices as biba/equal on create");
108105606SrwatsonTUNABLE_INT("security.mac.biba.ptys_equal", &ptys_equal);
109105606Srwatson
110101099Srwatsonstatic int	mac_biba_revocation_enabled = 0;
111101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, revocation_enabled, CTLFLAG_RW,
112101099Srwatson    &mac_biba_revocation_enabled, 0, "Revoke access to objects on relabel");
113101099SrwatsonTUNABLE_INT("security.mac.biba.revocation_enabled",
114101099Srwatson    &mac_biba_revocation_enabled);
115101099Srwatson
116101099Srwatsonstatic int	mac_biba_slot;
117101099Srwatson#define	SLOT(l)	((struct mac_biba *)LABEL_TO_SLOT((l), mac_biba_slot).l_ptr)
118101099Srwatson
119101099SrwatsonMALLOC_DEFINE(M_MACBIBA, "biba label", "MAC/Biba labels");
120101099Srwatson
121101099Srwatsonstatic int	mac_biba_check_vnode_open(struct ucred *cred, struct vnode *vp,
122101099Srwatson		    struct label *vnodelabel, mode_t acc_mode);
123101099Srwatson
124101099Srwatsonstatic struct mac_biba *
125104514Srwatsonbiba_alloc(int flag)
126101099Srwatson{
127101099Srwatson	struct mac_biba *mac_biba;
128101099Srwatson
129104514Srwatson	mac_biba = malloc(sizeof(struct mac_biba), M_MACBIBA, M_ZERO | flag);
130101099Srwatson
131101099Srwatson	return (mac_biba);
132101099Srwatson}
133101099Srwatson
134101099Srwatsonstatic void
135101099Srwatsonbiba_free(struct mac_biba *mac_biba)
136101099Srwatson{
137101099Srwatson
138101099Srwatson	if (mac_biba != NULL)
139101099Srwatson		free(mac_biba, M_MACBIBA);
140101099Srwatson	else
141101099Srwatson		atomic_add_int(&destroyed_not_inited, 1);
142101099Srwatson}
143101099Srwatson
144101099Srwatsonstatic int
145105634Srwatsonbiba_atmostflags(struct mac_biba *mac_biba, int flags)
146105634Srwatson{
147105634Srwatson
148105634Srwatson	if ((mac_biba->mb_flags & flags) != mac_biba->mb_flags)
149105634Srwatson		return (EINVAL);
150105634Srwatson	return (0);
151105634Srwatson}
152105634Srwatson
153105634Srwatsonstatic int
154101099Srwatsonmac_biba_dominate_element(struct mac_biba_element *a,
155101099Srwatson    struct mac_biba_element *b)
156101099Srwatson{
157101099Srwatson
158101099Srwatson	switch(a->mbe_type) {
159101099Srwatson	case MAC_BIBA_TYPE_EQUAL:
160101099Srwatson	case MAC_BIBA_TYPE_HIGH:
161101099Srwatson		return (1);
162101099Srwatson
163101099Srwatson	case MAC_BIBA_TYPE_LOW:
164101099Srwatson		switch (b->mbe_type) {
165101099Srwatson		case MAC_BIBA_TYPE_GRADE:
166101099Srwatson		case MAC_BIBA_TYPE_HIGH:
167101099Srwatson			return (0);
168101099Srwatson
169101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
170101099Srwatson		case MAC_BIBA_TYPE_LOW:
171101099Srwatson			return (1);
172101099Srwatson
173101099Srwatson		default:
174101099Srwatson			panic("mac_biba_dominate_element: b->mbe_type invalid");
175101099Srwatson		}
176101099Srwatson
177101099Srwatson	case MAC_BIBA_TYPE_GRADE:
178101099Srwatson		switch (b->mbe_type) {
179101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
180101099Srwatson		case MAC_BIBA_TYPE_LOW:
181101099Srwatson			return (1);
182101099Srwatson
183101099Srwatson		case MAC_BIBA_TYPE_HIGH:
184101099Srwatson			return (0);
185101099Srwatson
186101099Srwatson		case MAC_BIBA_TYPE_GRADE:
187101099Srwatson			return (a->mbe_grade >= b->mbe_grade);
188101099Srwatson
189101099Srwatson		default:
190101099Srwatson			panic("mac_biba_dominate_element: b->mbe_type invalid");
191101099Srwatson		}
192101099Srwatson
193101099Srwatson	default:
194101099Srwatson		panic("mac_biba_dominate_element: a->mbe_type invalid");
195101099Srwatson	}
196101099Srwatson
197101099Srwatson	return (0);
198101099Srwatson}
199101099Srwatson
200101099Srwatsonstatic int
201101099Srwatsonmac_biba_range_in_range(struct mac_biba *rangea, struct mac_biba *rangeb)
202101099Srwatson{
203101099Srwatson
204101099Srwatson	return (mac_biba_dominate_element(&rangeb->mb_rangehigh,
205101099Srwatson	    &rangea->mb_rangehigh) &&
206101099Srwatson	    mac_biba_dominate_element(&rangea->mb_rangelow,
207101099Srwatson	    &rangeb->mb_rangelow));
208101099Srwatson}
209101099Srwatson
210101099Srwatsonstatic int
211101099Srwatsonmac_biba_single_in_range(struct mac_biba *single, struct mac_biba *range)
212101099Srwatson{
213101099Srwatson
214103750Srwatson	KASSERT((single->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
215101099Srwatson	    ("mac_biba_single_in_range: a not single"));
216103750Srwatson	KASSERT((range->mb_flags & MAC_BIBA_FLAG_RANGE) != 0,
217101099Srwatson	    ("mac_biba_single_in_range: b not range"));
218101099Srwatson
219101099Srwatson	return (mac_biba_dominate_element(&range->mb_rangehigh,
220101099Srwatson	    &single->mb_single) &&
221101099Srwatson	    mac_biba_dominate_element(&single->mb_single,
222101099Srwatson	    &range->mb_rangelow));
223101099Srwatson
224101099Srwatson	return (1);
225101099Srwatson}
226101099Srwatson
227101099Srwatsonstatic int
228101099Srwatsonmac_biba_dominate_single(struct mac_biba *a, struct mac_biba *b)
229101099Srwatson{
230101099Srwatson	KASSERT((a->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
231101099Srwatson	    ("mac_biba_dominate_single: a not single"));
232101099Srwatson	KASSERT((b->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
233101099Srwatson	    ("mac_biba_dominate_single: b not single"));
234101099Srwatson
235101099Srwatson	return (mac_biba_dominate_element(&a->mb_single, &b->mb_single));
236101099Srwatson}
237101099Srwatson
238101099Srwatsonstatic int
239101099Srwatsonmac_biba_equal_element(struct mac_biba_element *a, struct mac_biba_element *b)
240101099Srwatson{
241101099Srwatson
242101099Srwatson	if (a->mbe_type == MAC_BIBA_TYPE_EQUAL ||
243101099Srwatson	    b->mbe_type == MAC_BIBA_TYPE_EQUAL)
244101099Srwatson		return (1);
245101099Srwatson
246101099Srwatson	return (a->mbe_type == b->mbe_type && a->mbe_grade == b->mbe_grade);
247101099Srwatson}
248101099Srwatson
249101099Srwatsonstatic int
250101099Srwatsonmac_biba_equal_single(struct mac_biba *a, struct mac_biba *b)
251101099Srwatson{
252101099Srwatson
253101099Srwatson	KASSERT((a->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
254101099Srwatson	    ("mac_biba_equal_single: a not single"));
255101099Srwatson	KASSERT((b->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
256101099Srwatson	    ("mac_biba_equal_single: b not single"));
257101099Srwatson
258101099Srwatson	return (mac_biba_equal_element(&a->mb_single, &b->mb_single));
259101099Srwatson}
260101099Srwatson
261101099Srwatsonstatic int
262105634Srwatsonmac_biba_contains_equal(struct mac_biba *mac_biba)
263105634Srwatson{
264105634Srwatson
265105634Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE)
266105634Srwatson		if (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_EQUAL)
267105634Srwatson			return (1);
268105634Srwatson
269105634Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
270105634Srwatson		if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL)
271105634Srwatson			return (1);
272105634Srwatson		if (mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL)
273105634Srwatson		return (1);
274105634Srwatson	}
275105634Srwatson
276105634Srwatson	return (0);
277105634Srwatson}
278105634Srwatson
279105634Srwatsonstatic int
280105634Srwatsonmac_biba_subject_equal_ok(struct mac_biba *mac_biba)
281105634Srwatson{
282105634Srwatson
283105634Srwatson	KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAGS_BOTH) ==
284105634Srwatson	    MAC_BIBA_FLAGS_BOTH,
285105634Srwatson	    ("mac_biba_subject_equal_ok: subject doesn't have both labels"));
286105634Srwatson
287105634Srwatson	/* If the single is EQUAL, it's ok. */
288105634Srwatson	if (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_EQUAL)
289105634Srwatson		return (0);
290105634Srwatson
291105634Srwatson	/* If either range endpoint is EQUAL, it's ok. */
292105634Srwatson	if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL ||
293105634Srwatson	    mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL)
294105634Srwatson		return (0);
295105634Srwatson
296105634Srwatson	/* If the range is low-high, it's ok. */
297105634Srwatson	if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_LOW &&
298105634Srwatson	    mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_HIGH)
299105634Srwatson		return (0);
300105634Srwatson
301105634Srwatson	/* It's not ok. */
302105634Srwatson	return (EPERM);
303105634Srwatson}
304105634Srwatson
305105634Srwatsonstatic int
306101099Srwatsonmac_biba_valid(struct mac_biba *mac_biba)
307101099Srwatson{
308101099Srwatson
309101099Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) {
310101099Srwatson		switch (mac_biba->mb_single.mbe_type) {
311101099Srwatson		case MAC_BIBA_TYPE_GRADE:
312101099Srwatson			break;
313101099Srwatson
314101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
315101099Srwatson		case MAC_BIBA_TYPE_HIGH:
316101099Srwatson		case MAC_BIBA_TYPE_LOW:
317101099Srwatson			if (mac_biba->mb_single.mbe_grade != 0)
318101099Srwatson				return (EINVAL);
319101099Srwatson			break;
320101099Srwatson
321101099Srwatson		default:
322101099Srwatson			return (EINVAL);
323101099Srwatson		}
324101099Srwatson	} else {
325101099Srwatson		if (mac_biba->mb_single.mbe_type != MAC_BIBA_TYPE_UNDEF)
326101099Srwatson			return (EINVAL);
327101099Srwatson	}
328101099Srwatson
329101099Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
330101099Srwatson		switch (mac_biba->mb_rangelow.mbe_type) {
331101099Srwatson		case MAC_BIBA_TYPE_GRADE:
332101099Srwatson			break;
333101099Srwatson
334101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
335101099Srwatson		case MAC_BIBA_TYPE_HIGH:
336101099Srwatson		case MAC_BIBA_TYPE_LOW:
337101099Srwatson			if (mac_biba->mb_rangelow.mbe_grade != 0)
338101099Srwatson				return (EINVAL);
339101099Srwatson			break;
340101099Srwatson
341101099Srwatson		default:
342101099Srwatson			return (EINVAL);
343101099Srwatson		}
344101099Srwatson
345101099Srwatson		switch (mac_biba->mb_rangehigh.mbe_type) {
346101099Srwatson		case MAC_BIBA_TYPE_GRADE:
347101099Srwatson			break;
348101099Srwatson
349101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
350101099Srwatson		case MAC_BIBA_TYPE_HIGH:
351101099Srwatson		case MAC_BIBA_TYPE_LOW:
352101099Srwatson			if (mac_biba->mb_rangehigh.mbe_grade != 0)
353101099Srwatson				return (EINVAL);
354101099Srwatson			break;
355101099Srwatson
356101099Srwatson		default:
357101099Srwatson			return (EINVAL);
358101099Srwatson		}
359101099Srwatson		if (!mac_biba_dominate_element(&mac_biba->mb_rangehigh,
360101099Srwatson		    &mac_biba->mb_rangelow))
361101099Srwatson			return (EINVAL);
362101099Srwatson	} else {
363101099Srwatson		if (mac_biba->mb_rangelow.mbe_type != MAC_BIBA_TYPE_UNDEF ||
364101099Srwatson		    mac_biba->mb_rangehigh.mbe_type != MAC_BIBA_TYPE_UNDEF)
365101099Srwatson			return (EINVAL);
366101099Srwatson	}
367101099Srwatson
368101099Srwatson	return (0);
369101099Srwatson}
370101099Srwatson
371101099Srwatsonstatic void
372101099Srwatsonmac_biba_set_range(struct mac_biba *mac_biba, u_short typelow,
373101099Srwatson    u_short gradelow, u_short typehigh, u_short gradehigh)
374101099Srwatson{
375101099Srwatson
376101099Srwatson	mac_biba->mb_rangelow.mbe_type = typelow;
377101099Srwatson	mac_biba->mb_rangelow.mbe_grade = gradelow;
378101099Srwatson	mac_biba->mb_rangehigh.mbe_type = typehigh;
379101099Srwatson	mac_biba->mb_rangehigh.mbe_grade = gradehigh;
380101099Srwatson	mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE;
381101099Srwatson}
382101099Srwatson
383101099Srwatsonstatic void
384101099Srwatsonmac_biba_set_single(struct mac_biba *mac_biba, u_short type, u_short grade)
385101099Srwatson{
386101099Srwatson
387101099Srwatson	mac_biba->mb_single.mbe_type = type;
388101099Srwatson	mac_biba->mb_single.mbe_grade = grade;
389101099Srwatson	mac_biba->mb_flags |= MAC_BIBA_FLAG_SINGLE;
390101099Srwatson}
391101099Srwatson
392101099Srwatsonstatic void
393101099Srwatsonmac_biba_copy_range(struct mac_biba *labelfrom, struct mac_biba *labelto)
394101099Srwatson{
395101099Srwatson	KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_RANGE) != 0,
396101099Srwatson	    ("mac_biba_copy_range: labelfrom not range"));
397101099Srwatson
398101099Srwatson	labelto->mb_rangelow = labelfrom->mb_rangelow;
399101099Srwatson	labelto->mb_rangehigh = labelfrom->mb_rangehigh;
400101099Srwatson	labelto->mb_flags |= MAC_BIBA_FLAG_RANGE;
401101099Srwatson}
402101099Srwatson
403101099Srwatsonstatic void
404101099Srwatsonmac_biba_copy_single(struct mac_biba *labelfrom, struct mac_biba *labelto)
405101099Srwatson{
406101099Srwatson
407101099Srwatson	KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
408101099Srwatson	    ("mac_biba_copy_single: labelfrom not single"));
409101099Srwatson
410101099Srwatson	labelto->mb_single = labelfrom->mb_single;
411101099Srwatson	labelto->mb_flags |= MAC_BIBA_FLAG_SINGLE;
412101099Srwatson}
413101099Srwatson
414101099Srwatsonstatic void
415101099Srwatsonmac_biba_copy_single_to_range(struct mac_biba *labelfrom,
416101099Srwatson    struct mac_biba *labelto)
417101099Srwatson{
418101099Srwatson
419101099Srwatson	KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
420101099Srwatson	    ("mac_biba_copy_single_to_range: labelfrom not single"));
421101099Srwatson
422101099Srwatson	labelto->mb_rangelow = labelfrom->mb_single;
423101099Srwatson	labelto->mb_rangehigh = labelfrom->mb_single;
424101099Srwatson	labelto->mb_flags |= MAC_BIBA_FLAG_RANGE;
425101099Srwatson}
426101099Srwatson
427101099Srwatson/*
428101099Srwatson * Policy module operations.
429101099Srwatson */
430101099Srwatsonstatic void
431101099Srwatsonmac_biba_destroy(struct mac_policy_conf *conf)
432101099Srwatson{
433101099Srwatson
434101099Srwatson}
435101099Srwatson
436101099Srwatsonstatic void
437101099Srwatsonmac_biba_init(struct mac_policy_conf *conf)
438101099Srwatson{
439101099Srwatson
440101099Srwatson}
441101099Srwatson
442101099Srwatson/*
443101099Srwatson * Label operations.
444101099Srwatson */
445101099Srwatsonstatic void
446104514Srwatsonmac_biba_init_label(struct label *label)
447101099Srwatson{
448101099Srwatson
449101099Srwatson	SLOT(label) = biba_alloc(M_WAITOK);
450101099Srwatson}
451101099Srwatson
452101099Srwatsonstatic int
453104514Srwatsonmac_biba_init_label_waitcheck(struct label *label, int flag)
454101099Srwatson{
455101099Srwatson
456104514Srwatson	SLOT(label) = biba_alloc(flag);
457101099Srwatson	if (SLOT(label) == NULL)
458101099Srwatson		return (ENOMEM);
459101099Srwatson
460101099Srwatson	return (0);
461101099Srwatson}
462101099Srwatson
463101099Srwatsonstatic void
464104514Srwatsonmac_biba_destroy_label(struct label *label)
465101099Srwatson{
466101099Srwatson
467101099Srwatson	biba_free(SLOT(label));
468101099Srwatson	SLOT(label) = NULL;
469101099Srwatson}
470101099Srwatson
471101099Srwatsonstatic int
472101099Srwatsonmac_biba_externalize(struct label *label, struct mac *extmac)
473101099Srwatson{
474101099Srwatson	struct mac_biba *mac_biba;
475101099Srwatson
476101099Srwatson	mac_biba = SLOT(label);
477101099Srwatson
478101099Srwatson	if (mac_biba == NULL) {
479101099Srwatson		printf("mac_biba_externalize: NULL pointer\n");
480101099Srwatson		return (0);
481101099Srwatson	}
482101099Srwatson
483101099Srwatson	extmac->m_biba = *mac_biba;
484101099Srwatson
485101099Srwatson	return (0);
486101099Srwatson}
487101099Srwatson
488101099Srwatsonstatic int
489101099Srwatsonmac_biba_internalize(struct label *label, struct mac *extmac)
490101099Srwatson{
491101099Srwatson	struct mac_biba *mac_biba;
492101099Srwatson	int error;
493101099Srwatson
494101099Srwatson	mac_biba = SLOT(label);
495101099Srwatson
496101099Srwatson	error = mac_biba_valid(mac_biba);
497101099Srwatson	if (error)
498101099Srwatson		return (error);
499101099Srwatson
500101099Srwatson	*mac_biba = extmac->m_biba;
501101099Srwatson
502101099Srwatson	return (0);
503101099Srwatson}
504101099Srwatson
505101099Srwatson/*
506101099Srwatson * Labeling event operations: file system objects, and things that look
507101099Srwatson * a lot like file system objects.
508101099Srwatson */
509101099Srwatsonstatic void
510101099Srwatsonmac_biba_create_devfs_device(dev_t dev, struct devfs_dirent *devfs_dirent,
511101099Srwatson    struct label *label)
512101099Srwatson{
513101099Srwatson	struct mac_biba *mac_biba;
514101099Srwatson	int biba_type;
515101099Srwatson
516101099Srwatson	mac_biba = SLOT(label);
517101099Srwatson	if (strcmp(dev->si_name, "null") == 0 ||
518101099Srwatson	    strcmp(dev->si_name, "zero") == 0 ||
519101099Srwatson	    strcmp(dev->si_name, "random") == 0 ||
520101099Srwatson	    strncmp(dev->si_name, "fd/", strlen("fd/")) == 0)
521101099Srwatson		biba_type = MAC_BIBA_TYPE_EQUAL;
522105606Srwatson	else if (ptys_equal &&
523105606Srwatson	    (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 ||
524105606Srwatson	    strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0))
525105606Srwatson		biba_type = MAC_BIBA_TYPE_EQUAL;
526101099Srwatson	else
527101099Srwatson		biba_type = MAC_BIBA_TYPE_HIGH;
528101099Srwatson	mac_biba_set_single(mac_biba, biba_type, 0);
529101099Srwatson}
530101099Srwatson
531101099Srwatsonstatic void
532101099Srwatsonmac_biba_create_devfs_directory(char *dirname, int dirnamelen,
533101099Srwatson    struct devfs_dirent *devfs_dirent, struct label *label)
534101099Srwatson{
535101099Srwatson	struct mac_biba *mac_biba;
536101099Srwatson
537101099Srwatson	mac_biba = SLOT(label);
538101099Srwatson	mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0);
539101099Srwatson}
540101099Srwatson
541101099Srwatsonstatic void
542104535Srwatsonmac_biba_create_devfs_symlink(struct ucred *cred, struct devfs_dirent *dd,
543104535Srwatson    struct label *ddlabel, struct devfs_dirent *de, struct label *delabel)
544104535Srwatson{
545104535Srwatson	struct mac_biba *source, *dest;
546104535Srwatson
547104535Srwatson	source = SLOT(&cred->cr_label);
548104535Srwatson	dest = SLOT(delabel);
549104535Srwatson
550104535Srwatson	mac_biba_copy_single(source, dest);
551104535Srwatson}
552104535Srwatson
553104535Srwatsonstatic void
554101099Srwatsonmac_biba_create_devfs_vnode(struct devfs_dirent *devfs_dirent,
555101099Srwatson    struct label *direntlabel, struct vnode *vp, struct label *vnodelabel)
556101099Srwatson{
557101099Srwatson	struct mac_biba *source, *dest;
558101099Srwatson
559101099Srwatson	source = SLOT(direntlabel);
560101099Srwatson	dest = SLOT(vnodelabel);
561101099Srwatson	mac_biba_copy_single(source, dest);
562101099Srwatson}
563101099Srwatson
564101099Srwatsonstatic void
565101099Srwatsonmac_biba_create_vnode(struct ucred *cred, struct vnode *parent,
566101099Srwatson    struct label *parentlabel, struct vnode *child, struct label *childlabel)
567101099Srwatson{
568101099Srwatson	struct mac_biba *source, *dest;
569101099Srwatson
570101099Srwatson	source = SLOT(&cred->cr_label);
571101099Srwatson	dest = SLOT(childlabel);
572101099Srwatson
573101099Srwatson	mac_biba_copy_single(source, dest);
574101099Srwatson}
575101099Srwatson
576101099Srwatsonstatic void
577101099Srwatsonmac_biba_create_mount(struct ucred *cred, struct mount *mp,
578101099Srwatson    struct label *mntlabel, struct label *fslabel)
579101099Srwatson{
580101099Srwatson	struct mac_biba *source, *dest;
581101099Srwatson
582101099Srwatson	source = SLOT(&cred->cr_label);
583101099Srwatson	dest = SLOT(mntlabel);
584101099Srwatson	mac_biba_copy_single(source, dest);
585101099Srwatson	dest = SLOT(fslabel);
586101099Srwatson	mac_biba_copy_single(source, dest);
587101099Srwatson}
588101099Srwatson
589101099Srwatsonstatic void
590101099Srwatsonmac_biba_create_root_mount(struct ucred *cred, struct mount *mp,
591101099Srwatson    struct label *mntlabel, struct label *fslabel)
592101099Srwatson{
593101099Srwatson	struct mac_biba *mac_biba;
594101099Srwatson
595101099Srwatson	/* Always mount root as high integrity. */
596101099Srwatson	mac_biba = SLOT(fslabel);
597101099Srwatson	mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0);
598101099Srwatson	mac_biba = SLOT(mntlabel);
599101099Srwatson	mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0);
600101099Srwatson}
601101099Srwatson
602101099Srwatsonstatic void
603101099Srwatsonmac_biba_relabel_vnode(struct ucred *cred, struct vnode *vp,
604101099Srwatson    struct label *vnodelabel, struct label *label)
605101099Srwatson{
606101099Srwatson	struct mac_biba *source, *dest;
607101099Srwatson
608101099Srwatson	source = SLOT(label);
609101099Srwatson	dest = SLOT(vnodelabel);
610101099Srwatson
611101099Srwatson	mac_biba_copy_single(source, dest);
612101099Srwatson}
613101099Srwatson
614101099Srwatsonstatic void
615101099Srwatsonmac_biba_update_devfsdirent(struct devfs_dirent *devfs_dirent,
616101099Srwatson    struct label *direntlabel, struct vnode *vp, struct label *vnodelabel)
617101099Srwatson{
618101099Srwatson	struct mac_biba *source, *dest;
619101099Srwatson
620101099Srwatson	source = SLOT(vnodelabel);
621101099Srwatson	dest = SLOT(direntlabel);
622101099Srwatson
623101099Srwatson	mac_biba_copy_single(source, dest);
624101099Srwatson}
625101099Srwatson
626101099Srwatsonstatic void
627101099Srwatsonmac_biba_update_procfsvnode(struct vnode *vp, struct label *vnodelabel,
628101099Srwatson    struct ucred *cred)
629101099Srwatson{
630101099Srwatson	struct mac_biba *source, *dest;
631101099Srwatson
632101099Srwatson	source = SLOT(&cred->cr_label);
633101099Srwatson	dest = SLOT(vnodelabel);
634101099Srwatson
635101099Srwatson	/*
636101099Srwatson	 * Only copy the single, not the range, since vnodes only have
637101099Srwatson	 * a single.
638101099Srwatson	 */
639101099Srwatson	mac_biba_copy_single(source, dest);
640101099Srwatson}
641101099Srwatson
642101099Srwatsonstatic int
643101099Srwatsonmac_biba_update_vnode_from_externalized(struct vnode *vp,
644101099Srwatson    struct label *vnodelabel, struct mac *extmac)
645101099Srwatson{
646101099Srwatson	struct mac_biba *source, *dest;
647101099Srwatson	int error;
648101099Srwatson
649101099Srwatson	source = &extmac->m_biba;
650101099Srwatson	dest = SLOT(vnodelabel);
651101099Srwatson
652101099Srwatson	error = mac_biba_valid(source);
653101099Srwatson	if (error)
654101099Srwatson		return (error);
655101099Srwatson
656101099Srwatson	if ((source->mb_flags & MAC_BIBA_FLAGS_BOTH) != MAC_BIBA_FLAG_SINGLE)
657101099Srwatson		return (EINVAL);
658101099Srwatson
659101099Srwatson	mac_biba_copy_single(source, dest);
660101099Srwatson
661101099Srwatson	return (0);
662101099Srwatson}
663101099Srwatson
664101099Srwatsonstatic void
665101099Srwatsonmac_biba_update_vnode_from_mount(struct vnode *vp, struct label *vnodelabel,
666101099Srwatson    struct mount *mp, struct label *fslabel)
667101099Srwatson{
668101099Srwatson	struct mac_biba *source, *dest;
669101099Srwatson
670101099Srwatson	source = SLOT(fslabel);
671101099Srwatson	dest = SLOT(vnodelabel);
672101099Srwatson
673101099Srwatson	mac_biba_copy_single(source, dest);
674101099Srwatson}
675101099Srwatson
676101099Srwatson/*
677101099Srwatson * Labeling event operations: IPC object.
678101099Srwatson */
679101099Srwatsonstatic void
680101099Srwatsonmac_biba_create_mbuf_from_socket(struct socket *so, struct label *socketlabel,
681101099Srwatson    struct mbuf *m, struct label *mbuflabel)
682101099Srwatson{
683101099Srwatson	struct mac_biba *source, *dest;
684101099Srwatson
685101099Srwatson	source = SLOT(socketlabel);
686101099Srwatson	dest = SLOT(mbuflabel);
687101099Srwatson
688101099Srwatson	mac_biba_copy_single(source, dest);
689101099Srwatson}
690101099Srwatson
691101099Srwatsonstatic void
692101099Srwatsonmac_biba_create_socket(struct ucred *cred, struct socket *socket,
693101099Srwatson    struct label *socketlabel)
694101099Srwatson{
695101099Srwatson	struct mac_biba *source, *dest;
696101099Srwatson
697101099Srwatson	source = SLOT(&cred->cr_label);
698101099Srwatson	dest = SLOT(socketlabel);
699101099Srwatson
700101099Srwatson	mac_biba_copy_single(source, dest);
701101099Srwatson	mac_biba_copy_single_to_range(source, dest);
702101099Srwatson}
703101099Srwatson
704101099Srwatsonstatic void
705101099Srwatsonmac_biba_create_pipe(struct ucred *cred, struct pipe *pipe,
706101099Srwatson    struct label *pipelabel)
707101099Srwatson{
708101099Srwatson	struct mac_biba *source, *dest;
709101099Srwatson
710101099Srwatson	source = SLOT(&cred->cr_label);
711101099Srwatson	dest = SLOT(pipelabel);
712101099Srwatson
713101099Srwatson	mac_biba_copy_single(source, dest);
714101099Srwatson}
715101099Srwatson
716101099Srwatsonstatic void
717101099Srwatsonmac_biba_create_socket_from_socket(struct socket *oldsocket,
718101099Srwatson    struct label *oldsocketlabel, struct socket *newsocket,
719101099Srwatson    struct label *newsocketlabel)
720101099Srwatson{
721101099Srwatson	struct mac_biba *source, *dest;
722101099Srwatson
723101099Srwatson	source = SLOT(oldsocketlabel);
724101099Srwatson	dest = SLOT(newsocketlabel);
725101099Srwatson
726101099Srwatson	mac_biba_copy_single(source, dest);
727101099Srwatson	mac_biba_copy_range(source, dest);
728101099Srwatson}
729101099Srwatson
730101099Srwatsonstatic void
731101099Srwatsonmac_biba_relabel_socket(struct ucred *cred, struct socket *socket,
732101099Srwatson    struct label *socketlabel, struct label *newlabel)
733101099Srwatson{
734101099Srwatson	struct mac_biba *source, *dest;
735101099Srwatson
736101099Srwatson	source = SLOT(newlabel);
737101099Srwatson	dest = SLOT(socketlabel);
738101099Srwatson
739101099Srwatson	mac_biba_copy_single(source, dest);
740101099Srwatson	mac_biba_copy_range(source, dest);
741101099Srwatson}
742101099Srwatson
743101099Srwatsonstatic void
744101099Srwatsonmac_biba_relabel_pipe(struct ucred *cred, struct pipe *pipe,
745101099Srwatson    struct label *pipelabel, struct label *newlabel)
746101099Srwatson{
747101099Srwatson	struct mac_biba *source, *dest;
748101099Srwatson
749101099Srwatson	source = SLOT(newlabel);
750101099Srwatson	dest = SLOT(pipelabel);
751101099Srwatson
752101099Srwatson	mac_biba_copy_single(source, dest);
753101099Srwatson}
754101099Srwatson
755101099Srwatsonstatic void
756101099Srwatsonmac_biba_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel,
757101099Srwatson    struct socket *socket, struct label *socketpeerlabel)
758101099Srwatson{
759101099Srwatson	struct mac_biba *source, *dest;
760101099Srwatson
761101099Srwatson	source = SLOT(mbuflabel);
762101099Srwatson	dest = SLOT(socketpeerlabel);
763101099Srwatson
764101099Srwatson	mac_biba_copy_single(source, dest);
765101099Srwatson}
766101099Srwatson
767101099Srwatson/*
768101099Srwatson * Labeling event operations: network objects.
769101099Srwatson */
770101099Srwatsonstatic void
771101099Srwatsonmac_biba_set_socket_peer_from_socket(struct socket *oldsocket,
772101099Srwatson    struct label *oldsocketlabel, struct socket *newsocket,
773101099Srwatson    struct label *newsocketpeerlabel)
774101099Srwatson{
775101099Srwatson	struct mac_biba *source, *dest;
776101099Srwatson
777101099Srwatson	source = SLOT(oldsocketlabel);
778101099Srwatson	dest = SLOT(newsocketpeerlabel);
779101099Srwatson
780101099Srwatson	mac_biba_copy_single(source, dest);
781101099Srwatson}
782101099Srwatson
783101099Srwatsonstatic void
784101099Srwatsonmac_biba_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d,
785101099Srwatson    struct label *bpflabel)
786101099Srwatson{
787101099Srwatson	struct mac_biba *source, *dest;
788101099Srwatson
789101099Srwatson	source = SLOT(&cred->cr_label);
790101099Srwatson	dest = SLOT(bpflabel);
791101099Srwatson
792101099Srwatson	mac_biba_copy_single(source, dest);
793101099Srwatson}
794101099Srwatson
795101099Srwatsonstatic void
796101099Srwatsonmac_biba_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel)
797101099Srwatson{
798101099Srwatson	char tifname[IFNAMSIZ], ifname[IFNAMSIZ], *p, *q;
799101099Srwatson	char tiflist[sizeof(trusted_interfaces)];
800101099Srwatson	struct mac_biba *dest;
801101099Srwatson	int len, grade;
802101099Srwatson
803101099Srwatson	dest = SLOT(ifnetlabel);
804101099Srwatson
805101099Srwatson	if (ifnet->if_type == IFT_LOOP) {
806101099Srwatson		grade = MAC_BIBA_TYPE_EQUAL;
807101099Srwatson		goto set;
808101099Srwatson	}
809101099Srwatson
810101099Srwatson	if (trust_all_interfaces) {
811101099Srwatson		grade = MAC_BIBA_TYPE_HIGH;
812101099Srwatson		goto set;
813101099Srwatson	}
814101099Srwatson
815101099Srwatson	grade = MAC_BIBA_TYPE_LOW;
816101099Srwatson
817101099Srwatson	if (trusted_interfaces[0] == '\0' ||
818101099Srwatson	    !strvalid(trusted_interfaces, sizeof(trusted_interfaces)))
819101099Srwatson		goto set;
820101099Srwatson
821101099Srwatson	for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++)
822101099Srwatson		if(*p != ' ' && *p != '\t')
823101099Srwatson			*q = *p;
824101099Srwatson
825101099Srwatson	snprintf(ifname, IFNAMSIZ, "%s%d", ifnet->if_name, ifnet->if_unit);
826101099Srwatson
827101099Srwatson	for (p = q = tiflist;; p++) {
828101099Srwatson		if (*p == ',' || *p == '\0') {
829101099Srwatson			len = p - q;
830101099Srwatson			if (len < IFNAMSIZ) {
831101099Srwatson				bzero(tifname, sizeof(tifname));
832101099Srwatson				bcopy(q, tifname, len);
833101099Srwatson				if (strcmp(tifname, ifname) == 0) {
834101099Srwatson					grade = MAC_BIBA_TYPE_HIGH;
835101099Srwatson					break;
836101099Srwatson				}
837101099Srwatson			}
838101099Srwatson			if (*p == '\0')
839101099Srwatson				break;
840101099Srwatson			q = p + 1;
841101099Srwatson		}
842101099Srwatson	}
843101099Srwatsonset:
844101099Srwatson	mac_biba_set_single(dest, grade, 0);
845101099Srwatson	mac_biba_set_range(dest, grade, 0, grade, 0);
846101099Srwatson}
847101099Srwatson
848101099Srwatsonstatic void
849101099Srwatsonmac_biba_create_ipq(struct mbuf *fragment, struct label *fragmentlabel,
850101099Srwatson    struct ipq *ipq, struct label *ipqlabel)
851101099Srwatson{
852101099Srwatson	struct mac_biba *source, *dest;
853101099Srwatson
854101099Srwatson	source = SLOT(fragmentlabel);
855101099Srwatson	dest = SLOT(ipqlabel);
856101099Srwatson
857101099Srwatson	mac_biba_copy_single(source, dest);
858101099Srwatson}
859101099Srwatson
860101099Srwatsonstatic void
861101099Srwatsonmac_biba_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel,
862101099Srwatson    struct mbuf *datagram, struct label *datagramlabel)
863101099Srwatson{
864101099Srwatson	struct mac_biba *source, *dest;
865101099Srwatson
866101099Srwatson	source = SLOT(ipqlabel);
867101099Srwatson	dest = SLOT(datagramlabel);
868101099Srwatson
869101099Srwatson	/* Just use the head, since we require them all to match. */
870101099Srwatson	mac_biba_copy_single(source, dest);
871101099Srwatson}
872101099Srwatson
873101099Srwatsonstatic void
874101099Srwatsonmac_biba_create_fragment(struct mbuf *datagram, struct label *datagramlabel,
875101099Srwatson    struct mbuf *fragment, struct label *fragmentlabel)
876101099Srwatson{
877101099Srwatson	struct mac_biba *source, *dest;
878101099Srwatson
879101099Srwatson	source = SLOT(datagramlabel);
880101099Srwatson	dest = SLOT(fragmentlabel);
881101099Srwatson
882101099Srwatson	mac_biba_copy_single(source, dest);
883101099Srwatson}
884101099Srwatson
885101099Srwatsonstatic void
886101099Srwatsonmac_biba_create_mbuf_from_mbuf(struct mbuf *oldmbuf,
887101099Srwatson    struct label *oldmbuflabel, struct mbuf *newmbuf,
888101099Srwatson    struct label *newmbuflabel)
889101099Srwatson{
890101099Srwatson	struct mac_biba *source, *dest;
891101099Srwatson
892101099Srwatson	source = SLOT(oldmbuflabel);
893101099Srwatson	dest = SLOT(newmbuflabel);
894101099Srwatson
895101099Srwatson	mac_biba_copy_single(source, dest);
896101099Srwatson}
897101099Srwatson
898101099Srwatsonstatic void
899101099Srwatsonmac_biba_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel,
900101099Srwatson    struct mbuf *mbuf, struct label *mbuflabel)
901101099Srwatson{
902101099Srwatson	struct mac_biba *dest;
903101099Srwatson
904101099Srwatson	dest = SLOT(mbuflabel);
905101099Srwatson
906101099Srwatson	mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0);
907101099Srwatson}
908101099Srwatson
909101099Srwatsonstatic void
910101099Srwatsonmac_biba_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel,
911101099Srwatson    struct mbuf *mbuf, struct label *mbuflabel)
912101099Srwatson{
913101099Srwatson	struct mac_biba *source, *dest;
914101099Srwatson
915101099Srwatson	source = SLOT(bpflabel);
916101099Srwatson	dest = SLOT(mbuflabel);
917101099Srwatson
918101099Srwatson	mac_biba_copy_single(source, dest);
919101099Srwatson}
920101099Srwatson
921101099Srwatsonstatic void
922101099Srwatsonmac_biba_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel,
923101099Srwatson    struct mbuf *m, struct label *mbuflabel)
924101099Srwatson{
925101099Srwatson	struct mac_biba *source, *dest;
926101099Srwatson
927101099Srwatson	source = SLOT(ifnetlabel);
928101099Srwatson	dest = SLOT(mbuflabel);
929101099Srwatson
930101099Srwatson	mac_biba_copy_single(source, dest);
931101099Srwatson}
932101099Srwatson
933101099Srwatsonstatic void
934101099Srwatsonmac_biba_create_mbuf_multicast_encap(struct mbuf *oldmbuf,
935101099Srwatson    struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel,
936101099Srwatson    struct mbuf *newmbuf, struct label *newmbuflabel)
937101099Srwatson{
938101099Srwatson	struct mac_biba *source, *dest;
939101099Srwatson
940101099Srwatson	source = SLOT(oldmbuflabel);
941101099Srwatson	dest = SLOT(newmbuflabel);
942101099Srwatson
943101099Srwatson	mac_biba_copy_single(source, dest);
944101099Srwatson}
945101099Srwatson
946101099Srwatsonstatic void
947101099Srwatsonmac_biba_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel,
948101099Srwatson    struct mbuf *newmbuf, struct label *newmbuflabel)
949101099Srwatson{
950101099Srwatson	struct mac_biba *source, *dest;
951101099Srwatson
952101099Srwatson	source = SLOT(oldmbuflabel);
953101099Srwatson	dest = SLOT(newmbuflabel);
954101099Srwatson
955101099Srwatson	mac_biba_copy_single(source, dest);
956101099Srwatson}
957101099Srwatson
958101099Srwatsonstatic int
959101099Srwatsonmac_biba_fragment_match(struct mbuf *fragment, struct label *fragmentlabel,
960101099Srwatson    struct ipq *ipq, struct label *ipqlabel)
961101099Srwatson{
962101099Srwatson	struct mac_biba *a, *b;
963101099Srwatson
964101099Srwatson	a = SLOT(ipqlabel);
965101099Srwatson	b = SLOT(fragmentlabel);
966101099Srwatson
967101099Srwatson	return (mac_biba_equal_single(a, b));
968101099Srwatson}
969101099Srwatson
970101099Srwatsonstatic void
971101099Srwatsonmac_biba_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet,
972101099Srwatson    struct label *ifnetlabel, struct label *newlabel)
973101099Srwatson{
974101099Srwatson	struct mac_biba *source, *dest;
975101099Srwatson
976101099Srwatson	source = SLOT(newlabel);
977101099Srwatson	dest = SLOT(ifnetlabel);
978101099Srwatson
979101099Srwatson	mac_biba_copy_single(source, dest);
980101099Srwatson	mac_biba_copy_range(source, dest);
981101099Srwatson}
982101099Srwatson
983101099Srwatsonstatic void
984101099Srwatsonmac_biba_update_ipq(struct mbuf *fragment, struct label *fragmentlabel,
985101099Srwatson    struct ipq *ipq, struct label *ipqlabel)
986101099Srwatson{
987101099Srwatson
988101099Srwatson	/* NOOP: we only accept matching labels, so no need to update */
989101099Srwatson}
990101099Srwatson
991101099Srwatson/*
992101099Srwatson * Labeling event operations: processes.
993101099Srwatson */
994101099Srwatsonstatic void
995101099Srwatsonmac_biba_create_cred(struct ucred *cred_parent, struct ucred *cred_child)
996101099Srwatson{
997101099Srwatson	struct mac_biba *source, *dest;
998101099Srwatson
999101099Srwatson	source = SLOT(&cred_parent->cr_label);
1000101099Srwatson	dest = SLOT(&cred_child->cr_label);
1001101099Srwatson
1002101099Srwatson	mac_biba_copy_single(source, dest);
1003101099Srwatson	mac_biba_copy_range(source, dest);
1004101099Srwatson}
1005101099Srwatson
1006101099Srwatsonstatic void
1007101099Srwatsonmac_biba_execve_transition(struct ucred *old, struct ucred *new,
1008101099Srwatson    struct vnode *vp, struct mac *vnodelabel)
1009101099Srwatson{
1010101099Srwatson	struct mac_biba *source, *dest;
1011101099Srwatson
1012101099Srwatson	source = SLOT(&old->cr_label);
1013101099Srwatson	dest = SLOT(&new->cr_label);
1014101099Srwatson
1015101099Srwatson	mac_biba_copy_single(source, dest);
1016101099Srwatson	mac_biba_copy_range(source, dest);
1017101099Srwatson}
1018101099Srwatson
1019101099Srwatsonstatic int
1020101099Srwatsonmac_biba_execve_will_transition(struct ucred *old, struct vnode *vp,
1021101099Srwatson    struct mac *vnodelabel)
1022101099Srwatson{
1023101099Srwatson
1024101099Srwatson	return (0);
1025101099Srwatson}
1026101099Srwatson
1027101099Srwatsonstatic void
1028101099Srwatsonmac_biba_create_proc0(struct ucred *cred)
1029101099Srwatson{
1030101099Srwatson	struct mac_biba *dest;
1031101099Srwatson
1032101099Srwatson	dest = SLOT(&cred->cr_label);
1033101099Srwatson
1034101099Srwatson	mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0);
1035101099Srwatson	mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, MAC_BIBA_TYPE_HIGH, 0);
1036101099Srwatson}
1037101099Srwatson
1038101099Srwatsonstatic void
1039101099Srwatsonmac_biba_create_proc1(struct ucred *cred)
1040101099Srwatson{
1041101099Srwatson	struct mac_biba *dest;
1042101099Srwatson
1043101099Srwatson	dest = SLOT(&cred->cr_label);
1044101099Srwatson
1045101099Srwatson	mac_biba_set_single(dest, MAC_BIBA_TYPE_HIGH, 0);
1046101099Srwatson	mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, MAC_BIBA_TYPE_HIGH, 0);
1047101099Srwatson}
1048101099Srwatson
1049101099Srwatsonstatic void
1050101099Srwatsonmac_biba_relabel_cred(struct ucred *cred, struct label *newlabel)
1051101099Srwatson{
1052101099Srwatson	struct mac_biba *source, *dest;
1053101099Srwatson
1054101099Srwatson	source = SLOT(newlabel);
1055101099Srwatson	dest = SLOT(&cred->cr_label);
1056101099Srwatson
1057101099Srwatson	mac_biba_copy_single(source, dest);
1058101099Srwatson	mac_biba_copy_range(source, dest);
1059101099Srwatson}
1060101099Srwatson
1061101099Srwatson/*
1062101099Srwatson * Access control checks.
1063101099Srwatson */
1064101099Srwatsonstatic int
1065101099Srwatsonmac_biba_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel,
1066101099Srwatson    struct ifnet *ifnet, struct label *ifnetlabel)
1067101099Srwatson{
1068101099Srwatson	struct mac_biba *a, *b;
1069101099Srwatson
1070101099Srwatson	if (!mac_biba_enabled)
1071101099Srwatson		return (0);
1072101099Srwatson
1073101099Srwatson	a = SLOT(bpflabel);
1074101099Srwatson	b = SLOT(ifnetlabel);
1075101099Srwatson
1076101099Srwatson	if (mac_biba_equal_single(a, b))
1077101099Srwatson		return (0);
1078101099Srwatson	return (EACCES);
1079101099Srwatson}
1080101099Srwatson
1081101099Srwatsonstatic int
1082101099Srwatsonmac_biba_check_cred_relabel(struct ucred *cred, struct label *newlabel)
1083101099Srwatson{
1084101099Srwatson	struct mac_biba *subj, *new;
1085105634Srwatson	int error;
1086101099Srwatson
1087101099Srwatson	subj = SLOT(&cred->cr_label);
1088101099Srwatson	new = SLOT(newlabel);
1089101099Srwatson
1090101099Srwatson	/*
1091105634Srwatson	 * If there is a Biba label update for the credential, it may
1092105634Srwatson	 * be an update of the single, range, or both.
1093101099Srwatson	 */
1094105634Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
1095105634Srwatson	if (error)
1096105634Srwatson		return (error);
1097101099Srwatson
1098101099Srwatson	/*
1099105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
1100101099Srwatson	 */
1101105634Srwatson	if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) {
1102105634Srwatson		/*
1103105634Srwatson		 * To change the Biba single label on a credential, the
1104105634Srwatson		 * new single label must be in the current range.
1105105634Srwatson		 */
1106105634Srwatson		if (new->mb_flags & MAC_BIBA_FLAG_SINGLE &&
1107105634Srwatson		    !mac_biba_single_in_range(new, subj))
1108105634Srwatson			return (EPERM);
1109101099Srwatson
1110105634Srwatson		/*
1111105634Srwatson		 * To change the Biba range on a credential, the new
1112105634Srwatson		 * range label must be in the current range.
1113105634Srwatson		 */
1114105634Srwatson		if (new->mb_flags & MAC_BIBA_FLAG_RANGE &&
1115105634Srwatson		    !mac_biba_range_in_range(new, subj))
1116105634Srwatson			return (EPERM);
1117101099Srwatson
1118105634Srwatson		/*
1119105634Srwatson		 * To have EQUAL in any component of the new credential
1120105634Srwatson		 * Biba label, the subject must already have EQUAL in
1121105634Srwatson		 * their label.
1122105634Srwatson		 */
1123105634Srwatson		if (mac_biba_contains_equal(new)) {
1124105634Srwatson			error = mac_biba_subject_equal_ok(subj);
1125105634Srwatson			if (error)
1126105634Srwatson				return (error);
1127105634Srwatson		}
1128101099Srwatson
1129105634Srwatson		/*
1130105634Srwatson		 * XXXMAC: Additional consistency tests regarding the
1131105634Srwatson		 * single and range of the new label might be performed
1132105634Srwatson		 * here.
1133105634Srwatson		 */
1134105634Srwatson	}
1135105634Srwatson
1136101099Srwatson	return (0);
1137101099Srwatson}
1138101099Srwatson
1139101099Srwatsonstatic int
1140101099Srwatsonmac_biba_check_cred_visible(struct ucred *u1, struct ucred *u2)
1141101099Srwatson{
1142101099Srwatson	struct mac_biba *subj, *obj;
1143101099Srwatson
1144101099Srwatson	if (!mac_biba_enabled)
1145101099Srwatson		return (0);
1146101099Srwatson
1147101099Srwatson	subj = SLOT(&u1->cr_label);
1148101099Srwatson	obj = SLOT(&u2->cr_label);
1149101099Srwatson
1150101099Srwatson	/* XXX: range */
1151101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1152101099Srwatson		return (ESRCH);
1153101099Srwatson
1154101099Srwatson	return (0);
1155101099Srwatson}
1156101099Srwatson
1157101099Srwatsonstatic int
1158101099Srwatsonmac_biba_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet,
1159101099Srwatson    struct label *ifnetlabel, struct label *newlabel)
1160101099Srwatson{
1161101099Srwatson	struct mac_biba *subj, *new;
1162105634Srwatson	int error;
1163101099Srwatson
1164101099Srwatson	subj = SLOT(&cred->cr_label);
1165101099Srwatson	new = SLOT(newlabel);
1166101099Srwatson
1167105634Srwatson	/*
1168105634Srwatson	 * If there is a Biba label update for the interface, it may
1169105634Srwatson	 * be an update of the single, range, or both.
1170105634Srwatson	 */
1171105634Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
1172105634Srwatson	if (error)
1173105634Srwatson		return (error);
1174101099Srwatson
1175105634Srwatson	/*
1176105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
1177105634Srwatson	 */
1178105634Srwatson	if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) {
1179105634Srwatson		/*
1180105634Srwatson		 * Rely on the traditional superuser status for the Biba
1181105634Srwatson		 * interface relabel requirements.  XXXMAC: This will go
1182105634Srwatson		 * away.
1183105634Srwatson		 */
1184105634Srwatson		error = suser_cred(cred, 0);
1185105634Srwatson		if (error)
1186105634Srwatson			return (EPERM);
1187105634Srwatson
1188105634Srwatson		/*
1189105634Srwatson		 * XXXMAC: Additional consistency tests regarding the single
1190105634Srwatson		 * and the range of the new label might be performed here.
1191105634Srwatson		 */
1192105634Srwatson	}
1193105634Srwatson
1194105634Srwatson	return (0);
1195101099Srwatson}
1196101099Srwatson
1197103759Srwatsonstatic int
1198101099Srwatsonmac_biba_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel,
1199101099Srwatson    struct mbuf *m, struct label *mbuflabel)
1200101099Srwatson{
1201101099Srwatson	struct mac_biba *p, *i;
1202103761Srwatson
1203101099Srwatson	if (!mac_biba_enabled)
1204101099Srwatson		return (0);
1205101099Srwatson
1206101099Srwatson	p = SLOT(mbuflabel);
1207101099Srwatson	i = SLOT(ifnetlabel);
1208103759Srwatson
1209101099Srwatson	return (mac_biba_single_in_range(p, i) ? 0 : EACCES);
1210101099Srwatson}
1211101099Srwatson
1212101099Srwatsonstatic int
1213101099Srwatsonmac_biba_check_mount_stat(struct ucred *cred, struct mount *mp,
1214101099Srwatson    struct label *mntlabel)
1215101099Srwatson{
1216101099Srwatson	struct mac_biba *subj, *obj;
1217101099Srwatson
1218101099Srwatson	if (!mac_biba_enabled)
1219101099Srwatson		return (0);
1220101099Srwatson
1221101099Srwatson	subj = SLOT(&cred->cr_label);
1222101099Srwatson	obj = SLOT(mntlabel);
1223101099Srwatson
1224101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1225101099Srwatson		return (EACCES);
1226101099Srwatson
1227101099Srwatson	return (0);
1228101099Srwatson}
1229101099Srwatson
1230101099Srwatsonstatic int
1231101099Srwatsonmac_biba_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe,
1232101099Srwatson    struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data)
1233101099Srwatson{
1234103759Srwatson
1235101099Srwatson	if(!mac_biba_enabled)
1236101099Srwatson		return (0);
1237101099Srwatson
1238101099Srwatson	/* XXX: This will be implemented soon... */
1239101099Srwatson
1240101099Srwatson	return (0);
1241101099Srwatson}
1242101099Srwatson
1243101099Srwatsonstatic int
1244102115Srwatsonmac_biba_check_pipe_poll(struct ucred *cred, struct pipe *pipe,
1245102115Srwatson    struct label *pipelabel)
1246101099Srwatson{
1247101099Srwatson	struct mac_biba *subj, *obj;
1248101099Srwatson
1249101099Srwatson	if (!mac_biba_enabled)
1250101099Srwatson		return (0);
1251101099Srwatson
1252101099Srwatson	subj = SLOT(&cred->cr_label);
1253101099Srwatson	obj = SLOT((pipelabel));
1254101099Srwatson
1255102115Srwatson	if (!mac_biba_dominate_single(obj, subj))
1256102115Srwatson		return (EACCES);
1257101099Srwatson
1258101099Srwatson	return (0);
1259101099Srwatson}
1260101099Srwatson
1261101099Srwatsonstatic int
1262102115Srwatsonmac_biba_check_pipe_read(struct ucred *cred, struct pipe *pipe,
1263102115Srwatson    struct label *pipelabel)
1264102115Srwatson{
1265102115Srwatson	struct mac_biba *subj, *obj;
1266102115Srwatson
1267102115Srwatson	if (!mac_biba_enabled)
1268102115Srwatson		return (0);
1269102115Srwatson
1270102115Srwatson	subj = SLOT(&cred->cr_label);
1271102115Srwatson	obj = SLOT((pipelabel));
1272102115Srwatson
1273102115Srwatson	if (!mac_biba_dominate_single(obj, subj))
1274102115Srwatson		return (EACCES);
1275102115Srwatson
1276102115Srwatson	return (0);
1277102115Srwatson}
1278102115Srwatson
1279102115Srwatsonstatic int
1280101099Srwatsonmac_biba_check_pipe_relabel(struct ucred *cred, struct pipe *pipe,
1281101099Srwatson    struct label *pipelabel, struct label *newlabel)
1282101099Srwatson{
1283101099Srwatson	struct mac_biba *subj, *obj, *new;
1284105634Srwatson	int error;
1285101099Srwatson
1286101099Srwatson	new = SLOT(newlabel);
1287101099Srwatson	subj = SLOT(&cred->cr_label);
1288101099Srwatson	obj = SLOT(pipelabel);
1289101099Srwatson
1290101099Srwatson	/*
1291105634Srwatson	 * If there is a Biba label update for a pipe, it must be a
1292105634Srwatson	 * single update.
1293101099Srwatson	 */
1294105634Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE);
1295105634Srwatson	if (error)
1296105634Srwatson		return (error);
1297101099Srwatson
1298101099Srwatson	/*
1299105634Srwatson	 * To perform a relabel of a pipe (Biba label or not), Biba must
1300105634Srwatson	 * authorize the relabel.
1301101099Srwatson	 */
1302105634Srwatson	if (!mac_biba_single_in_range(obj, subj))
1303101099Srwatson		return (EPERM);
1304101099Srwatson
1305101099Srwatson	/*
1306105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
1307101099Srwatson	 */
1308105634Srwatson	if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) {
1309105634Srwatson		/*
1310105634Srwatson		 * To change the Biba label on a pipe, the new pipe label
1311105634Srwatson		 * must be in the subject range.
1312105634Srwatson		 */
1313105634Srwatson		if (!mac_biba_single_in_range(new, subj))
1314105634Srwatson			return (EPERM);
1315101099Srwatson
1316105634Srwatson		/*
1317105634Srwatson		 * To change the Biba label on a pipe to be EQUAL, the
1318105634Srwatson		 * subject must have appropriate privilege.
1319105634Srwatson		 */
1320105634Srwatson		if (mac_biba_contains_equal(new)) {
1321105634Srwatson			error = mac_biba_subject_equal_ok(subj);
1322105634Srwatson			if (error)
1323105634Srwatson				return (error);
1324105634Srwatson		}
1325105634Srwatson	}
1326105634Srwatson
1327101099Srwatson	return (0);
1328101099Srwatson}
1329101099Srwatson
1330101099Srwatsonstatic int
1331102115Srwatsonmac_biba_check_pipe_stat(struct ucred *cred, struct pipe *pipe,
1332102115Srwatson    struct label *pipelabel)
1333102115Srwatson{
1334102115Srwatson	struct mac_biba *subj, *obj;
1335102115Srwatson
1336102115Srwatson	if (!mac_biba_enabled)
1337102115Srwatson		return (0);
1338102115Srwatson
1339102115Srwatson	subj = SLOT(&cred->cr_label);
1340102115Srwatson	obj = SLOT((pipelabel));
1341102115Srwatson
1342102115Srwatson	if (!mac_biba_dominate_single(obj, subj))
1343102115Srwatson		return (EACCES);
1344102115Srwatson
1345102115Srwatson	return (0);
1346102115Srwatson}
1347102115Srwatson
1348102115Srwatsonstatic int
1349102115Srwatsonmac_biba_check_pipe_write(struct ucred *cred, struct pipe *pipe,
1350102115Srwatson    struct label *pipelabel)
1351102115Srwatson{
1352102115Srwatson	struct mac_biba *subj, *obj;
1353102115Srwatson
1354102115Srwatson	if (!mac_biba_enabled)
1355102115Srwatson		return (0);
1356102115Srwatson
1357102115Srwatson	subj = SLOT(&cred->cr_label);
1358102115Srwatson	obj = SLOT((pipelabel));
1359102115Srwatson
1360102115Srwatson	if (!mac_biba_dominate_single(subj, obj))
1361102115Srwatson		return (EACCES);
1362102115Srwatson
1363102115Srwatson	return (0);
1364102115Srwatson}
1365102115Srwatson
1366102115Srwatsonstatic int
1367101099Srwatsonmac_biba_check_proc_debug(struct ucred *cred, struct proc *proc)
1368101099Srwatson{
1369101099Srwatson	struct mac_biba *subj, *obj;
1370101099Srwatson
1371101099Srwatson	if (!mac_biba_enabled)
1372101099Srwatson		return (0);
1373101099Srwatson
1374101099Srwatson	subj = SLOT(&cred->cr_label);
1375101099Srwatson	obj = SLOT(&proc->p_ucred->cr_label);
1376101099Srwatson
1377101099Srwatson	/* XXX: range checks */
1378101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1379101099Srwatson		return (ESRCH);
1380101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1381101099Srwatson		return (EACCES);
1382101099Srwatson
1383101099Srwatson	return (0);
1384101099Srwatson}
1385101099Srwatson
1386101099Srwatsonstatic int
1387101099Srwatsonmac_biba_check_proc_sched(struct ucred *cred, struct proc *proc)
1388101099Srwatson{
1389101099Srwatson	struct mac_biba *subj, *obj;
1390103759Srwatson
1391101099Srwatson	if (!mac_biba_enabled)
1392101099Srwatson		return (0);
1393101099Srwatson
1394101099Srwatson	subj = SLOT(&cred->cr_label);
1395101099Srwatson	obj = SLOT(&proc->p_ucred->cr_label);
1396103759Srwatson
1397101099Srwatson	/* XXX: range checks */
1398101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1399101099Srwatson		return (ESRCH);
1400101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1401101099Srwatson		return (EACCES);
1402101099Srwatson
1403101099Srwatson	return (0);
1404101099Srwatson}
1405101099Srwatson
1406101099Srwatsonstatic int
1407101099Srwatsonmac_biba_check_proc_signal(struct ucred *cred, struct proc *proc, int signum)
1408101099Srwatson{
1409101099Srwatson	struct mac_biba *subj, *obj;
1410103759Srwatson
1411101099Srwatson	if (!mac_biba_enabled)
1412101099Srwatson		return (0);
1413101099Srwatson
1414101099Srwatson	subj = SLOT(&cred->cr_label);
1415101099Srwatson	obj = SLOT(&proc->p_ucred->cr_label);
1416103759Srwatson
1417101099Srwatson	/* XXX: range checks */
1418101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1419101099Srwatson		return (ESRCH);
1420101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1421101099Srwatson		return (EACCES);
1422101099Srwatson
1423101099Srwatson	return (0);
1424101099Srwatson}
1425101099Srwatson
1426101099Srwatsonstatic int
1427101934Srwatsonmac_biba_check_socket_deliver(struct socket *so, struct label *socketlabel,
1428101099Srwatson    struct mbuf *m, struct label *mbuflabel)
1429101099Srwatson{
1430101099Srwatson	struct mac_biba *p, *s;
1431101099Srwatson
1432101099Srwatson	if (!mac_biba_enabled)
1433101099Srwatson		return (0);
1434101099Srwatson
1435101099Srwatson	p = SLOT(mbuflabel);
1436101099Srwatson	s = SLOT(socketlabel);
1437101099Srwatson
1438101099Srwatson	return (mac_biba_equal_single(p, s) ? 0 : EACCES);
1439101099Srwatson}
1440101099Srwatson
1441101099Srwatsonstatic int
1442101099Srwatsonmac_biba_check_socket_relabel(struct ucred *cred, struct socket *socket,
1443101099Srwatson    struct label *socketlabel, struct label *newlabel)
1444101099Srwatson{
1445101099Srwatson	struct mac_biba *subj, *obj, *new;
1446105634Srwatson	int error;
1447101099Srwatson
1448101099Srwatson	new = SLOT(newlabel);
1449101099Srwatson	subj = SLOT(&cred->cr_label);
1450101099Srwatson	obj = SLOT(socketlabel);
1451101099Srwatson
1452101099Srwatson	/*
1453105634Srwatson	 * If there is a Biba label update for the socket, it may be
1454105634Srwatson	 * an update of single.
1455101099Srwatson	 */
1456105634Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE);
1457105634Srwatson	if (error)
1458105634Srwatson		return (error);
1459101099Srwatson
1460101099Srwatson	/*
1461105634Srwatson	 * To relabel a socket, the old socket single must be in the subject
1462101099Srwatson	 * range.
1463101099Srwatson	 */
1464105634Srwatson	if (!mac_biba_single_in_range(obj, subj))
1465101099Srwatson		return (EPERM);
1466101099Srwatson
1467101099Srwatson	/*
1468105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
1469101099Srwatson	 */
1470105634Srwatson	if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) {
1471105634Srwatson		/*
1472105634Srwatson		 * To relabel a socket, the new socket single must be in
1473105634Srwatson		 * the subject range.
1474105634Srwatson		 */
1475105634Srwatson		if (!mac_biba_single_in_range(new, subj))
1476105634Srwatson			return (EPERM);
1477101099Srwatson
1478105634Srwatson		/*
1479105634Srwatson		 * To change the Biba label on the socket to contain EQUAL,
1480105634Srwatson		 * the subject must have appropriate privilege.
1481105634Srwatson		 */
1482105634Srwatson		if (mac_biba_contains_equal(new)) {
1483105634Srwatson			error = mac_biba_subject_equal_ok(subj);
1484105634Srwatson			if (error)
1485105634Srwatson				return (error);
1486105634Srwatson		}
1487105634Srwatson	}
1488105634Srwatson
1489101099Srwatson	return (0);
1490101099Srwatson}
1491101099Srwatson
1492101099Srwatsonstatic int
1493101099Srwatsonmac_biba_check_socket_visible(struct ucred *cred, struct socket *socket,
1494101099Srwatson    struct label *socketlabel)
1495101099Srwatson{
1496101099Srwatson	struct mac_biba *subj, *obj;
1497101099Srwatson
1498101099Srwatson	subj = SLOT(&cred->cr_label);
1499101099Srwatson	obj = SLOT(socketlabel);
1500101099Srwatson
1501101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1502101099Srwatson		return (ENOENT);
1503101099Srwatson
1504101099Srwatson	return (0);
1505101099Srwatson}
1506101099Srwatson
1507101099Srwatsonstatic int
1508101099Srwatsonmac_biba_check_vnode_access(struct ucred *cred, struct vnode *vp,
1509101099Srwatson    struct label *label, mode_t flags)
1510101099Srwatson{
1511101099Srwatson
1512101099Srwatson	return (mac_biba_check_vnode_open(cred, vp, label, flags));
1513101099Srwatson}
1514101099Srwatson
1515101099Srwatsonstatic int
1516101099Srwatsonmac_biba_check_vnode_chdir(struct ucred *cred, struct vnode *dvp,
1517101099Srwatson    struct label *dlabel)
1518101099Srwatson{
1519101099Srwatson	struct mac_biba *subj, *obj;
1520101099Srwatson
1521101099Srwatson	if (!mac_biba_enabled)
1522101099Srwatson		return (0);
1523101099Srwatson
1524101099Srwatson	subj = SLOT(&cred->cr_label);
1525101099Srwatson	obj = SLOT(dlabel);
1526101099Srwatson
1527101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1528101099Srwatson		return (EACCES);
1529101099Srwatson
1530101099Srwatson	return (0);
1531101099Srwatson}
1532101099Srwatson
1533101099Srwatsonstatic int
1534101099Srwatsonmac_biba_check_vnode_chroot(struct ucred *cred, struct vnode *dvp,
1535101099Srwatson    struct label *dlabel)
1536101099Srwatson{
1537101099Srwatson	struct mac_biba *subj, *obj;
1538101099Srwatson
1539101099Srwatson	if (!mac_biba_enabled)
1540101099Srwatson		return (0);
1541101099Srwatson
1542101099Srwatson	subj = SLOT(&cred->cr_label);
1543101099Srwatson	obj = SLOT(dlabel);
1544101099Srwatson
1545101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1546101099Srwatson		return (EACCES);
1547101099Srwatson
1548101099Srwatson	return (0);
1549101099Srwatson}
1550101099Srwatson
1551101099Srwatsonstatic int
1552101099Srwatsonmac_biba_check_vnode_create(struct ucred *cred, struct vnode *dvp,
1553101099Srwatson    struct label *dlabel, struct componentname *cnp, struct vattr *vap)
1554101099Srwatson{
1555101099Srwatson	struct mac_biba *subj, *obj;
1556101099Srwatson
1557101099Srwatson	if (!mac_biba_enabled)
1558101099Srwatson		return (0);
1559101099Srwatson
1560101099Srwatson	subj = SLOT(&cred->cr_label);
1561101099Srwatson	obj = SLOT(dlabel);
1562101099Srwatson
1563101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1564101099Srwatson		return (EACCES);
1565101099Srwatson
1566101099Srwatson	return (0);
1567101099Srwatson}
1568101099Srwatson
1569101099Srwatsonstatic int
1570101099Srwatsonmac_biba_check_vnode_delete(struct ucred *cred, struct vnode *dvp,
1571101099Srwatson    struct label *dlabel, struct vnode *vp, struct label *label,
1572101099Srwatson    struct componentname *cnp)
1573101099Srwatson{
1574101099Srwatson	struct mac_biba *subj, *obj;
1575101099Srwatson
1576101099Srwatson	if (!mac_biba_enabled)
1577101099Srwatson		return (0);
1578101099Srwatson
1579101099Srwatson	subj = SLOT(&cred->cr_label);
1580101099Srwatson	obj = SLOT(dlabel);
1581101099Srwatson
1582101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1583101099Srwatson		return (EACCES);
1584101099Srwatson
1585101099Srwatson	obj = SLOT(label);
1586101099Srwatson
1587101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1588101099Srwatson		return (EACCES);
1589101099Srwatson
1590101099Srwatson	return (0);
1591101099Srwatson}
1592101099Srwatson
1593101099Srwatsonstatic int
1594101099Srwatsonmac_biba_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
1595101099Srwatson    struct label *label, acl_type_t type)
1596101099Srwatson{
1597101099Srwatson	struct mac_biba *subj, *obj;
1598101099Srwatson
1599101099Srwatson	if (!mac_biba_enabled)
1600101099Srwatson		return (0);
1601101099Srwatson
1602101099Srwatson	subj = SLOT(&cred->cr_label);
1603101099Srwatson	obj = SLOT(label);
1604101099Srwatson
1605101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1606101099Srwatson		return (EACCES);
1607101099Srwatson
1608101099Srwatson	return (0);
1609101099Srwatson}
1610101099Srwatson
1611101099Srwatsonstatic int
1612101099Srwatsonmac_biba_check_vnode_exec(struct ucred *cred, struct vnode *vp,
1613101099Srwatson    struct label *label)
1614101099Srwatson{
1615101099Srwatson	struct mac_biba *subj, *obj;
1616101099Srwatson
1617101099Srwatson	if (!mac_biba_enabled)
1618101099Srwatson		return (0);
1619101099Srwatson
1620101099Srwatson	subj = SLOT(&cred->cr_label);
1621101099Srwatson	obj = SLOT(label);
1622101099Srwatson
1623101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1624101099Srwatson		return (EACCES);
1625101099Srwatson
1626101099Srwatson	return (0);
1627101099Srwatson}
1628101099Srwatson
1629101099Srwatsonstatic int
1630101099Srwatsonmac_biba_check_vnode_getacl(struct ucred *cred, struct vnode *vp,
1631101099Srwatson    struct label *label, acl_type_t type)
1632101099Srwatson{
1633101099Srwatson	struct mac_biba *subj, *obj;
1634101099Srwatson
1635101099Srwatson	if (!mac_biba_enabled)
1636101099Srwatson		return (0);
1637101099Srwatson
1638101099Srwatson	subj = SLOT(&cred->cr_label);
1639101099Srwatson	obj = SLOT(label);
1640101099Srwatson
1641101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1642101099Srwatson		return (EACCES);
1643101099Srwatson
1644101099Srwatson	return (0);
1645101099Srwatson}
1646101099Srwatson
1647101099Srwatsonstatic int
1648101099Srwatsonmac_biba_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
1649101099Srwatson    struct label *label, int attrnamespace, const char *name, struct uio *uio)
1650101099Srwatson{
1651101099Srwatson	struct mac_biba *subj, *obj;
1652101099Srwatson
1653101099Srwatson	if (!mac_biba_enabled)
1654101099Srwatson		return (0);
1655101099Srwatson
1656101099Srwatson	subj = SLOT(&cred->cr_label);
1657101099Srwatson	obj = SLOT(label);
1658101099Srwatson
1659101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1660101099Srwatson		return (EACCES);
1661101099Srwatson
1662101099Srwatson	return (0);
1663101099Srwatson}
1664101099Srwatson
1665101099Srwatsonstatic int
1666104530Srwatsonmac_biba_check_vnode_link(struct ucred *cred, struct vnode *dvp,
1667104530Srwatson    struct label *dlabel, struct vnode *vp, struct label *label,
1668104530Srwatson    struct componentname *cnp)
1669104530Srwatson{
1670104530Srwatson	struct mac_biba *subj, *obj;
1671104530Srwatson
1672104530Srwatson	if (!mac_biba_enabled)
1673104530Srwatson		return (0);
1674104530Srwatson
1675104530Srwatson	subj = SLOT(&cred->cr_label);
1676104530Srwatson	obj = SLOT(dlabel);
1677104530Srwatson
1678104530Srwatson	if (!mac_biba_dominate_single(subj, obj))
1679104530Srwatson		return (EACCES);
1680104530Srwatson
1681104530Srwatson	obj = SLOT(label);
1682104530Srwatson
1683104530Srwatson	if (!mac_biba_dominate_single(subj, obj))
1684104530Srwatson		return (EACCES);
1685104530Srwatson
1686104530Srwatson	return (0);
1687104530Srwatson}
1688104530Srwatson
1689104530Srwatsonstatic int
1690103759Srwatsonmac_biba_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
1691101099Srwatson    struct label *dlabel, struct componentname *cnp)
1692101099Srwatson{
1693101099Srwatson	struct mac_biba *subj, *obj;
1694103759Srwatson
1695101099Srwatson	if (!mac_biba_enabled)
1696101099Srwatson		return (0);
1697103759Srwatson
1698101099Srwatson	subj = SLOT(&cred->cr_label);
1699101099Srwatson	obj = SLOT(dlabel);
1700103759Srwatson
1701101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1702101099Srwatson		return (EACCES);
1703101099Srwatson
1704103759Srwatson	return (0);
1705101099Srwatson}
1706101099Srwatson
1707101099Srwatsonstatic int
1708104546Srwatsonmac_biba_check_vnode_mmap(struct ucred *cred, struct vnode *vp,
1709104546Srwatson    struct label *label, int prot)
1710104546Srwatson{
1711104546Srwatson	struct mac_biba *subj, *obj;
1712104546Srwatson
1713104546Srwatson	/*
1714104546Srwatson	 * Rely on the use of open()-time protections to handle
1715104546Srwatson	 * non-revocation cases.
1716104546Srwatson	 */
1717104546Srwatson	if (!mac_biba_enabled || !mac_biba_revocation_enabled)
1718104546Srwatson		return (0);
1719104546Srwatson
1720104546Srwatson	subj = SLOT(&cred->cr_label);
1721104546Srwatson	obj = SLOT(label);
1722104546Srwatson
1723104546Srwatson	if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
1724104546Srwatson		if (!mac_biba_dominate_single(obj, subj))
1725104546Srwatson			return (EACCES);
1726104546Srwatson	}
1727104546Srwatson	if (prot & VM_PROT_WRITE) {
1728104546Srwatson		if (!mac_biba_dominate_single(subj, obj))
1729104546Srwatson			return (EACCES);
1730104546Srwatson	}
1731104546Srwatson
1732104569Srwatson	return (0);
1733104546Srwatson}
1734104546Srwatson
1735104546Srwatsonstatic int
1736101099Srwatsonmac_biba_check_vnode_open(struct ucred *cred, struct vnode *vp,
1737101099Srwatson    struct label *vnodelabel, mode_t acc_mode)
1738101099Srwatson{
1739101099Srwatson	struct mac_biba *subj, *obj;
1740101099Srwatson
1741101099Srwatson	if (!mac_biba_enabled)
1742101099Srwatson		return (0);
1743101099Srwatson
1744101099Srwatson	subj = SLOT(&cred->cr_label);
1745101099Srwatson	obj = SLOT(vnodelabel);
1746101099Srwatson
1747101099Srwatson	/* XXX privilege override for admin? */
1748101099Srwatson	if (acc_mode & (VREAD | VEXEC | VSTAT)) {
1749101099Srwatson		if (!mac_biba_dominate_single(obj, subj))
1750101099Srwatson			return (EACCES);
1751101099Srwatson	}
1752101099Srwatson	if (acc_mode & (VWRITE | VAPPEND | VADMIN)) {
1753101099Srwatson		if (!mac_biba_dominate_single(subj, obj))
1754101099Srwatson			return (EACCES);
1755101099Srwatson	}
1756101099Srwatson
1757101099Srwatson	return (0);
1758101099Srwatson}
1759101099Srwatson
1760101099Srwatsonstatic int
1761102129Srwatsonmac_biba_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred,
1762102129Srwatson    struct vnode *vp, struct label *label)
1763102112Srwatson{
1764102112Srwatson	struct mac_biba *subj, *obj;
1765102112Srwatson
1766102112Srwatson	if (!mac_biba_enabled || !mac_biba_revocation_enabled)
1767102112Srwatson		return (0);
1768102112Srwatson
1769102129Srwatson	subj = SLOT(&active_cred->cr_label);
1770102112Srwatson	obj = SLOT(label);
1771102112Srwatson
1772102112Srwatson	if (!mac_biba_dominate_single(obj, subj))
1773102112Srwatson		return (EACCES);
1774102112Srwatson
1775102112Srwatson	return (0);
1776102112Srwatson}
1777102112Srwatson
1778102112Srwatsonstatic int
1779102129Srwatsonmac_biba_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
1780102129Srwatson    struct vnode *vp, struct label *label)
1781102112Srwatson{
1782102112Srwatson	struct mac_biba *subj, *obj;
1783102112Srwatson
1784102112Srwatson	if (!mac_biba_enabled || !mac_biba_revocation_enabled)
1785102112Srwatson		return (0);
1786102112Srwatson
1787102129Srwatson	subj = SLOT(&active_cred->cr_label);
1788102112Srwatson	obj = SLOT(label);
1789102112Srwatson
1790102112Srwatson	if (!mac_biba_dominate_single(obj, subj))
1791102112Srwatson		return (EACCES);
1792102112Srwatson
1793102112Srwatson	return (0);
1794102112Srwatson}
1795102112Srwatson
1796102112Srwatsonstatic int
1797101099Srwatsonmac_biba_check_vnode_readdir(struct ucred *cred, struct vnode *dvp,
1798101099Srwatson    struct label *dlabel)
1799101099Srwatson{
1800101099Srwatson	struct mac_biba *subj, *obj;
1801101099Srwatson
1802101099Srwatson	if (!mac_biba_enabled)
1803101099Srwatson		return (0);
1804101099Srwatson
1805101099Srwatson	subj = SLOT(&cred->cr_label);
1806101099Srwatson	obj = SLOT(dlabel);
1807101099Srwatson
1808101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1809101099Srwatson		return (EACCES);
1810101099Srwatson
1811101099Srwatson	return (0);
1812101099Srwatson}
1813101099Srwatson
1814101099Srwatsonstatic int
1815101099Srwatsonmac_biba_check_vnode_readlink(struct ucred *cred, struct vnode *vp,
1816101099Srwatson    struct label *label)
1817101099Srwatson{
1818101099Srwatson	struct mac_biba *subj, *obj;
1819101099Srwatson
1820101099Srwatson	if (!mac_biba_enabled)
1821101099Srwatson		return (0);
1822101099Srwatson
1823101099Srwatson	subj = SLOT(&cred->cr_label);
1824101099Srwatson	obj = SLOT(label);
1825101099Srwatson
1826101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1827101099Srwatson		return (EACCES);
1828101099Srwatson
1829101099Srwatson	return (0);
1830101099Srwatson}
1831101099Srwatson
1832101099Srwatsonstatic int
1833101099Srwatsonmac_biba_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
1834101099Srwatson    struct label *vnodelabel, struct label *newlabel)
1835101099Srwatson{
1836101099Srwatson	struct mac_biba *old, *new, *subj;
1837105634Srwatson	int error;
1838101099Srwatson
1839101099Srwatson	old = SLOT(vnodelabel);
1840101099Srwatson	new = SLOT(newlabel);
1841101099Srwatson	subj = SLOT(&cred->cr_label);
1842101099Srwatson
1843101099Srwatson	/*
1844105634Srwatson	 * If there is a Biba label update for the vnode, it must be a
1845105634Srwatson	 * single label.
1846101099Srwatson	 */
1847105634Srwatson	error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE);
1848105634Srwatson	if (error)
1849105634Srwatson		return (error);
1850101099Srwatson
1851101099Srwatson	/*
1852105634Srwatson	 * To perform a relabel of the vnode (Biba label or not), Biba must
1853105634Srwatson	 * authorize the relabel.
1854101099Srwatson	 */
1855105634Srwatson	if (!mac_biba_single_in_range(old, subj))
1856101099Srwatson		return (EPERM);
1857101099Srwatson
1858101099Srwatson	/*
1859105634Srwatson	 * If the Biba label is to be changed, authorize as appropriate.
1860101099Srwatson	 */
1861105634Srwatson	if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) {
1862105634Srwatson		/*
1863105634Srwatson		 * To change the Biba label on a vnode, the new vnode label
1864105634Srwatson		 * must be in the subject range.
1865105634Srwatson		 */
1866105634Srwatson		if (!mac_biba_single_in_range(new, subj))
1867105634Srwatson			return (EPERM);
1868101099Srwatson
1869105634Srwatson		/*
1870105634Srwatson		 * To change the Biba label on the vnode to be EQUAL,
1871105634Srwatson		 * the subject must have appropriate privilege.
1872105634Srwatson		 */
1873105634Srwatson		if (mac_biba_contains_equal(new)) {
1874105634Srwatson			error = mac_biba_subject_equal_ok(subj);
1875105634Srwatson			if (error)
1876105634Srwatson				return (error);
1877105634Srwatson		}
1878105634Srwatson	}
1879105634Srwatson
1880105634Srwatson	return (0);
1881101099Srwatson}
1882101099Srwatson
1883101099Srwatsonstatic int
1884101099Srwatsonmac_biba_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
1885101099Srwatson    struct label *dlabel, struct vnode *vp, struct label *label,
1886101099Srwatson    struct componentname *cnp)
1887101099Srwatson{
1888101099Srwatson	struct mac_biba *subj, *obj;
1889101099Srwatson
1890101099Srwatson	if (!mac_biba_enabled)
1891101099Srwatson		return (0);
1892101099Srwatson
1893101099Srwatson	subj = SLOT(&cred->cr_label);
1894101099Srwatson	obj = SLOT(dlabel);
1895101099Srwatson
1896101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1897101099Srwatson		return (EACCES);
1898101099Srwatson
1899101099Srwatson	obj = SLOT(label);
1900101099Srwatson
1901101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1902101099Srwatson		return (EACCES);
1903101099Srwatson
1904101099Srwatson	return (0);
1905101099Srwatson}
1906101099Srwatson
1907101099Srwatsonstatic int
1908101099Srwatsonmac_biba_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
1909101099Srwatson    struct label *dlabel, struct vnode *vp, struct label *label, int samedir,
1910101099Srwatson    struct componentname *cnp)
1911101099Srwatson{
1912101099Srwatson	struct mac_biba *subj, *obj;
1913101099Srwatson
1914101099Srwatson	if (!mac_biba_enabled)
1915101099Srwatson		return (0);
1916101099Srwatson
1917101099Srwatson	subj = SLOT(&cred->cr_label);
1918101099Srwatson	obj = SLOT(dlabel);
1919101099Srwatson
1920101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1921101099Srwatson		return (EACCES);
1922101099Srwatson
1923101099Srwatson	if (vp != NULL) {
1924101099Srwatson		obj = SLOT(label);
1925101099Srwatson
1926101099Srwatson		if (!mac_biba_dominate_single(subj, obj))
1927101099Srwatson			return (EACCES);
1928101099Srwatson	}
1929101099Srwatson
1930101099Srwatson	return (0);
1931101099Srwatson}
1932101099Srwatson
1933101099Srwatsonstatic int
1934101099Srwatsonmac_biba_check_vnode_revoke(struct ucred *cred, struct vnode *vp,
1935101099Srwatson    struct label *label)
1936101099Srwatson{
1937101099Srwatson	struct mac_biba *subj, *obj;
1938101099Srwatson
1939101099Srwatson	if (!mac_biba_enabled)
1940101099Srwatson		return (0);
1941101099Srwatson
1942101099Srwatson	subj = SLOT(&cred->cr_label);
1943101099Srwatson	obj = SLOT(label);
1944101099Srwatson
1945101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1946101099Srwatson		return (EACCES);
1947101099Srwatson
1948101099Srwatson	return (0);
1949101099Srwatson}
1950101099Srwatson
1951101099Srwatsonstatic int
1952101099Srwatsonmac_biba_check_vnode_setacl(struct ucred *cred, struct vnode *vp,
1953101099Srwatson    struct label *label, acl_type_t type, struct acl *acl)
1954101099Srwatson{
1955101099Srwatson	struct mac_biba *subj, *obj;
1956101099Srwatson
1957101099Srwatson	if (!mac_biba_enabled)
1958101099Srwatson		return (0);
1959101099Srwatson
1960101099Srwatson	subj = SLOT(&cred->cr_label);
1961101099Srwatson	obj = SLOT(label);
1962101099Srwatson
1963101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1964101099Srwatson		return (EACCES);
1965101099Srwatson
1966101099Srwatson	return (0);
1967101099Srwatson}
1968101099Srwatson
1969101099Srwatsonstatic int
1970101099Srwatsonmac_biba_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
1971101099Srwatson    struct label *vnodelabel, int attrnamespace, const char *name,
1972101099Srwatson    struct uio *uio)
1973101099Srwatson{
1974101099Srwatson	struct mac_biba *subj, *obj;
1975101099Srwatson
1976101099Srwatson	if (!mac_biba_enabled)
1977101099Srwatson		return (0);
1978101099Srwatson
1979101099Srwatson	subj = SLOT(&cred->cr_label);
1980101099Srwatson	obj = SLOT(vnodelabel);
1981101099Srwatson
1982101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1983101099Srwatson		return (EACCES);
1984101099Srwatson
1985101099Srwatson	/* XXX: protect the MAC EA in a special way? */
1986101099Srwatson
1987101099Srwatson	return (0);
1988101099Srwatson}
1989101099Srwatson
1990101099Srwatsonstatic int
1991101099Srwatsonmac_biba_check_vnode_setflags(struct ucred *cred, struct vnode *vp,
1992101099Srwatson    struct label *vnodelabel, u_long flags)
1993101099Srwatson{
1994101099Srwatson	struct mac_biba *subj, *obj;
1995101099Srwatson
1996101099Srwatson	if (!mac_biba_enabled)
1997101099Srwatson		return (0);
1998101099Srwatson
1999101099Srwatson	subj = SLOT(&cred->cr_label);
2000101099Srwatson	obj = SLOT(vnodelabel);
2001101099Srwatson
2002101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2003101099Srwatson		return (EACCES);
2004101099Srwatson
2005101099Srwatson	return (0);
2006101099Srwatson}
2007101099Srwatson
2008101099Srwatsonstatic int
2009101099Srwatsonmac_biba_check_vnode_setmode(struct ucred *cred, struct vnode *vp,
2010101099Srwatson    struct label *vnodelabel, mode_t mode)
2011101099Srwatson{
2012101099Srwatson	struct mac_biba *subj, *obj;
2013101099Srwatson
2014101099Srwatson	if (!mac_biba_enabled)
2015101099Srwatson		return (0);
2016101099Srwatson
2017101099Srwatson	subj = SLOT(&cred->cr_label);
2018101099Srwatson	obj = SLOT(vnodelabel);
2019101099Srwatson
2020101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2021101099Srwatson		return (EACCES);
2022101099Srwatson
2023101099Srwatson	return (0);
2024101099Srwatson}
2025101099Srwatson
2026101099Srwatsonstatic int
2027101099Srwatsonmac_biba_check_vnode_setowner(struct ucred *cred, struct vnode *vp,
2028101099Srwatson    struct label *vnodelabel, uid_t uid, gid_t gid)
2029101099Srwatson{
2030101099Srwatson	struct mac_biba *subj, *obj;
2031101099Srwatson
2032101099Srwatson	if (!mac_biba_enabled)
2033101099Srwatson		return (0);
2034101099Srwatson
2035101099Srwatson	subj = SLOT(&cred->cr_label);
2036101099Srwatson	obj = SLOT(vnodelabel);
2037101099Srwatson
2038101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2039101099Srwatson		return (EACCES);
2040101099Srwatson
2041101099Srwatson	return (0);
2042101099Srwatson}
2043101099Srwatson
2044101099Srwatsonstatic int
2045101099Srwatsonmac_biba_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
2046101099Srwatson    struct label *vnodelabel, struct timespec atime, struct timespec mtime)
2047101099Srwatson{
2048101099Srwatson	struct mac_biba *subj, *obj;
2049101099Srwatson
2050101099Srwatson	if (!mac_biba_enabled)
2051101099Srwatson		return (0);
2052101099Srwatson
2053101099Srwatson	subj = SLOT(&cred->cr_label);
2054101099Srwatson	obj = SLOT(vnodelabel);
2055101099Srwatson
2056101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
2057101099Srwatson		return (EACCES);
2058101099Srwatson
2059101099Srwatson	return (0);
2060101099Srwatson}
2061101099Srwatson
2062101099Srwatsonstatic int
2063102129Srwatsonmac_biba_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
2064102129Srwatson    struct vnode *vp, struct label *vnodelabel)
2065101099Srwatson{
2066101099Srwatson	struct mac_biba *subj, *obj;
2067101099Srwatson
2068101099Srwatson	if (!mac_biba_enabled)
2069101099Srwatson		return (0);
2070101099Srwatson
2071102129Srwatson	subj = SLOT(&active_cred->cr_label);
2072101099Srwatson	obj = SLOT(vnodelabel);
2073101099Srwatson
2074101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
2075101099Srwatson		return (EACCES);
2076101099Srwatson
2077101099Srwatson	return (0);
2078101099Srwatson}
2079101099Srwatson
2080102112Srwatsonstatic int
2081102129Srwatsonmac_biba_check_vnode_write(struct ucred *active_cred,
2082102129Srwatson    struct ucred *file_cred, struct vnode *vp, struct label *label)
2083102112Srwatson{
2084102112Srwatson	struct mac_biba *subj, *obj;
2085102112Srwatson
2086102112Srwatson	if (!mac_biba_enabled || !mac_biba_revocation_enabled)
2087102112Srwatson		return (0);
2088102112Srwatson
2089102129Srwatson	subj = SLOT(&active_cred->cr_label);
2090102112Srwatson	obj = SLOT(label);
2091102112Srwatson
2092102112Srwatson	if (!mac_biba_dominate_single(subj, obj))
2093102112Srwatson		return (EACCES);
2094102112Srwatson
2095102112Srwatson	return (0);
2096102112Srwatson}
2097102112Srwatson
2098101099Srwatsonstatic struct mac_policy_op_entry mac_biba_ops[] =
2099101099Srwatson{
2100101099Srwatson	{ MAC_DESTROY,
2101101099Srwatson	    (macop_t)mac_biba_destroy },
2102101099Srwatson	{ MAC_INIT,
2103101099Srwatson	    (macop_t)mac_biba_init },
2104104514Srwatson	{ MAC_INIT_BPFDESC_LABEL,
2105104514Srwatson	    (macop_t)mac_biba_init_label },
2106104514Srwatson	{ MAC_INIT_CRED_LABEL,
2107104514Srwatson	    (macop_t)mac_biba_init_label },
2108104514Srwatson	{ MAC_INIT_DEVFSDIRENT_LABEL,
2109104514Srwatson	    (macop_t)mac_biba_init_label },
2110104514Srwatson	{ MAC_INIT_IFNET_LABEL,
2111104514Srwatson	    (macop_t)mac_biba_init_label },
2112104514Srwatson	{ MAC_INIT_IPQ_LABEL,
2113104514Srwatson	    (macop_t)mac_biba_init_label },
2114104514Srwatson	{ MAC_INIT_MBUF_LABEL,
2115104514Srwatson	    (macop_t)mac_biba_init_label_waitcheck },
2116104514Srwatson	{ MAC_INIT_MOUNT_LABEL,
2117104514Srwatson	    (macop_t)mac_biba_init_label },
2118104514Srwatson	{ MAC_INIT_MOUNT_FS_LABEL,
2119104514Srwatson	    (macop_t)mac_biba_init_label },
2120104514Srwatson	{ MAC_INIT_PIPE_LABEL,
2121104514Srwatson	    (macop_t)mac_biba_init_label },
2122104514Srwatson	{ MAC_INIT_SOCKET_LABEL,
2123104541Srwatson	    (macop_t)mac_biba_init_label_waitcheck },
2124104514Srwatson	{ MAC_INIT_SOCKET_PEER_LABEL,
2125104541Srwatson	    (macop_t)mac_biba_init_label_waitcheck },
2126104514Srwatson	{ MAC_INIT_TEMP_LABEL,
2127104514Srwatson	    (macop_t)mac_biba_init_label },
2128104514Srwatson	{ MAC_INIT_VNODE_LABEL,
2129104514Srwatson	    (macop_t)mac_biba_init_label },
2130104514Srwatson	{ MAC_DESTROY_BPFDESC_LABEL,
2131104514Srwatson	    (macop_t)mac_biba_destroy_label },
2132104514Srwatson	{ MAC_DESTROY_CRED_LABEL,
2133104514Srwatson	    (macop_t)mac_biba_destroy_label },
2134104514Srwatson	{ MAC_DESTROY_DEVFSDIRENT_LABEL,
2135104514Srwatson	    (macop_t)mac_biba_destroy_label },
2136104514Srwatson	{ MAC_DESTROY_IFNET_LABEL,
2137104514Srwatson	    (macop_t)mac_biba_destroy_label },
2138104514Srwatson	{ MAC_DESTROY_IPQ_LABEL,
2139104514Srwatson	    (macop_t)mac_biba_destroy_label },
2140104514Srwatson	{ MAC_DESTROY_MBUF_LABEL,
2141104514Srwatson	    (macop_t)mac_biba_destroy_label },
2142104514Srwatson	{ MAC_DESTROY_MOUNT_LABEL,
2143104514Srwatson	    (macop_t)mac_biba_destroy_label },
2144104514Srwatson	{ MAC_DESTROY_MOUNT_FS_LABEL,
2145104514Srwatson	    (macop_t)mac_biba_destroy_label },
2146104514Srwatson	{ MAC_DESTROY_PIPE_LABEL,
2147104514Srwatson	    (macop_t)mac_biba_destroy_label },
2148104514Srwatson	{ MAC_DESTROY_SOCKET_LABEL,
2149104514Srwatson	    (macop_t)mac_biba_destroy_label },
2150104514Srwatson	{ MAC_DESTROY_SOCKET_PEER_LABEL,
2151104514Srwatson	    (macop_t)mac_biba_destroy_label },
2152104514Srwatson	{ MAC_DESTROY_TEMP_LABEL,
2153104514Srwatson	    (macop_t)mac_biba_destroy_label },
2154104514Srwatson	{ MAC_DESTROY_VNODE_LABEL,
2155104514Srwatson	    (macop_t)mac_biba_destroy_label },
2156101099Srwatson	{ MAC_EXTERNALIZE,
2157101099Srwatson	    (macop_t)mac_biba_externalize },
2158101099Srwatson	{ MAC_INTERNALIZE,
2159101099Srwatson	    (macop_t)mac_biba_internalize },
2160101099Srwatson	{ MAC_CREATE_DEVFS_DEVICE,
2161101099Srwatson	    (macop_t)mac_biba_create_devfs_device },
2162101099Srwatson	{ MAC_CREATE_DEVFS_DIRECTORY,
2163101099Srwatson	    (macop_t)mac_biba_create_devfs_directory },
2164104535Srwatson	{ MAC_CREATE_DEVFS_SYMLINK,
2165104535Srwatson	    (macop_t)mac_biba_create_devfs_symlink },
2166101099Srwatson	{ MAC_CREATE_DEVFS_VNODE,
2167101099Srwatson	    (macop_t)mac_biba_create_devfs_vnode },
2168101099Srwatson	{ MAC_CREATE_VNODE,
2169101099Srwatson	    (macop_t)mac_biba_create_vnode },
2170101099Srwatson	{ MAC_CREATE_MOUNT,
2171101099Srwatson	    (macop_t)mac_biba_create_mount },
2172101099Srwatson	{ MAC_CREATE_ROOT_MOUNT,
2173101099Srwatson	    (macop_t)mac_biba_create_root_mount },
2174101099Srwatson	{ MAC_RELABEL_VNODE,
2175101099Srwatson	    (macop_t)mac_biba_relabel_vnode },
2176101099Srwatson	{ MAC_UPDATE_DEVFSDIRENT,
2177101099Srwatson	    (macop_t)mac_biba_update_devfsdirent },
2178101099Srwatson	{ MAC_UPDATE_PROCFSVNODE,
2179101099Srwatson	    (macop_t)mac_biba_update_procfsvnode },
2180101099Srwatson	{ MAC_UPDATE_VNODE_FROM_EXTERNALIZED,
2181101099Srwatson	    (macop_t)mac_biba_update_vnode_from_externalized },
2182101099Srwatson	{ MAC_UPDATE_VNODE_FROM_MOUNT,
2183101099Srwatson	    (macop_t)mac_biba_update_vnode_from_mount },
2184101099Srwatson	{ MAC_CREATE_MBUF_FROM_SOCKET,
2185101099Srwatson	    (macop_t)mac_biba_create_mbuf_from_socket },
2186101099Srwatson	{ MAC_CREATE_PIPE,
2187101099Srwatson	    (macop_t)mac_biba_create_pipe },
2188101099Srwatson	{ MAC_CREATE_SOCKET,
2189101099Srwatson	    (macop_t)mac_biba_create_socket },
2190101099Srwatson	{ MAC_CREATE_SOCKET_FROM_SOCKET,
2191101099Srwatson	    (macop_t)mac_biba_create_socket_from_socket },
2192101099Srwatson	{ MAC_RELABEL_PIPE,
2193101099Srwatson	    (macop_t)mac_biba_relabel_pipe },
2194101099Srwatson	{ MAC_RELABEL_SOCKET,
2195101099Srwatson	    (macop_t)mac_biba_relabel_socket },
2196101099Srwatson	{ MAC_SET_SOCKET_PEER_FROM_MBUF,
2197101099Srwatson	    (macop_t)mac_biba_set_socket_peer_from_mbuf },
2198101099Srwatson	{ MAC_SET_SOCKET_PEER_FROM_SOCKET,
2199101099Srwatson	    (macop_t)mac_biba_set_socket_peer_from_socket },
2200101099Srwatson	{ MAC_CREATE_BPFDESC,
2201101099Srwatson	    (macop_t)mac_biba_create_bpfdesc },
2202101099Srwatson	{ MAC_CREATE_DATAGRAM_FROM_IPQ,
2203101099Srwatson	    (macop_t)mac_biba_create_datagram_from_ipq },
2204101099Srwatson	{ MAC_CREATE_FRAGMENT,
2205101099Srwatson	    (macop_t)mac_biba_create_fragment },
2206101099Srwatson	{ MAC_CREATE_IFNET,
2207101099Srwatson	    (macop_t)mac_biba_create_ifnet },
2208101099Srwatson	{ MAC_CREATE_IPQ,
2209101099Srwatson	    (macop_t)mac_biba_create_ipq },
2210101099Srwatson	{ MAC_CREATE_MBUF_FROM_MBUF,
2211101099Srwatson	    (macop_t)mac_biba_create_mbuf_from_mbuf },
2212101099Srwatson	{ MAC_CREATE_MBUF_LINKLAYER,
2213101099Srwatson	    (macop_t)mac_biba_create_mbuf_linklayer },
2214101099Srwatson	{ MAC_CREATE_MBUF_FROM_BPFDESC,
2215101099Srwatson	    (macop_t)mac_biba_create_mbuf_from_bpfdesc },
2216101099Srwatson	{ MAC_CREATE_MBUF_FROM_IFNET,
2217101099Srwatson	    (macop_t)mac_biba_create_mbuf_from_ifnet },
2218101099Srwatson	{ MAC_CREATE_MBUF_MULTICAST_ENCAP,
2219101099Srwatson	    (macop_t)mac_biba_create_mbuf_multicast_encap },
2220101099Srwatson	{ MAC_CREATE_MBUF_NETLAYER,
2221101099Srwatson	    (macop_t)mac_biba_create_mbuf_netlayer },
2222101099Srwatson	{ MAC_FRAGMENT_MATCH,
2223101099Srwatson	    (macop_t)mac_biba_fragment_match },
2224101099Srwatson	{ MAC_RELABEL_IFNET,
2225101099Srwatson	    (macop_t)mac_biba_relabel_ifnet },
2226101099Srwatson	{ MAC_UPDATE_IPQ,
2227101099Srwatson	    (macop_t)mac_biba_update_ipq },
2228101099Srwatson	{ MAC_CREATE_CRED,
2229101099Srwatson	    (macop_t)mac_biba_create_cred },
2230101099Srwatson	{ MAC_EXECVE_TRANSITION,
2231101099Srwatson	    (macop_t)mac_biba_execve_transition },
2232101099Srwatson	{ MAC_EXECVE_WILL_TRANSITION,
2233101099Srwatson	    (macop_t)mac_biba_execve_will_transition },
2234101099Srwatson	{ MAC_CREATE_PROC0,
2235101099Srwatson	    (macop_t)mac_biba_create_proc0 },
2236101099Srwatson	{ MAC_CREATE_PROC1,
2237101099Srwatson	    (macop_t)mac_biba_create_proc1 },
2238101099Srwatson	{ MAC_RELABEL_CRED,
2239101099Srwatson	    (macop_t)mac_biba_relabel_cred },
2240101099Srwatson	{ MAC_CHECK_BPFDESC_RECEIVE,
2241101099Srwatson	    (macop_t)mac_biba_check_bpfdesc_receive },
2242101099Srwatson	{ MAC_CHECK_CRED_RELABEL,
2243101099Srwatson	    (macop_t)mac_biba_check_cred_relabel },
2244101099Srwatson	{ MAC_CHECK_CRED_VISIBLE,
2245101099Srwatson	    (macop_t)mac_biba_check_cred_visible },
2246101099Srwatson	{ MAC_CHECK_IFNET_RELABEL,
2247101099Srwatson	    (macop_t)mac_biba_check_ifnet_relabel },
2248101099Srwatson	{ MAC_CHECK_IFNET_TRANSMIT,
2249101099Srwatson	    (macop_t)mac_biba_check_ifnet_transmit },
2250101099Srwatson	{ MAC_CHECK_MOUNT_STAT,
2251101099Srwatson	    (macop_t)mac_biba_check_mount_stat },
2252101099Srwatson	{ MAC_CHECK_PIPE_IOCTL,
2253101099Srwatson	    (macop_t)mac_biba_check_pipe_ioctl },
2254102115Srwatson	{ MAC_CHECK_PIPE_POLL,
2255102115Srwatson	    (macop_t)mac_biba_check_pipe_poll },
2256102115Srwatson	{ MAC_CHECK_PIPE_READ,
2257102115Srwatson	    (macop_t)mac_biba_check_pipe_read },
2258101099Srwatson	{ MAC_CHECK_PIPE_RELABEL,
2259101099Srwatson	    (macop_t)mac_biba_check_pipe_relabel },
2260102115Srwatson	{ MAC_CHECK_PIPE_STAT,
2261102115Srwatson	    (macop_t)mac_biba_check_pipe_stat },
2262102115Srwatson	{ MAC_CHECK_PIPE_WRITE,
2263102115Srwatson	    (macop_t)mac_biba_check_pipe_write },
2264101099Srwatson	{ MAC_CHECK_PROC_DEBUG,
2265101099Srwatson	    (macop_t)mac_biba_check_proc_debug },
2266101099Srwatson	{ MAC_CHECK_PROC_SCHED,
2267101099Srwatson	    (macop_t)mac_biba_check_proc_sched },
2268101099Srwatson	{ MAC_CHECK_PROC_SIGNAL,
2269101099Srwatson	    (macop_t)mac_biba_check_proc_signal },
2270101934Srwatson	{ MAC_CHECK_SOCKET_DELIVER,
2271101934Srwatson	    (macop_t)mac_biba_check_socket_deliver },
2272101099Srwatson	{ MAC_CHECK_SOCKET_RELABEL,
2273101099Srwatson	    (macop_t)mac_biba_check_socket_relabel },
2274101099Srwatson	{ MAC_CHECK_SOCKET_VISIBLE,
2275101099Srwatson	    (macop_t)mac_biba_check_socket_visible },
2276101099Srwatson	{ MAC_CHECK_VNODE_ACCESS,
2277101099Srwatson	    (macop_t)mac_biba_check_vnode_access },
2278101099Srwatson	{ MAC_CHECK_VNODE_CHDIR,
2279101099Srwatson	    (macop_t)mac_biba_check_vnode_chdir },
2280101099Srwatson	{ MAC_CHECK_VNODE_CHROOT,
2281101099Srwatson	    (macop_t)mac_biba_check_vnode_chroot },
2282101099Srwatson	{ MAC_CHECK_VNODE_CREATE,
2283101099Srwatson	    (macop_t)mac_biba_check_vnode_create },
2284101099Srwatson	{ MAC_CHECK_VNODE_DELETE,
2285101099Srwatson	    (macop_t)mac_biba_check_vnode_delete },
2286101099Srwatson	{ MAC_CHECK_VNODE_DELETEACL,
2287101099Srwatson	    (macop_t)mac_biba_check_vnode_deleteacl },
2288101099Srwatson	{ MAC_CHECK_VNODE_EXEC,
2289101099Srwatson	    (macop_t)mac_biba_check_vnode_exec },
2290101099Srwatson	{ MAC_CHECK_VNODE_GETACL,
2291101099Srwatson	    (macop_t)mac_biba_check_vnode_getacl },
2292101099Srwatson	{ MAC_CHECK_VNODE_GETEXTATTR,
2293101099Srwatson	    (macop_t)mac_biba_check_vnode_getextattr },
2294104530Srwatson	{ MAC_CHECK_VNODE_LINK,
2295104530Srwatson	    (macop_t)mac_biba_check_vnode_link },
2296101099Srwatson	{ MAC_CHECK_VNODE_LOOKUP,
2297101099Srwatson	    (macop_t)mac_biba_check_vnode_lookup },
2298104546Srwatson	{ MAC_CHECK_VNODE_MMAP,
2299104546Srwatson	    (macop_t)mac_biba_check_vnode_mmap },
2300104546Srwatson	{ MAC_CHECK_VNODE_MPROTECT,
2301104546Srwatson	    (macop_t)mac_biba_check_vnode_mmap },
2302101099Srwatson	{ MAC_CHECK_VNODE_OPEN,
2303101099Srwatson	    (macop_t)mac_biba_check_vnode_open },
2304102112Srwatson	{ MAC_CHECK_VNODE_POLL,
2305102112Srwatson	    (macop_t)mac_biba_check_vnode_poll },
2306102112Srwatson	{ MAC_CHECK_VNODE_READ,
2307102112Srwatson	    (macop_t)mac_biba_check_vnode_read },
2308101099Srwatson	{ MAC_CHECK_VNODE_READDIR,
2309101099Srwatson	    (macop_t)mac_biba_check_vnode_readdir },
2310101099Srwatson	{ MAC_CHECK_VNODE_READLINK,
2311101099Srwatson	    (macop_t)mac_biba_check_vnode_readlink },
2312101099Srwatson	{ MAC_CHECK_VNODE_RELABEL,
2313101099Srwatson	    (macop_t)mac_biba_check_vnode_relabel },
2314101099Srwatson	{ MAC_CHECK_VNODE_RENAME_FROM,
2315101099Srwatson	    (macop_t)mac_biba_check_vnode_rename_from },
2316101099Srwatson	{ MAC_CHECK_VNODE_RENAME_TO,
2317101099Srwatson	    (macop_t)mac_biba_check_vnode_rename_to },
2318101099Srwatson	{ MAC_CHECK_VNODE_REVOKE,
2319101099Srwatson	    (macop_t)mac_biba_check_vnode_revoke },
2320101099Srwatson	{ MAC_CHECK_VNODE_SETACL,
2321101099Srwatson	    (macop_t)mac_biba_check_vnode_setacl },
2322101099Srwatson	{ MAC_CHECK_VNODE_SETEXTATTR,
2323101099Srwatson	    (macop_t)mac_biba_check_vnode_setextattr },
2324101099Srwatson	{ MAC_CHECK_VNODE_SETFLAGS,
2325101099Srwatson	    (macop_t)mac_biba_check_vnode_setflags },
2326101099Srwatson	{ MAC_CHECK_VNODE_SETMODE,
2327101099Srwatson	    (macop_t)mac_biba_check_vnode_setmode },
2328101099Srwatson	{ MAC_CHECK_VNODE_SETOWNER,
2329101099Srwatson	    (macop_t)mac_biba_check_vnode_setowner },
2330101099Srwatson	{ MAC_CHECK_VNODE_SETUTIMES,
2331101099Srwatson	    (macop_t)mac_biba_check_vnode_setutimes },
2332101099Srwatson	{ MAC_CHECK_VNODE_STAT,
2333101099Srwatson	    (macop_t)mac_biba_check_vnode_stat },
2334102112Srwatson	{ MAC_CHECK_VNODE_WRITE,
2335102112Srwatson	    (macop_t)mac_biba_check_vnode_write },
2336101099Srwatson	{ MAC_OP_LAST, NULL }
2337101099Srwatson};
2338101099Srwatson
2339101099SrwatsonMAC_POLICY_SET(mac_biba_ops, trustedbsd_mac_biba, "TrustedBSD MAC/Biba",
2340101099Srwatson    MPC_LOADTIME_FLAG_NOTLATE, &mac_biba_slot);
2341