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