mac_biba.c revision 105656
1129906Sbmilekic/*-
2141991Sbmilekic * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson
3254515Sandre * Copyright (c) 2001, 2002 Networks Associates Technology, Inc.
4129906Sbmilekic * All rights reserved.
5129906Sbmilekic *
6129906Sbmilekic * This software was developed by Robert Watson for the TrustedBSD Project.
7129906Sbmilekic *
8129906Sbmilekic * This software was developed for the FreeBSD Project in part by NAI Labs,
9129906Sbmilekic * the Security Research Division of Network Associates, Inc. under
10129906Sbmilekic * DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA
11129906Sbmilekic * CHATS research program.
12129906Sbmilekic *
13129906Sbmilekic * Redistribution and use in source and binary forms, with or without
14129906Sbmilekic * modification, are permitted provided that the following conditions
15129906Sbmilekic * are met:
16129906Sbmilekic * 1. Redistributions of source code must retain the above copyright
17129906Sbmilekic *    notice, this list of conditions and the following disclaimer.
18129906Sbmilekic * 2. Redistributions in binary form must reproduce the above copyright
19129906Sbmilekic *    notice, this list of conditions and the following disclaimer in the
20129906Sbmilekic *    documentation and/or other materials provided with the distribution.
21129906Sbmilekic * 3. The names of the authors may not be used to endorse or promote
22129906Sbmilekic *    products derived from this software without specific prior written
23129906Sbmilekic *    permission.
24129906Sbmilekic *
25129906Sbmilekic * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
26129906Sbmilekic * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27129906Sbmilekic * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28129906Sbmilekic * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
29129906Sbmilekic * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30129906Sbmilekic * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31129906Sbmilekic * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32129906Sbmilekic * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33129906Sbmilekic * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34129906Sbmilekic * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35129906Sbmilekic * SUCH DAMAGE.
36129906Sbmilekic *
37129906Sbmilekic * $FreeBSD: head/sys/security/mac_biba/mac_biba.c 105656 2002-10-21 20:55:39Z rwatson $
38129906Sbmilekic */
39129906Sbmilekic
40129906Sbmilekic/*
41129906Sbmilekic * Developed by the TrustedBSD Project.
42129906Sbmilekic * Biba fixed label mandatory integrity policy.
43129906Sbmilekic */
44163606Srwatson
45163606Srwatson#include <sys/types.h>
46129906Sbmilekic#include <sys/param.h>
47194454Salc#include <sys/acl.h>
48194454Salc#include <sys/conf.h>
49129906Sbmilekic#include <sys/kernel.h>
50254515Sandre#include <sys/mac.h>
51129906Sbmilekic#include <sys/malloc.h>
52147537Ssilby#include <sys/mount.h>
53147537Ssilby#include <sys/proc.h>
54129906Sbmilekic#include <sys/systm.h>
55129906Sbmilekic#include <sys/sysproto.h>
56129906Sbmilekic#include <sys/sysent.h>
57129906Sbmilekic#include <sys/vnode.h>
58129906Sbmilekic#include <sys/file.h>
59129906Sbmilekic#include <sys/socket.h>
60129906Sbmilekic#include <sys/socketvar.h>
61129906Sbmilekic#include <sys/pipe.h>
62129906Sbmilekic#include <sys/sysctl.h>
63129906Sbmilekic
64129906Sbmilekic#include <fs/devfs/devfs.h>
65129906Sbmilekic
66129906Sbmilekic#include <net/bpfdesc.h>
67129906Sbmilekic#include <net/if.h>
68129906Sbmilekic#include <net/if_types.h>
69129906Sbmilekic#include <net/if_var.h>
70129906Sbmilekic
71129906Sbmilekic#include <netinet/in.h>
72129906Sbmilekic#include <netinet/ip_var.h>
73129906Sbmilekic
74129906Sbmilekic#include <vm/vm.h>
75129906Sbmilekic
76129906Sbmilekic#include <sys/mac_policy.h>
77129906Sbmilekic
78129906Sbmilekic#include <security/mac_biba/mac_biba.h>
79129906Sbmilekic
80254515SandreSYSCTL_DECL(_security_mac);
81129906Sbmilekic
82129906SbmilekicSYSCTL_NODE(_security_mac, OID_AUTO, biba, CTLFLAG_RW, 0,
83129906Sbmilekic    "TrustedBSD mac_biba policy controls");
84151976Sandre
85151976Sandrestatic int	mac_biba_enabled = 0;
86156023SglebiusSYSCTL_INT(_security_mac_biba, OID_AUTO, enabled, CTLFLAG_RW,
87151976Sandre    &mac_biba_enabled, 0, "Enforce MAC/Biba policy");
88156023SglebiusTUNABLE_INT("security.mac.biba.enabled", &mac_biba_enabled);
89151976Sandre
90156023Sglebiusstatic int	destroyed_not_inited;
91151976SandreSYSCTL_INT(_security_mac_biba, OID_AUTO, destroyed_not_inited, CTLFLAG_RD,
92151976Sandre    &destroyed_not_inited, 0, "Count of labels destroyed but not inited");
93156023Sglebius
94151976Sandrestatic int	trust_all_interfaces = 0;
95151976SandreSYSCTL_INT(_security_mac_biba, OID_AUTO, trust_all_interfaces, CTLFLAG_RD,
96151976Sandre    &trust_all_interfaces, 0, "Consider all interfaces 'trusted' by MAC/Biba");
97151976SandreTUNABLE_INT("security.mac.biba.trust_all_interfaces", &trust_all_interfaces);
98129906Sbmilekic
99129906Sbmilekicstatic char	trusted_interfaces[128];
100254515SandreSYSCTL_STRING(_security_mac_biba, OID_AUTO, trusted_interfaces, CTLFLAG_RD,
101151976Sandre    trusted_interfaces, 0, "Interfaces considered 'trusted' by MAC/Biba");
102155780SandreTUNABLE_STR("security.mac.biba.trusted_interfaces", trusted_interfaces,
103151976Sandre    sizeof(trusted_interfaces));
104151976Sandre
105129906Sbmilekicstatic int	max_compartments = MAC_BIBA_MAX_COMPARTMENTS;
106129906SbmilekicSYSCTL_INT(_security_mac_biba, OID_AUTO, max_compartments, CTLFLAG_RD,
107254515Sandre    &max_compartments, 0, "Maximum supported compartments");
108254515Sandre
109254515Sandrestatic int	ptys_equal = 0;
110254515SandreSYSCTL_INT(_security_mac_biba, OID_AUTO, ptys_equal, CTLFLAG_RW,
111254515Sandre    &ptys_equal, 0, "Label pty devices as biba/equal on create");
112185893SbzTUNABLE_INT("security.mac.biba.ptys_equal", &ptys_equal);
113254515Sandre
114185893Sbzstatic int	revocation_enabled = 0;
115129906SbmilekicSYSCTL_INT(_security_mac_biba, OID_AUTO, revocation_enabled, CTLFLAG_RW,
116129906Sbmilekic    &revocation_enabled, 0, "Revoke access to objects on relabel");
117129906SbmilekicTUNABLE_INT("security.mac.biba.revocation_enabled", &revocation_enabled);
118254515Sandre
119129906Sbmilekicstatic int	mac_biba_slot;
120254515Sandre#define	SLOT(l)	((struct mac_biba *)LABEL_TO_SLOT((l), mac_biba_slot).l_ptr)
121254515Sandre
122254515SandreMALLOC_DEFINE(M_MACBIBA, "biba label", "MAC/Biba labels");
123254515Sandre
124254515Sandrestatic __inline int
125254515Sandrebiba_bit_set_empty(u_char *set) {
126254515Sandre	int i;
127254515Sandre
128254515Sandre	for (i = 0; i < MAC_BIBA_MAX_COMPARTMENTS >> 3; i++)
129254515Sandre		if (set[i] != 0)
130254515Sandre			return (0);
131254515Sandre	return (1);
132241468Snp}
133184778Skmacy
134254515Sandrestatic struct mac_biba *
135241468Snpbiba_alloc(int flag)
136241468Snp{
137241468Snp	struct mac_biba *mac_biba;
138254515Sandre
139241468Snp	mac_biba = malloc(sizeof(struct mac_biba), M_MACBIBA, M_ZERO | flag);
140241468Snp
141241468Snp	return (mac_biba);
142254515Sandre}
143241468Snp
144241468Snpstatic void
145241468Snpbiba_free(struct mac_biba *mac_biba)
146254515Sandre{
147254515Sandre
148254515Sandre	if (mac_biba != NULL)
149254515Sandre		free(mac_biba, M_MACBIBA);
150254515Sandre	else
151254515Sandre		atomic_add_int(&destroyed_not_inited, 1);
152254515Sandre}
153254515Sandre
154254515Sandrestatic int
155254515Sandrebiba_atmostflags(struct mac_biba *mac_biba, int flags)
156129906Sbmilekic{
157254515Sandre
158129906Sbmilekic	if ((mac_biba->mb_flags & flags) != mac_biba->mb_flags)
159157927Sps		return (EINVAL);
160157927Sps	return (0);
161157927Sps}
162157927Sps
163157927Spsstatic int
164157927Spsmac_biba_dominate_element(struct mac_biba_element *a,
165254515Sandre    struct mac_biba_element *b)
166258183Sjhb{
167254515Sandre	int bit;
168254515Sandre
169157927Sps	switch(a->mbe_type) {
170254515Sandre	case MAC_BIBA_TYPE_EQUAL:
171157927Sps	case MAC_BIBA_TYPE_HIGH:
172157927Sps		return (1);
173157927Sps
174157927Sps	case MAC_BIBA_TYPE_LOW:
175157927Sps		switch (b->mbe_type) {
176157927Sps		case MAC_BIBA_TYPE_GRADE:
177157927Sps		case MAC_BIBA_TYPE_HIGH:
178157927Sps			return (0);
179129906Sbmilekic
180174292Srrs		case MAC_BIBA_TYPE_EQUAL:
181174292Srrs		case MAC_BIBA_TYPE_LOW:
182174292Srrs			return (1);
183174292Srrs
184174292Srrs		default:
185174292Srrs			panic("mac_biba_dominate_element: b->mbe_type invalid");
186174292Srrs		}
187254515Sandre
188258183Sjhb	case MAC_BIBA_TYPE_GRADE:
189254515Sandre		switch (b->mbe_type) {
190254515Sandre		case MAC_BIBA_TYPE_EQUAL:
191174292Srrs		case MAC_BIBA_TYPE_LOW:
192254515Sandre			return (1);
193174292Srrs
194174292Srrs		case MAC_BIBA_TYPE_HIGH:
195174292Srrs			return (0);
196174292Srrs
197174292Srrs		case MAC_BIBA_TYPE_GRADE:
198174292Srrs			for (bit = 1; bit <= MAC_BIBA_MAX_COMPARTMENTS; bit++)
199174292Srrs				if (!MAC_BIBA_BIT_TEST(bit,
200254515Sandre				    a->mbe_compartments) &&
201174292Srrs				    MAC_BIBA_BIT_TEST(bit, b->mbe_compartments))
202174292Srrs					return (0);
203174292Srrs			return (a->mbe_grade >= b->mbe_grade);
204174292Srrs
205174292Srrs		default:
206174292Srrs			panic("mac_biba_dominate_element: b->mbe_type invalid");
207174292Srrs		}
208254515Sandre
209258183Sjhb	default:
210254515Sandre		panic("mac_biba_dominate_element: a->mbe_type invalid");
211254515Sandre	}
212174292Srrs
213254515Sandre	return (0);
214174292Srrs}
215174292Srrs
216174292Srrsstatic int
217174292Srrsmac_biba_range_in_range(struct mac_biba *rangea, struct mac_biba *rangeb)
218174292Srrs{
219174292Srrs
220174292Srrs	return (mac_biba_dominate_element(&rangeb->mb_rangehigh,
221254515Sandre	    &rangea->mb_rangehigh) &&
222174292Srrs	    mac_biba_dominate_element(&rangea->mb_rangelow,
223174292Srrs	    &rangeb->mb_rangelow));
224174292Srrs}
225174292Srrs
226174292Srrsstatic int
227174292Srrsmac_biba_single_in_range(struct mac_biba *single, struct mac_biba *range)
228174292Srrs{
229254515Sandre
230258183Sjhb	KASSERT((single->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
231254515Sandre	    ("mac_biba_single_in_range: a not single"));
232254515Sandre	KASSERT((range->mb_flags & MAC_BIBA_FLAG_RANGE) != 0,
233174292Srrs	    ("mac_biba_single_in_range: b not range"));
234254515Sandre
235174292Srrs	return (mac_biba_dominate_element(&range->mb_rangehigh,
236174292Srrs	    &single->mb_single) &&
237174292Srrs	    mac_biba_dominate_element(&single->mb_single,
238174292Srrs	    &range->mb_rangelow));
239174292Srrs
240174292Srrs	return (1);
241174292Srrs}
242151976Sandre
243174292Srrsstatic int
244254515Sandremac_biba_dominate_single(struct mac_biba *a, struct mac_biba *b)
245254515Sandre{
246254515Sandre	KASSERT((a->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
247254515Sandre	    ("mac_biba_dominate_single: a not single"));
248174292Srrs	KASSERT((b->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
249254515Sandre	    ("mac_biba_dominate_single: b not single"));
250254515Sandre
251258183Sjhb	return (mac_biba_dominate_element(&a->mb_single, &b->mb_single));
252254515Sandre}
253254515Sandre
254254515Sandrestatic int
255254515Sandremac_biba_equal_element(struct mac_biba_element *a, struct mac_biba_element *b)
256254515Sandre{
257254515Sandre
258254515Sandre	if (a->mbe_type == MAC_BIBA_TYPE_EQUAL ||
259254515Sandre	    b->mbe_type == MAC_BIBA_TYPE_EQUAL)
260254515Sandre		return (1);
261254515Sandre
262254515Sandre	return (a->mbe_type == b->mbe_type && a->mbe_grade == b->mbe_grade);
263254515Sandre}
264174292Srrs
265129906Sbmilekicstatic int
266129906Sbmilekicmac_biba_equal_single(struct mac_biba *a, struct mac_biba *b)
267129906Sbmilekic{
268129906Sbmilekic
269129906Sbmilekic	KASSERT((a->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
270129906Sbmilekic	    ("mac_biba_equal_single: a not single"));
271129906Sbmilekic	KASSERT((b->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
272129906Sbmilekic	    ("mac_biba_equal_single: b not single"));
273129906Sbmilekic
274155780Sandre	return (mac_biba_equal_element(&a->mb_single, &b->mb_single));
275151976Sandre}
276151976Sandre
277151976Sandrestatic int
278129906Sbmilekicmac_biba_contains_equal(struct mac_biba *mac_biba)
279129906Sbmilekic{
280129906Sbmilekic
281129906Sbmilekic	if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE)
282132987Sgreen		if (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_EQUAL)
283132987Sgreen			return (1);
284132987Sgreen
285129906Sbmilekic	if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
286151976Sandre		if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL)
287151976Sandre			return (1);
288151976Sandre		if (mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL)
289151976Sandre			return (1);
290129906Sbmilekic	}
291129906Sbmilekic
292209390Sed	return (0);
293129906Sbmilekic}
294135510Sbrian
295135510Sbrianstatic int
296135510Sbrianmac_biba_subject_equal_ok(struct mac_biba *mac_biba)
297129906Sbmilekic{
298129906Sbmilekic
299129906Sbmilekic	KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAGS_BOTH) ==
300129906Sbmilekic	    MAC_BIBA_FLAGS_BOTH,
301129906Sbmilekic	    ("mac_biba_subject_equal_ok: subject doesn't have both labels"));
302129906Sbmilekic
303129906Sbmilekic	/* If the single is EQUAL, it's ok. */
304129906Sbmilekic	if (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_EQUAL)
305129906Sbmilekic		return (0);
306129906Sbmilekic
307151976Sandre	/* If either range endpoint is EQUAL, it's ok. */
308151976Sandre	if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL ||
309147537Ssilby	    mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL)
310151976Sandre		return (0);
311147537Ssilby
312151976Sandre	/* If the range is low-high, it's ok. */
313147537Ssilby	if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_LOW &&
314151976Sandre	    mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_HIGH)
315254515Sandre		return (0);
316254515Sandre
317151976Sandre	/* It's not ok. */
318148095Srwatson	return (EPERM);
319151976Sandre}
320147537Ssilby
321151976Sandrestatic int
322147537Ssilbymac_biba_valid(struct mac_biba *mac_biba)
323151976Sandre{
324147537Ssilby
325151976Sandre	if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) {
326129906Sbmilekic		switch (mac_biba->mb_single.mbe_type) {
327254515Sandre		case MAC_BIBA_TYPE_GRADE:
328151976Sandre			break;
329148095Srwatson
330151976Sandre		case MAC_BIBA_TYPE_EQUAL:
331129906Sbmilekic		case MAC_BIBA_TYPE_HIGH:
332156023Sglebius		case MAC_BIBA_TYPE_LOW:
333155780Sandre			if (mac_biba->mb_single.mbe_grade != 0 ||
334153232Sandre			    !MAC_BIBA_BIT_SET_EMPTY(
335153232Sandre			    mac_biba->mb_single.mbe_compartments))
336153232Sandre				return (EINVAL);
337153232Sandre			break;
338153232Sandre
339153232Sandre		default:
340153232Sandre			return (EINVAL);
341155780Sandre		}
342254515Sandre	} else {
343153232Sandre		if (mac_biba->mb_single.mbe_type != MAC_BIBA_TYPE_UNDEF)
344151976Sandre			return (EINVAL);
345151976Sandre	}
346151976Sandre
347151976Sandre	if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
348151976Sandre		switch (mac_biba->mb_rangelow.mbe_type) {
349151976Sandre		case MAC_BIBA_TYPE_GRADE:
350151976Sandre			break;
351151976Sandre
352254515Sandre		case MAC_BIBA_TYPE_EQUAL:
353151976Sandre		case MAC_BIBA_TYPE_HIGH:
354254515Sandre		case MAC_BIBA_TYPE_LOW:
355129906Sbmilekic			if (mac_biba->mb_rangelow.mbe_grade != 0 ||
356151976Sandre			    !MAC_BIBA_BIT_SET_EMPTY(
357151976Sandre			    mac_biba->mb_rangelow.mbe_compartments))
358151976Sandre				return (EINVAL);
359151976Sandre			break;
360151976Sandre
361151976Sandre		default:
362151976Sandre			return (EINVAL);
363151976Sandre		}
364254515Sandre
365151976Sandre		switch (mac_biba->mb_rangehigh.mbe_type) {
366254515Sandre		case MAC_BIBA_TYPE_GRADE:
367151976Sandre			break;
368151976Sandre
369151976Sandre		case MAC_BIBA_TYPE_EQUAL:
370151976Sandre		case MAC_BIBA_TYPE_HIGH:
371151976Sandre		case MAC_BIBA_TYPE_LOW:
372151976Sandre			if (mac_biba->mb_rangehigh.mbe_grade != 0 ||
373151976Sandre			    !MAC_BIBA_BIT_SET_EMPTY(
374151976Sandre			    mac_biba->mb_rangehigh.mbe_compartments))
375129906Sbmilekic				return (EINVAL);
376129906Sbmilekic			break;
377129906Sbmilekic
378129906Sbmilekic		default:
379129906Sbmilekic			return (EINVAL);
380129906Sbmilekic		}
381129906Sbmilekic		if (!mac_biba_dominate_element(&mac_biba->mb_rangehigh,
382129906Sbmilekic		    &mac_biba->mb_rangelow))
383129906Sbmilekic			return (EINVAL);
384129906Sbmilekic	} else {
385129906Sbmilekic		if (mac_biba->mb_rangelow.mbe_type != MAC_BIBA_TYPE_UNDEF ||
386129906Sbmilekic		    mac_biba->mb_rangehigh.mbe_type != MAC_BIBA_TYPE_UNDEF)
387129906Sbmilekic			return (EINVAL);
388129906Sbmilekic	}
389129906Sbmilekic
390129906Sbmilekic	return (0);
391129906Sbmilekic}
392129906Sbmilekic
393129906Sbmilekicstatic void
394129906Sbmilekicmac_biba_set_range(struct mac_biba *mac_biba, u_short typelow,
395129906Sbmilekic    u_short gradelow, u_char *compartmentslow, u_short typehigh,
396129906Sbmilekic    u_short gradehigh, u_char *compartmentshigh)
397129906Sbmilekic{
398129906Sbmilekic
399129906Sbmilekic	mac_biba->mb_rangelow.mbe_type = typelow;
400129906Sbmilekic	mac_biba->mb_rangelow.mbe_grade = gradelow;
401129906Sbmilekic	if (compartmentslow != NULL)
402254515Sandre		memcpy(mac_biba->mb_rangelow.mbe_compartments,
403129906Sbmilekic		    compartmentslow,
404129906Sbmilekic		    sizeof(mac_biba->mb_rangelow.mbe_compartments));
405174247Salc	mac_biba->mb_rangehigh.mbe_type = typehigh;
406174247Salc	mac_biba->mb_rangehigh.mbe_grade = gradehigh;
407174247Salc	if (compartmentshigh != NULL)
408174247Salc		memcpy(mac_biba->mb_rangehigh.mbe_compartments,
409174247Salc		    compartmentshigh,
410174247Salc		    sizeof(mac_biba->mb_rangehigh.mbe_compartments));
411209390Sed	mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE;
412174247Salc}
413174247Salc
414177921Salcstatic void
415177921Salcmac_biba_set_single(struct mac_biba *mac_biba, u_short type, u_short grade,
416194454Salc    u_char *compartments)
417195649Salc{
418174247Salc
419174247Salc	mac_biba->mb_single.mbe_type = type;
420174247Salc	mac_biba->mb_single.mbe_grade = grade;
421129906Sbmilekic	if (compartments != NULL)
422129906Sbmilekic		memcpy(mac_biba->mb_single.mbe_compartments, compartments,
423129906Sbmilekic		    sizeof(mac_biba->mb_single.mbe_compartments));
424129906Sbmilekic	mac_biba->mb_flags |= MAC_BIBA_FLAG_SINGLE;
425151976Sandre}
426129906Sbmilekic
427132987Sgreenstatic void
428132987Sgreenmac_biba_copy_range(struct mac_biba *labelfrom, struct mac_biba *labelto)
429129906Sbmilekic{
430129906Sbmilekic
431129906Sbmilekic	KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_RANGE) != 0,
432132987Sgreen	    ("mac_biba_copy_range: labelfrom not range"));
433132987Sgreen
434132987Sgreen	labelto->mb_rangelow = labelfrom->mb_rangelow;
435129906Sbmilekic	labelto->mb_rangehigh = labelfrom->mb_rangehigh;
436129906Sbmilekic	labelto->mb_flags |= MAC_BIBA_FLAG_RANGE;
437129906Sbmilekic}
438147537Ssilby
439147537Ssilbystatic void
440147537Ssilbymac_biba_copy_single(struct mac_biba *labelfrom, struct mac_biba *labelto)
441129906Sbmilekic{
442129906Sbmilekic
443129906Sbmilekic	KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
444129906Sbmilekic	    ("mac_biba_copy_single: labelfrom not single"));
445129906Sbmilekic
446151976Sandre	labelto->mb_single = labelfrom->mb_single;
447151976Sandre	labelto->mb_flags |= MAC_BIBA_FLAG_SINGLE;
448156059Sglebius}
449151976Sandre
450151976Sandrestatic void
451151976Sandremac_biba_copy(struct mac_biba *source, struct mac_biba *dest)
452151976Sandre{
453129906Sbmilekic
454129906Sbmilekic	if (source->mb_flags & MAC_BIBA_FLAG_SINGLE)
455151976Sandre		mac_biba_copy_single(source, dest);
456129947Sbmilekic	if (source->mb_flags & MAC_BIBA_FLAG_RANGE)
457151976Sandre		mac_biba_copy_range(source, dest);
458129906Sbmilekic}
459129906Sbmilekic
460129906Sbmilekic/*
461184778Skmacy * Policy module operations.
462151976Sandre */
463129906Sbmilekicstatic void
464151976Sandremac_biba_destroy(struct mac_policy_conf *conf)
465162377Sandre{
466162377Sandre
467186683Srwatson}
468129906Sbmilekic
469129906Sbmilekicstatic void
470129906Sbmilekicmac_biba_init(struct mac_policy_conf *conf)
471172930Srwatson{
472132987Sgreen
473132987Sgreen}
474129906Sbmilekic
475129947Sbmilekic/*
476129906Sbmilekic * Label operations.
477132987Sgreen */
478129906Sbmilekicstatic void
479129906Sbmilekicmac_biba_init_label(struct label *label)
480129906Sbmilekic{
481151976Sandre
482129906Sbmilekic	SLOT(label) = biba_alloc(M_WAITOK);
483129906Sbmilekic}
484129906Sbmilekic
485129906Sbmilekicstatic int
486129906Sbmilekicmac_biba_init_label_waitcheck(struct label *label, int flag)
487254515Sandre{
488129906Sbmilekic
489129906Sbmilekic	SLOT(label) = biba_alloc(flag);
490172462Skmacy	if (SLOT(label) == NULL)
491173029Sobrien		return (ENOMEM);
492172462Skmacy
493129906Sbmilekic	return (0);
494151976Sandre}
495173029Sobrien
496147537Ssilbystatic void
497147537Ssilbymac_biba_destroy_label(struct label *label)
498147537Ssilby{
499129906Sbmilekic
500129906Sbmilekic	biba_free(SLOT(label));
501151976Sandre	SLOT(label) = NULL;
502151976Sandre}
503151976Sandre
504129906Sbmilekicstatic int
505129906Sbmilekicmac_biba_externalize(struct label *label, struct mac *extmac)
506129906Sbmilekic{
507129906Sbmilekic	struct mac_biba *mac_biba;
508129906Sbmilekic
509129906Sbmilekic	mac_biba = SLOT(label);
510129906Sbmilekic
511129906Sbmilekic	if (mac_biba == NULL) {
512151976Sandre		printf("mac_biba_externalize: NULL pointer\n");
513151976Sandre		return (0);
514151976Sandre	}
515151976Sandre
516151976Sandre	extmac->m_biba = *mac_biba;
517175872Sphk
518175872Sphk	return (0);
519151976Sandre}
520152130Sglebius
521151976Sandrestatic int
522147537Ssilbymac_biba_internalize(struct label *label, struct mac *extmac)
523147537Ssilby{
524147537Ssilby	struct mac_biba *mac_biba;
525166213Smohans	int error;
526173029Sobrien
527173029Sobrien	mac_biba = SLOT(label);
528173029Sobrien
529173029Sobrien	error = mac_biba_valid(mac_biba);
530173029Sobrien	if (error)
531173029Sobrien		return (error);
532166213Smohans
533173029Sobrien	*mac_biba = extmac->m_biba;
534173029Sobrien
535129906Sbmilekic	return (0);
536129906Sbmilekic}
537129906Sbmilekic
538155780Sandre/*
539129906Sbmilekic * Labeling event operations: file system objects, and things that look
540129906Sbmilekic * a lot like file system objects.
541151976Sandre */
542151976Sandrestatic void
543151976Sandremac_biba_create_devfs_device(dev_t dev, struct devfs_dirent *devfs_dirent,
544129906Sbmilekic    struct label *label)
545132987Sgreen{
546132987Sgreen	struct mac_biba *mac_biba;
547129906Sbmilekic	int biba_type;
548129906Sbmilekic
549151976Sandre	mac_biba = SLOT(label);
550168374Skmacy	if (strcmp(dev->si_name, "null") == 0 ||
551168374Skmacy	    strcmp(dev->si_name, "zero") == 0 ||
552173029Sobrien	    strcmp(dev->si_name, "random") == 0 ||
553147537Ssilby	    strncmp(dev->si_name, "fd/", strlen("fd/")) == 0)
554147537Ssilby		biba_type = MAC_BIBA_TYPE_EQUAL;
555147537Ssilby	else if (ptys_equal &&
556168374Skmacy	    (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 ||
557168374Skmacy	    strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0))
558168374Skmacy		biba_type = MAC_BIBA_TYPE_EQUAL;
559168374Skmacy	else
560168374Skmacy		biba_type = MAC_BIBA_TYPE_HIGH;
561168374Skmacy	mac_biba_set_single(mac_biba, biba_type, 0, NULL);
562168374Skmacy}
563168374Skmacy
564168374Skmacystatic void
565168374Skmacymac_biba_create_devfs_directory(char *dirname, int dirnamelen,
566168374Skmacy    struct devfs_dirent *devfs_dirent, struct label *label)
567168374Skmacy{
568168374Skmacy	struct mac_biba *mac_biba;
569168374Skmacy
570168374Skmacy	mac_biba = SLOT(label);
571168374Skmacy	mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
572168374Skmacy}
573168374Skmacy
574168374Skmacystatic void
575168374Skmacymac_biba_create_devfs_symlink(struct ucred *cred, struct devfs_dirent *dd,
576168374Skmacy    struct label *ddlabel, struct devfs_dirent *de, struct label *delabel)
577168374Skmacy{
578168374Skmacy	struct mac_biba *source, *dest;
579168374Skmacy
580129906Sbmilekic	source = SLOT(&cred->cr_label);
581168374Skmacy	dest = SLOT(delabel);
582173029Sobrien
583151976Sandre	mac_biba_copy_single(source, dest);
584151976Sandre}
585151976Sandre
586151976Sandrestatic void
587151976Sandremac_biba_create_devfs_vnode(struct devfs_dirent *devfs_dirent,
588175872Sphk    struct label *direntlabel, struct vnode *vp, struct label *vnodelabel)
589175872Sphk{
590151976Sandre	struct mac_biba *source, *dest;
591151976Sandre
592168374Skmacy	source = SLOT(direntlabel);
593151976Sandre	dest = SLOT(vnodelabel);
594168374Skmacy	mac_biba_copy_single(source, dest);
595132987Sgreen}
596129906Sbmilekic
597129906Sbmilekicstatic void
598151976Sandremac_biba_create_vnode(struct ucred *cred, struct vnode *parent,
599151976Sandre    struct label *parentlabel, struct vnode *child, struct label *childlabel)
600151976Sandre{
601129906Sbmilekic	struct mac_biba *source, *dest;
602129906Sbmilekic
603129906Sbmilekic	source = SLOT(&cred->cr_label);
604168374Skmacy	dest = SLOT(childlabel);
605168374Skmacy
606151976Sandre	mac_biba_copy_single(source, dest);
607168374Skmacy}
608168374Skmacy
609152035Sandrestatic void
610168374Skmacymac_biba_create_mount(struct ucred *cred, struct mount *mp,
611168374Skmacy    struct label *mntlabel, struct label *fslabel)
612147537Ssilby{
613147537Ssilby	struct mac_biba *source, *dest;
614129906Sbmilekic
615129906Sbmilekic	source = SLOT(&cred->cr_label);
616129906Sbmilekic	dest = SLOT(mntlabel);
617129906Sbmilekic	mac_biba_copy_single(source, dest);
618151976Sandre	dest = SLOT(fslabel);
619129906Sbmilekic	mac_biba_copy_single(source, dest);
620132987Sgreen}
621151976Sandre
622129906Sbmilekicstatic void
623129906Sbmilekicmac_biba_create_root_mount(struct ucred *cred, struct mount *mp,
624129906Sbmilekic    struct label *mntlabel, struct label *fslabel)
625151976Sandre{
626156428Sandre	struct mac_biba *mac_biba;
627156428Sandre
628132987Sgreen	/* Always mount root as high integrity. */
629152101Sandre	mac_biba = SLOT(fslabel);
630147537Ssilby	mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
631147537Ssilby	mac_biba = SLOT(mntlabel);
632147537Ssilby	mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL);
633132987Sgreen}
634129906Sbmilekic
635129906Sbmilekicstatic void
636129906Sbmilekicmac_biba_relabel_vnode(struct ucred *cred, struct vnode *vp,
637129906Sbmilekic    struct label *vnodelabel, struct label *label)
638129906Sbmilekic{
639129906Sbmilekic	struct mac_biba *source, *dest;
640129906Sbmilekic
641151976Sandre	source = SLOT(label);
642129906Sbmilekic	dest = SLOT(vnodelabel);
643129906Sbmilekic
644129906Sbmilekic	mac_biba_copy(source, dest);
645129906Sbmilekic}
646147537Ssilby
647147537Ssilbystatic void
648147537Ssilbymac_biba_update_devfsdirent(struct devfs_dirent *devfs_dirent,
649129906Sbmilekic    struct label *direntlabel, struct vnode *vp, struct label *vnodelabel)
650147652Ssilby{
651147652Ssilby	struct mac_biba *source, *dest;
652147652Ssilby
653129906Sbmilekic	source = SLOT(vnodelabel);
654129906Sbmilekic	dest = SLOT(direntlabel);
655129906Sbmilekic
656129906Sbmilekic	mac_biba_copy(source, dest);
657129906Sbmilekic}
658132987Sgreen
659132987Sgreenstatic void
660129906Sbmilekicmac_biba_update_procfsvnode(struct vnode *vp, struct label *vnodelabel,
661129906Sbmilekic    struct ucred *cred)
662129906Sbmilekic{
663132987Sgreen	struct mac_biba *source, *dest;
664132987Sgreen
665132987Sgreen	source = SLOT(&cred->cr_label);
666132987Sgreen	dest = SLOT(vnodelabel);
667129906Sbmilekic
668129906Sbmilekic	/*
669129906Sbmilekic	 * Only copy the single, not the range, since vnodes only have
670129906Sbmilekic	 * a single.
671129906Sbmilekic	 */
672129906Sbmilekic	mac_biba_copy_single(source, dest);
673129906Sbmilekic}
674147537Ssilby
675147537Ssilbystatic int
676147537Ssilbymac_biba_update_vnode_from_externalized(struct vnode *vp,
677129906Sbmilekic    struct label *vnodelabel, struct mac *extmac)
678129947Sbmilekic{
679129906Sbmilekic	struct mac_biba *source, *dest;
680151976Sandre	int error;
681151976Sandre
682151976Sandre	source = &extmac->m_biba;
683173029Sobrien	dest = SLOT(vnodelabel);
684129906Sbmilekic
685129906Sbmilekic	error = mac_biba_valid(source);
686151976Sandre	if (error)
687151976Sandre		return (error);
688129906Sbmilekic
689151976Sandre	if ((source->mb_flags & MAC_BIBA_FLAGS_BOTH) != MAC_BIBA_FLAG_SINGLE)
690162377Sandre		return (EINVAL);
691162377Sandre
692186683Srwatson	mac_biba_copy_single(source, dest);
693129906Sbmilekic
694129906Sbmilekic	return (0);
695129906Sbmilekic}
696172930Srwatson
697132987Sgreenstatic void
698132987Sgreenmac_biba_update_vnode_from_mount(struct vnode *vp, struct label *vnodelabel,
699129906Sbmilekic    struct mount *mp, struct label *fslabel)
700129906Sbmilekic{
701151976Sandre	struct mac_biba *source, *dest;
702151976Sandre
703132987Sgreen	source = SLOT(fslabel);
704129906Sbmilekic	dest = SLOT(vnodelabel);
705129906Sbmilekic
706194515Skmacy	mac_biba_copy_single(source, dest);
707194515Skmacy}
708194515Skmacy
709194515Skmacy/*
710194515Skmacy * Labeling event operations: IPC object.
711194515Skmacy */
712194515Skmacystatic void
713194515Skmacymac_biba_create_mbuf_from_socket(struct socket *so, struct label *socketlabel,
714194515Skmacy    struct mbuf *m, struct label *mbuflabel)
715194515Skmacy{
716194515Skmacy	struct mac_biba *source, *dest;
717194515Skmacy
718194515Skmacy	source = SLOT(socketlabel);
719194515Skmacy	dest = SLOT(mbuflabel);
720194515Skmacy
721194515Skmacy	mac_biba_copy_single(source, dest);
722194515Skmacy}
723194515Skmacy
724194515Skmacystatic void
725194515Skmacymac_biba_create_socket(struct ucred *cred, struct socket *socket,
726194515Skmacy    struct label *socketlabel)
727194515Skmacy{
728194515Skmacy	struct mac_biba *source, *dest;
729194515Skmacy
730194515Skmacy	source = SLOT(&cred->cr_label);
731194515Skmacy	dest = SLOT(socketlabel);
732129906Sbmilekic
733129906Sbmilekic	mac_biba_copy_single(source, dest);
734129906Sbmilekic}
735129906Sbmilekic
736129906Sbmilekicstatic void
737129906Sbmilekicmac_biba_create_pipe(struct ucred *cred, struct pipe *pipe,
738129906Sbmilekic    struct label *pipelabel)
739129906Sbmilekic{
740129906Sbmilekic	struct mac_biba *source, *dest;
741129906Sbmilekic
742129906Sbmilekic	source = SLOT(&cred->cr_label);
743129906Sbmilekic	dest = SLOT(pipelabel);
744129906Sbmilekic
745129906Sbmilekic	mac_biba_copy_single(source, dest);
746129906Sbmilekic}
747129906Sbmilekic
748129906Sbmilekicstatic void
749129906Sbmilekicmac_biba_create_socket_from_socket(struct socket *oldsocket,
750129906Sbmilekic    struct label *oldsocketlabel, struct socket *newsocket,
751129906Sbmilekic    struct label *newsocketlabel)
752129906Sbmilekic{
753	struct mac_biba *source, *dest;
754
755	source = SLOT(oldsocketlabel);
756	dest = SLOT(newsocketlabel);
757
758	mac_biba_copy_single(source, dest);
759}
760
761static void
762mac_biba_relabel_socket(struct ucred *cred, struct socket *socket,
763    struct label *socketlabel, struct label *newlabel)
764{
765	struct mac_biba *source, *dest;
766
767	source = SLOT(newlabel);
768	dest = SLOT(socketlabel);
769
770	mac_biba_copy(source, dest);
771}
772
773static void
774mac_biba_relabel_pipe(struct ucred *cred, struct pipe *pipe,
775    struct label *pipelabel, struct label *newlabel)
776{
777	struct mac_biba *source, *dest;
778
779	source = SLOT(newlabel);
780	dest = SLOT(pipelabel);
781
782	mac_biba_copy(source, dest);
783}
784
785static void
786mac_biba_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel,
787    struct socket *socket, struct label *socketpeerlabel)
788{
789	struct mac_biba *source, *dest;
790
791	source = SLOT(mbuflabel);
792	dest = SLOT(socketpeerlabel);
793
794	mac_biba_copy_single(source, dest);
795}
796
797/*
798 * Labeling event operations: network objects.
799 */
800static void
801mac_biba_set_socket_peer_from_socket(struct socket *oldsocket,
802    struct label *oldsocketlabel, struct socket *newsocket,
803    struct label *newsocketpeerlabel)
804{
805	struct mac_biba *source, *dest;
806
807	source = SLOT(oldsocketlabel);
808	dest = SLOT(newsocketpeerlabel);
809
810	mac_biba_copy_single(source, dest);
811}
812
813static void
814mac_biba_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d,
815    struct label *bpflabel)
816{
817	struct mac_biba *source, *dest;
818
819	source = SLOT(&cred->cr_label);
820	dest = SLOT(bpflabel);
821
822	mac_biba_copy_single(source, dest);
823}
824
825static void
826mac_biba_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel)
827{
828	char tifname[IFNAMSIZ], ifname[IFNAMSIZ], *p, *q;
829	char tiflist[sizeof(trusted_interfaces)];
830	struct mac_biba *dest;
831	int len, grade;
832
833	dest = SLOT(ifnetlabel);
834
835	if (ifnet->if_type == IFT_LOOP) {
836		grade = MAC_BIBA_TYPE_EQUAL;
837		goto set;
838	}
839
840	if (trust_all_interfaces) {
841		grade = MAC_BIBA_TYPE_HIGH;
842		goto set;
843	}
844
845	grade = MAC_BIBA_TYPE_LOW;
846
847	if (trusted_interfaces[0] == '\0' ||
848	    !strvalid(trusted_interfaces, sizeof(trusted_interfaces)))
849		goto set;
850
851	for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++)
852		if(*p != ' ' && *p != '\t')
853			*q = *p;
854
855	snprintf(ifname, IFNAMSIZ, "%s%d", ifnet->if_name, ifnet->if_unit);
856
857	for (p = q = tiflist;; p++) {
858		if (*p == ',' || *p == '\0') {
859			len = p - q;
860			if (len < IFNAMSIZ) {
861				bzero(tifname, sizeof(tifname));
862				bcopy(q, tifname, len);
863				if (strcmp(tifname, ifname) == 0) {
864					grade = MAC_BIBA_TYPE_HIGH;
865					break;
866				}
867			}
868			if (*p == '\0')
869				break;
870			q = p + 1;
871		}
872	}
873set:
874	mac_biba_set_single(dest, grade, 0, NULL);
875	mac_biba_set_range(dest, grade, 0, NULL, grade, 0, NULL);
876}
877
878static void
879mac_biba_create_ipq(struct mbuf *fragment, struct label *fragmentlabel,
880    struct ipq *ipq, struct label *ipqlabel)
881{
882	struct mac_biba *source, *dest;
883
884	source = SLOT(fragmentlabel);
885	dest = SLOT(ipqlabel);
886
887	mac_biba_copy_single(source, dest);
888}
889
890static void
891mac_biba_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel,
892    struct mbuf *datagram, struct label *datagramlabel)
893{
894	struct mac_biba *source, *dest;
895
896	source = SLOT(ipqlabel);
897	dest = SLOT(datagramlabel);
898
899	/* Just use the head, since we require them all to match. */
900	mac_biba_copy_single(source, dest);
901}
902
903static void
904mac_biba_create_fragment(struct mbuf *datagram, struct label *datagramlabel,
905    struct mbuf *fragment, struct label *fragmentlabel)
906{
907	struct mac_biba *source, *dest;
908
909	source = SLOT(datagramlabel);
910	dest = SLOT(fragmentlabel);
911
912	mac_biba_copy_single(source, dest);
913}
914
915static void
916mac_biba_create_mbuf_from_mbuf(struct mbuf *oldmbuf,
917    struct label *oldmbuflabel, struct mbuf *newmbuf,
918    struct label *newmbuflabel)
919{
920	struct mac_biba *source, *dest;
921
922	source = SLOT(oldmbuflabel);
923	dest = SLOT(newmbuflabel);
924
925	/*
926	 * Because the source mbuf may not yet have been "created",
927	 * just initialiezd, we do a conditional copy.  Since we don't
928	 * allow mbufs to have ranges, do a KASSERT to make sure that
929	 * doesn't happen.
930	 */
931	KASSERT((source->mb_flags & MAC_BIBA_FLAG_RANGE) == 0,
932	    ("mac_biba_create_mbuf_from_mbuf: source mbuf has range"));
933	mac_biba_copy(source, dest);
934}
935
936static void
937mac_biba_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel,
938    struct mbuf *mbuf, struct label *mbuflabel)
939{
940	struct mac_biba *dest;
941
942	dest = SLOT(mbuflabel);
943
944	mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
945}
946
947static void
948mac_biba_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel,
949    struct mbuf *mbuf, struct label *mbuflabel)
950{
951	struct mac_biba *source, *dest;
952
953	source = SLOT(bpflabel);
954	dest = SLOT(mbuflabel);
955
956	mac_biba_copy_single(source, dest);
957}
958
959static void
960mac_biba_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel,
961    struct mbuf *m, struct label *mbuflabel)
962{
963	struct mac_biba *source, *dest;
964
965	source = SLOT(ifnetlabel);
966	dest = SLOT(mbuflabel);
967
968	mac_biba_copy_single(source, dest);
969}
970
971static void
972mac_biba_create_mbuf_multicast_encap(struct mbuf *oldmbuf,
973    struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel,
974    struct mbuf *newmbuf, struct label *newmbuflabel)
975{
976	struct mac_biba *source, *dest;
977
978	source = SLOT(oldmbuflabel);
979	dest = SLOT(newmbuflabel);
980
981	mac_biba_copy_single(source, dest);
982}
983
984static void
985mac_biba_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel,
986    struct mbuf *newmbuf, struct label *newmbuflabel)
987{
988	struct mac_biba *source, *dest;
989
990	source = SLOT(oldmbuflabel);
991	dest = SLOT(newmbuflabel);
992
993	mac_biba_copy_single(source, dest);
994}
995
996static int
997mac_biba_fragment_match(struct mbuf *fragment, struct label *fragmentlabel,
998    struct ipq *ipq, struct label *ipqlabel)
999{
1000	struct mac_biba *a, *b;
1001
1002	a = SLOT(ipqlabel);
1003	b = SLOT(fragmentlabel);
1004
1005	return (mac_biba_equal_single(a, b));
1006}
1007
1008static void
1009mac_biba_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet,
1010    struct label *ifnetlabel, struct label *newlabel)
1011{
1012	struct mac_biba *source, *dest;
1013
1014	source = SLOT(newlabel);
1015	dest = SLOT(ifnetlabel);
1016
1017	mac_biba_copy(source, dest);
1018}
1019
1020static void
1021mac_biba_update_ipq(struct mbuf *fragment, struct label *fragmentlabel,
1022    struct ipq *ipq, struct label *ipqlabel)
1023{
1024
1025	/* NOOP: we only accept matching labels, so no need to update */
1026}
1027
1028/*
1029 * Labeling event operations: processes.
1030 */
1031static void
1032mac_biba_create_cred(struct ucred *cred_parent, struct ucred *cred_child)
1033{
1034	struct mac_biba *source, *dest;
1035
1036	source = SLOT(&cred_parent->cr_label);
1037	dest = SLOT(&cred_child->cr_label);
1038
1039	mac_biba_copy_single(source, dest);
1040	mac_biba_copy_range(source, dest);
1041}
1042
1043static void
1044mac_biba_execve_transition(struct ucred *old, struct ucred *new,
1045    struct vnode *vp, struct mac *vnodelabel)
1046{
1047	struct mac_biba *source, *dest;
1048
1049	source = SLOT(&old->cr_label);
1050	dest = SLOT(&new->cr_label);
1051
1052	mac_biba_copy_single(source, dest);
1053	mac_biba_copy_range(source, dest);
1054}
1055
1056static int
1057mac_biba_execve_will_transition(struct ucred *old, struct vnode *vp,
1058    struct mac *vnodelabel)
1059{
1060
1061	return (0);
1062}
1063
1064static void
1065mac_biba_create_proc0(struct ucred *cred)
1066{
1067	struct mac_biba *dest;
1068
1069	dest = SLOT(&cred->cr_label);
1070
1071	mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL);
1072	mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL,
1073	    MAC_BIBA_TYPE_HIGH, 0, NULL);
1074}
1075
1076static void
1077mac_biba_create_proc1(struct ucred *cred)
1078{
1079	struct mac_biba *dest;
1080
1081	dest = SLOT(&cred->cr_label);
1082
1083	mac_biba_set_single(dest, MAC_BIBA_TYPE_HIGH, 0, NULL);
1084	mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL,
1085	    MAC_BIBA_TYPE_HIGH, 0, NULL);
1086}
1087
1088static void
1089mac_biba_relabel_cred(struct ucred *cred, struct label *newlabel)
1090{
1091	struct mac_biba *source, *dest;
1092
1093	source = SLOT(newlabel);
1094	dest = SLOT(&cred->cr_label);
1095
1096	mac_biba_copy(source, dest);
1097}
1098
1099/*
1100 * Access control checks.
1101 */
1102static int
1103mac_biba_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel,
1104    struct ifnet *ifnet, struct label *ifnetlabel)
1105{
1106	struct mac_biba *a, *b;
1107
1108	if (!mac_biba_enabled)
1109		return (0);
1110
1111	a = SLOT(bpflabel);
1112	b = SLOT(ifnetlabel);
1113
1114	if (mac_biba_equal_single(a, b))
1115		return (0);
1116	return (EACCES);
1117}
1118
1119static int
1120mac_biba_check_cred_relabel(struct ucred *cred, struct label *newlabel)
1121{
1122	struct mac_biba *subj, *new;
1123	int error;
1124
1125	subj = SLOT(&cred->cr_label);
1126	new = SLOT(newlabel);
1127
1128	/*
1129	 * If there is a Biba label update for the credential, it may
1130	 * be an update of the single, range, or both.
1131	 */
1132	error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
1133	if (error)
1134		return (error);
1135
1136	/*
1137	 * If the Biba label is to be changed, authorize as appropriate.
1138	 */
1139	if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) {
1140		/*
1141		 * To change the Biba single label on a credential, the
1142		 * new single label must be in the current range.
1143		 */
1144		if (new->mb_flags & MAC_BIBA_FLAG_SINGLE &&
1145		    !mac_biba_single_in_range(new, subj))
1146			return (EPERM);
1147
1148		/*
1149		 * To change the Biba range on a credential, the new
1150		 * range label must be in the current range.
1151		 */
1152		if (new->mb_flags & MAC_BIBA_FLAG_RANGE &&
1153		    !mac_biba_range_in_range(new, subj))
1154			return (EPERM);
1155
1156		/*
1157		 * To have EQUAL in any component of the new credential
1158		 * Biba label, the subject must already have EQUAL in
1159		 * their label.
1160		 */
1161		if (mac_biba_contains_equal(new)) {
1162			error = mac_biba_subject_equal_ok(subj);
1163			if (error)
1164				return (error);
1165		}
1166
1167		/*
1168		 * XXXMAC: Additional consistency tests regarding the
1169		 * single and range of the new label might be performed
1170		 * here.
1171		 */
1172	}
1173
1174	return (0);
1175}
1176
1177static int
1178mac_biba_check_cred_visible(struct ucred *u1, struct ucred *u2)
1179{
1180	struct mac_biba *subj, *obj;
1181
1182	if (!mac_biba_enabled)
1183		return (0);
1184
1185	subj = SLOT(&u1->cr_label);
1186	obj = SLOT(&u2->cr_label);
1187
1188	/* XXX: range */
1189	if (!mac_biba_dominate_single(obj, subj))
1190		return (ESRCH);
1191
1192	return (0);
1193}
1194
1195static int
1196mac_biba_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet,
1197    struct label *ifnetlabel, struct label *newlabel)
1198{
1199	struct mac_biba *subj, *new;
1200	int error;
1201
1202	subj = SLOT(&cred->cr_label);
1203	new = SLOT(newlabel);
1204
1205	/*
1206	 * If there is a Biba label update for the interface, it may
1207	 * be an update of the single, range, or both.
1208	 */
1209	error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH);
1210	if (error)
1211		return (error);
1212
1213	/*
1214	 * If the Biba label is to be changed, authorize as appropriate.
1215	 */
1216	if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) {
1217		/*
1218		 * Rely on the traditional superuser status for the Biba
1219		 * interface relabel requirements.  XXXMAC: This will go
1220		 * away.
1221		 */
1222		error = suser_cred(cred, 0);
1223		if (error)
1224			return (EPERM);
1225
1226		/*
1227		 * XXXMAC: Additional consistency tests regarding the single
1228		 * and the range of the new label might be performed here.
1229		 */
1230	}
1231
1232	return (0);
1233}
1234
1235static int
1236mac_biba_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel,
1237    struct mbuf *m, struct label *mbuflabel)
1238{
1239	struct mac_biba *p, *i;
1240
1241	if (!mac_biba_enabled)
1242		return (0);
1243
1244	p = SLOT(mbuflabel);
1245	i = SLOT(ifnetlabel);
1246
1247	return (mac_biba_single_in_range(p, i) ? 0 : EACCES);
1248}
1249
1250static int
1251mac_biba_check_mount_stat(struct ucred *cred, struct mount *mp,
1252    struct label *mntlabel)
1253{
1254	struct mac_biba *subj, *obj;
1255
1256	if (!mac_biba_enabled)
1257		return (0);
1258
1259	subj = SLOT(&cred->cr_label);
1260	obj = SLOT(mntlabel);
1261
1262	if (!mac_biba_dominate_single(obj, subj))
1263		return (EACCES);
1264
1265	return (0);
1266}
1267
1268static int
1269mac_biba_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe,
1270    struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data)
1271{
1272
1273	if(!mac_biba_enabled)
1274		return (0);
1275
1276	/* XXX: This will be implemented soon... */
1277
1278	return (0);
1279}
1280
1281static int
1282mac_biba_check_pipe_poll(struct ucred *cred, struct pipe *pipe,
1283    struct label *pipelabel)
1284{
1285	struct mac_biba *subj, *obj;
1286
1287	if (!mac_biba_enabled)
1288		return (0);
1289
1290	subj = SLOT(&cred->cr_label);
1291	obj = SLOT((pipelabel));
1292
1293	if (!mac_biba_dominate_single(obj, subj))
1294		return (EACCES);
1295
1296	return (0);
1297}
1298
1299static int
1300mac_biba_check_pipe_read(struct ucred *cred, struct pipe *pipe,
1301    struct label *pipelabel)
1302{
1303	struct mac_biba *subj, *obj;
1304
1305	if (!mac_biba_enabled)
1306		return (0);
1307
1308	subj = SLOT(&cred->cr_label);
1309	obj = SLOT((pipelabel));
1310
1311	if (!mac_biba_dominate_single(obj, subj))
1312		return (EACCES);
1313
1314	return (0);
1315}
1316
1317static int
1318mac_biba_check_pipe_relabel(struct ucred *cred, struct pipe *pipe,
1319    struct label *pipelabel, struct label *newlabel)
1320{
1321	struct mac_biba *subj, *obj, *new;
1322	int error;
1323
1324	new = SLOT(newlabel);
1325	subj = SLOT(&cred->cr_label);
1326	obj = SLOT(pipelabel);
1327
1328	/*
1329	 * If there is a Biba label update for a pipe, it must be a
1330	 * single update.
1331	 */
1332	error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE);
1333	if (error)
1334		return (error);
1335
1336	/*
1337	 * To perform a relabel of a pipe (Biba label or not), Biba must
1338	 * authorize the relabel.
1339	 */
1340	if (!mac_biba_single_in_range(obj, subj))
1341		return (EPERM);
1342
1343	/*
1344	 * If the Biba label is to be changed, authorize as appropriate.
1345	 */
1346	if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) {
1347		/*
1348		 * To change the Biba label on a pipe, the new pipe label
1349		 * must be in the subject range.
1350		 */
1351		if (!mac_biba_single_in_range(new, subj))
1352			return (EPERM);
1353
1354		/*
1355		 * To change the Biba label on a pipe to be EQUAL, the
1356		 * subject must have appropriate privilege.
1357		 */
1358		if (mac_biba_contains_equal(new)) {
1359			error = mac_biba_subject_equal_ok(subj);
1360			if (error)
1361				return (error);
1362		}
1363	}
1364
1365	return (0);
1366}
1367
1368static int
1369mac_biba_check_pipe_stat(struct ucred *cred, struct pipe *pipe,
1370    struct label *pipelabel)
1371{
1372	struct mac_biba *subj, *obj;
1373
1374	if (!mac_biba_enabled)
1375		return (0);
1376
1377	subj = SLOT(&cred->cr_label);
1378	obj = SLOT((pipelabel));
1379
1380	if (!mac_biba_dominate_single(obj, subj))
1381		return (EACCES);
1382
1383	return (0);
1384}
1385
1386static int
1387mac_biba_check_pipe_write(struct ucred *cred, struct pipe *pipe,
1388    struct label *pipelabel)
1389{
1390	struct mac_biba *subj, *obj;
1391
1392	if (!mac_biba_enabled)
1393		return (0);
1394
1395	subj = SLOT(&cred->cr_label);
1396	obj = SLOT((pipelabel));
1397
1398	if (!mac_biba_dominate_single(subj, obj))
1399		return (EACCES);
1400
1401	return (0);
1402}
1403
1404static int
1405mac_biba_check_proc_debug(struct ucred *cred, struct proc *proc)
1406{
1407	struct mac_biba *subj, *obj;
1408
1409	if (!mac_biba_enabled)
1410		return (0);
1411
1412	subj = SLOT(&cred->cr_label);
1413	obj = SLOT(&proc->p_ucred->cr_label);
1414
1415	/* XXX: range checks */
1416	if (!mac_biba_dominate_single(obj, subj))
1417		return (ESRCH);
1418	if (!mac_biba_dominate_single(subj, obj))
1419		return (EACCES);
1420
1421	return (0);
1422}
1423
1424static int
1425mac_biba_check_proc_sched(struct ucred *cred, struct proc *proc)
1426{
1427	struct mac_biba *subj, *obj;
1428
1429	if (!mac_biba_enabled)
1430		return (0);
1431
1432	subj = SLOT(&cred->cr_label);
1433	obj = SLOT(&proc->p_ucred->cr_label);
1434
1435	/* XXX: range checks */
1436	if (!mac_biba_dominate_single(obj, subj))
1437		return (ESRCH);
1438	if (!mac_biba_dominate_single(subj, obj))
1439		return (EACCES);
1440
1441	return (0);
1442}
1443
1444static int
1445mac_biba_check_proc_signal(struct ucred *cred, struct proc *proc, int signum)
1446{
1447	struct mac_biba *subj, *obj;
1448
1449	if (!mac_biba_enabled)
1450		return (0);
1451
1452	subj = SLOT(&cred->cr_label);
1453	obj = SLOT(&proc->p_ucred->cr_label);
1454
1455	/* XXX: range checks */
1456	if (!mac_biba_dominate_single(obj, subj))
1457		return (ESRCH);
1458	if (!mac_biba_dominate_single(subj, obj))
1459		return (EACCES);
1460
1461	return (0);
1462}
1463
1464static int
1465mac_biba_check_socket_deliver(struct socket *so, struct label *socketlabel,
1466    struct mbuf *m, struct label *mbuflabel)
1467{
1468	struct mac_biba *p, *s;
1469
1470	if (!mac_biba_enabled)
1471		return (0);
1472
1473	p = SLOT(mbuflabel);
1474	s = SLOT(socketlabel);
1475
1476	return (mac_biba_equal_single(p, s) ? 0 : EACCES);
1477}
1478
1479static int
1480mac_biba_check_socket_relabel(struct ucred *cred, struct socket *socket,
1481    struct label *socketlabel, struct label *newlabel)
1482{
1483	struct mac_biba *subj, *obj, *new;
1484	int error;
1485
1486	new = SLOT(newlabel);
1487	subj = SLOT(&cred->cr_label);
1488	obj = SLOT(socketlabel);
1489
1490	/*
1491	 * If there is a Biba label update for the socket, it may be
1492	 * an update of single.
1493	 */
1494	error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE);
1495	if (error)
1496		return (error);
1497
1498	/*
1499	 * To relabel a socket, the old socket single must be in the subject
1500	 * range.
1501	 */
1502	if (!mac_biba_single_in_range(obj, subj))
1503		return (EPERM);
1504
1505	/*
1506	 * If the Biba label is to be changed, authorize as appropriate.
1507	 */
1508	if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) {
1509		/*
1510		 * To relabel a socket, the new socket single must be in
1511		 * the subject range.
1512		 */
1513		if (!mac_biba_single_in_range(new, subj))
1514			return (EPERM);
1515
1516		/*
1517		 * To change the Biba label on the socket to contain EQUAL,
1518		 * the subject must have appropriate privilege.
1519		 */
1520		if (mac_biba_contains_equal(new)) {
1521			error = mac_biba_subject_equal_ok(subj);
1522			if (error)
1523				return (error);
1524		}
1525	}
1526
1527	return (0);
1528}
1529
1530static int
1531mac_biba_check_socket_visible(struct ucred *cred, struct socket *socket,
1532    struct label *socketlabel)
1533{
1534	struct mac_biba *subj, *obj;
1535
1536	subj = SLOT(&cred->cr_label);
1537	obj = SLOT(socketlabel);
1538
1539	if (!mac_biba_dominate_single(obj, subj))
1540		return (ENOENT);
1541
1542	return (0);
1543}
1544
1545static int
1546mac_biba_check_vnode_chdir(struct ucred *cred, struct vnode *dvp,
1547    struct label *dlabel)
1548{
1549	struct mac_biba *subj, *obj;
1550
1551	if (!mac_biba_enabled)
1552		return (0);
1553
1554	subj = SLOT(&cred->cr_label);
1555	obj = SLOT(dlabel);
1556
1557	if (!mac_biba_dominate_single(obj, subj))
1558		return (EACCES);
1559
1560	return (0);
1561}
1562
1563static int
1564mac_biba_check_vnode_chroot(struct ucred *cred, struct vnode *dvp,
1565    struct label *dlabel)
1566{
1567	struct mac_biba *subj, *obj;
1568
1569	if (!mac_biba_enabled)
1570		return (0);
1571
1572	subj = SLOT(&cred->cr_label);
1573	obj = SLOT(dlabel);
1574
1575	if (!mac_biba_dominate_single(obj, subj))
1576		return (EACCES);
1577
1578	return (0);
1579}
1580
1581static int
1582mac_biba_check_vnode_create(struct ucred *cred, struct vnode *dvp,
1583    struct label *dlabel, struct componentname *cnp, struct vattr *vap)
1584{
1585	struct mac_biba *subj, *obj;
1586
1587	if (!mac_biba_enabled)
1588		return (0);
1589
1590	subj = SLOT(&cred->cr_label);
1591	obj = SLOT(dlabel);
1592
1593	if (!mac_biba_dominate_single(subj, obj))
1594		return (EACCES);
1595
1596	return (0);
1597}
1598
1599static int
1600mac_biba_check_vnode_delete(struct ucred *cred, struct vnode *dvp,
1601    struct label *dlabel, struct vnode *vp, struct label *label,
1602    struct componentname *cnp)
1603{
1604	struct mac_biba *subj, *obj;
1605
1606	if (!mac_biba_enabled)
1607		return (0);
1608
1609	subj = SLOT(&cred->cr_label);
1610	obj = SLOT(dlabel);
1611
1612	if (!mac_biba_dominate_single(subj, obj))
1613		return (EACCES);
1614
1615	obj = SLOT(label);
1616
1617	if (!mac_biba_dominate_single(subj, obj))
1618		return (EACCES);
1619
1620	return (0);
1621}
1622
1623static int
1624mac_biba_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
1625    struct label *label, acl_type_t type)
1626{
1627	struct mac_biba *subj, *obj;
1628
1629	if (!mac_biba_enabled)
1630		return (0);
1631
1632	subj = SLOT(&cred->cr_label);
1633	obj = SLOT(label);
1634
1635	if (!mac_biba_dominate_single(subj, obj))
1636		return (EACCES);
1637
1638	return (0);
1639}
1640
1641static int
1642mac_biba_check_vnode_exec(struct ucred *cred, struct vnode *vp,
1643    struct label *label)
1644{
1645	struct mac_biba *subj, *obj;
1646
1647	if (!mac_biba_enabled)
1648		return (0);
1649
1650	subj = SLOT(&cred->cr_label);
1651	obj = SLOT(label);
1652
1653	if (!mac_biba_dominate_single(obj, subj))
1654		return (EACCES);
1655
1656	return (0);
1657}
1658
1659static int
1660mac_biba_check_vnode_getacl(struct ucred *cred, struct vnode *vp,
1661    struct label *label, acl_type_t type)
1662{
1663	struct mac_biba *subj, *obj;
1664
1665	if (!mac_biba_enabled)
1666		return (0);
1667
1668	subj = SLOT(&cred->cr_label);
1669	obj = SLOT(label);
1670
1671	if (!mac_biba_dominate_single(obj, subj))
1672		return (EACCES);
1673
1674	return (0);
1675}
1676
1677static int
1678mac_biba_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
1679    struct label *label, int attrnamespace, const char *name, struct uio *uio)
1680{
1681	struct mac_biba *subj, *obj;
1682
1683	if (!mac_biba_enabled)
1684		return (0);
1685
1686	subj = SLOT(&cred->cr_label);
1687	obj = SLOT(label);
1688
1689	if (!mac_biba_dominate_single(obj, subj))
1690		return (EACCES);
1691
1692	return (0);
1693}
1694
1695static int
1696mac_biba_check_vnode_link(struct ucred *cred, struct vnode *dvp,
1697    struct label *dlabel, struct vnode *vp, struct label *label,
1698    struct componentname *cnp)
1699{
1700	struct mac_biba *subj, *obj;
1701
1702	if (!mac_biba_enabled)
1703		return (0);
1704
1705	subj = SLOT(&cred->cr_label);
1706	obj = SLOT(dlabel);
1707
1708	if (!mac_biba_dominate_single(subj, obj))
1709		return (EACCES);
1710
1711	obj = SLOT(label);
1712
1713	if (!mac_biba_dominate_single(subj, obj))
1714		return (EACCES);
1715
1716	return (0);
1717}
1718
1719static int
1720mac_biba_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
1721    struct label *dlabel, struct componentname *cnp)
1722{
1723	struct mac_biba *subj, *obj;
1724
1725	if (!mac_biba_enabled)
1726		return (0);
1727
1728	subj = SLOT(&cred->cr_label);
1729	obj = SLOT(dlabel);
1730
1731	if (!mac_biba_dominate_single(obj, subj))
1732		return (EACCES);
1733
1734	return (0);
1735}
1736
1737static int
1738mac_biba_check_vnode_mmap(struct ucred *cred, struct vnode *vp,
1739    struct label *label, int prot)
1740{
1741	struct mac_biba *subj, *obj;
1742
1743	/*
1744	 * Rely on the use of open()-time protections to handle
1745	 * non-revocation cases.
1746	 */
1747	if (!mac_biba_enabled || !revocation_enabled)
1748		return (0);
1749
1750	subj = SLOT(&cred->cr_label);
1751	obj = SLOT(label);
1752
1753	if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
1754		if (!mac_biba_dominate_single(obj, subj))
1755			return (EACCES);
1756	}
1757	if (prot & VM_PROT_WRITE) {
1758		if (!mac_biba_dominate_single(subj, obj))
1759			return (EACCES);
1760	}
1761
1762	return (0);
1763}
1764
1765static int
1766mac_biba_check_vnode_open(struct ucred *cred, struct vnode *vp,
1767    struct label *vnodelabel, mode_t acc_mode)
1768{
1769	struct mac_biba *subj, *obj;
1770
1771	if (!mac_biba_enabled)
1772		return (0);
1773
1774	subj = SLOT(&cred->cr_label);
1775	obj = SLOT(vnodelabel);
1776
1777	/* XXX privilege override for admin? */
1778	if (acc_mode & (VREAD | VEXEC | VSTAT)) {
1779		if (!mac_biba_dominate_single(obj, subj))
1780			return (EACCES);
1781	}
1782	if (acc_mode & (VWRITE | VAPPEND | VADMIN)) {
1783		if (!mac_biba_dominate_single(subj, obj))
1784			return (EACCES);
1785	}
1786
1787	return (0);
1788}
1789
1790static int
1791mac_biba_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred,
1792    struct vnode *vp, struct label *label)
1793{
1794	struct mac_biba *subj, *obj;
1795
1796	if (!mac_biba_enabled || !revocation_enabled)
1797		return (0);
1798
1799	subj = SLOT(&active_cred->cr_label);
1800	obj = SLOT(label);
1801
1802	if (!mac_biba_dominate_single(obj, subj))
1803		return (EACCES);
1804
1805	return (0);
1806}
1807
1808static int
1809mac_biba_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
1810    struct vnode *vp, struct label *label)
1811{
1812	struct mac_biba *subj, *obj;
1813
1814	if (!mac_biba_enabled || !revocation_enabled)
1815		return (0);
1816
1817	subj = SLOT(&active_cred->cr_label);
1818	obj = SLOT(label);
1819
1820	if (!mac_biba_dominate_single(obj, subj))
1821		return (EACCES);
1822
1823	return (0);
1824}
1825
1826static int
1827mac_biba_check_vnode_readdir(struct ucred *cred, struct vnode *dvp,
1828    struct label *dlabel)
1829{
1830	struct mac_biba *subj, *obj;
1831
1832	if (!mac_biba_enabled)
1833		return (0);
1834
1835	subj = SLOT(&cred->cr_label);
1836	obj = SLOT(dlabel);
1837
1838	if (!mac_biba_dominate_single(obj, subj))
1839		return (EACCES);
1840
1841	return (0);
1842}
1843
1844static int
1845mac_biba_check_vnode_readlink(struct ucred *cred, struct vnode *vp,
1846    struct label *label)
1847{
1848	struct mac_biba *subj, *obj;
1849
1850	if (!mac_biba_enabled)
1851		return (0);
1852
1853	subj = SLOT(&cred->cr_label);
1854	obj = SLOT(label);
1855
1856	if (!mac_biba_dominate_single(obj, subj))
1857		return (EACCES);
1858
1859	return (0);
1860}
1861
1862static int
1863mac_biba_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
1864    struct label *vnodelabel, struct label *newlabel)
1865{
1866	struct mac_biba *old, *new, *subj;
1867	int error;
1868
1869	old = SLOT(vnodelabel);
1870	new = SLOT(newlabel);
1871	subj = SLOT(&cred->cr_label);
1872
1873	/*
1874	 * If there is a Biba label update for the vnode, it must be a
1875	 * single label.
1876	 */
1877	error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE);
1878	if (error)
1879		return (error);
1880
1881	/*
1882	 * To perform a relabel of the vnode (Biba label or not), Biba must
1883	 * authorize the relabel.
1884	 */
1885	if (!mac_biba_single_in_range(old, subj))
1886		return (EPERM);
1887
1888	/*
1889	 * If the Biba label is to be changed, authorize as appropriate.
1890	 */
1891	if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) {
1892		/*
1893		 * To change the Biba label on a vnode, the new vnode label
1894		 * must be in the subject range.
1895		 */
1896		if (!mac_biba_single_in_range(new, subj))
1897			return (EPERM);
1898
1899		/*
1900		 * To change the Biba label on the vnode to be EQUAL,
1901		 * the subject must have appropriate privilege.
1902		 */
1903		if (mac_biba_contains_equal(new)) {
1904			error = mac_biba_subject_equal_ok(subj);
1905			if (error)
1906				return (error);
1907		}
1908	}
1909
1910	return (0);
1911}
1912
1913static int
1914mac_biba_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
1915    struct label *dlabel, struct vnode *vp, struct label *label,
1916    struct componentname *cnp)
1917{
1918	struct mac_biba *subj, *obj;
1919
1920	if (!mac_biba_enabled)
1921		return (0);
1922
1923	subj = SLOT(&cred->cr_label);
1924	obj = SLOT(dlabel);
1925
1926	if (!mac_biba_dominate_single(subj, obj))
1927		return (EACCES);
1928
1929	obj = SLOT(label);
1930
1931	if (!mac_biba_dominate_single(subj, obj))
1932		return (EACCES);
1933
1934	return (0);
1935}
1936
1937static int
1938mac_biba_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
1939    struct label *dlabel, struct vnode *vp, struct label *label, int samedir,
1940    struct componentname *cnp)
1941{
1942	struct mac_biba *subj, *obj;
1943
1944	if (!mac_biba_enabled)
1945		return (0);
1946
1947	subj = SLOT(&cred->cr_label);
1948	obj = SLOT(dlabel);
1949
1950	if (!mac_biba_dominate_single(subj, obj))
1951		return (EACCES);
1952
1953	if (vp != NULL) {
1954		obj = SLOT(label);
1955
1956		if (!mac_biba_dominate_single(subj, obj))
1957			return (EACCES);
1958	}
1959
1960	return (0);
1961}
1962
1963static int
1964mac_biba_check_vnode_revoke(struct ucred *cred, struct vnode *vp,
1965    struct label *label)
1966{
1967	struct mac_biba *subj, *obj;
1968
1969	if (!mac_biba_enabled)
1970		return (0);
1971
1972	subj = SLOT(&cred->cr_label);
1973	obj = SLOT(label);
1974
1975	if (!mac_biba_dominate_single(subj, obj))
1976		return (EACCES);
1977
1978	return (0);
1979}
1980
1981static int
1982mac_biba_check_vnode_setacl(struct ucred *cred, struct vnode *vp,
1983    struct label *label, acl_type_t type, struct acl *acl)
1984{
1985	struct mac_biba *subj, *obj;
1986
1987	if (!mac_biba_enabled)
1988		return (0);
1989
1990	subj = SLOT(&cred->cr_label);
1991	obj = SLOT(label);
1992
1993	if (!mac_biba_dominate_single(subj, obj))
1994		return (EACCES);
1995
1996	return (0);
1997}
1998
1999static int
2000mac_biba_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
2001    struct label *vnodelabel, int attrnamespace, const char *name,
2002    struct uio *uio)
2003{
2004	struct mac_biba *subj, *obj;
2005
2006	if (!mac_biba_enabled)
2007		return (0);
2008
2009	subj = SLOT(&cred->cr_label);
2010	obj = SLOT(vnodelabel);
2011
2012	if (!mac_biba_dominate_single(subj, obj))
2013		return (EACCES);
2014
2015	/* XXX: protect the MAC EA in a special way? */
2016
2017	return (0);
2018}
2019
2020static int
2021mac_biba_check_vnode_setflags(struct ucred *cred, struct vnode *vp,
2022    struct label *vnodelabel, u_long flags)
2023{
2024	struct mac_biba *subj, *obj;
2025
2026	if (!mac_biba_enabled)
2027		return (0);
2028
2029	subj = SLOT(&cred->cr_label);
2030	obj = SLOT(vnodelabel);
2031
2032	if (!mac_biba_dominate_single(subj, obj))
2033		return (EACCES);
2034
2035	return (0);
2036}
2037
2038static int
2039mac_biba_check_vnode_setmode(struct ucred *cred, struct vnode *vp,
2040    struct label *vnodelabel, mode_t mode)
2041{
2042	struct mac_biba *subj, *obj;
2043
2044	if (!mac_biba_enabled)
2045		return (0);
2046
2047	subj = SLOT(&cred->cr_label);
2048	obj = SLOT(vnodelabel);
2049
2050	if (!mac_biba_dominate_single(subj, obj))
2051		return (EACCES);
2052
2053	return (0);
2054}
2055
2056static int
2057mac_biba_check_vnode_setowner(struct ucred *cred, struct vnode *vp,
2058    struct label *vnodelabel, uid_t uid, gid_t gid)
2059{
2060	struct mac_biba *subj, *obj;
2061
2062	if (!mac_biba_enabled)
2063		return (0);
2064
2065	subj = SLOT(&cred->cr_label);
2066	obj = SLOT(vnodelabel);
2067
2068	if (!mac_biba_dominate_single(subj, obj))
2069		return (EACCES);
2070
2071	return (0);
2072}
2073
2074static int
2075mac_biba_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
2076    struct label *vnodelabel, struct timespec atime, struct timespec mtime)
2077{
2078	struct mac_biba *subj, *obj;
2079
2080	if (!mac_biba_enabled)
2081		return (0);
2082
2083	subj = SLOT(&cred->cr_label);
2084	obj = SLOT(vnodelabel);
2085
2086	if (!mac_biba_dominate_single(subj, obj))
2087		return (EACCES);
2088
2089	return (0);
2090}
2091
2092static int
2093mac_biba_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
2094    struct vnode *vp, struct label *vnodelabel)
2095{
2096	struct mac_biba *subj, *obj;
2097
2098	if (!mac_biba_enabled)
2099		return (0);
2100
2101	subj = SLOT(&active_cred->cr_label);
2102	obj = SLOT(vnodelabel);
2103
2104	if (!mac_biba_dominate_single(obj, subj))
2105		return (EACCES);
2106
2107	return (0);
2108}
2109
2110static int
2111mac_biba_check_vnode_write(struct ucred *active_cred,
2112    struct ucred *file_cred, struct vnode *vp, struct label *label)
2113{
2114	struct mac_biba *subj, *obj;
2115
2116	if (!mac_biba_enabled || !revocation_enabled)
2117		return (0);
2118
2119	subj = SLOT(&active_cred->cr_label);
2120	obj = SLOT(label);
2121
2122	if (!mac_biba_dominate_single(subj, obj))
2123		return (EACCES);
2124
2125	return (0);
2126}
2127
2128static struct mac_policy_op_entry mac_biba_ops[] =
2129{
2130	{ MAC_DESTROY,
2131	    (macop_t)mac_biba_destroy },
2132	{ MAC_INIT,
2133	    (macop_t)mac_biba_init },
2134	{ MAC_INIT_BPFDESC_LABEL,
2135	    (macop_t)mac_biba_init_label },
2136	{ MAC_INIT_CRED_LABEL,
2137	    (macop_t)mac_biba_init_label },
2138	{ MAC_INIT_DEVFSDIRENT_LABEL,
2139	    (macop_t)mac_biba_init_label },
2140	{ MAC_INIT_IFNET_LABEL,
2141	    (macop_t)mac_biba_init_label },
2142	{ MAC_INIT_IPQ_LABEL,
2143	    (macop_t)mac_biba_init_label },
2144	{ MAC_INIT_MBUF_LABEL,
2145	    (macop_t)mac_biba_init_label_waitcheck },
2146	{ MAC_INIT_MOUNT_LABEL,
2147	    (macop_t)mac_biba_init_label },
2148	{ MAC_INIT_MOUNT_FS_LABEL,
2149	    (macop_t)mac_biba_init_label },
2150	{ MAC_INIT_PIPE_LABEL,
2151	    (macop_t)mac_biba_init_label },
2152	{ MAC_INIT_SOCKET_LABEL,
2153	    (macop_t)mac_biba_init_label_waitcheck },
2154	{ MAC_INIT_SOCKET_PEER_LABEL,
2155	    (macop_t)mac_biba_init_label_waitcheck },
2156	{ MAC_INIT_TEMP_LABEL,
2157	    (macop_t)mac_biba_init_label },
2158	{ MAC_INIT_VNODE_LABEL,
2159	    (macop_t)mac_biba_init_label },
2160	{ MAC_DESTROY_BPFDESC_LABEL,
2161	    (macop_t)mac_biba_destroy_label },
2162	{ MAC_DESTROY_CRED_LABEL,
2163	    (macop_t)mac_biba_destroy_label },
2164	{ MAC_DESTROY_DEVFSDIRENT_LABEL,
2165	    (macop_t)mac_biba_destroy_label },
2166	{ MAC_DESTROY_IFNET_LABEL,
2167	    (macop_t)mac_biba_destroy_label },
2168	{ MAC_DESTROY_IPQ_LABEL,
2169	    (macop_t)mac_biba_destroy_label },
2170	{ MAC_DESTROY_MBUF_LABEL,
2171	    (macop_t)mac_biba_destroy_label },
2172	{ MAC_DESTROY_MOUNT_LABEL,
2173	    (macop_t)mac_biba_destroy_label },
2174	{ MAC_DESTROY_MOUNT_FS_LABEL,
2175	    (macop_t)mac_biba_destroy_label },
2176	{ MAC_DESTROY_PIPE_LABEL,
2177	    (macop_t)mac_biba_destroy_label },
2178	{ MAC_DESTROY_SOCKET_LABEL,
2179	    (macop_t)mac_biba_destroy_label },
2180	{ MAC_DESTROY_SOCKET_PEER_LABEL,
2181	    (macop_t)mac_biba_destroy_label },
2182	{ MAC_DESTROY_TEMP_LABEL,
2183	    (macop_t)mac_biba_destroy_label },
2184	{ MAC_DESTROY_VNODE_LABEL,
2185	    (macop_t)mac_biba_destroy_label },
2186	{ MAC_EXTERNALIZE,
2187	    (macop_t)mac_biba_externalize },
2188	{ MAC_INTERNALIZE,
2189	    (macop_t)mac_biba_internalize },
2190	{ MAC_CREATE_DEVFS_DEVICE,
2191	    (macop_t)mac_biba_create_devfs_device },
2192	{ MAC_CREATE_DEVFS_DIRECTORY,
2193	    (macop_t)mac_biba_create_devfs_directory },
2194	{ MAC_CREATE_DEVFS_SYMLINK,
2195	    (macop_t)mac_biba_create_devfs_symlink },
2196	{ MAC_CREATE_DEVFS_VNODE,
2197	    (macop_t)mac_biba_create_devfs_vnode },
2198	{ MAC_CREATE_VNODE,
2199	    (macop_t)mac_biba_create_vnode },
2200	{ MAC_CREATE_MOUNT,
2201	    (macop_t)mac_biba_create_mount },
2202	{ MAC_CREATE_ROOT_MOUNT,
2203	    (macop_t)mac_biba_create_root_mount },
2204	{ MAC_RELABEL_VNODE,
2205	    (macop_t)mac_biba_relabel_vnode },
2206	{ MAC_UPDATE_DEVFSDIRENT,
2207	    (macop_t)mac_biba_update_devfsdirent },
2208	{ MAC_UPDATE_PROCFSVNODE,
2209	    (macop_t)mac_biba_update_procfsvnode },
2210	{ MAC_UPDATE_VNODE_FROM_EXTERNALIZED,
2211	    (macop_t)mac_biba_update_vnode_from_externalized },
2212	{ MAC_UPDATE_VNODE_FROM_MOUNT,
2213	    (macop_t)mac_biba_update_vnode_from_mount },
2214	{ MAC_CREATE_MBUF_FROM_SOCKET,
2215	    (macop_t)mac_biba_create_mbuf_from_socket },
2216	{ MAC_CREATE_PIPE,
2217	    (macop_t)mac_biba_create_pipe },
2218	{ MAC_CREATE_SOCKET,
2219	    (macop_t)mac_biba_create_socket },
2220	{ MAC_CREATE_SOCKET_FROM_SOCKET,
2221	    (macop_t)mac_biba_create_socket_from_socket },
2222	{ MAC_RELABEL_PIPE,
2223	    (macop_t)mac_biba_relabel_pipe },
2224	{ MAC_RELABEL_SOCKET,
2225	    (macop_t)mac_biba_relabel_socket },
2226	{ MAC_SET_SOCKET_PEER_FROM_MBUF,
2227	    (macop_t)mac_biba_set_socket_peer_from_mbuf },
2228	{ MAC_SET_SOCKET_PEER_FROM_SOCKET,
2229	    (macop_t)mac_biba_set_socket_peer_from_socket },
2230	{ MAC_CREATE_BPFDESC,
2231	    (macop_t)mac_biba_create_bpfdesc },
2232	{ MAC_CREATE_DATAGRAM_FROM_IPQ,
2233	    (macop_t)mac_biba_create_datagram_from_ipq },
2234	{ MAC_CREATE_FRAGMENT,
2235	    (macop_t)mac_biba_create_fragment },
2236	{ MAC_CREATE_IFNET,
2237	    (macop_t)mac_biba_create_ifnet },
2238	{ MAC_CREATE_IPQ,
2239	    (macop_t)mac_biba_create_ipq },
2240	{ MAC_CREATE_MBUF_FROM_MBUF,
2241	    (macop_t)mac_biba_create_mbuf_from_mbuf },
2242	{ MAC_CREATE_MBUF_LINKLAYER,
2243	    (macop_t)mac_biba_create_mbuf_linklayer },
2244	{ MAC_CREATE_MBUF_FROM_BPFDESC,
2245	    (macop_t)mac_biba_create_mbuf_from_bpfdesc },
2246	{ MAC_CREATE_MBUF_FROM_IFNET,
2247	    (macop_t)mac_biba_create_mbuf_from_ifnet },
2248	{ MAC_CREATE_MBUF_MULTICAST_ENCAP,
2249	    (macop_t)mac_biba_create_mbuf_multicast_encap },
2250	{ MAC_CREATE_MBUF_NETLAYER,
2251	    (macop_t)mac_biba_create_mbuf_netlayer },
2252	{ MAC_FRAGMENT_MATCH,
2253	    (macop_t)mac_biba_fragment_match },
2254	{ MAC_RELABEL_IFNET,
2255	    (macop_t)mac_biba_relabel_ifnet },
2256	{ MAC_UPDATE_IPQ,
2257	    (macop_t)mac_biba_update_ipq },
2258	{ MAC_CREATE_CRED,
2259	    (macop_t)mac_biba_create_cred },
2260	{ MAC_EXECVE_TRANSITION,
2261	    (macop_t)mac_biba_execve_transition },
2262	{ MAC_EXECVE_WILL_TRANSITION,
2263	    (macop_t)mac_biba_execve_will_transition },
2264	{ MAC_CREATE_PROC0,
2265	    (macop_t)mac_biba_create_proc0 },
2266	{ MAC_CREATE_PROC1,
2267	    (macop_t)mac_biba_create_proc1 },
2268	{ MAC_RELABEL_CRED,
2269	    (macop_t)mac_biba_relabel_cred },
2270	{ MAC_CHECK_BPFDESC_RECEIVE,
2271	    (macop_t)mac_biba_check_bpfdesc_receive },
2272	{ MAC_CHECK_CRED_RELABEL,
2273	    (macop_t)mac_biba_check_cred_relabel },
2274	{ MAC_CHECK_CRED_VISIBLE,
2275	    (macop_t)mac_biba_check_cred_visible },
2276	{ MAC_CHECK_IFNET_RELABEL,
2277	    (macop_t)mac_biba_check_ifnet_relabel },
2278	{ MAC_CHECK_IFNET_TRANSMIT,
2279	    (macop_t)mac_biba_check_ifnet_transmit },
2280	{ MAC_CHECK_MOUNT_STAT,
2281	    (macop_t)mac_biba_check_mount_stat },
2282	{ MAC_CHECK_PIPE_IOCTL,
2283	    (macop_t)mac_biba_check_pipe_ioctl },
2284	{ MAC_CHECK_PIPE_POLL,
2285	    (macop_t)mac_biba_check_pipe_poll },
2286	{ MAC_CHECK_PIPE_READ,
2287	    (macop_t)mac_biba_check_pipe_read },
2288	{ MAC_CHECK_PIPE_RELABEL,
2289	    (macop_t)mac_biba_check_pipe_relabel },
2290	{ MAC_CHECK_PIPE_STAT,
2291	    (macop_t)mac_biba_check_pipe_stat },
2292	{ MAC_CHECK_PIPE_WRITE,
2293	    (macop_t)mac_biba_check_pipe_write },
2294	{ MAC_CHECK_PROC_DEBUG,
2295	    (macop_t)mac_biba_check_proc_debug },
2296	{ MAC_CHECK_PROC_SCHED,
2297	    (macop_t)mac_biba_check_proc_sched },
2298	{ MAC_CHECK_PROC_SIGNAL,
2299	    (macop_t)mac_biba_check_proc_signal },
2300	{ MAC_CHECK_SOCKET_DELIVER,
2301	    (macop_t)mac_biba_check_socket_deliver },
2302	{ MAC_CHECK_SOCKET_RELABEL,
2303	    (macop_t)mac_biba_check_socket_relabel },
2304	{ MAC_CHECK_SOCKET_VISIBLE,
2305	    (macop_t)mac_biba_check_socket_visible },
2306	{ MAC_CHECK_VNODE_ACCESS,
2307	    (macop_t)mac_biba_check_vnode_open },
2308	{ MAC_CHECK_VNODE_CHDIR,
2309	    (macop_t)mac_biba_check_vnode_chdir },
2310	{ MAC_CHECK_VNODE_CHROOT,
2311	    (macop_t)mac_biba_check_vnode_chroot },
2312	{ MAC_CHECK_VNODE_CREATE,
2313	    (macop_t)mac_biba_check_vnode_create },
2314	{ MAC_CHECK_VNODE_DELETE,
2315	    (macop_t)mac_biba_check_vnode_delete },
2316	{ MAC_CHECK_VNODE_DELETEACL,
2317	    (macop_t)mac_biba_check_vnode_deleteacl },
2318	{ MAC_CHECK_VNODE_EXEC,
2319	    (macop_t)mac_biba_check_vnode_exec },
2320	{ MAC_CHECK_VNODE_GETACL,
2321	    (macop_t)mac_biba_check_vnode_getacl },
2322	{ MAC_CHECK_VNODE_GETEXTATTR,
2323	    (macop_t)mac_biba_check_vnode_getextattr },
2324	{ MAC_CHECK_VNODE_LINK,
2325	    (macop_t)mac_biba_check_vnode_link },
2326	{ MAC_CHECK_VNODE_LOOKUP,
2327	    (macop_t)mac_biba_check_vnode_lookup },
2328	{ MAC_CHECK_VNODE_MMAP,
2329	    (macop_t)mac_biba_check_vnode_mmap },
2330	{ MAC_CHECK_VNODE_MPROTECT,
2331	    (macop_t)mac_biba_check_vnode_mmap },
2332	{ MAC_CHECK_VNODE_OPEN,
2333	    (macop_t)mac_biba_check_vnode_open },
2334	{ MAC_CHECK_VNODE_POLL,
2335	    (macop_t)mac_biba_check_vnode_poll },
2336	{ MAC_CHECK_VNODE_READ,
2337	    (macop_t)mac_biba_check_vnode_read },
2338	{ MAC_CHECK_VNODE_READDIR,
2339	    (macop_t)mac_biba_check_vnode_readdir },
2340	{ MAC_CHECK_VNODE_READLINK,
2341	    (macop_t)mac_biba_check_vnode_readlink },
2342	{ MAC_CHECK_VNODE_RELABEL,
2343	    (macop_t)mac_biba_check_vnode_relabel },
2344	{ MAC_CHECK_VNODE_RENAME_FROM,
2345	    (macop_t)mac_biba_check_vnode_rename_from },
2346	{ MAC_CHECK_VNODE_RENAME_TO,
2347	    (macop_t)mac_biba_check_vnode_rename_to },
2348	{ MAC_CHECK_VNODE_REVOKE,
2349	    (macop_t)mac_biba_check_vnode_revoke },
2350	{ MAC_CHECK_VNODE_SETACL,
2351	    (macop_t)mac_biba_check_vnode_setacl },
2352	{ MAC_CHECK_VNODE_SETEXTATTR,
2353	    (macop_t)mac_biba_check_vnode_setextattr },
2354	{ MAC_CHECK_VNODE_SETFLAGS,
2355	    (macop_t)mac_biba_check_vnode_setflags },
2356	{ MAC_CHECK_VNODE_SETMODE,
2357	    (macop_t)mac_biba_check_vnode_setmode },
2358	{ MAC_CHECK_VNODE_SETOWNER,
2359	    (macop_t)mac_biba_check_vnode_setowner },
2360	{ MAC_CHECK_VNODE_SETUTIMES,
2361	    (macop_t)mac_biba_check_vnode_setutimes },
2362	{ MAC_CHECK_VNODE_STAT,
2363	    (macop_t)mac_biba_check_vnode_stat },
2364	{ MAC_CHECK_VNODE_WRITE,
2365	    (macop_t)mac_biba_check_vnode_write },
2366	{ MAC_OP_LAST, NULL }
2367};
2368
2369MAC_POLICY_SET(mac_biba_ops, trustedbsd_mac_biba, "TrustedBSD MAC/Biba",
2370    MPC_LOADTIME_FLAG_NOTLATE, &mac_biba_slot);
2371