xref: /freebsd/sys/security/mac_lomac/mac_lomac.c (revision 78007886c995898a9494648343e5236bca1cbba3)
1db2661ceSRobert Watson /*-
218717f69SRobert Watson  * Copyright (c) 1999-2002, 2007 Robert N. M. Watson
3c77cf2b1SRobert Watson  * Copyright (c) 2001-2005 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.
39c14d15aeSRobert Watson  *
40db2661ceSRobert Watson  * Low-watermark floating label mandatory integrity policy.
41db2661ceSRobert Watson  */
42db2661ceSRobert Watson 
43db2661ceSRobert Watson #include <sys/types.h>
44db2661ceSRobert Watson #include <sys/param.h>
45db2661ceSRobert Watson #include <sys/acl.h>
46db2661ceSRobert Watson #include <sys/conf.h>
47db2661ceSRobert Watson #include <sys/extattr.h>
48db2661ceSRobert Watson #include <sys/kernel.h>
49db2661ceSRobert Watson #include <sys/malloc.h>
50c92163dcSChristian S.J. Peron #include <sys/mman.h>
51db2661ceSRobert Watson #include <sys/mount.h>
52acd3428bSRobert Watson #include <sys/priv.h>
53db2661ceSRobert Watson #include <sys/proc.h>
54f51e5803SRobert Watson #include <sys/sbuf.h>
55db2661ceSRobert Watson #include <sys/systm.h>
56db2661ceSRobert Watson #include <sys/sysproto.h>
57db2661ceSRobert Watson #include <sys/sysent.h>
58db2661ceSRobert Watson #include <sys/systm.h>
59db2661ceSRobert Watson #include <sys/vnode.h>
60db2661ceSRobert Watson #include <sys/file.h>
61db2661ceSRobert Watson #include <sys/socket.h>
62db2661ceSRobert Watson #include <sys/socketvar.h>
6336422989SPoul-Henning Kamp #include <sys/sx.h>
64db2661ceSRobert Watson #include <sys/pipe.h>
65db2661ceSRobert Watson #include <sys/sysctl.h>
66db2661ceSRobert Watson #include <sys/syslog.h>
67db2661ceSRobert Watson 
68db2661ceSRobert Watson #include <fs/devfs/devfs.h>
69db2661ceSRobert Watson 
70db2661ceSRobert Watson #include <net/bpfdesc.h>
71db2661ceSRobert Watson #include <net/if.h>
72db2661ceSRobert Watson #include <net/if_types.h>
73db2661ceSRobert Watson #include <net/if_var.h>
74db2661ceSRobert Watson 
75db2661ceSRobert Watson #include <netinet/in.h>
76a557af22SRobert Watson #include <netinet/in_pcb.h>
77db2661ceSRobert Watson #include <netinet/ip_var.h>
78db2661ceSRobert Watson 
79db2661ceSRobert Watson #include <vm/vm.h>
80db2661ceSRobert Watson 
810efd6615SRobert Watson #include <security/mac/mac_policy.h>
82aed55708SRobert Watson #include <security/mac/mac_framework.h>
83db2661ceSRobert Watson #include <security/mac_lomac/mac_lomac.h>
84db2661ceSRobert Watson 
85db2661ceSRobert Watson struct mac_lomac_proc {
86db2661ceSRobert Watson 	struct mac_lomac mac_lomac;
87db2661ceSRobert Watson 	struct mtx mtx;
88db2661ceSRobert Watson };
89db2661ceSRobert Watson 
90db2661ceSRobert Watson SYSCTL_DECL(_security_mac);
91db2661ceSRobert Watson 
92db2661ceSRobert Watson SYSCTL_NODE(_security_mac, OID_AUTO, lomac, CTLFLAG_RW, 0,
93db2661ceSRobert Watson     "TrustedBSD mac_lomac policy controls");
94db2661ceSRobert Watson 
95db2661ceSRobert Watson static int	mac_lomac_label_size = sizeof(struct mac_lomac);
96db2661ceSRobert Watson SYSCTL_INT(_security_mac_lomac, OID_AUTO, label_size, CTLFLAG_RD,
97db2661ceSRobert Watson     &mac_lomac_label_size, 0, "Size of struct mac_lomac");
98db2661ceSRobert Watson 
99eba0370dSRobert Watson static int	mac_lomac_enabled = 1;
100db2661ceSRobert Watson SYSCTL_INT(_security_mac_lomac, OID_AUTO, enabled, CTLFLAG_RW,
101db2661ceSRobert Watson     &mac_lomac_enabled, 0, "Enforce MAC/LOMAC policy");
102db2661ceSRobert Watson TUNABLE_INT("security.mac.lomac.enabled", &mac_lomac_enabled);
103db2661ceSRobert Watson 
104db2661ceSRobert Watson static int	destroyed_not_inited;
105db2661ceSRobert Watson SYSCTL_INT(_security_mac_lomac, OID_AUTO, destroyed_not_inited, CTLFLAG_RD,
106db2661ceSRobert Watson     &destroyed_not_inited, 0, "Count of labels destroyed but not inited");
107db2661ceSRobert Watson 
108db2661ceSRobert Watson static int	trust_all_interfaces = 0;
109db2661ceSRobert Watson SYSCTL_INT(_security_mac_lomac, OID_AUTO, trust_all_interfaces, CTLFLAG_RD,
110db2661ceSRobert Watson     &trust_all_interfaces, 0, "Consider all interfaces 'trusted' by MAC/LOMAC");
111db2661ceSRobert Watson TUNABLE_INT("security.mac.lomac.trust_all_interfaces", &trust_all_interfaces);
112db2661ceSRobert Watson 
113db2661ceSRobert Watson static char	trusted_interfaces[128];
114db2661ceSRobert Watson SYSCTL_STRING(_security_mac_lomac, OID_AUTO, trusted_interfaces, CTLFLAG_RD,
115db2661ceSRobert Watson     trusted_interfaces, 0, "Interfaces considered 'trusted' by MAC/LOMAC");
116db2661ceSRobert Watson TUNABLE_STR("security.mac.lomac.trusted_interfaces", trusted_interfaces,
117db2661ceSRobert Watson     sizeof(trusted_interfaces));
118db2661ceSRobert Watson 
119db2661ceSRobert Watson static int	ptys_equal = 0;
120db2661ceSRobert Watson SYSCTL_INT(_security_mac_lomac, OID_AUTO, ptys_equal, CTLFLAG_RW,
121db2661ceSRobert Watson     &ptys_equal, 0, "Label pty devices as lomac/equal on create");
122db2661ceSRobert Watson TUNABLE_INT("security.mac.lomac.ptys_equal", &ptys_equal);
123db2661ceSRobert Watson 
124db2661ceSRobert Watson static int	revocation_enabled = 1;
125db2661ceSRobert Watson SYSCTL_INT(_security_mac_lomac, OID_AUTO, revocation_enabled, CTLFLAG_RW,
126db2661ceSRobert Watson     &revocation_enabled, 0, "Revoke access to objects on relabel");
127db2661ceSRobert Watson TUNABLE_INT("security.mac.lomac.revocation_enabled", &revocation_enabled);
128db2661ceSRobert Watson 
129db2661ceSRobert Watson static int	mac_lomac_slot;
1300142affcSRobert Watson #define	SLOT(l)	((struct mac_lomac *)mac_label_get((l), mac_lomac_slot))
1310142affcSRobert Watson #define	SLOT_SET(l, val) mac_label_set((l), mac_lomac_slot, (uintptr_t)(val))
132db2661ceSRobert Watson #define	PSLOT(l) ((struct mac_lomac_proc *)				\
1330142affcSRobert Watson     mac_label_get((l), mac_lomac_slot))
1340142affcSRobert Watson #define	PSLOT_SET(l, val) mac_label_set((l), mac_lomac_slot, (uintptr_t)(val))
135db2661ceSRobert Watson 
1365bb84bc8SRobert Watson MALLOC_DEFINE(M_MACLOMAC, "mac_lomac_label", "MAC/LOMAC labels");
137db2661ceSRobert Watson 
138db2661ceSRobert Watson static struct mac_lomac *
139db2661ceSRobert Watson lomac_alloc(int flag)
140db2661ceSRobert Watson {
141db2661ceSRobert Watson 	struct mac_lomac *mac_lomac;
142db2661ceSRobert Watson 
143db2661ceSRobert Watson 	mac_lomac = malloc(sizeof(struct mac_lomac), M_MACLOMAC, M_ZERO | flag);
144db2661ceSRobert Watson 
145db2661ceSRobert Watson 	return (mac_lomac);
146db2661ceSRobert Watson }
147db2661ceSRobert Watson 
148db2661ceSRobert Watson static void
149db2661ceSRobert Watson lomac_free(struct mac_lomac *mac_lomac)
150db2661ceSRobert Watson {
151db2661ceSRobert Watson 
152db2661ceSRobert Watson 	if (mac_lomac != NULL)
153db2661ceSRobert Watson 		free(mac_lomac, M_MACLOMAC);
154db2661ceSRobert Watson 	else
155db2661ceSRobert Watson 		atomic_add_int(&destroyed_not_inited, 1);
156db2661ceSRobert Watson }
157db2661ceSRobert Watson 
158db2661ceSRobert Watson static int
159db2661ceSRobert Watson lomac_atmostflags(struct mac_lomac *mac_lomac, int flags)
160db2661ceSRobert Watson {
161db2661ceSRobert Watson 
162db2661ceSRobert Watson 	if ((mac_lomac->ml_flags & flags) != mac_lomac->ml_flags)
163db2661ceSRobert Watson 		return (EINVAL);
164db2661ceSRobert Watson 	return (0);
165db2661ceSRobert Watson }
166db2661ceSRobert Watson 
167db2661ceSRobert Watson static int
168db2661ceSRobert Watson mac_lomac_dominate_element(struct mac_lomac_element *a,
169db2661ceSRobert Watson     struct mac_lomac_element *b)
170db2661ceSRobert Watson {
171db2661ceSRobert Watson 
172db2661ceSRobert Watson 	switch (a->mle_type) {
173db2661ceSRobert Watson 	case MAC_LOMAC_TYPE_EQUAL:
174db2661ceSRobert Watson 	case MAC_LOMAC_TYPE_HIGH:
175db2661ceSRobert Watson 		return (1);
176db2661ceSRobert Watson 
177db2661ceSRobert Watson 	case MAC_LOMAC_TYPE_LOW:
178db2661ceSRobert Watson 		switch (b->mle_type) {
179db2661ceSRobert Watson 		case MAC_LOMAC_TYPE_GRADE:
180db2661ceSRobert Watson 		case MAC_LOMAC_TYPE_HIGH:
181db2661ceSRobert Watson 			return (0);
182db2661ceSRobert Watson 
183db2661ceSRobert Watson 		case MAC_LOMAC_TYPE_EQUAL:
184db2661ceSRobert Watson 		case MAC_LOMAC_TYPE_LOW:
185db2661ceSRobert Watson 			return (1);
186db2661ceSRobert Watson 
187db2661ceSRobert Watson 		default:
188db2661ceSRobert Watson 			panic("mac_lomac_dominate_element: b->mle_type invalid");
189db2661ceSRobert Watson 		}
190db2661ceSRobert Watson 
191db2661ceSRobert Watson 	case MAC_LOMAC_TYPE_GRADE:
192db2661ceSRobert Watson 		switch (b->mle_type) {
193db2661ceSRobert Watson 		case MAC_LOMAC_TYPE_EQUAL:
194db2661ceSRobert Watson 		case MAC_LOMAC_TYPE_LOW:
195db2661ceSRobert Watson 			return (1);
196db2661ceSRobert Watson 
197db2661ceSRobert Watson 		case MAC_LOMAC_TYPE_HIGH:
198db2661ceSRobert Watson 			return (0);
199db2661ceSRobert Watson 
200db2661ceSRobert Watson 		case MAC_LOMAC_TYPE_GRADE:
201db2661ceSRobert Watson 			return (a->mle_grade >= b->mle_grade);
202db2661ceSRobert Watson 
203db2661ceSRobert Watson 		default:
204db2661ceSRobert Watson 			panic("mac_lomac_dominate_element: b->mle_type invalid");
205db2661ceSRobert Watson 		}
206db2661ceSRobert Watson 
207db2661ceSRobert Watson 	default:
208db2661ceSRobert Watson 		panic("mac_lomac_dominate_element: a->mle_type invalid");
209db2661ceSRobert Watson 	}
210db2661ceSRobert Watson }
211db2661ceSRobert Watson 
212db2661ceSRobert Watson static int
213db2661ceSRobert Watson mac_lomac_range_in_range(struct mac_lomac *rangea, struct mac_lomac *rangeb)
214db2661ceSRobert Watson {
215db2661ceSRobert Watson 
216db2661ceSRobert Watson 	return (mac_lomac_dominate_element(&rangeb->ml_rangehigh,
217db2661ceSRobert Watson 	    &rangea->ml_rangehigh) &&
218db2661ceSRobert Watson 	    mac_lomac_dominate_element(&rangea->ml_rangelow,
219db2661ceSRobert Watson 	    &rangeb->ml_rangelow));
220db2661ceSRobert Watson }
221db2661ceSRobert Watson 
222db2661ceSRobert Watson static int
223db2661ceSRobert Watson mac_lomac_single_in_range(struct mac_lomac *single, struct mac_lomac *range)
224db2661ceSRobert Watson {
225db2661ceSRobert Watson 
226db2661ceSRobert Watson 	KASSERT((single->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0,
227db2661ceSRobert Watson 	    ("mac_lomac_single_in_range: a not single"));
228db2661ceSRobert Watson 	KASSERT((range->ml_flags & MAC_LOMAC_FLAG_RANGE) != 0,
229db2661ceSRobert Watson 	    ("mac_lomac_single_in_range: b not range"));
230db2661ceSRobert Watson 
231db2661ceSRobert Watson 	return (mac_lomac_dominate_element(&range->ml_rangehigh,
232db2661ceSRobert Watson 	    &single->ml_single) &&
233db2661ceSRobert Watson 	    mac_lomac_dominate_element(&single->ml_single,
234db2661ceSRobert Watson 	    &range->ml_rangelow));
235db2661ceSRobert Watson }
236db2661ceSRobert Watson 
237db2661ceSRobert Watson static int
238db2661ceSRobert Watson mac_lomac_auxsingle_in_range(struct mac_lomac *single, struct mac_lomac *range)
239db2661ceSRobert Watson {
240db2661ceSRobert Watson 
241db2661ceSRobert Watson 	KASSERT((single->ml_flags & MAC_LOMAC_FLAG_AUX) != 0,
242db2661ceSRobert Watson 	    ("mac_lomac_single_in_range: a not auxsingle"));
243db2661ceSRobert Watson 	KASSERT((range->ml_flags & MAC_LOMAC_FLAG_RANGE) != 0,
244db2661ceSRobert Watson 	    ("mac_lomac_single_in_range: b not range"));
245db2661ceSRobert Watson 
246db2661ceSRobert Watson 	return (mac_lomac_dominate_element(&range->ml_rangehigh,
247db2661ceSRobert Watson 	    &single->ml_auxsingle) &&
248db2661ceSRobert Watson 	    mac_lomac_dominate_element(&single->ml_auxsingle,
249db2661ceSRobert Watson 	    &range->ml_rangelow));
250db2661ceSRobert Watson }
251db2661ceSRobert Watson 
252db2661ceSRobert Watson static int
253db2661ceSRobert Watson mac_lomac_dominate_single(struct mac_lomac *a, struct mac_lomac *b)
254db2661ceSRobert Watson {
255db2661ceSRobert Watson 	KASSERT((a->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0,
256db2661ceSRobert Watson 	    ("mac_lomac_dominate_single: a not single"));
257db2661ceSRobert Watson 	KASSERT((b->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0,
258db2661ceSRobert Watson 	    ("mac_lomac_dominate_single: b not single"));
259db2661ceSRobert Watson 
260db2661ceSRobert Watson 	return (mac_lomac_dominate_element(&a->ml_single, &b->ml_single));
261db2661ceSRobert Watson }
262db2661ceSRobert Watson 
263db2661ceSRobert Watson static int
264db2661ceSRobert Watson mac_lomac_subject_dominate(struct mac_lomac *a, struct mac_lomac *b)
265db2661ceSRobert Watson {
266db2661ceSRobert Watson 	KASSERT((~a->ml_flags &
267db2661ceSRobert Watson 	    (MAC_LOMAC_FLAG_SINGLE | MAC_LOMAC_FLAG_RANGE)) == 0,
268db2661ceSRobert Watson 	    ("mac_lomac_dominate_single: a not subject"));
269db2661ceSRobert Watson 	KASSERT((b->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0,
270db2661ceSRobert Watson 	    ("mac_lomac_dominate_single: b not single"));
271db2661ceSRobert Watson 
272db2661ceSRobert Watson 	return (mac_lomac_dominate_element(&a->ml_rangehigh,
273db2661ceSRobert Watson 	    &b->ml_single));
274db2661ceSRobert Watson }
275db2661ceSRobert Watson 
276db2661ceSRobert Watson static int
277db2661ceSRobert Watson mac_lomac_equal_element(struct mac_lomac_element *a, struct mac_lomac_element *b)
278db2661ceSRobert Watson {
279db2661ceSRobert Watson 
280db2661ceSRobert Watson 	if (a->mle_type == MAC_LOMAC_TYPE_EQUAL ||
281db2661ceSRobert Watson 	    b->mle_type == MAC_LOMAC_TYPE_EQUAL)
282db2661ceSRobert Watson 		return (1);
283db2661ceSRobert Watson 
284db2661ceSRobert Watson 	return (a->mle_type == b->mle_type && a->mle_grade == b->mle_grade);
285db2661ceSRobert Watson }
286db2661ceSRobert Watson 
287db2661ceSRobert Watson static int
288db2661ceSRobert Watson mac_lomac_equal_single(struct mac_lomac *a, struct mac_lomac *b)
289db2661ceSRobert Watson {
290db2661ceSRobert Watson 
291db2661ceSRobert Watson 	KASSERT((a->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0,
292db2661ceSRobert Watson 	    ("mac_lomac_equal_single: a not single"));
293db2661ceSRobert Watson 	KASSERT((b->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0,
294db2661ceSRobert Watson 	    ("mac_lomac_equal_single: b not single"));
295db2661ceSRobert Watson 
296db2661ceSRobert Watson 	return (mac_lomac_equal_element(&a->ml_single, &b->ml_single));
297db2661ceSRobert Watson }
298db2661ceSRobert Watson 
299db2661ceSRobert Watson static int
300db2661ceSRobert Watson mac_lomac_contains_equal(struct mac_lomac *mac_lomac)
301db2661ceSRobert Watson {
302db2661ceSRobert Watson 
303db2661ceSRobert Watson 	if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_SINGLE)
304db2661ceSRobert Watson 		if (mac_lomac->ml_single.mle_type == MAC_LOMAC_TYPE_EQUAL)
305db2661ceSRobert Watson 			return (1);
306db2661ceSRobert Watson 	if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_AUX)
307db2661ceSRobert Watson 		if (mac_lomac->ml_auxsingle.mle_type == MAC_LOMAC_TYPE_EQUAL)
308db2661ceSRobert Watson 			return (1);
309db2661ceSRobert Watson 
310db2661ceSRobert Watson 	if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_RANGE) {
311db2661ceSRobert Watson 		if (mac_lomac->ml_rangelow.mle_type == MAC_LOMAC_TYPE_EQUAL)
312db2661ceSRobert Watson 			return (1);
313db2661ceSRobert Watson 		if (mac_lomac->ml_rangehigh.mle_type == MAC_LOMAC_TYPE_EQUAL)
314db2661ceSRobert Watson 			return (1);
315db2661ceSRobert Watson 	}
316db2661ceSRobert Watson 
317db2661ceSRobert Watson 	return (0);
318db2661ceSRobert Watson }
319db2661ceSRobert Watson 
320db2661ceSRobert Watson static int
321db2661ceSRobert Watson mac_lomac_subject_privileged(struct mac_lomac *mac_lomac)
322db2661ceSRobert Watson {
323db2661ceSRobert Watson 
324db2661ceSRobert Watson 	KASSERT((mac_lomac->ml_flags & MAC_LOMAC_FLAGS_BOTH) ==
325db2661ceSRobert Watson 	    MAC_LOMAC_FLAGS_BOTH,
326db2661ceSRobert Watson 	    ("mac_lomac_subject_privileged: subject doesn't have both labels"));
327db2661ceSRobert Watson 
328db2661ceSRobert Watson 	/* If the single is EQUAL, it's ok. */
329db2661ceSRobert Watson 	if (mac_lomac->ml_single.mle_type == MAC_LOMAC_TYPE_EQUAL)
330db2661ceSRobert Watson 		return (0);
331db2661ceSRobert Watson 
332db2661ceSRobert Watson 	/* If either range endpoint is EQUAL, it's ok. */
333db2661ceSRobert Watson 	if (mac_lomac->ml_rangelow.mle_type == MAC_LOMAC_TYPE_EQUAL ||
334db2661ceSRobert Watson 	    mac_lomac->ml_rangehigh.mle_type == MAC_LOMAC_TYPE_EQUAL)
335db2661ceSRobert Watson 		return (0);
336db2661ceSRobert Watson 
337db2661ceSRobert Watson 	/* If the range is low-high, it's ok. */
338db2661ceSRobert Watson 	if (mac_lomac->ml_rangelow.mle_type == MAC_LOMAC_TYPE_LOW &&
339db2661ceSRobert Watson 	    mac_lomac->ml_rangehigh.mle_type == MAC_LOMAC_TYPE_HIGH)
340db2661ceSRobert Watson 		return (0);
341db2661ceSRobert Watson 
342db2661ceSRobert Watson 	/* It's not ok. */
343db2661ceSRobert Watson 	return (EPERM);
344db2661ceSRobert Watson }
345db2661ceSRobert Watson 
346db2661ceSRobert Watson static int
347db2661ceSRobert Watson mac_lomac_high_single(struct mac_lomac *mac_lomac)
348db2661ceSRobert Watson {
349db2661ceSRobert Watson 
350db2661ceSRobert Watson 	KASSERT((mac_lomac->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0,
351db2661ceSRobert Watson 	    ("mac_lomac_high_single: mac_lomac not single"));
352db2661ceSRobert Watson 
353db2661ceSRobert Watson 	return (mac_lomac->ml_single.mle_type == MAC_LOMAC_TYPE_HIGH);
354db2661ceSRobert Watson }
355db2661ceSRobert Watson 
356db2661ceSRobert Watson static int
357db2661ceSRobert Watson mac_lomac_valid(struct mac_lomac *mac_lomac)
358db2661ceSRobert Watson {
359db2661ceSRobert Watson 
360db2661ceSRobert Watson 	if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_SINGLE) {
361db2661ceSRobert Watson 		switch (mac_lomac->ml_single.mle_type) {
362db2661ceSRobert Watson 		case MAC_LOMAC_TYPE_GRADE:
363db2661ceSRobert Watson 		case MAC_LOMAC_TYPE_EQUAL:
364db2661ceSRobert Watson 		case MAC_LOMAC_TYPE_HIGH:
365db2661ceSRobert Watson 		case MAC_LOMAC_TYPE_LOW:
366db2661ceSRobert Watson 			break;
367db2661ceSRobert Watson 
368db2661ceSRobert Watson 		default:
369db2661ceSRobert Watson 			return (EINVAL);
370db2661ceSRobert Watson 		}
371db2661ceSRobert Watson 	} else {
372db2661ceSRobert Watson 		if (mac_lomac->ml_single.mle_type != MAC_LOMAC_TYPE_UNDEF)
373db2661ceSRobert Watson 			return (EINVAL);
374db2661ceSRobert Watson 	}
375db2661ceSRobert Watson 
376db2661ceSRobert Watson 	if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_AUX) {
377db2661ceSRobert Watson 		switch (mac_lomac->ml_auxsingle.mle_type) {
378db2661ceSRobert Watson 		case MAC_LOMAC_TYPE_GRADE:
379db2661ceSRobert Watson 		case MAC_LOMAC_TYPE_EQUAL:
380db2661ceSRobert Watson 		case MAC_LOMAC_TYPE_HIGH:
381db2661ceSRobert Watson 		case MAC_LOMAC_TYPE_LOW:
382db2661ceSRobert Watson 			break;
383db2661ceSRobert Watson 
384db2661ceSRobert Watson 		default:
385db2661ceSRobert Watson 			return (EINVAL);
386db2661ceSRobert Watson 		}
387db2661ceSRobert Watson 	} else {
388db2661ceSRobert Watson 		if (mac_lomac->ml_auxsingle.mle_type != MAC_LOMAC_TYPE_UNDEF)
389db2661ceSRobert Watson 			return (EINVAL);
390db2661ceSRobert Watson 	}
391db2661ceSRobert Watson 
392db2661ceSRobert Watson 	if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_RANGE) {
393db2661ceSRobert Watson 		switch (mac_lomac->ml_rangelow.mle_type) {
394db2661ceSRobert Watson 		case MAC_LOMAC_TYPE_GRADE:
395db2661ceSRobert Watson 		case MAC_LOMAC_TYPE_EQUAL:
396db2661ceSRobert Watson 		case MAC_LOMAC_TYPE_HIGH:
397db2661ceSRobert Watson 		case MAC_LOMAC_TYPE_LOW:
398db2661ceSRobert Watson 			break;
399db2661ceSRobert Watson 
400db2661ceSRobert Watson 		default:
401db2661ceSRobert Watson 			return (EINVAL);
402db2661ceSRobert Watson 		}
403db2661ceSRobert Watson 
404db2661ceSRobert Watson 		switch (mac_lomac->ml_rangehigh.mle_type) {
405db2661ceSRobert Watson 		case MAC_LOMAC_TYPE_GRADE:
406db2661ceSRobert Watson 		case MAC_LOMAC_TYPE_EQUAL:
407db2661ceSRobert Watson 		case MAC_LOMAC_TYPE_HIGH:
408db2661ceSRobert Watson 		case MAC_LOMAC_TYPE_LOW:
409db2661ceSRobert Watson 			break;
410db2661ceSRobert Watson 
411db2661ceSRobert Watson 		default:
412db2661ceSRobert Watson 			return (EINVAL);
413db2661ceSRobert Watson 		}
414db2661ceSRobert Watson 		if (!mac_lomac_dominate_element(&mac_lomac->ml_rangehigh,
415db2661ceSRobert Watson 		    &mac_lomac->ml_rangelow))
416db2661ceSRobert Watson 			return (EINVAL);
417db2661ceSRobert Watson 	} else {
418db2661ceSRobert Watson 		if (mac_lomac->ml_rangelow.mle_type != MAC_LOMAC_TYPE_UNDEF ||
419db2661ceSRobert Watson 		    mac_lomac->ml_rangehigh.mle_type != MAC_LOMAC_TYPE_UNDEF)
420db2661ceSRobert Watson 			return (EINVAL);
421db2661ceSRobert Watson 	}
422db2661ceSRobert Watson 
423db2661ceSRobert Watson 	return (0);
424db2661ceSRobert Watson }
425db2661ceSRobert Watson 
426db2661ceSRobert Watson static void
427db2661ceSRobert Watson mac_lomac_set_range(struct mac_lomac *mac_lomac, u_short typelow,
428db2661ceSRobert Watson     u_short gradelow, u_short typehigh, u_short gradehigh)
429db2661ceSRobert Watson {
430db2661ceSRobert Watson 
431db2661ceSRobert Watson 	mac_lomac->ml_rangelow.mle_type = typelow;
432db2661ceSRobert Watson 	mac_lomac->ml_rangelow.mle_grade = gradelow;
433db2661ceSRobert Watson 	mac_lomac->ml_rangehigh.mle_type = typehigh;
434db2661ceSRobert Watson 	mac_lomac->ml_rangehigh.mle_grade = gradehigh;
435db2661ceSRobert Watson 	mac_lomac->ml_flags |= MAC_LOMAC_FLAG_RANGE;
436db2661ceSRobert Watson }
437db2661ceSRobert Watson 
438db2661ceSRobert Watson static void
439db2661ceSRobert Watson mac_lomac_set_single(struct mac_lomac *mac_lomac, u_short type, u_short grade)
440db2661ceSRobert Watson {
441db2661ceSRobert Watson 
442db2661ceSRobert Watson 	mac_lomac->ml_single.mle_type = type;
443db2661ceSRobert Watson 	mac_lomac->ml_single.mle_grade = grade;
444db2661ceSRobert Watson 	mac_lomac->ml_flags |= MAC_LOMAC_FLAG_SINGLE;
445db2661ceSRobert Watson }
446db2661ceSRobert Watson 
447db2661ceSRobert Watson static void
448db2661ceSRobert Watson mac_lomac_copy_range(struct mac_lomac *labelfrom, struct mac_lomac *labelto)
449db2661ceSRobert Watson {
450db2661ceSRobert Watson 
451db2661ceSRobert Watson 	KASSERT((labelfrom->ml_flags & MAC_LOMAC_FLAG_RANGE) != 0,
452db2661ceSRobert Watson 	    ("mac_lomac_copy_range: labelfrom not range"));
453db2661ceSRobert Watson 
454db2661ceSRobert Watson 	labelto->ml_rangelow = labelfrom->ml_rangelow;
455db2661ceSRobert Watson 	labelto->ml_rangehigh = labelfrom->ml_rangehigh;
456db2661ceSRobert Watson 	labelto->ml_flags |= MAC_LOMAC_FLAG_RANGE;
457db2661ceSRobert Watson }
458db2661ceSRobert Watson 
459db2661ceSRobert Watson static void
460db2661ceSRobert Watson mac_lomac_copy_single(struct mac_lomac *labelfrom, struct mac_lomac *labelto)
461db2661ceSRobert Watson {
462db2661ceSRobert Watson 
463db2661ceSRobert Watson 	KASSERT((labelfrom->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0,
464db2661ceSRobert Watson 	    ("mac_lomac_copy_single: labelfrom not single"));
465db2661ceSRobert Watson 
466db2661ceSRobert Watson 	labelto->ml_single = labelfrom->ml_single;
467db2661ceSRobert Watson 	labelto->ml_flags |= MAC_LOMAC_FLAG_SINGLE;
468db2661ceSRobert Watson }
469db2661ceSRobert Watson 
470db2661ceSRobert Watson static void
471db2661ceSRobert Watson mac_lomac_copy_auxsingle(struct mac_lomac *labelfrom, struct mac_lomac *labelto)
472db2661ceSRobert Watson {
473db2661ceSRobert Watson 
474db2661ceSRobert Watson 	KASSERT((labelfrom->ml_flags & MAC_LOMAC_FLAG_AUX) != 0,
475db2661ceSRobert Watson 	    ("mac_lomac_copy_auxsingle: labelfrom not auxsingle"));
476db2661ceSRobert Watson 
477db2661ceSRobert Watson 	labelto->ml_auxsingle = labelfrom->ml_auxsingle;
478db2661ceSRobert Watson 	labelto->ml_flags |= MAC_LOMAC_FLAG_AUX;
479db2661ceSRobert Watson }
480db2661ceSRobert Watson 
481db2661ceSRobert Watson static void
482db2661ceSRobert Watson mac_lomac_copy(struct mac_lomac *source, struct mac_lomac *dest)
483db2661ceSRobert Watson {
484db2661ceSRobert Watson 
485db2661ceSRobert Watson 	if (source->ml_flags & MAC_LOMAC_FLAG_SINGLE)
486db2661ceSRobert Watson 		mac_lomac_copy_single(source, dest);
487db2661ceSRobert Watson 	if (source->ml_flags & MAC_LOMAC_FLAG_AUX)
488db2661ceSRobert Watson 		mac_lomac_copy_auxsingle(source, dest);
489db2661ceSRobert Watson 	if (source->ml_flags & MAC_LOMAC_FLAG_RANGE)
490db2661ceSRobert Watson 		mac_lomac_copy_range(source, dest);
491db2661ceSRobert Watson }
492db2661ceSRobert Watson 
493f51e5803SRobert Watson static int	mac_lomac_to_string(struct sbuf *sb,
494f51e5803SRobert Watson 		    struct mac_lomac *mac_lomac);
495db2661ceSRobert Watson 
496db2661ceSRobert Watson static int
497db2661ceSRobert Watson maybe_demote(struct mac_lomac *subjlabel, struct mac_lomac *objlabel,
49878007886SRobert Watson     const char *actionname, const char *objname, struct vnode *vp)
499db2661ceSRobert Watson {
500f51e5803SRobert Watson 	struct sbuf subjlabel_sb, subjtext_sb, objlabel_sb;
501f51e5803SRobert Watson 	char *subjlabeltext, *objlabeltext, *subjtext;
502f51e5803SRobert Watson 	struct mac_lomac cached_subjlabel;
503f51e5803SRobert Watson 	struct mac_lomac_proc *subj;
504db2661ceSRobert Watson 	struct vattr va;
505db2661ceSRobert Watson 	struct proc *p;
506db2661ceSRobert Watson 	pid_t pgid;
507db2661ceSRobert Watson 
508eca8a663SRobert Watson 	subj = PSLOT(curthread->td_proc->p_label);
509f51e5803SRobert Watson 
510db2661ceSRobert Watson 	p = curthread->td_proc;
511db2661ceSRobert Watson 	mtx_lock(&subj->mtx);
512db2661ceSRobert Watson         if (subj->mac_lomac.ml_flags & MAC_LOMAC_FLAG_UPDATE) {
513db2661ceSRobert Watson 		/*
514db2661ceSRobert Watson 		 * Check to see if the pending demotion would be more or
515db2661ceSRobert Watson 		 * less severe than this one, and keep the more severe.
516db2661ceSRobert Watson 		 * This can only happen for a multi-threaded application.
517db2661ceSRobert Watson 		 */
518db2661ceSRobert Watson 		if (mac_lomac_dominate_single(objlabel, &subj->mac_lomac)) {
519db2661ceSRobert Watson 			mtx_unlock(&subj->mtx);
520db2661ceSRobert Watson 			return (0);
521db2661ceSRobert Watson 		}
522db2661ceSRobert Watson 	}
523db2661ceSRobert Watson 	bzero(&subj->mac_lomac, sizeof(subj->mac_lomac));
524db2661ceSRobert Watson 	/*
525db2661ceSRobert Watson 	 * Always demote the single label.
526db2661ceSRobert Watson 	 */
527db2661ceSRobert Watson 	mac_lomac_copy_single(objlabel, &subj->mac_lomac);
528db2661ceSRobert Watson 	/*
529db2661ceSRobert Watson 	 * Start with the original range, then minimize each side of
530db2661ceSRobert Watson 	 * the range to the point of not dominating the object.  The
531db2661ceSRobert Watson 	 * high side will always be demoted, of course.
532db2661ceSRobert Watson 	 */
533db2661ceSRobert Watson 	mac_lomac_copy_range(subjlabel, &subj->mac_lomac);
534db2661ceSRobert Watson 	if (!mac_lomac_dominate_element(&objlabel->ml_single,
535db2661ceSRobert Watson 	    &subj->mac_lomac.ml_rangelow))
536db2661ceSRobert Watson 		subj->mac_lomac.ml_rangelow = objlabel->ml_single;
537db2661ceSRobert Watson 	subj->mac_lomac.ml_rangehigh = objlabel->ml_single;
538db2661ceSRobert Watson 	subj->mac_lomac.ml_flags |= MAC_LOMAC_FLAG_UPDATE;
539db2661ceSRobert Watson 	mtx_lock_spin(&sched_lock);
5404a338afdSJulian Elischer 	curthread->td_flags |= TDF_ASTPENDING;
541db2661ceSRobert Watson 	curthread->td_proc->p_sflag |= PS_MACPEND;
542db2661ceSRobert Watson 	mtx_unlock_spin(&sched_lock);
543f51e5803SRobert Watson 
544f51e5803SRobert Watson 	/*
545f51e5803SRobert Watson 	 * Avoid memory allocation while holding a mutex; cache the
546f51e5803SRobert Watson 	 * label.
547f51e5803SRobert Watson 	 */
548f51e5803SRobert Watson 	mac_lomac_copy_single(&subj->mac_lomac, &cached_subjlabel);
549db2661ceSRobert Watson 	mtx_unlock(&subj->mtx);
550f51e5803SRobert Watson 
551f51e5803SRobert Watson 	sbuf_new(&subjlabel_sb, NULL, 0, SBUF_AUTOEXTEND);
552f51e5803SRobert Watson 	mac_lomac_to_string(&subjlabel_sb, subjlabel);
553f51e5803SRobert Watson 	sbuf_finish(&subjlabel_sb);
554f51e5803SRobert Watson 	subjlabeltext = sbuf_data(&subjlabel_sb);
555f51e5803SRobert Watson 
556f51e5803SRobert Watson 	sbuf_new(&subjtext_sb, NULL, 0, SBUF_AUTOEXTEND);
557f51e5803SRobert Watson 	mac_lomac_to_string(&subjtext_sb, &subj->mac_lomac);
558f51e5803SRobert Watson 	sbuf_finish(&subjtext_sb);
559f51e5803SRobert Watson 	subjtext = sbuf_data(&subjtext_sb);
560f51e5803SRobert Watson 
561f51e5803SRobert Watson 	sbuf_new(&objlabel_sb, NULL, 0, SBUF_AUTOEXTEND);
562f51e5803SRobert Watson 	mac_lomac_to_string(&objlabel_sb, objlabel);
563f51e5803SRobert Watson 	sbuf_finish(&objlabel_sb);
564f51e5803SRobert Watson 	objlabeltext = sbuf_data(&objlabel_sb);
565f51e5803SRobert Watson 
566db2661ceSRobert Watson 	pgid = p->p_pgrp->pg_id;		/* XXX could be stale? */
56778007886SRobert Watson 	if (vp != NULL && VOP_GETATTR(vp, &va, curthread->td_ucred,
568db2661ceSRobert Watson 	    curthread) == 0) {
569db2661ceSRobert Watson 		log(LOG_INFO, "LOMAC: level-%s subject p%dg%du%d:%s demoted to"
570db2661ceSRobert Watson 		    " level %s after %s a level-%s %s (inode=%ld, "
571db2661ceSRobert Watson 		    "mountpount=%s)\n",
572db2661ceSRobert Watson 		    subjlabeltext, p->p_pid, pgid, curthread->td_ucred->cr_uid,
573db2661ceSRobert Watson 		    p->p_comm, subjtext, actionname, objlabeltext, objname,
57478007886SRobert Watson 		    va.va_fileid, vp->v_mount->mnt_stat.f_mntonname);
575db2661ceSRobert Watson 	} else {
576db2661ceSRobert Watson 		log(LOG_INFO, "LOMAC: level-%s subject p%dg%du%d:%s demoted to"
577db2661ceSRobert Watson 		    " level %s after %s a level-%s %s\n",
578db2661ceSRobert Watson 		    subjlabeltext, p->p_pid, pgid, curthread->td_ucred->cr_uid,
579db2661ceSRobert Watson 		    p->p_comm, subjtext, actionname, objlabeltext, objname);
580db2661ceSRobert Watson 	}
581db2661ceSRobert Watson 
582f51e5803SRobert Watson 	sbuf_delete(&subjlabel_sb);
583f51e5803SRobert Watson 	sbuf_delete(&subjtext_sb);
584f51e5803SRobert Watson 	sbuf_delete(&objlabel_sb);
585f51e5803SRobert Watson 
586db2661ceSRobert Watson 	return (0);
587db2661ceSRobert Watson }
588db2661ceSRobert Watson 
589db2661ceSRobert Watson /*
590db2661ceSRobert Watson  * Relabel "to" to "from" only if "from" is a valid label (contains
591db2661ceSRobert Watson  * at least a single), as for a relabel operation which may or may
592db2661ceSRobert Watson  * not involve a relevant label.
593db2661ceSRobert Watson  */
5947496ed81SRobert Watson static void
595db2661ceSRobert Watson try_relabel(struct mac_lomac *from, struct mac_lomac *to)
596db2661ceSRobert Watson {
597db2661ceSRobert Watson 
598db2661ceSRobert Watson 	if (from->ml_flags & MAC_LOMAC_FLAG_SINGLE) {
599db2661ceSRobert Watson 		bzero(to, sizeof(*to));
600db2661ceSRobert Watson 		mac_lomac_copy(from, to);
601db2661ceSRobert Watson 	}
602db2661ceSRobert Watson }
603db2661ceSRobert Watson 
604db2661ceSRobert Watson /*
605db2661ceSRobert Watson  * Policy module operations.
606db2661ceSRobert Watson  */
607db2661ceSRobert Watson static void
608db2661ceSRobert Watson mac_lomac_init(struct mac_policy_conf *conf)
609db2661ceSRobert Watson {
610db2661ceSRobert Watson 
611db2661ceSRobert Watson }
612db2661ceSRobert Watson 
613db2661ceSRobert Watson /*
614db2661ceSRobert Watson  * Label operations.
615db2661ceSRobert Watson  */
616db2661ceSRobert Watson static void
617db2661ceSRobert Watson mac_lomac_init_label(struct label *label)
618db2661ceSRobert Watson {
619db2661ceSRobert Watson 
6201477f588SAlexander Kabaev 	SLOT_SET(label, lomac_alloc(M_WAITOK));
621db2661ceSRobert Watson }
622db2661ceSRobert Watson 
623db2661ceSRobert Watson static int
624db2661ceSRobert Watson mac_lomac_init_label_waitcheck(struct label *label, int flag)
625db2661ceSRobert Watson {
626db2661ceSRobert Watson 
6271477f588SAlexander Kabaev 	SLOT_SET(label, lomac_alloc(flag));
628db2661ceSRobert Watson 	if (SLOT(label) == NULL)
629db2661ceSRobert Watson 		return (ENOMEM);
630db2661ceSRobert Watson 
631db2661ceSRobert Watson 	return (0);
632db2661ceSRobert Watson }
633db2661ceSRobert Watson 
634db2661ceSRobert Watson static void
635db2661ceSRobert Watson mac_lomac_init_proc_label(struct label *label)
636db2661ceSRobert Watson {
637db2661ceSRobert Watson 
6381477f588SAlexander Kabaev 	PSLOT_SET(label, malloc(sizeof(struct mac_lomac_proc), M_MACLOMAC,
6391477f588SAlexander Kabaev 	    M_ZERO | M_WAITOK));
640db2661ceSRobert Watson 	mtx_init(&PSLOT(label)->mtx, "MAC/Lomac proc lock", NULL, MTX_DEF);
641db2661ceSRobert Watson }
642db2661ceSRobert Watson 
643db2661ceSRobert Watson static void
644db2661ceSRobert Watson mac_lomac_destroy_label(struct label *label)
645db2661ceSRobert Watson {
646db2661ceSRobert Watson 
647db2661ceSRobert Watson 	lomac_free(SLOT(label));
6481477f588SAlexander Kabaev 	SLOT_SET(label, NULL);
649db2661ceSRobert Watson }
650db2661ceSRobert Watson 
651db2661ceSRobert Watson static void
652db2661ceSRobert Watson mac_lomac_destroy_proc_label(struct label *label)
653db2661ceSRobert Watson {
654db2661ceSRobert Watson 
655db2661ceSRobert Watson 	mtx_destroy(&PSLOT(label)->mtx);
656db2661ceSRobert Watson 	FREE(PSLOT(label), M_MACLOMAC);
6571477f588SAlexander Kabaev 	PSLOT_SET(label, NULL);
658db2661ceSRobert Watson }
659db2661ceSRobert Watson 
660f51e5803SRobert Watson static int
661f51e5803SRobert Watson mac_lomac_element_to_string(struct sbuf *sb, struct mac_lomac_element *element)
662db2661ceSRobert Watson {
663db2661ceSRobert Watson 
664db2661ceSRobert Watson 	switch (element->mle_type) {
665db2661ceSRobert Watson 	case MAC_LOMAC_TYPE_HIGH:
666f51e5803SRobert Watson 		return (sbuf_printf(sb, "high"));
667db2661ceSRobert Watson 
668db2661ceSRobert Watson 	case MAC_LOMAC_TYPE_LOW:
669f51e5803SRobert Watson 		return (sbuf_printf(sb, "low"));
670db2661ceSRobert Watson 
671db2661ceSRobert Watson 	case MAC_LOMAC_TYPE_EQUAL:
672f51e5803SRobert Watson 		return (sbuf_printf(sb, "equal"));
673db2661ceSRobert Watson 
674db2661ceSRobert Watson 	case MAC_LOMAC_TYPE_GRADE:
675f51e5803SRobert Watson 		return (sbuf_printf(sb, "%d", element->mle_grade));
676db2661ceSRobert Watson 
677db2661ceSRobert Watson 	default:
678db2661ceSRobert Watson 		panic("mac_lomac_element_to_string: invalid type (%d)",
679db2661ceSRobert Watson 		    element->mle_type);
680db2661ceSRobert Watson 	}
681db2661ceSRobert Watson }
682db2661ceSRobert Watson 
683db2661ceSRobert Watson static int
684f51e5803SRobert Watson mac_lomac_to_string(struct sbuf *sb, struct mac_lomac *mac_lomac)
685db2661ceSRobert Watson {
686db2661ceSRobert Watson 
687db2661ceSRobert Watson 	if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_SINGLE) {
688f51e5803SRobert Watson 		if (mac_lomac_element_to_string(sb, &mac_lomac->ml_single)
689f51e5803SRobert Watson 		    == -1)
690f51e5803SRobert Watson 			return (EINVAL);
691db2661ceSRobert Watson 	}
692db2661ceSRobert Watson 
693db2661ceSRobert Watson 	if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_AUX) {
694f51e5803SRobert Watson 		if (sbuf_putc(sb, '[') == -1)
695f51e5803SRobert Watson 			return (EINVAL);
696db2661ceSRobert Watson 
697f51e5803SRobert Watson 		if (mac_lomac_element_to_string(sb, &mac_lomac->ml_auxsingle)
698f51e5803SRobert Watson 		    == -1)
699f51e5803SRobert Watson 			return (EINVAL);
700db2661ceSRobert Watson 
701f51e5803SRobert Watson 		if (sbuf_putc(sb, ']') == -1)
702f51e5803SRobert Watson 			return (EINVAL);
703db2661ceSRobert Watson 	}
704db2661ceSRobert Watson 
705db2661ceSRobert Watson 	if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_RANGE) {
706f51e5803SRobert Watson 		if (sbuf_putc(sb, '(') == -1)
707f51e5803SRobert Watson 			return (EINVAL);
708db2661ceSRobert Watson 
709f51e5803SRobert Watson 		if (mac_lomac_element_to_string(sb, &mac_lomac->ml_rangelow)
710f51e5803SRobert Watson 		    == -1)
711f51e5803SRobert Watson 			return (EINVAL);
712db2661ceSRobert Watson 
713f51e5803SRobert Watson 		if (sbuf_putc(sb, '-') == -1)
714f51e5803SRobert Watson 			return (EINVAL);
715db2661ceSRobert Watson 
716f51e5803SRobert Watson 		if (mac_lomac_element_to_string(sb, &mac_lomac->ml_rangehigh)
717f51e5803SRobert Watson 		    == -1)
718f51e5803SRobert Watson 			return (EINVAL);
719db2661ceSRobert Watson 
7208a4b86b9SRobert Watson 		if (sbuf_putc(sb, ')') == -1)
721f51e5803SRobert Watson 			return (EINVAL);
722db2661ceSRobert Watson 	}
723db2661ceSRobert Watson 
724db2661ceSRobert Watson 	return (0);
725db2661ceSRobert Watson }
726db2661ceSRobert Watson 
727db2661ceSRobert Watson static int
728db2661ceSRobert Watson mac_lomac_externalize_label(struct label *label, char *element_name,
729f51e5803SRobert Watson     struct sbuf *sb, int *claimed)
730db2661ceSRobert Watson {
731db2661ceSRobert Watson 	struct mac_lomac *mac_lomac;
732db2661ceSRobert Watson 
733db2661ceSRobert Watson 	if (strcmp(MAC_LOMAC_LABEL_NAME, element_name) != 0)
734db2661ceSRobert Watson 		return (0);
735db2661ceSRobert Watson 
736db2661ceSRobert Watson 	(*claimed)++;
737db2661ceSRobert Watson 
738db2661ceSRobert Watson 	mac_lomac = SLOT(label);
739db2661ceSRobert Watson 
740f51e5803SRobert Watson 	return (mac_lomac_to_string(sb, mac_lomac));
741db2661ceSRobert Watson }
742db2661ceSRobert Watson 
743db2661ceSRobert Watson static int
744db2661ceSRobert Watson mac_lomac_parse_element(struct mac_lomac_element *element, char *string)
745db2661ceSRobert Watson {
746db2661ceSRobert Watson 
747db2661ceSRobert Watson 	if (strcmp(string, "high") == 0 ||
748db2661ceSRobert Watson 	    strcmp(string, "hi") == 0) {
749db2661ceSRobert Watson 		element->mle_type = MAC_LOMAC_TYPE_HIGH;
750db2661ceSRobert Watson 		element->mle_grade = MAC_LOMAC_TYPE_UNDEF;
751db2661ceSRobert Watson 	} else if (strcmp(string, "low") == 0 ||
752db2661ceSRobert Watson 	    strcmp(string, "lo") == 0) {
753db2661ceSRobert Watson 		element->mle_type = MAC_LOMAC_TYPE_LOW;
754db2661ceSRobert Watson 		element->mle_grade = MAC_LOMAC_TYPE_UNDEF;
755db2661ceSRobert Watson 	} else if (strcmp(string, "equal") == 0 ||
756db2661ceSRobert Watson 	    strcmp(string, "eq") == 0) {
757db2661ceSRobert Watson 		element->mle_type = MAC_LOMAC_TYPE_EQUAL;
758db2661ceSRobert Watson 		element->mle_grade = MAC_LOMAC_TYPE_UNDEF;
759db2661ceSRobert Watson 	} else {
760db2661ceSRobert Watson 		char *p0, *p1;
761db2661ceSRobert Watson 		int d;
762db2661ceSRobert Watson 
763db2661ceSRobert Watson 		p0 = string;
764db2661ceSRobert Watson 		d = strtol(p0, &p1, 10);
765db2661ceSRobert Watson 
766db2661ceSRobert Watson 		if (d < 0 || d > 65535)
767db2661ceSRobert Watson 			return (EINVAL);
768db2661ceSRobert Watson 		element->mle_type = MAC_LOMAC_TYPE_GRADE;
769db2661ceSRobert Watson 		element->mle_grade = d;
770db2661ceSRobert Watson 
771db2661ceSRobert Watson 		if (p1 == p0 || *p1 != '\0')
772db2661ceSRobert Watson 			return (EINVAL);
773db2661ceSRobert Watson 	}
774db2661ceSRobert Watson 
775db2661ceSRobert Watson 	return (0);
776db2661ceSRobert Watson }
777db2661ceSRobert Watson 
778db2661ceSRobert Watson /*
779db2661ceSRobert Watson  * Note: destructively consumes the string, make a local copy before
780db2661ceSRobert Watson  * calling if that's a problem.
781db2661ceSRobert Watson  */
782db2661ceSRobert Watson static int
783db2661ceSRobert Watson mac_lomac_parse(struct mac_lomac *mac_lomac, char *string)
784db2661ceSRobert Watson {
785db2661ceSRobert Watson 	char *range, *rangeend, *rangehigh, *rangelow, *single, *auxsingle,
786db2661ceSRobert Watson 	    *auxsingleend;
787db2661ceSRobert Watson 	int error;
788db2661ceSRobert Watson 
789db2661ceSRobert Watson 	/* Do we have a range? */
790db2661ceSRobert Watson 	single = string;
791db2661ceSRobert Watson 	range = index(string, '(');
792db2661ceSRobert Watson 	if (range == single)
793db2661ceSRobert Watson 		single = NULL;
794db2661ceSRobert Watson 	auxsingle = index(string, '[');
795db2661ceSRobert Watson 	if (auxsingle == single)
796db2661ceSRobert Watson 		single = NULL;
797db2661ceSRobert Watson 	if (range != NULL && auxsingle != NULL)
798db2661ceSRobert Watson 		return (EINVAL);
799db2661ceSRobert Watson 	rangelow = rangehigh = NULL;
800db2661ceSRobert Watson 	if (range != NULL) {
801db2661ceSRobert Watson 		/* Nul terminate the end of the single string. */
802db2661ceSRobert Watson 		*range = '\0';
803db2661ceSRobert Watson 		range++;
804db2661ceSRobert Watson 		rangelow = range;
805db2661ceSRobert Watson 		rangehigh = index(rangelow, '-');
806db2661ceSRobert Watson 		if (rangehigh == NULL)
807db2661ceSRobert Watson 			return (EINVAL);
808db2661ceSRobert Watson 		rangehigh++;
809db2661ceSRobert Watson 		if (*rangelow == '\0' || *rangehigh == '\0')
810db2661ceSRobert Watson 			return (EINVAL);
811db2661ceSRobert Watson 		rangeend = index(rangehigh, ')');
812db2661ceSRobert Watson 		if (rangeend == NULL)
813db2661ceSRobert Watson 			return (EINVAL);
814db2661ceSRobert Watson 		if (*(rangeend + 1) != '\0')
815db2661ceSRobert Watson 			return (EINVAL);
816db2661ceSRobert Watson 		/* Nul terminate the ends of the ranges. */
817db2661ceSRobert Watson 		*(rangehigh - 1) = '\0';
818db2661ceSRobert Watson 		*rangeend = '\0';
819db2661ceSRobert Watson 	}
820db2661ceSRobert Watson 	KASSERT((rangelow != NULL && rangehigh != NULL) ||
821db2661ceSRobert Watson 	    (rangelow == NULL && rangehigh == NULL),
822db2661ceSRobert Watson 	    ("mac_lomac_internalize_label: range mismatch"));
823db2661ceSRobert Watson 	if (auxsingle != NULL) {
824db2661ceSRobert Watson 		/* Nul terminate the end of the single string. */
825db2661ceSRobert Watson 		*auxsingle = '\0';
826db2661ceSRobert Watson 		auxsingle++;
827db2661ceSRobert Watson 		auxsingleend = index(auxsingle, ']');
828db2661ceSRobert Watson 		if (auxsingleend == NULL)
829db2661ceSRobert Watson 			return (EINVAL);
830db2661ceSRobert Watson 		if (*(auxsingleend + 1) != '\0')
831db2661ceSRobert Watson 			return (EINVAL);
832db2661ceSRobert Watson 		/* Nul terminate the end of the auxsingle. */
833db2661ceSRobert Watson 		*auxsingleend = '\0';
834db2661ceSRobert Watson 	}
835db2661ceSRobert Watson 
836db2661ceSRobert Watson 	bzero(mac_lomac, sizeof(*mac_lomac));
837db2661ceSRobert Watson 	if (single != NULL) {
838db2661ceSRobert Watson 		error = mac_lomac_parse_element(&mac_lomac->ml_single, single);
839db2661ceSRobert Watson 		if (error)
840db2661ceSRobert Watson 			return (error);
841db2661ceSRobert Watson 		mac_lomac->ml_flags |= MAC_LOMAC_FLAG_SINGLE;
842db2661ceSRobert Watson 	}
843db2661ceSRobert Watson 
844db2661ceSRobert Watson 	if (auxsingle != NULL) {
845db2661ceSRobert Watson 		error = mac_lomac_parse_element(&mac_lomac->ml_auxsingle,
846db2661ceSRobert Watson 		    auxsingle);
847db2661ceSRobert Watson 		if (error)
848db2661ceSRobert Watson 			return (error);
849db2661ceSRobert Watson 		mac_lomac->ml_flags |= MAC_LOMAC_FLAG_AUX;
850db2661ceSRobert Watson 	}
851db2661ceSRobert Watson 
852db2661ceSRobert Watson 	if (rangelow != NULL) {
853db2661ceSRobert Watson 		error = mac_lomac_parse_element(&mac_lomac->ml_rangelow,
854db2661ceSRobert Watson 		    rangelow);
855db2661ceSRobert Watson 		if (error)
856db2661ceSRobert Watson 			return (error);
857db2661ceSRobert Watson 		error = mac_lomac_parse_element(&mac_lomac->ml_rangehigh,
858db2661ceSRobert Watson 		    rangehigh);
859db2661ceSRobert Watson 		if (error)
860db2661ceSRobert Watson 			return (error);
861db2661ceSRobert Watson 		mac_lomac->ml_flags |= MAC_LOMAC_FLAG_RANGE;
862db2661ceSRobert Watson 	}
863db2661ceSRobert Watson 
864db2661ceSRobert Watson 	error = mac_lomac_valid(mac_lomac);
865db2661ceSRobert Watson 	if (error)
866db2661ceSRobert Watson 		return (error);
867db2661ceSRobert Watson 
868db2661ceSRobert Watson 	return (0);
869db2661ceSRobert Watson }
870db2661ceSRobert Watson 
871db2661ceSRobert Watson static int
872db2661ceSRobert Watson mac_lomac_internalize_label(struct label *label, char *element_name,
873db2661ceSRobert Watson     char *element_data, int *claimed)
874db2661ceSRobert Watson {
875db2661ceSRobert Watson 	struct mac_lomac *mac_lomac, mac_lomac_temp;
876db2661ceSRobert Watson 	int error;
877db2661ceSRobert Watson 
878db2661ceSRobert Watson 	if (strcmp(MAC_LOMAC_LABEL_NAME, element_name) != 0)
879db2661ceSRobert Watson 		return (0);
880db2661ceSRobert Watson 
881db2661ceSRobert Watson 	(*claimed)++;
882db2661ceSRobert Watson 
883db2661ceSRobert Watson 	error = mac_lomac_parse(&mac_lomac_temp, element_data);
884db2661ceSRobert Watson 	if (error)
885db2661ceSRobert Watson 		return (error);
886db2661ceSRobert Watson 
887db2661ceSRobert Watson 	mac_lomac = SLOT(label);
888db2661ceSRobert Watson 	*mac_lomac = mac_lomac_temp;
889db2661ceSRobert Watson 
890db2661ceSRobert Watson 	return (0);
891db2661ceSRobert Watson }
892db2661ceSRobert Watson 
893db2661ceSRobert Watson static void
894db2661ceSRobert Watson mac_lomac_copy_label(struct label *src, struct label *dest)
895db2661ceSRobert Watson {
896db2661ceSRobert Watson 
897db2661ceSRobert Watson 	*SLOT(dest) = *SLOT(src);
898db2661ceSRobert Watson }
899db2661ceSRobert Watson 
900db2661ceSRobert Watson /*
901db2661ceSRobert Watson  * Labeling event operations: file system objects, and things that look
902db2661ceSRobert Watson  * a lot like file system objects.
903db2661ceSRobert Watson  */
904db2661ceSRobert Watson static void
905d26dd2d9SRobert Watson mac_lomac_create_devfs_device(struct ucred *cred, struct mount *mp,
90678007886SRobert Watson     struct cdev *dev, struct devfs_dirent *de, struct label *delabel)
907db2661ceSRobert Watson {
908db2661ceSRobert Watson 	struct mac_lomac *mac_lomac;
909db2661ceSRobert Watson 	int lomac_type;
910db2661ceSRobert Watson 
91178007886SRobert Watson 	mac_lomac = SLOT(delabel);
912db2661ceSRobert Watson 	if (strcmp(dev->si_name, "null") == 0 ||
913db2661ceSRobert Watson 	    strcmp(dev->si_name, "zero") == 0 ||
914db2661ceSRobert Watson 	    strcmp(dev->si_name, "random") == 0 ||
915db2661ceSRobert Watson 	    strncmp(dev->si_name, "fd/", strlen("fd/")) == 0 ||
916db2661ceSRobert Watson 	    strncmp(dev->si_name, "ttyv", strlen("ttyv")) == 0)
917db2661ceSRobert Watson 		lomac_type = MAC_LOMAC_TYPE_EQUAL;
918db2661ceSRobert Watson 	else if (ptys_equal &&
919db2661ceSRobert Watson 	    (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 ||
920db2661ceSRobert Watson 	    strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0))
921db2661ceSRobert Watson 		lomac_type = MAC_LOMAC_TYPE_EQUAL;
922db2661ceSRobert Watson 	else
923db2661ceSRobert Watson 		lomac_type = MAC_LOMAC_TYPE_HIGH;
924db2661ceSRobert Watson 	mac_lomac_set_single(mac_lomac, lomac_type, 0);
925db2661ceSRobert Watson }
926db2661ceSRobert Watson 
927db2661ceSRobert Watson static void
928990b4b2dSRobert Watson mac_lomac_create_devfs_directory(struct mount *mp, char *dirname,
92978007886SRobert Watson     int dirnamelen, struct devfs_dirent *de, struct label *delabel)
930db2661ceSRobert Watson {
931db2661ceSRobert Watson 	struct mac_lomac *mac_lomac;
932db2661ceSRobert Watson 
93378007886SRobert Watson 	mac_lomac = SLOT(delabel);
934db2661ceSRobert Watson 	mac_lomac_set_single(mac_lomac, MAC_LOMAC_TYPE_HIGH, 0);
935db2661ceSRobert Watson }
936db2661ceSRobert Watson 
937db2661ceSRobert Watson static void
938990b4b2dSRobert Watson mac_lomac_create_devfs_symlink(struct ucred *cred, struct mount *mp,
939990b4b2dSRobert Watson     struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de,
940990b4b2dSRobert Watson     struct label *delabel)
941db2661ceSRobert Watson {
942db2661ceSRobert Watson 	struct mac_lomac *source, *dest;
943db2661ceSRobert Watson 
944eca8a663SRobert Watson 	source = SLOT(cred->cr_label);
945db2661ceSRobert Watson 	dest = SLOT(delabel);
946db2661ceSRobert Watson 
947db2661ceSRobert Watson 	mac_lomac_copy_single(source, dest);
948db2661ceSRobert Watson }
949db2661ceSRobert Watson 
950db2661ceSRobert Watson static void
951db2661ceSRobert Watson mac_lomac_create_mount(struct ucred *cred, struct mount *mp,
95278007886SRobert Watson     struct label *mplabel)
953db2661ceSRobert Watson {
954db2661ceSRobert Watson 	struct mac_lomac *source, *dest;
955db2661ceSRobert Watson 
956eca8a663SRobert Watson 	source = SLOT(cred->cr_label);
95778007886SRobert Watson 	dest = SLOT(mplabel);
958db2661ceSRobert Watson 	mac_lomac_copy_single(source, dest);
959db2661ceSRobert Watson }
960db2661ceSRobert Watson 
961db2661ceSRobert Watson static void
962db2661ceSRobert Watson mac_lomac_relabel_vnode(struct ucred *cred, struct vnode *vp,
96378007886SRobert Watson     struct label *vplabel, struct label *newlabel)
964db2661ceSRobert Watson {
965db2661ceSRobert Watson 	struct mac_lomac *source, *dest;
966db2661ceSRobert Watson 
96778007886SRobert Watson 	source = SLOT(newlabel);
96878007886SRobert Watson 	dest = SLOT(vplabel);
969db2661ceSRobert Watson 
970db2661ceSRobert Watson 	try_relabel(source, dest);
971db2661ceSRobert Watson }
972db2661ceSRobert Watson 
973db2661ceSRobert Watson static void
97478007886SRobert Watson mac_lomac_update_devfsdirent(struct mount *mp, struct devfs_dirent *de,
97578007886SRobert Watson     struct label *delabel, struct vnode *vp, struct label *vplabel)
976db2661ceSRobert Watson {
977db2661ceSRobert Watson 	struct mac_lomac *source, *dest;
978db2661ceSRobert Watson 
97978007886SRobert Watson 	source = SLOT(vplabel);
98078007886SRobert Watson 	dest = SLOT(delabel);
981db2661ceSRobert Watson 
982db2661ceSRobert Watson 	mac_lomac_copy(source, dest);
983db2661ceSRobert Watson }
984db2661ceSRobert Watson 
985db2661ceSRobert Watson static void
98678007886SRobert Watson mac_lomac_associate_vnode_devfs(struct mount *mp, struct label *mplabel,
987db2661ceSRobert Watson     struct devfs_dirent *de, struct label *delabel, struct vnode *vp,
98878007886SRobert Watson     struct label *vplabel)
989db2661ceSRobert Watson {
990db2661ceSRobert Watson 	struct mac_lomac *source, *dest;
991db2661ceSRobert Watson 
992db2661ceSRobert Watson 	source = SLOT(delabel);
99378007886SRobert Watson 	dest = SLOT(vplabel);
994db2661ceSRobert Watson 
995db2661ceSRobert Watson 	mac_lomac_copy_single(source, dest);
996db2661ceSRobert Watson }
997db2661ceSRobert Watson 
998db2661ceSRobert Watson static int
99978007886SRobert Watson mac_lomac_associate_vnode_extattr(struct mount *mp, struct label *mplabel,
100078007886SRobert Watson     struct vnode *vp, struct label *vplabel)
1001db2661ceSRobert Watson {
1002db2661ceSRobert Watson 	struct mac_lomac temp, *source, *dest;
1003b247d661SMaxime Henrion 	int buflen, error;
1004db2661ceSRobert Watson 
100578007886SRobert Watson 	source = SLOT(mplabel);
100678007886SRobert Watson 	dest = SLOT(vplabel);
1007db2661ceSRobert Watson 
1008db2661ceSRobert Watson 	buflen = sizeof(temp);
1009db2661ceSRobert Watson 	bzero(&temp, buflen);
1010db2661ceSRobert Watson 
1011db2661ceSRobert Watson 	error = vn_extattr_get(vp, IO_NODELOCKED, MAC_LOMAC_EXTATTR_NAMESPACE,
1012db2661ceSRobert Watson 	    MAC_LOMAC_EXTATTR_NAME, &buflen, (char *)&temp, curthread);
1013db2661ceSRobert Watson 	if (error == ENOATTR || error == EOPNOTSUPP) {
1014eb542415SRobert Watson 		/* Fall back to the mntlabel. */
1015db2661ceSRobert Watson 		mac_lomac_copy_single(source, dest);
1016db2661ceSRobert Watson 		return (0);
1017db2661ceSRobert Watson 	} else if (error)
1018db2661ceSRobert Watson 		return (error);
1019db2661ceSRobert Watson 
1020db2661ceSRobert Watson 	if (buflen != sizeof(temp)) {
1021db2661ceSRobert Watson 		if (buflen != sizeof(temp) - sizeof(temp.ml_auxsingle)) {
1022db2661ceSRobert Watson 			printf("mac_lomac_associate_vnode_extattr: bad size %d\n",
1023db2661ceSRobert Watson 			    buflen);
1024db2661ceSRobert Watson 			return (EPERM);
1025db2661ceSRobert Watson 		}
1026db2661ceSRobert Watson 		bzero(&temp.ml_auxsingle, sizeof(temp.ml_auxsingle));
1027db2661ceSRobert Watson 		buflen = sizeof(temp);
1028db2661ceSRobert Watson 		(void)vn_extattr_set(vp, IO_NODELOCKED,
1029db2661ceSRobert Watson 		    MAC_LOMAC_EXTATTR_NAMESPACE, MAC_LOMAC_EXTATTR_NAME,
1030db2661ceSRobert Watson 		    buflen, (char *)&temp, curthread);
1031db2661ceSRobert Watson 	}
1032db2661ceSRobert Watson 	if (mac_lomac_valid(&temp) != 0) {
1033db2661ceSRobert Watson 		printf("mac_lomac_associate_vnode_extattr: invalid\n");
1034db2661ceSRobert Watson 		return (EPERM);
1035db2661ceSRobert Watson 	}
1036db2661ceSRobert Watson 	if ((temp.ml_flags & MAC_LOMAC_FLAGS_BOTH) != MAC_LOMAC_FLAG_SINGLE) {
1037db2661ceSRobert Watson 		printf("mac_lomac_associate_vnode_extattr: not single\n");
1038db2661ceSRobert Watson 		return (EPERM);
1039db2661ceSRobert Watson 	}
1040db2661ceSRobert Watson 
1041db2661ceSRobert Watson 	mac_lomac_copy_single(&temp, dest);
1042db2661ceSRobert Watson 	return (0);
1043db2661ceSRobert Watson }
1044db2661ceSRobert Watson 
1045db2661ceSRobert Watson static void
1046db2661ceSRobert Watson mac_lomac_associate_vnode_singlelabel(struct mount *mp,
104778007886SRobert Watson     struct label *mplabel, struct vnode *vp, struct label *vplabel)
1048db2661ceSRobert Watson {
1049db2661ceSRobert Watson 	struct mac_lomac *source, *dest;
1050db2661ceSRobert Watson 
105178007886SRobert Watson 	source = SLOT(mplabel);
105278007886SRobert Watson 	dest = SLOT(vplabel);
1053db2661ceSRobert Watson 
1054db2661ceSRobert Watson 	mac_lomac_copy_single(source, dest);
1055db2661ceSRobert Watson }
1056db2661ceSRobert Watson 
1057db2661ceSRobert Watson static int
1058db2661ceSRobert Watson mac_lomac_create_vnode_extattr(struct ucred *cred, struct mount *mp,
105978007886SRobert Watson     struct label *mplabel, struct vnode *dvp, struct label *dvplabel,
106078007886SRobert Watson     struct vnode *vp, struct label *vplabel, struct componentname *cnp)
1061db2661ceSRobert Watson {
1062db2661ceSRobert Watson 	struct mac_lomac *source, *dest, *dir, temp;
1063db2661ceSRobert Watson 	size_t buflen;
1064db2661ceSRobert Watson 	int error;
1065db2661ceSRobert Watson 
1066db2661ceSRobert Watson 	buflen = sizeof(temp);
1067db2661ceSRobert Watson 	bzero(&temp, buflen);
1068db2661ceSRobert Watson 
1069eca8a663SRobert Watson 	source = SLOT(cred->cr_label);
107078007886SRobert Watson 	dest = SLOT(vplabel);
107178007886SRobert Watson 	dir = SLOT(dvplabel);
1072db2661ceSRobert Watson 	if (dir->ml_flags & MAC_LOMAC_FLAG_AUX) {
1073db2661ceSRobert Watson 		mac_lomac_copy_auxsingle(dir, &temp);
1074db2661ceSRobert Watson 		mac_lomac_set_single(&temp, dir->ml_auxsingle.mle_type,
1075db2661ceSRobert Watson 		    dir->ml_auxsingle.mle_grade);
1076db2661ceSRobert Watson 	} else {
1077db2661ceSRobert Watson 		mac_lomac_copy_single(source, &temp);
1078db2661ceSRobert Watson 	}
1079db2661ceSRobert Watson 
1080db2661ceSRobert Watson 	error = vn_extattr_set(vp, IO_NODELOCKED, MAC_LOMAC_EXTATTR_NAMESPACE,
1081db2661ceSRobert Watson 	    MAC_LOMAC_EXTATTR_NAME, buflen, (char *)&temp, curthread);
1082db2661ceSRobert Watson 	if (error == 0)
1083db2661ceSRobert Watson 		mac_lomac_copy(&temp, dest);
1084db2661ceSRobert Watson 	return (error);
1085db2661ceSRobert Watson }
1086db2661ceSRobert Watson 
1087db2661ceSRobert Watson static int
1088db2661ceSRobert Watson mac_lomac_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp,
108978007886SRobert Watson     struct label *vplabel, struct label *intlabel)
1090db2661ceSRobert Watson {
1091db2661ceSRobert Watson 	struct mac_lomac *source, temp;
1092db2661ceSRobert Watson 	size_t buflen;
1093db2661ceSRobert Watson 	int error;
1094db2661ceSRobert Watson 
1095db2661ceSRobert Watson 	buflen = sizeof(temp);
1096db2661ceSRobert Watson 	bzero(&temp, buflen);
1097db2661ceSRobert Watson 
1098db2661ceSRobert Watson 	source = SLOT(intlabel);
1099db2661ceSRobert Watson 	if ((source->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0)
1100db2661ceSRobert Watson 		return (0);
1101db2661ceSRobert Watson 
1102db2661ceSRobert Watson 	mac_lomac_copy_single(source, &temp);
1103db2661ceSRobert Watson 	error = vn_extattr_set(vp, IO_NODELOCKED, MAC_LOMAC_EXTATTR_NAMESPACE,
1104db2661ceSRobert Watson 	    MAC_LOMAC_EXTATTR_NAME, buflen, (char *)&temp, curthread);
1105db2661ceSRobert Watson 	return (error);
1106db2661ceSRobert Watson }
1107db2661ceSRobert Watson 
1108db2661ceSRobert Watson /*
1109db2661ceSRobert Watson  * Labeling event operations: IPC object.
1110db2661ceSRobert Watson  */
1111db2661ceSRobert Watson static void
1112a557af22SRobert Watson mac_lomac_create_inpcb_from_socket(struct socket *so, struct label *solabel,
1113a557af22SRobert Watson     struct inpcb *inp, struct label *inplabel)
1114a557af22SRobert Watson {
1115a557af22SRobert Watson 	struct mac_lomac *source, *dest;
1116a557af22SRobert Watson 
1117a557af22SRobert Watson 	source = SLOT(solabel);
1118a557af22SRobert Watson 	dest = SLOT(inplabel);
1119a557af22SRobert Watson 
1120a557af22SRobert Watson 	mac_lomac_copy_single(source, dest);
1121a557af22SRobert Watson }
1122a557af22SRobert Watson 
1123a557af22SRobert Watson static void
112478007886SRobert Watson mac_lomac_create_mbuf_from_socket(struct socket *so, struct label *solabel,
112578007886SRobert Watson     struct mbuf *m, struct label *mlabel)
1126db2661ceSRobert Watson {
1127db2661ceSRobert Watson 	struct mac_lomac *source, *dest;
1128db2661ceSRobert Watson 
112978007886SRobert Watson 	source = SLOT(solabel);
113078007886SRobert Watson 	dest = SLOT(mlabel);
1131db2661ceSRobert Watson 
1132db2661ceSRobert Watson 	mac_lomac_copy_single(source, dest);
1133db2661ceSRobert Watson }
1134db2661ceSRobert Watson 
1135db2661ceSRobert Watson static void
113678007886SRobert Watson mac_lomac_create_socket(struct ucred *cred, struct socket *so,
113778007886SRobert Watson     struct label *solabel)
1138db2661ceSRobert Watson {
1139db2661ceSRobert Watson 	struct mac_lomac *source, *dest;
1140db2661ceSRobert Watson 
1141eca8a663SRobert Watson 	source = SLOT(cred->cr_label);
114278007886SRobert Watson 	dest = SLOT(solabel);
1143db2661ceSRobert Watson 
1144db2661ceSRobert Watson 	mac_lomac_copy_single(source, dest);
1145db2661ceSRobert Watson }
1146db2661ceSRobert Watson 
1147db2661ceSRobert Watson static void
11484795b82cSRobert Watson mac_lomac_create_pipe(struct ucred *cred, struct pipepair *pp,
114978007886SRobert Watson     struct label *pplabel)
1150db2661ceSRobert Watson {
1151db2661ceSRobert Watson 	struct mac_lomac *source, *dest;
1152db2661ceSRobert Watson 
1153eca8a663SRobert Watson 	source = SLOT(cred->cr_label);
115478007886SRobert Watson 	dest = SLOT(pplabel);
1155db2661ceSRobert Watson 
1156db2661ceSRobert Watson 	mac_lomac_copy_single(source, dest);
1157db2661ceSRobert Watson }
1158db2661ceSRobert Watson 
1159db2661ceSRobert Watson static void
116078007886SRobert Watson mac_lomac_create_socket_from_socket(struct socket *oldso,
116178007886SRobert Watson     struct label *oldsolabel, struct socket *newso, struct label *newsolabel)
1162db2661ceSRobert Watson {
1163db2661ceSRobert Watson 	struct mac_lomac *source, *dest;
1164db2661ceSRobert Watson 
116578007886SRobert Watson 	source = SLOT(oldsolabel);
116678007886SRobert Watson 	dest = SLOT(newsolabel);
1167db2661ceSRobert Watson 
1168db2661ceSRobert Watson 	mac_lomac_copy_single(source, dest);
1169db2661ceSRobert Watson }
1170db2661ceSRobert Watson 
1171db2661ceSRobert Watson static void
117278007886SRobert Watson mac_lomac_relabel_socket(struct ucred *cred, struct socket *so,
117378007886SRobert Watson     struct label *solabel, struct label *newlabel)
1174db2661ceSRobert Watson {
1175db2661ceSRobert Watson 	struct mac_lomac *source, *dest;
1176db2661ceSRobert Watson 
1177db2661ceSRobert Watson 	source = SLOT(newlabel);
117878007886SRobert Watson 	dest = SLOT(solabel);
1179db2661ceSRobert Watson 
1180db2661ceSRobert Watson 	try_relabel(source, dest);
1181db2661ceSRobert Watson }
1182db2661ceSRobert Watson 
1183db2661ceSRobert Watson static void
11844795b82cSRobert Watson mac_lomac_relabel_pipe(struct ucred *cred, struct pipepair *pp,
118578007886SRobert Watson     struct label *pplabel, struct label *newlabel)
1186db2661ceSRobert Watson {
1187db2661ceSRobert Watson 	struct mac_lomac *source, *dest;
1188db2661ceSRobert Watson 
1189db2661ceSRobert Watson 	source = SLOT(newlabel);
119078007886SRobert Watson 	dest = SLOT(pplabel);
1191db2661ceSRobert Watson 
1192db2661ceSRobert Watson 	try_relabel(source, dest);
1193db2661ceSRobert Watson }
1194db2661ceSRobert Watson 
1195db2661ceSRobert Watson static void
119678007886SRobert Watson mac_lomac_set_socket_peer_from_mbuf(struct mbuf *m, struct label *mlabel,
119778007886SRobert Watson     struct socket *so, struct label *sopeerlabel)
1198db2661ceSRobert Watson {
1199db2661ceSRobert Watson 	struct mac_lomac *source, *dest;
1200db2661ceSRobert Watson 
120178007886SRobert Watson 	source = SLOT(mlabel);
120278007886SRobert Watson 	dest = SLOT(sopeerlabel);
1203db2661ceSRobert Watson 
1204db2661ceSRobert Watson 	mac_lomac_copy_single(source, dest);
1205db2661ceSRobert Watson }
1206db2661ceSRobert Watson 
1207db2661ceSRobert Watson /*
1208db2661ceSRobert Watson  * Labeling event operations: network objects.
1209db2661ceSRobert Watson  */
1210db2661ceSRobert Watson static void
121178007886SRobert Watson mac_lomac_set_socket_peer_from_socket(struct socket *oldso,
121278007886SRobert Watson     struct label *oldsolabel, struct socket *newso,
121378007886SRobert Watson     struct label *newsopeerlabel)
1214db2661ceSRobert Watson {
1215db2661ceSRobert Watson 	struct mac_lomac *source, *dest;
1216db2661ceSRobert Watson 
121778007886SRobert Watson 	source = SLOT(oldsolabel);
121878007886SRobert Watson 	dest = SLOT(newsopeerlabel);
1219db2661ceSRobert Watson 
1220db2661ceSRobert Watson 	mac_lomac_copy_single(source, dest);
1221db2661ceSRobert Watson }
1222db2661ceSRobert Watson 
1223db2661ceSRobert Watson static void
122478007886SRobert Watson mac_lomac_create_bpfdesc(struct ucred *cred, struct bpf_d *d,
122578007886SRobert Watson     struct label *dlabel)
1226db2661ceSRobert Watson {
1227db2661ceSRobert Watson 	struct mac_lomac *source, *dest;
1228db2661ceSRobert Watson 
1229eca8a663SRobert Watson 	source = SLOT(cred->cr_label);
123078007886SRobert Watson 	dest = SLOT(dlabel);
1231db2661ceSRobert Watson 
1232db2661ceSRobert Watson 	mac_lomac_copy_single(source, dest);
1233db2661ceSRobert Watson }
1234db2661ceSRobert Watson 
1235db2661ceSRobert Watson static void
123678007886SRobert Watson mac_lomac_create_ifnet(struct ifnet *ifp, struct label *ifplabel)
1237db2661ceSRobert Watson {
12389bf40edeSBrooks Davis 	char tifname[IFNAMSIZ], *p, *q;
1239db2661ceSRobert Watson 	char tiflist[sizeof(trusted_interfaces)];
1240db2661ceSRobert Watson 	struct mac_lomac *dest;
1241db2661ceSRobert Watson 	int len, grade;
1242db2661ceSRobert Watson 
124378007886SRobert Watson 	dest = SLOT(ifplabel);
1244db2661ceSRobert Watson 
124578007886SRobert Watson 	if (ifp->if_type == IFT_LOOP) {
1246db2661ceSRobert Watson 		grade = MAC_LOMAC_TYPE_EQUAL;
1247db2661ceSRobert Watson 		goto set;
1248db2661ceSRobert Watson 	}
1249db2661ceSRobert Watson 
1250db2661ceSRobert Watson 	if (trust_all_interfaces) {
1251db2661ceSRobert Watson 		grade = MAC_LOMAC_TYPE_HIGH;
1252db2661ceSRobert Watson 		goto set;
1253db2661ceSRobert Watson 	}
1254db2661ceSRobert Watson 
1255db2661ceSRobert Watson 	grade = MAC_LOMAC_TYPE_LOW;
1256db2661ceSRobert Watson 
1257db2661ceSRobert Watson 	if (trusted_interfaces[0] == '\0' ||
1258db2661ceSRobert Watson 	    !strvalid(trusted_interfaces, sizeof(trusted_interfaces)))
1259db2661ceSRobert Watson 		goto set;
1260db2661ceSRobert Watson 
1261db2661ceSRobert Watson 	bzero(tiflist, sizeof(tiflist));
1262db2661ceSRobert Watson 	for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++)
1263db2661ceSRobert Watson 		if(*p != ' ' && *p != '\t')
1264db2661ceSRobert Watson 			*q = *p;
1265db2661ceSRobert Watson 
1266db2661ceSRobert Watson 	for (p = q = tiflist;; p++) {
1267db2661ceSRobert Watson 		if (*p == ',' || *p == '\0') {
1268db2661ceSRobert Watson 			len = p - q;
1269db2661ceSRobert Watson 			if (len < IFNAMSIZ) {
1270db2661ceSRobert Watson 				bzero(tifname, sizeof(tifname));
1271db2661ceSRobert Watson 				bcopy(q, tifname, len);
127278007886SRobert Watson 				if (strcmp(tifname, ifp->if_xname) == 0) {
1273db2661ceSRobert Watson 					grade = MAC_LOMAC_TYPE_HIGH;
1274db2661ceSRobert Watson 					break;
1275db2661ceSRobert Watson 				}
1276db2661ceSRobert Watson 			}
1277db2661ceSRobert Watson 			else {
1278db2661ceSRobert Watson 				*p = '\0';
1279db2661ceSRobert Watson 				printf("MAC/LOMAC warning: interface name "
1280db2661ceSRobert Watson 				    "\"%s\" is too long (must be < %d)\n",
1281db2661ceSRobert Watson 				    q, IFNAMSIZ);
1282db2661ceSRobert Watson 			}
1283db2661ceSRobert Watson 			if (*p == '\0')
1284db2661ceSRobert Watson 				break;
1285db2661ceSRobert Watson 			q = p + 1;
1286db2661ceSRobert Watson 		}
1287db2661ceSRobert Watson 	}
1288db2661ceSRobert Watson set:
1289db2661ceSRobert Watson 	mac_lomac_set_single(dest, grade, 0);
1290db2661ceSRobert Watson 	mac_lomac_set_range(dest, grade, 0, grade, 0);
1291db2661ceSRobert Watson }
1292db2661ceSRobert Watson 
1293db2661ceSRobert Watson static void
129478007886SRobert Watson mac_lomac_create_ipq(struct mbuf *m, struct label *mlabel, struct ipq *ipq,
129578007886SRobert Watson     struct label *ipqlabel)
1296db2661ceSRobert Watson {
1297db2661ceSRobert Watson 	struct mac_lomac *source, *dest;
1298db2661ceSRobert Watson 
129978007886SRobert Watson 	source = SLOT(mlabel);
1300db2661ceSRobert Watson 	dest = SLOT(ipqlabel);
1301db2661ceSRobert Watson 
1302db2661ceSRobert Watson 	mac_lomac_copy_single(source, dest);
1303db2661ceSRobert Watson }
1304db2661ceSRobert Watson 
1305db2661ceSRobert Watson static void
1306db2661ceSRobert Watson mac_lomac_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel,
130778007886SRobert Watson     struct mbuf *m, struct label *mlabel)
1308db2661ceSRobert Watson {
1309db2661ceSRobert Watson 	struct mac_lomac *source, *dest;
1310db2661ceSRobert Watson 
1311db2661ceSRobert Watson 	source = SLOT(ipqlabel);
131278007886SRobert Watson 	dest = SLOT(mlabel);
1313db2661ceSRobert Watson 
1314db2661ceSRobert Watson 	/* Just use the head, since we require them all to match. */
1315db2661ceSRobert Watson 	mac_lomac_copy_single(source, dest);
1316db2661ceSRobert Watson }
1317db2661ceSRobert Watson 
1318db2661ceSRobert Watson static void
131978007886SRobert Watson mac_lomac_create_fragment(struct mbuf *m, struct label *mlabel,
132078007886SRobert Watson     struct mbuf *frag, struct label *fraglabel)
1321db2661ceSRobert Watson {
1322db2661ceSRobert Watson 	struct mac_lomac *source, *dest;
1323db2661ceSRobert Watson 
132478007886SRobert Watson 	source = SLOT(mlabel);
132578007886SRobert Watson 	dest = SLOT(fraglabel);
1326db2661ceSRobert Watson 
1327db2661ceSRobert Watson 	mac_lomac_copy_single(source, dest);
1328db2661ceSRobert Watson }
1329db2661ceSRobert Watson 
1330db2661ceSRobert Watson static void
13312d92ec98SRobert Watson mac_lomac_create_mbuf_from_inpcb(struct inpcb *inp, struct label *inplabel,
13322d92ec98SRobert Watson     struct mbuf *m, struct label *mlabel)
13332d92ec98SRobert Watson {
13342d92ec98SRobert Watson 	struct mac_lomac *source, *dest;
13352d92ec98SRobert Watson 
13362d92ec98SRobert Watson 	source = SLOT(inplabel);
13372d92ec98SRobert Watson 	dest = SLOT(mlabel);
13382d92ec98SRobert Watson 
13392d92ec98SRobert Watson 	mac_lomac_copy_single(source, dest);
13402d92ec98SRobert Watson }
13412d92ec98SRobert Watson 
13422d92ec98SRobert Watson static void
134378007886SRobert Watson mac_lomac_create_mbuf_linklayer(struct ifnet *ifp, struct label *ifplabel,
134478007886SRobert Watson     struct mbuf *m, struct label *mlabel)
1345db2661ceSRobert Watson {
1346db2661ceSRobert Watson 	struct mac_lomac *dest;
1347db2661ceSRobert Watson 
134878007886SRobert Watson 	dest = SLOT(mlabel);
1349db2661ceSRobert Watson 
1350db2661ceSRobert Watson 	mac_lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0);
1351db2661ceSRobert Watson }
1352db2661ceSRobert Watson 
1353db2661ceSRobert Watson static void
135478007886SRobert Watson mac_lomac_create_mbuf_from_bpfdesc(struct bpf_d *d, struct label *dlabel,
135578007886SRobert Watson     struct mbuf *m, struct label *mlabel)
1356db2661ceSRobert Watson {
1357db2661ceSRobert Watson 	struct mac_lomac *source, *dest;
1358db2661ceSRobert Watson 
135978007886SRobert Watson 	source = SLOT(dlabel);
136078007886SRobert Watson 	dest = SLOT(mlabel);
1361db2661ceSRobert Watson 
1362db2661ceSRobert Watson 	mac_lomac_copy_single(source, dest);
1363db2661ceSRobert Watson }
1364db2661ceSRobert Watson 
1365db2661ceSRobert Watson static void
136678007886SRobert Watson mac_lomac_create_mbuf_from_ifnet(struct ifnet *ifp, struct label *ifplabel,
136778007886SRobert Watson     struct mbuf *m, struct label *mlabel)
1368db2661ceSRobert Watson {
1369db2661ceSRobert Watson 	struct mac_lomac *source, *dest;
1370db2661ceSRobert Watson 
137178007886SRobert Watson 	source = SLOT(ifplabel);
137278007886SRobert Watson 	dest = SLOT(mlabel);
1373db2661ceSRobert Watson 
1374db2661ceSRobert Watson 	mac_lomac_copy_single(source, dest);
1375db2661ceSRobert Watson }
1376db2661ceSRobert Watson 
1377db2661ceSRobert Watson static void
137878007886SRobert Watson mac_lomac_create_mbuf_multicast_encap(struct mbuf *m, struct label *mlabel,
137978007886SRobert Watson     struct ifnet *ifp, struct label *ifplabel, struct mbuf *mnew,
138078007886SRobert Watson     struct label *mnewlabel)
1381db2661ceSRobert Watson {
1382db2661ceSRobert Watson 	struct mac_lomac *source, *dest;
1383db2661ceSRobert Watson 
138478007886SRobert Watson 	source = SLOT(mlabel);
138578007886SRobert Watson 	dest = SLOT(mnewlabel);
1386db2661ceSRobert Watson 
1387db2661ceSRobert Watson 	mac_lomac_copy_single(source, dest);
1388db2661ceSRobert Watson }
1389db2661ceSRobert Watson 
1390db2661ceSRobert Watson static void
139178007886SRobert Watson mac_lomac_create_mbuf_netlayer(struct mbuf *m, struct label *mlabel,
139278007886SRobert Watson     struct mbuf *mnew, struct label *mnewlabel)
1393db2661ceSRobert Watson {
1394db2661ceSRobert Watson 	struct mac_lomac *source, *dest;
1395db2661ceSRobert Watson 
139678007886SRobert Watson 	source = SLOT(mlabel);
139778007886SRobert Watson 	dest = SLOT(mnewlabel);
1398db2661ceSRobert Watson 
1399db2661ceSRobert Watson 	mac_lomac_copy_single(source, dest);
1400db2661ceSRobert Watson }
1401db2661ceSRobert Watson 
1402db2661ceSRobert Watson static int
140378007886SRobert Watson mac_lomac_fragment_match(struct mbuf *m, struct label *mlabel,
1404db2661ceSRobert Watson     struct ipq *ipq, struct label *ipqlabel)
1405db2661ceSRobert Watson {
1406db2661ceSRobert Watson 	struct mac_lomac *a, *b;
1407db2661ceSRobert Watson 
1408db2661ceSRobert Watson 	a = SLOT(ipqlabel);
140978007886SRobert Watson 	b = SLOT(mlabel);
1410db2661ceSRobert Watson 
1411db2661ceSRobert Watson 	return (mac_lomac_equal_single(a, b));
1412db2661ceSRobert Watson }
1413db2661ceSRobert Watson 
1414db2661ceSRobert Watson static void
141578007886SRobert Watson mac_lomac_relabel_ifnet(struct ucred *cred, struct ifnet *ifp,
141678007886SRobert Watson     struct label *ifplabel, struct label *newlabel)
1417db2661ceSRobert Watson {
1418db2661ceSRobert Watson 	struct mac_lomac *source, *dest;
1419db2661ceSRobert Watson 
1420db2661ceSRobert Watson 	source = SLOT(newlabel);
142178007886SRobert Watson 	dest = SLOT(ifplabel);
1422db2661ceSRobert Watson 
1423db2661ceSRobert Watson 	try_relabel(source, dest);
1424db2661ceSRobert Watson }
1425db2661ceSRobert Watson 
1426db2661ceSRobert Watson static void
142778007886SRobert Watson mac_lomac_update_ipq(struct mbuf *m, struct label *mlabel, struct ipq *ipq,
142878007886SRobert Watson     struct label *ipqlabel)
1429db2661ceSRobert Watson {
1430db2661ceSRobert Watson 
1431db2661ceSRobert Watson 	/* NOOP: we only accept matching labels, so no need to update */
1432db2661ceSRobert Watson }
1433db2661ceSRobert Watson 
1434a557af22SRobert Watson static void
1435a557af22SRobert Watson mac_lomac_inpcb_sosetlabel(struct socket *so, struct label *solabel,
1436a557af22SRobert Watson     struct inpcb *inp, struct label *inplabel)
1437a557af22SRobert Watson {
1438a557af22SRobert Watson 	struct mac_lomac *source, *dest;
1439a557af22SRobert Watson 
1440a557af22SRobert Watson 	source = SLOT(solabel);
1441a557af22SRobert Watson 	dest = SLOT(inplabel);
1442a557af22SRobert Watson 
1443a557af22SRobert Watson 	mac_lomac_copy_single(source, dest);
1444a557af22SRobert Watson }
1445a557af22SRobert Watson 
1446d94f2a68SChristian S.J. Peron static void
1447430fc756SChristian S.J. Peron mac_lomac_init_syncache_from_inpcb(struct label *label, struct inpcb *inp)
1448430fc756SChristian S.J. Peron {
1449430fc756SChristian S.J. Peron 	struct mac_lomac *source, *dest;
1450430fc756SChristian S.J. Peron 
1451430fc756SChristian S.J. Peron 	source = SLOT(inp->inp_label);
1452430fc756SChristian S.J. Peron 	dest = SLOT(label);
1453430fc756SChristian S.J. Peron 	mac_lomac_copy(source, dest);
1454430fc756SChristian S.J. Peron }
1455430fc756SChristian S.J. Peron 
1456430fc756SChristian S.J. Peron static void
1457430fc756SChristian S.J. Peron mac_lomac_create_mbuf_from_syncache(struct label *sc_label, struct mbuf *m,
145878007886SRobert Watson     struct label *mlabel)
1459430fc756SChristian S.J. Peron {
1460430fc756SChristian S.J. Peron 	struct mac_lomac *source, *dest;
1461430fc756SChristian S.J. Peron 
1462430fc756SChristian S.J. Peron 	source = SLOT(sc_label);
146378007886SRobert Watson 	dest = SLOT(mlabel);
1464430fc756SChristian S.J. Peron 	mac_lomac_copy(source, dest);
1465430fc756SChristian S.J. Peron }
1466430fc756SChristian S.J. Peron 
1467430fc756SChristian S.J. Peron static void
146878007886SRobert Watson mac_lomac_create_mbuf_from_firewall(struct mbuf *m, struct label *mlabel)
1469d94f2a68SChristian S.J. Peron {
1470d94f2a68SChristian S.J. Peron 	struct mac_lomac *dest;
1471d94f2a68SChristian S.J. Peron 
147278007886SRobert Watson 	dest = SLOT(mlabel);
1473d94f2a68SChristian S.J. Peron 
1474d94f2a68SChristian S.J. Peron 	/* XXX: where is the label for the firewall really comming from? */
1475d94f2a68SChristian S.J. Peron 	mac_lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0);
1476d94f2a68SChristian S.J. Peron }
1477d94f2a68SChristian S.J. Peron 
1478db2661ceSRobert Watson /*
1479db2661ceSRobert Watson  * Labeling event operations: processes.
1480db2661ceSRobert Watson  */
1481db2661ceSRobert Watson static void
1482db2661ceSRobert Watson mac_lomac_execve_transition(struct ucred *old, struct ucred *new,
148378007886SRobert Watson     struct vnode *vp, struct label *vplabel, struct label *interpvnodelabel,
148478007886SRobert Watson     struct image_params *imgp, struct label *execlabel)
1485db2661ceSRobert Watson {
1486db2661ceSRobert Watson 	struct mac_lomac *source, *dest, *obj, *robj;
1487db2661ceSRobert Watson 
1488eca8a663SRobert Watson 	source = SLOT(old->cr_label);
1489eca8a663SRobert Watson 	dest = SLOT(new->cr_label);
149078007886SRobert Watson 	obj = SLOT(vplabel);
1491db2661ceSRobert Watson 	robj = interpvnodelabel != NULL ? SLOT(interpvnodelabel) : obj;
1492db2661ceSRobert Watson 
1493db2661ceSRobert Watson 	mac_lomac_copy(source, dest);
1494db2661ceSRobert Watson 	/*
1495db2661ceSRobert Watson 	 * If there's an auxiliary label on the real object, respect it
1496db2661ceSRobert Watson 	 * and assume that this level should be assumed immediately if
1497db2661ceSRobert Watson 	 * a higher level is currently in place.
1498db2661ceSRobert Watson 	 */
1499db2661ceSRobert Watson 	if (robj->ml_flags & MAC_LOMAC_FLAG_AUX &&
1500db2661ceSRobert Watson 	    !mac_lomac_dominate_element(&robj->ml_auxsingle, &dest->ml_single)
1501db2661ceSRobert Watson 	    && mac_lomac_auxsingle_in_range(robj, dest))
1502db2661ceSRobert Watson 		mac_lomac_set_single(dest, robj->ml_auxsingle.mle_type,
1503db2661ceSRobert Watson 		    robj->ml_auxsingle.mle_grade);
1504db2661ceSRobert Watson 	/*
1505db2661ceSRobert Watson 	 * Restructuring to use the execve transitioning mechanism
1506db2661ceSRobert Watson 	 * instead of the normal demotion mechanism here would be
1507db2661ceSRobert Watson 	 * difficult, so just copy the label over and perform standard
1508db2661ceSRobert Watson 	 * demotion.  This is also non-optimal because it will result
1509db2661ceSRobert Watson 	 * in the intermediate label "new" being created and immediately
1510db2661ceSRobert Watson 	 * recycled.
1511db2661ceSRobert Watson 	 */
1512db2661ceSRobert Watson 	if (mac_lomac_enabled && revocation_enabled &&
1513db2661ceSRobert Watson 	    !mac_lomac_dominate_single(obj, source))
1514db2661ceSRobert Watson 		(void)maybe_demote(source, obj, "executing", "file", vp);
1515db2661ceSRobert Watson }
1516db2661ceSRobert Watson 
1517db2661ceSRobert Watson static int
1518db2661ceSRobert Watson mac_lomac_execve_will_transition(struct ucred *old, struct vnode *vp,
151978007886SRobert Watson     struct label *vplabel, struct label *interpvnodelabel,
1520db2661ceSRobert Watson     struct image_params *imgp, struct label *execlabel)
1521db2661ceSRobert Watson {
1522db2661ceSRobert Watson 	struct mac_lomac *subj, *obj, *robj;
1523db2661ceSRobert Watson 
1524db2661ceSRobert Watson 	if (!mac_lomac_enabled || !revocation_enabled)
1525db2661ceSRobert Watson 		return (0);
1526db2661ceSRobert Watson 
1527eca8a663SRobert Watson 	subj = SLOT(old->cr_label);
152878007886SRobert Watson 	obj = SLOT(vplabel);
1529db2661ceSRobert Watson 	robj = interpvnodelabel != NULL ? SLOT(interpvnodelabel) : obj;
1530db2661ceSRobert Watson 
1531db2661ceSRobert Watson 	return ((robj->ml_flags & MAC_LOMAC_FLAG_AUX &&
1532db2661ceSRobert Watson 	    !mac_lomac_dominate_element(&robj->ml_auxsingle, &subj->ml_single)
1533db2661ceSRobert Watson 	    && mac_lomac_auxsingle_in_range(robj, subj)) ||
1534db2661ceSRobert Watson 	    !mac_lomac_dominate_single(obj, subj));
1535db2661ceSRobert Watson }
1536db2661ceSRobert Watson 
1537db2661ceSRobert Watson static void
1538db2661ceSRobert Watson mac_lomac_create_proc0(struct ucred *cred)
1539db2661ceSRobert Watson {
1540db2661ceSRobert Watson 	struct mac_lomac *dest;
1541db2661ceSRobert Watson 
1542eca8a663SRobert Watson 	dest = SLOT(cred->cr_label);
1543db2661ceSRobert Watson 
1544db2661ceSRobert Watson 	mac_lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0);
1545db2661ceSRobert Watson 	mac_lomac_set_range(dest, MAC_LOMAC_TYPE_LOW, 0, MAC_LOMAC_TYPE_HIGH,
1546db2661ceSRobert Watson 	    0);
1547db2661ceSRobert Watson }
1548db2661ceSRobert Watson 
1549db2661ceSRobert Watson static void
1550db2661ceSRobert Watson mac_lomac_create_proc1(struct ucred *cred)
1551db2661ceSRobert Watson {
1552db2661ceSRobert Watson 	struct mac_lomac *dest;
1553db2661ceSRobert Watson 
1554eca8a663SRobert Watson 	dest = SLOT(cred->cr_label);
1555db2661ceSRobert Watson 
1556db2661ceSRobert Watson 	mac_lomac_set_single(dest, MAC_LOMAC_TYPE_HIGH, 0);
1557db2661ceSRobert Watson 	mac_lomac_set_range(dest, MAC_LOMAC_TYPE_LOW, 0, MAC_LOMAC_TYPE_HIGH,
1558db2661ceSRobert Watson 	    0);
1559db2661ceSRobert Watson }
1560db2661ceSRobert Watson 
1561db2661ceSRobert Watson static void
1562db2661ceSRobert Watson mac_lomac_relabel_cred(struct ucred *cred, struct label *newlabel)
1563db2661ceSRobert Watson {
1564db2661ceSRobert Watson 	struct mac_lomac *source, *dest;
1565db2661ceSRobert Watson 
1566db2661ceSRobert Watson 	source = SLOT(newlabel);
1567eca8a663SRobert Watson 	dest = SLOT(cred->cr_label);
1568db2661ceSRobert Watson 
1569db2661ceSRobert Watson 	try_relabel(source, dest);
1570db2661ceSRobert Watson }
1571db2661ceSRobert Watson 
1572db2661ceSRobert Watson /*
1573db2661ceSRobert Watson  * Access control checks.
1574db2661ceSRobert Watson  */
1575db2661ceSRobert Watson static int
157678007886SRobert Watson mac_lomac_check_bpfdesc_receive(struct bpf_d *d, struct label *dlabel,
157778007886SRobert Watson     struct ifnet *ifp, struct label *ifplabel)
1578db2661ceSRobert Watson {
1579db2661ceSRobert Watson 	struct mac_lomac *a, *b;
1580db2661ceSRobert Watson 
1581db2661ceSRobert Watson 	if (!mac_lomac_enabled)
1582db2661ceSRobert Watson 		return (0);
1583db2661ceSRobert Watson 
158478007886SRobert Watson 	a = SLOT(dlabel);
158578007886SRobert Watson 	b = SLOT(ifplabel);
1586db2661ceSRobert Watson 
1587db2661ceSRobert Watson 	if (mac_lomac_equal_single(a, b))
1588db2661ceSRobert Watson 		return (0);
1589db2661ceSRobert Watson 	return (EACCES);
1590db2661ceSRobert Watson }
1591db2661ceSRobert Watson 
1592db2661ceSRobert Watson static int
1593db2661ceSRobert Watson mac_lomac_check_cred_relabel(struct ucred *cred, struct label *newlabel)
1594db2661ceSRobert Watson {
1595db2661ceSRobert Watson 	struct mac_lomac *subj, *new;
1596db2661ceSRobert Watson 	int error;
1597db2661ceSRobert Watson 
1598eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
1599db2661ceSRobert Watson 	new = SLOT(newlabel);
1600db2661ceSRobert Watson 
1601db2661ceSRobert Watson 	/*
1602db2661ceSRobert Watson 	 * If there is a LOMAC label update for the credential, it may
1603db2661ceSRobert Watson 	 * be an update of the single, range, or both.
1604db2661ceSRobert Watson 	 */
1605db2661ceSRobert Watson 	error = lomac_atmostflags(new, MAC_LOMAC_FLAGS_BOTH);
1606db2661ceSRobert Watson 	if (error)
1607db2661ceSRobert Watson 		return (error);
1608db2661ceSRobert Watson 
1609db2661ceSRobert Watson 	/*
1610db2661ceSRobert Watson 	 * If the LOMAC label is to be changed, authorize as appropriate.
1611db2661ceSRobert Watson 	 */
1612db2661ceSRobert Watson 	if (new->ml_flags & MAC_LOMAC_FLAGS_BOTH) {
1613db2661ceSRobert Watson 		/*
161484bdb083SRobert Watson 		 * Fill in the missing parts from the previous label.
1615db2661ceSRobert Watson 		 */
161684bdb083SRobert Watson 		if ((new->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0)
161784bdb083SRobert Watson 			mac_lomac_copy_single(subj, new);
161884bdb083SRobert Watson 		if ((new->ml_flags & MAC_LOMAC_FLAG_RANGE) == 0)
161984bdb083SRobert Watson 			mac_lomac_copy_range(subj, new);
1620db2661ceSRobert Watson 
1621db2661ceSRobert Watson 		/*
1622db2661ceSRobert Watson 		 * To change the LOMAC range on a credential, the new
1623db2661ceSRobert Watson 		 * range label must be in the current range.
1624db2661ceSRobert Watson 		 */
162584bdb083SRobert Watson 		if (!mac_lomac_range_in_range(new, subj))
162684bdb083SRobert Watson 			return (EPERM);
162784bdb083SRobert Watson 
162884bdb083SRobert Watson 		/*
162984bdb083SRobert Watson 		 * To change the LOMAC single label on a credential, the
163084bdb083SRobert Watson 		 * new single label must be in the new range.  Implicitly
163184bdb083SRobert Watson 		 * from the previous check, the new single is in the old
163284bdb083SRobert Watson 		 * range.
163384bdb083SRobert Watson 		 */
163484bdb083SRobert Watson 		if (!mac_lomac_single_in_range(new, new))
1635db2661ceSRobert Watson 			return (EPERM);
1636db2661ceSRobert Watson 
1637db2661ceSRobert Watson 		/*
1638db2661ceSRobert Watson 		 * To have EQUAL in any component of the new credential
1639db2661ceSRobert Watson 		 * LOMAC label, the subject must already have EQUAL in
1640db2661ceSRobert Watson 		 * their label.
1641db2661ceSRobert Watson 		 */
1642db2661ceSRobert Watson 		if (mac_lomac_contains_equal(new)) {
1643db2661ceSRobert Watson 			error = mac_lomac_subject_privileged(subj);
1644db2661ceSRobert Watson 			if (error)
1645db2661ceSRobert Watson 				return (error);
1646db2661ceSRobert Watson 		}
1647db2661ceSRobert Watson 
1648db2661ceSRobert Watson 		/*
1649db2661ceSRobert Watson 		 * XXXMAC: Additional consistency tests regarding the
1650db2661ceSRobert Watson 		 * single and range of the new label might be performed
1651db2661ceSRobert Watson 		 * here.
1652db2661ceSRobert Watson 		 */
1653db2661ceSRobert Watson 	}
1654db2661ceSRobert Watson 
1655db2661ceSRobert Watson 	return (0);
1656db2661ceSRobert Watson }
1657db2661ceSRobert Watson 
1658db2661ceSRobert Watson static int
165978007886SRobert Watson mac_lomac_check_cred_visible(struct ucred *cr1, struct ucred *cr2)
1660db2661ceSRobert Watson {
1661db2661ceSRobert Watson 	struct mac_lomac *subj, *obj;
1662db2661ceSRobert Watson 
1663db2661ceSRobert Watson 	if (!mac_lomac_enabled)
1664db2661ceSRobert Watson 		return (0);
1665db2661ceSRobert Watson 
166678007886SRobert Watson 	subj = SLOT(cr1->cr_label);
166778007886SRobert Watson 	obj = SLOT(cr2->cr_label);
1668db2661ceSRobert Watson 
1669db2661ceSRobert Watson 	/* XXX: range */
1670db2661ceSRobert Watson 	if (!mac_lomac_dominate_single(obj, subj))
1671db2661ceSRobert Watson 		return (ESRCH);
1672db2661ceSRobert Watson 
1673db2661ceSRobert Watson 	return (0);
1674db2661ceSRobert Watson }
1675db2661ceSRobert Watson 
1676db2661ceSRobert Watson static int
167778007886SRobert Watson mac_lomac_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifp,
167878007886SRobert Watson     struct label *ifplabel, struct label *newlabel)
1679db2661ceSRobert Watson {
1680db2661ceSRobert Watson 	struct mac_lomac *subj, *new;
1681db2661ceSRobert Watson 	int error;
1682db2661ceSRobert Watson 
1683eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
1684db2661ceSRobert Watson 	new = SLOT(newlabel);
1685db2661ceSRobert Watson 
1686db2661ceSRobert Watson 	/*
1687db2661ceSRobert Watson 	 * If there is a LOMAC label update for the interface, it may
1688db2661ceSRobert Watson 	 * be an update of the single, range, or both.
1689db2661ceSRobert Watson 	 */
1690db2661ceSRobert Watson 	error = lomac_atmostflags(new, MAC_LOMAC_FLAGS_BOTH);
1691db2661ceSRobert Watson 	if (error)
1692db2661ceSRobert Watson 		return (error);
1693db2661ceSRobert Watson 
1694db2661ceSRobert Watson 	/*
1695db2661ceSRobert Watson 	 * Relabling network interfaces requires LOMAC privilege.
1696db2661ceSRobert Watson 	 */
1697db2661ceSRobert Watson 	error = mac_lomac_subject_privileged(subj);
1698db2661ceSRobert Watson 	if (error)
1699db2661ceSRobert Watson 		return (error);
1700db2661ceSRobert Watson 
1701db2661ceSRobert Watson 	/*
1702db2661ceSRobert Watson 	 * If the LOMAC label is to be changed, authorize as appropriate.
1703db2661ceSRobert Watson 	 */
1704db2661ceSRobert Watson 	if (new->ml_flags & MAC_LOMAC_FLAGS_BOTH) {
1705db2661ceSRobert Watson 		/*
170684bdb083SRobert Watson 		 * Fill in the missing parts from the previous label.
170784bdb083SRobert Watson 		 */
170884bdb083SRobert Watson 		if ((new->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0)
170984bdb083SRobert Watson 			mac_lomac_copy_single(subj, new);
171084bdb083SRobert Watson 		if ((new->ml_flags & MAC_LOMAC_FLAG_RANGE) == 0)
171184bdb083SRobert Watson 			mac_lomac_copy_range(subj, new);
171284bdb083SRobert Watson 
171384bdb083SRobert Watson 		/*
1714db2661ceSRobert Watson 		 * Rely on the traditional superuser status for the LOMAC
1715db2661ceSRobert Watson 		 * interface relabel requirements.  XXXMAC: This will go
1716db2661ceSRobert Watson 		 * away.
1717acd3428bSRobert Watson 		 *
1718acd3428bSRobert Watson 		 * XXXRW: This is also redundant to a higher layer check.
1719db2661ceSRobert Watson 		 */
1720acd3428bSRobert Watson 		error = priv_check_cred(cred, PRIV_NET_SETIFMAC, 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
173478007886SRobert Watson mac_lomac_check_ifnet_transmit(struct ifnet *ifp, struct label *ifplabel,
173578007886SRobert Watson     struct mbuf *m, struct label *mlabel)
1736db2661ceSRobert Watson {
1737db2661ceSRobert Watson 	struct mac_lomac *p, *i;
1738db2661ceSRobert Watson 
1739db2661ceSRobert Watson 	if (!mac_lomac_enabled)
1740db2661ceSRobert Watson 		return (0);
1741db2661ceSRobert Watson 
174278007886SRobert Watson 	p = SLOT(mlabel);
174378007886SRobert Watson 	i = SLOT(ifplabel);
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,
176578007886SRobert Watson     struct label *vplabel)
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);
177378007886SRobert Watson 	obj = SLOT(vplabel);
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
17854795b82cSRobert Watson mac_lomac_check_pipe_ioctl(struct ucred *cred, struct pipepair *pp,
178678007886SRobert Watson     struct label *pplabel, unsigned long cmd, void /* caddr_t */ *data)
1787db2661ceSRobert Watson {
1788db2661ceSRobert Watson 
1789db2661ceSRobert Watson 	if (!mac_lomac_enabled)
1790db2661ceSRobert Watson 		return (0);
1791db2661ceSRobert Watson 
1792db2661ceSRobert Watson 	/* XXX: This will be implemented soon... */
1793db2661ceSRobert Watson 
1794db2661ceSRobert Watson 	return (0);
1795db2661ceSRobert Watson }
1796db2661ceSRobert Watson 
1797db2661ceSRobert Watson static int
17984795b82cSRobert Watson mac_lomac_check_pipe_read(struct ucred *cred, struct pipepair *pp,
179978007886SRobert Watson     struct label *pplabel)
1800db2661ceSRobert Watson {
1801db2661ceSRobert Watson 	struct mac_lomac *subj, *obj;
1802db2661ceSRobert Watson 
1803db2661ceSRobert Watson 	if (!mac_lomac_enabled)
1804db2661ceSRobert Watson 		return (0);
1805db2661ceSRobert Watson 
1806eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
180778007886SRobert Watson 	obj = SLOT(pplabel);
1808db2661ceSRobert Watson 
1809db2661ceSRobert Watson 	if (!mac_lomac_dominate_single(obj, subj))
1810db2661ceSRobert Watson 		return (maybe_demote(subj, obj, "reading", "pipe", NULL));
1811db2661ceSRobert Watson 
1812db2661ceSRobert Watson 	return (0);
1813db2661ceSRobert Watson }
1814db2661ceSRobert Watson 
1815db2661ceSRobert Watson static int
18164795b82cSRobert Watson mac_lomac_check_pipe_relabel(struct ucred *cred, struct pipepair *pp,
181778007886SRobert Watson     struct label *pplabel, struct label *newlabel)
1818db2661ceSRobert Watson {
1819db2661ceSRobert Watson 	struct mac_lomac *subj, *obj, *new;
1820db2661ceSRobert Watson 	int error;
1821db2661ceSRobert Watson 
1822db2661ceSRobert Watson 	new = SLOT(newlabel);
1823eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
182478007886SRobert Watson 	obj = SLOT(pplabel);
1825db2661ceSRobert Watson 
1826db2661ceSRobert Watson 	/*
1827db2661ceSRobert Watson 	 * If there is a LOMAC label update for a pipe, it must be a
1828db2661ceSRobert Watson 	 * single update.
1829db2661ceSRobert Watson 	 */
1830db2661ceSRobert Watson 	error = lomac_atmostflags(new, MAC_LOMAC_FLAG_SINGLE);
1831db2661ceSRobert Watson 	if (error)
1832db2661ceSRobert Watson 		return (error);
1833db2661ceSRobert Watson 
1834db2661ceSRobert Watson 	/*
1835db2661ceSRobert Watson 	 * To perform a relabel of a pipe (LOMAC label or not), LOMAC must
1836db2661ceSRobert Watson 	 * authorize the relabel.
1837db2661ceSRobert Watson 	 */
1838db2661ceSRobert Watson 	if (!mac_lomac_single_in_range(obj, subj))
1839db2661ceSRobert Watson 		return (EPERM);
1840db2661ceSRobert Watson 
1841db2661ceSRobert Watson 	/*
1842db2661ceSRobert Watson 	 * If the LOMAC label is to be changed, authorize as appropriate.
1843db2661ceSRobert Watson 	 */
1844db2661ceSRobert Watson 	if (new->ml_flags & MAC_LOMAC_FLAG_SINGLE) {
1845db2661ceSRobert Watson 		/*
1846db2661ceSRobert Watson 		 * To change the LOMAC label on a pipe, the new pipe label
1847db2661ceSRobert Watson 		 * must be in the subject range.
1848db2661ceSRobert Watson 		 */
1849db2661ceSRobert Watson 		if (!mac_lomac_single_in_range(new, subj))
1850db2661ceSRobert Watson 			return (EPERM);
1851db2661ceSRobert Watson 
1852db2661ceSRobert Watson 		/*
1853db2661ceSRobert Watson 		 * To change the LOMAC label on a pipe to be EQUAL, the
1854db2661ceSRobert Watson 		 * subject must have appropriate privilege.
1855db2661ceSRobert Watson 		 */
1856db2661ceSRobert Watson 		if (mac_lomac_contains_equal(new)) {
1857db2661ceSRobert Watson 			error = mac_lomac_subject_privileged(subj);
1858db2661ceSRobert Watson 			if (error)
1859db2661ceSRobert Watson 				return (error);
1860db2661ceSRobert Watson 		}
1861db2661ceSRobert Watson 	}
1862db2661ceSRobert Watson 
1863db2661ceSRobert Watson 	return (0);
1864db2661ceSRobert Watson }
1865db2661ceSRobert Watson 
1866db2661ceSRobert Watson static int
18674795b82cSRobert Watson mac_lomac_check_pipe_write(struct ucred *cred, struct pipepair *pp,
186878007886SRobert Watson     struct label *pplabel)
1869db2661ceSRobert Watson {
1870db2661ceSRobert Watson 	struct mac_lomac *subj, *obj;
1871db2661ceSRobert Watson 
1872db2661ceSRobert Watson 	if (!mac_lomac_enabled)
1873db2661ceSRobert Watson 		return (0);
1874db2661ceSRobert Watson 
1875eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
187678007886SRobert Watson 	obj = SLOT(pplabel);
1877db2661ceSRobert Watson 
1878db2661ceSRobert Watson 	if (!mac_lomac_subject_dominate(subj, obj))
1879db2661ceSRobert Watson 		return (EACCES);
1880db2661ceSRobert Watson 
1881db2661ceSRobert Watson 	return (0);
1882db2661ceSRobert Watson }
1883db2661ceSRobert Watson 
1884db2661ceSRobert Watson static int
188578007886SRobert Watson mac_lomac_check_proc_debug(struct ucred *cred, struct proc *p)
1886db2661ceSRobert Watson {
1887db2661ceSRobert Watson 	struct mac_lomac *subj, *obj;
1888db2661ceSRobert Watson 
1889db2661ceSRobert Watson 	if (!mac_lomac_enabled)
1890db2661ceSRobert Watson 		return (0);
1891db2661ceSRobert Watson 
1892eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
189378007886SRobert Watson 	obj = SLOT(p->p_ucred->cr_label);
1894db2661ceSRobert Watson 
1895db2661ceSRobert Watson 	/* XXX: range checks */
1896db2661ceSRobert Watson 	if (!mac_lomac_dominate_single(obj, subj))
1897db2661ceSRobert Watson 		return (ESRCH);
1898db2661ceSRobert Watson 	if (!mac_lomac_subject_dominate(subj, obj))
1899db2661ceSRobert Watson 		return (EACCES);
1900db2661ceSRobert Watson 
1901db2661ceSRobert Watson 	return (0);
1902db2661ceSRobert Watson }
1903db2661ceSRobert Watson 
1904db2661ceSRobert Watson static int
190578007886SRobert Watson mac_lomac_check_proc_sched(struct ucred *cred, struct proc *p)
1906db2661ceSRobert Watson {
1907db2661ceSRobert Watson 	struct mac_lomac *subj, *obj;
1908db2661ceSRobert Watson 
1909db2661ceSRobert Watson 	if (!mac_lomac_enabled)
1910db2661ceSRobert Watson 		return (0);
1911db2661ceSRobert Watson 
1912eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
191378007886SRobert Watson 	obj = SLOT(p->p_ucred->cr_label);
1914db2661ceSRobert Watson 
1915db2661ceSRobert Watson 	/* XXX: range checks */
1916db2661ceSRobert Watson 	if (!mac_lomac_dominate_single(obj, subj))
1917db2661ceSRobert Watson 		return (ESRCH);
1918db2661ceSRobert Watson 	if (!mac_lomac_subject_dominate(subj, obj))
1919db2661ceSRobert Watson 		return (EACCES);
1920db2661ceSRobert Watson 
1921db2661ceSRobert Watson 	return (0);
1922db2661ceSRobert Watson }
1923db2661ceSRobert Watson 
1924db2661ceSRobert Watson static int
192578007886SRobert Watson mac_lomac_check_proc_signal(struct ucred *cred, struct proc *p, int signum)
1926db2661ceSRobert Watson {
1927db2661ceSRobert Watson 	struct mac_lomac *subj, *obj;
1928db2661ceSRobert Watson 
1929db2661ceSRobert Watson 	if (!mac_lomac_enabled)
1930db2661ceSRobert Watson 		return (0);
1931db2661ceSRobert Watson 
1932eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
193378007886SRobert Watson 	obj = SLOT(p->p_ucred->cr_label);
1934db2661ceSRobert Watson 
1935db2661ceSRobert Watson 	/* XXX: range checks */
1936db2661ceSRobert Watson 	if (!mac_lomac_dominate_single(obj, subj))
1937db2661ceSRobert Watson 		return (ESRCH);
1938db2661ceSRobert Watson 	if (!mac_lomac_subject_dominate(subj, obj))
1939db2661ceSRobert Watson 		return (EACCES);
1940db2661ceSRobert Watson 
1941db2661ceSRobert Watson 	return (0);
1942db2661ceSRobert Watson }
1943db2661ceSRobert Watson 
1944db2661ceSRobert Watson static int
194578007886SRobert Watson mac_lomac_check_socket_deliver(struct socket *so, struct label *solabel,
194678007886SRobert Watson     struct mbuf *m, struct label *mlabel)
1947db2661ceSRobert Watson {
1948db2661ceSRobert Watson 	struct mac_lomac *p, *s;
1949db2661ceSRobert Watson 
1950db2661ceSRobert Watson 	if (!mac_lomac_enabled)
1951db2661ceSRobert Watson 		return (0);
1952db2661ceSRobert Watson 
195378007886SRobert Watson 	p = SLOT(mlabel);
195478007886SRobert Watson 	s = SLOT(solabel);
1955db2661ceSRobert Watson 
1956db2661ceSRobert Watson 	return (mac_lomac_equal_single(p, s) ? 0 : EACCES);
1957db2661ceSRobert Watson }
1958db2661ceSRobert Watson 
1959db2661ceSRobert Watson static int
196078007886SRobert Watson mac_lomac_check_socket_relabel(struct ucred *cred, struct socket *so,
196178007886SRobert Watson     struct label *solabel, struct label *newlabel)
1962db2661ceSRobert Watson {
1963db2661ceSRobert Watson 	struct mac_lomac *subj, *obj, *new;
1964db2661ceSRobert Watson 	int error;
1965db2661ceSRobert Watson 
1966db2661ceSRobert Watson 	new = SLOT(newlabel);
1967eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
196878007886SRobert Watson 	obj = SLOT(solabel);
1969db2661ceSRobert Watson 
1970db2661ceSRobert Watson 	/*
1971db2661ceSRobert Watson 	 * If there is a LOMAC label update for the socket, it may be
1972db2661ceSRobert Watson 	 * an update of single.
1973db2661ceSRobert Watson 	 */
1974db2661ceSRobert Watson 	error = lomac_atmostflags(new, MAC_LOMAC_FLAG_SINGLE);
1975db2661ceSRobert Watson 	if (error)
1976db2661ceSRobert Watson 		return (error);
1977db2661ceSRobert Watson 
1978db2661ceSRobert Watson 	/*
1979db2661ceSRobert Watson 	 * To relabel a socket, the old socket single must be in the subject
1980db2661ceSRobert Watson 	 * range.
1981db2661ceSRobert Watson 	 */
1982db2661ceSRobert Watson 	if (!mac_lomac_single_in_range(obj, subj))
1983db2661ceSRobert Watson 		return (EPERM);
1984db2661ceSRobert Watson 
1985db2661ceSRobert Watson 	/*
1986db2661ceSRobert Watson 	 * If the LOMAC label is to be changed, authorize as appropriate.
1987db2661ceSRobert Watson 	 */
1988db2661ceSRobert Watson 	if (new->ml_flags & MAC_LOMAC_FLAG_SINGLE) {
1989db2661ceSRobert Watson 		/*
1990db2661ceSRobert Watson 		 * To relabel a socket, the new socket single must be in
1991db2661ceSRobert Watson 		 * the subject range.
1992db2661ceSRobert Watson 		 */
1993db2661ceSRobert Watson 		if (!mac_lomac_single_in_range(new, subj))
1994db2661ceSRobert Watson 			return (EPERM);
1995db2661ceSRobert Watson 
1996db2661ceSRobert Watson 		/*
1997db2661ceSRobert Watson 		 * To change the LOMAC label on the socket to contain EQUAL,
1998db2661ceSRobert Watson 		 * the subject must have appropriate privilege.
1999db2661ceSRobert Watson 		 */
2000db2661ceSRobert Watson 		if (mac_lomac_contains_equal(new)) {
2001db2661ceSRobert Watson 			error = mac_lomac_subject_privileged(subj);
2002db2661ceSRobert Watson 			if (error)
2003db2661ceSRobert Watson 				return (error);
2004db2661ceSRobert Watson 		}
2005db2661ceSRobert Watson 	}
2006db2661ceSRobert Watson 
2007db2661ceSRobert Watson 	return (0);
2008db2661ceSRobert Watson }
2009db2661ceSRobert Watson 
2010db2661ceSRobert Watson static int
201178007886SRobert Watson mac_lomac_check_socket_visible(struct ucred *cred, struct socket *so,
201278007886SRobert Watson     struct label *solabel)
2013db2661ceSRobert Watson {
2014db2661ceSRobert Watson 	struct mac_lomac *subj, *obj;
2015db2661ceSRobert Watson 
2016db2661ceSRobert Watson 	if (!mac_lomac_enabled)
2017db2661ceSRobert Watson 		return (0);
2018db2661ceSRobert Watson 
2019eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
202078007886SRobert Watson 	obj = SLOT(solabel);
2021db2661ceSRobert Watson 
2022db2661ceSRobert Watson 	if (!mac_lomac_dominate_single(obj, subj))
2023db2661ceSRobert Watson 		return (ENOENT);
2024db2661ceSRobert Watson 
2025db2661ceSRobert Watson 	return (0);
2026db2661ceSRobert Watson }
2027db2661ceSRobert Watson 
2028c14d15aeSRobert Watson /*
2029c14d15aeSRobert Watson  * Some system privileges are allowed regardless of integrity grade; others
2030c14d15aeSRobert Watson  * are allowed only when running with privilege with respect to the LOMAC
2031c14d15aeSRobert Watson  * policy as they might otherwise allow bypassing of the integrity policy.
2032c14d15aeSRobert Watson  */
2033c14d15aeSRobert Watson static int
2034c14d15aeSRobert Watson mac_lomac_priv_check(struct ucred *cred, int priv)
2035c14d15aeSRobert Watson {
2036c14d15aeSRobert Watson 	struct mac_lomac *subj;
2037c14d15aeSRobert Watson 	int error;
2038c14d15aeSRobert Watson 
2039c14d15aeSRobert Watson 	if (!mac_lomac_enabled)
2040c14d15aeSRobert Watson 		return (0);
2041c14d15aeSRobert Watson 
2042c14d15aeSRobert Watson 	/*
2043c14d15aeSRobert Watson 	 * Exempt only specific privileges from the LOMAC integrity policy.
2044c14d15aeSRobert Watson 	 */
2045c14d15aeSRobert Watson 	switch (priv) {
2046c14d15aeSRobert Watson 	case PRIV_KTRACE:
2047c14d15aeSRobert Watson 	case PRIV_MSGBUF:
2048c14d15aeSRobert Watson 
2049c14d15aeSRobert Watson 	/*
2050c14d15aeSRobert Watson 	 * Allow processes to manipulate basic process audit properties, and
2051c14d15aeSRobert Watson 	 * to submit audit records.
2052c14d15aeSRobert Watson 	 */
2053c14d15aeSRobert Watson 	case PRIV_AUDIT_GETAUDIT:
2054c14d15aeSRobert Watson 	case PRIV_AUDIT_SETAUDIT:
2055c14d15aeSRobert Watson 	case PRIV_AUDIT_SUBMIT:
2056c14d15aeSRobert Watson 
2057c14d15aeSRobert Watson 	/*
2058c14d15aeSRobert Watson 	 * Allow processes to manipulate their regular UNIX credentials.
2059c14d15aeSRobert Watson 	 */
2060c14d15aeSRobert Watson 	case PRIV_CRED_SETUID:
2061c14d15aeSRobert Watson 	case PRIV_CRED_SETEUID:
2062c14d15aeSRobert Watson 	case PRIV_CRED_SETGID:
2063c14d15aeSRobert Watson 	case PRIV_CRED_SETEGID:
2064c14d15aeSRobert Watson 	case PRIV_CRED_SETGROUPS:
2065c14d15aeSRobert Watson 	case PRIV_CRED_SETREUID:
2066c14d15aeSRobert Watson 	case PRIV_CRED_SETREGID:
2067c14d15aeSRobert Watson 	case PRIV_CRED_SETRESUID:
2068c14d15aeSRobert Watson 	case PRIV_CRED_SETRESGID:
2069c14d15aeSRobert Watson 
2070c14d15aeSRobert Watson 	/*
2071c14d15aeSRobert Watson 	 * Allow processes to perform system monitoring.
2072c14d15aeSRobert Watson 	 */
2073c14d15aeSRobert Watson 	case PRIV_SEEOTHERGIDS:
2074c14d15aeSRobert Watson 	case PRIV_SEEOTHERUIDS:
2075c14d15aeSRobert Watson 		break;
2076c14d15aeSRobert Watson 
2077c14d15aeSRobert Watson 	/*
2078c14d15aeSRobert Watson 	 * Allow access to general process debugging facilities.  We
2079c14d15aeSRobert Watson 	 * separately control debugging based on MAC label.
2080c14d15aeSRobert Watson 	 */
2081c14d15aeSRobert Watson 	case PRIV_DEBUG_DIFFCRED:
2082c14d15aeSRobert Watson 	case PRIV_DEBUG_SUGID:
2083c14d15aeSRobert Watson 	case PRIV_DEBUG_UNPRIV:
2084c14d15aeSRobert Watson 
2085c14d15aeSRobert Watson 	/*
2086c14d15aeSRobert Watson 	 * Allow manipulating jails.
2087c14d15aeSRobert Watson 	 */
2088c14d15aeSRobert Watson 	case PRIV_JAIL_ATTACH:
2089c14d15aeSRobert Watson 
2090c14d15aeSRobert Watson 	/*
2091c14d15aeSRobert Watson 	 * Allow privilege with respect to the Partition policy, but not the
2092c14d15aeSRobert Watson 	 * Privs policy.
2093c14d15aeSRobert Watson 	 */
2094c14d15aeSRobert Watson 	case PRIV_MAC_PARTITION:
2095c14d15aeSRobert Watson 
2096c14d15aeSRobert Watson 	/*
2097c14d15aeSRobert Watson 	 * Allow privilege with respect to process resource limits and login
2098c14d15aeSRobert Watson 	 * context.
2099c14d15aeSRobert Watson 	 */
2100c14d15aeSRobert Watson 	case PRIV_PROC_LIMIT:
2101c14d15aeSRobert Watson 	case PRIV_PROC_SETLOGIN:
2102c14d15aeSRobert Watson 	case PRIV_PROC_SETRLIMIT:
2103c14d15aeSRobert Watson 
2104c14d15aeSRobert Watson 	/*
2105c14d15aeSRobert Watson 	 * Allow System V and POSIX IPC privileges.
2106c14d15aeSRobert Watson 	 */
2107c14d15aeSRobert Watson 	case PRIV_IPC_READ:
2108c14d15aeSRobert Watson 	case PRIV_IPC_WRITE:
2109c14d15aeSRobert Watson 	case PRIV_IPC_ADMIN:
2110c14d15aeSRobert Watson 	case PRIV_IPC_MSGSIZE:
2111c14d15aeSRobert Watson 	case PRIV_MQ_ADMIN:
2112c14d15aeSRobert Watson 
2113c14d15aeSRobert Watson 	/*
2114c14d15aeSRobert Watson 	 * Allow certain scheduler manipulations -- possibly this should be
2115c14d15aeSRobert Watson 	 * controlled by more fine-grained policy, as potentially low
2116c14d15aeSRobert Watson 	 * integrity processes can deny CPU to higher integrity ones.
2117c14d15aeSRobert Watson 	 */
2118c14d15aeSRobert Watson 	case PRIV_SCHED_DIFFCRED:
2119c14d15aeSRobert Watson 	case PRIV_SCHED_SETPRIORITY:
2120c14d15aeSRobert Watson 	case PRIV_SCHED_RTPRIO:
2121c14d15aeSRobert Watson 	case PRIV_SCHED_SETPOLICY:
2122c14d15aeSRobert Watson 	case PRIV_SCHED_SET:
2123c14d15aeSRobert Watson 	case PRIV_SCHED_SETPARAM:
2124c14d15aeSRobert Watson 
2125c14d15aeSRobert Watson 	/*
2126c14d15aeSRobert Watson 	 * More IPC privileges.
2127c14d15aeSRobert Watson 	 */
2128c14d15aeSRobert Watson 	case PRIV_SEM_WRITE:
2129c14d15aeSRobert Watson 
2130c14d15aeSRobert Watson 	/*
2131c14d15aeSRobert Watson 	 * Allow signaling privileges subject to integrity policy.
2132c14d15aeSRobert Watson 	 */
2133c14d15aeSRobert Watson 	case PRIV_SIGNAL_DIFFCRED:
2134c14d15aeSRobert Watson 	case PRIV_SIGNAL_SUGID:
2135c14d15aeSRobert Watson 
2136c14d15aeSRobert Watson 	/*
2137c14d15aeSRobert Watson 	 * Allow access to only limited sysctls from lower integrity levels;
2138c14d15aeSRobert Watson 	 * piggy-back on the Jail definition.
2139c14d15aeSRobert Watson 	 */
2140c14d15aeSRobert Watson 	case PRIV_SYSCTL_WRITEJAIL:
2141c14d15aeSRobert Watson 
2142c14d15aeSRobert Watson 	/*
2143c14d15aeSRobert Watson 	 * Allow TTY-based privileges, subject to general device access using
2144c14d15aeSRobert Watson 	 * labels on TTY device nodes, but not console privilege.
2145c14d15aeSRobert Watson 	 */
2146c14d15aeSRobert Watson 	case PRIV_TTY_DRAINWAIT:
2147c14d15aeSRobert Watson 	case PRIV_TTY_DTRWAIT:
2148c14d15aeSRobert Watson 	case PRIV_TTY_EXCLUSIVE:
2149c14d15aeSRobert Watson 	case PRIV_TTY_PRISON:
2150c14d15aeSRobert Watson 	case PRIV_TTY_STI:
2151c14d15aeSRobert Watson 	case PRIV_TTY_SETA:
2152c14d15aeSRobert Watson 
2153c14d15aeSRobert Watson 	/*
2154c14d15aeSRobert Watson 	 * Grant most VFS privileges, as almost all are in practice bounded
2155c14d15aeSRobert Watson 	 * by more specific checks using labels.
2156c14d15aeSRobert Watson 	 */
2157c14d15aeSRobert Watson 	case PRIV_VFS_READ:
2158c14d15aeSRobert Watson 	case PRIV_VFS_WRITE:
2159c14d15aeSRobert Watson 	case PRIV_VFS_ADMIN:
2160c14d15aeSRobert Watson 	case PRIV_VFS_EXEC:
2161c14d15aeSRobert Watson 	case PRIV_VFS_LOOKUP:
2162c14d15aeSRobert Watson 	case PRIV_VFS_CHFLAGS_DEV:
2163c14d15aeSRobert Watson 	case PRIV_VFS_CHOWN:
2164c14d15aeSRobert Watson 	case PRIV_VFS_CHROOT:
2165c14d15aeSRobert Watson 	case PRIV_VFS_RETAINSUGID:
2166c14d15aeSRobert Watson 	case PRIV_VFS_EXCEEDQUOTA:
2167c14d15aeSRobert Watson 	case PRIV_VFS_FCHROOT:
2168c14d15aeSRobert Watson 	case PRIV_VFS_FHOPEN:
2169c14d15aeSRobert Watson 	case PRIV_VFS_FHSTATFS:
2170c14d15aeSRobert Watson 	case PRIV_VFS_GENERATION:
2171c14d15aeSRobert Watson 	case PRIV_VFS_GETFH:
2172c14d15aeSRobert Watson 	case PRIV_VFS_GETQUOTA:
2173c14d15aeSRobert Watson 	case PRIV_VFS_LINK:
2174c14d15aeSRobert Watson 	case PRIV_VFS_MOUNT:
2175c14d15aeSRobert Watson 	case PRIV_VFS_MOUNT_OWNER:
2176c14d15aeSRobert Watson 	case PRIV_VFS_MOUNT_PERM:
2177c14d15aeSRobert Watson 	case PRIV_VFS_MOUNT_SUIDDIR:
2178c14d15aeSRobert Watson 	case PRIV_VFS_MOUNT_NONUSER:
2179c14d15aeSRobert Watson 	case PRIV_VFS_SETGID:
2180c14d15aeSRobert Watson 	case PRIV_VFS_STICKYFILE:
2181c14d15aeSRobert Watson 	case PRIV_VFS_SYSFLAGS:
2182c14d15aeSRobert Watson 	case PRIV_VFS_UNMOUNT:
2183c14d15aeSRobert Watson 
2184c14d15aeSRobert Watson 	/*
2185c14d15aeSRobert Watson 	 * Allow VM privileges; it would be nice if these were subject to
2186c14d15aeSRobert Watson 	 * resource limits.
2187c14d15aeSRobert Watson 	 */
2188c14d15aeSRobert Watson 	case PRIV_VM_MADV_PROTECT:
2189c14d15aeSRobert Watson 	case PRIV_VM_MLOCK:
2190c14d15aeSRobert Watson 	case PRIV_VM_MUNLOCK:
2191c14d15aeSRobert Watson 
2192c14d15aeSRobert Watson 	/*
2193c14d15aeSRobert Watson 	 * Allow some but not all network privileges.  In general, dont allow
2194c14d15aeSRobert Watson 	 * reconfiguring the network stack, just normal use.
2195c14d15aeSRobert Watson 	 */
2196c14d15aeSRobert Watson 	case PRIV_NETATALK_RESERVEDPORT:
2197c14d15aeSRobert Watson 	case PRIV_NETINET_RESERVEDPORT:
2198c14d15aeSRobert Watson 	case PRIV_NETINET_RAW:
2199c14d15aeSRobert Watson 	case PRIV_NETINET_REUSEPORT:
2200c14d15aeSRobert Watson 	case PRIV_NETIPX_RESERVEDPORT:
2201c14d15aeSRobert Watson 	case PRIV_NETIPX_RAW:
2202c14d15aeSRobert Watson 		break;
2203c14d15aeSRobert Watson 
2204c14d15aeSRobert Watson 	/*
2205c14d15aeSRobert Watson 	 * All remaining system privileges are allow only if the process
2206c14d15aeSRobert Watson 	 * holds privilege with respect to the LOMAC policy.
2207c14d15aeSRobert Watson 	 */
2208c14d15aeSRobert Watson 	default:
2209c14d15aeSRobert Watson 		subj = SLOT(cred->cr_label);
2210c14d15aeSRobert Watson 		error = mac_lomac_subject_privileged(subj);
2211c14d15aeSRobert Watson 		if (error)
2212c14d15aeSRobert Watson 			return (error);
2213c14d15aeSRobert Watson 	}
2214c14d15aeSRobert Watson 	return (0);
2215c14d15aeSRobert Watson }
2216c14d15aeSRobert Watson 
2217c14d15aeSRobert Watson 
2218db2661ceSRobert Watson static int
221918717f69SRobert Watson mac_lomac_check_system_acct(struct ucred *cred, struct vnode *vp,
222078007886SRobert Watson     struct label *vplabel)
222118717f69SRobert Watson {
222218717f69SRobert Watson 	struct mac_lomac *subj, *obj;
222318717f69SRobert Watson 
222418717f69SRobert Watson 	if (!mac_lomac_enabled)
222518717f69SRobert Watson 		return (0);
222618717f69SRobert Watson 
222718717f69SRobert Watson 	subj = SLOT(cred->cr_label);
222878007886SRobert Watson 	obj = SLOT(vplabel);
222918717f69SRobert Watson 
223018717f69SRobert Watson 	if (mac_lomac_subject_privileged(subj))
223118717f69SRobert Watson 		return (EPERM);
223218717f69SRobert Watson 
223318717f69SRobert Watson 	if (!mac_lomac_high_single(obj))
223418717f69SRobert Watson 		return (EACCES);
223518717f69SRobert Watson 
223618717f69SRobert Watson 	return (0);
223718717f69SRobert Watson }
223818717f69SRobert Watson 
223918717f69SRobert Watson static int
224018717f69SRobert Watson mac_lomac_check_system_auditctl(struct ucred *cred, struct vnode *vp,
224178007886SRobert Watson     struct label *vplabel)
224218717f69SRobert Watson {
224318717f69SRobert Watson 	struct mac_lomac *subj, *obj;
224418717f69SRobert Watson 
224518717f69SRobert Watson 	if (!mac_lomac_enabled)
224618717f69SRobert Watson 		return (0);
224718717f69SRobert Watson 
224818717f69SRobert Watson 	subj = SLOT(cred->cr_label);
224978007886SRobert Watson 	obj = SLOT(vplabel);
225018717f69SRobert Watson 
225118717f69SRobert Watson 	if (mac_lomac_subject_privileged(subj))
225218717f69SRobert Watson 		return (EPERM);
225318717f69SRobert Watson 
225418717f69SRobert Watson 	if (!mac_lomac_high_single(obj))
225518717f69SRobert Watson 		return (EACCES);
225618717f69SRobert Watson 
225718717f69SRobert Watson 	return (0);
225818717f69SRobert Watson }
225918717f69SRobert Watson 
226018717f69SRobert Watson static int
226118717f69SRobert Watson mac_lomac_check_system_swapoff(struct ucred *cred, struct vnode *vp,
226278007886SRobert Watson     struct label *vplabel)
226318717f69SRobert Watson {
226418717f69SRobert Watson 	struct mac_lomac *subj;
226518717f69SRobert Watson 
226618717f69SRobert Watson 	if (!mac_lomac_enabled)
226718717f69SRobert Watson 		return (0);
226818717f69SRobert Watson 
226918717f69SRobert Watson 	subj = SLOT(cred->cr_label);
227018717f69SRobert Watson 
227118717f69SRobert Watson 	if (mac_lomac_subject_privileged(subj))
227218717f69SRobert Watson 		return (EPERM);
227318717f69SRobert Watson 
227418717f69SRobert Watson 	return (0);
227518717f69SRobert Watson }
227618717f69SRobert Watson 
227718717f69SRobert Watson static int
2278db2661ceSRobert Watson mac_lomac_check_system_swapon(struct ucred *cred, struct vnode *vp,
227978007886SRobert Watson     struct label *vplabel)
2280db2661ceSRobert Watson {
2281db2661ceSRobert Watson 	struct mac_lomac *subj, *obj;
2282db2661ceSRobert Watson 
2283db2661ceSRobert Watson 	if (!mac_lomac_enabled)
2284db2661ceSRobert Watson 		return (0);
2285db2661ceSRobert Watson 
2286eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
228778007886SRobert Watson 	obj = SLOT(vplabel);
2288db2661ceSRobert Watson 
2289db2661ceSRobert Watson 	if (mac_lomac_subject_privileged(subj))
2290db2661ceSRobert Watson 		return (EPERM);
2291db2661ceSRobert Watson 
2292db2661ceSRobert Watson 	if (!mac_lomac_high_single(obj))
2293db2661ceSRobert Watson 		return (EACCES);
2294db2661ceSRobert Watson 
2295db2661ceSRobert Watson 	return (0);
2296db2661ceSRobert Watson }
2297db2661ceSRobert Watson 
2298db2661ceSRobert Watson static int
229963dba32bSPawel Jakub Dawidek mac_lomac_check_system_sysctl(struct ucred *cred, struct sysctl_oid *oidp,
230063dba32bSPawel Jakub Dawidek     void *arg1, int arg2, struct sysctl_req *req)
2301db2661ceSRobert Watson {
2302db2661ceSRobert Watson 	struct mac_lomac *subj;
2303db2661ceSRobert Watson 
2304db2661ceSRobert Watson 	if (!mac_lomac_enabled)
2305db2661ceSRobert Watson 		return (0);
2306db2661ceSRobert Watson 
2307eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
2308db2661ceSRobert Watson 
2309db2661ceSRobert Watson 	/*
231063dba32bSPawel Jakub Dawidek 	 * Treat sysctl variables without CTLFLAG_ANYBODY flag as
231163dba32bSPawel Jakub Dawidek 	 * lomac/high, but also require privilege to change them.
2312db2661ceSRobert Watson 	 */
231363dba32bSPawel Jakub Dawidek 	if (req->newptr != NULL && (oidp->oid_kind & CTLFLAG_ANYBODY) == 0) {
2314db2661ceSRobert Watson #ifdef notdef
2315db2661ceSRobert Watson 		if (!mac_lomac_subject_dominate_high(subj))
2316db2661ceSRobert Watson 			return (EACCES);
2317db2661ceSRobert Watson #endif
2318db2661ceSRobert Watson 
2319db2661ceSRobert Watson 		if (mac_lomac_subject_privileged(subj))
2320db2661ceSRobert Watson 			return (EPERM);
2321db2661ceSRobert Watson 	}
2322db2661ceSRobert Watson 
2323db2661ceSRobert Watson 	return (0);
2324db2661ceSRobert Watson }
2325db2661ceSRobert Watson 
2326db2661ceSRobert Watson static int
2327db2661ceSRobert Watson mac_lomac_check_vnode_create(struct ucred *cred, struct vnode *dvp,
232878007886SRobert Watson     struct label *dvplabel, struct componentname *cnp, struct vattr *vap)
2329db2661ceSRobert Watson {
2330db2661ceSRobert Watson 	struct mac_lomac *subj, *obj;
2331db2661ceSRobert Watson 
2332db2661ceSRobert Watson 	if (!mac_lomac_enabled)
2333db2661ceSRobert Watson 		return (0);
2334db2661ceSRobert Watson 
2335eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
233678007886SRobert Watson 	obj = SLOT(dvplabel);
2337db2661ceSRobert Watson 
2338db2661ceSRobert Watson 	if (!mac_lomac_subject_dominate(subj, obj))
2339db2661ceSRobert Watson 		return (EACCES);
2340db2661ceSRobert Watson 	if (obj->ml_flags & MAC_LOMAC_FLAG_AUX &&
2341db2661ceSRobert Watson 	    !mac_lomac_dominate_element(&subj->ml_single, &obj->ml_auxsingle))
2342db2661ceSRobert Watson 		return (EACCES);
2343db2661ceSRobert Watson 
2344db2661ceSRobert Watson 	return (0);
2345db2661ceSRobert Watson }
2346db2661ceSRobert Watson 
2347db2661ceSRobert Watson static int
2348db2661ceSRobert Watson mac_lomac_check_vnode_delete(struct ucred *cred, struct vnode *dvp,
234978007886SRobert Watson     struct label *dvplabel, struct vnode *vp, struct label *vplabel,
2350db2661ceSRobert Watson     struct componentname *cnp)
2351db2661ceSRobert Watson {
2352db2661ceSRobert Watson 	struct mac_lomac *subj, *obj;
2353db2661ceSRobert Watson 
2354db2661ceSRobert Watson 	if (!mac_lomac_enabled)
2355db2661ceSRobert Watson 		return (0);
2356db2661ceSRobert Watson 
2357eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
235878007886SRobert Watson 	obj = SLOT(dvplabel);
2359db2661ceSRobert Watson 
2360db2661ceSRobert Watson 	if (!mac_lomac_subject_dominate(subj, obj))
2361db2661ceSRobert Watson 		return (EACCES);
2362db2661ceSRobert Watson 
236378007886SRobert Watson 	obj = SLOT(vplabel);
2364db2661ceSRobert Watson 
2365db2661ceSRobert Watson 	if (!mac_lomac_subject_dominate(subj, obj))
2366db2661ceSRobert Watson 		return (EACCES);
2367db2661ceSRobert Watson 
2368db2661ceSRobert Watson 	return (0);
2369db2661ceSRobert Watson }
2370db2661ceSRobert Watson 
2371db2661ceSRobert Watson static int
2372db2661ceSRobert Watson mac_lomac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
237378007886SRobert Watson     struct label *vplabel, acl_type_t type)
2374db2661ceSRobert Watson {
2375db2661ceSRobert Watson 	struct mac_lomac *subj, *obj;
2376db2661ceSRobert Watson 
2377db2661ceSRobert Watson 	if (!mac_lomac_enabled)
2378db2661ceSRobert Watson 		return (0);
2379db2661ceSRobert Watson 
2380eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
238178007886SRobert Watson 	obj = SLOT(vplabel);
2382db2661ceSRobert Watson 
2383db2661ceSRobert Watson 	if (!mac_lomac_subject_dominate(subj, obj))
2384db2661ceSRobert Watson 		return (EACCES);
2385db2661ceSRobert Watson 
2386db2661ceSRobert Watson 	return (0);
2387db2661ceSRobert Watson }
2388db2661ceSRobert Watson 
2389db2661ceSRobert Watson static int
2390db2661ceSRobert Watson mac_lomac_check_vnode_link(struct ucred *cred, struct vnode *dvp,
239178007886SRobert Watson     struct label *dvplabel, struct vnode *vp, struct label *vplabel,
2392db2661ceSRobert Watson     struct componentname *cnp)
2393db2661ceSRobert Watson {
2394db2661ceSRobert Watson 	struct mac_lomac *subj, *obj;
2395db2661ceSRobert Watson 
2396db2661ceSRobert Watson 	if (!mac_lomac_enabled)
2397db2661ceSRobert Watson 		return (0);
2398db2661ceSRobert Watson 
2399eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
240078007886SRobert Watson 	obj = SLOT(dvplabel);
2401db2661ceSRobert Watson 
2402db2661ceSRobert Watson 	if (!mac_lomac_subject_dominate(subj, obj))
2403db2661ceSRobert Watson 		return (EACCES);
2404db2661ceSRobert Watson 
240578007886SRobert Watson 	obj = SLOT(vplabel);
2406db2661ceSRobert Watson 
2407db2661ceSRobert Watson 	if (!mac_lomac_subject_dominate(subj, obj))
2408db2661ceSRobert Watson 		return (EACCES);
2409db2661ceSRobert Watson 
2410db2661ceSRobert Watson 	return (0);
2411db2661ceSRobert Watson }
2412db2661ceSRobert Watson 
2413db2661ceSRobert Watson static int
2414db2661ceSRobert Watson mac_lomac_check_vnode_mmap(struct ucred *cred, struct vnode *vp,
241578007886SRobert Watson     struct label *vplabel, int prot, int flags)
2416db2661ceSRobert Watson {
2417db2661ceSRobert Watson 	struct mac_lomac *subj, *obj;
2418db2661ceSRobert Watson 
2419db2661ceSRobert Watson 	/*
2420db2661ceSRobert Watson 	 * Rely on the use of open()-time protections to handle
2421db2661ceSRobert Watson 	 * non-revocation cases.
2422db2661ceSRobert Watson 	 */
2423db2661ceSRobert Watson 	if (!mac_lomac_enabled)
2424db2661ceSRobert Watson 		return (0);
2425db2661ceSRobert Watson 
2426eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
242778007886SRobert Watson 	obj = SLOT(vplabel);
2428db2661ceSRobert Watson 
2429c92163dcSChristian S.J. Peron 	if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) {
2430db2661ceSRobert Watson 		if (!mac_lomac_subject_dominate(subj, obj))
2431db2661ceSRobert Watson 			return (EACCES);
2432db2661ceSRobert Watson 	}
2433db2661ceSRobert Watson 	if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
2434db2661ceSRobert Watson 		if (!mac_lomac_dominate_single(obj, subj))
2435db2661ceSRobert Watson 			return (maybe_demote(subj, obj, "mapping", "file", vp));
2436db2661ceSRobert Watson 	}
2437db2661ceSRobert Watson 
2438db2661ceSRobert Watson 	return (0);
2439db2661ceSRobert Watson }
2440db2661ceSRobert Watson 
2441db2661ceSRobert Watson static void
2442db2661ceSRobert Watson mac_lomac_check_vnode_mmap_downgrade(struct ucred *cred, struct vnode *vp,
244378007886SRobert Watson     struct label *vplabel, /* XXX vm_prot_t */ int *prot)
2444db2661ceSRobert Watson {
2445db2661ceSRobert Watson 	struct mac_lomac *subj, *obj;
2446db2661ceSRobert Watson 
2447db2661ceSRobert Watson 	/*
2448db2661ceSRobert Watson 	 * Rely on the use of open()-time protections to handle
2449db2661ceSRobert Watson 	 * non-revocation cases.
2450db2661ceSRobert Watson 	 */
2451db2661ceSRobert Watson 	if (!mac_lomac_enabled || !revocation_enabled)
2452db2661ceSRobert Watson 		return;
2453db2661ceSRobert Watson 
2454eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
245578007886SRobert Watson 	obj = SLOT(vplabel);
2456db2661ceSRobert Watson 
2457db2661ceSRobert Watson 	if (!mac_lomac_subject_dominate(subj, obj))
2458db2661ceSRobert Watson 		*prot &= ~VM_PROT_WRITE;
2459db2661ceSRobert Watson }
2460db2661ceSRobert Watson 
2461db2661ceSRobert Watson static int
2462db2661ceSRobert Watson mac_lomac_check_vnode_open(struct ucred *cred, struct vnode *vp,
246378007886SRobert Watson     struct label *vplabel, int acc_mode)
2464db2661ceSRobert Watson {
2465db2661ceSRobert Watson 	struct mac_lomac *subj, *obj;
2466db2661ceSRobert Watson 
2467db2661ceSRobert Watson 	if (!mac_lomac_enabled)
2468db2661ceSRobert Watson 		return (0);
2469db2661ceSRobert Watson 
2470eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
247178007886SRobert Watson 	obj = SLOT(vplabel);
2472db2661ceSRobert Watson 
2473db2661ceSRobert Watson 	/* XXX privilege override for admin? */
2474db2661ceSRobert Watson 	if (acc_mode & (VWRITE | VAPPEND | VADMIN)) {
2475db2661ceSRobert Watson 		if (!mac_lomac_subject_dominate(subj, obj))
2476db2661ceSRobert Watson 			return (EACCES);
2477db2661ceSRobert Watson 	}
2478db2661ceSRobert Watson 
2479db2661ceSRobert Watson 	return (0);
2480db2661ceSRobert Watson }
2481db2661ceSRobert Watson 
2482db2661ceSRobert Watson static int
2483db2661ceSRobert Watson mac_lomac_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
248478007886SRobert Watson     struct vnode *vp, struct label *vplabel)
2485db2661ceSRobert Watson {
2486db2661ceSRobert Watson 	struct mac_lomac *subj, *obj;
2487db2661ceSRobert Watson 
2488db2661ceSRobert Watson 	if (!mac_lomac_enabled || !revocation_enabled)
2489db2661ceSRobert Watson 		return (0);
2490db2661ceSRobert Watson 
2491eca8a663SRobert Watson 	subj = SLOT(active_cred->cr_label);
249278007886SRobert Watson 	obj = SLOT(vplabel);
2493db2661ceSRobert Watson 
2494db2661ceSRobert Watson 	if (!mac_lomac_dominate_single(obj, subj))
2495db2661ceSRobert Watson 		return (maybe_demote(subj, obj, "reading", "file", vp));
2496db2661ceSRobert Watson 
2497db2661ceSRobert Watson 	return (0);
2498db2661ceSRobert Watson }
2499db2661ceSRobert Watson 
2500db2661ceSRobert Watson static int
2501db2661ceSRobert Watson mac_lomac_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
250278007886SRobert Watson     struct label *vplabel, struct label *newlabel)
2503db2661ceSRobert Watson {
2504db2661ceSRobert Watson 	struct mac_lomac *old, *new, *subj;
2505db2661ceSRobert Watson 	int error;
2506db2661ceSRobert Watson 
250778007886SRobert Watson 	old = SLOT(vplabel);
2508db2661ceSRobert Watson 	new = SLOT(newlabel);
2509eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
2510db2661ceSRobert Watson 
2511db2661ceSRobert Watson 	/*
2512db2661ceSRobert Watson 	 * If there is a LOMAC label update for the vnode, it must be a
2513db2661ceSRobert Watson 	 * single label, with an optional explicit auxiliary single.
2514db2661ceSRobert Watson 	 */
2515db2661ceSRobert Watson 	error = lomac_atmostflags(new,
2516db2661ceSRobert Watson 	    MAC_LOMAC_FLAG_SINGLE | MAC_LOMAC_FLAG_AUX);
2517db2661ceSRobert Watson 	if (error)
2518db2661ceSRobert Watson 		return (error);
2519db2661ceSRobert Watson 
2520db2661ceSRobert Watson 	/*
2521db2661ceSRobert Watson 	 * To perform a relabel of the vnode (LOMAC label or not), LOMAC must
2522db2661ceSRobert Watson 	 * authorize the relabel.
2523db2661ceSRobert Watson 	 */
2524db2661ceSRobert Watson 	if (!mac_lomac_single_in_range(old, subj))
2525db2661ceSRobert Watson 		return (EPERM);
2526db2661ceSRobert Watson 
2527db2661ceSRobert Watson 	/*
2528db2661ceSRobert Watson 	 * If the LOMAC label is to be changed, authorize as appropriate.
2529db2661ceSRobert Watson 	 */
2530db2661ceSRobert Watson 	if (new->ml_flags & MAC_LOMAC_FLAG_SINGLE) {
2531db2661ceSRobert Watson 		/*
2532db2661ceSRobert Watson 		 * To change the LOMAC label on a vnode, the new vnode label
2533db2661ceSRobert Watson 		 * must be in the subject range.
2534db2661ceSRobert Watson 		 */
2535db2661ceSRobert Watson 		if (!mac_lomac_single_in_range(new, subj))
2536db2661ceSRobert Watson 			return (EPERM);
2537db2661ceSRobert Watson 
2538db2661ceSRobert Watson 		/*
2539db2661ceSRobert Watson 		 * To change the LOMAC label on the vnode to be EQUAL,
2540db2661ceSRobert Watson 		 * the subject must have appropriate privilege.
2541db2661ceSRobert Watson 		 */
2542db2661ceSRobert Watson 		if (mac_lomac_contains_equal(new)) {
2543db2661ceSRobert Watson 			error = mac_lomac_subject_privileged(subj);
2544db2661ceSRobert Watson 			if (error)
2545db2661ceSRobert Watson 				return (error);
2546db2661ceSRobert Watson 		}
2547db2661ceSRobert Watson 	}
2548db2661ceSRobert Watson 	if (new->ml_flags & MAC_LOMAC_FLAG_AUX) {
2549db2661ceSRobert Watson 		/*
255084bdb083SRobert Watson 		 * Fill in the missing parts from the previous label.
255184bdb083SRobert Watson 		 */
255284bdb083SRobert Watson 		if ((new->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0)
255384bdb083SRobert Watson 			mac_lomac_copy_single(subj, new);
255484bdb083SRobert Watson 
255584bdb083SRobert Watson 		/*
2556db2661ceSRobert Watson 		 * To change the auxiliary LOMAC label on a vnode, the new
2557db2661ceSRobert Watson 		 * vnode label must be in the subject range.
2558db2661ceSRobert Watson 		 */
2559db2661ceSRobert Watson 		if (!mac_lomac_auxsingle_in_range(new, subj))
2560db2661ceSRobert Watson 			return (EPERM);
2561db2661ceSRobert Watson 
2562db2661ceSRobert Watson 		/*
2563db2661ceSRobert Watson 		 * To change the auxiliary LOMAC label on the vnode to be
2564db2661ceSRobert Watson 		 * EQUAL, the subject must have appropriate privilege.
2565db2661ceSRobert Watson 		 */
2566db2661ceSRobert Watson 		if (mac_lomac_contains_equal(new)) {
2567db2661ceSRobert Watson 			error = mac_lomac_subject_privileged(subj);
2568db2661ceSRobert Watson 			if (error)
2569db2661ceSRobert Watson 				return (error);
2570db2661ceSRobert Watson 		}
2571db2661ceSRobert Watson 	}
2572db2661ceSRobert Watson 
2573db2661ceSRobert Watson 	return (0);
2574db2661ceSRobert Watson }
2575db2661ceSRobert Watson 
2576db2661ceSRobert Watson static int
2577db2661ceSRobert Watson mac_lomac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
257878007886SRobert Watson     struct label *dvplabel, struct vnode *vp, struct label *vplabel,
2579db2661ceSRobert Watson     struct componentname *cnp)
2580db2661ceSRobert Watson {
2581db2661ceSRobert Watson 	struct mac_lomac *subj, *obj;
2582db2661ceSRobert Watson 
2583db2661ceSRobert Watson 	if (!mac_lomac_enabled)
2584db2661ceSRobert Watson 		return (0);
2585db2661ceSRobert Watson 
2586eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
258778007886SRobert Watson 	obj = SLOT(dvplabel);
2588db2661ceSRobert Watson 
2589db2661ceSRobert Watson 	if (!mac_lomac_subject_dominate(subj, obj))
2590db2661ceSRobert Watson 		return (EACCES);
2591db2661ceSRobert Watson 
259278007886SRobert Watson 	obj = SLOT(vplabel);
2593db2661ceSRobert Watson 
2594db2661ceSRobert Watson 	if (!mac_lomac_subject_dominate(subj, obj))
2595db2661ceSRobert Watson 		return (EACCES);
2596db2661ceSRobert Watson 
2597db2661ceSRobert Watson 	return (0);
2598db2661ceSRobert Watson }
2599db2661ceSRobert Watson 
2600db2661ceSRobert Watson static int
2601db2661ceSRobert Watson mac_lomac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
260278007886SRobert Watson     struct label *dvplabel, struct vnode *vp, struct label *vplabel,
260378007886SRobert Watson     int samedir, struct componentname *cnp)
2604db2661ceSRobert Watson {
2605db2661ceSRobert Watson 	struct mac_lomac *subj, *obj;
2606db2661ceSRobert Watson 
2607db2661ceSRobert Watson 	if (!mac_lomac_enabled)
2608db2661ceSRobert Watson 		return (0);
2609db2661ceSRobert Watson 
2610eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
261178007886SRobert Watson 	obj = SLOT(dvplabel);
2612db2661ceSRobert Watson 
2613db2661ceSRobert Watson 	if (!mac_lomac_subject_dominate(subj, obj))
2614db2661ceSRobert Watson 		return (EACCES);
2615db2661ceSRobert Watson 
2616db2661ceSRobert Watson 	if (vp != NULL) {
261778007886SRobert Watson 		obj = SLOT(vplabel);
2618db2661ceSRobert Watson 
2619db2661ceSRobert Watson 		if (!mac_lomac_subject_dominate(subj, obj))
2620db2661ceSRobert Watson 			return (EACCES);
2621db2661ceSRobert Watson 	}
2622db2661ceSRobert Watson 
2623db2661ceSRobert Watson 	return (0);
2624db2661ceSRobert Watson }
2625db2661ceSRobert Watson 
2626db2661ceSRobert Watson static int
2627db2661ceSRobert Watson mac_lomac_check_vnode_revoke(struct ucred *cred, struct vnode *vp,
262878007886SRobert Watson     struct label *vplabel)
2629db2661ceSRobert Watson {
2630db2661ceSRobert Watson 	struct mac_lomac *subj, *obj;
2631db2661ceSRobert Watson 
2632db2661ceSRobert Watson 	if (!mac_lomac_enabled)
2633db2661ceSRobert Watson 		return (0);
2634db2661ceSRobert Watson 
2635eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
263678007886SRobert Watson 	obj = SLOT(vplabel);
2637db2661ceSRobert Watson 
2638db2661ceSRobert Watson 	if (!mac_lomac_subject_dominate(subj, obj))
2639db2661ceSRobert Watson 		return (EACCES);
2640db2661ceSRobert Watson 
2641db2661ceSRobert Watson 	return (0);
2642db2661ceSRobert Watson }
2643db2661ceSRobert Watson 
2644db2661ceSRobert Watson static int
2645db2661ceSRobert Watson mac_lomac_check_vnode_setacl(struct ucred *cred, struct vnode *vp,
264678007886SRobert Watson     struct label *vplabel, acl_type_t type, struct acl *acl)
2647db2661ceSRobert Watson {
2648db2661ceSRobert Watson 	struct mac_lomac *subj, *obj;
2649db2661ceSRobert Watson 
2650db2661ceSRobert Watson 	if (!mac_lomac_enabled)
2651db2661ceSRobert Watson 		return (0);
2652db2661ceSRobert Watson 
2653eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
265478007886SRobert Watson 	obj = SLOT(vplabel);
2655db2661ceSRobert Watson 
2656db2661ceSRobert Watson 	if (!mac_lomac_subject_dominate(subj, obj))
2657db2661ceSRobert Watson 		return (EACCES);
2658db2661ceSRobert Watson 
2659db2661ceSRobert Watson 	return (0);
2660db2661ceSRobert Watson }
2661db2661ceSRobert Watson 
2662db2661ceSRobert Watson static int
2663db2661ceSRobert Watson mac_lomac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
266478007886SRobert Watson     struct label *vplabel, int attrnamespace, const char *name,
2665db2661ceSRobert Watson     struct uio *uio)
2666db2661ceSRobert Watson {
2667db2661ceSRobert Watson 	struct mac_lomac *subj, *obj;
2668db2661ceSRobert Watson 
2669db2661ceSRobert Watson 	if (!mac_lomac_enabled)
2670db2661ceSRobert Watson 		return (0);
2671db2661ceSRobert Watson 
2672eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
267378007886SRobert Watson 	obj = SLOT(vplabel);
2674db2661ceSRobert Watson 
2675db2661ceSRobert Watson 	if (!mac_lomac_subject_dominate(subj, obj))
2676db2661ceSRobert Watson 		return (EACCES);
2677db2661ceSRobert Watson 
2678db2661ceSRobert Watson 	/* XXX: protect the MAC EA in a special way? */
2679db2661ceSRobert Watson 
2680db2661ceSRobert Watson 	return (0);
2681db2661ceSRobert Watson }
2682db2661ceSRobert Watson 
2683db2661ceSRobert Watson static int
2684db2661ceSRobert Watson mac_lomac_check_vnode_setflags(struct ucred *cred, struct vnode *vp,
268578007886SRobert Watson     struct label *vplabel, u_long flags)
2686db2661ceSRobert Watson {
2687db2661ceSRobert Watson 	struct mac_lomac *subj, *obj;
2688db2661ceSRobert Watson 
2689db2661ceSRobert Watson 	if (!mac_lomac_enabled)
2690db2661ceSRobert Watson 		return (0);
2691db2661ceSRobert Watson 
2692eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
269378007886SRobert Watson 	obj = SLOT(vplabel);
2694db2661ceSRobert Watson 
2695db2661ceSRobert Watson 	if (!mac_lomac_subject_dominate(subj, obj))
2696db2661ceSRobert Watson 		return (EACCES);
2697db2661ceSRobert Watson 
2698db2661ceSRobert Watson 	return (0);
2699db2661ceSRobert Watson }
2700db2661ceSRobert Watson 
2701db2661ceSRobert Watson static int
2702db2661ceSRobert Watson mac_lomac_check_vnode_setmode(struct ucred *cred, struct vnode *vp,
270378007886SRobert Watson     struct label *vplabel, mode_t mode)
2704db2661ceSRobert Watson {
2705db2661ceSRobert Watson 	struct mac_lomac *subj, *obj;
2706db2661ceSRobert Watson 
2707db2661ceSRobert Watson 	if (!mac_lomac_enabled)
2708db2661ceSRobert Watson 		return (0);
2709db2661ceSRobert Watson 
2710eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
271178007886SRobert Watson 	obj = SLOT(vplabel);
2712db2661ceSRobert Watson 
2713db2661ceSRobert Watson 	if (!mac_lomac_subject_dominate(subj, obj))
2714db2661ceSRobert Watson 		return (EACCES);
2715db2661ceSRobert Watson 
2716db2661ceSRobert Watson 	return (0);
2717db2661ceSRobert Watson }
2718db2661ceSRobert Watson 
2719db2661ceSRobert Watson static int
2720db2661ceSRobert Watson mac_lomac_check_vnode_setowner(struct ucred *cred, struct vnode *vp,
272178007886SRobert Watson     struct label *vplabel, uid_t uid, gid_t gid)
2722db2661ceSRobert Watson {
2723db2661ceSRobert Watson 	struct mac_lomac *subj, *obj;
2724db2661ceSRobert Watson 
2725db2661ceSRobert Watson 	if (!mac_lomac_enabled)
2726db2661ceSRobert Watson 		return (0);
2727db2661ceSRobert Watson 
2728eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
272978007886SRobert Watson 	obj = SLOT(vplabel);
2730db2661ceSRobert Watson 
2731db2661ceSRobert Watson 	if (!mac_lomac_subject_dominate(subj, obj))
2732db2661ceSRobert Watson 		return (EACCES);
2733db2661ceSRobert Watson 
2734db2661ceSRobert Watson 	return (0);
2735db2661ceSRobert Watson }
2736db2661ceSRobert Watson 
2737db2661ceSRobert Watson static int
2738db2661ceSRobert Watson mac_lomac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
273978007886SRobert Watson     struct label *vplabel, struct timespec atime, struct timespec mtime)
2740db2661ceSRobert Watson {
2741db2661ceSRobert Watson 	struct mac_lomac *subj, *obj;
2742db2661ceSRobert Watson 
2743db2661ceSRobert Watson 	if (!mac_lomac_enabled)
2744db2661ceSRobert Watson 		return (0);
2745db2661ceSRobert Watson 
2746eca8a663SRobert Watson 	subj = SLOT(cred->cr_label);
274778007886SRobert Watson 	obj = SLOT(vplabel);
2748db2661ceSRobert Watson 
2749db2661ceSRobert Watson 	if (!mac_lomac_subject_dominate(subj, obj))
2750db2661ceSRobert Watson 		return (EACCES);
2751db2661ceSRobert Watson 
2752db2661ceSRobert Watson 	return (0);
2753db2661ceSRobert Watson }
2754db2661ceSRobert Watson 
2755db2661ceSRobert Watson static int
2756db2661ceSRobert Watson mac_lomac_check_vnode_write(struct ucred *active_cred,
275778007886SRobert Watson     struct ucred *file_cred, struct vnode *vp, struct label *vplabel)
2758db2661ceSRobert Watson {
2759db2661ceSRobert Watson 	struct mac_lomac *subj, *obj;
2760db2661ceSRobert Watson 
2761db2661ceSRobert Watson 	if (!mac_lomac_enabled || !revocation_enabled)
2762db2661ceSRobert Watson 		return (0);
2763db2661ceSRobert Watson 
2764eca8a663SRobert Watson 	subj = SLOT(active_cred->cr_label);
276578007886SRobert Watson 	obj = SLOT(vplabel);
2766db2661ceSRobert Watson 
2767db2661ceSRobert Watson 	if (!mac_lomac_subject_dominate(subj, obj))
2768db2661ceSRobert Watson 		return (EACCES);
2769db2661ceSRobert Watson 
2770db2661ceSRobert Watson 	return (0);
2771db2661ceSRobert Watson }
2772db2661ceSRobert Watson 
2773db2661ceSRobert Watson static void
2774db2661ceSRobert Watson mac_lomac_thread_userret(struct thread *td)
2775db2661ceSRobert Watson {
2776db2661ceSRobert Watson 	struct proc *p = td->td_proc;
2777eca8a663SRobert Watson 	struct mac_lomac_proc *subj = PSLOT(p->p_label);
2778db2661ceSRobert Watson 	struct ucred *newcred, *oldcred;
2779db2661ceSRobert Watson 	int dodrop;
2780db2661ceSRobert Watson 
2781db2661ceSRobert Watson 	mtx_lock(&subj->mtx);
2782db2661ceSRobert Watson 	if (subj->mac_lomac.ml_flags & MAC_LOMAC_FLAG_UPDATE) {
2783db2661ceSRobert Watson 		dodrop = 0;
2784db2661ceSRobert Watson 		mtx_unlock(&subj->mtx);
2785db2661ceSRobert Watson 		newcred = crget();
2786db2661ceSRobert Watson 		/*
2787db2661ceSRobert Watson 		 * Prevent a lock order reversal in
2788db2661ceSRobert Watson 		 * mac_cred_mmapped_drop_perms; ideally, the other
2789db2661ceSRobert Watson 		 * user of subj->mtx wouldn't be holding Giant.
2790db2661ceSRobert Watson 		 */
2791db2661ceSRobert Watson 		mtx_lock(&Giant);
2792db2661ceSRobert Watson 		PROC_LOCK(p);
2793db2661ceSRobert Watson 		mtx_lock(&subj->mtx);
2794db2661ceSRobert Watson 		/*
2795db2661ceSRobert Watson 		 * Check if we lost the race while allocating the cred.
2796db2661ceSRobert Watson 		 */
2797db2661ceSRobert Watson 		if ((subj->mac_lomac.ml_flags & MAC_LOMAC_FLAG_UPDATE) == 0) {
2798db2661ceSRobert Watson 			crfree(newcred);
2799db2661ceSRobert Watson 			goto out;
2800db2661ceSRobert Watson 		}
2801db2661ceSRobert Watson 		oldcred = p->p_ucred;
2802db2661ceSRobert Watson 		crcopy(newcred, oldcred);
2803db2661ceSRobert Watson 		crhold(newcred);
2804eca8a663SRobert Watson 		mac_lomac_copy(&subj->mac_lomac, SLOT(newcred->cr_label));
2805db2661ceSRobert Watson 		p->p_ucred = newcred;
2806db2661ceSRobert Watson 		crfree(oldcred);
2807db2661ceSRobert Watson 		dodrop = 1;
2808db2661ceSRobert Watson 	out:
2809db2661ceSRobert Watson 		mtx_unlock(&subj->mtx);
2810db2661ceSRobert Watson 		PROC_UNLOCK(p);
2811db2661ceSRobert Watson 		if (dodrop)
2812db2661ceSRobert Watson 			mac_cred_mmapped_drop_perms(curthread, newcred);
2813db2661ceSRobert Watson 		mtx_unlock(&Giant);
2814db2661ceSRobert Watson 	} else {
2815db2661ceSRobert Watson 		mtx_unlock(&subj->mtx);
2816db2661ceSRobert Watson 	}
2817db2661ceSRobert Watson }
2818db2661ceSRobert Watson 
2819db2661ceSRobert Watson static struct mac_policy_ops mac_lomac_ops =
2820db2661ceSRobert Watson {
2821db2661ceSRobert Watson 	.mpo_init = mac_lomac_init,
2822db2661ceSRobert Watson 	.mpo_init_bpfdesc_label = mac_lomac_init_label,
2823db2661ceSRobert Watson 	.mpo_init_cred_label = mac_lomac_init_label,
2824db2661ceSRobert Watson 	.mpo_init_devfsdirent_label = mac_lomac_init_label,
2825db2661ceSRobert Watson 	.mpo_init_ifnet_label = mac_lomac_init_label,
2826430fc756SChristian S.J. Peron 	.mpo_init_syncache_label = mac_lomac_init_label_waitcheck,
2827a557af22SRobert Watson 	.mpo_init_inpcb_label = mac_lomac_init_label_waitcheck,
28285e7ce478SRobert Watson 	.mpo_init_ipq_label = mac_lomac_init_label_waitcheck,
2829db2661ceSRobert Watson 	.mpo_init_mbuf_label = mac_lomac_init_label_waitcheck,
2830db2661ceSRobert Watson 	.mpo_init_mount_label = mac_lomac_init_label,
2831db2661ceSRobert Watson 	.mpo_init_pipe_label = mac_lomac_init_label,
2832db2661ceSRobert Watson 	.mpo_init_proc_label = mac_lomac_init_proc_label,
2833db2661ceSRobert Watson 	.mpo_init_socket_label = mac_lomac_init_label_waitcheck,
2834db2661ceSRobert Watson 	.mpo_init_socket_peer_label = mac_lomac_init_label_waitcheck,
2835db2661ceSRobert Watson 	.mpo_init_vnode_label = mac_lomac_init_label,
2836430fc756SChristian S.J. Peron 	.mpo_init_syncache_from_inpcb = mac_lomac_init_syncache_from_inpcb,
2837db2661ceSRobert Watson 	.mpo_destroy_bpfdesc_label = mac_lomac_destroy_label,
2838db2661ceSRobert Watson 	.mpo_destroy_cred_label = mac_lomac_destroy_label,
2839db2661ceSRobert Watson 	.mpo_destroy_devfsdirent_label = mac_lomac_destroy_label,
2840db2661ceSRobert Watson 	.mpo_destroy_ifnet_label = mac_lomac_destroy_label,
2841a557af22SRobert Watson 	.mpo_destroy_inpcb_label = mac_lomac_destroy_label,
2842db2661ceSRobert Watson 	.mpo_destroy_ipq_label = mac_lomac_destroy_label,
2843db2661ceSRobert Watson 	.mpo_destroy_mbuf_label = mac_lomac_destroy_label,
2844db2661ceSRobert Watson 	.mpo_destroy_mount_label = mac_lomac_destroy_label,
2845db2661ceSRobert Watson 	.mpo_destroy_pipe_label = mac_lomac_destroy_label,
2846db2661ceSRobert Watson 	.mpo_destroy_proc_label = mac_lomac_destroy_proc_label,
2847430fc756SChristian S.J. Peron 	.mpo_destroy_syncache_label = mac_lomac_destroy_label,
2848db2661ceSRobert Watson 	.mpo_destroy_socket_label = mac_lomac_destroy_label,
2849db2661ceSRobert Watson 	.mpo_destroy_socket_peer_label = mac_lomac_destroy_label,
2850db2661ceSRobert Watson 	.mpo_destroy_vnode_label = mac_lomac_destroy_label,
285156d9e932SRobert Watson 	.mpo_copy_cred_label = mac_lomac_copy_label,
28522220907bSRobert Watson 	.mpo_copy_ifnet_label = mac_lomac_copy_label,
2853985a0d97SRobert Watson 	.mpo_copy_mbuf_label = mac_lomac_copy_label,
2854db2661ceSRobert Watson 	.mpo_copy_pipe_label = mac_lomac_copy_label,
2855b0323ea3SRobert Watson 	.mpo_copy_socket_label = mac_lomac_copy_label,
2856db2661ceSRobert Watson 	.mpo_copy_vnode_label = mac_lomac_copy_label,
2857db2661ceSRobert Watson 	.mpo_externalize_cred_label = mac_lomac_externalize_label,
2858db2661ceSRobert Watson 	.mpo_externalize_ifnet_label = mac_lomac_externalize_label,
2859db2661ceSRobert Watson 	.mpo_externalize_pipe_label = mac_lomac_externalize_label,
2860db2661ceSRobert Watson 	.mpo_externalize_socket_label = mac_lomac_externalize_label,
2861db2661ceSRobert Watson 	.mpo_externalize_socket_peer_label = mac_lomac_externalize_label,
2862db2661ceSRobert Watson 	.mpo_externalize_vnode_label = mac_lomac_externalize_label,
2863db2661ceSRobert Watson 	.mpo_internalize_cred_label = mac_lomac_internalize_label,
2864db2661ceSRobert Watson 	.mpo_internalize_ifnet_label = mac_lomac_internalize_label,
2865db2661ceSRobert Watson 	.mpo_internalize_pipe_label = mac_lomac_internalize_label,
2866db2661ceSRobert Watson 	.mpo_internalize_socket_label = mac_lomac_internalize_label,
2867db2661ceSRobert Watson 	.mpo_internalize_vnode_label = mac_lomac_internalize_label,
2868db2661ceSRobert Watson 	.mpo_create_devfs_device = mac_lomac_create_devfs_device,
2869db2661ceSRobert Watson 	.mpo_create_devfs_directory = mac_lomac_create_devfs_directory,
2870db2661ceSRobert Watson 	.mpo_create_devfs_symlink = mac_lomac_create_devfs_symlink,
2871db2661ceSRobert Watson 	.mpo_create_mount = mac_lomac_create_mount,
2872db2661ceSRobert Watson 	.mpo_relabel_vnode = mac_lomac_relabel_vnode,
2873db2661ceSRobert Watson 	.mpo_update_devfsdirent = mac_lomac_update_devfsdirent,
2874db2661ceSRobert Watson 	.mpo_associate_vnode_devfs = mac_lomac_associate_vnode_devfs,
2875db2661ceSRobert Watson 	.mpo_associate_vnode_extattr = mac_lomac_associate_vnode_extattr,
2876db2661ceSRobert Watson 	.mpo_associate_vnode_singlelabel =
2877db2661ceSRobert Watson 	    mac_lomac_associate_vnode_singlelabel,
2878db2661ceSRobert Watson 	.mpo_create_vnode_extattr = mac_lomac_create_vnode_extattr,
2879db2661ceSRobert Watson 	.mpo_setlabel_vnode_extattr = mac_lomac_setlabel_vnode_extattr,
2880db2661ceSRobert Watson 	.mpo_create_mbuf_from_socket = mac_lomac_create_mbuf_from_socket,
2881430fc756SChristian S.J. Peron 	.mpo_create_mbuf_from_syncache = mac_lomac_create_mbuf_from_syncache,
2882db2661ceSRobert Watson 	.mpo_create_pipe = mac_lomac_create_pipe,
2883db2661ceSRobert Watson 	.mpo_create_socket = mac_lomac_create_socket,
2884db2661ceSRobert Watson 	.mpo_create_socket_from_socket = mac_lomac_create_socket_from_socket,
2885db2661ceSRobert Watson 	.mpo_relabel_pipe = mac_lomac_relabel_pipe,
2886db2661ceSRobert Watson 	.mpo_relabel_socket = mac_lomac_relabel_socket,
2887db2661ceSRobert Watson 	.mpo_set_socket_peer_from_mbuf = mac_lomac_set_socket_peer_from_mbuf,
2888db2661ceSRobert Watson 	.mpo_set_socket_peer_from_socket =
2889db2661ceSRobert Watson 	    mac_lomac_set_socket_peer_from_socket,
2890db2661ceSRobert Watson 	.mpo_create_bpfdesc = mac_lomac_create_bpfdesc,
2891db2661ceSRobert Watson 	.mpo_create_datagram_from_ipq = mac_lomac_create_datagram_from_ipq,
2892db2661ceSRobert Watson 	.mpo_create_fragment = mac_lomac_create_fragment,
2893db2661ceSRobert Watson 	.mpo_create_ifnet = mac_lomac_create_ifnet,
2894a557af22SRobert Watson 	.mpo_create_inpcb_from_socket = mac_lomac_create_inpcb_from_socket,
2895db2661ceSRobert Watson 	.mpo_create_ipq = mac_lomac_create_ipq,
28962d92ec98SRobert Watson 	.mpo_create_mbuf_from_inpcb = mac_lomac_create_mbuf_from_inpcb,
2897db2661ceSRobert Watson 	.mpo_create_mbuf_linklayer = mac_lomac_create_mbuf_linklayer,
2898db2661ceSRobert Watson 	.mpo_create_mbuf_from_bpfdesc = mac_lomac_create_mbuf_from_bpfdesc,
2899db2661ceSRobert Watson 	.mpo_create_mbuf_from_ifnet = mac_lomac_create_mbuf_from_ifnet,
2900db2661ceSRobert Watson 	.mpo_create_mbuf_multicast_encap =
2901db2661ceSRobert Watson 	    mac_lomac_create_mbuf_multicast_encap,
2902db2661ceSRobert Watson 	.mpo_create_mbuf_netlayer = mac_lomac_create_mbuf_netlayer,
2903db2661ceSRobert Watson 	.mpo_fragment_match = mac_lomac_fragment_match,
2904db2661ceSRobert Watson 	.mpo_relabel_ifnet = mac_lomac_relabel_ifnet,
2905db2661ceSRobert Watson 	.mpo_update_ipq = mac_lomac_update_ipq,
2906a557af22SRobert Watson 	.mpo_inpcb_sosetlabel = mac_lomac_inpcb_sosetlabel,
2907db2661ceSRobert Watson 	.mpo_execve_transition = mac_lomac_execve_transition,
2908db2661ceSRobert Watson 	.mpo_execve_will_transition = mac_lomac_execve_will_transition,
2909db2661ceSRobert Watson 	.mpo_create_proc0 = mac_lomac_create_proc0,
2910db2661ceSRobert Watson 	.mpo_create_proc1 = mac_lomac_create_proc1,
2911db2661ceSRobert Watson 	.mpo_relabel_cred = mac_lomac_relabel_cred,
2912db2661ceSRobert Watson 	.mpo_check_bpfdesc_receive = mac_lomac_check_bpfdesc_receive,
2913db2661ceSRobert Watson 	.mpo_check_cred_relabel = mac_lomac_check_cred_relabel,
2914db2661ceSRobert Watson 	.mpo_check_cred_visible = mac_lomac_check_cred_visible,
2915db2661ceSRobert Watson 	.mpo_check_ifnet_relabel = mac_lomac_check_ifnet_relabel,
2916db2661ceSRobert Watson 	.mpo_check_ifnet_transmit = mac_lomac_check_ifnet_transmit,
2917a557af22SRobert Watson 	.mpo_check_inpcb_deliver = mac_lomac_check_inpcb_deliver,
2918db2661ceSRobert Watson 	.mpo_check_kld_load = mac_lomac_check_kld_load,
2919db2661ceSRobert Watson 	.mpo_check_pipe_ioctl = mac_lomac_check_pipe_ioctl,
2920db2661ceSRobert Watson 	.mpo_check_pipe_read = mac_lomac_check_pipe_read,
2921db2661ceSRobert Watson 	.mpo_check_pipe_relabel = mac_lomac_check_pipe_relabel,
2922db2661ceSRobert Watson 	.mpo_check_pipe_write = mac_lomac_check_pipe_write,
2923db2661ceSRobert Watson 	.mpo_check_proc_debug = mac_lomac_check_proc_debug,
2924db2661ceSRobert Watson 	.mpo_check_proc_sched = mac_lomac_check_proc_sched,
2925db2661ceSRobert Watson 	.mpo_check_proc_signal = mac_lomac_check_proc_signal,
2926db2661ceSRobert Watson 	.mpo_check_socket_deliver = mac_lomac_check_socket_deliver,
2927db2661ceSRobert Watson 	.mpo_check_socket_relabel = mac_lomac_check_socket_relabel,
2928db2661ceSRobert Watson 	.mpo_check_socket_visible = mac_lomac_check_socket_visible,
292918717f69SRobert Watson 	.mpo_check_system_acct = mac_lomac_check_system_acct,
293018717f69SRobert Watson 	.mpo_check_system_auditctl = mac_lomac_check_system_auditctl,
293118717f69SRobert Watson 	.mpo_check_system_swapoff = mac_lomac_check_system_swapoff,
2932db2661ceSRobert Watson 	.mpo_check_system_swapon = mac_lomac_check_system_swapon,
2933db2661ceSRobert Watson 	.mpo_check_system_sysctl = mac_lomac_check_system_sysctl,
2934db2661ceSRobert Watson 	.mpo_check_vnode_access = mac_lomac_check_vnode_open,
2935db2661ceSRobert Watson 	.mpo_check_vnode_create = mac_lomac_check_vnode_create,
2936db2661ceSRobert Watson 	.mpo_check_vnode_delete = mac_lomac_check_vnode_delete,
2937db2661ceSRobert Watson 	.mpo_check_vnode_deleteacl = mac_lomac_check_vnode_deleteacl,
2938db2661ceSRobert Watson 	.mpo_check_vnode_link = mac_lomac_check_vnode_link,
2939db2661ceSRobert Watson 	.mpo_check_vnode_mmap = mac_lomac_check_vnode_mmap,
2940db2661ceSRobert Watson 	.mpo_check_vnode_mmap_downgrade = mac_lomac_check_vnode_mmap_downgrade,
2941db2661ceSRobert Watson 	.mpo_check_vnode_open = mac_lomac_check_vnode_open,
2942db2661ceSRobert Watson 	.mpo_check_vnode_read = mac_lomac_check_vnode_read,
2943db2661ceSRobert Watson 	.mpo_check_vnode_relabel = mac_lomac_check_vnode_relabel,
2944db2661ceSRobert Watson 	.mpo_check_vnode_rename_from = mac_lomac_check_vnode_rename_from,
2945db2661ceSRobert Watson 	.mpo_check_vnode_rename_to = mac_lomac_check_vnode_rename_to,
2946db2661ceSRobert Watson 	.mpo_check_vnode_revoke = mac_lomac_check_vnode_revoke,
2947db2661ceSRobert Watson 	.mpo_check_vnode_setacl = mac_lomac_check_vnode_setacl,
2948db2661ceSRobert Watson 	.mpo_check_vnode_setextattr = mac_lomac_check_vnode_setextattr,
2949db2661ceSRobert Watson 	.mpo_check_vnode_setflags = mac_lomac_check_vnode_setflags,
2950db2661ceSRobert Watson 	.mpo_check_vnode_setmode = mac_lomac_check_vnode_setmode,
2951db2661ceSRobert Watson 	.mpo_check_vnode_setowner = mac_lomac_check_vnode_setowner,
2952db2661ceSRobert Watson 	.mpo_check_vnode_setutimes = mac_lomac_check_vnode_setutimes,
2953db2661ceSRobert Watson 	.mpo_check_vnode_write = mac_lomac_check_vnode_write,
2954db2661ceSRobert Watson 	.mpo_thread_userret = mac_lomac_thread_userret,
2955d94f2a68SChristian S.J. Peron 	.mpo_create_mbuf_from_firewall = mac_lomac_create_mbuf_from_firewall,
2956c14d15aeSRobert Watson 	.mpo_priv_check = mac_lomac_priv_check,
2957db2661ceSRobert Watson };
2958db2661ceSRobert Watson 
2959db2661ceSRobert Watson MAC_POLICY_SET(&mac_lomac_ops, mac_lomac, "TrustedBSD MAC/LOMAC",
2960aa6a0037SRobert Watson     MPC_LOADTIME_FLAG_NOTLATE | MPC_LOADTIME_FLAG_LABELMBUFS,
2961aa6a0037SRobert Watson     &mac_lomac_slot);
2962