xref: /freebsd/sys/security/mac_lomac/mac_lomac.c (revision 63dba32b76bdbc5438c5121c7209f7a8f6774b28)
1db2661ceSRobert Watson /*-
2f6a41092SRobert Watson  * Copyright (c) 1999-2002 Robert N. M. Watson
3f6a41092SRobert Watson  * Copyright (c) 2001-2003 Networks Associates Technology, Inc.
4db2661ceSRobert Watson  * All rights reserved.
5db2661ceSRobert Watson  *
6db2661ceSRobert Watson  * This software was developed by Robert Watson for the TrustedBSD Project.
7db2661ceSRobert Watson  *
8db2661ceSRobert Watson  * This software was developed for the FreeBSD Project in part by NAI Labs,
9db2661ceSRobert Watson  * the Security Research Division of Network Associates, Inc. under
10db2661ceSRobert Watson  * DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA
11db2661ceSRobert Watson  * CHATS research program.
12db2661ceSRobert Watson  *
13db2661ceSRobert Watson  * Redistribution and use in source and binary forms, with or without
14db2661ceSRobert Watson  * modification, are permitted provided that the following conditions
15db2661ceSRobert Watson  * are met:
16db2661ceSRobert Watson  * 1. Redistributions of source code must retain the above copyright
17db2661ceSRobert Watson  *    notice, this list of conditions and the following disclaimer.
18db2661ceSRobert Watson  * 2. Redistributions in binary form must reproduce the above copyright
19db2661ceSRobert Watson  *    notice, this list of conditions and the following disclaimer in the
20db2661ceSRobert Watson  *    documentation and/or other materials provided with the distribution.
21db2661ceSRobert Watson  *
22db2661ceSRobert Watson  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
23db2661ceSRobert Watson  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24db2661ceSRobert Watson  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25db2661ceSRobert Watson  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
26db2661ceSRobert Watson  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27db2661ceSRobert Watson  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28db2661ceSRobert Watson  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29db2661ceSRobert Watson  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30db2661ceSRobert Watson  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31db2661ceSRobert Watson  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32db2661ceSRobert Watson  * SUCH DAMAGE.
33db2661ceSRobert Watson  *
34db2661ceSRobert Watson  * $FreeBSD$
35db2661ceSRobert Watson  */
36db2661ceSRobert Watson 
37db2661ceSRobert Watson /*
38db2661ceSRobert Watson  * Developed by the TrustedBSD Project.
39db2661ceSRobert Watson  * Low-watermark floating label mandatory integrity policy.
40db2661ceSRobert Watson  */
41db2661ceSRobert Watson 
42db2661ceSRobert Watson #include <sys/types.h>
43db2661ceSRobert Watson #include <sys/param.h>
44db2661ceSRobert Watson #include <sys/acl.h>
45db2661ceSRobert Watson #include <sys/conf.h>
46db2661ceSRobert Watson #include <sys/extattr.h>
47db2661ceSRobert Watson #include <sys/kernel.h>
48db2661ceSRobert Watson #include <sys/mac.h>
49db2661ceSRobert Watson #include <sys/malloc.h>
50db2661ceSRobert Watson #include <sys/mount.h>
51db2661ceSRobert Watson #include <sys/proc.h>
52f51e5803SRobert Watson #include <sys/sbuf.h>
53db2661ceSRobert Watson #include <sys/systm.h>
54db2661ceSRobert Watson #include <sys/sysproto.h>
55db2661ceSRobert Watson #include <sys/sysent.h>
56db2661ceSRobert Watson #include <sys/systm.h>
57db2661ceSRobert Watson #include <sys/vnode.h>
58db2661ceSRobert Watson #include <sys/file.h>
59db2661ceSRobert Watson #include <sys/socket.h>
60db2661ceSRobert Watson #include <sys/socketvar.h>
61db2661ceSRobert Watson #include <sys/pipe.h>
62db2661ceSRobert Watson #include <sys/sysctl.h>
63db2661ceSRobert Watson #include <sys/syslog.h>
64db2661ceSRobert Watson 
65db2661ceSRobert Watson #include <fs/devfs/devfs.h>
66db2661ceSRobert Watson 
67db2661ceSRobert Watson #include <net/bpfdesc.h>
68db2661ceSRobert Watson #include <net/if.h>
69db2661ceSRobert Watson #include <net/if_types.h>
70db2661ceSRobert Watson #include <net/if_var.h>
71db2661ceSRobert Watson 
72db2661ceSRobert Watson #include <netinet/in.h>
73a557af22SRobert Watson #include <netinet/in_pcb.h>
74db2661ceSRobert Watson #include <netinet/ip_var.h>
75db2661ceSRobert Watson 
76db2661ceSRobert Watson #include <vm/vm.h>
77db2661ceSRobert Watson 
78db2661ceSRobert Watson #include <sys/mac_policy.h>
79db2661ceSRobert Watson 
80db2661ceSRobert Watson #include <security/mac_lomac/mac_lomac.h>
81db2661ceSRobert Watson 
82db2661ceSRobert Watson struct mac_lomac_proc {
83db2661ceSRobert Watson 	struct mac_lomac mac_lomac;
84db2661ceSRobert Watson 	struct mtx mtx;
85db2661ceSRobert Watson };
86db2661ceSRobert Watson 
87db2661ceSRobert Watson SYSCTL_DECL(_security_mac);
88db2661ceSRobert Watson 
89db2661ceSRobert Watson SYSCTL_NODE(_security_mac, OID_AUTO, lomac, CTLFLAG_RW, 0,
90db2661ceSRobert Watson     "TrustedBSD mac_lomac policy controls");
91db2661ceSRobert Watson 
92db2661ceSRobert Watson static int	mac_lomac_label_size = sizeof(struct mac_lomac);
93db2661ceSRobert Watson SYSCTL_INT(_security_mac_lomac, OID_AUTO, label_size, CTLFLAG_RD,
94db2661ceSRobert Watson     &mac_lomac_label_size, 0, "Size of struct mac_lomac");
95db2661ceSRobert Watson 
96eba0370dSRobert Watson static int	mac_lomac_enabled = 1;
97db2661ceSRobert Watson SYSCTL_INT(_security_mac_lomac, OID_AUTO, enabled, CTLFLAG_RW,
98db2661ceSRobert Watson     &mac_lomac_enabled, 0, "Enforce MAC/LOMAC policy");
99db2661ceSRobert Watson TUNABLE_INT("security.mac.lomac.enabled", &mac_lomac_enabled);
100db2661ceSRobert Watson 
101db2661ceSRobert Watson static int	destroyed_not_inited;
102db2661ceSRobert Watson SYSCTL_INT(_security_mac_lomac, OID_AUTO, destroyed_not_inited, CTLFLAG_RD,
103db2661ceSRobert Watson     &destroyed_not_inited, 0, "Count of labels destroyed but not inited");
104db2661ceSRobert Watson 
105db2661ceSRobert Watson static int	trust_all_interfaces = 0;
106db2661ceSRobert Watson SYSCTL_INT(_security_mac_lomac, OID_AUTO, trust_all_interfaces, CTLFLAG_RD,
107db2661ceSRobert Watson     &trust_all_interfaces, 0, "Consider all interfaces 'trusted' by MAC/LOMAC");
108db2661ceSRobert Watson TUNABLE_INT("security.mac.lomac.trust_all_interfaces", &trust_all_interfaces);
109db2661ceSRobert Watson 
110db2661ceSRobert Watson static char	trusted_interfaces[128];
111db2661ceSRobert Watson SYSCTL_STRING(_security_mac_lomac, OID_AUTO, trusted_interfaces, CTLFLAG_RD,
112db2661ceSRobert Watson     trusted_interfaces, 0, "Interfaces considered 'trusted' by MAC/LOMAC");
113db2661ceSRobert Watson TUNABLE_STR("security.mac.lomac.trusted_interfaces", trusted_interfaces,
114db2661ceSRobert Watson     sizeof(trusted_interfaces));
115db2661ceSRobert Watson 
116db2661ceSRobert Watson static int	ptys_equal = 0;
117db2661ceSRobert Watson SYSCTL_INT(_security_mac_lomac, OID_AUTO, ptys_equal, CTLFLAG_RW,
118db2661ceSRobert Watson     &ptys_equal, 0, "Label pty devices as lomac/equal on create");
119db2661ceSRobert Watson TUNABLE_INT("security.mac.lomac.ptys_equal", &ptys_equal);
120db2661ceSRobert Watson 
121db2661ceSRobert Watson static int	revocation_enabled = 1;
122db2661ceSRobert Watson SYSCTL_INT(_security_mac_lomac, OID_AUTO, revocation_enabled, CTLFLAG_RW,
123db2661ceSRobert Watson     &revocation_enabled, 0, "Revoke access to objects on relabel");
124db2661ceSRobert Watson TUNABLE_INT("security.mac.lomac.revocation_enabled", &revocation_enabled);
125db2661ceSRobert Watson 
126db2661ceSRobert Watson static int	mac_lomac_slot;
127db2661ceSRobert Watson #define	SLOT(l)	((struct mac_lomac *)LABEL_TO_SLOT((l), mac_lomac_slot).l_ptr)
128db2661ceSRobert Watson #define	PSLOT(l) ((struct mac_lomac_proc *)				\
129db2661ceSRobert Watson     LABEL_TO_SLOT((l), mac_lomac_slot).l_ptr)
130db2661ceSRobert Watson 
131db2661ceSRobert Watson MALLOC_DEFINE(M_MACLOMAC, "lomac label", "MAC/LOMAC labels");
132db2661ceSRobert Watson 
133db2661ceSRobert Watson static struct mac_lomac *
134db2661ceSRobert Watson lomac_alloc(int flag)
135db2661ceSRobert Watson {
136db2661ceSRobert Watson 	struct mac_lomac *mac_lomac;
137db2661ceSRobert Watson 
138db2661ceSRobert Watson 	mac_lomac = malloc(sizeof(struct mac_lomac), M_MACLOMAC, M_ZERO | flag);
139db2661ceSRobert Watson 
140db2661ceSRobert Watson 	return (mac_lomac);
141db2661ceSRobert Watson }
142db2661ceSRobert Watson 
143db2661ceSRobert Watson static void
144db2661ceSRobert Watson lomac_free(struct mac_lomac *mac_lomac)
145db2661ceSRobert Watson {
146db2661ceSRobert Watson 
147db2661ceSRobert Watson 	if (mac_lomac != NULL)
148db2661ceSRobert Watson 		free(mac_lomac, M_MACLOMAC);
149db2661ceSRobert Watson 	else
150db2661ceSRobert Watson 		atomic_add_int(&destroyed_not_inited, 1);
151db2661ceSRobert Watson }
152db2661ceSRobert Watson 
153db2661ceSRobert Watson static int
154db2661ceSRobert Watson lomac_atmostflags(struct mac_lomac *mac_lomac, int flags)
155db2661ceSRobert Watson {
156db2661ceSRobert Watson 
157db2661ceSRobert Watson 	if ((mac_lomac->ml_flags & flags) != mac_lomac->ml_flags)
158db2661ceSRobert Watson 		return (EINVAL);
159db2661ceSRobert Watson 	return (0);
160db2661ceSRobert Watson }
161db2661ceSRobert Watson 
162db2661ceSRobert Watson static int
163db2661ceSRobert Watson mac_lomac_dominate_element(struct mac_lomac_element *a,
164db2661ceSRobert Watson     struct mac_lomac_element *b)
165db2661ceSRobert Watson {
166db2661ceSRobert Watson 
167db2661ceSRobert Watson 	switch (a->mle_type) {
168db2661ceSRobert Watson 	case MAC_LOMAC_TYPE_EQUAL:
169db2661ceSRobert Watson 	case MAC_LOMAC_TYPE_HIGH:
170db2661ceSRobert Watson 		return (1);
171db2661ceSRobert Watson 
172db2661ceSRobert Watson 	case MAC_LOMAC_TYPE_LOW:
173db2661ceSRobert Watson 		switch (b->mle_type) {
174db2661ceSRobert Watson 		case MAC_LOMAC_TYPE_GRADE:
175db2661ceSRobert Watson 		case MAC_LOMAC_TYPE_HIGH:
176db2661ceSRobert Watson 			return (0);
177db2661ceSRobert Watson 
178db2661ceSRobert Watson 		case MAC_LOMAC_TYPE_EQUAL:
179db2661ceSRobert Watson 		case MAC_LOMAC_TYPE_LOW:
180db2661ceSRobert Watson 			return (1);
181db2661ceSRobert Watson 
182db2661ceSRobert Watson 		default:
183db2661ceSRobert Watson 			panic("mac_lomac_dominate_element: b->mle_type invalid");
184db2661ceSRobert Watson 		}
185db2661ceSRobert Watson 
186db2661ceSRobert Watson 	case MAC_LOMAC_TYPE_GRADE:
187db2661ceSRobert Watson 		switch (b->mle_type) {
188db2661ceSRobert Watson 		case MAC_LOMAC_TYPE_EQUAL:
189db2661ceSRobert Watson 		case MAC_LOMAC_TYPE_LOW:
190db2661ceSRobert Watson 			return (1);
191db2661ceSRobert Watson 
192db2661ceSRobert Watson 		case MAC_LOMAC_TYPE_HIGH:
193db2661ceSRobert Watson 			return (0);
194db2661ceSRobert Watson 
195db2661ceSRobert Watson 		case MAC_LOMAC_TYPE_GRADE:
196db2661ceSRobert Watson 			return (a->mle_grade >= b->mle_grade);
197db2661ceSRobert Watson 
198db2661ceSRobert Watson 		default:
199db2661ceSRobert Watson 			panic("mac_lomac_dominate_element: b->mle_type invalid");
200db2661ceSRobert Watson 		}
201db2661ceSRobert Watson 
202db2661ceSRobert Watson 	default:
203db2661ceSRobert Watson 		panic("mac_lomac_dominate_element: a->mle_type invalid");
204db2661ceSRobert Watson 	}
205db2661ceSRobert Watson }
206db2661ceSRobert Watson 
207db2661ceSRobert Watson static int
208db2661ceSRobert Watson mac_lomac_range_in_range(struct mac_lomac *rangea, struct mac_lomac *rangeb)
209db2661ceSRobert Watson {
210db2661ceSRobert Watson 
211db2661ceSRobert Watson 	return (mac_lomac_dominate_element(&rangeb->ml_rangehigh,
212db2661ceSRobert Watson 	    &rangea->ml_rangehigh) &&
213db2661ceSRobert Watson 	    mac_lomac_dominate_element(&rangea->ml_rangelow,
214db2661ceSRobert Watson 	    &rangeb->ml_rangelow));
215db2661ceSRobert Watson }
216db2661ceSRobert Watson 
217db2661ceSRobert Watson static int
218db2661ceSRobert Watson mac_lomac_single_in_range(struct mac_lomac *single, struct mac_lomac *range)
219db2661ceSRobert Watson {
220db2661ceSRobert Watson 
221db2661ceSRobert Watson 	KASSERT((single->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0,
222db2661ceSRobert Watson 	    ("mac_lomac_single_in_range: a not single"));
223db2661ceSRobert Watson 	KASSERT((range->ml_flags & MAC_LOMAC_FLAG_RANGE) != 0,
224db2661ceSRobert Watson 	    ("mac_lomac_single_in_range: b not range"));
225db2661ceSRobert Watson 
226db2661ceSRobert Watson 	return (mac_lomac_dominate_element(&range->ml_rangehigh,
227db2661ceSRobert Watson 	    &single->ml_single) &&
228db2661ceSRobert Watson 	    mac_lomac_dominate_element(&single->ml_single,
229db2661ceSRobert Watson 	    &range->ml_rangelow));
230db2661ceSRobert Watson }
231db2661ceSRobert Watson 
232db2661ceSRobert Watson static int
233db2661ceSRobert Watson mac_lomac_auxsingle_in_range(struct mac_lomac *single, struct mac_lomac *range)
234db2661ceSRobert Watson {
235db2661ceSRobert Watson 
236db2661ceSRobert Watson 	KASSERT((single->ml_flags & MAC_LOMAC_FLAG_AUX) != 0,
237db2661ceSRobert Watson 	    ("mac_lomac_single_in_range: a not auxsingle"));
238db2661ceSRobert Watson 	KASSERT((range->ml_flags & MAC_LOMAC_FLAG_RANGE) != 0,
239db2661ceSRobert Watson 	    ("mac_lomac_single_in_range: b not range"));
240db2661ceSRobert Watson 
241db2661ceSRobert Watson 	return (mac_lomac_dominate_element(&range->ml_rangehigh,
242db2661ceSRobert Watson 	    &single->ml_auxsingle) &&
243db2661ceSRobert Watson 	    mac_lomac_dominate_element(&single->ml_auxsingle,
244db2661ceSRobert Watson 	    &range->ml_rangelow));
245db2661ceSRobert Watson }
246db2661ceSRobert Watson 
247db2661ceSRobert Watson static int
248db2661ceSRobert Watson mac_lomac_dominate_single(struct mac_lomac *a, struct mac_lomac *b)
249db2661ceSRobert Watson {
250db2661ceSRobert Watson 	KASSERT((a->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0,
251db2661ceSRobert Watson 	    ("mac_lomac_dominate_single: a not single"));
252db2661ceSRobert Watson 	KASSERT((b->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0,
253db2661ceSRobert Watson 	    ("mac_lomac_dominate_single: b not single"));
254db2661ceSRobert Watson 
255db2661ceSRobert Watson 	return (mac_lomac_dominate_element(&a->ml_single, &b->ml_single));
256db2661ceSRobert Watson }
257db2661ceSRobert Watson 
258db2661ceSRobert Watson static int
259db2661ceSRobert Watson mac_lomac_subject_dominate(struct mac_lomac *a, struct mac_lomac *b)
260db2661ceSRobert Watson {
261db2661ceSRobert Watson 	KASSERT((~a->ml_flags &
262db2661ceSRobert Watson 	    (MAC_LOMAC_FLAG_SINGLE | MAC_LOMAC_FLAG_RANGE)) == 0,
263db2661ceSRobert Watson 	    ("mac_lomac_dominate_single: a not subject"));
264db2661ceSRobert Watson 	KASSERT((b->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0,
265db2661ceSRobert Watson 	    ("mac_lomac_dominate_single: b not single"));
266db2661ceSRobert Watson 
267db2661ceSRobert Watson 	return (mac_lomac_dominate_element(&a->ml_rangehigh,
268db2661ceSRobert Watson 	    &b->ml_single));
269db2661ceSRobert Watson }
270db2661ceSRobert Watson 
271db2661ceSRobert Watson static int
272db2661ceSRobert Watson mac_lomac_equal_element(struct mac_lomac_element *a, struct mac_lomac_element *b)
273db2661ceSRobert Watson {
274db2661ceSRobert Watson 
275db2661ceSRobert Watson 	if (a->mle_type == MAC_LOMAC_TYPE_EQUAL ||
276db2661ceSRobert Watson 	    b->mle_type == MAC_LOMAC_TYPE_EQUAL)
277db2661ceSRobert Watson 		return (1);
278db2661ceSRobert Watson 
279db2661ceSRobert Watson 	return (a->mle_type == b->mle_type && a->mle_grade == b->mle_grade);
280db2661ceSRobert Watson }
281db2661ceSRobert Watson 
282db2661ceSRobert Watson static int
283db2661ceSRobert Watson mac_lomac_equal_single(struct mac_lomac *a, struct mac_lomac *b)
284db2661ceSRobert Watson {
285db2661ceSRobert Watson 
286db2661ceSRobert Watson 	KASSERT((a->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0,
287db2661ceSRobert Watson 	    ("mac_lomac_equal_single: a not single"));
288db2661ceSRobert Watson 	KASSERT((b->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0,
289db2661ceSRobert Watson 	    ("mac_lomac_equal_single: b not single"));
290db2661ceSRobert Watson 
291db2661ceSRobert Watson 	return (mac_lomac_equal_element(&a->ml_single, &b->ml_single));
292db2661ceSRobert Watson }
293db2661ceSRobert Watson 
294db2661ceSRobert Watson static int
295db2661ceSRobert Watson mac_lomac_contains_equal(struct mac_lomac *mac_lomac)
296db2661ceSRobert Watson {
297db2661ceSRobert Watson 
298db2661ceSRobert Watson 	if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_SINGLE)
299db2661ceSRobert Watson 		if (mac_lomac->ml_single.mle_type == MAC_LOMAC_TYPE_EQUAL)
300db2661ceSRobert Watson 			return (1);
301db2661ceSRobert Watson 	if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_AUX)
302db2661ceSRobert Watson 		if (mac_lomac->ml_auxsingle.mle_type == MAC_LOMAC_TYPE_EQUAL)
303db2661ceSRobert Watson 			return (1);
304db2661ceSRobert Watson 
305db2661ceSRobert Watson 	if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_RANGE) {
306db2661ceSRobert Watson 		if (mac_lomac->ml_rangelow.mle_type == MAC_LOMAC_TYPE_EQUAL)
307db2661ceSRobert Watson 			return (1);
308db2661ceSRobert Watson 		if (mac_lomac->ml_rangehigh.mle_type == MAC_LOMAC_TYPE_EQUAL)
309db2661ceSRobert Watson 			return (1);
310db2661ceSRobert Watson 	}
311db2661ceSRobert Watson 
312db2661ceSRobert Watson 	return (0);
313db2661ceSRobert Watson }
314db2661ceSRobert Watson 
315db2661ceSRobert Watson static int
316db2661ceSRobert Watson mac_lomac_subject_privileged(struct mac_lomac *mac_lomac)
317db2661ceSRobert Watson {
318db2661ceSRobert Watson 
319db2661ceSRobert Watson 	KASSERT((mac_lomac->ml_flags & MAC_LOMAC_FLAGS_BOTH) ==
320db2661ceSRobert Watson 	    MAC_LOMAC_FLAGS_BOTH,
321db2661ceSRobert Watson 	    ("mac_lomac_subject_privileged: subject doesn't have both labels"));
322db2661ceSRobert Watson 
323db2661ceSRobert Watson 	/* If the single is EQUAL, it's ok. */
324db2661ceSRobert Watson 	if (mac_lomac->ml_single.mle_type == MAC_LOMAC_TYPE_EQUAL)
325db2661ceSRobert Watson 		return (0);
326db2661ceSRobert Watson 
327db2661ceSRobert Watson 	/* If either range endpoint is EQUAL, it's ok. */
328db2661ceSRobert Watson 	if (mac_lomac->ml_rangelow.mle_type == MAC_LOMAC_TYPE_EQUAL ||
329db2661ceSRobert Watson 	    mac_lomac->ml_rangehigh.mle_type == MAC_LOMAC_TYPE_EQUAL)
330db2661ceSRobert Watson 		return (0);
331db2661ceSRobert Watson 
332db2661ceSRobert Watson 	/* If the range is low-high, it's ok. */
333db2661ceSRobert Watson 	if (mac_lomac->ml_rangelow.mle_type == MAC_LOMAC_TYPE_LOW &&
334db2661ceSRobert Watson 	    mac_lomac->ml_rangehigh.mle_type == MAC_LOMAC_TYPE_HIGH)
335db2661ceSRobert Watson 		return (0);
336db2661ceSRobert Watson 
337db2661ceSRobert Watson 	/* It's not ok. */
338db2661ceSRobert Watson 	return (EPERM);
339db2661ceSRobert Watson }
340db2661ceSRobert Watson 
341db2661ceSRobert Watson static int
342db2661ceSRobert Watson mac_lomac_high_single(struct mac_lomac *mac_lomac)
343db2661ceSRobert Watson {
344db2661ceSRobert Watson 
345db2661ceSRobert Watson 	KASSERT((mac_lomac->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0,
346db2661ceSRobert Watson 	    ("mac_lomac_high_single: mac_lomac not single"));
347db2661ceSRobert Watson 
348db2661ceSRobert Watson 	return (mac_lomac->ml_single.mle_type == MAC_LOMAC_TYPE_HIGH);
349db2661ceSRobert Watson }
350db2661ceSRobert Watson 
351db2661ceSRobert Watson static int
352db2661ceSRobert Watson mac_lomac_valid(struct mac_lomac *mac_lomac)
353db2661ceSRobert Watson {
354db2661ceSRobert Watson 
355db2661ceSRobert Watson 	if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_SINGLE) {
356db2661ceSRobert Watson 		switch (mac_lomac->ml_single.mle_type) {
357db2661ceSRobert Watson 		case MAC_LOMAC_TYPE_GRADE:
358db2661ceSRobert Watson 		case MAC_LOMAC_TYPE_EQUAL:
359db2661ceSRobert Watson 		case MAC_LOMAC_TYPE_HIGH:
360db2661ceSRobert Watson 		case MAC_LOMAC_TYPE_LOW:
361db2661ceSRobert Watson 			break;
362db2661ceSRobert Watson 
363db2661ceSRobert Watson 		default:
364db2661ceSRobert Watson 			return (EINVAL);
365db2661ceSRobert Watson 		}
366db2661ceSRobert Watson 	} else {
367db2661ceSRobert Watson 		if (mac_lomac->ml_single.mle_type != MAC_LOMAC_TYPE_UNDEF)
368db2661ceSRobert Watson 			return (EINVAL);
369db2661ceSRobert Watson 	}
370db2661ceSRobert Watson 
371db2661ceSRobert Watson 	if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_AUX) {
372db2661ceSRobert Watson 		switch (mac_lomac->ml_auxsingle.mle_type) {
373db2661ceSRobert Watson 		case MAC_LOMAC_TYPE_GRADE:
374db2661ceSRobert Watson 		case MAC_LOMAC_TYPE_EQUAL:
375db2661ceSRobert Watson 		case MAC_LOMAC_TYPE_HIGH:
376db2661ceSRobert Watson 		case MAC_LOMAC_TYPE_LOW:
377db2661ceSRobert Watson 			break;
378db2661ceSRobert Watson 
379db2661ceSRobert Watson 		default:
380db2661ceSRobert Watson 			return (EINVAL);
381db2661ceSRobert Watson 		}
382db2661ceSRobert Watson 	} else {
383db2661ceSRobert Watson 		if (mac_lomac->ml_auxsingle.mle_type != MAC_LOMAC_TYPE_UNDEF)
384db2661ceSRobert Watson 			return (EINVAL);
385db2661ceSRobert Watson 	}
386db2661ceSRobert Watson 
387db2661ceSRobert Watson 	if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_RANGE) {
388db2661ceSRobert Watson 		switch (mac_lomac->ml_rangelow.mle_type) {
389db2661ceSRobert Watson 		case MAC_LOMAC_TYPE_GRADE:
390db2661ceSRobert Watson 		case MAC_LOMAC_TYPE_EQUAL:
391db2661ceSRobert Watson 		case MAC_LOMAC_TYPE_HIGH:
392db2661ceSRobert Watson 		case MAC_LOMAC_TYPE_LOW:
393db2661ceSRobert Watson 			break;
394db2661ceSRobert Watson 
395db2661ceSRobert Watson 		default:
396db2661ceSRobert Watson 			return (EINVAL);
397db2661ceSRobert Watson 		}
398db2661ceSRobert Watson 
399db2661ceSRobert Watson 		switch (mac_lomac->ml_rangehigh.mle_type) {
400db2661ceSRobert Watson 		case MAC_LOMAC_TYPE_GRADE:
401db2661ceSRobert Watson 		case MAC_LOMAC_TYPE_EQUAL:
402db2661ceSRobert Watson 		case MAC_LOMAC_TYPE_HIGH:
403db2661ceSRobert Watson 		case MAC_LOMAC_TYPE_LOW:
404db2661ceSRobert Watson 			break;
405db2661ceSRobert Watson 
406db2661ceSRobert Watson 		default:
407db2661ceSRobert Watson 			return (EINVAL);
408db2661ceSRobert Watson 		}
409db2661ceSRobert Watson 		if (!mac_lomac_dominate_element(&mac_lomac->ml_rangehigh,
410db2661ceSRobert Watson 		    &mac_lomac->ml_rangelow))
411db2661ceSRobert Watson 			return (EINVAL);
412db2661ceSRobert Watson 	} else {
413db2661ceSRobert Watson 		if (mac_lomac->ml_rangelow.mle_type != MAC_LOMAC_TYPE_UNDEF ||
414db2661ceSRobert Watson 		    mac_lomac->ml_rangehigh.mle_type != MAC_LOMAC_TYPE_UNDEF)
415db2661ceSRobert Watson 			return (EINVAL);
416db2661ceSRobert Watson 	}
417db2661ceSRobert Watson 
418db2661ceSRobert Watson 	return (0);
419db2661ceSRobert Watson }
420db2661ceSRobert Watson 
421db2661ceSRobert Watson static void
422db2661ceSRobert Watson mac_lomac_set_range(struct mac_lomac *mac_lomac, u_short typelow,
423db2661ceSRobert Watson     u_short gradelow, u_short typehigh, u_short gradehigh)
424db2661ceSRobert Watson {
425db2661ceSRobert Watson 
426db2661ceSRobert Watson 	mac_lomac->ml_rangelow.mle_type = typelow;
427db2661ceSRobert Watson 	mac_lomac->ml_rangelow.mle_grade = gradelow;
428db2661ceSRobert Watson 	mac_lomac->ml_rangehigh.mle_type = typehigh;
429db2661ceSRobert Watson 	mac_lomac->ml_rangehigh.mle_grade = gradehigh;
430db2661ceSRobert Watson 	mac_lomac->ml_flags |= MAC_LOMAC_FLAG_RANGE;
431db2661ceSRobert Watson }
432db2661ceSRobert Watson 
433db2661ceSRobert Watson static void
434db2661ceSRobert Watson mac_lomac_set_single(struct mac_lomac *mac_lomac, u_short type, u_short grade)
435db2661ceSRobert Watson {
436db2661ceSRobert Watson 
437db2661ceSRobert Watson 	mac_lomac->ml_single.mle_type = type;
438db2661ceSRobert Watson 	mac_lomac->ml_single.mle_grade = grade;
439db2661ceSRobert Watson 	mac_lomac->ml_flags |= MAC_LOMAC_FLAG_SINGLE;
440db2661ceSRobert Watson }
441db2661ceSRobert Watson 
442db2661ceSRobert Watson static void
443db2661ceSRobert Watson mac_lomac_copy_range(struct mac_lomac *labelfrom, struct mac_lomac *labelto)
444db2661ceSRobert Watson {
445db2661ceSRobert Watson 
446db2661ceSRobert Watson 	KASSERT((labelfrom->ml_flags & MAC_LOMAC_FLAG_RANGE) != 0,
447db2661ceSRobert Watson 	    ("mac_lomac_copy_range: labelfrom not range"));
448db2661ceSRobert Watson 
449db2661ceSRobert Watson 	labelto->ml_rangelow = labelfrom->ml_rangelow;
450db2661ceSRobert Watson 	labelto->ml_rangehigh = labelfrom->ml_rangehigh;
451db2661ceSRobert Watson 	labelto->ml_flags |= MAC_LOMAC_FLAG_RANGE;
452db2661ceSRobert Watson }
453db2661ceSRobert Watson 
454db2661ceSRobert Watson static void
455db2661ceSRobert Watson mac_lomac_copy_single(struct mac_lomac *labelfrom, struct mac_lomac *labelto)
456db2661ceSRobert Watson {
457db2661ceSRobert Watson 
458db2661ceSRobert Watson 	KASSERT((labelfrom->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0,
459db2661ceSRobert Watson 	    ("mac_lomac_copy_single: labelfrom not single"));
460db2661ceSRobert Watson 
461db2661ceSRobert Watson 	labelto->ml_single = labelfrom->ml_single;
462db2661ceSRobert Watson 	labelto->ml_flags |= MAC_LOMAC_FLAG_SINGLE;
463db2661ceSRobert Watson }
464db2661ceSRobert Watson 
465db2661ceSRobert Watson static void
466db2661ceSRobert Watson mac_lomac_copy_auxsingle(struct mac_lomac *labelfrom, struct mac_lomac *labelto)
467db2661ceSRobert Watson {
468db2661ceSRobert Watson 
469db2661ceSRobert Watson 	KASSERT((labelfrom->ml_flags & MAC_LOMAC_FLAG_AUX) != 0,
470db2661ceSRobert Watson 	    ("mac_lomac_copy_auxsingle: labelfrom not auxsingle"));
471db2661ceSRobert Watson 
472db2661ceSRobert Watson 	labelto->ml_auxsingle = labelfrom->ml_auxsingle;
473db2661ceSRobert Watson 	labelto->ml_flags |= MAC_LOMAC_FLAG_AUX;
474db2661ceSRobert Watson }
475db2661ceSRobert Watson 
476db2661ceSRobert Watson static void
477db2661ceSRobert Watson mac_lomac_copy(struct mac_lomac *source, struct mac_lomac *dest)
478db2661ceSRobert Watson {
479db2661ceSRobert Watson 
480db2661ceSRobert Watson 	if (source->ml_flags & MAC_LOMAC_FLAG_SINGLE)
481db2661ceSRobert Watson 		mac_lomac_copy_single(source, dest);
482db2661ceSRobert Watson 	if (source->ml_flags & MAC_LOMAC_FLAG_AUX)
483db2661ceSRobert Watson 		mac_lomac_copy_auxsingle(source, dest);
484db2661ceSRobert Watson 	if (source->ml_flags & MAC_LOMAC_FLAG_RANGE)
485db2661ceSRobert Watson 		mac_lomac_copy_range(source, dest);
486db2661ceSRobert Watson }
487db2661ceSRobert Watson 
488f51e5803SRobert Watson static int	mac_lomac_to_string(struct sbuf *sb,
489f51e5803SRobert Watson 		    struct mac_lomac *mac_lomac);
490db2661ceSRobert Watson 
491db2661ceSRobert Watson static int
492db2661ceSRobert Watson maybe_demote(struct mac_lomac *subjlabel, struct mac_lomac *objlabel,
493db2661ceSRobert Watson     const char *actionname, const char *objname, struct vnode *vpq)
494db2661ceSRobert Watson {
495f51e5803SRobert Watson 	struct sbuf subjlabel_sb, subjtext_sb, objlabel_sb;
496f51e5803SRobert Watson 	char *subjlabeltext, *objlabeltext, *subjtext;
497f51e5803SRobert Watson 	struct mac_lomac cached_subjlabel;
498f51e5803SRobert Watson 	struct mac_lomac_proc *subj;
499db2661ceSRobert Watson 	struct vattr va;
500db2661ceSRobert Watson 	struct proc *p;
501db2661ceSRobert Watson 	pid_t pgid;
502db2661ceSRobert Watson 
503eca8a663SRobert Watson 	subj = PSLOT(curthread->td_proc->p_label);
504f51e5803SRobert Watson 
505db2661ceSRobert Watson 	p = curthread->td_proc;
506db2661ceSRobert Watson 	mtx_lock(&subj->mtx);
507db2661ceSRobert Watson         if (subj->mac_lomac.ml_flags & MAC_LOMAC_FLAG_UPDATE) {
508db2661ceSRobert Watson 		/*
509db2661ceSRobert Watson 		 * Check to see if the pending demotion would be more or
510db2661ceSRobert Watson 		 * less severe than this one, and keep the more severe.
511db2661ceSRobert Watson 		 * This can only happen for a multi-threaded application.
512db2661ceSRobert Watson 		 */
513db2661ceSRobert Watson 		if (mac_lomac_dominate_single(objlabel, &subj->mac_lomac)) {
514db2661ceSRobert Watson 			mtx_unlock(&subj->mtx);
515db2661ceSRobert Watson 			return (0);
516db2661ceSRobert Watson 		}
517db2661ceSRobert Watson 	}
518db2661ceSRobert Watson 	bzero(&subj->mac_lomac, sizeof(subj->mac_lomac));
519db2661ceSRobert Watson 	/*
520db2661ceSRobert Watson 	 * Always demote the single label.
521db2661ceSRobert Watson 	 */
522db2661ceSRobert Watson 	mac_lomac_copy_single(objlabel, &subj->mac_lomac);
523db2661ceSRobert Watson 	/*
524db2661ceSRobert Watson 	 * Start with the original range, then minimize each side of
525db2661ceSRobert Watson 	 * the range to the point of not dominating the object.  The
526db2661ceSRobert Watson 	 * high side will always be demoted, of course.
527db2661ceSRobert Watson 	 */
528db2661ceSRobert Watson 	mac_lomac_copy_range(subjlabel, &subj->mac_lomac);
529db2661ceSRobert Watson 	if (!mac_lomac_dominate_element(&objlabel->ml_single,
530db2661ceSRobert Watson 	    &subj->mac_lomac.ml_rangelow))
531db2661ceSRobert Watson 		subj->mac_lomac.ml_rangelow = objlabel->ml_single;
532db2661ceSRobert Watson 	subj->mac_lomac.ml_rangehigh = objlabel->ml_single;
533db2661ceSRobert Watson 	subj->mac_lomac.ml_flags |= MAC_LOMAC_FLAG_UPDATE;
534db2661ceSRobert Watson 	mtx_lock_spin(&sched_lock);
5354a338afdSJulian Elischer 	curthread->td_flags |= TDF_ASTPENDING;
536db2661ceSRobert Watson 	curthread->td_proc->p_sflag |= PS_MACPEND;
537db2661ceSRobert Watson 	mtx_unlock_spin(&sched_lock);
538f51e5803SRobert Watson 
539f51e5803SRobert Watson 	/*
540f51e5803SRobert Watson 	 * Avoid memory allocation while holding a mutex; cache the
541f51e5803SRobert Watson 	 * label.
542f51e5803SRobert Watson 	 */
543f51e5803SRobert Watson 	mac_lomac_copy_single(&subj->mac_lomac, &cached_subjlabel);
544db2661ceSRobert Watson 	mtx_unlock(&subj->mtx);
545f51e5803SRobert Watson 
546f51e5803SRobert Watson 	sbuf_new(&subjlabel_sb, NULL, 0, SBUF_AUTOEXTEND);
547f51e5803SRobert Watson 	mac_lomac_to_string(&subjlabel_sb, subjlabel);
548f51e5803SRobert Watson 	sbuf_finish(&subjlabel_sb);
549f51e5803SRobert Watson 	subjlabeltext = sbuf_data(&subjlabel_sb);
550f51e5803SRobert Watson 
551f51e5803SRobert Watson 	sbuf_new(&subjtext_sb, NULL, 0, SBUF_AUTOEXTEND);
552f51e5803SRobert Watson 	mac_lomac_to_string(&subjtext_sb, &subj->mac_lomac);
553f51e5803SRobert Watson 	sbuf_finish(&subjtext_sb);
554f51e5803SRobert Watson 	subjtext = sbuf_data(&subjtext_sb);
555f51e5803SRobert Watson 
556f51e5803SRobert Watson 	sbuf_new(&objlabel_sb, NULL, 0, SBUF_AUTOEXTEND);
557f51e5803SRobert Watson 	mac_lomac_to_string(&objlabel_sb, objlabel);
558f51e5803SRobert Watson 	sbuf_finish(&objlabel_sb);
559f51e5803SRobert Watson 	objlabeltext = sbuf_data(&objlabel_sb);
560f51e5803SRobert Watson 
561db2661ceSRobert Watson 	pgid = p->p_pgrp->pg_id;		/* XXX could be stale? */
562db2661ceSRobert Watson 	if (vpq != NULL && VOP_GETATTR(vpq, &va, curthread->td_ucred,
563db2661ceSRobert Watson 	    curthread) == 0) {
564db2661ceSRobert Watson 		log(LOG_INFO, "LOMAC: level-%s subject p%dg%du%d:%s demoted to"
565db2661ceSRobert Watson 		    " level %s after %s a level-%s %s (inode=%ld, "
566db2661ceSRobert Watson 		    "mountpount=%s)\n",
567db2661ceSRobert Watson 		    subjlabeltext, p->p_pid, pgid, curthread->td_ucred->cr_uid,
568db2661ceSRobert Watson 		    p->p_comm, subjtext, actionname, objlabeltext, objname,
569db2661ceSRobert Watson 		    va.va_fileid, vpq->v_mount->mnt_stat.f_mntonname);
570db2661ceSRobert Watson 	} else {
571db2661ceSRobert Watson 		log(LOG_INFO, "LOMAC: level-%s subject p%dg%du%d:%s demoted to"
572db2661ceSRobert Watson 		    " level %s after %s a level-%s %s\n",
573db2661ceSRobert Watson 		    subjlabeltext, p->p_pid, pgid, curthread->td_ucred->cr_uid,
574db2661ceSRobert Watson 		    p->p_comm, subjtext, actionname, objlabeltext, objname);
575db2661ceSRobert Watson 	}
576db2661ceSRobert Watson 
577f51e5803SRobert Watson 	sbuf_delete(&subjlabel_sb);
578f51e5803SRobert Watson 	sbuf_delete(&subjtext_sb);
579f51e5803SRobert Watson 	sbuf_delete(&objlabel_sb);
580f51e5803SRobert Watson 
581db2661ceSRobert Watson 	return (0);
582db2661ceSRobert Watson }
583db2661ceSRobert Watson 
584db2661ceSRobert Watson /*
585db2661ceSRobert Watson  * Relabel "to" to "from" only if "from" is a valid label (contains
586db2661ceSRobert Watson  * at least a single), as for a relabel operation which may or may
587db2661ceSRobert Watson  * not involve a relevant label.
588db2661ceSRobert Watson  */
5897496ed81SRobert Watson static void
590db2661ceSRobert Watson try_relabel(struct mac_lomac *from, struct mac_lomac *to)
591db2661ceSRobert Watson {
592db2661ceSRobert Watson 
593db2661ceSRobert Watson 	if (from->ml_flags & MAC_LOMAC_FLAG_SINGLE) {
594db2661ceSRobert Watson 		bzero(to, sizeof(*to));
595db2661ceSRobert Watson 		mac_lomac_copy(from, to);
596db2661ceSRobert Watson 	}
597db2661ceSRobert Watson }
598db2661ceSRobert Watson 
599db2661ceSRobert Watson /*
600db2661ceSRobert Watson  * Policy module operations.
601db2661ceSRobert Watson  */
602db2661ceSRobert Watson static void
603db2661ceSRobert Watson mac_lomac_init(struct mac_policy_conf *conf)
604db2661ceSRobert Watson {
605db2661ceSRobert Watson 
606db2661ceSRobert Watson }
607db2661ceSRobert Watson 
608db2661ceSRobert Watson /*
609db2661ceSRobert Watson  * Label operations.
610db2661ceSRobert Watson  */
611db2661ceSRobert Watson static void
612db2661ceSRobert Watson mac_lomac_init_label(struct label *label)
613db2661ceSRobert Watson {
614db2661ceSRobert Watson 
615a163d034SWarner Losh 	SLOT(label) = lomac_alloc(M_WAITOK);
616db2661ceSRobert Watson }
617db2661ceSRobert Watson 
618db2661ceSRobert Watson static int
619db2661ceSRobert Watson mac_lomac_init_label_waitcheck(struct label *label, int flag)
620db2661ceSRobert Watson {
621db2661ceSRobert Watson 
622db2661ceSRobert Watson 	SLOT(label) = lomac_alloc(flag);
623db2661ceSRobert Watson 	if (SLOT(label) == NULL)
624db2661ceSRobert Watson 		return (ENOMEM);
625db2661ceSRobert Watson 
626db2661ceSRobert Watson 	return (0);
627db2661ceSRobert Watson }
628db2661ceSRobert Watson 
629db2661ceSRobert Watson static void
630db2661ceSRobert Watson mac_lomac_init_proc_label(struct label *label)
631db2661ceSRobert Watson {
632db2661ceSRobert Watson 
633db2661ceSRobert Watson 	PSLOT(label) = malloc(sizeof(struct mac_lomac_proc), M_MACLOMAC,
634a163d034SWarner Losh 	    M_ZERO | M_WAITOK);
635db2661ceSRobert Watson 	mtx_init(&PSLOT(label)->mtx, "MAC/Lomac proc lock", NULL, MTX_DEF);
636db2661ceSRobert Watson }
637db2661ceSRobert Watson 
638db2661ceSRobert Watson static void
639db2661ceSRobert Watson mac_lomac_destroy_label(struct label *label)
640db2661ceSRobert Watson {
641db2661ceSRobert Watson 
642db2661ceSRobert Watson 	lomac_free(SLOT(label));
643db2661ceSRobert Watson 	SLOT(label) = NULL;
644db2661ceSRobert Watson }
645db2661ceSRobert Watson 
646db2661ceSRobert Watson static void
647db2661ceSRobert Watson mac_lomac_destroy_proc_label(struct label *label)
648db2661ceSRobert Watson {
649db2661ceSRobert Watson 
650db2661ceSRobert Watson 	mtx_destroy(&PSLOT(label)->mtx);
651db2661ceSRobert Watson 	FREE(PSLOT(label), M_MACLOMAC);
652db2661ceSRobert Watson 	PSLOT(label) = NULL;
653db2661ceSRobert Watson }
654db2661ceSRobert Watson 
655f51e5803SRobert Watson static int
656f51e5803SRobert Watson mac_lomac_element_to_string(struct sbuf *sb, struct mac_lomac_element *element)
657db2661ceSRobert Watson {
658db2661ceSRobert Watson 
659db2661ceSRobert Watson 	switch (element->mle_type) {
660db2661ceSRobert Watson 	case MAC_LOMAC_TYPE_HIGH:
661f51e5803SRobert Watson 		return (sbuf_printf(sb, "high"));
662db2661ceSRobert Watson 
663db2661ceSRobert Watson 	case MAC_LOMAC_TYPE_LOW:
664f51e5803SRobert Watson 		return (sbuf_printf(sb, "low"));
665db2661ceSRobert Watson 
666db2661ceSRobert Watson 	case MAC_LOMAC_TYPE_EQUAL:
667f51e5803SRobert Watson 		return (sbuf_printf(sb, "equal"));
668db2661ceSRobert Watson 
669db2661ceSRobert Watson 	case MAC_LOMAC_TYPE_GRADE:
670f51e5803SRobert Watson 		return (sbuf_printf(sb, "%d", element->mle_grade));
671db2661ceSRobert Watson 
672db2661ceSRobert Watson 	default:
673db2661ceSRobert Watson 		panic("mac_lomac_element_to_string: invalid type (%d)",
674db2661ceSRobert Watson 		    element->mle_type);
675db2661ceSRobert Watson 	}
676db2661ceSRobert Watson }
677db2661ceSRobert Watson 
678db2661ceSRobert Watson static int
679f51e5803SRobert Watson mac_lomac_to_string(struct sbuf *sb, struct mac_lomac *mac_lomac)
680db2661ceSRobert Watson {
681db2661ceSRobert Watson 
682db2661ceSRobert Watson 	if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_SINGLE) {
683f51e5803SRobert Watson 		if (mac_lomac_element_to_string(sb, &mac_lomac->ml_single)
684f51e5803SRobert Watson 		    == -1)
685f51e5803SRobert Watson 			return (EINVAL);
686db2661ceSRobert Watson 	}
687db2661ceSRobert Watson 
688db2661ceSRobert Watson 	if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_AUX) {
689f51e5803SRobert Watson 		if (sbuf_putc(sb, '[') == -1)
690f51e5803SRobert Watson 			return (EINVAL);
691db2661ceSRobert Watson 
692f51e5803SRobert Watson 		if (mac_lomac_element_to_string(sb, &mac_lomac->ml_auxsingle)
693f51e5803SRobert Watson 		    == -1)
694f51e5803SRobert Watson 			return (EINVAL);
695db2661ceSRobert Watson 
696f51e5803SRobert Watson 		if (sbuf_putc(sb, ']') == -1)
697f51e5803SRobert Watson 			return (EINVAL);
698db2661ceSRobert Watson 	}
699db2661ceSRobert Watson 
700db2661ceSRobert Watson 	if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_RANGE) {
701f51e5803SRobert Watson 		if (sbuf_putc(sb, '(') == -1)
702f51e5803SRobert Watson 			return (EINVAL);
703db2661ceSRobert Watson 
704f51e5803SRobert Watson 		if (mac_lomac_element_to_string(sb, &mac_lomac->ml_rangelow)
705f51e5803SRobert Watson 		    == -1)
706f51e5803SRobert Watson 			return (EINVAL);
707db2661ceSRobert Watson 
708f51e5803SRobert Watson 		if (sbuf_putc(sb, '-') == -1)
709f51e5803SRobert Watson 			return (EINVAL);
710db2661ceSRobert Watson 
711f51e5803SRobert Watson 		if (mac_lomac_element_to_string(sb, &mac_lomac->ml_rangehigh)
712f51e5803SRobert Watson 		    == -1)
713f51e5803SRobert Watson 			return (EINVAL);
714db2661ceSRobert Watson 
7158a4b86b9SRobert Watson 		if (sbuf_putc(sb, ')') == -1)
716f51e5803SRobert Watson 			return (EINVAL);
717db2661ceSRobert Watson 	}
718db2661ceSRobert Watson 
719db2661ceSRobert Watson 	return (0);
720db2661ceSRobert Watson }
721db2661ceSRobert Watson 
722db2661ceSRobert Watson static int
723db2661ceSRobert Watson mac_lomac_externalize_label(struct label *label, char *element_name,
724f51e5803SRobert Watson     struct sbuf *sb, int *claimed)
725db2661ceSRobert Watson {
726db2661ceSRobert Watson 	struct mac_lomac *mac_lomac;
727db2661ceSRobert Watson 
728db2661ceSRobert Watson 	if (strcmp(MAC_LOMAC_LABEL_NAME, element_name) != 0)
729db2661ceSRobert Watson 		return (0);
730db2661ceSRobert Watson 
731db2661ceSRobert Watson 	(*claimed)++;
732db2661ceSRobert Watson 
733db2661ceSRobert Watson 	mac_lomac = SLOT(label);
734db2661ceSRobert Watson 
735f51e5803SRobert Watson 	return (mac_lomac_to_string(sb, mac_lomac));
736db2661ceSRobert Watson }
737db2661ceSRobert Watson 
738db2661ceSRobert Watson static int
739db2661ceSRobert Watson mac_lomac_parse_element(struct mac_lomac_element *element, char *string)
740db2661ceSRobert Watson {
741db2661ceSRobert Watson 
742db2661ceSRobert Watson 	if (strcmp(string, "high") == 0 ||
743db2661ceSRobert Watson 	    strcmp(string, "hi") == 0) {
744db2661ceSRobert Watson 		element->mle_type = MAC_LOMAC_TYPE_HIGH;
745db2661ceSRobert Watson 		element->mle_grade = MAC_LOMAC_TYPE_UNDEF;
746db2661ceSRobert Watson 	} else if (strcmp(string, "low") == 0 ||
747db2661ceSRobert Watson 	    strcmp(string, "lo") == 0) {
748db2661ceSRobert Watson 		element->mle_type = MAC_LOMAC_TYPE_LOW;
749db2661ceSRobert Watson 		element->mle_grade = MAC_LOMAC_TYPE_UNDEF;
750db2661ceSRobert Watson 	} else if (strcmp(string, "equal") == 0 ||
751db2661ceSRobert Watson 	    strcmp(string, "eq") == 0) {
752db2661ceSRobert Watson 		element->mle_type = MAC_LOMAC_TYPE_EQUAL;
753db2661ceSRobert Watson 		element->mle_grade = MAC_LOMAC_TYPE_UNDEF;
754db2661ceSRobert Watson 	} else {
755db2661ceSRobert Watson 		char *p0, *p1;
756db2661ceSRobert Watson 		int d;
757db2661ceSRobert Watson 
758db2661ceSRobert Watson 		p0 = string;
759db2661ceSRobert Watson 		d = strtol(p0, &p1, 10);
760db2661ceSRobert Watson 
761db2661ceSRobert Watson 		if (d < 0 || d > 65535)
762db2661ceSRobert Watson 			return (EINVAL);
763db2661ceSRobert Watson 		element->mle_type = MAC_LOMAC_TYPE_GRADE;
764db2661ceSRobert Watson 		element->mle_grade = d;
765db2661ceSRobert Watson 
766db2661ceSRobert Watson 		if (p1 == p0 || *p1 != '\0')
767db2661ceSRobert Watson 			return (EINVAL);
768db2661ceSRobert Watson 	}
769db2661ceSRobert Watson 
770db2661ceSRobert Watson 	return (0);
771db2661ceSRobert Watson }
772db2661ceSRobert Watson 
773db2661ceSRobert Watson /*
774db2661ceSRobert Watson  * Note: destructively consumes the string, make a local copy before
775db2661ceSRobert Watson  * calling if that's a problem.
776db2661ceSRobert Watson  */
777db2661ceSRobert Watson static int
778db2661ceSRobert Watson mac_lomac_parse(struct mac_lomac *mac_lomac, char *string)
779db2661ceSRobert Watson {
780db2661ceSRobert Watson 	char *range, *rangeend, *rangehigh, *rangelow, *single, *auxsingle,
781db2661ceSRobert Watson 	    *auxsingleend;
782db2661ceSRobert Watson 	int error;
783db2661ceSRobert Watson 
784db2661ceSRobert Watson 	/* Do we have a range? */
785db2661ceSRobert Watson 	single = string;
786db2661ceSRobert Watson 	range = index(string, '(');
787db2661ceSRobert Watson 	if (range == single)
788db2661ceSRobert Watson 		single = NULL;
789db2661ceSRobert Watson 	auxsingle = index(string, '[');
790db2661ceSRobert Watson 	if (auxsingle == single)
791db2661ceSRobert Watson 		single = NULL;
792db2661ceSRobert Watson 	if (range != NULL && auxsingle != NULL)
793db2661ceSRobert Watson 		return (EINVAL);
794db2661ceSRobert Watson 	rangelow = rangehigh = NULL;
795db2661ceSRobert Watson 	if (range != NULL) {
796db2661ceSRobert Watson 		/* Nul terminate the end of the single string. */
797db2661ceSRobert Watson 		*range = '\0';
798db2661ceSRobert Watson 		range++;
799db2661ceSRobert Watson 		rangelow = range;
800db2661ceSRobert Watson 		rangehigh = index(rangelow, '-');
801db2661ceSRobert Watson 		if (rangehigh == NULL)
802db2661ceSRobert Watson 			return (EINVAL);
803db2661ceSRobert Watson 		rangehigh++;
804db2661ceSRobert Watson 		if (*rangelow == '\0' || *rangehigh == '\0')
805db2661ceSRobert Watson 			return (EINVAL);
806db2661ceSRobert Watson 		rangeend = index(rangehigh, ')');
807db2661ceSRobert Watson 		if (rangeend == NULL)
808db2661ceSRobert Watson 			return (EINVAL);
809db2661ceSRobert Watson 		if (*(rangeend + 1) != '\0')
810db2661ceSRobert Watson 			return (EINVAL);
811db2661ceSRobert Watson 		/* Nul terminate the ends of the ranges. */
812db2661ceSRobert Watson 		*(rangehigh - 1) = '\0';
813db2661ceSRobert Watson 		*rangeend = '\0';
814db2661ceSRobert Watson 	}
815db2661ceSRobert Watson 	KASSERT((rangelow != NULL && rangehigh != NULL) ||
816db2661ceSRobert Watson 	    (rangelow == NULL && rangehigh == NULL),
817db2661ceSRobert Watson 	    ("mac_lomac_internalize_label: range mismatch"));
818db2661ceSRobert Watson 	if (auxsingle != NULL) {
819db2661ceSRobert Watson 		/* Nul terminate the end of the single string. */
820db2661ceSRobert Watson 		*auxsingle = '\0';
821db2661ceSRobert Watson 		auxsingle++;
822db2661ceSRobert Watson 		auxsingleend = index(auxsingle, ']');
823db2661ceSRobert Watson 		if (auxsingleend == NULL)
824db2661ceSRobert Watson 			return (EINVAL);
825db2661ceSRobert Watson 		if (*(auxsingleend + 1) != '\0')
826db2661ceSRobert Watson 			return (EINVAL);
827db2661ceSRobert Watson 		/* Nul terminate the end of the auxsingle. */
828db2661ceSRobert Watson 		*auxsingleend = '\0';
829db2661ceSRobert Watson 	}
830db2661ceSRobert Watson 
831db2661ceSRobert Watson 	bzero(mac_lomac, sizeof(*mac_lomac));
832db2661ceSRobert Watson 	if (single != NULL) {
833db2661ceSRobert Watson 		error = mac_lomac_parse_element(&mac_lomac->ml_single, single);
834db2661ceSRobert Watson 		if (error)
835db2661ceSRobert Watson 			return (error);
836db2661ceSRobert Watson 		mac_lomac->ml_flags |= MAC_LOMAC_FLAG_SINGLE;
837db2661ceSRobert Watson 	}
838db2661ceSRobert Watson 
839db2661ceSRobert Watson 	if (auxsingle != NULL) {
840db2661ceSRobert Watson 		error = mac_lomac_parse_element(&mac_lomac->ml_auxsingle,
841db2661ceSRobert Watson 		    auxsingle);
842db2661ceSRobert Watson 		if (error)
843db2661ceSRobert Watson 			return (error);
844db2661ceSRobert Watson 		mac_lomac->ml_flags |= MAC_LOMAC_FLAG_AUX;
845db2661ceSRobert Watson 	}
846db2661ceSRobert Watson 
847db2661ceSRobert Watson 	if (rangelow != NULL) {
848db2661ceSRobert Watson 		error = mac_lomac_parse_element(&mac_lomac->ml_rangelow,
849db2661ceSRobert Watson 		    rangelow);
850db2661ceSRobert Watson 		if (error)
851db2661ceSRobert Watson 			return (error);
852db2661ceSRobert Watson 		error = mac_lomac_parse_element(&mac_lomac->ml_rangehigh,
853db2661ceSRobert Watson 		    rangehigh);
854db2661ceSRobert Watson 		if (error)
855db2661ceSRobert Watson 			return (error);
856db2661ceSRobert Watson 		mac_lomac->ml_flags |= MAC_LOMAC_FLAG_RANGE;
857db2661ceSRobert Watson 	}
858db2661ceSRobert Watson 
859db2661ceSRobert Watson 	error = mac_lomac_valid(mac_lomac);
860db2661ceSRobert Watson 	if (error)
861db2661ceSRobert Watson 		return (error);
862db2661ceSRobert Watson 
863db2661ceSRobert Watson 	return (0);
864db2661ceSRobert Watson }
865db2661ceSRobert Watson 
866db2661ceSRobert Watson static int
867db2661ceSRobert Watson mac_lomac_internalize_label(struct label *label, char *element_name,
868db2661ceSRobert Watson     char *element_data, int *claimed)
869db2661ceSRobert Watson {
870db2661ceSRobert Watson 	struct mac_lomac *mac_lomac, mac_lomac_temp;
871db2661ceSRobert Watson 	int error;
872db2661ceSRobert Watson 
873db2661ceSRobert Watson 	if (strcmp(MAC_LOMAC_LABEL_NAME, element_name) != 0)
874db2661ceSRobert Watson 		return (0);
875db2661ceSRobert Watson 
876db2661ceSRobert Watson 	(*claimed)++;
877db2661ceSRobert Watson 
878db2661ceSRobert Watson 	error = mac_lomac_parse(&mac_lomac_temp, element_data);
879db2661ceSRobert Watson 	if (error)
880db2661ceSRobert Watson 		return (error);
881db2661ceSRobert Watson 
882db2661ceSRobert Watson 	mac_lomac = SLOT(label);
883db2661ceSRobert Watson 	*mac_lomac = mac_lomac_temp;
884db2661ceSRobert Watson 
885db2661ceSRobert Watson 	return (0);
886db2661ceSRobert Watson }
887db2661ceSRobert Watson 
888db2661ceSRobert Watson static void
889db2661ceSRobert Watson mac_lomac_copy_label(struct label *src, struct label *dest)
890db2661ceSRobert Watson {
891db2661ceSRobert Watson 
892db2661ceSRobert Watson 	*SLOT(dest) = *SLOT(src);
893db2661ceSRobert Watson }
894db2661ceSRobert Watson 
895db2661ceSRobert Watson /*
896db2661ceSRobert Watson  * Labeling event operations: file system objects, and things that look
897db2661ceSRobert Watson  * a lot like file system objects.
898db2661ceSRobert Watson  */
899db2661ceSRobert Watson static void
900990b4b2dSRobert Watson mac_lomac_create_devfs_device(struct mount *mp, dev_t dev,
901990b4b2dSRobert Watson     struct devfs_dirent *devfs_dirent, struct label *label)
902db2661ceSRobert Watson {
903db2661ceSRobert Watson 	struct mac_lomac *mac_lomac;
904db2661ceSRobert Watson 	int lomac_type;
905db2661ceSRobert Watson 
906db2661ceSRobert Watson 	mac_lomac = SLOT(label);
907db2661ceSRobert Watson 	if (strcmp(dev->si_name, "null") == 0 ||
908db2661ceSRobert Watson 	    strcmp(dev->si_name, "zero") == 0 ||
909db2661ceSRobert Watson 	    strcmp(dev->si_name, "random") == 0 ||
910db2661ceSRobert Watson 	    strncmp(dev->si_name, "fd/", strlen("fd/")) == 0 ||
911db2661ceSRobert Watson 	    strncmp(dev->si_name, "ttyv", strlen("ttyv")) == 0)
912db2661ceSRobert Watson 		lomac_type = MAC_LOMAC_TYPE_EQUAL;
913db2661ceSRobert Watson 	else if (ptys_equal &&
914db2661ceSRobert Watson 	    (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 ||
915db2661ceSRobert Watson 	    strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0))
916db2661ceSRobert Watson 		lomac_type = MAC_LOMAC_TYPE_EQUAL;
917db2661ceSRobert Watson 	else
918db2661ceSRobert Watson 		lomac_type = MAC_LOMAC_TYPE_HIGH;
919db2661ceSRobert Watson 	mac_lomac_set_single(mac_lomac, lomac_type, 0);
920db2661ceSRobert Watson }
921db2661ceSRobert Watson 
922db2661ceSRobert Watson static void
923990b4b2dSRobert Watson mac_lomac_create_devfs_directory(struct mount *mp, char *dirname,
924990b4b2dSRobert Watson     int dirnamelen, struct devfs_dirent *devfs_dirent, struct label *label)
925db2661ceSRobert Watson {
926db2661ceSRobert Watson 	struct mac_lomac *mac_lomac;
927db2661ceSRobert Watson 
928db2661ceSRobert Watson 	mac_lomac = SLOT(label);
929db2661ceSRobert Watson 	mac_lomac_set_single(mac_lomac, MAC_LOMAC_TYPE_HIGH, 0);
930db2661ceSRobert Watson }
931db2661ceSRobert Watson 
932db2661ceSRobert Watson static void
933990b4b2dSRobert Watson mac_lomac_create_devfs_symlink(struct ucred *cred, struct mount *mp,
934990b4b2dSRobert Watson     struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de,
935990b4b2dSRobert Watson     struct label *delabel)
936db2661ceSRobert Watson {
937db2661ceSRobert Watson 	struct mac_lomac *source, *dest;
938db2661ceSRobert Watson 
939eca8a663SRobert Watson 	source = SLOT(cred->cr_label);
940db2661ceSRobert Watson 	dest = SLOT(delabel);
941db2661ceSRobert Watson 
942db2661ceSRobert Watson 	mac_lomac_copy_single(source, dest);
943db2661ceSRobert Watson }
944db2661ceSRobert Watson 
945db2661ceSRobert Watson static void
946db2661ceSRobert Watson mac_lomac_create_mount(struct ucred *cred, struct mount *mp,
947db2661ceSRobert Watson     struct label *mntlabel, struct label *fslabel)
948db2661ceSRobert Watson {
949db2661ceSRobert Watson 	struct mac_lomac *source, *dest;
950db2661ceSRobert Watson 
951eca8a663SRobert Watson 	source = SLOT(cred->cr_label);
952db2661ceSRobert Watson 	dest = SLOT(mntlabel);
953db2661ceSRobert Watson 	mac_lomac_copy_single(source, dest);
954db2661ceSRobert Watson 	dest = SLOT(fslabel);
955db2661ceSRobert Watson 	mac_lomac_copy_single(source, dest);
956db2661ceSRobert Watson }
957db2661ceSRobert Watson 
958db2661ceSRobert Watson static void
959db2661ceSRobert Watson mac_lomac_create_root_mount(struct ucred *cred, struct mount *mp,
960db2661ceSRobert Watson     struct label *mntlabel, struct label *fslabel)
961db2661ceSRobert Watson {
962db2661ceSRobert Watson 	struct mac_lomac *mac_lomac;
963db2661ceSRobert Watson 
964db2661ceSRobert Watson 	/* Always mount root as high integrity. */
965db2661ceSRobert Watson 	mac_lomac = SLOT(fslabel);
966db2661ceSRobert Watson 	mac_lomac_set_single(mac_lomac, MAC_LOMAC_TYPE_HIGH, 0);
967db2661ceSRobert Watson 	mac_lomac = SLOT(mntlabel);
968db2661ceSRobert Watson 	mac_lomac_set_single(mac_lomac, MAC_LOMAC_TYPE_HIGH, 0);
969db2661ceSRobert Watson }
970db2661ceSRobert Watson 
971db2661ceSRobert Watson static void
972db2661ceSRobert Watson mac_lomac_relabel_vnode(struct ucred *cred, struct vnode *vp,
973db2661ceSRobert Watson     struct label *vnodelabel, struct label *label)
974db2661ceSRobert Watson {
975db2661ceSRobert Watson 	struct mac_lomac *source, *dest;
976db2661ceSRobert Watson 
977db2661ceSRobert Watson 	source = SLOT(label);
978db2661ceSRobert Watson 	dest = SLOT(vnodelabel);
979db2661ceSRobert Watson 
980db2661ceSRobert Watson 	try_relabel(source, dest);
981db2661ceSRobert Watson }
982db2661ceSRobert Watson 
983db2661ceSRobert Watson static void
984990b4b2dSRobert Watson mac_lomac_update_devfsdirent(struct mount *mp,
985990b4b2dSRobert Watson     struct devfs_dirent *devfs_dirent, struct label *direntlabel,
986990b4b2dSRobert Watson     struct vnode *vp, struct label *vnodelabel)
987db2661ceSRobert Watson {
988db2661ceSRobert Watson 	struct mac_lomac *source, *dest;
989db2661ceSRobert Watson 
990db2661ceSRobert Watson 	source = SLOT(vnodelabel);
991db2661ceSRobert Watson 	dest = SLOT(direntlabel);
992db2661ceSRobert Watson 
993db2661ceSRobert Watson 	mac_lomac_copy(source, dest);
994db2661ceSRobert Watson }
995db2661ceSRobert Watson 
996db2661ceSRobert Watson static void
997db2661ceSRobert Watson mac_lomac_associate_vnode_devfs(struct mount *mp, struct label *fslabel,
998db2661ceSRobert Watson     struct devfs_dirent *de, struct label *delabel, struct vnode *vp,
999db2661ceSRobert Watson     struct label *vlabel)
1000db2661ceSRobert Watson {
1001db2661ceSRobert Watson 	struct mac_lomac *source, *dest;
1002db2661ceSRobert Watson 
1003db2661ceSRobert Watson 	source = SLOT(delabel);
1004db2661ceSRobert Watson 	dest = SLOT(vlabel);
1005db2661ceSRobert Watson 
1006db2661ceSRobert Watson 	mac_lomac_copy_single(source, dest);
1007db2661ceSRobert Watson }
1008db2661ceSRobert Watson 
1009db2661ceSRobert Watson static int
1010db2661ceSRobert Watson mac_lomac_associate_vnode_extattr(struct mount *mp, struct label *fslabel,
1011db2661ceSRobert Watson     struct vnode *vp, struct label *vlabel)
1012db2661ceSRobert Watson {
1013db2661ceSRobert Watson 	struct mac_lomac temp, *source, *dest;
1014b247d661SMaxime Henrion 	int buflen, error;
1015db2661ceSRobert Watson 
1016db2661ceSRobert Watson 	source = SLOT(fslabel);
1017db2661ceSRobert Watson 	dest = SLOT(vlabel);
1018db2661ceSRobert Watson 
1019db2661ceSRobert Watson 	buflen = sizeof(temp);
1020db2661ceSRobert Watson 	bzero(&temp, buflen);
1021db2661ceSRobert Watson 
1022db2661ceSRobert Watson 	error = vn_extattr_get(vp, IO_NODELOCKED, MAC_LOMAC_EXTATTR_NAMESPACE,
1023db2661ceSRobert Watson 	    MAC_LOMAC_EXTATTR_NAME, &buflen, (char *)&temp, curthread);
1024db2661ceSRobert Watson 	if (error == ENOATTR || error == EOPNOTSUPP) {
1025db2661ceSRobert Watson 		/* Fall back to the fslabel. */
1026db2661ceSRobert Watson 		mac_lomac_copy_single(source, dest);
1027db2661ceSRobert Watson 		return (0);
1028db2661ceSRobert Watson 	} else if (error)
1029db2661ceSRobert Watson 		return (error);
1030db2661ceSRobert Watson 
1031db2661ceSRobert Watson 	if (buflen != sizeof(temp)) {
1032db2661ceSRobert Watson 		if (buflen != sizeof(temp) - sizeof(temp.ml_auxsingle)) {
1033db2661ceSRobert Watson 			printf("mac_lomac_associate_vnode_extattr: bad size %d\n",
1034db2661ceSRobert Watson 			    buflen);
1035db2661ceSRobert Watson 			return (EPERM);
1036db2661ceSRobert Watson 		}
1037db2661ceSRobert Watson 		bzero(&temp.ml_auxsingle, sizeof(temp.ml_auxsingle));
1038db2661ceSRobert Watson 		buflen = sizeof(temp);
1039db2661ceSRobert Watson 		(void)vn_extattr_set(vp, IO_NODELOCKED,
1040db2661ceSRobert Watson 		    MAC_LOMAC_EXTATTR_NAMESPACE, MAC_LOMAC_EXTATTR_NAME,
1041db2661ceSRobert Watson 		    buflen, (char *)&temp, curthread);
1042db2661ceSRobert Watson 	}
1043db2661ceSRobert Watson 	if (mac_lomac_valid(&temp) != 0) {
1044db2661ceSRobert Watson 		printf("mac_lomac_associate_vnode_extattr: invalid\n");
1045db2661ceSRobert Watson 		return (EPERM);
1046db2661ceSRobert Watson 	}
1047db2661ceSRobert Watson 	if ((temp.ml_flags & MAC_LOMAC_FLAGS_BOTH) != MAC_LOMAC_FLAG_SINGLE) {
1048db2661ceSRobert Watson 		printf("mac_lomac_associate_vnode_extattr: not single\n");
1049db2661ceSRobert Watson 		return (EPERM);
1050db2661ceSRobert Watson 	}
1051db2661ceSRobert Watson 
1052db2661ceSRobert Watson 	mac_lomac_copy_single(&temp, dest);
1053db2661ceSRobert Watson 	return (0);
1054db2661ceSRobert Watson }
1055db2661ceSRobert Watson 
1056db2661ceSRobert Watson static void
1057db2661ceSRobert Watson mac_lomac_associate_vnode_singlelabel(struct mount *mp,
1058db2661ceSRobert Watson     struct label *fslabel, struct vnode *vp, struct label *vlabel)
1059db2661ceSRobert Watson {
1060db2661ceSRobert Watson 	struct mac_lomac *source, *dest;
1061db2661ceSRobert Watson 
1062db2661ceSRobert Watson 	source = SLOT(fslabel);
1063db2661ceSRobert Watson 	dest = SLOT(vlabel);
1064db2661ceSRobert Watson 
1065db2661ceSRobert Watson 	mac_lomac_copy_single(source, dest);
1066db2661ceSRobert Watson }
1067db2661ceSRobert Watson 
1068db2661ceSRobert Watson static int
1069db2661ceSRobert Watson mac_lomac_create_vnode_extattr(struct ucred *cred, struct mount *mp,
1070db2661ceSRobert Watson     struct label *fslabel, struct vnode *dvp, struct label *dlabel,
1071db2661ceSRobert Watson     struct vnode *vp, struct label *vlabel, struct componentname *cnp)
1072db2661ceSRobert Watson {
1073db2661ceSRobert Watson 	struct mac_lomac *source, *dest, *dir, temp;
1074db2661ceSRobert Watson 	size_t buflen;
1075db2661ceSRobert Watson 	int error;
1076db2661ceSRobert Watson 
1077db2661ceSRobert Watson 	buflen = sizeof(temp);
1078db2661ceSRobert Watson 	bzero(&temp, buflen);
1079db2661ceSRobert Watson 
1080eca8a663SRobert Watson 	source = SLOT(cred->cr_label);
1081db2661ceSRobert Watson 	dest = SLOT(vlabel);
1082db2661ceSRobert Watson 	dir = SLOT(dlabel);
1083db2661ceSRobert Watson 	if (dir->ml_flags & MAC_LOMAC_FLAG_AUX) {
1084db2661ceSRobert Watson 		mac_lomac_copy_auxsingle(dir, &temp);
1085db2661ceSRobert Watson 		mac_lomac_set_single(&temp, dir->ml_auxsingle.mle_type,
1086db2661ceSRobert Watson 		    dir->ml_auxsingle.mle_grade);
1087db2661ceSRobert Watson 	} else {
1088db2661ceSRobert Watson 		mac_lomac_copy_single(source, &temp);
1089db2661ceSRobert Watson 	}
1090db2661ceSRobert Watson 
1091db2661ceSRobert Watson 	error = vn_extattr_set(vp, IO_NODELOCKED, MAC_LOMAC_EXTATTR_NAMESPACE,
1092db2661ceSRobert Watson 	    MAC_LOMAC_EXTATTR_NAME, buflen, (char *)&temp, curthread);
1093db2661ceSRobert Watson 	if (error == 0)
1094db2661ceSRobert Watson 		mac_lomac_copy(&temp, dest);
1095db2661ceSRobert Watson 	return (error);
1096db2661ceSRobert Watson }
1097db2661ceSRobert Watson 
1098db2661ceSRobert Watson static int
1099db2661ceSRobert Watson mac_lomac_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp,
1100db2661ceSRobert Watson     struct label *vlabel, struct label *intlabel)
1101db2661ceSRobert Watson {
1102db2661ceSRobert Watson 	struct mac_lomac *source, temp;
1103db2661ceSRobert Watson 	size_t buflen;
1104db2661ceSRobert Watson 	int error;
1105db2661ceSRobert Watson 
1106db2661ceSRobert Watson 	buflen = sizeof(temp);
1107db2661ceSRobert Watson 	bzero(&temp, buflen);
1108db2661ceSRobert Watson 
1109db2661ceSRobert Watson 	source = SLOT(intlabel);
1110db2661ceSRobert Watson 	if ((source->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0)
1111db2661ceSRobert Watson 		return (0);
1112db2661ceSRobert Watson 
1113db2661ceSRobert Watson 	mac_lomac_copy_single(source, &temp);
1114db2661ceSRobert Watson 	error = vn_extattr_set(vp, IO_NODELOCKED, MAC_LOMAC_EXTATTR_NAMESPACE,
1115db2661ceSRobert Watson 	    MAC_LOMAC_EXTATTR_NAME, buflen, (char *)&temp, curthread);
1116db2661ceSRobert Watson 	return (error);
1117db2661ceSRobert Watson }
1118db2661ceSRobert Watson 
1119db2661ceSRobert Watson /*
1120db2661ceSRobert Watson  * Labeling event operations: IPC object.
1121db2661ceSRobert Watson  */
1122db2661ceSRobert Watson static void
1123a557af22SRobert Watson mac_lomac_create_inpcb_from_socket(struct socket *so, struct label *solabel,
1124a557af22SRobert Watson     struct inpcb *inp, struct label *inplabel)
1125a557af22SRobert Watson {
1126a557af22SRobert Watson 	struct mac_lomac *source, *dest;
1127a557af22SRobert Watson 
1128a557af22SRobert Watson 	source = SLOT(solabel);
1129a557af22SRobert Watson 	dest = SLOT(inplabel);
1130a557af22SRobert Watson 
1131a557af22SRobert Watson 	mac_lomac_copy_single(source, dest);
1132a557af22SRobert Watson }
1133a557af22SRobert Watson 
1134a557af22SRobert Watson static void
1135db2661ceSRobert Watson mac_lomac_create_mbuf_from_socket(struct socket *so, struct label *socketlabel,
1136db2661ceSRobert Watson     struct mbuf *m, struct label *mbuflabel)
1137db2661ceSRobert Watson {
1138db2661ceSRobert Watson 	struct mac_lomac *source, *dest;
1139db2661ceSRobert Watson 
1140db2661ceSRobert Watson 	source = SLOT(socketlabel);
1141db2661ceSRobert Watson 	dest = SLOT(mbuflabel);
1142db2661ceSRobert Watson 
1143db2661ceSRobert Watson 	mac_lomac_copy_single(source, dest);
1144db2661ceSRobert Watson }
1145db2661ceSRobert Watson 
1146db2661ceSRobert Watson static void
1147db2661ceSRobert Watson mac_lomac_create_socket(struct ucred *cred, struct socket *socket,
1148db2661ceSRobert Watson     struct label *socketlabel)
1149db2661ceSRobert Watson {
1150db2661ceSRobert Watson 	struct mac_lomac *source, *dest;
1151db2661ceSRobert Watson 
1152eca8a663SRobert Watson 	source = SLOT(cred->cr_label);
1153db2661ceSRobert Watson 	dest = SLOT(socketlabel);
1154db2661ceSRobert Watson 
1155db2661ceSRobert Watson 	mac_lomac_copy_single(source, dest);
1156db2661ceSRobert Watson }
1157db2661ceSRobert Watson 
1158db2661ceSRobert Watson static void
11594795b82cSRobert Watson mac_lomac_create_pipe(struct ucred *cred, struct pipepair *pp,
1160db2661ceSRobert Watson     struct label *pipelabel)
1161db2661ceSRobert Watson {
1162db2661ceSRobert Watson 	struct mac_lomac *source, *dest;
1163db2661ceSRobert Watson 
1164eca8a663SRobert Watson 	source = SLOT(cred->cr_label);
1165db2661ceSRobert Watson 	dest = SLOT(pipelabel);
1166db2661ceSRobert Watson 
1167db2661ceSRobert Watson 	mac_lomac_copy_single(source, dest);
1168db2661ceSRobert Watson }
1169db2661ceSRobert Watson 
1170db2661ceSRobert Watson static void
1171db2661ceSRobert Watson mac_lomac_create_socket_from_socket(struct socket *oldsocket,
1172db2661ceSRobert Watson     struct label *oldsocketlabel, struct socket *newsocket,
1173db2661ceSRobert Watson     struct label *newsocketlabel)
1174db2661ceSRobert Watson {
1175db2661ceSRobert Watson 	struct mac_lomac *source, *dest;
1176db2661ceSRobert Watson 
1177db2661ceSRobert Watson 	source = SLOT(oldsocketlabel);
1178db2661ceSRobert Watson 	dest = SLOT(newsocketlabel);
1179db2661ceSRobert Watson 
1180db2661ceSRobert Watson 	mac_lomac_copy_single(source, dest);
1181db2661ceSRobert Watson }
1182db2661ceSRobert Watson 
1183db2661ceSRobert Watson static void
1184db2661ceSRobert Watson mac_lomac_relabel_socket(struct ucred *cred, struct socket *socket,
1185db2661ceSRobert Watson     struct label *socketlabel, struct label *newlabel)
1186db2661ceSRobert Watson {
1187db2661ceSRobert Watson 	struct mac_lomac *source, *dest;
1188db2661ceSRobert Watson 
1189db2661ceSRobert Watson 	source = SLOT(newlabel);
1190db2661ceSRobert Watson 	dest = SLOT(socketlabel);
1191db2661ceSRobert Watson 
1192db2661ceSRobert Watson 	try_relabel(source, dest);
1193db2661ceSRobert Watson }
1194db2661ceSRobert Watson 
1195db2661ceSRobert Watson static void
11964795b82cSRobert Watson mac_lomac_relabel_pipe(struct ucred *cred, struct pipepair *pp,
1197db2661ceSRobert Watson     struct label *pipelabel, struct label *newlabel)
1198db2661ceSRobert Watson {
1199db2661ceSRobert Watson 	struct mac_lomac *source, *dest;
1200db2661ceSRobert Watson 
1201db2661ceSRobert Watson 	source = SLOT(newlabel);
1202db2661ceSRobert Watson 	dest = SLOT(pipelabel);
1203db2661ceSRobert Watson 
1204db2661ceSRobert Watson 	try_relabel(source, dest);
1205db2661ceSRobert Watson }
1206db2661ceSRobert Watson 
1207db2661ceSRobert Watson static void
1208db2661ceSRobert Watson mac_lomac_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel,
1209db2661ceSRobert Watson     struct socket *socket, struct label *socketpeerlabel)
1210db2661ceSRobert Watson {
1211db2661ceSRobert Watson 	struct mac_lomac *source, *dest;
1212db2661ceSRobert Watson 
1213db2661ceSRobert Watson 	source = SLOT(mbuflabel);
1214db2661ceSRobert Watson 	dest = SLOT(socketpeerlabel);
1215db2661ceSRobert Watson 
1216db2661ceSRobert Watson 	mac_lomac_copy_single(source, dest);
1217db2661ceSRobert Watson }
1218db2661ceSRobert Watson 
1219db2661ceSRobert Watson /*
1220db2661ceSRobert Watson  * Labeling event operations: network objects.
1221db2661ceSRobert Watson  */
1222db2661ceSRobert Watson static void
1223db2661ceSRobert Watson mac_lomac_set_socket_peer_from_socket(struct socket *oldsocket,
1224db2661ceSRobert Watson     struct label *oldsocketlabel, struct socket *newsocket,
1225db2661ceSRobert Watson     struct label *newsocketpeerlabel)
1226db2661ceSRobert Watson {
1227db2661ceSRobert Watson 	struct mac_lomac *source, *dest;
1228db2661ceSRobert Watson 
1229db2661ceSRobert Watson 	source = SLOT(oldsocketlabel);
1230db2661ceSRobert Watson 	dest = SLOT(newsocketpeerlabel);
1231db2661ceSRobert Watson 
1232db2661ceSRobert Watson 	mac_lomac_copy_single(source, dest);
1233db2661ceSRobert Watson }
1234db2661ceSRobert Watson 
1235db2661ceSRobert Watson static void
1236db2661ceSRobert Watson mac_lomac_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d,
1237db2661ceSRobert Watson     struct label *bpflabel)
1238db2661ceSRobert Watson {
1239db2661ceSRobert Watson 	struct mac_lomac *source, *dest;
1240db2661ceSRobert Watson 
1241eca8a663SRobert Watson 	source = SLOT(cred->cr_label);
1242db2661ceSRobert Watson 	dest = SLOT(bpflabel);
1243db2661ceSRobert Watson 
1244db2661ceSRobert Watson 	mac_lomac_copy_single(source, dest);
1245db2661ceSRobert Watson }
1246db2661ceSRobert Watson 
1247db2661ceSRobert Watson static void
1248db2661ceSRobert Watson mac_lomac_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel)
1249db2661ceSRobert Watson {
12509bf40edeSBrooks Davis 	char tifname[IFNAMSIZ], *p, *q;
1251db2661ceSRobert Watson 	char tiflist[sizeof(trusted_interfaces)];
1252db2661ceSRobert Watson 	struct mac_lomac *dest;
1253db2661ceSRobert Watson 	int len, grade;
1254db2661ceSRobert Watson 
1255db2661ceSRobert Watson 	dest = SLOT(ifnetlabel);
1256db2661ceSRobert Watson 
1257db2661ceSRobert Watson 	if (ifnet->if_type == IFT_LOOP) {
1258db2661ceSRobert Watson 		grade = MAC_LOMAC_TYPE_EQUAL;
1259db2661ceSRobert Watson 		goto set;
1260db2661ceSRobert Watson 	}
1261db2661ceSRobert Watson 
1262db2661ceSRobert Watson 	if (trust_all_interfaces) {
1263db2661ceSRobert Watson 		grade = MAC_LOMAC_TYPE_HIGH;
1264db2661ceSRobert Watson 		goto set;
1265db2661ceSRobert Watson 	}
1266db2661ceSRobert Watson 
1267db2661ceSRobert Watson 	grade = MAC_LOMAC_TYPE_LOW;
1268db2661ceSRobert Watson 
1269db2661ceSRobert Watson 	if (trusted_interfaces[0] == '\0' ||
1270db2661ceSRobert Watson 	    !strvalid(trusted_interfaces, sizeof(trusted_interfaces)))
1271db2661ceSRobert Watson 		goto set;
1272db2661ceSRobert Watson 
1273db2661ceSRobert Watson 	bzero(tiflist, sizeof(tiflist));
1274db2661ceSRobert Watson 	for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++)
1275db2661ceSRobert Watson 		if(*p != ' ' && *p != '\t')
1276db2661ceSRobert Watson 			*q = *p;
1277db2661ceSRobert Watson 
1278db2661ceSRobert Watson 	for (p = q = tiflist;; p++) {
1279db2661ceSRobert Watson 		if (*p == ',' || *p == '\0') {
1280db2661ceSRobert Watson 			len = p - q;
1281db2661ceSRobert Watson 			if (len < IFNAMSIZ) {
1282db2661ceSRobert Watson 				bzero(tifname, sizeof(tifname));
1283db2661ceSRobert Watson 				bcopy(q, tifname, len);
12849bf40edeSBrooks Davis 				if (strcmp(tifname, ifnet->if_xname) == 0) {
1285db2661ceSRobert Watson 					grade = MAC_LOMAC_TYPE_HIGH;
1286db2661ceSRobert Watson 					break;
1287db2661ceSRobert Watson 				}
1288db2661ceSRobert Watson 			}
1289db2661ceSRobert Watson 			else {
1290db2661ceSRobert Watson 				*p = '\0';
1291db2661ceSRobert Watson 				printf("MAC/LOMAC warning: interface name "
1292db2661ceSRobert Watson 				    "\"%s\" is too long (must be < %d)\n",
1293db2661ceSRobert Watson 				    q, IFNAMSIZ);
1294db2661ceSRobert Watson 			}
1295db2661ceSRobert Watson 			if (*p == '\0')
1296db2661ceSRobert Watson 				break;
1297db2661ceSRobert Watson 			q = p + 1;
1298db2661ceSRobert Watson 		}
1299db2661ceSRobert Watson 	}
1300db2661ceSRobert Watson set:
1301db2661ceSRobert Watson 	mac_lomac_set_single(dest, grade, 0);
1302db2661ceSRobert Watson 	mac_lomac_set_range(dest, grade, 0, grade, 0);
1303db2661ceSRobert Watson }
1304db2661ceSRobert Watson 
1305db2661ceSRobert Watson static void
1306db2661ceSRobert Watson mac_lomac_create_ipq(struct mbuf *fragment, struct label *fragmentlabel,
1307db2661ceSRobert Watson     struct ipq *ipq, struct label *ipqlabel)
1308db2661ceSRobert Watson {
1309db2661ceSRobert Watson 	struct mac_lomac *source, *dest;
1310db2661ceSRobert Watson 
1311db2661ceSRobert Watson 	source = SLOT(fragmentlabel);
1312db2661ceSRobert Watson 	dest = SLOT(ipqlabel);
1313db2661ceSRobert Watson 
1314db2661ceSRobert Watson 	mac_lomac_copy_single(source, dest);
1315db2661ceSRobert Watson }
1316db2661ceSRobert Watson 
1317db2661ceSRobert Watson static void
1318db2661ceSRobert Watson mac_lomac_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel,
1319db2661ceSRobert Watson     struct mbuf *datagram, struct label *datagramlabel)
1320db2661ceSRobert Watson {
1321db2661ceSRobert Watson 	struct mac_lomac *source, *dest;
1322db2661ceSRobert Watson 
1323db2661ceSRobert Watson 	source = SLOT(ipqlabel);
1324db2661ceSRobert Watson 	dest = SLOT(datagramlabel);
1325db2661ceSRobert Watson 
1326db2661ceSRobert Watson 	/* Just use the head, since we require them all to match. */
1327db2661ceSRobert Watson 	mac_lomac_copy_single(source, dest);
1328db2661ceSRobert Watson }
1329db2661ceSRobert Watson 
1330db2661ceSRobert Watson static void
1331db2661ceSRobert Watson mac_lomac_create_fragment(struct mbuf *datagram, struct label *datagramlabel,
1332db2661ceSRobert Watson     struct mbuf *fragment, struct label *fragmentlabel)
1333db2661ceSRobert Watson {
1334db2661ceSRobert Watson 	struct mac_lomac *source, *dest;
1335db2661ceSRobert Watson 
1336db2661ceSRobert Watson 	source = SLOT(datagramlabel);
1337db2661ceSRobert Watson 	dest = SLOT(fragmentlabel);
1338db2661ceSRobert Watson 
1339db2661ceSRobert Watson 	mac_lomac_copy_single(source, dest);
1340db2661ceSRobert Watson }
1341db2661ceSRobert Watson 
1342db2661ceSRobert Watson static void
13432d92ec98SRobert Watson mac_lomac_create_mbuf_from_inpcb(struct inpcb *inp, struct label *inplabel,
13442d92ec98SRobert Watson     struct mbuf *m, struct label *mlabel)
13452d92ec98SRobert Watson {
13462d92ec98SRobert Watson 	struct mac_lomac *source, *dest;
13472d92ec98SRobert Watson 
13482d92ec98SRobert Watson 	source = SLOT(inplabel);
13492d92ec98SRobert Watson 	dest = SLOT(mlabel);
13502d92ec98SRobert Watson 
13512d92ec98SRobert Watson 	mac_lomac_copy_single(source, dest);
13522d92ec98SRobert Watson }
13532d92ec98SRobert Watson 
13542d92ec98SRobert Watson static void
1355db2661ceSRobert Watson mac_lomac_create_mbuf_from_mbuf(struct mbuf *oldmbuf,
1356db2661ceSRobert Watson     struct label *oldmbuflabel, struct mbuf *newmbuf,
1357db2661ceSRobert Watson     struct label *newmbuflabel)
1358db2661ceSRobert Watson {
1359db2661ceSRobert Watson 	struct mac_lomac *source, *dest;
1360db2661ceSRobert Watson 
1361db2661ceSRobert Watson 	source = SLOT(oldmbuflabel);
1362db2661ceSRobert Watson 	dest = SLOT(newmbuflabel);
1363db2661ceSRobert Watson 
1364db2661ceSRobert Watson 	/*
1365db2661ceSRobert Watson 	 * Because the source mbuf may not yet have been "created",
1366db2661ceSRobert Watson 	 * just initialized, we do a conditional copy.  Since we don't
1367db2661ceSRobert Watson 	 * allow mbufs to have ranges, do a KASSERT to make sure that
1368db2661ceSRobert Watson 	 * doesn't happen.
1369db2661ceSRobert Watson 	 */
1370db2661ceSRobert Watson 	KASSERT((source->ml_flags & MAC_LOMAC_FLAG_RANGE) == 0,
1371db2661ceSRobert Watson 	    ("mac_lomac_create_mbuf_from_mbuf: source mbuf has range"));
1372db2661ceSRobert Watson 	mac_lomac_copy(source, dest);
1373db2661ceSRobert Watson }
1374db2661ceSRobert Watson 
1375db2661ceSRobert Watson static void
1376db2661ceSRobert Watson mac_lomac_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel,
1377db2661ceSRobert Watson     struct mbuf *mbuf, struct label *mbuflabel)
1378db2661ceSRobert Watson {
1379db2661ceSRobert Watson 	struct mac_lomac *dest;
1380db2661ceSRobert Watson 
1381db2661ceSRobert Watson 	dest = SLOT(mbuflabel);
1382db2661ceSRobert Watson 
1383db2661ceSRobert Watson 	mac_lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0);
1384db2661ceSRobert Watson }
1385db2661ceSRobert Watson 
1386db2661ceSRobert Watson static void
1387db2661ceSRobert Watson mac_lomac_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel,
1388db2661ceSRobert Watson     struct mbuf *mbuf, struct label *mbuflabel)
1389db2661ceSRobert Watson {
1390db2661ceSRobert Watson 	struct mac_lomac *source, *dest;
1391db2661ceSRobert Watson 
1392db2661ceSRobert Watson 	source = SLOT(bpflabel);
1393db2661ceSRobert Watson 	dest = SLOT(mbuflabel);
1394db2661ceSRobert Watson 
1395db2661ceSRobert Watson 	mac_lomac_copy_single(source, dest);
1396db2661ceSRobert Watson }
1397db2661ceSRobert Watson 
1398db2661ceSRobert Watson static void
1399db2661ceSRobert Watson mac_lomac_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel,
1400db2661ceSRobert Watson     struct mbuf *m, struct label *mbuflabel)
1401db2661ceSRobert Watson {
1402db2661ceSRobert Watson 	struct mac_lomac *source, *dest;
1403db2661ceSRobert Watson 
1404db2661ceSRobert Watson 	source = SLOT(ifnetlabel);
1405db2661ceSRobert Watson 	dest = SLOT(mbuflabel);
1406db2661ceSRobert Watson 
1407db2661ceSRobert Watson 	mac_lomac_copy_single(source, dest);
1408db2661ceSRobert Watson }
1409db2661ceSRobert Watson 
1410db2661ceSRobert Watson static void
1411db2661ceSRobert Watson mac_lomac_create_mbuf_multicast_encap(struct mbuf *oldmbuf,
1412db2661ceSRobert Watson     struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel,
1413db2661ceSRobert Watson     struct mbuf *newmbuf, struct label *newmbuflabel)
1414db2661ceSRobert Watson {
1415db2661ceSRobert Watson 	struct mac_lomac *source, *dest;
1416db2661ceSRobert Watson 
1417db2661ceSRobert Watson 	source = SLOT(oldmbuflabel);
1418db2661ceSRobert Watson 	dest = SLOT(newmbuflabel);
1419db2661ceSRobert Watson 
1420db2661ceSRobert Watson 	mac_lomac_copy_single(source, dest);
1421db2661ceSRobert Watson }
1422db2661ceSRobert Watson 
1423db2661ceSRobert Watson static void
1424db2661ceSRobert Watson mac_lomac_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel,
1425db2661ceSRobert Watson     struct mbuf *newmbuf, struct label *newmbuflabel)
1426db2661ceSRobert Watson {
1427db2661ceSRobert Watson 	struct mac_lomac *source, *dest;
1428db2661ceSRobert Watson 
1429db2661ceSRobert Watson 	source = SLOT(oldmbuflabel);
1430db2661ceSRobert Watson 	dest = SLOT(newmbuflabel);
1431db2661ceSRobert Watson 
1432db2661ceSRobert Watson 	mac_lomac_copy_single(source, dest);
1433db2661ceSRobert Watson }
1434db2661ceSRobert Watson 
1435db2661ceSRobert Watson static int
1436db2661ceSRobert Watson mac_lomac_fragment_match(struct mbuf *fragment, struct label *fragmentlabel,
1437db2661ceSRobert Watson     struct ipq *ipq, struct label *ipqlabel)
1438db2661ceSRobert Watson {
1439db2661ceSRobert Watson 	struct mac_lomac *a, *b;
1440db2661ceSRobert Watson 
1441db2661ceSRobert Watson 	a = SLOT(ipqlabel);
1442db2661ceSRobert Watson 	b = SLOT(fragmentlabel);
1443db2661ceSRobert Watson 
1444db2661ceSRobert Watson 	return (mac_lomac_equal_single(a, b));
1445db2661ceSRobert Watson }
1446db2661ceSRobert Watson 
1447db2661ceSRobert Watson static void
1448db2661ceSRobert Watson mac_lomac_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet,
1449db2661ceSRobert Watson     struct label *ifnetlabel, struct label *newlabel)
1450db2661ceSRobert Watson {
1451db2661ceSRobert Watson 	struct mac_lomac *source, *dest;
1452db2661ceSRobert Watson 
1453db2661ceSRobert Watson 	source = SLOT(newlabel);
1454db2661ceSRobert Watson 	dest = SLOT(ifnetlabel);
1455db2661ceSRobert Watson 
1456db2661ceSRobert Watson 	try_relabel(source, dest);
1457db2661ceSRobert Watson }
1458db2661ceSRobert Watson 
1459db2661ceSRobert Watson static void
1460db2661ceSRobert Watson mac_lomac_update_ipq(struct mbuf *fragment, struct label *fragmentlabel,
1461db2661ceSRobert Watson     struct ipq *ipq, struct label *ipqlabel)
1462db2661ceSRobert Watson {
1463db2661ceSRobert Watson 
1464db2661ceSRobert Watson 	/* NOOP: we only accept matching labels, so no need to update */
1465db2661ceSRobert Watson }
1466db2661ceSRobert Watson 
1467a557af22SRobert Watson static void
1468a557af22SRobert Watson mac_lomac_inpcb_sosetlabel(struct socket *so, struct label *solabel,
1469a557af22SRobert Watson     struct inpcb *inp, struct label *inplabel)
1470a557af22SRobert Watson {
1471a557af22SRobert Watson 	struct mac_lomac *source, *dest;
1472a557af22SRobert Watson 
1473a557af22SRobert Watson 	source = SLOT(solabel);
1474a557af22SRobert Watson 	dest = SLOT(inplabel);
1475a557af22SRobert Watson 
1476a557af22SRobert Watson 	mac_lomac_copy_single(source, dest);
1477a557af22SRobert Watson }
1478a557af22SRobert Watson 
1479db2661ceSRobert Watson /*
1480db2661ceSRobert Watson  * Labeling event operations: processes.
1481db2661ceSRobert Watson  */
1482db2661ceSRobert Watson static void
1483db2661ceSRobert Watson mac_lomac_execve_transition(struct ucred *old, struct ucred *new,
1484db2661ceSRobert Watson     struct vnode *vp, struct label *vnodelabel,
1485db2661ceSRobert Watson     struct label *interpvnodelabel, struct image_params *imgp,
1486db2661ceSRobert Watson     struct label *execlabel)
1487db2661ceSRobert Watson {
1488db2661ceSRobert Watson 	struct mac_lomac *source, *dest, *obj, *robj;
1489db2661ceSRobert Watson 
1490eca8a663SRobert Watson 	source = SLOT(old->cr_label);
1491eca8a663SRobert Watson 	dest = SLOT(new->cr_label);
1492db2661ceSRobert Watson 	obj = SLOT(vnodelabel);
1493db2661ceSRobert Watson 	robj = interpvnodelabel != NULL ? SLOT(interpvnodelabel) : obj;
1494db2661ceSRobert Watson 
1495db2661ceSRobert Watson 	mac_lomac_copy(source, dest);
1496db2661ceSRobert Watson 	/*
1497db2661ceSRobert Watson 	 * If there's an auxiliary label on the real object, respect it
1498db2661ceSRobert Watson 	 * and assume that this level should be assumed immediately if
1499db2661ceSRobert Watson 	 * a higher level is currently in place.
1500db2661ceSRobert Watson 	 */
1501db2661ceSRobert Watson 	if (robj->ml_flags & MAC_LOMAC_FLAG_AUX &&
1502db2661ceSRobert Watson 	    !mac_lomac_dominate_element(&robj->ml_auxsingle, &dest->ml_single)
1503db2661ceSRobert Watson 	    && mac_lomac_auxsingle_in_range(robj, dest))
1504db2661ceSRobert Watson 		mac_lomac_set_single(dest, robj->ml_auxsingle.mle_type,
1505db2661ceSRobert Watson 		    robj->ml_auxsingle.mle_grade);
1506db2661ceSRobert Watson 	/*
1507db2661ceSRobert Watson 	 * Restructuring to use the execve transitioning mechanism
1508db2661ceSRobert Watson 	 * instead of the normal demotion mechanism here would be
1509db2661ceSRobert Watson 	 * difficult, so just copy the label over and perform standard
1510db2661ceSRobert Watson 	 * demotion.  This is also non-optimal because it will result
1511db2661ceSRobert Watson 	 * in the intermediate label "new" being created and immediately
1512db2661ceSRobert Watson 	 * recycled.
1513db2661ceSRobert Watson 	 */
1514db2661ceSRobert Watson 	if (mac_lomac_enabled && revocation_enabled &&
1515db2661ceSRobert Watson 	    !mac_lomac_dominate_single(obj, source))
1516db2661ceSRobert Watson 		(void)maybe_demote(source, obj, "executing", "file", vp);
1517db2661ceSRobert Watson }
1518db2661ceSRobert Watson 
1519db2661ceSRobert Watson static int
1520db2661ceSRobert Watson mac_lomac_execve_will_transition(struct ucred *old, struct vnode *vp,
1521db2661ceSRobert Watson     struct label *vnodelabel, struct label *interpvnodelabel,
1522db2661ceSRobert Watson     struct image_params *imgp, struct label *execlabel)
1523db2661ceSRobert Watson {
1524db2661ceSRobert Watson 	struct mac_lomac *subj, *obj, *robj;
1525db2661ceSRobert Watson 
1526db2661ceSRobert Watson 	if (!mac_lomac_enabled || !revocation_enabled)
1527db2661ceSRobert Watson 		return (0);
1528db2661ceSRobert Watson 
1529eca8a663SRobert Watson 	subj = SLOT(old->cr_label);
1530db2661ceSRobert Watson 	obj = SLOT(vnodelabel);
1531db2661ceSRobert Watson 	robj = interpvnodelabel != NULL ? SLOT(interpvnodelabel) : obj;
1532db2661ceSRobert Watson 
1533db2661ceSRobert Watson 	return ((robj->ml_flags & MAC_LOMAC_FLAG_AUX &&
1534db2661ceSRobert Watson 	    !mac_lomac_dominate_element(&robj->ml_auxsingle, &subj->ml_single)
1535db2661ceSRobert Watson 	    && mac_lomac_auxsingle_in_range(robj, subj)) ||
1536db2661ceSRobert Watson 	    !mac_lomac_dominate_single(obj, subj));
1537db2661ceSRobert Watson }
1538db2661ceSRobert Watson 
1539db2661ceSRobert Watson static void
1540db2661ceSRobert Watson mac_lomac_create_proc0(struct ucred *cred)
1541db2661ceSRobert Watson {
1542db2661ceSRobert Watson 	struct mac_lomac *dest;
1543db2661ceSRobert Watson 
1544eca8a663SRobert Watson 	dest = SLOT(cred->cr_label);
1545db2661ceSRobert Watson 
1546db2661ceSRobert Watson 	mac_lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0);
1547db2661ceSRobert Watson 	mac_lomac_set_range(dest, MAC_LOMAC_TYPE_LOW, 0, MAC_LOMAC_TYPE_HIGH,
1548db2661ceSRobert Watson 	    0);
1549db2661ceSRobert Watson }
1550db2661ceSRobert Watson 
1551db2661ceSRobert Watson static void
1552db2661ceSRobert Watson mac_lomac_create_proc1(struct ucred *cred)
1553db2661ceSRobert Watson {
1554db2661ceSRobert Watson 	struct mac_lomac *dest;
1555db2661ceSRobert Watson 
1556eca8a663SRobert Watson 	dest = SLOT(cred->cr_label);
1557db2661ceSRobert Watson 
1558db2661ceSRobert Watson 	mac_lomac_set_single(dest, MAC_LOMAC_TYPE_HIGH, 0);
1559db2661ceSRobert Watson 	mac_lomac_set_range(dest, MAC_LOMAC_TYPE_LOW, 0, MAC_LOMAC_TYPE_HIGH,
1560db2661ceSRobert Watson 	    0);
1561db2661ceSRobert Watson }
1562db2661ceSRobert Watson 
1563db2661ceSRobert Watson static void
1564db2661ceSRobert Watson mac_lomac_relabel_cred(struct ucred *cred, struct label *newlabel)
1565db2661ceSRobert Watson {
1566db2661ceSRobert Watson 	struct mac_lomac *source, *dest;
1567db2661ceSRobert Watson 
1568db2661ceSRobert Watson 	source = SLOT(newlabel);
1569eca8a663SRobert Watson 	dest = SLOT(cred->cr_label);
1570db2661ceSRobert Watson 
1571db2661ceSRobert Watson 	try_relabel(source, dest);
1572db2661ceSRobert Watson }
1573db2661ceSRobert Watson 
1574db2661ceSRobert Watson /*
1575db2661ceSRobert Watson  * Access control checks.
1576db2661ceSRobert Watson  */
1577db2661ceSRobert Watson static int
1578db2661ceSRobert Watson mac_lomac_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel,
1579db2661ceSRobert Watson     struct ifnet *ifnet, struct label *ifnetlabel)
1580db2661ceSRobert Watson {
1581db2661ceSRobert Watson 	struct mac_lomac *a, *b;
1582db2661ceSRobert Watson 
1583db2661ceSRobert Watson 	if (!mac_lomac_enabled)
1584db2661ceSRobert Watson 		return (0);
1585db2661ceSRobert Watson 
1586db2661ceSRobert Watson 	a = SLOT(bpflabel);
1587db2661ceSRobert Watson 	b = SLOT(ifnetlabel);
1588db2661ceSRobert Watson 
1589db2661ceSRobert Watson 	if (mac_lomac_equal_single(a, b))
1590db2661ceSRobert Watson 		return (0);
1591db2661ceSRobert Watson 	return (EACCES);
1592db2661ceSRobert Watson }
1593db2661ceSRobert Watson 
1594db2661ceSRobert Watson static int
1595db2661ceSRobert Watson mac_lomac_check_cred_relabel(struct ucred *cred, struct label *newlabel)
1596db2661ceSRobert Watson {
1597db2661ceSRobert Watson 	struct mac_lomac *subj, *new;
1598db2661ceSRobert Watson 	int error;
1599db2661ceSRobert Watson 
1600eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
1601db2661ceSRobert Watson 	new = SLOT(newlabel);
1602db2661ceSRobert Watson 
1603db2661ceSRobert Watson 	/*
1604db2661ceSRobert Watson 	 * If there is a LOMAC label update for the credential, it may
1605db2661ceSRobert Watson 	 * be an update of the single, range, or both.
1606db2661ceSRobert Watson 	 */
1607db2661ceSRobert Watson 	error = lomac_atmostflags(new, MAC_LOMAC_FLAGS_BOTH);
1608db2661ceSRobert Watson 	if (error)
1609db2661ceSRobert Watson 		return (error);
1610db2661ceSRobert Watson 
1611db2661ceSRobert Watson 	/*
1612db2661ceSRobert Watson 	 * If the LOMAC label is to be changed, authorize as appropriate.
1613db2661ceSRobert Watson 	 */
1614db2661ceSRobert Watson 	if (new->ml_flags & MAC_LOMAC_FLAGS_BOTH) {
1615db2661ceSRobert Watson 		/*
161684bdb083SRobert Watson 		 * Fill in the missing parts from the previous label.
1617db2661ceSRobert Watson 		 */
161884bdb083SRobert Watson 		if ((new->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0)
161984bdb083SRobert Watson 			mac_lomac_copy_single(subj, new);
162084bdb083SRobert Watson 		if ((new->ml_flags & MAC_LOMAC_FLAG_RANGE) == 0)
162184bdb083SRobert Watson 			mac_lomac_copy_range(subj, new);
1622db2661ceSRobert Watson 
1623db2661ceSRobert Watson 		/*
1624db2661ceSRobert Watson 		 * To change the LOMAC range on a credential, the new
1625db2661ceSRobert Watson 		 * range label must be in the current range.
1626db2661ceSRobert Watson 		 */
162784bdb083SRobert Watson 		if (!mac_lomac_range_in_range(new, subj))
162884bdb083SRobert Watson 			return (EPERM);
162984bdb083SRobert Watson 
163084bdb083SRobert Watson 		/*
163184bdb083SRobert Watson 		 * To change the LOMAC single label on a credential, the
163284bdb083SRobert Watson 		 * new single label must be in the new range.  Implicitly
163384bdb083SRobert Watson 		 * from the previous check, the new single is in the old
163484bdb083SRobert Watson 		 * range.
163584bdb083SRobert Watson 		 */
163684bdb083SRobert Watson 		if (!mac_lomac_single_in_range(new, new))
1637db2661ceSRobert Watson 			return (EPERM);
1638db2661ceSRobert Watson 
1639db2661ceSRobert Watson 		/*
1640db2661ceSRobert Watson 		 * To have EQUAL in any component of the new credential
1641db2661ceSRobert Watson 		 * LOMAC label, the subject must already have EQUAL in
1642db2661ceSRobert Watson 		 * their label.
1643db2661ceSRobert Watson 		 */
1644db2661ceSRobert Watson 		if (mac_lomac_contains_equal(new)) {
1645db2661ceSRobert Watson 			error = mac_lomac_subject_privileged(subj);
1646db2661ceSRobert Watson 			if (error)
1647db2661ceSRobert Watson 				return (error);
1648db2661ceSRobert Watson 		}
1649db2661ceSRobert Watson 
1650db2661ceSRobert Watson 		/*
1651db2661ceSRobert Watson 		 * XXXMAC: Additional consistency tests regarding the
1652db2661ceSRobert Watson 		 * single and range of the new label might be performed
1653db2661ceSRobert Watson 		 * here.
1654db2661ceSRobert Watson 		 */
1655db2661ceSRobert Watson 	}
1656db2661ceSRobert Watson 
1657db2661ceSRobert Watson 	return (0);
1658db2661ceSRobert Watson }
1659db2661ceSRobert Watson 
1660db2661ceSRobert Watson static int
1661db2661ceSRobert Watson mac_lomac_check_cred_visible(struct ucred *u1, struct ucred *u2)
1662db2661ceSRobert Watson {
1663db2661ceSRobert Watson 	struct mac_lomac *subj, *obj;
1664db2661ceSRobert Watson 
1665db2661ceSRobert Watson 	if (!mac_lomac_enabled)
1666db2661ceSRobert Watson 		return (0);
1667db2661ceSRobert Watson 
1668eca8a663SRobert Watson 	subj = SLOT(u1->cr_label);
1669eca8a663SRobert Watson 	obj = SLOT(u2->cr_label);
1670db2661ceSRobert Watson 
1671db2661ceSRobert Watson 	/* XXX: range */
1672db2661ceSRobert Watson 	if (!mac_lomac_dominate_single(obj, subj))
1673db2661ceSRobert Watson 		return (ESRCH);
1674db2661ceSRobert Watson 
1675db2661ceSRobert Watson 	return (0);
1676db2661ceSRobert Watson }
1677db2661ceSRobert Watson 
1678db2661ceSRobert Watson static int
1679db2661ceSRobert Watson mac_lomac_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet,
1680db2661ceSRobert Watson     struct label *ifnetlabel, struct label *newlabel)
1681db2661ceSRobert Watson {
1682db2661ceSRobert Watson 	struct mac_lomac *subj, *new;
1683db2661ceSRobert Watson 	int error;
1684db2661ceSRobert Watson 
1685eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
1686db2661ceSRobert Watson 	new = SLOT(newlabel);
1687db2661ceSRobert Watson 
1688db2661ceSRobert Watson 	/*
1689db2661ceSRobert Watson 	 * If there is a LOMAC label update for the interface, it may
1690db2661ceSRobert Watson 	 * be an update of the single, range, or both.
1691db2661ceSRobert Watson 	 */
1692db2661ceSRobert Watson 	error = lomac_atmostflags(new, MAC_LOMAC_FLAGS_BOTH);
1693db2661ceSRobert Watson 	if (error)
1694db2661ceSRobert Watson 		return (error);
1695db2661ceSRobert Watson 
1696db2661ceSRobert Watson 	/*
1697db2661ceSRobert Watson 	 * Relabling network interfaces requires LOMAC privilege.
1698db2661ceSRobert Watson 	 */
1699db2661ceSRobert Watson 	error = mac_lomac_subject_privileged(subj);
1700db2661ceSRobert Watson 	if (error)
1701db2661ceSRobert Watson 		return (error);
1702db2661ceSRobert Watson 
1703db2661ceSRobert Watson 	/*
1704db2661ceSRobert Watson 	 * If the LOMAC label is to be changed, authorize as appropriate.
1705db2661ceSRobert Watson 	 */
1706db2661ceSRobert Watson 	if (new->ml_flags & MAC_LOMAC_FLAGS_BOTH) {
1707db2661ceSRobert Watson 		/*
170884bdb083SRobert Watson 		 * Fill in the missing parts from the previous label.
170984bdb083SRobert Watson 		 */
171084bdb083SRobert Watson 		if ((new->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0)
171184bdb083SRobert Watson 			mac_lomac_copy_single(subj, new);
171284bdb083SRobert Watson 		if ((new->ml_flags & MAC_LOMAC_FLAG_RANGE) == 0)
171384bdb083SRobert Watson 			mac_lomac_copy_range(subj, new);
171484bdb083SRobert Watson 
171584bdb083SRobert Watson 		/*
1716db2661ceSRobert Watson 		 * Rely on the traditional superuser status for the LOMAC
1717db2661ceSRobert Watson 		 * interface relabel requirements.  XXXMAC: This will go
1718db2661ceSRobert Watson 		 * away.
1719db2661ceSRobert Watson 		 */
1720db2661ceSRobert Watson 		error = suser_cred(cred, 0);
1721db2661ceSRobert Watson 		if (error)
1722db2661ceSRobert Watson 			return (EPERM);
1723db2661ceSRobert Watson 
1724db2661ceSRobert Watson 		/*
1725db2661ceSRobert Watson 		 * XXXMAC: Additional consistency tests regarding the single
1726db2661ceSRobert Watson 		 * and the range of the new label might be performed here.
1727db2661ceSRobert Watson 		 */
1728db2661ceSRobert Watson 	}
1729db2661ceSRobert Watson 
1730db2661ceSRobert Watson 	return (0);
1731db2661ceSRobert Watson }
1732db2661ceSRobert Watson 
1733db2661ceSRobert Watson static int
1734db2661ceSRobert Watson mac_lomac_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel,
1735db2661ceSRobert Watson     struct mbuf *m, struct label *mbuflabel)
1736db2661ceSRobert Watson {
1737db2661ceSRobert Watson 	struct mac_lomac *p, *i;
1738db2661ceSRobert Watson 
1739db2661ceSRobert Watson 	if (!mac_lomac_enabled)
1740db2661ceSRobert Watson 		return (0);
1741db2661ceSRobert Watson 
1742db2661ceSRobert Watson 	p = SLOT(mbuflabel);
1743db2661ceSRobert Watson 	i = SLOT(ifnetlabel);
1744db2661ceSRobert Watson 
1745db2661ceSRobert Watson 	return (mac_lomac_single_in_range(p, i) ? 0 : EACCES);
1746db2661ceSRobert Watson }
1747db2661ceSRobert Watson 
1748db2661ceSRobert Watson static int
1749a557af22SRobert Watson mac_lomac_check_inpcb_deliver(struct inpcb *inp, struct label *inplabel,
1750a557af22SRobert Watson     struct mbuf *m, struct label *mlabel)
1751a557af22SRobert Watson {
1752a557af22SRobert Watson 	struct mac_lomac *p, *i;
1753a557af22SRobert Watson 
1754a557af22SRobert Watson 	if (!mac_lomac_enabled)
1755a557af22SRobert Watson 		return (0);
1756a557af22SRobert Watson 
1757a557af22SRobert Watson 	p = SLOT(mlabel);
1758a557af22SRobert Watson 	i = SLOT(inplabel);
1759a557af22SRobert Watson 
1760a557af22SRobert Watson 	return (mac_lomac_equal_single(p, i) ? 0 : EACCES);
1761a557af22SRobert Watson }
1762a557af22SRobert Watson 
1763a557af22SRobert Watson static int
1764db2661ceSRobert Watson mac_lomac_check_kld_load(struct ucred *cred, struct vnode *vp,
1765db2661ceSRobert Watson     struct label *label)
1766db2661ceSRobert Watson {
1767db2661ceSRobert Watson 	struct mac_lomac *subj, *obj;
1768db2661ceSRobert Watson 
1769db2661ceSRobert Watson 	if (!mac_lomac_enabled)
1770db2661ceSRobert Watson 		return (0);
1771db2661ceSRobert Watson 
1772eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
1773db2661ceSRobert Watson 	obj = SLOT(label);
1774db2661ceSRobert Watson 
1775db2661ceSRobert Watson 	if (mac_lomac_subject_privileged(subj))
1776db2661ceSRobert Watson 		return (EPERM);
1777db2661ceSRobert Watson 
1778db2661ceSRobert Watson 	if (!mac_lomac_high_single(obj))
1779db2661ceSRobert Watson 		return (EACCES);
1780db2661ceSRobert Watson 
1781db2661ceSRobert Watson 	return (0);
1782db2661ceSRobert Watson }
1783db2661ceSRobert Watson 
1784db2661ceSRobert Watson static int
1785db2661ceSRobert Watson mac_lomac_check_kld_unload(struct ucred *cred)
1786db2661ceSRobert Watson {
1787db2661ceSRobert Watson 	struct mac_lomac *subj;
1788db2661ceSRobert Watson 
1789db2661ceSRobert Watson 	if (!mac_lomac_enabled)
1790db2661ceSRobert Watson 		return (0);
1791db2661ceSRobert Watson 
1792eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
1793db2661ceSRobert Watson 
1794db2661ceSRobert Watson 	if (mac_lomac_subject_privileged(subj))
1795db2661ceSRobert Watson 		return (EPERM);
1796db2661ceSRobert Watson 
1797db2661ceSRobert Watson 	return (0);
1798db2661ceSRobert Watson }
1799db2661ceSRobert Watson 
1800db2661ceSRobert Watson static int
18014795b82cSRobert Watson mac_lomac_check_pipe_ioctl(struct ucred *cred, struct pipepair *pp,
1802db2661ceSRobert Watson     struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data)
1803db2661ceSRobert Watson {
1804db2661ceSRobert Watson 
1805db2661ceSRobert Watson 	if(!mac_lomac_enabled)
1806db2661ceSRobert Watson 		return (0);
1807db2661ceSRobert Watson 
1808db2661ceSRobert Watson 	/* XXX: This will be implemented soon... */
1809db2661ceSRobert Watson 
1810db2661ceSRobert Watson 	return (0);
1811db2661ceSRobert Watson }
1812db2661ceSRobert Watson 
1813db2661ceSRobert Watson static int
18144795b82cSRobert Watson mac_lomac_check_pipe_read(struct ucred *cred, struct pipepair *pp,
1815db2661ceSRobert Watson     struct label *pipelabel)
1816db2661ceSRobert Watson {
1817db2661ceSRobert Watson 	struct mac_lomac *subj, *obj;
1818db2661ceSRobert Watson 
1819db2661ceSRobert Watson 	if (!mac_lomac_enabled)
1820db2661ceSRobert Watson 		return (0);
1821db2661ceSRobert Watson 
1822eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
1823db2661ceSRobert Watson 	obj = SLOT((pipelabel));
1824db2661ceSRobert Watson 
1825db2661ceSRobert Watson 	if (!mac_lomac_dominate_single(obj, subj))
1826db2661ceSRobert Watson 		return (maybe_demote(subj, obj, "reading", "pipe", NULL));
1827db2661ceSRobert Watson 
1828db2661ceSRobert Watson 	return (0);
1829db2661ceSRobert Watson }
1830db2661ceSRobert Watson 
1831db2661ceSRobert Watson static int
18324795b82cSRobert Watson mac_lomac_check_pipe_relabel(struct ucred *cred, struct pipepair *pp,
1833db2661ceSRobert Watson     struct label *pipelabel, struct label *newlabel)
1834db2661ceSRobert Watson {
1835db2661ceSRobert Watson 	struct mac_lomac *subj, *obj, *new;
1836db2661ceSRobert Watson 	int error;
1837db2661ceSRobert Watson 
1838db2661ceSRobert Watson 	new = SLOT(newlabel);
1839eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
1840db2661ceSRobert Watson 	obj = SLOT(pipelabel);
1841db2661ceSRobert Watson 
1842db2661ceSRobert Watson 	/*
1843db2661ceSRobert Watson 	 * If there is a LOMAC label update for a pipe, it must be a
1844db2661ceSRobert Watson 	 * single update.
1845db2661ceSRobert Watson 	 */
1846db2661ceSRobert Watson 	error = lomac_atmostflags(new, MAC_LOMAC_FLAG_SINGLE);
1847db2661ceSRobert Watson 	if (error)
1848db2661ceSRobert Watson 		return (error);
1849db2661ceSRobert Watson 
1850db2661ceSRobert Watson 	/*
1851db2661ceSRobert Watson 	 * To perform a relabel of a pipe (LOMAC label or not), LOMAC must
1852db2661ceSRobert Watson 	 * authorize the relabel.
1853db2661ceSRobert Watson 	 */
1854db2661ceSRobert Watson 	if (!mac_lomac_single_in_range(obj, subj))
1855db2661ceSRobert Watson 		return (EPERM);
1856db2661ceSRobert Watson 
1857db2661ceSRobert Watson 	/*
1858db2661ceSRobert Watson 	 * If the LOMAC label is to be changed, authorize as appropriate.
1859db2661ceSRobert Watson 	 */
1860db2661ceSRobert Watson 	if (new->ml_flags & MAC_LOMAC_FLAG_SINGLE) {
1861db2661ceSRobert Watson 		/*
1862db2661ceSRobert Watson 		 * To change the LOMAC label on a pipe, the new pipe label
1863db2661ceSRobert Watson 		 * must be in the subject range.
1864db2661ceSRobert Watson 		 */
1865db2661ceSRobert Watson 		if (!mac_lomac_single_in_range(new, subj))
1866db2661ceSRobert Watson 			return (EPERM);
1867db2661ceSRobert Watson 
1868db2661ceSRobert Watson 		/*
1869db2661ceSRobert Watson 		 * To change the LOMAC label on a pipe to be EQUAL, the
1870db2661ceSRobert Watson 		 * subject must have appropriate privilege.
1871db2661ceSRobert Watson 		 */
1872db2661ceSRobert Watson 		if (mac_lomac_contains_equal(new)) {
1873db2661ceSRobert Watson 			error = mac_lomac_subject_privileged(subj);
1874db2661ceSRobert Watson 			if (error)
1875db2661ceSRobert Watson 				return (error);
1876db2661ceSRobert Watson 		}
1877db2661ceSRobert Watson 	}
1878db2661ceSRobert Watson 
1879db2661ceSRobert Watson 	return (0);
1880db2661ceSRobert Watson }
1881db2661ceSRobert Watson 
1882db2661ceSRobert Watson static int
18834795b82cSRobert Watson mac_lomac_check_pipe_write(struct ucred *cred, struct pipepair *pp,
1884db2661ceSRobert Watson     struct label *pipelabel)
1885db2661ceSRobert Watson {
1886db2661ceSRobert Watson 	struct mac_lomac *subj, *obj;
1887db2661ceSRobert Watson 
1888db2661ceSRobert Watson 	if (!mac_lomac_enabled)
1889db2661ceSRobert Watson 		return (0);
1890db2661ceSRobert Watson 
1891eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
1892db2661ceSRobert Watson 	obj = SLOT((pipelabel));
1893db2661ceSRobert Watson 
1894db2661ceSRobert Watson 	if (!mac_lomac_subject_dominate(subj, obj))
1895db2661ceSRobert Watson 		return (EACCES);
1896db2661ceSRobert Watson 
1897db2661ceSRobert Watson 	return (0);
1898db2661ceSRobert Watson }
1899db2661ceSRobert Watson 
1900db2661ceSRobert Watson static int
1901db2661ceSRobert Watson mac_lomac_check_proc_debug(struct ucred *cred, struct proc *proc)
1902db2661ceSRobert Watson {
1903db2661ceSRobert Watson 	struct mac_lomac *subj, *obj;
1904db2661ceSRobert Watson 
1905db2661ceSRobert Watson 	if (!mac_lomac_enabled)
1906db2661ceSRobert Watson 		return (0);
1907db2661ceSRobert Watson 
1908eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
1909eca8a663SRobert Watson 	obj = SLOT(proc->p_ucred->cr_label);
1910db2661ceSRobert Watson 
1911db2661ceSRobert Watson 	/* XXX: range checks */
1912db2661ceSRobert Watson 	if (!mac_lomac_dominate_single(obj, subj))
1913db2661ceSRobert Watson 		return (ESRCH);
1914db2661ceSRobert Watson 	if (!mac_lomac_subject_dominate(subj, obj))
1915db2661ceSRobert Watson 		return (EACCES);
1916db2661ceSRobert Watson 
1917db2661ceSRobert Watson 	return (0);
1918db2661ceSRobert Watson }
1919db2661ceSRobert Watson 
1920db2661ceSRobert Watson static int
1921db2661ceSRobert Watson mac_lomac_check_proc_sched(struct ucred *cred, struct proc *proc)
1922db2661ceSRobert Watson {
1923db2661ceSRobert Watson 	struct mac_lomac *subj, *obj;
1924db2661ceSRobert Watson 
1925db2661ceSRobert Watson 	if (!mac_lomac_enabled)
1926db2661ceSRobert Watson 		return (0);
1927db2661ceSRobert Watson 
1928eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
1929eca8a663SRobert Watson 	obj = SLOT(proc->p_ucred->cr_label);
1930db2661ceSRobert Watson 
1931db2661ceSRobert Watson 	/* XXX: range checks */
1932db2661ceSRobert Watson 	if (!mac_lomac_dominate_single(obj, subj))
1933db2661ceSRobert Watson 		return (ESRCH);
1934db2661ceSRobert Watson 	if (!mac_lomac_subject_dominate(subj, obj))
1935db2661ceSRobert Watson 		return (EACCES);
1936db2661ceSRobert Watson 
1937db2661ceSRobert Watson 	return (0);
1938db2661ceSRobert Watson }
1939db2661ceSRobert Watson 
1940db2661ceSRobert Watson static int
1941db2661ceSRobert Watson mac_lomac_check_proc_signal(struct ucred *cred, struct proc *proc, int signum)
1942db2661ceSRobert Watson {
1943db2661ceSRobert Watson 	struct mac_lomac *subj, *obj;
1944db2661ceSRobert Watson 
1945db2661ceSRobert Watson 	if (!mac_lomac_enabled)
1946db2661ceSRobert Watson 		return (0);
1947db2661ceSRobert Watson 
1948eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
1949eca8a663SRobert Watson 	obj = SLOT(proc->p_ucred->cr_label);
1950db2661ceSRobert Watson 
1951db2661ceSRobert Watson 	/* XXX: range checks */
1952db2661ceSRobert Watson 	if (!mac_lomac_dominate_single(obj, subj))
1953db2661ceSRobert Watson 		return (ESRCH);
1954db2661ceSRobert Watson 	if (!mac_lomac_subject_dominate(subj, obj))
1955db2661ceSRobert Watson 		return (EACCES);
1956db2661ceSRobert Watson 
1957db2661ceSRobert Watson 	return (0);
1958db2661ceSRobert Watson }
1959db2661ceSRobert Watson 
1960db2661ceSRobert Watson static int
1961db2661ceSRobert Watson mac_lomac_check_socket_deliver(struct socket *so, struct label *socketlabel,
1962db2661ceSRobert Watson     struct mbuf *m, struct label *mbuflabel)
1963db2661ceSRobert Watson {
1964db2661ceSRobert Watson 	struct mac_lomac *p, *s;
1965db2661ceSRobert Watson 
1966db2661ceSRobert Watson 	if (!mac_lomac_enabled)
1967db2661ceSRobert Watson 		return (0);
1968db2661ceSRobert Watson 
1969db2661ceSRobert Watson 	p = SLOT(mbuflabel);
1970db2661ceSRobert Watson 	s = SLOT(socketlabel);
1971db2661ceSRobert Watson 
1972db2661ceSRobert Watson 	return (mac_lomac_equal_single(p, s) ? 0 : EACCES);
1973db2661ceSRobert Watson }
1974db2661ceSRobert Watson 
1975db2661ceSRobert Watson static int
1976db2661ceSRobert Watson mac_lomac_check_socket_relabel(struct ucred *cred, struct socket *socket,
1977db2661ceSRobert Watson     struct label *socketlabel, struct label *newlabel)
1978db2661ceSRobert Watson {
1979db2661ceSRobert Watson 	struct mac_lomac *subj, *obj, *new;
1980db2661ceSRobert Watson 	int error;
1981db2661ceSRobert Watson 
1982db2661ceSRobert Watson 	new = SLOT(newlabel);
1983eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
1984db2661ceSRobert Watson 	obj = SLOT(socketlabel);
1985db2661ceSRobert Watson 
1986db2661ceSRobert Watson 	/*
1987db2661ceSRobert Watson 	 * If there is a LOMAC label update for the socket, it may be
1988db2661ceSRobert Watson 	 * an update of single.
1989db2661ceSRobert Watson 	 */
1990db2661ceSRobert Watson 	error = lomac_atmostflags(new, MAC_LOMAC_FLAG_SINGLE);
1991db2661ceSRobert Watson 	if (error)
1992db2661ceSRobert Watson 		return (error);
1993db2661ceSRobert Watson 
1994db2661ceSRobert Watson 	/*
1995db2661ceSRobert Watson 	 * To relabel a socket, the old socket single must be in the subject
1996db2661ceSRobert Watson 	 * range.
1997db2661ceSRobert Watson 	 */
1998db2661ceSRobert Watson 	if (!mac_lomac_single_in_range(obj, subj))
1999db2661ceSRobert Watson 		return (EPERM);
2000db2661ceSRobert Watson 
2001db2661ceSRobert Watson 	/*
2002db2661ceSRobert Watson 	 * If the LOMAC label is to be changed, authorize as appropriate.
2003db2661ceSRobert Watson 	 */
2004db2661ceSRobert Watson 	if (new->ml_flags & MAC_LOMAC_FLAG_SINGLE) {
2005db2661ceSRobert Watson 		/*
2006db2661ceSRobert Watson 		 * To relabel a socket, the new socket single must be in
2007db2661ceSRobert Watson 		 * the subject range.
2008db2661ceSRobert Watson 		 */
2009db2661ceSRobert Watson 		if (!mac_lomac_single_in_range(new, subj))
2010db2661ceSRobert Watson 			return (EPERM);
2011db2661ceSRobert Watson 
2012db2661ceSRobert Watson 		/*
2013db2661ceSRobert Watson 		 * To change the LOMAC label on the socket to contain EQUAL,
2014db2661ceSRobert Watson 		 * the subject must have appropriate privilege.
2015db2661ceSRobert Watson 		 */
2016db2661ceSRobert Watson 		if (mac_lomac_contains_equal(new)) {
2017db2661ceSRobert Watson 			error = mac_lomac_subject_privileged(subj);
2018db2661ceSRobert Watson 			if (error)
2019db2661ceSRobert Watson 				return (error);
2020db2661ceSRobert Watson 		}
2021db2661ceSRobert Watson 	}
2022db2661ceSRobert Watson 
2023db2661ceSRobert Watson 	return (0);
2024db2661ceSRobert Watson }
2025db2661ceSRobert Watson 
2026db2661ceSRobert Watson static int
2027db2661ceSRobert Watson mac_lomac_check_socket_visible(struct ucred *cred, struct socket *socket,
2028db2661ceSRobert Watson     struct label *socketlabel)
2029db2661ceSRobert Watson {
2030db2661ceSRobert Watson 	struct mac_lomac *subj, *obj;
2031db2661ceSRobert Watson 
2032db2661ceSRobert Watson 	if (!mac_lomac_enabled)
2033db2661ceSRobert Watson 		return (0);
2034db2661ceSRobert Watson 
2035eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
2036db2661ceSRobert Watson 	obj = SLOT(socketlabel);
2037db2661ceSRobert Watson 
2038db2661ceSRobert Watson 	if (!mac_lomac_dominate_single(obj, subj))
2039db2661ceSRobert Watson 		return (ENOENT);
2040db2661ceSRobert Watson 
2041db2661ceSRobert Watson 	return (0);
2042db2661ceSRobert Watson }
2043db2661ceSRobert Watson 
2044db2661ceSRobert Watson static int
2045db2661ceSRobert Watson mac_lomac_check_system_swapon(struct ucred *cred, struct vnode *vp,
2046db2661ceSRobert Watson     struct label *label)
2047db2661ceSRobert Watson {
2048db2661ceSRobert Watson 	struct mac_lomac *subj, *obj;
2049db2661ceSRobert Watson 
2050db2661ceSRobert Watson 	if (!mac_lomac_enabled)
2051db2661ceSRobert Watson 		return (0);
2052db2661ceSRobert Watson 
2053eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
2054db2661ceSRobert Watson 	obj = SLOT(label);
2055db2661ceSRobert Watson 
2056db2661ceSRobert Watson 	if (mac_lomac_subject_privileged(subj))
2057db2661ceSRobert Watson 		return (EPERM);
2058db2661ceSRobert Watson 
2059db2661ceSRobert Watson 	if (!mac_lomac_high_single(obj))
2060db2661ceSRobert Watson 		return (EACCES);
2061db2661ceSRobert Watson 
2062db2661ceSRobert Watson 	return (0);
2063db2661ceSRobert Watson }
2064db2661ceSRobert Watson 
2065db2661ceSRobert Watson static int
206663dba32bSPawel Jakub Dawidek mac_lomac_check_system_sysctl(struct ucred *cred, struct sysctl_oid *oidp,
206763dba32bSPawel Jakub Dawidek     void *arg1, int arg2, struct sysctl_req *req)
2068db2661ceSRobert Watson {
2069db2661ceSRobert Watson 	struct mac_lomac *subj;
2070db2661ceSRobert Watson 
2071db2661ceSRobert Watson 	if (!mac_lomac_enabled)
2072db2661ceSRobert Watson 		return (0);
2073db2661ceSRobert Watson 
2074eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
2075db2661ceSRobert Watson 
2076db2661ceSRobert Watson 	/*
207763dba32bSPawel Jakub Dawidek 	 * Treat sysctl variables without CTLFLAG_ANYBODY flag as
207863dba32bSPawel Jakub Dawidek 	 * lomac/high, but also require privilege to change them.
2079db2661ceSRobert Watson 	 */
208063dba32bSPawel Jakub Dawidek 	if (req->newptr != NULL && (oidp->oid_kind & CTLFLAG_ANYBODY) == 0) {
2081db2661ceSRobert Watson #ifdef notdef
2082db2661ceSRobert Watson 		if (!mac_lomac_subject_dominate_high(subj))
2083db2661ceSRobert Watson 			return (EACCES);
2084db2661ceSRobert Watson #endif
2085db2661ceSRobert Watson 
2086db2661ceSRobert Watson 		if (mac_lomac_subject_privileged(subj))
2087db2661ceSRobert Watson 			return (EPERM);
2088db2661ceSRobert Watson 	}
2089db2661ceSRobert Watson 
2090db2661ceSRobert Watson 	return (0);
2091db2661ceSRobert Watson }
2092db2661ceSRobert Watson 
2093db2661ceSRobert Watson static int
2094db2661ceSRobert Watson mac_lomac_check_vnode_create(struct ucred *cred, struct vnode *dvp,
2095db2661ceSRobert Watson     struct label *dlabel, struct componentname *cnp, struct vattr *vap)
2096db2661ceSRobert Watson {
2097db2661ceSRobert Watson 	struct mac_lomac *subj, *obj;
2098db2661ceSRobert Watson 
2099db2661ceSRobert Watson 	if (!mac_lomac_enabled)
2100db2661ceSRobert Watson 		return (0);
2101db2661ceSRobert Watson 
2102eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
2103db2661ceSRobert Watson 	obj = SLOT(dlabel);
2104db2661ceSRobert Watson 
2105db2661ceSRobert Watson 	if (!mac_lomac_subject_dominate(subj, obj))
2106db2661ceSRobert Watson 		return (EACCES);
2107db2661ceSRobert Watson 	if (obj->ml_flags & MAC_LOMAC_FLAG_AUX &&
2108db2661ceSRobert Watson 	    !mac_lomac_dominate_element(&subj->ml_single, &obj->ml_auxsingle))
2109db2661ceSRobert Watson 		return (EACCES);
2110db2661ceSRobert Watson 
2111db2661ceSRobert Watson 	return (0);
2112db2661ceSRobert Watson }
2113db2661ceSRobert Watson 
2114db2661ceSRobert Watson static int
2115db2661ceSRobert Watson mac_lomac_check_vnode_delete(struct ucred *cred, struct vnode *dvp,
2116db2661ceSRobert Watson     struct label *dlabel, struct vnode *vp, struct label *label,
2117db2661ceSRobert Watson     struct componentname *cnp)
2118db2661ceSRobert Watson {
2119db2661ceSRobert Watson 	struct mac_lomac *subj, *obj;
2120db2661ceSRobert Watson 
2121db2661ceSRobert Watson 	if (!mac_lomac_enabled)
2122db2661ceSRobert Watson 		return (0);
2123db2661ceSRobert Watson 
2124eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
2125db2661ceSRobert Watson 	obj = SLOT(dlabel);
2126db2661ceSRobert Watson 
2127db2661ceSRobert Watson 	if (!mac_lomac_subject_dominate(subj, obj))
2128db2661ceSRobert Watson 		return (EACCES);
2129db2661ceSRobert Watson 
2130db2661ceSRobert Watson 	obj = SLOT(label);
2131db2661ceSRobert Watson 
2132db2661ceSRobert Watson 	if (!mac_lomac_subject_dominate(subj, obj))
2133db2661ceSRobert Watson 		return (EACCES);
2134db2661ceSRobert Watson 
2135db2661ceSRobert Watson 	return (0);
2136db2661ceSRobert Watson }
2137db2661ceSRobert Watson 
2138db2661ceSRobert Watson static int
2139db2661ceSRobert Watson mac_lomac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
2140db2661ceSRobert Watson     struct label *label, acl_type_t type)
2141db2661ceSRobert Watson {
2142db2661ceSRobert Watson 	struct mac_lomac *subj, *obj;
2143db2661ceSRobert Watson 
2144db2661ceSRobert Watson 	if (!mac_lomac_enabled)
2145db2661ceSRobert Watson 		return (0);
2146db2661ceSRobert Watson 
2147eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
2148db2661ceSRobert Watson 	obj = SLOT(label);
2149db2661ceSRobert Watson 
2150db2661ceSRobert Watson 	if (!mac_lomac_subject_dominate(subj, obj))
2151db2661ceSRobert Watson 		return (EACCES);
2152db2661ceSRobert Watson 
2153db2661ceSRobert Watson 	return (0);
2154db2661ceSRobert Watson }
2155db2661ceSRobert Watson 
2156db2661ceSRobert Watson static int
2157db2661ceSRobert Watson mac_lomac_check_vnode_link(struct ucred *cred, struct vnode *dvp,
2158db2661ceSRobert Watson     struct label *dlabel, struct vnode *vp, struct label *label,
2159db2661ceSRobert Watson     struct componentname *cnp)
2160db2661ceSRobert Watson {
2161db2661ceSRobert Watson 	struct mac_lomac *subj, *obj;
2162db2661ceSRobert Watson 
2163db2661ceSRobert Watson 	if (!mac_lomac_enabled)
2164db2661ceSRobert Watson 		return (0);
2165db2661ceSRobert Watson 
2166eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
2167db2661ceSRobert Watson 	obj = SLOT(dlabel);
2168db2661ceSRobert Watson 
2169db2661ceSRobert Watson 	if (!mac_lomac_subject_dominate(subj, obj))
2170db2661ceSRobert Watson 		return (EACCES);
2171db2661ceSRobert Watson 
2172db2661ceSRobert Watson 	obj = SLOT(label);
2173db2661ceSRobert Watson 
2174db2661ceSRobert Watson 	if (!mac_lomac_subject_dominate(subj, obj))
2175db2661ceSRobert Watson 		return (EACCES);
2176db2661ceSRobert Watson 
2177db2661ceSRobert Watson 	return (0);
2178db2661ceSRobert Watson }
2179db2661ceSRobert Watson 
2180db2661ceSRobert Watson static int
2181db2661ceSRobert Watson mac_lomac_check_vnode_mmap(struct ucred *cred, struct vnode *vp,
2182db2661ceSRobert Watson     struct label *label, int prot)
2183db2661ceSRobert Watson {
2184db2661ceSRobert Watson 	struct mac_lomac *subj, *obj;
2185db2661ceSRobert Watson 
2186db2661ceSRobert Watson 	/*
2187db2661ceSRobert Watson 	 * Rely on the use of open()-time protections to handle
2188db2661ceSRobert Watson 	 * non-revocation cases.
2189db2661ceSRobert Watson 	 */
2190db2661ceSRobert Watson 	if (!mac_lomac_enabled)
2191db2661ceSRobert Watson 		return (0);
2192db2661ceSRobert Watson 
2193eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
2194db2661ceSRobert Watson 	obj = SLOT(label);
2195db2661ceSRobert Watson 
2196db2661ceSRobert Watson 	if (prot & VM_PROT_WRITE) {
2197db2661ceSRobert Watson 		if (!mac_lomac_subject_dominate(subj, obj))
2198db2661ceSRobert Watson 			return (EACCES);
2199db2661ceSRobert Watson 	}
2200db2661ceSRobert Watson 	if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
2201db2661ceSRobert Watson 		if (!mac_lomac_dominate_single(obj, subj))
2202db2661ceSRobert Watson 			return (maybe_demote(subj, obj, "mapping", "file", vp));
2203db2661ceSRobert Watson 	}
2204db2661ceSRobert Watson 
2205db2661ceSRobert Watson 	return (0);
2206db2661ceSRobert Watson }
2207db2661ceSRobert Watson 
2208db2661ceSRobert Watson static int
2209db2661ceSRobert Watson mac_lomac_check_vnode_mprotect(struct ucred *cred, struct vnode *vp,
2210db2661ceSRobert Watson     struct label *label, int prot)
2211db2661ceSRobert Watson {
2212db2661ceSRobert Watson 	struct mac_lomac *subj, *obj;
2213db2661ceSRobert Watson 
2214db2661ceSRobert Watson 	/*
2215db2661ceSRobert Watson 	 * Rely on the use of open()-time protections to handle
2216db2661ceSRobert Watson 	 * non-revocation cases.
2217db2661ceSRobert Watson 	 */
2218db2661ceSRobert Watson 	if (!mac_lomac_enabled || !revocation_enabled)
2219db2661ceSRobert Watson 		return (0);
2220db2661ceSRobert Watson 
2221eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
2222db2661ceSRobert Watson 	obj = SLOT(label);
2223db2661ceSRobert Watson 
2224db2661ceSRobert Watson 	if (prot & VM_PROT_WRITE) {
2225db2661ceSRobert Watson 		if (!mac_lomac_subject_dominate(subj, obj))
2226db2661ceSRobert Watson 			return (EACCES);
2227db2661ceSRobert Watson 	}
2228db2661ceSRobert Watson 	if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
2229db2661ceSRobert Watson 		if (!mac_lomac_dominate_single(obj, subj))
2230db2661ceSRobert Watson 			return (EACCES);
2231db2661ceSRobert Watson 	}
2232db2661ceSRobert Watson 
2233db2661ceSRobert Watson 	return (0);
2234db2661ceSRobert Watson }
2235db2661ceSRobert Watson 
2236db2661ceSRobert Watson static void
2237db2661ceSRobert Watson mac_lomac_check_vnode_mmap_downgrade(struct ucred *cred, struct vnode *vp,
2238db2661ceSRobert Watson     struct label *label, /* XXX vm_prot_t */ int *prot)
2239db2661ceSRobert Watson {
2240db2661ceSRobert Watson 	struct mac_lomac *subj, *obj;
2241db2661ceSRobert Watson 
2242db2661ceSRobert Watson 	/*
2243db2661ceSRobert Watson 	 * Rely on the use of open()-time protections to handle
2244db2661ceSRobert Watson 	 * non-revocation cases.
2245db2661ceSRobert Watson 	 */
2246db2661ceSRobert Watson 	if (!mac_lomac_enabled || !revocation_enabled)
2247db2661ceSRobert Watson 		return;
2248db2661ceSRobert Watson 
2249eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
2250db2661ceSRobert Watson 	obj = SLOT(label);
2251db2661ceSRobert Watson 
2252db2661ceSRobert Watson 	if (!mac_lomac_subject_dominate(subj, obj))
2253db2661ceSRobert Watson 		*prot &= ~VM_PROT_WRITE;
2254db2661ceSRobert Watson }
2255db2661ceSRobert Watson 
2256db2661ceSRobert Watson static int
2257db2661ceSRobert Watson mac_lomac_check_vnode_open(struct ucred *cred, struct vnode *vp,
2258db2661ceSRobert Watson     struct label *vnodelabel, int acc_mode)
2259db2661ceSRobert Watson {
2260db2661ceSRobert Watson 	struct mac_lomac *subj, *obj;
2261db2661ceSRobert Watson 
2262db2661ceSRobert Watson 	if (!mac_lomac_enabled)
2263db2661ceSRobert Watson 		return (0);
2264db2661ceSRobert Watson 
2265eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
2266db2661ceSRobert Watson 	obj = SLOT(vnodelabel);
2267db2661ceSRobert Watson 
2268db2661ceSRobert Watson 	/* XXX privilege override for admin? */
2269db2661ceSRobert Watson 	if (acc_mode & (VWRITE | VAPPEND | VADMIN)) {
2270db2661ceSRobert Watson 		if (!mac_lomac_subject_dominate(subj, obj))
2271db2661ceSRobert Watson 			return (EACCES);
2272db2661ceSRobert Watson 	}
2273db2661ceSRobert Watson 
2274db2661ceSRobert Watson 	return (0);
2275db2661ceSRobert Watson }
2276db2661ceSRobert Watson 
2277db2661ceSRobert Watson static int
2278db2661ceSRobert Watson mac_lomac_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
2279db2661ceSRobert Watson     struct vnode *vp, struct label *label)
2280db2661ceSRobert Watson {
2281db2661ceSRobert Watson 	struct mac_lomac *subj, *obj;
2282db2661ceSRobert Watson 
2283db2661ceSRobert Watson 	if (!mac_lomac_enabled || !revocation_enabled)
2284db2661ceSRobert Watson 		return (0);
2285db2661ceSRobert Watson 
2286eca8a663SRobert Watson 	subj = SLOT(active_cred->cr_label);
2287db2661ceSRobert Watson 	obj = SLOT(label);
2288db2661ceSRobert Watson 
2289db2661ceSRobert Watson 	if (!mac_lomac_dominate_single(obj, subj))
2290db2661ceSRobert Watson 		return (maybe_demote(subj, obj, "reading", "file", vp));
2291db2661ceSRobert Watson 
2292db2661ceSRobert Watson 	return (0);
2293db2661ceSRobert Watson }
2294db2661ceSRobert Watson 
2295db2661ceSRobert Watson static int
2296db2661ceSRobert Watson mac_lomac_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
2297db2661ceSRobert Watson     struct label *vnodelabel, struct label *newlabel)
2298db2661ceSRobert Watson {
2299db2661ceSRobert Watson 	struct mac_lomac *old, *new, *subj;
2300db2661ceSRobert Watson 	int error;
2301db2661ceSRobert Watson 
2302db2661ceSRobert Watson 	old = SLOT(vnodelabel);
2303db2661ceSRobert Watson 	new = SLOT(newlabel);
2304eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
2305db2661ceSRobert Watson 
2306db2661ceSRobert Watson 	/*
2307db2661ceSRobert Watson 	 * If there is a LOMAC label update for the vnode, it must be a
2308db2661ceSRobert Watson 	 * single label, with an optional explicit auxiliary single.
2309db2661ceSRobert Watson 	 */
2310db2661ceSRobert Watson 	error = lomac_atmostflags(new,
2311db2661ceSRobert Watson 	    MAC_LOMAC_FLAG_SINGLE | MAC_LOMAC_FLAG_AUX);
2312db2661ceSRobert Watson 	if (error)
2313db2661ceSRobert Watson 		return (error);
2314db2661ceSRobert Watson 
2315db2661ceSRobert Watson 	/*
2316db2661ceSRobert Watson 	 * To perform a relabel of the vnode (LOMAC label or not), LOMAC must
2317db2661ceSRobert Watson 	 * authorize the relabel.
2318db2661ceSRobert Watson 	 */
2319db2661ceSRobert Watson 	if (!mac_lomac_single_in_range(old, subj))
2320db2661ceSRobert Watson 		return (EPERM);
2321db2661ceSRobert Watson 
2322db2661ceSRobert Watson 	/*
2323db2661ceSRobert Watson 	 * If the LOMAC label is to be changed, authorize as appropriate.
2324db2661ceSRobert Watson 	 */
2325db2661ceSRobert Watson 	if (new->ml_flags & MAC_LOMAC_FLAG_SINGLE) {
2326db2661ceSRobert Watson 		/*
2327db2661ceSRobert Watson 		 * To change the LOMAC label on a vnode, the new vnode label
2328db2661ceSRobert Watson 		 * must be in the subject range.
2329db2661ceSRobert Watson 		 */
2330db2661ceSRobert Watson 		if (!mac_lomac_single_in_range(new, subj))
2331db2661ceSRobert Watson 			return (EPERM);
2332db2661ceSRobert Watson 
2333db2661ceSRobert Watson 		/*
2334db2661ceSRobert Watson 		 * To change the LOMAC label on the vnode to be EQUAL,
2335db2661ceSRobert Watson 		 * the subject must have appropriate privilege.
2336db2661ceSRobert Watson 		 */
2337db2661ceSRobert Watson 		if (mac_lomac_contains_equal(new)) {
2338db2661ceSRobert Watson 			error = mac_lomac_subject_privileged(subj);
2339db2661ceSRobert Watson 			if (error)
2340db2661ceSRobert Watson 				return (error);
2341db2661ceSRobert Watson 		}
2342db2661ceSRobert Watson 	}
2343db2661ceSRobert Watson 	if (new->ml_flags & MAC_LOMAC_FLAG_AUX) {
2344db2661ceSRobert Watson 		/*
234584bdb083SRobert Watson 		 * Fill in the missing parts from the previous label.
234684bdb083SRobert Watson 		 */
234784bdb083SRobert Watson 		if ((new->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0)
234884bdb083SRobert Watson 			mac_lomac_copy_single(subj, new);
234984bdb083SRobert Watson 
235084bdb083SRobert Watson 		/*
2351db2661ceSRobert Watson 		 * To change the auxiliary LOMAC label on a vnode, the new
2352db2661ceSRobert Watson 		 * vnode label must be in the subject range.
2353db2661ceSRobert Watson 		 */
2354db2661ceSRobert Watson 		if (!mac_lomac_auxsingle_in_range(new, subj))
2355db2661ceSRobert Watson 			return (EPERM);
2356db2661ceSRobert Watson 
2357db2661ceSRobert Watson 		/*
2358db2661ceSRobert Watson 		 * To change the auxiliary LOMAC label on the vnode to be
2359db2661ceSRobert Watson 		 * EQUAL, the subject must have appropriate privilege.
2360db2661ceSRobert Watson 		 */
2361db2661ceSRobert Watson 		if (mac_lomac_contains_equal(new)) {
2362db2661ceSRobert Watson 			error = mac_lomac_subject_privileged(subj);
2363db2661ceSRobert Watson 			if (error)
2364db2661ceSRobert Watson 				return (error);
2365db2661ceSRobert Watson 		}
2366db2661ceSRobert Watson 	}
2367db2661ceSRobert Watson 
2368db2661ceSRobert Watson 	return (0);
2369db2661ceSRobert Watson }
2370db2661ceSRobert Watson 
2371db2661ceSRobert Watson static int
2372db2661ceSRobert Watson mac_lomac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
2373db2661ceSRobert Watson     struct label *dlabel, struct vnode *vp, struct label *label,
2374db2661ceSRobert Watson     struct componentname *cnp)
2375db2661ceSRobert Watson {
2376db2661ceSRobert Watson 	struct mac_lomac *subj, *obj;
2377db2661ceSRobert Watson 
2378db2661ceSRobert Watson 	if (!mac_lomac_enabled)
2379db2661ceSRobert Watson 		return (0);
2380db2661ceSRobert Watson 
2381eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
2382db2661ceSRobert Watson 	obj = SLOT(dlabel);
2383db2661ceSRobert Watson 
2384db2661ceSRobert Watson 	if (!mac_lomac_subject_dominate(subj, obj))
2385db2661ceSRobert Watson 		return (EACCES);
2386db2661ceSRobert Watson 
2387db2661ceSRobert Watson 	obj = SLOT(label);
2388db2661ceSRobert Watson 
2389db2661ceSRobert Watson 	if (!mac_lomac_subject_dominate(subj, obj))
2390db2661ceSRobert Watson 		return (EACCES);
2391db2661ceSRobert Watson 
2392db2661ceSRobert Watson 	return (0);
2393db2661ceSRobert Watson }
2394db2661ceSRobert Watson 
2395db2661ceSRobert Watson static int
2396db2661ceSRobert Watson mac_lomac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
2397db2661ceSRobert Watson     struct label *dlabel, struct vnode *vp, struct label *label, int samedir,
2398db2661ceSRobert Watson     struct componentname *cnp)
2399db2661ceSRobert Watson {
2400db2661ceSRobert Watson 	struct mac_lomac *subj, *obj;
2401db2661ceSRobert Watson 
2402db2661ceSRobert Watson 	if (!mac_lomac_enabled)
2403db2661ceSRobert Watson 		return (0);
2404db2661ceSRobert Watson 
2405eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
2406db2661ceSRobert Watson 	obj = SLOT(dlabel);
2407db2661ceSRobert Watson 
2408db2661ceSRobert Watson 	if (!mac_lomac_subject_dominate(subj, obj))
2409db2661ceSRobert Watson 		return (EACCES);
2410db2661ceSRobert Watson 
2411db2661ceSRobert Watson 	if (vp != NULL) {
2412db2661ceSRobert Watson 		obj = SLOT(label);
2413db2661ceSRobert Watson 
2414db2661ceSRobert Watson 		if (!mac_lomac_subject_dominate(subj, obj))
2415db2661ceSRobert Watson 			return (EACCES);
2416db2661ceSRobert Watson 	}
2417db2661ceSRobert Watson 
2418db2661ceSRobert Watson 	return (0);
2419db2661ceSRobert Watson }
2420db2661ceSRobert Watson 
2421db2661ceSRobert Watson static int
2422db2661ceSRobert Watson mac_lomac_check_vnode_revoke(struct ucred *cred, struct vnode *vp,
2423db2661ceSRobert Watson     struct label *label)
2424db2661ceSRobert Watson {
2425db2661ceSRobert Watson 	struct mac_lomac *subj, *obj;
2426db2661ceSRobert Watson 
2427db2661ceSRobert Watson 	if (!mac_lomac_enabled)
2428db2661ceSRobert Watson 		return (0);
2429db2661ceSRobert Watson 
2430eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
2431db2661ceSRobert Watson 	obj = SLOT(label);
2432db2661ceSRobert Watson 
2433db2661ceSRobert Watson 	if (!mac_lomac_subject_dominate(subj, obj))
2434db2661ceSRobert Watson 		return (EACCES);
2435db2661ceSRobert Watson 
2436db2661ceSRobert Watson 	return (0);
2437db2661ceSRobert Watson }
2438db2661ceSRobert Watson 
2439db2661ceSRobert Watson static int
2440db2661ceSRobert Watson mac_lomac_check_vnode_setacl(struct ucred *cred, struct vnode *vp,
2441db2661ceSRobert Watson     struct label *label, acl_type_t type, struct acl *acl)
2442db2661ceSRobert Watson {
2443db2661ceSRobert Watson 	struct mac_lomac *subj, *obj;
2444db2661ceSRobert Watson 
2445db2661ceSRobert Watson 	if (!mac_lomac_enabled)
2446db2661ceSRobert Watson 		return (0);
2447db2661ceSRobert Watson 
2448eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
2449db2661ceSRobert Watson 	obj = SLOT(label);
2450db2661ceSRobert Watson 
2451db2661ceSRobert Watson 	if (!mac_lomac_subject_dominate(subj, obj))
2452db2661ceSRobert Watson 		return (EACCES);
2453db2661ceSRobert Watson 
2454db2661ceSRobert Watson 	return (0);
2455db2661ceSRobert Watson }
2456db2661ceSRobert Watson 
2457db2661ceSRobert Watson static int
2458db2661ceSRobert Watson mac_lomac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
2459db2661ceSRobert Watson     struct label *vnodelabel, int attrnamespace, const char *name,
2460db2661ceSRobert Watson     struct uio *uio)
2461db2661ceSRobert Watson {
2462db2661ceSRobert Watson 	struct mac_lomac *subj, *obj;
2463db2661ceSRobert Watson 
2464db2661ceSRobert Watson 	if (!mac_lomac_enabled)
2465db2661ceSRobert Watson 		return (0);
2466db2661ceSRobert Watson 
2467eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
2468db2661ceSRobert Watson 	obj = SLOT(vnodelabel);
2469db2661ceSRobert Watson 
2470db2661ceSRobert Watson 	if (!mac_lomac_subject_dominate(subj, obj))
2471db2661ceSRobert Watson 		return (EACCES);
2472db2661ceSRobert Watson 
2473db2661ceSRobert Watson 	/* XXX: protect the MAC EA in a special way? */
2474db2661ceSRobert Watson 
2475db2661ceSRobert Watson 	return (0);
2476db2661ceSRobert Watson }
2477db2661ceSRobert Watson 
2478db2661ceSRobert Watson static int
2479db2661ceSRobert Watson mac_lomac_check_vnode_setflags(struct ucred *cred, struct vnode *vp,
2480db2661ceSRobert Watson     struct label *vnodelabel, u_long flags)
2481db2661ceSRobert Watson {
2482db2661ceSRobert Watson 	struct mac_lomac *subj, *obj;
2483db2661ceSRobert Watson 
2484db2661ceSRobert Watson 	if (!mac_lomac_enabled)
2485db2661ceSRobert Watson 		return (0);
2486db2661ceSRobert Watson 
2487eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
2488db2661ceSRobert Watson 	obj = SLOT(vnodelabel);
2489db2661ceSRobert Watson 
2490db2661ceSRobert Watson 	if (!mac_lomac_subject_dominate(subj, obj))
2491db2661ceSRobert Watson 		return (EACCES);
2492db2661ceSRobert Watson 
2493db2661ceSRobert Watson 	return (0);
2494db2661ceSRobert Watson }
2495db2661ceSRobert Watson 
2496db2661ceSRobert Watson static int
2497db2661ceSRobert Watson mac_lomac_check_vnode_setmode(struct ucred *cred, struct vnode *vp,
2498db2661ceSRobert Watson     struct label *vnodelabel, mode_t mode)
2499db2661ceSRobert Watson {
2500db2661ceSRobert Watson 	struct mac_lomac *subj, *obj;
2501db2661ceSRobert Watson 
2502db2661ceSRobert Watson 	if (!mac_lomac_enabled)
2503db2661ceSRobert Watson 		return (0);
2504db2661ceSRobert Watson 
2505eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
2506db2661ceSRobert Watson 	obj = SLOT(vnodelabel);
2507db2661ceSRobert Watson 
2508db2661ceSRobert Watson 	if (!mac_lomac_subject_dominate(subj, obj))
2509db2661ceSRobert Watson 		return (EACCES);
2510db2661ceSRobert Watson 
2511db2661ceSRobert Watson 	return (0);
2512db2661ceSRobert Watson }
2513db2661ceSRobert Watson 
2514db2661ceSRobert Watson static int
2515db2661ceSRobert Watson mac_lomac_check_vnode_setowner(struct ucred *cred, struct vnode *vp,
2516db2661ceSRobert Watson     struct label *vnodelabel, uid_t uid, gid_t gid)
2517db2661ceSRobert Watson {
2518db2661ceSRobert Watson 	struct mac_lomac *subj, *obj;
2519db2661ceSRobert Watson 
2520db2661ceSRobert Watson 	if (!mac_lomac_enabled)
2521db2661ceSRobert Watson 		return (0);
2522db2661ceSRobert Watson 
2523eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
2524db2661ceSRobert Watson 	obj = SLOT(vnodelabel);
2525db2661ceSRobert Watson 
2526db2661ceSRobert Watson 	if (!mac_lomac_subject_dominate(subj, obj))
2527db2661ceSRobert Watson 		return (EACCES);
2528db2661ceSRobert Watson 
2529db2661ceSRobert Watson 	return (0);
2530db2661ceSRobert Watson }
2531db2661ceSRobert Watson 
2532db2661ceSRobert Watson static int
2533db2661ceSRobert Watson mac_lomac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
2534db2661ceSRobert Watson     struct label *vnodelabel, struct timespec atime, struct timespec mtime)
2535db2661ceSRobert Watson {
2536db2661ceSRobert Watson 	struct mac_lomac *subj, *obj;
2537db2661ceSRobert Watson 
2538db2661ceSRobert Watson 	if (!mac_lomac_enabled)
2539db2661ceSRobert Watson 		return (0);
2540db2661ceSRobert Watson 
2541eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
2542db2661ceSRobert Watson 	obj = SLOT(vnodelabel);
2543db2661ceSRobert Watson 
2544db2661ceSRobert Watson 	if (!mac_lomac_subject_dominate(subj, obj))
2545db2661ceSRobert Watson 		return (EACCES);
2546db2661ceSRobert Watson 
2547db2661ceSRobert Watson 	return (0);
2548db2661ceSRobert Watson }
2549db2661ceSRobert Watson 
2550db2661ceSRobert Watson static int
2551db2661ceSRobert Watson mac_lomac_check_vnode_write(struct ucred *active_cred,
2552db2661ceSRobert Watson     struct ucred *file_cred, struct vnode *vp, struct label *label)
2553db2661ceSRobert Watson {
2554db2661ceSRobert Watson 	struct mac_lomac *subj, *obj;
2555db2661ceSRobert Watson 
2556db2661ceSRobert Watson 	if (!mac_lomac_enabled || !revocation_enabled)
2557db2661ceSRobert Watson 		return (0);
2558db2661ceSRobert Watson 
2559eca8a663SRobert Watson 	subj = SLOT(active_cred->cr_label);
2560db2661ceSRobert Watson 	obj = SLOT(label);
2561db2661ceSRobert Watson 
2562db2661ceSRobert Watson 	if (!mac_lomac_subject_dominate(subj, obj))
2563db2661ceSRobert Watson 		return (EACCES);
2564db2661ceSRobert Watson 
2565db2661ceSRobert Watson 	return (0);
2566db2661ceSRobert Watson }
2567db2661ceSRobert Watson 
2568db2661ceSRobert Watson static void
2569db2661ceSRobert Watson mac_lomac_thread_userret(struct thread *td)
2570db2661ceSRobert Watson {
2571db2661ceSRobert Watson 	struct proc *p = td->td_proc;
2572eca8a663SRobert Watson 	struct mac_lomac_proc *subj = PSLOT(p->p_label);
2573db2661ceSRobert Watson 	struct ucred *newcred, *oldcred;
2574db2661ceSRobert Watson 	int dodrop;
2575db2661ceSRobert Watson 
2576db2661ceSRobert Watson 	mtx_lock(&subj->mtx);
2577db2661ceSRobert Watson 	if (subj->mac_lomac.ml_flags & MAC_LOMAC_FLAG_UPDATE) {
2578db2661ceSRobert Watson 		dodrop = 0;
2579db2661ceSRobert Watson 		mtx_unlock(&subj->mtx);
2580db2661ceSRobert Watson 		newcred = crget();
2581db2661ceSRobert Watson 		/*
2582db2661ceSRobert Watson 		 * Prevent a lock order reversal in
2583db2661ceSRobert Watson 		 * mac_cred_mmapped_drop_perms; ideally, the other
2584db2661ceSRobert Watson 		 * user of subj->mtx wouldn't be holding Giant.
2585db2661ceSRobert Watson 		 */
2586db2661ceSRobert Watson 		mtx_lock(&Giant);
2587db2661ceSRobert Watson 		PROC_LOCK(p);
2588db2661ceSRobert Watson 		mtx_lock(&subj->mtx);
2589db2661ceSRobert Watson 		/*
2590db2661ceSRobert Watson 		 * Check if we lost the race while allocating the cred.
2591db2661ceSRobert Watson 		 */
2592db2661ceSRobert Watson 		if ((subj->mac_lomac.ml_flags & MAC_LOMAC_FLAG_UPDATE) == 0) {
2593db2661ceSRobert Watson 			crfree(newcred);
2594db2661ceSRobert Watson 			goto out;
2595db2661ceSRobert Watson 		}
2596db2661ceSRobert Watson 		oldcred = p->p_ucred;
2597db2661ceSRobert Watson 		crcopy(newcred, oldcred);
2598db2661ceSRobert Watson 		crhold(newcred);
2599eca8a663SRobert Watson 		mac_lomac_copy(&subj->mac_lomac, SLOT(newcred->cr_label));
2600db2661ceSRobert Watson 		p->p_ucred = newcred;
2601db2661ceSRobert Watson 		crfree(oldcred);
2602db2661ceSRobert Watson 		dodrop = 1;
2603db2661ceSRobert Watson 	out:
2604db2661ceSRobert Watson 		mtx_unlock(&subj->mtx);
2605db2661ceSRobert Watson 		PROC_UNLOCK(p);
2606db2661ceSRobert Watson 		if (dodrop)
2607db2661ceSRobert Watson 			mac_cred_mmapped_drop_perms(curthread, newcred);
2608db2661ceSRobert Watson 		mtx_unlock(&Giant);
2609db2661ceSRobert Watson 	} else {
2610db2661ceSRobert Watson 		mtx_unlock(&subj->mtx);
2611db2661ceSRobert Watson 	}
2612db2661ceSRobert Watson }
2613db2661ceSRobert Watson 
2614db2661ceSRobert Watson static struct mac_policy_ops mac_lomac_ops =
2615db2661ceSRobert Watson {
2616db2661ceSRobert Watson 	.mpo_init = mac_lomac_init,
2617db2661ceSRobert Watson 	.mpo_init_bpfdesc_label = mac_lomac_init_label,
2618db2661ceSRobert Watson 	.mpo_init_cred_label = mac_lomac_init_label,
2619db2661ceSRobert Watson 	.mpo_init_devfsdirent_label = mac_lomac_init_label,
2620db2661ceSRobert Watson 	.mpo_init_ifnet_label = mac_lomac_init_label,
2621a557af22SRobert Watson 	.mpo_init_inpcb_label = mac_lomac_init_label_waitcheck,
26225e7ce478SRobert Watson 	.mpo_init_ipq_label = mac_lomac_init_label_waitcheck,
2623db2661ceSRobert Watson 	.mpo_init_mbuf_label = mac_lomac_init_label_waitcheck,
2624db2661ceSRobert Watson 	.mpo_init_mount_label = mac_lomac_init_label,
2625db2661ceSRobert Watson 	.mpo_init_mount_fs_label = mac_lomac_init_label,
2626db2661ceSRobert Watson 	.mpo_init_pipe_label = mac_lomac_init_label,
2627db2661ceSRobert Watson 	.mpo_init_proc_label = mac_lomac_init_proc_label,
2628db2661ceSRobert Watson 	.mpo_init_socket_label = mac_lomac_init_label_waitcheck,
2629db2661ceSRobert Watson 	.mpo_init_socket_peer_label = mac_lomac_init_label_waitcheck,
2630db2661ceSRobert Watson 	.mpo_init_vnode_label = mac_lomac_init_label,
2631db2661ceSRobert Watson 	.mpo_destroy_bpfdesc_label = mac_lomac_destroy_label,
2632db2661ceSRobert Watson 	.mpo_destroy_cred_label = mac_lomac_destroy_label,
2633db2661ceSRobert Watson 	.mpo_destroy_devfsdirent_label = mac_lomac_destroy_label,
2634db2661ceSRobert Watson 	.mpo_destroy_ifnet_label = mac_lomac_destroy_label,
2635a557af22SRobert Watson 	.mpo_destroy_inpcb_label = mac_lomac_destroy_label,
2636db2661ceSRobert Watson 	.mpo_destroy_ipq_label = mac_lomac_destroy_label,
2637db2661ceSRobert Watson 	.mpo_destroy_mbuf_label = mac_lomac_destroy_label,
2638db2661ceSRobert Watson 	.mpo_destroy_mount_label = mac_lomac_destroy_label,
2639db2661ceSRobert Watson 	.mpo_destroy_mount_fs_label = mac_lomac_destroy_label,
2640db2661ceSRobert Watson 	.mpo_destroy_pipe_label = mac_lomac_destroy_label,
2641db2661ceSRobert Watson 	.mpo_destroy_proc_label = mac_lomac_destroy_proc_label,
2642db2661ceSRobert Watson 	.mpo_destroy_socket_label = mac_lomac_destroy_label,
2643db2661ceSRobert Watson 	.mpo_destroy_socket_peer_label = mac_lomac_destroy_label,
2644db2661ceSRobert Watson 	.mpo_destroy_vnode_label = mac_lomac_destroy_label,
264556d9e932SRobert Watson 	.mpo_copy_cred_label = mac_lomac_copy_label,
2646985a0d97SRobert Watson 	.mpo_copy_mbuf_label = mac_lomac_copy_label,
2647db2661ceSRobert Watson 	.mpo_copy_pipe_label = mac_lomac_copy_label,
2648b0323ea3SRobert Watson 	.mpo_copy_socket_label = mac_lomac_copy_label,
2649db2661ceSRobert Watson 	.mpo_copy_vnode_label = mac_lomac_copy_label,
2650db2661ceSRobert Watson 	.mpo_externalize_cred_label = mac_lomac_externalize_label,
2651db2661ceSRobert Watson 	.mpo_externalize_ifnet_label = mac_lomac_externalize_label,
2652db2661ceSRobert Watson 	.mpo_externalize_pipe_label = mac_lomac_externalize_label,
2653db2661ceSRobert Watson 	.mpo_externalize_socket_label = mac_lomac_externalize_label,
2654db2661ceSRobert Watson 	.mpo_externalize_socket_peer_label = mac_lomac_externalize_label,
2655db2661ceSRobert Watson 	.mpo_externalize_vnode_label = mac_lomac_externalize_label,
2656db2661ceSRobert Watson 	.mpo_internalize_cred_label = mac_lomac_internalize_label,
2657db2661ceSRobert Watson 	.mpo_internalize_ifnet_label = mac_lomac_internalize_label,
2658db2661ceSRobert Watson 	.mpo_internalize_pipe_label = mac_lomac_internalize_label,
2659db2661ceSRobert Watson 	.mpo_internalize_socket_label = mac_lomac_internalize_label,
2660db2661ceSRobert Watson 	.mpo_internalize_vnode_label = mac_lomac_internalize_label,
2661db2661ceSRobert Watson 	.mpo_create_devfs_device = mac_lomac_create_devfs_device,
2662db2661ceSRobert Watson 	.mpo_create_devfs_directory = mac_lomac_create_devfs_directory,
2663db2661ceSRobert Watson 	.mpo_create_devfs_symlink = mac_lomac_create_devfs_symlink,
2664db2661ceSRobert Watson 	.mpo_create_mount = mac_lomac_create_mount,
2665db2661ceSRobert Watson 	.mpo_create_root_mount = mac_lomac_create_root_mount,
2666db2661ceSRobert Watson 	.mpo_relabel_vnode = mac_lomac_relabel_vnode,
2667db2661ceSRobert Watson 	.mpo_update_devfsdirent = mac_lomac_update_devfsdirent,
2668db2661ceSRobert Watson 	.mpo_associate_vnode_devfs = mac_lomac_associate_vnode_devfs,
2669db2661ceSRobert Watson 	.mpo_associate_vnode_extattr = mac_lomac_associate_vnode_extattr,
2670db2661ceSRobert Watson 	.mpo_associate_vnode_singlelabel =
2671db2661ceSRobert Watson 	    mac_lomac_associate_vnode_singlelabel,
2672db2661ceSRobert Watson 	.mpo_create_vnode_extattr = mac_lomac_create_vnode_extattr,
2673db2661ceSRobert Watson 	.mpo_setlabel_vnode_extattr = mac_lomac_setlabel_vnode_extattr,
2674db2661ceSRobert Watson 	.mpo_create_mbuf_from_socket = mac_lomac_create_mbuf_from_socket,
2675db2661ceSRobert Watson 	.mpo_create_pipe = mac_lomac_create_pipe,
2676db2661ceSRobert Watson 	.mpo_create_socket = mac_lomac_create_socket,
2677db2661ceSRobert Watson 	.mpo_create_socket_from_socket = mac_lomac_create_socket_from_socket,
2678db2661ceSRobert Watson 	.mpo_relabel_pipe = mac_lomac_relabel_pipe,
2679db2661ceSRobert Watson 	.mpo_relabel_socket = mac_lomac_relabel_socket,
2680db2661ceSRobert Watson 	.mpo_set_socket_peer_from_mbuf = mac_lomac_set_socket_peer_from_mbuf,
2681db2661ceSRobert Watson 	.mpo_set_socket_peer_from_socket =
2682db2661ceSRobert Watson 	    mac_lomac_set_socket_peer_from_socket,
2683db2661ceSRobert Watson 	.mpo_create_bpfdesc = mac_lomac_create_bpfdesc,
2684db2661ceSRobert Watson 	.mpo_create_datagram_from_ipq = mac_lomac_create_datagram_from_ipq,
2685db2661ceSRobert Watson 	.mpo_create_fragment = mac_lomac_create_fragment,
2686db2661ceSRobert Watson 	.mpo_create_ifnet = mac_lomac_create_ifnet,
2687a557af22SRobert Watson 	.mpo_create_inpcb_from_socket = mac_lomac_create_inpcb_from_socket,
2688db2661ceSRobert Watson 	.mpo_create_ipq = mac_lomac_create_ipq,
26892d92ec98SRobert Watson 	.mpo_create_mbuf_from_inpcb = mac_lomac_create_mbuf_from_inpcb,
2690db2661ceSRobert Watson 	.mpo_create_mbuf_from_mbuf = mac_lomac_create_mbuf_from_mbuf,
2691db2661ceSRobert Watson 	.mpo_create_mbuf_linklayer = mac_lomac_create_mbuf_linklayer,
2692db2661ceSRobert Watson 	.mpo_create_mbuf_from_bpfdesc = mac_lomac_create_mbuf_from_bpfdesc,
2693db2661ceSRobert Watson 	.mpo_create_mbuf_from_ifnet = mac_lomac_create_mbuf_from_ifnet,
2694db2661ceSRobert Watson 	.mpo_create_mbuf_multicast_encap =
2695db2661ceSRobert Watson 	    mac_lomac_create_mbuf_multicast_encap,
2696db2661ceSRobert Watson 	.mpo_create_mbuf_netlayer = mac_lomac_create_mbuf_netlayer,
2697db2661ceSRobert Watson 	.mpo_fragment_match = mac_lomac_fragment_match,
2698db2661ceSRobert Watson 	.mpo_relabel_ifnet = mac_lomac_relabel_ifnet,
2699db2661ceSRobert Watson 	.mpo_update_ipq = mac_lomac_update_ipq,
2700a557af22SRobert Watson 	.mpo_inpcb_sosetlabel = mac_lomac_inpcb_sosetlabel,
2701db2661ceSRobert Watson 	.mpo_execve_transition = mac_lomac_execve_transition,
2702db2661ceSRobert Watson 	.mpo_execve_will_transition = mac_lomac_execve_will_transition,
2703db2661ceSRobert Watson 	.mpo_create_proc0 = mac_lomac_create_proc0,
2704db2661ceSRobert Watson 	.mpo_create_proc1 = mac_lomac_create_proc1,
2705db2661ceSRobert Watson 	.mpo_relabel_cred = mac_lomac_relabel_cred,
2706db2661ceSRobert Watson 	.mpo_check_bpfdesc_receive = mac_lomac_check_bpfdesc_receive,
2707db2661ceSRobert Watson 	.mpo_check_cred_relabel = mac_lomac_check_cred_relabel,
2708db2661ceSRobert Watson 	.mpo_check_cred_visible = mac_lomac_check_cred_visible,
2709db2661ceSRobert Watson 	.mpo_check_ifnet_relabel = mac_lomac_check_ifnet_relabel,
2710db2661ceSRobert Watson 	.mpo_check_ifnet_transmit = mac_lomac_check_ifnet_transmit,
2711a557af22SRobert Watson 	.mpo_check_inpcb_deliver = mac_lomac_check_inpcb_deliver,
2712db2661ceSRobert Watson 	.mpo_check_kld_load = mac_lomac_check_kld_load,
2713db2661ceSRobert Watson 	.mpo_check_kld_unload = mac_lomac_check_kld_unload,
2714db2661ceSRobert Watson 	.mpo_check_pipe_ioctl = mac_lomac_check_pipe_ioctl,
2715db2661ceSRobert Watson 	.mpo_check_pipe_read = mac_lomac_check_pipe_read,
2716db2661ceSRobert Watson 	.mpo_check_pipe_relabel = mac_lomac_check_pipe_relabel,
2717db2661ceSRobert Watson 	.mpo_check_pipe_write = mac_lomac_check_pipe_write,
2718db2661ceSRobert Watson 	.mpo_check_proc_debug = mac_lomac_check_proc_debug,
2719db2661ceSRobert Watson 	.mpo_check_proc_sched = mac_lomac_check_proc_sched,
2720db2661ceSRobert Watson 	.mpo_check_proc_signal = mac_lomac_check_proc_signal,
2721db2661ceSRobert Watson 	.mpo_check_socket_deliver = mac_lomac_check_socket_deliver,
2722db2661ceSRobert Watson 	.mpo_check_socket_relabel = mac_lomac_check_socket_relabel,
2723db2661ceSRobert Watson 	.mpo_check_socket_visible = mac_lomac_check_socket_visible,
2724db2661ceSRobert Watson 	.mpo_check_system_swapon = mac_lomac_check_system_swapon,
2725db2661ceSRobert Watson 	.mpo_check_system_sysctl = mac_lomac_check_system_sysctl,
2726db2661ceSRobert Watson 	.mpo_check_vnode_access = mac_lomac_check_vnode_open,
2727db2661ceSRobert Watson 	.mpo_check_vnode_create = mac_lomac_check_vnode_create,
2728db2661ceSRobert Watson 	.mpo_check_vnode_delete = mac_lomac_check_vnode_delete,
2729db2661ceSRobert Watson 	.mpo_check_vnode_deleteacl = mac_lomac_check_vnode_deleteacl,
2730db2661ceSRobert Watson 	.mpo_check_vnode_link = mac_lomac_check_vnode_link,
2731db2661ceSRobert Watson 	.mpo_check_vnode_mmap = mac_lomac_check_vnode_mmap,
2732db2661ceSRobert Watson 	.mpo_check_vnode_mmap_downgrade = mac_lomac_check_vnode_mmap_downgrade,
2733db2661ceSRobert Watson 	.mpo_check_vnode_mprotect = mac_lomac_check_vnode_mprotect,
2734db2661ceSRobert Watson 	.mpo_check_vnode_open = mac_lomac_check_vnode_open,
2735db2661ceSRobert Watson 	.mpo_check_vnode_read = mac_lomac_check_vnode_read,
2736db2661ceSRobert Watson 	.mpo_check_vnode_relabel = mac_lomac_check_vnode_relabel,
2737db2661ceSRobert Watson 	.mpo_check_vnode_rename_from = mac_lomac_check_vnode_rename_from,
2738db2661ceSRobert Watson 	.mpo_check_vnode_rename_to = mac_lomac_check_vnode_rename_to,
2739db2661ceSRobert Watson 	.mpo_check_vnode_revoke = mac_lomac_check_vnode_revoke,
2740db2661ceSRobert Watson 	.mpo_check_vnode_setacl = mac_lomac_check_vnode_setacl,
2741db2661ceSRobert Watson 	.mpo_check_vnode_setextattr = mac_lomac_check_vnode_setextattr,
2742db2661ceSRobert Watson 	.mpo_check_vnode_setflags = mac_lomac_check_vnode_setflags,
2743db2661ceSRobert Watson 	.mpo_check_vnode_setmode = mac_lomac_check_vnode_setmode,
2744db2661ceSRobert Watson 	.mpo_check_vnode_setowner = mac_lomac_check_vnode_setowner,
2745db2661ceSRobert Watson 	.mpo_check_vnode_setutimes = mac_lomac_check_vnode_setutimes,
2746db2661ceSRobert Watson 	.mpo_check_vnode_write = mac_lomac_check_vnode_write,
2747db2661ceSRobert Watson 	.mpo_thread_userret = mac_lomac_thread_userret,
2748db2661ceSRobert Watson };
2749db2661ceSRobert Watson 
2750db2661ceSRobert Watson MAC_POLICY_SET(&mac_lomac_ops, mac_lomac, "TrustedBSD MAC/LOMAC",
2751aa6a0037SRobert Watson     MPC_LOADTIME_FLAG_NOTLATE | MPC_LOADTIME_FLAG_LABELMBUFS,
2752aa6a0037SRobert Watson     &mac_lomac_slot);
2753