mac_biba.c revision 103761
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 103761 2002-09-21 19:50:28Z 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
105101099Srwatsonstatic int	mac_biba_revocation_enabled = 0;
106101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, revocation_enabled, CTLFLAG_RW,
107101099Srwatson    &mac_biba_revocation_enabled, 0, "Revoke access to objects on relabel");
108101099SrwatsonTUNABLE_INT("security.mac.biba.revocation_enabled",
109101099Srwatson    &mac_biba_revocation_enabled);
110101099Srwatson
111101099Srwatsonstatic int	mac_biba_slot;
112101099Srwatson#define	SLOT(l)	((struct mac_biba *)LABEL_TO_SLOT((l), mac_biba_slot).l_ptr)
113101099Srwatson
114101099SrwatsonMALLOC_DEFINE(M_MACBIBA, "biba label", "MAC/Biba labels");
115101099Srwatson
116101099Srwatsonstatic int	mac_biba_check_vnode_open(struct ucred *cred, struct vnode *vp,
117101099Srwatson		    struct label *vnodelabel, mode_t acc_mode);
118101099Srwatson
119101099Srwatsonstatic struct mac_biba *
120101099Srwatsonbiba_alloc(int how)
121101099Srwatson{
122101099Srwatson	struct mac_biba *mac_biba;
123101099Srwatson
124101099Srwatson	mac_biba = malloc(sizeof(struct mac_biba), M_MACBIBA, M_ZERO | how);
125101099Srwatson
126101099Srwatson	return (mac_biba);
127101099Srwatson}
128101099Srwatson
129101099Srwatsonstatic void
130101099Srwatsonbiba_free(struct mac_biba *mac_biba)
131101099Srwatson{
132101099Srwatson
133101099Srwatson	if (mac_biba != NULL)
134101099Srwatson		free(mac_biba, M_MACBIBA);
135101099Srwatson	else
136101099Srwatson		atomic_add_int(&destroyed_not_inited, 1);
137101099Srwatson}
138101099Srwatson
139101099Srwatsonstatic int
140101099Srwatsonmac_biba_dominate_element(struct mac_biba_element *a,
141101099Srwatson    struct mac_biba_element *b)
142101099Srwatson{
143101099Srwatson
144101099Srwatson	switch(a->mbe_type) {
145101099Srwatson	case MAC_BIBA_TYPE_EQUAL:
146101099Srwatson	case MAC_BIBA_TYPE_HIGH:
147101099Srwatson		return (1);
148101099Srwatson
149101099Srwatson	case MAC_BIBA_TYPE_LOW:
150101099Srwatson		switch (b->mbe_type) {
151101099Srwatson		case MAC_BIBA_TYPE_GRADE:
152101099Srwatson		case MAC_BIBA_TYPE_HIGH:
153101099Srwatson			return (0);
154101099Srwatson
155101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
156101099Srwatson		case MAC_BIBA_TYPE_LOW:
157101099Srwatson			return (1);
158101099Srwatson
159101099Srwatson		default:
160101099Srwatson			panic("mac_biba_dominate_element: b->mbe_type invalid");
161101099Srwatson		}
162101099Srwatson
163101099Srwatson	case MAC_BIBA_TYPE_GRADE:
164101099Srwatson		switch (b->mbe_type) {
165101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
166101099Srwatson		case MAC_BIBA_TYPE_LOW:
167101099Srwatson			return (1);
168101099Srwatson
169101099Srwatson		case MAC_BIBA_TYPE_HIGH:
170101099Srwatson			return (0);
171101099Srwatson
172101099Srwatson		case MAC_BIBA_TYPE_GRADE:
173101099Srwatson			return (a->mbe_grade >= b->mbe_grade);
174101099Srwatson
175101099Srwatson		default:
176101099Srwatson			panic("mac_biba_dominate_element: b->mbe_type invalid");
177101099Srwatson		}
178101099Srwatson
179101099Srwatson	default:
180101099Srwatson		panic("mac_biba_dominate_element: a->mbe_type invalid");
181101099Srwatson	}
182101099Srwatson
183101099Srwatson	return (0);
184101099Srwatson}
185101099Srwatson
186101099Srwatsonstatic int
187101099Srwatsonmac_biba_range_in_range(struct mac_biba *rangea, struct mac_biba *rangeb)
188101099Srwatson{
189101099Srwatson
190101099Srwatson	return (mac_biba_dominate_element(&rangeb->mb_rangehigh,
191101099Srwatson	    &rangea->mb_rangehigh) &&
192101099Srwatson	    mac_biba_dominate_element(&rangea->mb_rangelow,
193101099Srwatson	    &rangeb->mb_rangelow));
194101099Srwatson}
195101099Srwatson
196101099Srwatsonstatic int
197101099Srwatsonmac_biba_single_in_range(struct mac_biba *single, struct mac_biba *range)
198101099Srwatson{
199101099Srwatson
200103750Srwatson	KASSERT((single->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
201101099Srwatson	    ("mac_biba_single_in_range: a not single"));
202103750Srwatson	KASSERT((range->mb_flags & MAC_BIBA_FLAG_RANGE) != 0,
203101099Srwatson	    ("mac_biba_single_in_range: b not range"));
204101099Srwatson
205101099Srwatson	return (mac_biba_dominate_element(&range->mb_rangehigh,
206101099Srwatson	    &single->mb_single) &&
207101099Srwatson	    mac_biba_dominate_element(&single->mb_single,
208101099Srwatson	    &range->mb_rangelow));
209101099Srwatson
210101099Srwatson	return (1);
211101099Srwatson}
212101099Srwatson
213101099Srwatsonstatic int
214101099Srwatsonmac_biba_dominate_single(struct mac_biba *a, struct mac_biba *b)
215101099Srwatson{
216101099Srwatson	KASSERT((a->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
217101099Srwatson	    ("mac_biba_dominate_single: a not single"));
218101099Srwatson	KASSERT((b->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
219101099Srwatson	    ("mac_biba_dominate_single: b not single"));
220101099Srwatson
221101099Srwatson	return (mac_biba_dominate_element(&a->mb_single, &b->mb_single));
222101099Srwatson}
223101099Srwatson
224101099Srwatsonstatic int
225101099Srwatsonmac_biba_equal_element(struct mac_biba_element *a, struct mac_biba_element *b)
226101099Srwatson{
227101099Srwatson
228101099Srwatson	if (a->mbe_type == MAC_BIBA_TYPE_EQUAL ||
229101099Srwatson	    b->mbe_type == MAC_BIBA_TYPE_EQUAL)
230101099Srwatson		return (1);
231101099Srwatson
232101099Srwatson	return (a->mbe_type == b->mbe_type && a->mbe_grade == b->mbe_grade);
233101099Srwatson}
234101099Srwatson
235101099Srwatsonstatic int
236101099Srwatsonmac_biba_equal_single(struct mac_biba *a, struct mac_biba *b)
237101099Srwatson{
238101099Srwatson
239101099Srwatson	KASSERT((a->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
240101099Srwatson	    ("mac_biba_equal_single: a not single"));
241101099Srwatson	KASSERT((b->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
242101099Srwatson	    ("mac_biba_equal_single: b not single"));
243101099Srwatson
244101099Srwatson	return (mac_biba_equal_element(&a->mb_single, &b->mb_single));
245101099Srwatson}
246101099Srwatson
247101099Srwatsonstatic int
248101099Srwatsonmac_biba_valid(struct mac_biba *mac_biba)
249101099Srwatson{
250101099Srwatson
251101099Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) {
252101099Srwatson		switch (mac_biba->mb_single.mbe_type) {
253101099Srwatson		case MAC_BIBA_TYPE_GRADE:
254101099Srwatson			break;
255101099Srwatson
256101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
257101099Srwatson		case MAC_BIBA_TYPE_HIGH:
258101099Srwatson		case MAC_BIBA_TYPE_LOW:
259101099Srwatson			if (mac_biba->mb_single.mbe_grade != 0)
260101099Srwatson				return (EINVAL);
261101099Srwatson			break;
262101099Srwatson
263101099Srwatson		default:
264101099Srwatson			return (EINVAL);
265101099Srwatson		}
266101099Srwatson	} else {
267101099Srwatson		if (mac_biba->mb_single.mbe_type != MAC_BIBA_TYPE_UNDEF)
268101099Srwatson			return (EINVAL);
269101099Srwatson	}
270101099Srwatson
271101099Srwatson	if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
272101099Srwatson		switch (mac_biba->mb_rangelow.mbe_type) {
273101099Srwatson		case MAC_BIBA_TYPE_GRADE:
274101099Srwatson			break;
275101099Srwatson
276101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
277101099Srwatson		case MAC_BIBA_TYPE_HIGH:
278101099Srwatson		case MAC_BIBA_TYPE_LOW:
279101099Srwatson			if (mac_biba->mb_rangelow.mbe_grade != 0)
280101099Srwatson				return (EINVAL);
281101099Srwatson			break;
282101099Srwatson
283101099Srwatson		default:
284101099Srwatson			return (EINVAL);
285101099Srwatson		}
286101099Srwatson
287101099Srwatson		switch (mac_biba->mb_rangehigh.mbe_type) {
288101099Srwatson		case MAC_BIBA_TYPE_GRADE:
289101099Srwatson			break;
290101099Srwatson
291101099Srwatson		case MAC_BIBA_TYPE_EQUAL:
292101099Srwatson		case MAC_BIBA_TYPE_HIGH:
293101099Srwatson		case MAC_BIBA_TYPE_LOW:
294101099Srwatson			if (mac_biba->mb_rangehigh.mbe_grade != 0)
295101099Srwatson				return (EINVAL);
296101099Srwatson			break;
297101099Srwatson
298101099Srwatson		default:
299101099Srwatson			return (EINVAL);
300101099Srwatson		}
301101099Srwatson		if (!mac_biba_dominate_element(&mac_biba->mb_rangehigh,
302101099Srwatson		    &mac_biba->mb_rangelow))
303101099Srwatson			return (EINVAL);
304101099Srwatson	} else {
305101099Srwatson		if (mac_biba->mb_rangelow.mbe_type != MAC_BIBA_TYPE_UNDEF ||
306101099Srwatson		    mac_biba->mb_rangehigh.mbe_type != MAC_BIBA_TYPE_UNDEF)
307101099Srwatson			return (EINVAL);
308101099Srwatson	}
309101099Srwatson
310101099Srwatson	return (0);
311101099Srwatson}
312101099Srwatson
313101099Srwatsonstatic void
314101099Srwatsonmac_biba_set_range(struct mac_biba *mac_biba, u_short typelow,
315101099Srwatson    u_short gradelow, u_short typehigh, u_short gradehigh)
316101099Srwatson{
317101099Srwatson
318101099Srwatson	mac_biba->mb_rangelow.mbe_type = typelow;
319101099Srwatson	mac_biba->mb_rangelow.mbe_grade = gradelow;
320101099Srwatson	mac_biba->mb_rangehigh.mbe_type = typehigh;
321101099Srwatson	mac_biba->mb_rangehigh.mbe_grade = gradehigh;
322101099Srwatson	mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE;
323101099Srwatson}
324101099Srwatson
325101099Srwatsonstatic void
326101099Srwatsonmac_biba_set_single(struct mac_biba *mac_biba, u_short type, u_short grade)
327101099Srwatson{
328101099Srwatson
329101099Srwatson	mac_biba->mb_single.mbe_type = type;
330101099Srwatson	mac_biba->mb_single.mbe_grade = grade;
331101099Srwatson	mac_biba->mb_flags |= MAC_BIBA_FLAG_SINGLE;
332101099Srwatson}
333101099Srwatson
334101099Srwatsonstatic void
335101099Srwatsonmac_biba_copy_range(struct mac_biba *labelfrom, struct mac_biba *labelto)
336101099Srwatson{
337101099Srwatson	KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_RANGE) != 0,
338101099Srwatson	    ("mac_biba_copy_range: labelfrom not range"));
339101099Srwatson
340101099Srwatson	labelto->mb_rangelow = labelfrom->mb_rangelow;
341101099Srwatson	labelto->mb_rangehigh = labelfrom->mb_rangehigh;
342101099Srwatson	labelto->mb_flags |= MAC_BIBA_FLAG_RANGE;
343101099Srwatson}
344101099Srwatson
345101099Srwatsonstatic void
346101099Srwatsonmac_biba_copy_single(struct mac_biba *labelfrom, struct mac_biba *labelto)
347101099Srwatson{
348101099Srwatson
349101099Srwatson	KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
350101099Srwatson	    ("mac_biba_copy_single: labelfrom not single"));
351101099Srwatson
352101099Srwatson	labelto->mb_single = labelfrom->mb_single;
353101099Srwatson	labelto->mb_flags |= MAC_BIBA_FLAG_SINGLE;
354101099Srwatson}
355101099Srwatson
356101099Srwatsonstatic void
357101099Srwatsonmac_biba_copy_single_to_range(struct mac_biba *labelfrom,
358101099Srwatson    struct mac_biba *labelto)
359101099Srwatson{
360101099Srwatson
361101099Srwatson	KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
362101099Srwatson	    ("mac_biba_copy_single_to_range: labelfrom not single"));
363101099Srwatson
364101099Srwatson	labelto->mb_rangelow = labelfrom->mb_single;
365101099Srwatson	labelto->mb_rangehigh = labelfrom->mb_single;
366101099Srwatson	labelto->mb_flags |= MAC_BIBA_FLAG_RANGE;
367101099Srwatson}
368101099Srwatson
369101099Srwatson/*
370101099Srwatson * Policy module operations.
371101099Srwatson */
372101099Srwatsonstatic void
373101099Srwatsonmac_biba_destroy(struct mac_policy_conf *conf)
374101099Srwatson{
375101099Srwatson
376101099Srwatson}
377101099Srwatson
378101099Srwatsonstatic void
379101099Srwatsonmac_biba_init(struct mac_policy_conf *conf)
380101099Srwatson{
381101099Srwatson
382101099Srwatson}
383101099Srwatson
384101099Srwatson/*
385101099Srwatson * Label operations.
386101099Srwatson */
387101099Srwatsonstatic void
388101099Srwatsonmac_biba_init_bpfdesc(struct bpf_d *bpf_d, struct label *label)
389101099Srwatson{
390101099Srwatson
391101099Srwatson	SLOT(label) = biba_alloc(M_WAITOK);
392101099Srwatson}
393101099Srwatson
394101099Srwatsonstatic void
395101099Srwatsonmac_biba_init_cred(struct ucred *ucred, struct label *label)
396101099Srwatson{
397101099Srwatson
398101099Srwatson	SLOT(label) = biba_alloc(M_WAITOK);
399101099Srwatson}
400101099Srwatson
401101099Srwatsonstatic void
402101099Srwatsonmac_biba_init_devfsdirent(struct devfs_dirent *devfs_dirent,
403101099Srwatson    struct label *label)
404101099Srwatson{
405101099Srwatson
406101099Srwatson	SLOT(label) = biba_alloc(M_WAITOK);
407101099Srwatson}
408101099Srwatson
409101099Srwatsonstatic void
410101099Srwatsonmac_biba_init_ifnet(struct ifnet *ifnet, struct label *label)
411101099Srwatson{
412101099Srwatson
413101099Srwatson	SLOT(label) = biba_alloc(M_WAITOK);
414101099Srwatson}
415101099Srwatson
416101099Srwatsonstatic void
417101099Srwatsonmac_biba_init_ipq(struct ipq *ipq, struct label *label)
418101099Srwatson{
419101099Srwatson
420101099Srwatson	SLOT(label) = biba_alloc(M_WAITOK);
421101099Srwatson}
422101099Srwatson
423101099Srwatsonstatic int
424101099Srwatsonmac_biba_init_mbuf(struct mbuf *mbuf, int how, struct label *label)
425101099Srwatson{
426101099Srwatson
427101099Srwatson	SLOT(label) = biba_alloc(how);
428101099Srwatson	if (SLOT(label) == NULL)
429101099Srwatson		return (ENOMEM);
430101099Srwatson
431101099Srwatson	return (0);
432101099Srwatson}
433101099Srwatson
434101099Srwatsonstatic void
435101099Srwatsonmac_biba_init_mount(struct mount *mount, struct label *mntlabel,
436101099Srwatson    struct label *fslabel)
437101099Srwatson{
438101099Srwatson
439101099Srwatson	SLOT(mntlabel) = biba_alloc(M_WAITOK);
440101099Srwatson	SLOT(fslabel) = biba_alloc(M_WAITOK);
441101099Srwatson}
442101099Srwatson
443101099Srwatsonstatic void
444101099Srwatsonmac_biba_init_socket(struct socket *socket, struct label *label,
445101099Srwatson    struct label *peerlabel)
446101099Srwatson{
447101099Srwatson
448101099Srwatson	SLOT(label) = biba_alloc(M_WAITOK);
449101099Srwatson	SLOT(peerlabel) = biba_alloc(M_WAITOK);
450101099Srwatson}
451101099Srwatson
452101099Srwatsonstatic void
453101099Srwatsonmac_biba_init_pipe(struct pipe *pipe, struct label *label)
454101099Srwatson{
455101099Srwatson
456101099Srwatson	SLOT(label) = biba_alloc(M_WAITOK);
457101099Srwatson}
458101099Srwatson
459101099Srwatsonstatic void
460101099Srwatsonmac_biba_init_temp(struct label *label)
461101099Srwatson{
462101099Srwatson
463101099Srwatson	SLOT(label) = biba_alloc(M_WAITOK);
464101099Srwatson}
465101099Srwatson
466101099Srwatsonstatic void
467101099Srwatsonmac_biba_init_vnode(struct vnode *vp, struct label *label)
468101099Srwatson{
469101099Srwatson
470101099Srwatson	SLOT(label) = biba_alloc(M_WAITOK);
471101099Srwatson}
472101099Srwatson
473101099Srwatsonstatic void
474101099Srwatsonmac_biba_destroy_bpfdesc(struct bpf_d *bpf_d, struct label *label)
475101099Srwatson{
476101099Srwatson
477101099Srwatson	biba_free(SLOT(label));
478101099Srwatson	SLOT(label) = NULL;
479101099Srwatson}
480101099Srwatson
481101099Srwatsonstatic void
482101099Srwatsonmac_biba_destroy_cred(struct ucred *ucred, struct label *label)
483101099Srwatson{
484101099Srwatson
485101099Srwatson	biba_free(SLOT(label));
486101099Srwatson	SLOT(label) = NULL;
487101099Srwatson}
488101099Srwatson
489101099Srwatsonstatic void
490101099Srwatsonmac_biba_destroy_devfsdirent(struct devfs_dirent *devfs_dirent,
491101099Srwatson    struct label *label)
492101099Srwatson{
493101099Srwatson
494101099Srwatson	biba_free(SLOT(label));
495101099Srwatson	SLOT(label) = NULL;
496101099Srwatson}
497101099Srwatson
498101099Srwatsonstatic void
499101099Srwatsonmac_biba_destroy_ifnet(struct ifnet *ifnet, struct label *label)
500101099Srwatson{
501101099Srwatson
502101099Srwatson	biba_free(SLOT(label));
503101099Srwatson	SLOT(label) = NULL;
504101099Srwatson}
505101099Srwatson
506101099Srwatsonstatic void
507101099Srwatsonmac_biba_destroy_ipq(struct ipq *ipq, struct label *label)
508101099Srwatson{
509101099Srwatson
510101099Srwatson	biba_free(SLOT(label));
511101099Srwatson	SLOT(label) = NULL;
512101099Srwatson}
513101099Srwatson
514101099Srwatsonstatic void
515101099Srwatsonmac_biba_destroy_mbuf(struct mbuf *mbuf, struct label *label)
516101099Srwatson{
517101099Srwatson
518101099Srwatson	biba_free(SLOT(label));
519101099Srwatson	SLOT(label) = NULL;
520101099Srwatson}
521101099Srwatson
522101099Srwatsonstatic void
523101099Srwatsonmac_biba_destroy_mount(struct mount *mount, struct label *mntlabel,
524101099Srwatson    struct label *fslabel)
525101099Srwatson{
526101099Srwatson
527101099Srwatson	biba_free(SLOT(mntlabel));
528101099Srwatson	SLOT(mntlabel) = NULL;
529101099Srwatson	biba_free(SLOT(fslabel));
530101099Srwatson	SLOT(fslabel) = NULL;
531101099Srwatson}
532101099Srwatson
533101099Srwatsonstatic void
534101099Srwatsonmac_biba_destroy_socket(struct socket *socket, struct label *label,
535101099Srwatson    struct label *peerlabel)
536101099Srwatson{
537101099Srwatson
538101099Srwatson	biba_free(SLOT(label));
539101099Srwatson	SLOT(label) = NULL;
540101099Srwatson	biba_free(SLOT(peerlabel));
541101099Srwatson	SLOT(peerlabel) = NULL;
542101099Srwatson}
543101099Srwatson
544101099Srwatsonstatic void
545101099Srwatsonmac_biba_destroy_pipe(struct pipe *pipe, struct label *label)
546101099Srwatson{
547101099Srwatson
548101099Srwatson	biba_free(SLOT(label));
549101099Srwatson	SLOT(label) = NULL;
550101099Srwatson}
551101099Srwatson
552101099Srwatsonstatic void
553101099Srwatsonmac_biba_destroy_temp(struct label *label)
554101099Srwatson{
555101099Srwatson
556101099Srwatson	biba_free(SLOT(label));
557101099Srwatson	SLOT(label) = NULL;
558101099Srwatson}
559101099Srwatson
560101099Srwatsonstatic void
561101099Srwatsonmac_biba_destroy_vnode(struct vnode *vp, struct label *label)
562101099Srwatson{
563101099Srwatson
564101099Srwatson	biba_free(SLOT(label));
565101099Srwatson	SLOT(label) = NULL;
566101099Srwatson}
567101099Srwatson
568101099Srwatsonstatic int
569101099Srwatsonmac_biba_externalize(struct label *label, struct mac *extmac)
570101099Srwatson{
571101099Srwatson	struct mac_biba *mac_biba;
572101099Srwatson
573101099Srwatson	mac_biba = SLOT(label);
574101099Srwatson
575101099Srwatson	if (mac_biba == NULL) {
576101099Srwatson		printf("mac_biba_externalize: NULL pointer\n");
577101099Srwatson		return (0);
578101099Srwatson	}
579101099Srwatson
580101099Srwatson	extmac->m_biba = *mac_biba;
581101099Srwatson
582101099Srwatson	return (0);
583101099Srwatson}
584101099Srwatson
585101099Srwatsonstatic int
586101099Srwatsonmac_biba_internalize(struct label *label, struct mac *extmac)
587101099Srwatson{
588101099Srwatson	struct mac_biba *mac_biba;
589101099Srwatson	int error;
590101099Srwatson
591101099Srwatson	mac_biba = SLOT(label);
592101099Srwatson
593101099Srwatson	error = mac_biba_valid(mac_biba);
594101099Srwatson	if (error)
595101099Srwatson		return (error);
596101099Srwatson
597101099Srwatson	*mac_biba = extmac->m_biba;
598101099Srwatson
599101099Srwatson	return (0);
600101099Srwatson}
601101099Srwatson
602101099Srwatson/*
603101099Srwatson * Labeling event operations: file system objects, and things that look
604101099Srwatson * a lot like file system objects.
605101099Srwatson */
606101099Srwatsonstatic void
607101099Srwatsonmac_biba_create_devfs_device(dev_t dev, struct devfs_dirent *devfs_dirent,
608101099Srwatson    struct label *label)
609101099Srwatson{
610101099Srwatson	struct mac_biba *mac_biba;
611101099Srwatson	int biba_type;
612101099Srwatson
613101099Srwatson	mac_biba = SLOT(label);
614101099Srwatson	if (strcmp(dev->si_name, "null") == 0 ||
615101099Srwatson	    strcmp(dev->si_name, "zero") == 0 ||
616101099Srwatson	    strcmp(dev->si_name, "random") == 0 ||
617101099Srwatson	    strncmp(dev->si_name, "fd/", strlen("fd/")) == 0)
618101099Srwatson		biba_type = MAC_BIBA_TYPE_EQUAL;
619101099Srwatson	else
620101099Srwatson		biba_type = MAC_BIBA_TYPE_HIGH;
621101099Srwatson	mac_biba_set_single(mac_biba, biba_type, 0);
622101099Srwatson}
623101099Srwatson
624101099Srwatsonstatic void
625101099Srwatsonmac_biba_create_devfs_directory(char *dirname, int dirnamelen,
626101099Srwatson    struct devfs_dirent *devfs_dirent, struct label *label)
627101099Srwatson{
628101099Srwatson	struct mac_biba *mac_biba;
629101099Srwatson
630101099Srwatson	mac_biba = SLOT(label);
631101099Srwatson	mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0);
632101099Srwatson}
633101099Srwatson
634101099Srwatsonstatic void
635101099Srwatsonmac_biba_create_devfs_vnode(struct devfs_dirent *devfs_dirent,
636101099Srwatson    struct label *direntlabel, struct vnode *vp, struct label *vnodelabel)
637101099Srwatson{
638101099Srwatson	struct mac_biba *source, *dest;
639101099Srwatson
640101099Srwatson	source = SLOT(direntlabel);
641101099Srwatson	dest = SLOT(vnodelabel);
642101099Srwatson	mac_biba_copy_single(source, dest);
643101099Srwatson}
644101099Srwatson
645101099Srwatsonstatic void
646101099Srwatsonmac_biba_create_vnode(struct ucred *cred, struct vnode *parent,
647101099Srwatson    struct label *parentlabel, struct vnode *child, struct label *childlabel)
648101099Srwatson{
649101099Srwatson	struct mac_biba *source, *dest;
650101099Srwatson
651101099Srwatson	source = SLOT(&cred->cr_label);
652101099Srwatson	dest = SLOT(childlabel);
653101099Srwatson
654101099Srwatson	mac_biba_copy_single(source, dest);
655101099Srwatson}
656101099Srwatson
657101099Srwatsonstatic void
658101099Srwatsonmac_biba_create_mount(struct ucred *cred, struct mount *mp,
659101099Srwatson    struct label *mntlabel, struct label *fslabel)
660101099Srwatson{
661101099Srwatson	struct mac_biba *source, *dest;
662101099Srwatson
663101099Srwatson	source = SLOT(&cred->cr_label);
664101099Srwatson	dest = SLOT(mntlabel);
665101099Srwatson	mac_biba_copy_single(source, dest);
666101099Srwatson	dest = SLOT(fslabel);
667101099Srwatson	mac_biba_copy_single(source, dest);
668101099Srwatson}
669101099Srwatson
670101099Srwatsonstatic void
671101099Srwatsonmac_biba_create_root_mount(struct ucred *cred, struct mount *mp,
672101099Srwatson    struct label *mntlabel, struct label *fslabel)
673101099Srwatson{
674101099Srwatson	struct mac_biba *mac_biba;
675101099Srwatson
676101099Srwatson	/* Always mount root as high integrity. */
677101099Srwatson	mac_biba = SLOT(fslabel);
678101099Srwatson	mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0);
679101099Srwatson	mac_biba = SLOT(mntlabel);
680101099Srwatson	mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0);
681101099Srwatson}
682101099Srwatson
683101099Srwatsonstatic void
684101099Srwatsonmac_biba_relabel_vnode(struct ucred *cred, struct vnode *vp,
685101099Srwatson    struct label *vnodelabel, struct label *label)
686101099Srwatson{
687101099Srwatson	struct mac_biba *source, *dest;
688101099Srwatson
689101099Srwatson	source = SLOT(label);
690101099Srwatson	dest = SLOT(vnodelabel);
691101099Srwatson
692101099Srwatson	mac_biba_copy_single(source, dest);
693101099Srwatson}
694101099Srwatson
695101099Srwatsonstatic void
696101099Srwatsonmac_biba_update_devfsdirent(struct devfs_dirent *devfs_dirent,
697101099Srwatson    struct label *direntlabel, struct vnode *vp, struct label *vnodelabel)
698101099Srwatson{
699101099Srwatson	struct mac_biba *source, *dest;
700101099Srwatson
701101099Srwatson	source = SLOT(vnodelabel);
702101099Srwatson	dest = SLOT(direntlabel);
703101099Srwatson
704101099Srwatson	mac_biba_copy_single(source, dest);
705101099Srwatson}
706101099Srwatson
707101099Srwatsonstatic void
708101099Srwatsonmac_biba_update_procfsvnode(struct vnode *vp, struct label *vnodelabel,
709101099Srwatson    struct ucred *cred)
710101099Srwatson{
711101099Srwatson	struct mac_biba *source, *dest;
712101099Srwatson
713101099Srwatson	source = SLOT(&cred->cr_label);
714101099Srwatson	dest = SLOT(vnodelabel);
715101099Srwatson
716101099Srwatson	/*
717101099Srwatson	 * Only copy the single, not the range, since vnodes only have
718101099Srwatson	 * a single.
719101099Srwatson	 */
720101099Srwatson	mac_biba_copy_single(source, dest);
721101099Srwatson}
722101099Srwatson
723101099Srwatsonstatic int
724101099Srwatsonmac_biba_update_vnode_from_externalized(struct vnode *vp,
725101099Srwatson    struct label *vnodelabel, struct mac *extmac)
726101099Srwatson{
727101099Srwatson	struct mac_biba *source, *dest;
728101099Srwatson	int error;
729101099Srwatson
730101099Srwatson	source = &extmac->m_biba;
731101099Srwatson	dest = SLOT(vnodelabel);
732101099Srwatson
733101099Srwatson	error = mac_biba_valid(source);
734101099Srwatson	if (error)
735101099Srwatson		return (error);
736101099Srwatson
737101099Srwatson	if ((source->mb_flags & MAC_BIBA_FLAGS_BOTH) != MAC_BIBA_FLAG_SINGLE)
738101099Srwatson		return (EINVAL);
739101099Srwatson
740101099Srwatson	mac_biba_copy_single(source, dest);
741101099Srwatson
742101099Srwatson	return (0);
743101099Srwatson}
744101099Srwatson
745101099Srwatsonstatic void
746101099Srwatsonmac_biba_update_vnode_from_mount(struct vnode *vp, struct label *vnodelabel,
747101099Srwatson    struct mount *mp, struct label *fslabel)
748101099Srwatson{
749101099Srwatson	struct mac_biba *source, *dest;
750101099Srwatson
751101099Srwatson	source = SLOT(fslabel);
752101099Srwatson	dest = SLOT(vnodelabel);
753101099Srwatson
754101099Srwatson	mac_biba_copy_single(source, dest);
755101099Srwatson}
756101099Srwatson
757101099Srwatson/*
758101099Srwatson * Labeling event operations: IPC object.
759101099Srwatson */
760101099Srwatsonstatic void
761101099Srwatsonmac_biba_create_mbuf_from_socket(struct socket *so, struct label *socketlabel,
762101099Srwatson    struct mbuf *m, struct label *mbuflabel)
763101099Srwatson{
764101099Srwatson	struct mac_biba *source, *dest;
765101099Srwatson
766101099Srwatson	source = SLOT(socketlabel);
767101099Srwatson	dest = SLOT(mbuflabel);
768101099Srwatson
769101099Srwatson	mac_biba_copy_single(source, dest);
770101099Srwatson}
771101099Srwatson
772101099Srwatsonstatic void
773101099Srwatsonmac_biba_create_socket(struct ucred *cred, struct socket *socket,
774101099Srwatson    struct label *socketlabel)
775101099Srwatson{
776101099Srwatson	struct mac_biba *source, *dest;
777101099Srwatson
778101099Srwatson	source = SLOT(&cred->cr_label);
779101099Srwatson	dest = SLOT(socketlabel);
780101099Srwatson
781101099Srwatson	mac_biba_copy_single(source, dest);
782101099Srwatson	mac_biba_copy_single_to_range(source, dest);
783101099Srwatson}
784101099Srwatson
785101099Srwatsonstatic void
786101099Srwatsonmac_biba_create_pipe(struct ucred *cred, struct pipe *pipe,
787101099Srwatson    struct label *pipelabel)
788101099Srwatson{
789101099Srwatson	struct mac_biba *source, *dest;
790101099Srwatson
791101099Srwatson	source = SLOT(&cred->cr_label);
792101099Srwatson	dest = SLOT(pipelabel);
793101099Srwatson
794101099Srwatson	mac_biba_copy_single(source, dest);
795101099Srwatson}
796101099Srwatson
797101099Srwatsonstatic void
798101099Srwatsonmac_biba_create_socket_from_socket(struct socket *oldsocket,
799101099Srwatson    struct label *oldsocketlabel, struct socket *newsocket,
800101099Srwatson    struct label *newsocketlabel)
801101099Srwatson{
802101099Srwatson	struct mac_biba *source, *dest;
803101099Srwatson
804101099Srwatson	source = SLOT(oldsocketlabel);
805101099Srwatson	dest = SLOT(newsocketlabel);
806101099Srwatson
807101099Srwatson	mac_biba_copy_single(source, dest);
808101099Srwatson	mac_biba_copy_range(source, dest);
809101099Srwatson}
810101099Srwatson
811101099Srwatsonstatic void
812101099Srwatsonmac_biba_relabel_socket(struct ucred *cred, struct socket *socket,
813101099Srwatson    struct label *socketlabel, struct label *newlabel)
814101099Srwatson{
815101099Srwatson	struct mac_biba *source, *dest;
816101099Srwatson
817101099Srwatson	source = SLOT(newlabel);
818101099Srwatson	dest = SLOT(socketlabel);
819101099Srwatson
820101099Srwatson	mac_biba_copy_single(source, dest);
821101099Srwatson	mac_biba_copy_range(source, dest);
822101099Srwatson}
823101099Srwatson
824101099Srwatsonstatic void
825101099Srwatsonmac_biba_relabel_pipe(struct ucred *cred, struct pipe *pipe,
826101099Srwatson    struct label *pipelabel, struct label *newlabel)
827101099Srwatson{
828101099Srwatson	struct mac_biba *source, *dest;
829101099Srwatson
830101099Srwatson	source = SLOT(newlabel);
831101099Srwatson	dest = SLOT(pipelabel);
832101099Srwatson
833101099Srwatson	mac_biba_copy_single(source, dest);
834101099Srwatson}
835101099Srwatson
836101099Srwatsonstatic void
837101099Srwatsonmac_biba_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel,
838101099Srwatson    struct socket *socket, struct label *socketpeerlabel)
839101099Srwatson{
840101099Srwatson	struct mac_biba *source, *dest;
841101099Srwatson
842101099Srwatson	source = SLOT(mbuflabel);
843101099Srwatson	dest = SLOT(socketpeerlabel);
844101099Srwatson
845101099Srwatson	mac_biba_copy_single(source, dest);
846101099Srwatson}
847101099Srwatson
848101099Srwatson/*
849101099Srwatson * Labeling event operations: network objects.
850101099Srwatson */
851101099Srwatsonstatic void
852101099Srwatsonmac_biba_set_socket_peer_from_socket(struct socket *oldsocket,
853101099Srwatson    struct label *oldsocketlabel, struct socket *newsocket,
854101099Srwatson    struct label *newsocketpeerlabel)
855101099Srwatson{
856101099Srwatson	struct mac_biba *source, *dest;
857101099Srwatson
858101099Srwatson	source = SLOT(oldsocketlabel);
859101099Srwatson	dest = SLOT(newsocketpeerlabel);
860101099Srwatson
861101099Srwatson	mac_biba_copy_single(source, dest);
862101099Srwatson}
863101099Srwatson
864101099Srwatsonstatic void
865101099Srwatsonmac_biba_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d,
866101099Srwatson    struct label *bpflabel)
867101099Srwatson{
868101099Srwatson	struct mac_biba *source, *dest;
869101099Srwatson
870101099Srwatson	source = SLOT(&cred->cr_label);
871101099Srwatson	dest = SLOT(bpflabel);
872101099Srwatson
873101099Srwatson	mac_biba_copy_single(source, dest);
874101099Srwatson}
875101099Srwatson
876101099Srwatsonstatic void
877101099Srwatsonmac_biba_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel)
878101099Srwatson{
879101099Srwatson	char tifname[IFNAMSIZ], ifname[IFNAMSIZ], *p, *q;
880101099Srwatson	char tiflist[sizeof(trusted_interfaces)];
881101099Srwatson	struct mac_biba *dest;
882101099Srwatson	int len, grade;
883101099Srwatson
884101099Srwatson	dest = SLOT(ifnetlabel);
885101099Srwatson
886101099Srwatson	if (ifnet->if_type == IFT_LOOP) {
887101099Srwatson		grade = MAC_BIBA_TYPE_EQUAL;
888101099Srwatson		goto set;
889101099Srwatson	}
890101099Srwatson
891101099Srwatson	if (trust_all_interfaces) {
892101099Srwatson		grade = MAC_BIBA_TYPE_HIGH;
893101099Srwatson		goto set;
894101099Srwatson	}
895101099Srwatson
896101099Srwatson	grade = MAC_BIBA_TYPE_LOW;
897101099Srwatson
898101099Srwatson	if (trusted_interfaces[0] == '\0' ||
899101099Srwatson	    !strvalid(trusted_interfaces, sizeof(trusted_interfaces)))
900101099Srwatson		goto set;
901101099Srwatson
902101099Srwatson	for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++)
903101099Srwatson		if(*p != ' ' && *p != '\t')
904101099Srwatson			*q = *p;
905101099Srwatson
906101099Srwatson	snprintf(ifname, IFNAMSIZ, "%s%d", ifnet->if_name, ifnet->if_unit);
907101099Srwatson
908101099Srwatson	for (p = q = tiflist;; p++) {
909101099Srwatson		if (*p == ',' || *p == '\0') {
910101099Srwatson			len = p - q;
911101099Srwatson			if (len < IFNAMSIZ) {
912101099Srwatson				bzero(tifname, sizeof(tifname));
913101099Srwatson				bcopy(q, tifname, len);
914101099Srwatson				if (strcmp(tifname, ifname) == 0) {
915101099Srwatson					grade = MAC_BIBA_TYPE_HIGH;
916101099Srwatson					break;
917101099Srwatson				}
918101099Srwatson			}
919101099Srwatson			if (*p == '\0')
920101099Srwatson				break;
921101099Srwatson			q = p + 1;
922101099Srwatson		}
923101099Srwatson	}
924101099Srwatsonset:
925101099Srwatson	mac_biba_set_single(dest, grade, 0);
926101099Srwatson	mac_biba_set_range(dest, grade, 0, grade, 0);
927101099Srwatson}
928101099Srwatson
929101099Srwatsonstatic void
930101099Srwatsonmac_biba_create_ipq(struct mbuf *fragment, struct label *fragmentlabel,
931101099Srwatson    struct ipq *ipq, struct label *ipqlabel)
932101099Srwatson{
933101099Srwatson	struct mac_biba *source, *dest;
934101099Srwatson
935101099Srwatson	source = SLOT(fragmentlabel);
936101099Srwatson	dest = SLOT(ipqlabel);
937101099Srwatson
938101099Srwatson	mac_biba_copy_single(source, dest);
939101099Srwatson}
940101099Srwatson
941101099Srwatsonstatic void
942101099Srwatsonmac_biba_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel,
943101099Srwatson    struct mbuf *datagram, struct label *datagramlabel)
944101099Srwatson{
945101099Srwatson	struct mac_biba *source, *dest;
946101099Srwatson
947101099Srwatson	source = SLOT(ipqlabel);
948101099Srwatson	dest = SLOT(datagramlabel);
949101099Srwatson
950101099Srwatson	/* Just use the head, since we require them all to match. */
951101099Srwatson	mac_biba_copy_single(source, dest);
952101099Srwatson}
953101099Srwatson
954101099Srwatsonstatic void
955101099Srwatsonmac_biba_create_fragment(struct mbuf *datagram, struct label *datagramlabel,
956101099Srwatson    struct mbuf *fragment, struct label *fragmentlabel)
957101099Srwatson{
958101099Srwatson	struct mac_biba *source, *dest;
959101099Srwatson
960101099Srwatson	source = SLOT(datagramlabel);
961101099Srwatson	dest = SLOT(fragmentlabel);
962101099Srwatson
963101099Srwatson	mac_biba_copy_single(source, dest);
964101099Srwatson}
965101099Srwatson
966101099Srwatsonstatic void
967101099Srwatsonmac_biba_create_mbuf_from_mbuf(struct mbuf *oldmbuf,
968101099Srwatson    struct label *oldmbuflabel, struct mbuf *newmbuf,
969101099Srwatson    struct label *newmbuflabel)
970101099Srwatson{
971101099Srwatson	struct mac_biba *source, *dest;
972101099Srwatson
973101099Srwatson	source = SLOT(oldmbuflabel);
974101099Srwatson	dest = SLOT(newmbuflabel);
975101099Srwatson
976101099Srwatson	mac_biba_copy_single(source, dest);
977101099Srwatson}
978101099Srwatson
979101099Srwatsonstatic void
980101099Srwatsonmac_biba_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel,
981101099Srwatson    struct mbuf *mbuf, struct label *mbuflabel)
982101099Srwatson{
983101099Srwatson	struct mac_biba *dest;
984101099Srwatson
985101099Srwatson	dest = SLOT(mbuflabel);
986101099Srwatson
987101099Srwatson	mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0);
988101099Srwatson}
989101099Srwatson
990101099Srwatsonstatic void
991101099Srwatsonmac_biba_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel,
992101099Srwatson    struct mbuf *mbuf, struct label *mbuflabel)
993101099Srwatson{
994101099Srwatson	struct mac_biba *source, *dest;
995101099Srwatson
996101099Srwatson	source = SLOT(bpflabel);
997101099Srwatson	dest = SLOT(mbuflabel);
998101099Srwatson
999101099Srwatson	mac_biba_copy_single(source, dest);
1000101099Srwatson}
1001101099Srwatson
1002101099Srwatsonstatic void
1003101099Srwatsonmac_biba_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel,
1004101099Srwatson    struct mbuf *m, struct label *mbuflabel)
1005101099Srwatson{
1006101099Srwatson	struct mac_biba *source, *dest;
1007101099Srwatson
1008101099Srwatson	source = SLOT(ifnetlabel);
1009101099Srwatson	dest = SLOT(mbuflabel);
1010101099Srwatson
1011101099Srwatson	mac_biba_copy_single(source, dest);
1012101099Srwatson}
1013101099Srwatson
1014101099Srwatsonstatic void
1015101099Srwatsonmac_biba_create_mbuf_multicast_encap(struct mbuf *oldmbuf,
1016101099Srwatson    struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel,
1017101099Srwatson    struct mbuf *newmbuf, struct label *newmbuflabel)
1018101099Srwatson{
1019101099Srwatson	struct mac_biba *source, *dest;
1020101099Srwatson
1021101099Srwatson	source = SLOT(oldmbuflabel);
1022101099Srwatson	dest = SLOT(newmbuflabel);
1023101099Srwatson
1024101099Srwatson	mac_biba_copy_single(source, dest);
1025101099Srwatson}
1026101099Srwatson
1027101099Srwatsonstatic void
1028101099Srwatsonmac_biba_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel,
1029101099Srwatson    struct mbuf *newmbuf, struct label *newmbuflabel)
1030101099Srwatson{
1031101099Srwatson	struct mac_biba *source, *dest;
1032101099Srwatson
1033101099Srwatson	source = SLOT(oldmbuflabel);
1034101099Srwatson	dest = SLOT(newmbuflabel);
1035101099Srwatson
1036101099Srwatson	mac_biba_copy_single(source, dest);
1037101099Srwatson}
1038101099Srwatson
1039101099Srwatsonstatic int
1040101099Srwatsonmac_biba_fragment_match(struct mbuf *fragment, struct label *fragmentlabel,
1041101099Srwatson    struct ipq *ipq, struct label *ipqlabel)
1042101099Srwatson{
1043101099Srwatson	struct mac_biba *a, *b;
1044101099Srwatson
1045101099Srwatson	a = SLOT(ipqlabel);
1046101099Srwatson	b = SLOT(fragmentlabel);
1047101099Srwatson
1048101099Srwatson	return (mac_biba_equal_single(a, b));
1049101099Srwatson}
1050101099Srwatson
1051101099Srwatsonstatic void
1052101099Srwatsonmac_biba_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet,
1053101099Srwatson    struct label *ifnetlabel, struct label *newlabel)
1054101099Srwatson{
1055101099Srwatson	struct mac_biba *source, *dest;
1056101099Srwatson
1057101099Srwatson	source = SLOT(newlabel);
1058101099Srwatson	dest = SLOT(ifnetlabel);
1059101099Srwatson
1060101099Srwatson	mac_biba_copy_single(source, dest);
1061101099Srwatson	mac_biba_copy_range(source, dest);
1062101099Srwatson}
1063101099Srwatson
1064101099Srwatsonstatic void
1065101099Srwatsonmac_biba_update_ipq(struct mbuf *fragment, struct label *fragmentlabel,
1066101099Srwatson    struct ipq *ipq, struct label *ipqlabel)
1067101099Srwatson{
1068101099Srwatson
1069101099Srwatson	/* NOOP: we only accept matching labels, so no need to update */
1070101099Srwatson}
1071101099Srwatson
1072101099Srwatson/*
1073101099Srwatson * Labeling event operations: processes.
1074101099Srwatson */
1075101099Srwatsonstatic void
1076101099Srwatsonmac_biba_create_cred(struct ucred *cred_parent, struct ucred *cred_child)
1077101099Srwatson{
1078101099Srwatson	struct mac_biba *source, *dest;
1079101099Srwatson
1080101099Srwatson	source = SLOT(&cred_parent->cr_label);
1081101099Srwatson	dest = SLOT(&cred_child->cr_label);
1082101099Srwatson
1083101099Srwatson	mac_biba_copy_single(source, dest);
1084101099Srwatson	mac_biba_copy_range(source, dest);
1085101099Srwatson}
1086101099Srwatson
1087101099Srwatsonstatic void
1088101099Srwatsonmac_biba_execve_transition(struct ucred *old, struct ucred *new,
1089101099Srwatson    struct vnode *vp, struct mac *vnodelabel)
1090101099Srwatson{
1091101099Srwatson	struct mac_biba *source, *dest;
1092101099Srwatson
1093101099Srwatson	source = SLOT(&old->cr_label);
1094101099Srwatson	dest = SLOT(&new->cr_label);
1095101099Srwatson
1096101099Srwatson	mac_biba_copy_single(source, dest);
1097101099Srwatson	mac_biba_copy_range(source, dest);
1098101099Srwatson}
1099101099Srwatson
1100101099Srwatsonstatic int
1101101099Srwatsonmac_biba_execve_will_transition(struct ucred *old, struct vnode *vp,
1102101099Srwatson    struct mac *vnodelabel)
1103101099Srwatson{
1104101099Srwatson
1105101099Srwatson	return (0);
1106101099Srwatson}
1107101099Srwatson
1108101099Srwatsonstatic void
1109101099Srwatsonmac_biba_create_proc0(struct ucred *cred)
1110101099Srwatson{
1111101099Srwatson	struct mac_biba *dest;
1112101099Srwatson
1113101099Srwatson	dest = SLOT(&cred->cr_label);
1114101099Srwatson
1115101099Srwatson	mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0);
1116101099Srwatson	mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, MAC_BIBA_TYPE_HIGH, 0);
1117101099Srwatson}
1118101099Srwatson
1119101099Srwatsonstatic void
1120101099Srwatsonmac_biba_create_proc1(struct ucred *cred)
1121101099Srwatson{
1122101099Srwatson	struct mac_biba *dest;
1123101099Srwatson
1124101099Srwatson	dest = SLOT(&cred->cr_label);
1125101099Srwatson
1126101099Srwatson	mac_biba_set_single(dest, MAC_BIBA_TYPE_HIGH, 0);
1127101099Srwatson	mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, MAC_BIBA_TYPE_HIGH, 0);
1128101099Srwatson}
1129101099Srwatson
1130101099Srwatsonstatic void
1131101099Srwatsonmac_biba_relabel_cred(struct ucred *cred, struct label *newlabel)
1132101099Srwatson{
1133101099Srwatson	struct mac_biba *source, *dest;
1134101099Srwatson
1135101099Srwatson	source = SLOT(newlabel);
1136101099Srwatson	dest = SLOT(&cred->cr_label);
1137101099Srwatson
1138101099Srwatson	mac_biba_copy_single(source, dest);
1139101099Srwatson	mac_biba_copy_range(source, dest);
1140101099Srwatson}
1141101099Srwatson
1142101099Srwatson/*
1143101099Srwatson * Access control checks.
1144101099Srwatson */
1145101099Srwatsonstatic int
1146101099Srwatsonmac_biba_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel,
1147101099Srwatson    struct ifnet *ifnet, struct label *ifnetlabel)
1148101099Srwatson{
1149101099Srwatson	struct mac_biba *a, *b;
1150101099Srwatson
1151101099Srwatson	if (!mac_biba_enabled)
1152101099Srwatson		return (0);
1153101099Srwatson
1154101099Srwatson	a = SLOT(bpflabel);
1155101099Srwatson	b = SLOT(ifnetlabel);
1156101099Srwatson
1157101099Srwatson	if (mac_biba_equal_single(a, b))
1158101099Srwatson		return (0);
1159101099Srwatson	return (EACCES);
1160101099Srwatson}
1161101099Srwatson
1162101099Srwatsonstatic int
1163101099Srwatsonmac_biba_check_cred_relabel(struct ucred *cred, struct label *newlabel)
1164101099Srwatson{
1165101099Srwatson	struct mac_biba *subj, *new;
1166101099Srwatson
1167101099Srwatson	subj = SLOT(&cred->cr_label);
1168101099Srwatson	new = SLOT(newlabel);
1169101099Srwatson
1170101099Srwatson	if ((new->mb_flags & MAC_BIBA_FLAGS_BOTH) != MAC_BIBA_FLAGS_BOTH)
1171101099Srwatson		return (EINVAL);
1172101099Srwatson
1173101099Srwatson	/*
1174101099Srwatson	 * XXX: Allow processes with root privilege to set labels outside
1175101099Srwatson	 * their range, so suid things like "su" work.  This WILL go away
1176101099Srwatson	 * when we figure out the 'correct' solution...
1177101099Srwatson	 */
1178101099Srwatson	if (!suser_cred(cred, 0))
1179101099Srwatson		return (0);
1180101099Srwatson
1181101099Srwatson	/*
1182101099Srwatson	 * The new single must be in the old range.
1183101099Srwatson	 */
1184101099Srwatson	if (!mac_biba_single_in_range(new, subj))
1185101099Srwatson		return (EPERM);
1186101099Srwatson
1187101099Srwatson	/*
1188101099Srwatson	 * The new range must be in the old range.
1189101099Srwatson	 */
1190101099Srwatson	if (!mac_biba_range_in_range(new, subj))
1191101099Srwatson		return (EPERM);
1192101099Srwatson
1193101099Srwatson	/*
1194101099Srwatson	 * XXX: Don't permit EQUAL in a label unless the subject has EQUAL.
1195101099Srwatson	 */
1196101099Srwatson
1197101099Srwatson	return (0);
1198101099Srwatson}
1199101099Srwatson
1200101099Srwatsonstatic int
1201101099Srwatsonmac_biba_check_cred_visible(struct ucred *u1, struct ucred *u2)
1202101099Srwatson{
1203101099Srwatson	struct mac_biba *subj, *obj;
1204101099Srwatson
1205101099Srwatson	if (!mac_biba_enabled)
1206101099Srwatson		return (0);
1207101099Srwatson
1208101099Srwatson	subj = SLOT(&u1->cr_label);
1209101099Srwatson	obj = SLOT(&u2->cr_label);
1210101099Srwatson
1211101099Srwatson	/* XXX: range */
1212101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1213101099Srwatson		return (ESRCH);
1214101099Srwatson
1215101099Srwatson	return (0);
1216101099Srwatson}
1217101099Srwatson
1218101099Srwatsonstatic int
1219101099Srwatsonmac_biba_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet,
1220101099Srwatson    struct label *ifnetlabel, struct label *newlabel)
1221101099Srwatson{
1222101099Srwatson	struct mac_biba *subj, *new;
1223101099Srwatson
1224101099Srwatson	subj = SLOT(&cred->cr_label);
1225101099Srwatson	new = SLOT(newlabel);
1226101099Srwatson
1227101099Srwatson	if ((new->mb_flags & MAC_BIBA_FLAGS_BOTH) != MAC_BIBA_FLAGS_BOTH)
1228101099Srwatson		return (EINVAL);
1229101099Srwatson
1230101099Srwatson	return (suser_cred(cred, 0));
1231101099Srwatson}
1232101099Srwatson
1233103759Srwatsonstatic int
1234101099Srwatsonmac_biba_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel,
1235101099Srwatson    struct mbuf *m, struct label *mbuflabel)
1236101099Srwatson{
1237101099Srwatson	struct mac_biba *p, *i;
1238103761Srwatson
1239101099Srwatson	if (!mac_biba_enabled)
1240101099Srwatson		return (0);
1241101099Srwatson
1242101099Srwatson	p = SLOT(mbuflabel);
1243101099Srwatson	i = SLOT(ifnetlabel);
1244103759Srwatson
1245101099Srwatson	return (mac_biba_single_in_range(p, i) ? 0 : EACCES);
1246101099Srwatson}
1247101099Srwatson
1248101099Srwatsonstatic int
1249101099Srwatsonmac_biba_check_mount_stat(struct ucred *cred, struct mount *mp,
1250101099Srwatson    struct label *mntlabel)
1251101099Srwatson{
1252101099Srwatson	struct mac_biba *subj, *obj;
1253101099Srwatson
1254101099Srwatson	if (!mac_biba_enabled)
1255101099Srwatson		return (0);
1256101099Srwatson
1257101099Srwatson	subj = SLOT(&cred->cr_label);
1258101099Srwatson	obj = SLOT(mntlabel);
1259101099Srwatson
1260101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1261101099Srwatson		return (EACCES);
1262101099Srwatson
1263101099Srwatson	return (0);
1264101099Srwatson}
1265101099Srwatson
1266101099Srwatsonstatic int
1267101099Srwatsonmac_biba_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe,
1268101099Srwatson    struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data)
1269101099Srwatson{
1270103759Srwatson
1271101099Srwatson	if(!mac_biba_enabled)
1272101099Srwatson		return (0);
1273101099Srwatson
1274101099Srwatson	/* XXX: This will be implemented soon... */
1275101099Srwatson
1276101099Srwatson	return (0);
1277101099Srwatson}
1278101099Srwatson
1279101099Srwatsonstatic int
1280102115Srwatsonmac_biba_check_pipe_poll(struct ucred *cred, struct pipe *pipe,
1281102115Srwatson    struct label *pipelabel)
1282101099Srwatson{
1283101099Srwatson	struct mac_biba *subj, *obj;
1284101099Srwatson
1285101099Srwatson	if (!mac_biba_enabled)
1286101099Srwatson		return (0);
1287101099Srwatson
1288101099Srwatson	subj = SLOT(&cred->cr_label);
1289101099Srwatson	obj = SLOT((pipelabel));
1290101099Srwatson
1291102115Srwatson	if (!mac_biba_dominate_single(obj, subj))
1292102115Srwatson		return (EACCES);
1293101099Srwatson
1294101099Srwatson	return (0);
1295101099Srwatson}
1296101099Srwatson
1297101099Srwatsonstatic int
1298102115Srwatsonmac_biba_check_pipe_read(struct ucred *cred, struct pipe *pipe,
1299102115Srwatson    struct label *pipelabel)
1300102115Srwatson{
1301102115Srwatson	struct mac_biba *subj, *obj;
1302102115Srwatson
1303102115Srwatson	if (!mac_biba_enabled)
1304102115Srwatson		return (0);
1305102115Srwatson
1306102115Srwatson	subj = SLOT(&cred->cr_label);
1307102115Srwatson	obj = SLOT((pipelabel));
1308102115Srwatson
1309102115Srwatson	if (!mac_biba_dominate_single(obj, subj))
1310102115Srwatson		return (EACCES);
1311102115Srwatson
1312102115Srwatson	return (0);
1313102115Srwatson}
1314102115Srwatson
1315102115Srwatsonstatic int
1316101099Srwatsonmac_biba_check_pipe_relabel(struct ucred *cred, struct pipe *pipe,
1317101099Srwatson    struct label *pipelabel, struct label *newlabel)
1318101099Srwatson{
1319101099Srwatson	struct mac_biba *subj, *obj, *new;
1320101099Srwatson
1321101099Srwatson	new = SLOT(newlabel);
1322101099Srwatson	subj = SLOT(&cred->cr_label);
1323101099Srwatson	obj = SLOT(pipelabel);
1324101099Srwatson
1325101099Srwatson	if ((new->mb_flags & MAC_BIBA_FLAGS_BOTH) != MAC_BIBA_FLAG_SINGLE)
1326101099Srwatson		return (EINVAL);
1327101099Srwatson
1328101099Srwatson	/*
1329101099Srwatson	 * To relabel a pipe, the old pipe label must be in the subject
1330101099Srwatson	 * range.
1331101099Srwatson	 */
1332101099Srwatson	if (!mac_biba_single_in_range(obj, subj))
1333101099Srwatson		return (EPERM);
1334101099Srwatson
1335101099Srwatson	/*
1336101099Srwatson	 * To relabel a pipe, the new pipe label must be in the subject
1337101099Srwatson	 * range.
1338101099Srwatson	 */
1339101099Srwatson	if (!mac_biba_single_in_range(new, subj))
1340101099Srwatson		return (EPERM);
1341101099Srwatson
1342101099Srwatson	/*
1343101099Srwatson	 * XXX: Don't permit EQUAL in a label unless the subject has EQUAL.
1344101099Srwatson	 */
1345101099Srwatson
1346101099Srwatson	return (0);
1347101099Srwatson}
1348101099Srwatson
1349101099Srwatsonstatic int
1350102115Srwatsonmac_biba_check_pipe_stat(struct ucred *cred, struct pipe *pipe,
1351102115Srwatson    struct label *pipelabel)
1352102115Srwatson{
1353102115Srwatson	struct mac_biba *subj, *obj;
1354102115Srwatson
1355102115Srwatson	if (!mac_biba_enabled)
1356102115Srwatson		return (0);
1357102115Srwatson
1358102115Srwatson	subj = SLOT(&cred->cr_label);
1359102115Srwatson	obj = SLOT((pipelabel));
1360102115Srwatson
1361102115Srwatson	if (!mac_biba_dominate_single(obj, subj))
1362102115Srwatson		return (EACCES);
1363102115Srwatson
1364102115Srwatson	return (0);
1365102115Srwatson}
1366102115Srwatson
1367102115Srwatsonstatic int
1368102115Srwatsonmac_biba_check_pipe_write(struct ucred *cred, struct pipe *pipe,
1369102115Srwatson    struct label *pipelabel)
1370102115Srwatson{
1371102115Srwatson	struct mac_biba *subj, *obj;
1372102115Srwatson
1373102115Srwatson	if (!mac_biba_enabled)
1374102115Srwatson		return (0);
1375102115Srwatson
1376102115Srwatson	subj = SLOT(&cred->cr_label);
1377102115Srwatson	obj = SLOT((pipelabel));
1378102115Srwatson
1379102115Srwatson	if (!mac_biba_dominate_single(subj, obj))
1380102115Srwatson		return (EACCES);
1381102115Srwatson
1382102115Srwatson	return (0);
1383102115Srwatson}
1384102115Srwatson
1385102115Srwatsonstatic int
1386101099Srwatsonmac_biba_check_proc_debug(struct ucred *cred, struct proc *proc)
1387101099Srwatson{
1388101099Srwatson	struct mac_biba *subj, *obj;
1389101099Srwatson
1390101099Srwatson	if (!mac_biba_enabled)
1391101099Srwatson		return (0);
1392101099Srwatson
1393101099Srwatson	subj = SLOT(&cred->cr_label);
1394101099Srwatson	obj = SLOT(&proc->p_ucred->cr_label);
1395101099Srwatson
1396101099Srwatson	/* XXX: range checks */
1397101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1398101099Srwatson		return (ESRCH);
1399101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1400101099Srwatson		return (EACCES);
1401101099Srwatson
1402101099Srwatson	return (0);
1403101099Srwatson}
1404101099Srwatson
1405101099Srwatsonstatic int
1406101099Srwatsonmac_biba_check_proc_sched(struct ucred *cred, struct proc *proc)
1407101099Srwatson{
1408101099Srwatson	struct mac_biba *subj, *obj;
1409103759Srwatson
1410101099Srwatson	if (!mac_biba_enabled)
1411101099Srwatson		return (0);
1412101099Srwatson
1413101099Srwatson	subj = SLOT(&cred->cr_label);
1414101099Srwatson	obj = SLOT(&proc->p_ucred->cr_label);
1415103759Srwatson
1416101099Srwatson	/* XXX: range checks */
1417101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1418101099Srwatson		return (ESRCH);
1419101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1420101099Srwatson		return (EACCES);
1421101099Srwatson
1422101099Srwatson	return (0);
1423101099Srwatson}
1424101099Srwatson
1425101099Srwatsonstatic int
1426101099Srwatsonmac_biba_check_proc_signal(struct ucred *cred, struct proc *proc, int signum)
1427101099Srwatson{
1428101099Srwatson	struct mac_biba *subj, *obj;
1429103759Srwatson
1430101099Srwatson	if (!mac_biba_enabled)
1431101099Srwatson		return (0);
1432101099Srwatson
1433101099Srwatson	subj = SLOT(&cred->cr_label);
1434101099Srwatson	obj = SLOT(&proc->p_ucred->cr_label);
1435103759Srwatson
1436101099Srwatson	/* XXX: range checks */
1437101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1438101099Srwatson		return (ESRCH);
1439101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1440101099Srwatson		return (EACCES);
1441101099Srwatson
1442101099Srwatson	return (0);
1443101099Srwatson}
1444101099Srwatson
1445101099Srwatsonstatic int
1446101934Srwatsonmac_biba_check_socket_deliver(struct socket *so, struct label *socketlabel,
1447101099Srwatson    struct mbuf *m, struct label *mbuflabel)
1448101099Srwatson{
1449101099Srwatson	struct mac_biba *p, *s;
1450101099Srwatson
1451101099Srwatson	if (!mac_biba_enabled)
1452101099Srwatson		return (0);
1453101099Srwatson
1454101099Srwatson	p = SLOT(mbuflabel);
1455101099Srwatson	s = SLOT(socketlabel);
1456101099Srwatson
1457101099Srwatson	return (mac_biba_equal_single(p, s) ? 0 : EACCES);
1458101099Srwatson}
1459101099Srwatson
1460101099Srwatsonstatic int
1461101099Srwatsonmac_biba_check_socket_relabel(struct ucred *cred, struct socket *socket,
1462101099Srwatson    struct label *socketlabel, struct label *newlabel)
1463101099Srwatson{
1464101099Srwatson	struct mac_biba *subj, *obj, *new;
1465101099Srwatson
1466101099Srwatson	new = SLOT(newlabel);
1467101099Srwatson	subj = SLOT(&cred->cr_label);
1468101099Srwatson	obj = SLOT(socketlabel);
1469101099Srwatson
1470101099Srwatson	if ((new->mb_flags & MAC_BIBA_FLAGS_BOTH) != MAC_BIBA_FLAG_SINGLE)
1471101099Srwatson		return (EINVAL);
1472101099Srwatson
1473101099Srwatson	/*
1474101099Srwatson	 * To relabel a socket, the old socket label must be in the subject
1475101099Srwatson	 * range.
1476101099Srwatson	 */
1477101099Srwatson	if (!mac_biba_single_in_range(obj, subj))
1478101099Srwatson		return (EPERM);
1479101099Srwatson
1480101099Srwatson	/*
1481101099Srwatson	 * To relabel a socket, the new socket label must be in the subject
1482101099Srwatson	 * range.
1483101099Srwatson	 */
1484101099Srwatson	if (!mac_biba_single_in_range(new, subj))
1485101099Srwatson		return (EPERM);
1486101099Srwatson
1487101099Srwatson	/*
1488101099Srwatson	 * XXX: Don't permit EQUAL in a label unless the subject has EQUAL.
1489101099Srwatson	 */
1490101099Srwatson
1491101099Srwatson	return (0);
1492101099Srwatson}
1493101099Srwatson
1494101099Srwatsonstatic int
1495101099Srwatsonmac_biba_check_socket_visible(struct ucred *cred, struct socket *socket,
1496101099Srwatson    struct label *socketlabel)
1497101099Srwatson{
1498101099Srwatson	struct mac_biba *subj, *obj;
1499101099Srwatson
1500101099Srwatson	subj = SLOT(&cred->cr_label);
1501101099Srwatson	obj = SLOT(socketlabel);
1502101099Srwatson
1503101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1504101099Srwatson		return (ENOENT);
1505101099Srwatson
1506101099Srwatson	return (0);
1507101099Srwatson}
1508101099Srwatson
1509101099Srwatsonstatic int
1510101099Srwatsonmac_biba_check_vnode_access(struct ucred *cred, struct vnode *vp,
1511101099Srwatson    struct label *label, mode_t flags)
1512101099Srwatson{
1513101099Srwatson
1514101099Srwatson	return (mac_biba_check_vnode_open(cred, vp, label, flags));
1515101099Srwatson}
1516101099Srwatson
1517101099Srwatsonstatic int
1518101099Srwatsonmac_biba_check_vnode_chdir(struct ucred *cred, struct vnode *dvp,
1519101099Srwatson    struct label *dlabel)
1520101099Srwatson{
1521101099Srwatson	struct mac_biba *subj, *obj;
1522101099Srwatson
1523101099Srwatson	if (!mac_biba_enabled)
1524101099Srwatson		return (0);
1525101099Srwatson
1526101099Srwatson	subj = SLOT(&cred->cr_label);
1527101099Srwatson	obj = SLOT(dlabel);
1528101099Srwatson
1529101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1530101099Srwatson		return (EACCES);
1531101099Srwatson
1532101099Srwatson	return (0);
1533101099Srwatson}
1534101099Srwatson
1535101099Srwatsonstatic int
1536101099Srwatsonmac_biba_check_vnode_chroot(struct ucred *cred, struct vnode *dvp,
1537101099Srwatson    struct label *dlabel)
1538101099Srwatson{
1539101099Srwatson	struct mac_biba *subj, *obj;
1540101099Srwatson
1541101099Srwatson	if (!mac_biba_enabled)
1542101099Srwatson		return (0);
1543101099Srwatson
1544101099Srwatson	subj = SLOT(&cred->cr_label);
1545101099Srwatson	obj = SLOT(dlabel);
1546101099Srwatson
1547101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1548101099Srwatson		return (EACCES);
1549101099Srwatson
1550101099Srwatson	return (0);
1551101099Srwatson}
1552101099Srwatson
1553101099Srwatsonstatic int
1554101099Srwatsonmac_biba_check_vnode_create(struct ucred *cred, struct vnode *dvp,
1555101099Srwatson    struct label *dlabel, struct componentname *cnp, struct vattr *vap)
1556101099Srwatson{
1557101099Srwatson	struct mac_biba *subj, *obj;
1558101099Srwatson
1559101099Srwatson	if (!mac_biba_enabled)
1560101099Srwatson		return (0);
1561101099Srwatson
1562101099Srwatson	subj = SLOT(&cred->cr_label);
1563101099Srwatson	obj = SLOT(dlabel);
1564101099Srwatson
1565101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1566101099Srwatson		return (EACCES);
1567101099Srwatson
1568101099Srwatson	return (0);
1569101099Srwatson}
1570101099Srwatson
1571101099Srwatsonstatic int
1572101099Srwatsonmac_biba_check_vnode_delete(struct ucred *cred, struct vnode *dvp,
1573101099Srwatson    struct label *dlabel, struct vnode *vp, struct label *label,
1574101099Srwatson    struct componentname *cnp)
1575101099Srwatson{
1576101099Srwatson	struct mac_biba *subj, *obj;
1577101099Srwatson
1578101099Srwatson	if (!mac_biba_enabled)
1579101099Srwatson		return (0);
1580101099Srwatson
1581101099Srwatson	subj = SLOT(&cred->cr_label);
1582101099Srwatson	obj = SLOT(dlabel);
1583101099Srwatson
1584101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1585101099Srwatson		return (EACCES);
1586101099Srwatson
1587101099Srwatson	obj = SLOT(label);
1588101099Srwatson
1589101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1590101099Srwatson		return (EACCES);
1591101099Srwatson
1592101099Srwatson	return (0);
1593101099Srwatson}
1594101099Srwatson
1595101099Srwatsonstatic int
1596101099Srwatsonmac_biba_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
1597101099Srwatson    struct label *label, acl_type_t type)
1598101099Srwatson{
1599101099Srwatson	struct mac_biba *subj, *obj;
1600101099Srwatson
1601101099Srwatson	if (!mac_biba_enabled)
1602101099Srwatson		return (0);
1603101099Srwatson
1604101099Srwatson	subj = SLOT(&cred->cr_label);
1605101099Srwatson	obj = SLOT(label);
1606101099Srwatson
1607101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1608101099Srwatson		return (EACCES);
1609101099Srwatson
1610101099Srwatson	return (0);
1611101099Srwatson}
1612101099Srwatson
1613101099Srwatsonstatic int
1614101099Srwatsonmac_biba_check_vnode_exec(struct ucred *cred, struct vnode *vp,
1615101099Srwatson    struct label *label)
1616101099Srwatson{
1617101099Srwatson	struct mac_biba *subj, *obj;
1618101099Srwatson
1619101099Srwatson	if (!mac_biba_enabled)
1620101099Srwatson		return (0);
1621101099Srwatson
1622101099Srwatson	subj = SLOT(&cred->cr_label);
1623101099Srwatson	obj = SLOT(label);
1624101099Srwatson
1625101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1626101099Srwatson		return (EACCES);
1627101099Srwatson
1628101099Srwatson	return (0);
1629101099Srwatson}
1630101099Srwatson
1631101099Srwatsonstatic int
1632101099Srwatsonmac_biba_check_vnode_getacl(struct ucred *cred, struct vnode *vp,
1633101099Srwatson    struct label *label, acl_type_t type)
1634101099Srwatson{
1635101099Srwatson	struct mac_biba *subj, *obj;
1636101099Srwatson
1637101099Srwatson	if (!mac_biba_enabled)
1638101099Srwatson		return (0);
1639101099Srwatson
1640101099Srwatson	subj = SLOT(&cred->cr_label);
1641101099Srwatson	obj = SLOT(label);
1642101099Srwatson
1643101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1644101099Srwatson		return (EACCES);
1645101099Srwatson
1646101099Srwatson	return (0);
1647101099Srwatson}
1648101099Srwatson
1649101099Srwatsonstatic int
1650101099Srwatsonmac_biba_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
1651101099Srwatson    struct label *label, int attrnamespace, const char *name, struct uio *uio)
1652101099Srwatson{
1653101099Srwatson	struct mac_biba *subj, *obj;
1654101099Srwatson
1655101099Srwatson	if (!mac_biba_enabled)
1656101099Srwatson		return (0);
1657101099Srwatson
1658101099Srwatson	subj = SLOT(&cred->cr_label);
1659101099Srwatson	obj = SLOT(label);
1660101099Srwatson
1661101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1662101099Srwatson		return (EACCES);
1663101099Srwatson
1664101099Srwatson	return (0);
1665101099Srwatson}
1666101099Srwatson
1667101099Srwatsonstatic int
1668103759Srwatsonmac_biba_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
1669101099Srwatson    struct label *dlabel, struct componentname *cnp)
1670101099Srwatson{
1671101099Srwatson	struct mac_biba *subj, *obj;
1672103759Srwatson
1673101099Srwatson	if (!mac_biba_enabled)
1674101099Srwatson		return (0);
1675103759Srwatson
1676101099Srwatson	subj = SLOT(&cred->cr_label);
1677101099Srwatson	obj = SLOT(dlabel);
1678103759Srwatson
1679101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1680101099Srwatson		return (EACCES);
1681101099Srwatson
1682103759Srwatson	return (0);
1683101099Srwatson}
1684101099Srwatson
1685101099Srwatsonstatic int
1686101099Srwatsonmac_biba_check_vnode_open(struct ucred *cred, struct vnode *vp,
1687101099Srwatson    struct label *vnodelabel, mode_t acc_mode)
1688101099Srwatson{
1689101099Srwatson	struct mac_biba *subj, *obj;
1690101099Srwatson
1691101099Srwatson	if (!mac_biba_enabled)
1692101099Srwatson		return (0);
1693101099Srwatson
1694101099Srwatson	subj = SLOT(&cred->cr_label);
1695101099Srwatson	obj = SLOT(vnodelabel);
1696101099Srwatson
1697101099Srwatson	/* XXX privilege override for admin? */
1698101099Srwatson	if (acc_mode & (VREAD | VEXEC | VSTAT)) {
1699101099Srwatson		if (!mac_biba_dominate_single(obj, subj))
1700101099Srwatson			return (EACCES);
1701101099Srwatson	}
1702101099Srwatson	if (acc_mode & (VWRITE | VAPPEND | VADMIN)) {
1703101099Srwatson		if (!mac_biba_dominate_single(subj, obj))
1704101099Srwatson			return (EACCES);
1705101099Srwatson	}
1706101099Srwatson
1707101099Srwatson	return (0);
1708101099Srwatson}
1709101099Srwatson
1710101099Srwatsonstatic int
1711102129Srwatsonmac_biba_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred,
1712102129Srwatson    struct vnode *vp, struct label *label)
1713102112Srwatson{
1714102112Srwatson	struct mac_biba *subj, *obj;
1715102112Srwatson
1716102112Srwatson	if (!mac_biba_enabled || !mac_biba_revocation_enabled)
1717102112Srwatson		return (0);
1718102112Srwatson
1719102129Srwatson	subj = SLOT(&active_cred->cr_label);
1720102112Srwatson	obj = SLOT(label);
1721102112Srwatson
1722102112Srwatson	if (!mac_biba_dominate_single(obj, subj))
1723102112Srwatson		return (EACCES);
1724102112Srwatson
1725102112Srwatson	return (0);
1726102112Srwatson}
1727102112Srwatson
1728102112Srwatsonstatic int
1729102129Srwatsonmac_biba_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
1730102129Srwatson    struct vnode *vp, struct label *label)
1731102112Srwatson{
1732102112Srwatson	struct mac_biba *subj, *obj;
1733102112Srwatson
1734102112Srwatson	if (!mac_biba_enabled || !mac_biba_revocation_enabled)
1735102112Srwatson		return (0);
1736102112Srwatson
1737102129Srwatson	subj = SLOT(&active_cred->cr_label);
1738102112Srwatson	obj = SLOT(label);
1739102112Srwatson
1740102112Srwatson	if (!mac_biba_dominate_single(obj, subj))
1741102112Srwatson		return (EACCES);
1742102112Srwatson
1743102112Srwatson	return (0);
1744102112Srwatson}
1745102112Srwatson
1746102112Srwatsonstatic int
1747101099Srwatsonmac_biba_check_vnode_readdir(struct ucred *cred, struct vnode *dvp,
1748101099Srwatson    struct label *dlabel)
1749101099Srwatson{
1750101099Srwatson	struct mac_biba *subj, *obj;
1751101099Srwatson
1752101099Srwatson	if (!mac_biba_enabled)
1753101099Srwatson		return (0);
1754101099Srwatson
1755101099Srwatson	subj = SLOT(&cred->cr_label);
1756101099Srwatson	obj = SLOT(dlabel);
1757101099Srwatson
1758101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1759101099Srwatson		return (EACCES);
1760101099Srwatson
1761101099Srwatson	return (0);
1762101099Srwatson}
1763101099Srwatson
1764101099Srwatsonstatic int
1765101099Srwatsonmac_biba_check_vnode_readlink(struct ucred *cred, struct vnode *vp,
1766101099Srwatson    struct label *label)
1767101099Srwatson{
1768101099Srwatson	struct mac_biba *subj, *obj;
1769101099Srwatson
1770101099Srwatson	if (!mac_biba_enabled)
1771101099Srwatson		return (0);
1772101099Srwatson
1773101099Srwatson	subj = SLOT(&cred->cr_label);
1774101099Srwatson	obj = SLOT(label);
1775101099Srwatson
1776101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
1777101099Srwatson		return (EACCES);
1778101099Srwatson
1779101099Srwatson	return (0);
1780101099Srwatson}
1781101099Srwatson
1782101099Srwatsonstatic int
1783101099Srwatsonmac_biba_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
1784101099Srwatson    struct label *vnodelabel, struct label *newlabel)
1785101099Srwatson{
1786101099Srwatson	struct mac_biba *old, *new, *subj;
1787101099Srwatson
1788101099Srwatson	old = SLOT(vnodelabel);
1789101099Srwatson	new = SLOT(newlabel);
1790101099Srwatson	subj = SLOT(&cred->cr_label);
1791101099Srwatson
1792101099Srwatson	if ((new->mb_flags & MAC_BIBA_FLAGS_BOTH) != MAC_BIBA_FLAG_SINGLE)
1793101099Srwatson		return (EINVAL);
1794101099Srwatson
1795101099Srwatson	/*
1796101099Srwatson	 * To relabel a vnode, the old vnode label must be in the subject
1797101099Srwatson	 * range.
1798101099Srwatson	 */
1799101099Srwatson	if (!mac_biba_single_in_range(old, subj))
1800101099Srwatson		return (EPERM);
1801101099Srwatson
1802101099Srwatson	/*
1803101099Srwatson	 * To relabel a vnode, the new vnode label must be in the subject
1804101099Srwatson	 * range.
1805101099Srwatson	 */
1806101099Srwatson	if (!mac_biba_single_in_range(new, subj))
1807101099Srwatson		return (EPERM);
1808101099Srwatson
1809101099Srwatson	/*
1810101099Srwatson	 * XXX: Don't permit EQUAL in a label unless the subject has EQUAL.
1811101099Srwatson	 */
1812101099Srwatson
1813101099Srwatson	return (suser_cred(cred, 0));
1814101099Srwatson}
1815101099Srwatson
1816101099Srwatsonstatic int
1817101099Srwatsonmac_biba_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
1818101099Srwatson    struct label *dlabel, struct vnode *vp, struct label *label,
1819101099Srwatson    struct componentname *cnp)
1820101099Srwatson{
1821101099Srwatson	struct mac_biba *subj, *obj;
1822101099Srwatson
1823101099Srwatson	if (!mac_biba_enabled)
1824101099Srwatson		return (0);
1825101099Srwatson
1826101099Srwatson	subj = SLOT(&cred->cr_label);
1827101099Srwatson	obj = SLOT(dlabel);
1828101099Srwatson
1829101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1830101099Srwatson		return (EACCES);
1831101099Srwatson
1832101099Srwatson	obj = SLOT(label);
1833101099Srwatson
1834101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1835101099Srwatson		return (EACCES);
1836101099Srwatson
1837101099Srwatson	return (0);
1838101099Srwatson}
1839101099Srwatson
1840101099Srwatsonstatic int
1841101099Srwatsonmac_biba_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
1842101099Srwatson    struct label *dlabel, struct vnode *vp, struct label *label, int samedir,
1843101099Srwatson    struct componentname *cnp)
1844101099Srwatson{
1845101099Srwatson	struct mac_biba *subj, *obj;
1846101099Srwatson
1847101099Srwatson	if (!mac_biba_enabled)
1848101099Srwatson		return (0);
1849101099Srwatson
1850101099Srwatson	subj = SLOT(&cred->cr_label);
1851101099Srwatson	obj = SLOT(dlabel);
1852101099Srwatson
1853101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1854101099Srwatson		return (EACCES);
1855101099Srwatson
1856101099Srwatson	if (vp != NULL) {
1857101099Srwatson		obj = SLOT(label);
1858101099Srwatson
1859101099Srwatson		if (!mac_biba_dominate_single(subj, obj))
1860101099Srwatson			return (EACCES);
1861101099Srwatson	}
1862101099Srwatson
1863101099Srwatson	return (0);
1864101099Srwatson}
1865101099Srwatson
1866101099Srwatsonstatic int
1867101099Srwatsonmac_biba_check_vnode_revoke(struct ucred *cred, struct vnode *vp,
1868101099Srwatson    struct label *label)
1869101099Srwatson{
1870101099Srwatson	struct mac_biba *subj, *obj;
1871101099Srwatson
1872101099Srwatson	if (!mac_biba_enabled)
1873101099Srwatson		return (0);
1874101099Srwatson
1875101099Srwatson	subj = SLOT(&cred->cr_label);
1876101099Srwatson	obj = SLOT(label);
1877101099Srwatson
1878101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1879101099Srwatson		return (EACCES);
1880101099Srwatson
1881101099Srwatson	return (0);
1882101099Srwatson}
1883101099Srwatson
1884101099Srwatsonstatic int
1885101099Srwatsonmac_biba_check_vnode_setacl(struct ucred *cred, struct vnode *vp,
1886101099Srwatson    struct label *label, acl_type_t type, struct acl *acl)
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(label);
1895101099Srwatson
1896101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1897101099Srwatson		return (EACCES);
1898101099Srwatson
1899101099Srwatson	return (0);
1900101099Srwatson}
1901101099Srwatson
1902101099Srwatsonstatic int
1903101099Srwatsonmac_biba_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
1904101099Srwatson    struct label *vnodelabel, int attrnamespace, const char *name,
1905101099Srwatson    struct uio *uio)
1906101099Srwatson{
1907101099Srwatson	struct mac_biba *subj, *obj;
1908101099Srwatson
1909101099Srwatson	if (!mac_biba_enabled)
1910101099Srwatson		return (0);
1911101099Srwatson
1912101099Srwatson	subj = SLOT(&cred->cr_label);
1913101099Srwatson	obj = SLOT(vnodelabel);
1914101099Srwatson
1915101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1916101099Srwatson		return (EACCES);
1917101099Srwatson
1918101099Srwatson	/* XXX: protect the MAC EA in a special way? */
1919101099Srwatson
1920101099Srwatson	return (0);
1921101099Srwatson}
1922101099Srwatson
1923101099Srwatsonstatic int
1924101099Srwatsonmac_biba_check_vnode_setflags(struct ucred *cred, struct vnode *vp,
1925101099Srwatson    struct label *vnodelabel, u_long flags)
1926101099Srwatson{
1927101099Srwatson	struct mac_biba *subj, *obj;
1928101099Srwatson
1929101099Srwatson	if (!mac_biba_enabled)
1930101099Srwatson		return (0);
1931101099Srwatson
1932101099Srwatson	subj = SLOT(&cred->cr_label);
1933101099Srwatson	obj = SLOT(vnodelabel);
1934101099Srwatson
1935101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1936101099Srwatson		return (EACCES);
1937101099Srwatson
1938101099Srwatson	return (0);
1939101099Srwatson}
1940101099Srwatson
1941101099Srwatsonstatic int
1942101099Srwatsonmac_biba_check_vnode_setmode(struct ucred *cred, struct vnode *vp,
1943101099Srwatson    struct label *vnodelabel, mode_t mode)
1944101099Srwatson{
1945101099Srwatson	struct mac_biba *subj, *obj;
1946101099Srwatson
1947101099Srwatson	if (!mac_biba_enabled)
1948101099Srwatson		return (0);
1949101099Srwatson
1950101099Srwatson	subj = SLOT(&cred->cr_label);
1951101099Srwatson	obj = SLOT(vnodelabel);
1952101099Srwatson
1953101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1954101099Srwatson		return (EACCES);
1955101099Srwatson
1956101099Srwatson	return (0);
1957101099Srwatson}
1958101099Srwatson
1959101099Srwatsonstatic int
1960101099Srwatsonmac_biba_check_vnode_setowner(struct ucred *cred, struct vnode *vp,
1961101099Srwatson    struct label *vnodelabel, uid_t uid, gid_t gid)
1962101099Srwatson{
1963101099Srwatson	struct mac_biba *subj, *obj;
1964101099Srwatson
1965101099Srwatson	if (!mac_biba_enabled)
1966101099Srwatson		return (0);
1967101099Srwatson
1968101099Srwatson	subj = SLOT(&cred->cr_label);
1969101099Srwatson	obj = SLOT(vnodelabel);
1970101099Srwatson
1971101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1972101099Srwatson		return (EACCES);
1973101099Srwatson
1974101099Srwatson	return (0);
1975101099Srwatson}
1976101099Srwatson
1977101099Srwatsonstatic int
1978101099Srwatsonmac_biba_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
1979101099Srwatson    struct label *vnodelabel, struct timespec atime, struct timespec mtime)
1980101099Srwatson{
1981101099Srwatson	struct mac_biba *subj, *obj;
1982101099Srwatson
1983101099Srwatson	if (!mac_biba_enabled)
1984101099Srwatson		return (0);
1985101099Srwatson
1986101099Srwatson	subj = SLOT(&cred->cr_label);
1987101099Srwatson	obj = SLOT(vnodelabel);
1988101099Srwatson
1989101099Srwatson	if (!mac_biba_dominate_single(subj, obj))
1990101099Srwatson		return (EACCES);
1991101099Srwatson
1992101099Srwatson	return (0);
1993101099Srwatson}
1994101099Srwatson
1995101099Srwatsonstatic int
1996102129Srwatsonmac_biba_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
1997102129Srwatson    struct vnode *vp, struct label *vnodelabel)
1998101099Srwatson{
1999101099Srwatson	struct mac_biba *subj, *obj;
2000101099Srwatson
2001101099Srwatson	if (!mac_biba_enabled)
2002101099Srwatson		return (0);
2003101099Srwatson
2004102129Srwatson	subj = SLOT(&active_cred->cr_label);
2005101099Srwatson	obj = SLOT(vnodelabel);
2006101099Srwatson
2007101099Srwatson	if (!mac_biba_dominate_single(obj, subj))
2008101099Srwatson		return (EACCES);
2009101099Srwatson
2010101099Srwatson	return (0);
2011101099Srwatson}
2012101099Srwatson
2013102112Srwatsonstatic int
2014102129Srwatsonmac_biba_check_vnode_write(struct ucred *active_cred,
2015102129Srwatson    struct ucred *file_cred, struct vnode *vp, struct label *label)
2016102112Srwatson{
2017102112Srwatson	struct mac_biba *subj, *obj;
2018102112Srwatson
2019102112Srwatson	if (!mac_biba_enabled || !mac_biba_revocation_enabled)
2020102112Srwatson		return (0);
2021102112Srwatson
2022102129Srwatson	subj = SLOT(&active_cred->cr_label);
2023102112Srwatson	obj = SLOT(label);
2024102112Srwatson
2025102112Srwatson	if (!mac_biba_dominate_single(subj, obj))
2026102112Srwatson		return (EACCES);
2027102112Srwatson
2028102112Srwatson	return (0);
2029102112Srwatson}
2030102112Srwatson
2031101099Srwatsonstatic vm_prot_t
2032101099Srwatsonmac_biba_check_vnode_mmap_perms(struct ucred *cred, struct vnode *vp,
2033101099Srwatson    struct label *label, int newmapping)
2034101099Srwatson{
2035101099Srwatson	struct mac_biba *subj, *obj;
2036101099Srwatson	vm_prot_t prot = 0;
2037101099Srwatson
2038101099Srwatson	if (!mac_biba_enabled || (!mac_biba_revocation_enabled && !newmapping))
2039101099Srwatson		return (VM_PROT_ALL);
2040101099Srwatson
2041101099Srwatson	subj = SLOT(&cred->cr_label);
2042101099Srwatson	obj = SLOT(label);
2043101099Srwatson
2044101099Srwatson	if (mac_biba_dominate_single(obj, subj))
2045101099Srwatson		prot |= VM_PROT_READ | VM_PROT_EXECUTE;
2046101099Srwatson	if (mac_biba_dominate_single(subj, obj))
2047101099Srwatson		prot |= VM_PROT_WRITE;
2048101099Srwatson	return (prot);
2049101099Srwatson}
2050101099Srwatson
2051101099Srwatsonstatic struct mac_policy_op_entry mac_biba_ops[] =
2052101099Srwatson{
2053101099Srwatson	{ MAC_DESTROY,
2054101099Srwatson	    (macop_t)mac_biba_destroy },
2055101099Srwatson	{ MAC_INIT,
2056101099Srwatson	    (macop_t)mac_biba_init },
2057101099Srwatson	{ MAC_INIT_BPFDESC,
2058101099Srwatson	    (macop_t)mac_biba_init_bpfdesc },
2059101099Srwatson	{ MAC_INIT_CRED,
2060101099Srwatson	    (macop_t)mac_biba_init_cred },
2061101099Srwatson	{ MAC_INIT_DEVFSDIRENT,
2062101099Srwatson	    (macop_t)mac_biba_init_devfsdirent },
2063101099Srwatson	{ MAC_INIT_IFNET,
2064101099Srwatson	    (macop_t)mac_biba_init_ifnet },
2065101099Srwatson	{ MAC_INIT_IPQ,
2066101099Srwatson	    (macop_t)mac_biba_init_ipq },
2067101099Srwatson	{ MAC_INIT_MBUF,
2068101099Srwatson	    (macop_t)mac_biba_init_mbuf },
2069101099Srwatson	{ MAC_INIT_MOUNT,
2070101099Srwatson	    (macop_t)mac_biba_init_mount },
2071101099Srwatson	{ MAC_INIT_PIPE,
2072101099Srwatson	    (macop_t)mac_biba_init_pipe },
2073101099Srwatson	{ MAC_INIT_SOCKET,
2074101099Srwatson	    (macop_t)mac_biba_init_socket },
2075101099Srwatson	{ MAC_INIT_TEMP,
2076101099Srwatson	    (macop_t)mac_biba_init_temp },
2077101099Srwatson	{ MAC_INIT_VNODE,
2078101099Srwatson	    (macop_t)mac_biba_init_vnode },
2079101099Srwatson	{ MAC_DESTROY_BPFDESC,
2080101099Srwatson	    (macop_t)mac_biba_destroy_bpfdesc },
2081101099Srwatson	{ MAC_DESTROY_CRED,
2082101099Srwatson	    (macop_t)mac_biba_destroy_cred },
2083101099Srwatson	{ MAC_DESTROY_DEVFSDIRENT,
2084101099Srwatson	    (macop_t)mac_biba_destroy_devfsdirent },
2085101099Srwatson	{ MAC_DESTROY_IFNET,
2086101099Srwatson	    (macop_t)mac_biba_destroy_ifnet },
2087101099Srwatson	{ MAC_DESTROY_IPQ,
2088101099Srwatson	    (macop_t)mac_biba_destroy_ipq },
2089101099Srwatson	{ MAC_DESTROY_MBUF,
2090101099Srwatson	    (macop_t)mac_biba_destroy_mbuf },
2091101099Srwatson	{ MAC_DESTROY_MOUNT,
2092101099Srwatson	    (macop_t)mac_biba_destroy_mount },
2093101099Srwatson	{ MAC_DESTROY_PIPE,
2094101099Srwatson	    (macop_t)mac_biba_destroy_pipe },
2095101099Srwatson	{ MAC_DESTROY_SOCKET,
2096101099Srwatson	    (macop_t)mac_biba_destroy_socket },
2097101099Srwatson	{ MAC_DESTROY_TEMP,
2098101099Srwatson	    (macop_t)mac_biba_destroy_temp },
2099101099Srwatson	{ MAC_DESTROY_VNODE,
2100101099Srwatson	    (macop_t)mac_biba_destroy_vnode },
2101101099Srwatson	{ MAC_EXTERNALIZE,
2102101099Srwatson	    (macop_t)mac_biba_externalize },
2103101099Srwatson	{ MAC_INTERNALIZE,
2104101099Srwatson	    (macop_t)mac_biba_internalize },
2105101099Srwatson	{ MAC_CREATE_DEVFS_DEVICE,
2106101099Srwatson	    (macop_t)mac_biba_create_devfs_device },
2107101099Srwatson	{ MAC_CREATE_DEVFS_DIRECTORY,
2108101099Srwatson	    (macop_t)mac_biba_create_devfs_directory },
2109101099Srwatson	{ MAC_CREATE_DEVFS_VNODE,
2110101099Srwatson	    (macop_t)mac_biba_create_devfs_vnode },
2111101099Srwatson	{ MAC_CREATE_VNODE,
2112101099Srwatson	    (macop_t)mac_biba_create_vnode },
2113101099Srwatson	{ MAC_CREATE_MOUNT,
2114101099Srwatson	    (macop_t)mac_biba_create_mount },
2115101099Srwatson	{ MAC_CREATE_ROOT_MOUNT,
2116101099Srwatson	    (macop_t)mac_biba_create_root_mount },
2117101099Srwatson	{ MAC_RELABEL_VNODE,
2118101099Srwatson	    (macop_t)mac_biba_relabel_vnode },
2119101099Srwatson	{ MAC_UPDATE_DEVFSDIRENT,
2120101099Srwatson	    (macop_t)mac_biba_update_devfsdirent },
2121101099Srwatson	{ MAC_UPDATE_PROCFSVNODE,
2122101099Srwatson	    (macop_t)mac_biba_update_procfsvnode },
2123101099Srwatson	{ MAC_UPDATE_VNODE_FROM_EXTERNALIZED,
2124101099Srwatson	    (macop_t)mac_biba_update_vnode_from_externalized },
2125101099Srwatson	{ MAC_UPDATE_VNODE_FROM_MOUNT,
2126101099Srwatson	    (macop_t)mac_biba_update_vnode_from_mount },
2127101099Srwatson	{ MAC_CREATE_MBUF_FROM_SOCKET,
2128101099Srwatson	    (macop_t)mac_biba_create_mbuf_from_socket },
2129101099Srwatson	{ MAC_CREATE_PIPE,
2130101099Srwatson	    (macop_t)mac_biba_create_pipe },
2131101099Srwatson	{ MAC_CREATE_SOCKET,
2132101099Srwatson	    (macop_t)mac_biba_create_socket },
2133101099Srwatson	{ MAC_CREATE_SOCKET_FROM_SOCKET,
2134101099Srwatson	    (macop_t)mac_biba_create_socket_from_socket },
2135101099Srwatson	{ MAC_RELABEL_PIPE,
2136101099Srwatson	    (macop_t)mac_biba_relabel_pipe },
2137101099Srwatson	{ MAC_RELABEL_SOCKET,
2138101099Srwatson	    (macop_t)mac_biba_relabel_socket },
2139101099Srwatson	{ MAC_SET_SOCKET_PEER_FROM_MBUF,
2140101099Srwatson	    (macop_t)mac_biba_set_socket_peer_from_mbuf },
2141101099Srwatson	{ MAC_SET_SOCKET_PEER_FROM_SOCKET,
2142101099Srwatson	    (macop_t)mac_biba_set_socket_peer_from_socket },
2143101099Srwatson	{ MAC_CREATE_BPFDESC,
2144101099Srwatson	    (macop_t)mac_biba_create_bpfdesc },
2145101099Srwatson	{ MAC_CREATE_DATAGRAM_FROM_IPQ,
2146101099Srwatson	    (macop_t)mac_biba_create_datagram_from_ipq },
2147101099Srwatson	{ MAC_CREATE_FRAGMENT,
2148101099Srwatson	    (macop_t)mac_biba_create_fragment },
2149101099Srwatson	{ MAC_CREATE_IFNET,
2150101099Srwatson	    (macop_t)mac_biba_create_ifnet },
2151101099Srwatson	{ MAC_CREATE_IPQ,
2152101099Srwatson	    (macop_t)mac_biba_create_ipq },
2153101099Srwatson	{ MAC_CREATE_MBUF_FROM_MBUF,
2154101099Srwatson	    (macop_t)mac_biba_create_mbuf_from_mbuf },
2155101099Srwatson	{ MAC_CREATE_MBUF_LINKLAYER,
2156101099Srwatson	    (macop_t)mac_biba_create_mbuf_linklayer },
2157101099Srwatson	{ MAC_CREATE_MBUF_FROM_BPFDESC,
2158101099Srwatson	    (macop_t)mac_biba_create_mbuf_from_bpfdesc },
2159101099Srwatson	{ MAC_CREATE_MBUF_FROM_IFNET,
2160101099Srwatson	    (macop_t)mac_biba_create_mbuf_from_ifnet },
2161101099Srwatson	{ MAC_CREATE_MBUF_MULTICAST_ENCAP,
2162101099Srwatson	    (macop_t)mac_biba_create_mbuf_multicast_encap },
2163101099Srwatson	{ MAC_CREATE_MBUF_NETLAYER,
2164101099Srwatson	    (macop_t)mac_biba_create_mbuf_netlayer },
2165101099Srwatson	{ MAC_FRAGMENT_MATCH,
2166101099Srwatson	    (macop_t)mac_biba_fragment_match },
2167101099Srwatson	{ MAC_RELABEL_IFNET,
2168101099Srwatson	    (macop_t)mac_biba_relabel_ifnet },
2169101099Srwatson	{ MAC_UPDATE_IPQ,
2170101099Srwatson	    (macop_t)mac_biba_update_ipq },
2171101099Srwatson	{ MAC_CREATE_CRED,
2172101099Srwatson	    (macop_t)mac_biba_create_cred },
2173101099Srwatson	{ MAC_EXECVE_TRANSITION,
2174101099Srwatson	    (macop_t)mac_biba_execve_transition },
2175101099Srwatson	{ MAC_EXECVE_WILL_TRANSITION,
2176101099Srwatson	    (macop_t)mac_biba_execve_will_transition },
2177101099Srwatson	{ MAC_CREATE_PROC0,
2178101099Srwatson	    (macop_t)mac_biba_create_proc0 },
2179101099Srwatson	{ MAC_CREATE_PROC1,
2180101099Srwatson	    (macop_t)mac_biba_create_proc1 },
2181101099Srwatson	{ MAC_RELABEL_CRED,
2182101099Srwatson	    (macop_t)mac_biba_relabel_cred },
2183101099Srwatson	{ MAC_CHECK_BPFDESC_RECEIVE,
2184101099Srwatson	    (macop_t)mac_biba_check_bpfdesc_receive },
2185101099Srwatson	{ MAC_CHECK_CRED_RELABEL,
2186101099Srwatson	    (macop_t)mac_biba_check_cred_relabel },
2187101099Srwatson	{ MAC_CHECK_CRED_VISIBLE,
2188101099Srwatson	    (macop_t)mac_biba_check_cred_visible },
2189101099Srwatson	{ MAC_CHECK_IFNET_RELABEL,
2190101099Srwatson	    (macop_t)mac_biba_check_ifnet_relabel },
2191101099Srwatson	{ MAC_CHECK_IFNET_TRANSMIT,
2192101099Srwatson	    (macop_t)mac_biba_check_ifnet_transmit },
2193101099Srwatson	{ MAC_CHECK_MOUNT_STAT,
2194101099Srwatson	    (macop_t)mac_biba_check_mount_stat },
2195101099Srwatson	{ MAC_CHECK_PIPE_IOCTL,
2196101099Srwatson	    (macop_t)mac_biba_check_pipe_ioctl },
2197102115Srwatson	{ MAC_CHECK_PIPE_POLL,
2198102115Srwatson	    (macop_t)mac_biba_check_pipe_poll },
2199102115Srwatson	{ MAC_CHECK_PIPE_READ,
2200102115Srwatson	    (macop_t)mac_biba_check_pipe_read },
2201101099Srwatson	{ MAC_CHECK_PIPE_RELABEL,
2202101099Srwatson	    (macop_t)mac_biba_check_pipe_relabel },
2203102115Srwatson	{ MAC_CHECK_PIPE_STAT,
2204102115Srwatson	    (macop_t)mac_biba_check_pipe_stat },
2205102115Srwatson	{ MAC_CHECK_PIPE_WRITE,
2206102115Srwatson	    (macop_t)mac_biba_check_pipe_write },
2207101099Srwatson	{ MAC_CHECK_PROC_DEBUG,
2208101099Srwatson	    (macop_t)mac_biba_check_proc_debug },
2209101099Srwatson	{ MAC_CHECK_PROC_SCHED,
2210101099Srwatson	    (macop_t)mac_biba_check_proc_sched },
2211101099Srwatson	{ MAC_CHECK_PROC_SIGNAL,
2212101099Srwatson	    (macop_t)mac_biba_check_proc_signal },
2213101934Srwatson	{ MAC_CHECK_SOCKET_DELIVER,
2214101934Srwatson	    (macop_t)mac_biba_check_socket_deliver },
2215101099Srwatson	{ MAC_CHECK_SOCKET_RELABEL,
2216101099Srwatson	    (macop_t)mac_biba_check_socket_relabel },
2217101099Srwatson	{ MAC_CHECK_SOCKET_VISIBLE,
2218101099Srwatson	    (macop_t)mac_biba_check_socket_visible },
2219101099Srwatson	{ MAC_CHECK_VNODE_ACCESS,
2220101099Srwatson	    (macop_t)mac_biba_check_vnode_access },
2221101099Srwatson	{ MAC_CHECK_VNODE_CHDIR,
2222101099Srwatson	    (macop_t)mac_biba_check_vnode_chdir },
2223101099Srwatson	{ MAC_CHECK_VNODE_CHROOT,
2224101099Srwatson	    (macop_t)mac_biba_check_vnode_chroot },
2225101099Srwatson	{ MAC_CHECK_VNODE_CREATE,
2226101099Srwatson	    (macop_t)mac_biba_check_vnode_create },
2227101099Srwatson	{ MAC_CHECK_VNODE_DELETE,
2228101099Srwatson	    (macop_t)mac_biba_check_vnode_delete },
2229101099Srwatson	{ MAC_CHECK_VNODE_DELETEACL,
2230101099Srwatson	    (macop_t)mac_biba_check_vnode_deleteacl },
2231101099Srwatson	{ MAC_CHECK_VNODE_EXEC,
2232101099Srwatson	    (macop_t)mac_biba_check_vnode_exec },
2233101099Srwatson	{ MAC_CHECK_VNODE_GETACL,
2234101099Srwatson	    (macop_t)mac_biba_check_vnode_getacl },
2235101099Srwatson	{ MAC_CHECK_VNODE_GETEXTATTR,
2236101099Srwatson	    (macop_t)mac_biba_check_vnode_getextattr },
2237101099Srwatson	{ MAC_CHECK_VNODE_LOOKUP,
2238101099Srwatson	    (macop_t)mac_biba_check_vnode_lookup },
2239101099Srwatson	{ MAC_CHECK_VNODE_OPEN,
2240101099Srwatson	    (macop_t)mac_biba_check_vnode_open },
2241102112Srwatson	{ MAC_CHECK_VNODE_POLL,
2242102112Srwatson	    (macop_t)mac_biba_check_vnode_poll },
2243102112Srwatson	{ MAC_CHECK_VNODE_READ,
2244102112Srwatson	    (macop_t)mac_biba_check_vnode_read },
2245101099Srwatson	{ MAC_CHECK_VNODE_READDIR,
2246101099Srwatson	    (macop_t)mac_biba_check_vnode_readdir },
2247101099Srwatson	{ MAC_CHECK_VNODE_READLINK,
2248101099Srwatson	    (macop_t)mac_biba_check_vnode_readlink },
2249101099Srwatson	{ MAC_CHECK_VNODE_RELABEL,
2250101099Srwatson	    (macop_t)mac_biba_check_vnode_relabel },
2251101099Srwatson	{ MAC_CHECK_VNODE_RENAME_FROM,
2252101099Srwatson	    (macop_t)mac_biba_check_vnode_rename_from },
2253101099Srwatson	{ MAC_CHECK_VNODE_RENAME_TO,
2254101099Srwatson	    (macop_t)mac_biba_check_vnode_rename_to },
2255101099Srwatson	{ MAC_CHECK_VNODE_REVOKE,
2256101099Srwatson	    (macop_t)mac_biba_check_vnode_revoke },
2257101099Srwatson	{ MAC_CHECK_VNODE_SETACL,
2258101099Srwatson	    (macop_t)mac_biba_check_vnode_setacl },
2259101099Srwatson	{ MAC_CHECK_VNODE_SETEXTATTR,
2260101099Srwatson	    (macop_t)mac_biba_check_vnode_setextattr },
2261101099Srwatson	{ MAC_CHECK_VNODE_SETFLAGS,
2262101099Srwatson	    (macop_t)mac_biba_check_vnode_setflags },
2263101099Srwatson	{ MAC_CHECK_VNODE_SETMODE,
2264101099Srwatson	    (macop_t)mac_biba_check_vnode_setmode },
2265101099Srwatson	{ MAC_CHECK_VNODE_SETOWNER,
2266101099Srwatson	    (macop_t)mac_biba_check_vnode_setowner },
2267101099Srwatson	{ MAC_CHECK_VNODE_SETUTIMES,
2268101099Srwatson	    (macop_t)mac_biba_check_vnode_setutimes },
2269101099Srwatson	{ MAC_CHECK_VNODE_STAT,
2270101099Srwatson	    (macop_t)mac_biba_check_vnode_stat },
2271102112Srwatson	{ MAC_CHECK_VNODE_WRITE,
2272102112Srwatson	    (macop_t)mac_biba_check_vnode_write },
2273101099Srwatson	{ MAC_CHECK_VNODE_MMAP_PERMS,
2274101099Srwatson	    (macop_t)mac_biba_check_vnode_mmap_perms },
2275101099Srwatson	{ MAC_OP_LAST, NULL }
2276101099Srwatson};
2277101099Srwatson
2278101099SrwatsonMAC_POLICY_SET(mac_biba_ops, trustedbsd_mac_biba, "TrustedBSD MAC/Biba",
2279101099Srwatson    MPC_LOADTIME_FLAG_NOTLATE, &mac_biba_slot);
2280