xref: /freebsd/sys/security/mac/mac_process.c (revision c1ff2d9baf689d473f19a763b22cf70bb1d758c1)
1 /*-
2  * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson
3  * Copyright (c) 2001 Ilmar S. Habibulin
4  * Copyright (c) 2001, 2002 Networks Associates Technology, Inc.
5  * All rights reserved.
6  *
7  * This software was developed by Robert Watson and Ilmar Habibulin for the
8  * TrustedBSD Project.
9  *
10  * This software was developed for the FreeBSD Project in part by NAI Labs,
11  * the Security Research Division of Network Associates, Inc. under
12  * DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA
13  * CHATS research program.
14  *
15  * Redistribution and use in source and binary forms, with or without
16  * modification, are permitted provided that the following conditions
17  * are met:
18  * 1. Redistributions of source code must retain the above copyright
19  *    notice, this list of conditions and the following disclaimer.
20  * 2. Redistributions in binary form must reproduce the above copyright
21  *    notice, this list of conditions and the following disclaimer in the
22  *    documentation and/or other materials provided with the distribution.
23  * 3. The names of the authors may not be used to endorse or promote
24  *    products derived from this software without specific prior written
25  *    permission.
26  *
27  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
28  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
31  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37  * SUCH DAMAGE.
38  *
39  * $FreeBSD$
40  */
41 /*
42  * Developed by the TrustedBSD Project.
43  *
44  * Framework for extensible kernel access control.  Kernel and userland
45  * interface to the framework, policy registration and composition.
46  */
47 
48 #include "opt_mac.h"
49 #include <sys/param.h>
50 #include <sys/extattr.h>
51 #include <sys/kernel.h>
52 #include <sys/lock.h>
53 #include <sys/mutex.h>
54 #include <sys/sx.h>
55 #include <sys/mac.h>
56 #include <sys/proc.h>
57 #include <sys/systm.h>
58 #include <sys/sysproto.h>
59 #include <sys/sysent.h>
60 #include <sys/vnode.h>
61 #include <sys/mount.h>
62 #include <sys/file.h>
63 #include <sys/namei.h>
64 #include <sys/socket.h>
65 #include <sys/pipe.h>
66 #include <sys/socketvar.h>
67 #include <sys/sx.h>
68 #include <sys/sysctl.h>
69 
70 #include <vm/vm.h>
71 #include <vm/pmap.h>
72 #include <vm/vm_map.h>
73 #include <vm/vm_object.h>
74 
75 #include <sys/mac_policy.h>
76 
77 #include <fs/devfs/devfs.h>
78 
79 #include <net/bpf.h>
80 #include <net/bpfdesc.h>
81 #include <net/if.h>
82 #include <net/if_var.h>
83 
84 #include <netinet/in.h>
85 #include <netinet/ip_var.h>
86 
87 #ifdef MAC
88 
89 SYSCTL_DECL(_security);
90 
91 SYSCTL_NODE(_security, OID_AUTO, mac, CTLFLAG_RW, 0,
92     "TrustedBSD MAC policy controls");
93 SYSCTL_NODE(_security_mac, OID_AUTO, debug, CTLFLAG_RW, 0,
94     "TrustedBSD MAC debug info");
95 
96 static int	mac_debug_label_fallback = 0;
97 SYSCTL_INT(_security_mac_debug, OID_AUTO, label_fallback, CTLFLAG_RW,
98     &mac_debug_label_fallback, 0, "Filesystems should fall back to fs label"
99     "when label is corrupted.");
100 TUNABLE_INT("security.mac.debug_label_fallback",
101     &mac_debug_label_fallback);
102 
103 #ifndef MAC_MAX_POLICIES
104 #define	MAC_MAX_POLICIES	8
105 #endif
106 #if MAC_MAX_POLICIES > 32
107 #error "MAC_MAX_POLICIES too large"
108 #endif
109 static unsigned int mac_max_policies = MAC_MAX_POLICIES;
110 static unsigned int mac_policy_offsets_free = (1 << MAC_MAX_POLICIES) - 1;
111 SYSCTL_UINT(_security_mac, OID_AUTO, max_policies, CTLFLAG_RD,
112     &mac_max_policies, 0, "");
113 
114 static int	mac_late = 0;
115 
116 static int	mac_enforce_fs = 1;
117 SYSCTL_INT(_security_mac, OID_AUTO, enforce_fs, CTLFLAG_RW,
118     &mac_enforce_fs, 0, "Enforce MAC policy on file system objects");
119 TUNABLE_INT("security.mac.enforce_fs", &mac_enforce_fs);
120 
121 static int	mac_enforce_network = 1;
122 SYSCTL_INT(_security_mac, OID_AUTO, enforce_network, CTLFLAG_RW,
123     &mac_enforce_network, 0, "Enforce MAC policy on network packets");
124 TUNABLE_INT("security.mac.enforce_network", &mac_enforce_network);
125 
126 static int	mac_enforce_process = 1;
127 SYSCTL_INT(_security_mac, OID_AUTO, enforce_process, CTLFLAG_RW,
128     &mac_enforce_process, 0, "Enforce MAC policy on inter-process operations");
129 TUNABLE_INT("security.mac.enforce_process", &mac_enforce_process);
130 
131 static int	mac_enforce_socket = 1;
132 SYSCTL_INT(_security_mac, OID_AUTO, enforce_socket, CTLFLAG_RW,
133     &mac_enforce_socket, 0, "Enforce MAC policy on socket operations");
134 TUNABLE_INT("security.mac.enforce_socket", &mac_enforce_socket);
135 
136 static int	mac_enforce_pipe = 1;
137 SYSCTL_INT(_security_mac, OID_AUTO, enforce_pipe, CTLFLAG_RW,
138     &mac_enforce_pipe, 0, "Enforce MAC policy on pipe operations");
139 
140 static int	mac_label_size = sizeof(struct mac);
141 SYSCTL_INT(_security_mac, OID_AUTO, label_size, CTLFLAG_RD,
142     &mac_label_size, 0, "Pre-compiled MAC label size");
143 
144 static int	mac_cache_fslabel_in_vnode = 1;
145 SYSCTL_INT(_security_mac, OID_AUTO, cache_fslabel_in_vnode, CTLFLAG_RW,
146     &mac_cache_fslabel_in_vnode, 0, "Cache mount fslabel in vnode");
147 TUNABLE_INT("security.mac.cache_fslabel_in_vnode",
148     &mac_cache_fslabel_in_vnode);
149 
150 static int	mac_vnode_label_cache_hits = 0;
151 SYSCTL_INT(_security_mac, OID_AUTO, vnode_label_cache_hits, CTLFLAG_RD,
152     &mac_vnode_label_cache_hits, 0, "Cache hits on vnode labels");
153 static int	mac_vnode_label_cache_misses = 0;
154 SYSCTL_INT(_security_mac, OID_AUTO, vnode_label_cache_misses, CTLFLAG_RD,
155     &mac_vnode_label_cache_misses, 0, "Cache misses on vnode labels");
156 static int	mac_mmap_revocation_via_cow = 1;
157 SYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation_via_cow, CTLFLAG_RW,
158     &mac_mmap_revocation_via_cow, 0, "Revoke mmap access to files via "
159     "copy-on-write semantics, or by removing all write access");
160 
161 static unsigned int nmacmbufs, nmaccreds, nmacifnets, nmacbpfdescs,
162     nmacsockets, nmacmounts, nmactemp, nmacvnodes, nmacdevfsdirents,
163     nmacipqs, nmacpipes;
164 SYSCTL_UINT(_security_mac_debug, OID_AUTO, mbufs, CTLFLAG_RD,
165     &nmacmbufs, 0, "number of mbufs in use");
166 SYSCTL_UINT(_security_mac_debug, OID_AUTO, creds, CTLFLAG_RD,
167     &nmaccreds, 0, "number of ucreds in use");
168 SYSCTL_UINT(_security_mac_debug, OID_AUTO, ifnets, CTLFLAG_RD,
169     &nmacifnets, 0, "number of ifnets in use");
170 SYSCTL_UINT(_security_mac_debug, OID_AUTO, ipqs, CTLFLAG_RD,
171     &nmacipqs, 0, "number of ipqs in use");
172 SYSCTL_UINT(_security_mac_debug, OID_AUTO, bpfdescs, CTLFLAG_RD,
173     &nmacbpfdescs, 0, "number of bpfdescs in use");
174 SYSCTL_UINT(_security_mac_debug, OID_AUTO, sockets, CTLFLAG_RD,
175     &nmacsockets, 0, "number of sockets in use");
176 SYSCTL_UINT(_security_mac_debug, OID_AUTO, pipes, CTLFLAG_RD,
177     &nmacpipes, 0, "number of pipes in use");
178 SYSCTL_UINT(_security_mac_debug, OID_AUTO, mounts, CTLFLAG_RD,
179     &nmacmounts, 0, "number of mounts in use");
180 SYSCTL_UINT(_security_mac_debug, OID_AUTO, temp, CTLFLAG_RD,
181     &nmactemp, 0, "number of temporary labels in use");
182 SYSCTL_UINT(_security_mac_debug, OID_AUTO, vnodes, CTLFLAG_RD,
183     &nmacvnodes, 0, "number of vnodes in use");
184 SYSCTL_UINT(_security_mac_debug, OID_AUTO, devfsdirents, CTLFLAG_RD,
185     &nmacdevfsdirents, 0, "number of devfs dirents inuse");
186 
187 static int	error_select(int error1, int error2);
188 static int	mac_externalize(struct label *label, struct mac *mac);
189 static int	mac_policy_register(struct mac_policy_conf *mpc);
190 static int	mac_policy_unregister(struct mac_policy_conf *mpc);
191 
192 static int	mac_stdcreatevnode_ea(struct vnode *vp);
193 static void	mac_cred_mmapped_drop_perms(struct thread *td,
194 		    struct ucred *cred);
195 static void	mac_cred_mmapped_drop_perms_recurse(struct thread *td,
196 		    struct ucred *cred, struct vm_map *map);
197 
198 MALLOC_DEFINE(M_MACOPVEC, "macopvec", "MAC policy operation vector");
199 MALLOC_DEFINE(M_MACPIPELABEL, "macpipelabel", "MAC labels for pipes");
200 
201 /*
202  * mac_policy_list_lock protects the consistency of 'mac_policy_list',
203  * the linked list of attached policy modules.  Read-only consumers of
204  * the list must acquire a shared lock for the duration of their use;
205  * writers must acquire an exclusive lock.  Note that for compound
206  * operations, locks should be held for the entire compound operation,
207  * and that this is not yet done for relabel requests.
208  */
209 static struct mtx mac_policy_list_lock;
210 static LIST_HEAD(, mac_policy_conf) mac_policy_list;
211 static int mac_policy_list_busy;
212 #define	MAC_POLICY_LIST_LOCKINIT()	mtx_init(&mac_policy_list_lock,	\
213 	"mac_policy_list_lock", NULL, MTX_DEF);
214 #define	MAC_POLICY_LIST_LOCK()	mtx_lock(&mac_policy_list_lock);
215 #define	MAC_POLICY_LIST_UNLOCK()	mtx_unlock(&mac_policy_list_lock);
216 
217 #define	MAC_POLICY_LIST_BUSY() do {					\
218 	MAC_POLICY_LIST_LOCK();						\
219 	mac_policy_list_busy++;						\
220 	MAC_POLICY_LIST_UNLOCK();					\
221 } while (0)
222 
223 #define	MAC_POLICY_LIST_UNBUSY() do {					\
224 	MAC_POLICY_LIST_LOCK();						\
225 	mac_policy_list_busy--;						\
226 	if (mac_policy_list_busy < 0)					\
227 		panic("Extra mac_policy_list_busy--");			\
228 	MAC_POLICY_LIST_UNLOCK();					\
229 } while (0)
230 
231 /*
232  * MAC_CHECK performs the designated check by walking the policy
233  * module list and checking with each as to how it feels about the
234  * request.  Note that it returns its value via 'error' in the scope
235  * of the caller.
236  */
237 #define	MAC_CHECK(check, args...) do {					\
238 	struct mac_policy_conf *mpc;					\
239 									\
240 	error = 0;							\
241 	MAC_POLICY_LIST_BUSY();						\
242 	LIST_FOREACH(mpc, &mac_policy_list, mpc_list) {			\
243 		if (mpc->mpc_ops->mpo_ ## check != NULL)		\
244 			error = error_select(				\
245 			    mpc->mpc_ops->mpo_ ## check (args),		\
246 			    error);					\
247 	}								\
248 	MAC_POLICY_LIST_UNBUSY();					\
249 } while (0)
250 
251 /*
252  * MAC_BOOLEAN performs the designated boolean composition by walking
253  * the module list, invoking each instance of the operation, and
254  * combining the results using the passed C operator.  Note that it
255  * returns its value via 'result' in the scope of the caller, which
256  * should be initialized by the caller in a meaningful way to get
257  * a meaningful result.
258  */
259 #define	MAC_BOOLEAN(operation, composition, args...) do {		\
260 	struct mac_policy_conf *mpc;					\
261 									\
262 	MAC_POLICY_LIST_BUSY();						\
263 	LIST_FOREACH(mpc, &mac_policy_list, mpc_list) {			\
264 		if (mpc->mpc_ops->mpo_ ## operation != NULL)		\
265 			result = result composition			\
266 			    mpc->mpc_ops->mpo_ ## operation (args);	\
267 	}								\
268 	MAC_POLICY_LIST_UNBUSY();					\
269 } while (0)
270 
271 /*
272  * MAC_PERFORM performs the designated operation by walking the policy
273  * module list and invoking that operation for each policy.
274  */
275 #define	MAC_PERFORM(operation, args...) do {				\
276 	struct mac_policy_conf *mpc;					\
277 									\
278 	MAC_POLICY_LIST_BUSY();						\
279 	LIST_FOREACH(mpc, &mac_policy_list, mpc_list) {			\
280 		if (mpc->mpc_ops->mpo_ ## operation != NULL)		\
281 			mpc->mpc_ops->mpo_ ## operation (args);		\
282 	}								\
283 	MAC_POLICY_LIST_UNBUSY();					\
284 } while (0)
285 
286 /*
287  * Initialize the MAC subsystem, including appropriate SMP locks.
288  */
289 static void
290 mac_init(void)
291 {
292 
293 	LIST_INIT(&mac_policy_list);
294 	MAC_POLICY_LIST_LOCKINIT();
295 }
296 
297 /*
298  * For the purposes of modules that want to know if they were loaded
299  * "early", set the mac_late flag once we've processed modules either
300  * linked into the kernel, or loaded before the kernel startup.
301  */
302 static void
303 mac_late_init(void)
304 {
305 
306 	mac_late = 1;
307 }
308 
309 /*
310  * Allow MAC policy modules to register during boot, etc.
311  */
312 int
313 mac_policy_modevent(module_t mod, int type, void *data)
314 {
315 	struct mac_policy_conf *mpc;
316 	int error;
317 
318 	error = 0;
319 	mpc = (struct mac_policy_conf *) data;
320 
321 	switch (type) {
322 	case MOD_LOAD:
323 		if (mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_NOTLATE &&
324 		    mac_late) {
325 			printf("mac_policy_modevent: can't load %s policy "
326 			    "after booting\n", mpc->mpc_name);
327 			error = EBUSY;
328 			break;
329 		}
330 		error = mac_policy_register(mpc);
331 		break;
332 	case MOD_UNLOAD:
333 		/* Don't unregister the module if it was never registered. */
334 		if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED)
335 		    != 0)
336 			error = mac_policy_unregister(mpc);
337 		else
338 			error = 0;
339 		break;
340 	default:
341 		break;
342 	}
343 
344 	return (error);
345 }
346 
347 static int
348 mac_policy_register(struct mac_policy_conf *mpc)
349 {
350 	struct mac_policy_conf *tmpc;
351 	struct mac_policy_ops *ops;
352 	struct mac_policy_op_entry *mpe;
353 	int slot;
354 
355 	MALLOC(mpc->mpc_ops, struct mac_policy_ops *, sizeof(*ops), M_MACOPVEC,
356 	    M_WAITOK | M_ZERO);
357 	for (mpe = mpc->mpc_entries; mpe->mpe_constant != MAC_OP_LAST; mpe++) {
358 		switch (mpe->mpe_constant) {
359 		case MAC_OP_LAST:
360 			/*
361 			 * Doesn't actually happen, but this allows checking
362 			 * that all enumerated values are handled.
363 			 */
364 			break;
365 		case MAC_DESTROY:
366 			mpc->mpc_ops->mpo_destroy =
367 			    mpe->mpe_function;
368 			break;
369 		case MAC_INIT:
370 			mpc->mpc_ops->mpo_init =
371 			    mpe->mpe_function;
372 			break;
373 		case MAC_INIT_BPFDESC:
374 			mpc->mpc_ops->mpo_init_bpfdesc =
375 			    mpe->mpe_function;
376 			break;
377 		case MAC_INIT_CRED:
378 			mpc->mpc_ops->mpo_init_cred =
379 			    mpe->mpe_function;
380 			break;
381 		case MAC_INIT_DEVFSDIRENT:
382 			mpc->mpc_ops->mpo_init_devfsdirent =
383 			    mpe->mpe_function;
384 			break;
385 		case MAC_INIT_IFNET:
386 			mpc->mpc_ops->mpo_init_ifnet =
387 			    mpe->mpe_function;
388 			break;
389 		case MAC_INIT_IPQ:
390 			mpc->mpc_ops->mpo_init_ipq =
391 			    mpe->mpe_function;
392 			break;
393 		case MAC_INIT_MBUF:
394 			mpc->mpc_ops->mpo_init_mbuf =
395 			    mpe->mpe_function;
396 			break;
397 		case MAC_INIT_MOUNT:
398 			mpc->mpc_ops->mpo_init_mount =
399 			    mpe->mpe_function;
400 			break;
401 		case MAC_INIT_PIPE:
402 			mpc->mpc_ops->mpo_init_pipe =
403 			    mpe->mpe_function;
404 			break;
405 		case MAC_INIT_SOCKET:
406 			mpc->mpc_ops->mpo_init_socket =
407 			    mpe->mpe_function;
408 			break;
409 		case MAC_INIT_TEMP:
410 			mpc->mpc_ops->mpo_init_temp =
411 			    mpe->mpe_function;
412 			break;
413 		case MAC_INIT_VNODE:
414 			mpc->mpc_ops->mpo_init_vnode =
415 			    mpe->mpe_function;
416 			break;
417 		case MAC_DESTROY_BPFDESC:
418 			mpc->mpc_ops->mpo_destroy_bpfdesc =
419 			    mpe->mpe_function;
420 			break;
421 		case MAC_DESTROY_CRED:
422 			mpc->mpc_ops->mpo_destroy_cred =
423 			    mpe->mpe_function;
424 			break;
425 		case MAC_DESTROY_DEVFSDIRENT:
426 			mpc->mpc_ops->mpo_destroy_devfsdirent =
427 			    mpe->mpe_function;
428 			break;
429 		case MAC_DESTROY_IFNET:
430 			mpc->mpc_ops->mpo_destroy_ifnet =
431 			    mpe->mpe_function;
432 			break;
433 		case MAC_DESTROY_IPQ:
434 			mpc->mpc_ops->mpo_destroy_ipq =
435 			    mpe->mpe_function;
436 			break;
437 		case MAC_DESTROY_MBUF:
438 			mpc->mpc_ops->mpo_destroy_mbuf =
439 			    mpe->mpe_function;
440 			break;
441 		case MAC_DESTROY_MOUNT:
442 			mpc->mpc_ops->mpo_destroy_mount =
443 			    mpe->mpe_function;
444 			break;
445 		case MAC_DESTROY_PIPE:
446 			mpc->mpc_ops->mpo_destroy_pipe =
447 			    mpe->mpe_function;
448 			break;
449 		case MAC_DESTROY_SOCKET:
450 			mpc->mpc_ops->mpo_destroy_socket =
451 			    mpe->mpe_function;
452 			break;
453 		case MAC_DESTROY_TEMP:
454 			mpc->mpc_ops->mpo_destroy_temp =
455 			    mpe->mpe_function;
456 			break;
457 		case MAC_DESTROY_VNODE:
458 			mpc->mpc_ops->mpo_destroy_vnode =
459 			    mpe->mpe_function;
460 			break;
461 		case MAC_EXTERNALIZE:
462 			mpc->mpc_ops->mpo_externalize =
463 			    mpe->mpe_function;
464 			break;
465 		case MAC_INTERNALIZE:
466 			mpc->mpc_ops->mpo_internalize =
467 			    mpe->mpe_function;
468 			break;
469 		case MAC_CREATE_DEVFS_DEVICE:
470 			mpc->mpc_ops->mpo_create_devfs_device =
471 			    mpe->mpe_function;
472 			break;
473 		case MAC_CREATE_DEVFS_DIRECTORY:
474 			mpc->mpc_ops->mpo_create_devfs_directory =
475 			    mpe->mpe_function;
476 			break;
477 		case MAC_CREATE_DEVFS_VNODE:
478 			mpc->mpc_ops->mpo_create_devfs_vnode =
479 			    mpe->mpe_function;
480 			break;
481 		case MAC_STDCREATEVNODE_EA:
482 			mpc->mpc_ops->mpo_stdcreatevnode_ea =
483 			    mpe->mpe_function;
484 			break;
485 		case MAC_CREATE_VNODE:
486 			mpc->mpc_ops->mpo_create_vnode =
487 			    mpe->mpe_function;
488 			break;
489 		case MAC_CREATE_MOUNT:
490 			mpc->mpc_ops->mpo_create_mount =
491 			    mpe->mpe_function;
492 			break;
493 		case MAC_CREATE_ROOT_MOUNT:
494 			mpc->mpc_ops->mpo_create_root_mount =
495 			    mpe->mpe_function;
496 			break;
497 		case MAC_RELABEL_VNODE:
498 			mpc->mpc_ops->mpo_relabel_vnode =
499 			    mpe->mpe_function;
500 			break;
501 		case MAC_UPDATE_DEVFSDIRENT:
502 			mpc->mpc_ops->mpo_update_devfsdirent =
503 			    mpe->mpe_function;
504 			break;
505 		case MAC_UPDATE_PROCFSVNODE:
506 			mpc->mpc_ops->mpo_update_procfsvnode =
507 			    mpe->mpe_function;
508 			break;
509 		case MAC_UPDATE_VNODE_FROM_EXTATTR:
510 			mpc->mpc_ops->mpo_update_vnode_from_extattr =
511 			    mpe->mpe_function;
512 			break;
513 		case MAC_UPDATE_VNODE_FROM_EXTERNALIZED:
514 			mpc->mpc_ops->mpo_update_vnode_from_externalized =
515 			    mpe->mpe_function;
516 			break;
517 		case MAC_UPDATE_VNODE_FROM_MOUNT:
518 			mpc->mpc_ops->mpo_update_vnode_from_mount =
519 			    mpe->mpe_function;
520 			break;
521 		case MAC_CREATE_MBUF_FROM_SOCKET:
522 			mpc->mpc_ops->mpo_create_mbuf_from_socket =
523 			    mpe->mpe_function;
524 			break;
525 		case MAC_CREATE_PIPE:
526 			mpc->mpc_ops->mpo_create_pipe =
527 			    mpe->mpe_function;
528 			break;
529 		case MAC_CREATE_SOCKET:
530 			mpc->mpc_ops->mpo_create_socket =
531 			    mpe->mpe_function;
532 			break;
533 		case MAC_CREATE_SOCKET_FROM_SOCKET:
534 			mpc->mpc_ops->mpo_create_socket_from_socket =
535 			    mpe->mpe_function;
536 			break;
537 		case MAC_RELABEL_PIPE:
538 			mpc->mpc_ops->mpo_relabel_pipe =
539 			    mpe->mpe_function;
540 			break;
541 		case MAC_RELABEL_SOCKET:
542 			mpc->mpc_ops->mpo_relabel_socket =
543 			    mpe->mpe_function;
544 			break;
545 		case MAC_SET_SOCKET_PEER_FROM_MBUF:
546 			mpc->mpc_ops->mpo_set_socket_peer_from_mbuf =
547 			    mpe->mpe_function;
548 			break;
549 		case MAC_SET_SOCKET_PEER_FROM_SOCKET:
550 			mpc->mpc_ops->mpo_set_socket_peer_from_socket =
551 			    mpe->mpe_function;
552 			break;
553 		case MAC_CREATE_BPFDESC:
554 			mpc->mpc_ops->mpo_create_bpfdesc =
555 			    mpe->mpe_function;
556 			break;
557 		case MAC_CREATE_DATAGRAM_FROM_IPQ:
558 			mpc->mpc_ops->mpo_create_datagram_from_ipq =
559 			    mpe->mpe_function;
560 			break;
561 		case MAC_CREATE_FRAGMENT:
562 			mpc->mpc_ops->mpo_create_fragment =
563 			    mpe->mpe_function;
564 			break;
565 		case MAC_CREATE_IFNET:
566 			mpc->mpc_ops->mpo_create_ifnet =
567 			    mpe->mpe_function;
568 			break;
569 		case MAC_CREATE_IPQ:
570 			mpc->mpc_ops->mpo_create_ipq =
571 			    mpe->mpe_function;
572 			break;
573 		case MAC_CREATE_MBUF_FROM_MBUF:
574 			mpc->mpc_ops->mpo_create_mbuf_from_mbuf =
575 			    mpe->mpe_function;
576 			break;
577 		case MAC_CREATE_MBUF_LINKLAYER:
578 			mpc->mpc_ops->mpo_create_mbuf_linklayer =
579 			    mpe->mpe_function;
580 			break;
581 		case MAC_CREATE_MBUF_FROM_BPFDESC:
582 			mpc->mpc_ops->mpo_create_mbuf_from_bpfdesc =
583 			    mpe->mpe_function;
584 			break;
585 		case MAC_CREATE_MBUF_FROM_IFNET:
586 			mpc->mpc_ops->mpo_create_mbuf_from_ifnet =
587 			    mpe->mpe_function;
588 			break;
589 		case MAC_CREATE_MBUF_MULTICAST_ENCAP:
590 			mpc->mpc_ops->mpo_create_mbuf_multicast_encap =
591 			    mpe->mpe_function;
592 			break;
593 		case MAC_CREATE_MBUF_NETLAYER:
594 			mpc->mpc_ops->mpo_create_mbuf_netlayer =
595 			    mpe->mpe_function;
596 			break;
597 		case MAC_FRAGMENT_MATCH:
598 			mpc->mpc_ops->mpo_fragment_match =
599 			    mpe->mpe_function;
600 			break;
601 		case MAC_RELABEL_IFNET:
602 			mpc->mpc_ops->mpo_relabel_ifnet =
603 			    mpe->mpe_function;
604 			break;
605 		case MAC_UPDATE_IPQ:
606 			mpc->mpc_ops->mpo_update_ipq =
607 			    mpe->mpe_function;
608 			break;
609 		case MAC_CREATE_CRED:
610 			mpc->mpc_ops->mpo_create_cred =
611 			    mpe->mpe_function;
612 			break;
613 		case MAC_EXECVE_TRANSITION:
614 			mpc->mpc_ops->mpo_execve_transition =
615 			    mpe->mpe_function;
616 			break;
617 		case MAC_EXECVE_WILL_TRANSITION:
618 			mpc->mpc_ops->mpo_execve_will_transition =
619 			    mpe->mpe_function;
620 			break;
621 		case MAC_CREATE_PROC0:
622 			mpc->mpc_ops->mpo_create_proc0 = mpe->mpe_function;
623 			break;
624 		case MAC_CREATE_PROC1:
625 			mpc->mpc_ops->mpo_create_proc1 = mpe->mpe_function;
626 			break;
627 		case MAC_RELABEL_CRED:
628 			mpc->mpc_ops->mpo_relabel_cred =
629 			    mpe->mpe_function;
630 			break;
631 		case MAC_CHECK_BPFDESC_RECEIVE:
632 			mpc->mpc_ops->mpo_check_bpfdesc_receive =
633 			    mpe->mpe_function;
634 			break;
635 		case MAC_CHECK_CRED_RELABEL:
636 			mpc->mpc_ops->mpo_check_cred_relabel =
637 			    mpe->mpe_function;
638 			break;
639 		case MAC_CHECK_CRED_VISIBLE:
640 			mpc->mpc_ops->mpo_check_cred_visible =
641 			    mpe->mpe_function;
642 			break;
643 		case MAC_CHECK_IFNET_RELABEL:
644 			mpc->mpc_ops->mpo_check_ifnet_relabel =
645 			    mpe->mpe_function;
646 			break;
647 		case MAC_CHECK_IFNET_TRANSMIT:
648 			mpc->mpc_ops->mpo_check_ifnet_transmit =
649 			    mpe->mpe_function;
650 			break;
651 		case MAC_CHECK_MOUNT_STAT:
652 			mpc->mpc_ops->mpo_check_mount_stat =
653 			    mpe->mpe_function;
654 			break;
655 		case MAC_CHECK_PIPE_IOCTL:
656 			mpc->mpc_ops->mpo_check_pipe_ioctl =
657 			    mpe->mpe_function;
658 			break;
659 		case MAC_CHECK_PIPE_OP:
660 			mpc->mpc_ops->mpo_check_pipe_op =
661 			    mpe->mpe_function;
662 			break;
663 		case MAC_CHECK_PIPE_RELABEL:
664 			mpc->mpc_ops->mpo_check_pipe_relabel =
665 			    mpe->mpe_function;
666 			break;
667 		case MAC_CHECK_PROC_DEBUG:
668 			mpc->mpc_ops->mpo_check_proc_debug =
669 			    mpe->mpe_function;
670 			break;
671 		case MAC_CHECK_PROC_SCHED:
672 			mpc->mpc_ops->mpo_check_proc_sched =
673 			    mpe->mpe_function;
674 			break;
675 		case MAC_CHECK_PROC_SIGNAL:
676 			mpc->mpc_ops->mpo_check_proc_signal =
677 			    mpe->mpe_function;
678 			break;
679 		case MAC_CHECK_SOCKET_BIND:
680 			mpc->mpc_ops->mpo_check_socket_bind =
681 			    mpe->mpe_function;
682 			break;
683 		case MAC_CHECK_SOCKET_CONNECT:
684 			mpc->mpc_ops->mpo_check_socket_connect =
685 			    mpe->mpe_function;
686 			break;
687 		case MAC_CHECK_SOCKET_LISTEN:
688 			mpc->mpc_ops->mpo_check_socket_listen =
689 			    mpe->mpe_function;
690 			break;
691 		case MAC_CHECK_SOCKET_RECEIVE:
692 			mpc->mpc_ops->mpo_check_socket_receive =
693 			    mpe->mpe_function;
694 			break;
695 		case MAC_CHECK_SOCKET_RELABEL:
696 			mpc->mpc_ops->mpo_check_socket_relabel =
697 			    mpe->mpe_function;
698 			break;
699 		case MAC_CHECK_SOCKET_VISIBLE:
700 			mpc->mpc_ops->mpo_check_socket_visible =
701 			    mpe->mpe_function;
702 			break;
703 		case MAC_CHECK_VNODE_ACCESS:
704 			mpc->mpc_ops->mpo_check_vnode_access =
705 			    mpe->mpe_function;
706 			break;
707 		case MAC_CHECK_VNODE_CHDIR:
708 			mpc->mpc_ops->mpo_check_vnode_chdir =
709 			    mpe->mpe_function;
710 			break;
711 		case MAC_CHECK_VNODE_CHROOT:
712 			mpc->mpc_ops->mpo_check_vnode_chroot =
713 			    mpe->mpe_function;
714 			break;
715 		case MAC_CHECK_VNODE_CREATE:
716 			mpc->mpc_ops->mpo_check_vnode_create =
717 			    mpe->mpe_function;
718 			break;
719 		case MAC_CHECK_VNODE_DELETE:
720 			mpc->mpc_ops->mpo_check_vnode_delete =
721 			    mpe->mpe_function;
722 			break;
723 		case MAC_CHECK_VNODE_DELETEACL:
724 			mpc->mpc_ops->mpo_check_vnode_deleteacl =
725 			    mpe->mpe_function;
726 			break;
727 		case MAC_CHECK_VNODE_EXEC:
728 			mpc->mpc_ops->mpo_check_vnode_exec =
729 			    mpe->mpe_function;
730 			break;
731 		case MAC_CHECK_VNODE_GETACL:
732 			mpc->mpc_ops->mpo_check_vnode_getacl =
733 			    mpe->mpe_function;
734 			break;
735 		case MAC_CHECK_VNODE_GETEXTATTR:
736 			mpc->mpc_ops->mpo_check_vnode_getextattr =
737 			    mpe->mpe_function;
738 			break;
739 		case MAC_CHECK_VNODE_LOOKUP:
740 			mpc->mpc_ops->mpo_check_vnode_lookup =
741 			    mpe->mpe_function;
742 			break;
743 		case MAC_CHECK_VNODE_MMAP_PERMS:
744 			mpc->mpc_ops->mpo_check_vnode_mmap_perms =
745 			    mpe->mpe_function;
746 			break;
747 		case MAC_CHECK_VNODE_OP:
748 			mpc->mpc_ops->mpo_check_vnode_op =
749 			    mpe->mpe_function;
750 			break;
751 		case MAC_CHECK_VNODE_OPEN:
752 			mpc->mpc_ops->mpo_check_vnode_open =
753 			    mpe->mpe_function;
754 			break;
755 		case MAC_CHECK_VNODE_READDIR:
756 			mpc->mpc_ops->mpo_check_vnode_readdir =
757 			    mpe->mpe_function;
758 			break;
759 		case MAC_CHECK_VNODE_READLINK:
760 			mpc->mpc_ops->mpo_check_vnode_readlink =
761 			    mpe->mpe_function;
762 			break;
763 		case MAC_CHECK_VNODE_RELABEL:
764 			mpc->mpc_ops->mpo_check_vnode_relabel =
765 			    mpe->mpe_function;
766 			break;
767 		case MAC_CHECK_VNODE_RENAME_FROM:
768 			mpc->mpc_ops->mpo_check_vnode_rename_from =
769 			    mpe->mpe_function;
770 			break;
771 		case MAC_CHECK_VNODE_RENAME_TO:
772 			mpc->mpc_ops->mpo_check_vnode_rename_to =
773 			    mpe->mpe_function;
774 			break;
775 		case MAC_CHECK_VNODE_REVOKE:
776 			mpc->mpc_ops->mpo_check_vnode_revoke =
777 			    mpe->mpe_function;
778 			break;
779 		case MAC_CHECK_VNODE_SETACL:
780 			mpc->mpc_ops->mpo_check_vnode_setacl =
781 			    mpe->mpe_function;
782 			break;
783 		case MAC_CHECK_VNODE_SETEXTATTR:
784 			mpc->mpc_ops->mpo_check_vnode_setextattr =
785 			    mpe->mpe_function;
786 			break;
787 		case MAC_CHECK_VNODE_SETFLAGS:
788 			mpc->mpc_ops->mpo_check_vnode_setflags =
789 			    mpe->mpe_function;
790 			break;
791 		case MAC_CHECK_VNODE_SETMODE:
792 			mpc->mpc_ops->mpo_check_vnode_setmode =
793 			    mpe->mpe_function;
794 			break;
795 		case MAC_CHECK_VNODE_SETOWNER:
796 			mpc->mpc_ops->mpo_check_vnode_setowner =
797 			    mpe->mpe_function;
798 			break;
799 		case MAC_CHECK_VNODE_SETUTIMES:
800 			mpc->mpc_ops->mpo_check_vnode_setutimes =
801 			    mpe->mpe_function;
802 			break;
803 		case MAC_CHECK_VNODE_STAT:
804 			mpc->mpc_ops->mpo_check_vnode_stat =
805 			    mpe->mpe_function;
806 			break;
807 /*
808 		default:
809 			printf("MAC policy `%s': unknown operation %d\n",
810 			    mpc->mpc_name, mpe->mpe_constant);
811 			return (EINVAL);
812 */
813 		}
814 	}
815 	MAC_POLICY_LIST_LOCK();
816 	if (mac_policy_list_busy > 0) {
817 		MAC_POLICY_LIST_UNLOCK();
818 		FREE(mpc->mpc_ops, M_MACOPVEC);
819 		mpc->mpc_ops = NULL;
820 		return (EBUSY);
821 	}
822 	LIST_FOREACH(tmpc, &mac_policy_list, mpc_list) {
823 		if (strcmp(tmpc->mpc_name, mpc->mpc_name) == 0) {
824 			MAC_POLICY_LIST_UNLOCK();
825 			FREE(mpc->mpc_ops, M_MACOPVEC);
826 			mpc->mpc_ops = NULL;
827 			return (EEXIST);
828 		}
829 	}
830 	if (mpc->mpc_field_off != NULL) {
831 		slot = ffs(mac_policy_offsets_free);
832 		if (slot == 0) {
833 			MAC_POLICY_LIST_UNLOCK();
834 			FREE(mpc->mpc_ops, M_MACOPVEC);
835 			mpc->mpc_ops = NULL;
836 			return (ENOMEM);
837 		}
838 		slot--;
839 		mac_policy_offsets_free &= ~(1 << slot);
840 		*mpc->mpc_field_off = slot;
841 	}
842 	mpc->mpc_runtime_flags |= MPC_RUNTIME_FLAG_REGISTERED;
843 	LIST_INSERT_HEAD(&mac_policy_list, mpc, mpc_list);
844 
845 	/* Per-policy initialization. */
846 	if (mpc->mpc_ops->mpo_init != NULL)
847 		(*(mpc->mpc_ops->mpo_init))(mpc);
848 	MAC_POLICY_LIST_UNLOCK();
849 
850 	printf("Security policy loaded: %s (%s)\n", mpc->mpc_fullname,
851 	    mpc->mpc_name);
852 
853 	return (0);
854 }
855 
856 static int
857 mac_policy_unregister(struct mac_policy_conf *mpc)
858 {
859 
860 #if 0
861 	/*
862 	 * Don't allow unloading modules with private data.
863 	 */
864 	if (mpc->mpc_field_off != NULL)
865 		return (EBUSY);
866 #endif
867 	if ((mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_UNLOADOK) == 0)
868 		return (EBUSY);
869 	MAC_POLICY_LIST_LOCK();
870 	if (mac_policy_list_busy > 0) {
871 		MAC_POLICY_LIST_UNLOCK();
872 		return (EBUSY);
873 	}
874 	if (mpc->mpc_ops->mpo_destroy != NULL)
875 		(*(mpc->mpc_ops->mpo_destroy))(mpc);
876 
877 	LIST_REMOVE(mpc, mpc_list);
878 	MAC_POLICY_LIST_UNLOCK();
879 
880 	FREE(mpc->mpc_ops, M_MACOPVEC);
881 	mpc->mpc_ops = NULL;
882 
883 	printf("Security policy unload: %s (%s)\n", mpc->mpc_fullname,
884 	    mpc->mpc_name);
885 
886 	return (0);
887 }
888 
889 /*
890  * Define an error value precedence, and given two arguments, selects the
891  * value with the higher precedence.
892  */
893 static int
894 error_select(int error1, int error2)
895 {
896 
897 	/* Certain decision-making errors take top priority. */
898 	if (error1 == EDEADLK || error2 == EDEADLK)
899 		return (EDEADLK);
900 
901 	/* Invalid arguments should be reported where possible. */
902 	if (error1 == EINVAL || error2 == EINVAL)
903 		return (EINVAL);
904 
905 	/* Precedence goes to "visibility", with both process and file. */
906 	if (error1 == ESRCH || error2 == ESRCH)
907 		return (ESRCH);
908 
909 	if (error1 == ENOENT || error2 == ENOENT)
910 		return (ENOENT);
911 
912 	/* Precedence goes to DAC/MAC protections. */
913 	if (error1 == EACCES || error2 == EACCES)
914 		return (EACCES);
915 
916 	/* Precedence goes to privilege. */
917 	if (error1 == EPERM || error2 == EPERM)
918 		return (EPERM);
919 
920 	/* Precedence goes to error over success; otherwise, arbitrary. */
921 	if (error1 != 0)
922 		return (error1);
923 	return (error2);
924 }
925 
926 void
927 mac_update_devfsdirent(struct devfs_dirent *de, struct vnode *vp)
928 {
929 
930 	MAC_PERFORM(update_devfsdirent, de, &de->de_label, vp, &vp->v_label);
931 }
932 
933 void
934 mac_update_procfsvnode(struct vnode *vp, struct ucred *cred)
935 {
936 
937 	MAC_PERFORM(update_procfsvnode, vp, &vp->v_label, cred);
938 }
939 
940 /*
941  * Support callout for policies that manage their own externalization
942  * using extended attributes.
943  */
944 static int
945 mac_update_vnode_from_extattr(struct vnode *vp, struct mount *mp)
946 {
947 	int error;
948 
949 	MAC_CHECK(update_vnode_from_extattr, vp, &vp->v_label, mp,
950 	    &mp->mnt_fslabel);
951 
952 	return (error);
953 }
954 
955 /*
956  * Given an externalized mac label, internalize it and stamp it on a
957  * vnode.
958  */
959 static int
960 mac_update_vnode_from_externalized(struct vnode *vp, struct mac *extmac)
961 {
962 	int error;
963 
964 	MAC_CHECK(update_vnode_from_externalized, vp, &vp->v_label, extmac);
965 
966 	return (error);
967 }
968 
969 /*
970  * Call out to individual policies to update the label in a vnode from
971  * the mountpoint.
972  */
973 void
974 mac_update_vnode_from_mount(struct vnode *vp, struct mount *mp)
975 {
976 
977 	MAC_PERFORM(update_vnode_from_mount, vp, &vp->v_label, mp,
978 	    &mp->mnt_fslabel);
979 
980 	if (mac_cache_fslabel_in_vnode)
981 		vp->v_flag |= VCACHEDLABEL;
982 }
983 
984 /*
985  * Implementation of VOP_REFRESHLABEL() that relies on extended attributes
986  * to store label data.  Can be referenced by filesystems supporting
987  * extended attributes.
988  */
989 int
990 vop_stdrefreshlabel_ea(struct vop_refreshlabel_args *ap)
991 {
992 	struct vnode *vp = ap->a_vp;
993 	struct mac extmac;
994 	int buflen, error;
995 
996 	ASSERT_VOP_LOCKED(vp, "vop_stdrefreshlabel_ea");
997 
998 	/*
999 	 * Call out to external policies first.  Order doesn't really
1000 	 * matter, as long as failure of one assures failure of all.
1001 	 */
1002 	error = mac_update_vnode_from_extattr(vp, vp->v_mount);
1003 	if (error)
1004 		return (error);
1005 
1006 	buflen = sizeof(extmac);
1007 	error = vn_extattr_get(vp, IO_NODELOCKED,
1008 	    FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME, &buflen,
1009 	    (char *)&extmac, curthread);
1010 	switch (error) {
1011 	case 0:
1012 		/* Got it */
1013 		break;
1014 
1015 	case ENOATTR:
1016 		/*
1017 		 * Use the label from the mount point.
1018 		 */
1019 		mac_update_vnode_from_mount(vp, vp->v_mount);
1020 		return (0);
1021 
1022 	case EOPNOTSUPP:
1023 	default:
1024 		/* Fail horribly. */
1025 		return (error);
1026 	}
1027 
1028 	if (buflen != sizeof(extmac))
1029 		error = EPERM;		/* Fail very closed. */
1030 	if (error == 0)
1031 		error = mac_update_vnode_from_externalized(vp, &extmac);
1032 	if (error == 0)
1033 		vp->v_flag |= VCACHEDLABEL;
1034 	else {
1035 		struct vattr va;
1036 
1037 		printf("Corrupted label on %s",
1038 		    vp->v_mount->mnt_stat.f_mntonname);
1039 		if (VOP_GETATTR(vp, &va, curthread->td_ucred, curthread) == 0)
1040 			printf(" inum %ld", va.va_fileid);
1041 		if (mac_debug_label_fallback) {
1042 			printf(", falling back.\n");
1043 			mac_update_vnode_from_mount(vp, vp->v_mount);
1044 			error = 0;
1045 		} else {
1046 			printf(".\n");
1047 			error = EPERM;
1048 		}
1049 	}
1050 
1051 	return (error);
1052 }
1053 
1054 /*
1055  * Make sure the vnode label is up-to-date.  If EOPNOTSUPP, then we handle
1056  * the labeling activity outselves.  Filesystems should be careful not
1057  * to change their minds regarding whether they support vop_refreshlabel()
1058  * for a vnode or not.  Don't cache the vnode here, allow the file
1059  * system code to determine if it's safe to cache.  If we update from
1060  * the mount, don't cache since a change to the mount label should affect
1061  * all vnodes.
1062  */
1063 static int
1064 vn_refreshlabel(struct vnode *vp, struct ucred *cred)
1065 {
1066 	int error;
1067 
1068 	ASSERT_VOP_LOCKED(vp, "vn_refreshlabel");
1069 
1070 	if (vp->v_mount == NULL) {
1071 /*
1072 		Eventually, we probably want to special-case refreshing
1073 		of deadfs vnodes, and if there's a lock-free race somewhere,
1074 		that case might be handled here.
1075 
1076 		mac_update_vnode_deadfs(vp);
1077 		return (0);
1078  */
1079 		/* printf("vn_refreshlabel: null v_mount\n"); */
1080 		if (vp->v_tag != VT_NON)
1081 			printf(
1082 			    "vn_refreshlabel: null v_mount with non-VT_NON\n");
1083 		return (EBADF);
1084 	}
1085 
1086 	if (vp->v_flag & VCACHEDLABEL) {
1087 		mac_vnode_label_cache_hits++;
1088 		return (0);
1089 	} else
1090 		mac_vnode_label_cache_misses++;
1091 
1092 	if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) {
1093 		mac_update_vnode_from_mount(vp, vp->v_mount);
1094 		return (0);
1095 	}
1096 
1097 	error = VOP_REFRESHLABEL(vp, cred, curthread);
1098 	switch (error) {
1099 	case EOPNOTSUPP:
1100 		/*
1101 		 * If labels are not supported on this vnode, fall back to
1102 		 * the label in the mount and propagate it to the vnode.
1103 		 * There should probably be some sort of policy/flag/decision
1104 		 * about doing this.
1105 		 */
1106 		mac_update_vnode_from_mount(vp, vp->v_mount);
1107 		error = 0;
1108 	default:
1109 		return (error);
1110 	}
1111 }
1112 
1113 /*
1114  * Helper function for file systems using the vop_std*_ea() calls.  This
1115  * function must be called after EA service is available for the vnode,
1116  * but before it's hooked up to the namespace so that the node persists
1117  * if there's a crash, or before it can be accessed.  On successful
1118  * commit of the label to disk (etc), do cache the label.
1119  */
1120 int
1121 vop_stdcreatevnode_ea(struct vnode *dvp, struct vnode *tvp, struct ucred *cred)
1122 {
1123 	struct mac extmac;
1124 	int error;
1125 
1126 	if ((dvp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) {
1127 		mac_update_vnode_from_mount(tvp, tvp->v_mount);
1128 	} else {
1129 		error = vn_refreshlabel(dvp, cred);
1130 		if (error)
1131 			return (error);
1132 
1133 		/*
1134 		 * Stick the label in the vnode.  Then try to write to
1135 		 * disk.  If we fail, return a failure to abort the
1136 		 * create operation.  Really, this failure shouldn't
1137 		 * happen except in fairly unusual circumstances (out
1138 		 * of disk, etc).
1139 		 */
1140 		mac_create_vnode(cred, dvp, tvp);
1141 
1142 		error = mac_stdcreatevnode_ea(tvp);
1143 		if (error)
1144 			return (error);
1145 
1146 		/*
1147 		 * XXX: Eventually this will go away and all policies will
1148 		 * directly manage their extended attributes.
1149 		 */
1150 		error = mac_externalize(&tvp->v_label, &extmac);
1151 		if (error)
1152 			return (error);
1153 
1154 		error = vn_extattr_set(tvp, IO_NODELOCKED,
1155 		    FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME,
1156 		    sizeof(extmac), (char *)&extmac, curthread);
1157 		if (error == 0)
1158 			tvp->v_flag |= VCACHEDLABEL;
1159 		else {
1160 #if 0
1161 			/*
1162 			 * In theory, we could have fall-back behavior here.
1163 			 * It would probably be incorrect.
1164 			 */
1165 #endif
1166 			return (error);
1167 		}
1168 	}
1169 
1170 	return (0);
1171 }
1172 
1173 void
1174 mac_execve_transition(struct ucred *old, struct ucred *new, struct vnode *vp)
1175 {
1176 	int error;
1177 
1178 	ASSERT_VOP_LOCKED(vp, "mac_execve_transition");
1179 
1180 	error = vn_refreshlabel(vp, old);
1181 	if (error) {
1182 		printf("mac_execve_transition: vn_refreshlabel returned %d\n",
1183 		    error);
1184 		printf("mac_execve_transition: using old vnode label\n");
1185 	}
1186 
1187 	MAC_PERFORM(execve_transition, old, new, vp, &vp->v_label);
1188 }
1189 
1190 int
1191 mac_execve_will_transition(struct ucred *old, struct vnode *vp)
1192 {
1193 	int error, result;
1194 
1195 	error = vn_refreshlabel(vp, old);
1196 	if (error)
1197 		return (error);
1198 
1199 	result = 0;
1200 	MAC_BOOLEAN(execve_will_transition, ||, old, vp, &vp->v_label);
1201 
1202 	return (result);
1203 }
1204 
1205 static void
1206 mac_init_label(struct label *label)
1207 {
1208 
1209 	bzero(label, sizeof(*label));
1210 	label->l_flags = MAC_FLAG_INITIALIZED;
1211 }
1212 
1213 static void
1214 mac_init_structmac(struct mac *mac)
1215 {
1216 
1217 	bzero(mac, sizeof(*mac));
1218 	mac->m_macflags = MAC_FLAG_INITIALIZED;
1219 }
1220 
1221 static void
1222 mac_destroy_label(struct label *label)
1223 {
1224 
1225 	KASSERT(label->l_flags & MAC_FLAG_INITIALIZED,
1226 	    ("destroying uninitialized label"));
1227 
1228 	bzero(label, sizeof(*label));
1229 	/* implicit: label->l_flags &= ~MAC_FLAG_INITIALIZED; */
1230 }
1231 
1232 int
1233 mac_init_mbuf(struct mbuf *m, int how)
1234 {
1235 	KASSERT(m->m_flags & M_PKTHDR, ("mac_init_mbuf on non-header mbuf"));
1236 
1237 	/* "how" is one of M_(TRY|DONT)WAIT */
1238 	mac_init_label(&m->m_pkthdr.label);
1239 	MAC_PERFORM(init_mbuf, m, how, &m->m_pkthdr.label);
1240 	atomic_add_int(&nmacmbufs, 1);
1241 	return (0);
1242 }
1243 
1244 void
1245 mac_destroy_mbuf(struct mbuf *m)
1246 {
1247 
1248 	MAC_PERFORM(destroy_mbuf, m, &m->m_pkthdr.label);
1249 	mac_destroy_label(&m->m_pkthdr.label);
1250 	atomic_subtract_int(&nmacmbufs, 1);
1251 }
1252 
1253 void
1254 mac_init_cred(struct ucred *cr)
1255 {
1256 
1257 	mac_init_label(&cr->cr_label);
1258 	MAC_PERFORM(init_cred, cr, &cr->cr_label);
1259 	atomic_add_int(&nmaccreds, 1);
1260 }
1261 
1262 void
1263 mac_destroy_cred(struct ucred *cr)
1264 {
1265 
1266 	MAC_PERFORM(destroy_cred, cr, &cr->cr_label);
1267 	mac_destroy_label(&cr->cr_label);
1268 	atomic_subtract_int(&nmaccreds, 1);
1269 }
1270 
1271 void
1272 mac_init_ifnet(struct ifnet *ifp)
1273 {
1274 
1275 	mac_init_label(&ifp->if_label);
1276 	MAC_PERFORM(init_ifnet, ifp, &ifp->if_label);
1277 	atomic_add_int(&nmacifnets, 1);
1278 }
1279 
1280 void
1281 mac_destroy_ifnet(struct ifnet *ifp)
1282 {
1283 
1284 	MAC_PERFORM(destroy_ifnet, ifp, &ifp->if_label);
1285 	mac_destroy_label(&ifp->if_label);
1286 	atomic_subtract_int(&nmacifnets, 1);
1287 }
1288 
1289 void
1290 mac_init_ipq(struct ipq *ipq)
1291 {
1292 
1293 	mac_init_label(&ipq->ipq_label);
1294 	MAC_PERFORM(init_ipq, ipq, &ipq->ipq_label);
1295 	atomic_add_int(&nmacipqs, 1);
1296 }
1297 
1298 void
1299 mac_destroy_ipq(struct ipq *ipq)
1300 {
1301 
1302 	MAC_PERFORM(destroy_ipq, ipq, &ipq->ipq_label);
1303 	mac_destroy_label(&ipq->ipq_label);
1304 	atomic_subtract_int(&nmacipqs, 1);
1305 }
1306 
1307 void
1308 mac_init_socket(struct socket *socket)
1309 {
1310 
1311 	mac_init_label(&socket->so_label);
1312 	mac_init_label(&socket->so_peerlabel);
1313 	MAC_PERFORM(init_socket, socket, &socket->so_label,
1314 	    &socket->so_peerlabel);
1315 	atomic_add_int(&nmacsockets, 1);
1316 }
1317 
1318 void
1319 mac_destroy_socket(struct socket *socket)
1320 {
1321 
1322 	MAC_PERFORM(destroy_socket, socket, &socket->so_label,
1323 	    &socket->so_peerlabel);
1324 	mac_destroy_label(&socket->so_label);
1325 	mac_destroy_label(&socket->so_peerlabel);
1326 	atomic_subtract_int(&nmacsockets, 1);
1327 }
1328 
1329 void
1330 mac_init_pipe(struct pipe *pipe)
1331 {
1332 	struct label *label;
1333 
1334 	label = malloc(sizeof(struct label), M_MACPIPELABEL, M_ZERO|M_WAITOK);
1335 	mac_init_label(label);
1336 	pipe->pipe_label = label;
1337 	pipe->pipe_peer->pipe_label = label;
1338 	MAC_PERFORM(init_pipe, pipe, pipe->pipe_label);
1339 	atomic_add_int(&nmacpipes, 1);
1340 }
1341 
1342 void
1343 mac_destroy_pipe(struct pipe *pipe)
1344 {
1345 
1346 	MAC_PERFORM(destroy_pipe, pipe, pipe->pipe_label);
1347 	mac_destroy_label(pipe->pipe_label);
1348 	free(pipe->pipe_label, M_MACPIPELABEL);
1349 	atomic_subtract_int(&nmacpipes, 1);
1350 }
1351 
1352 void
1353 mac_init_bpfdesc(struct bpf_d *bpf_d)
1354 {
1355 
1356 	mac_init_label(&bpf_d->bd_label);
1357 	MAC_PERFORM(init_bpfdesc, bpf_d, &bpf_d->bd_label);
1358 	atomic_add_int(&nmacbpfdescs, 1);
1359 }
1360 
1361 void
1362 mac_destroy_bpfdesc(struct bpf_d *bpf_d)
1363 {
1364 
1365 	MAC_PERFORM(destroy_bpfdesc, bpf_d, &bpf_d->bd_label);
1366 	mac_destroy_label(&bpf_d->bd_label);
1367 	atomic_subtract_int(&nmacbpfdescs, 1);
1368 }
1369 
1370 void
1371 mac_init_mount(struct mount *mp)
1372 {
1373 
1374 	mac_init_label(&mp->mnt_mntlabel);
1375 	mac_init_label(&mp->mnt_fslabel);
1376 	MAC_PERFORM(init_mount, mp, &mp->mnt_mntlabel, &mp->mnt_fslabel);
1377 	atomic_add_int(&nmacmounts, 1);
1378 }
1379 
1380 void
1381 mac_destroy_mount(struct mount *mp)
1382 {
1383 
1384 	MAC_PERFORM(destroy_mount, mp, &mp->mnt_mntlabel, &mp->mnt_fslabel);
1385 	mac_destroy_label(&mp->mnt_fslabel);
1386 	mac_destroy_label(&mp->mnt_mntlabel);
1387 	atomic_subtract_int(&nmacmounts, 1);
1388 }
1389 
1390 static void
1391 mac_init_temp(struct label *label)
1392 {
1393 
1394 	mac_init_label(label);
1395 	MAC_PERFORM(init_temp, label);
1396 	atomic_add_int(&nmactemp, 1);
1397 }
1398 
1399 static void
1400 mac_destroy_temp(struct label *label)
1401 {
1402 
1403 	MAC_PERFORM(destroy_temp, label);
1404 	mac_destroy_label(label);
1405 	atomic_subtract_int(&nmactemp, 1);
1406 }
1407 
1408 void
1409 mac_init_vnode(struct vnode *vp)
1410 {
1411 
1412 	mac_init_label(&vp->v_label);
1413 	MAC_PERFORM(init_vnode, vp, &vp->v_label);
1414 	atomic_add_int(&nmacvnodes, 1);
1415 }
1416 
1417 void
1418 mac_destroy_vnode(struct vnode *vp)
1419 {
1420 
1421 	MAC_PERFORM(destroy_vnode, vp, &vp->v_label);
1422 	mac_destroy_label(&vp->v_label);
1423 	atomic_subtract_int(&nmacvnodes, 1);
1424 }
1425 
1426 void
1427 mac_init_devfsdirent(struct devfs_dirent *de)
1428 {
1429 
1430 	mac_init_label(&de->de_label);
1431 	MAC_PERFORM(init_devfsdirent, de, &de->de_label);
1432 	atomic_add_int(&nmacdevfsdirents, 1);
1433 }
1434 
1435 void
1436 mac_destroy_devfsdirent(struct devfs_dirent *de)
1437 {
1438 
1439 	MAC_PERFORM(destroy_devfsdirent, de, &de->de_label);
1440 	mac_destroy_label(&de->de_label);
1441 	atomic_subtract_int(&nmacdevfsdirents, 1);
1442 }
1443 
1444 static int
1445 mac_externalize(struct label *label, struct mac *mac)
1446 {
1447 	int error;
1448 
1449 	mac_init_structmac(mac);
1450 	MAC_CHECK(externalize, label, mac);
1451 
1452 	return (error);
1453 }
1454 
1455 static int
1456 mac_internalize(struct label *label, struct mac *mac)
1457 {
1458 	int error;
1459 
1460 	mac_init_temp(label);
1461 	MAC_CHECK(internalize, label, mac);
1462 	if (error)
1463 		mac_destroy_temp(label);
1464 
1465 	return (error);
1466 }
1467 
1468 /*
1469  * Initialize MAC label for the first kernel process, from which other
1470  * kernel processes and threads are spawned.
1471  */
1472 void
1473 mac_create_proc0(struct ucred *cred)
1474 {
1475 
1476 	MAC_PERFORM(create_proc0, cred);
1477 }
1478 
1479 /*
1480  * Initialize MAC label for the first userland process, from which other
1481  * userland processes and threads are spawned.
1482  */
1483 void
1484 mac_create_proc1(struct ucred *cred)
1485 {
1486 
1487 	MAC_PERFORM(create_proc1, cred);
1488 }
1489 
1490 /*
1491  * When a new process is created, its label must be initialized.  Generally,
1492  * this involves inheritence from the parent process, modulo possible
1493  * deltas.  This function allows that processing to take place.
1494  */
1495 void
1496 mac_create_cred(struct ucred *parent_cred, struct ucred *child_cred)
1497 {
1498 
1499 	MAC_PERFORM(create_cred, parent_cred, child_cred);
1500 }
1501 
1502 int
1503 mac_check_vnode_access(struct ucred *cred, struct vnode *vp, int flags)
1504 {
1505 	int error;
1506 
1507 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_access");
1508 
1509 	if (!mac_enforce_fs)
1510 		return (0);
1511 
1512 	error = vn_refreshlabel(vp, cred);
1513 	if (error)
1514 		return (error);
1515 
1516 	MAC_CHECK(check_vnode_access, cred, vp, &vp->v_label, flags);
1517 	return (error);
1518 }
1519 
1520 int
1521 mac_check_vnode_chdir(struct ucred *cred, struct vnode *dvp)
1522 {
1523 	int error;
1524 
1525 	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chdir");
1526 
1527 	if (!mac_enforce_fs)
1528 		return (0);
1529 
1530 	error = vn_refreshlabel(dvp, cred);
1531 	if (error)
1532 		return (error);
1533 
1534 	MAC_CHECK(check_vnode_chdir, cred, dvp, &dvp->v_label);
1535 	return (error);
1536 }
1537 
1538 int
1539 mac_check_vnode_chroot(struct ucred *cred, struct vnode *dvp)
1540 {
1541 	int error;
1542 
1543 	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chroot");
1544 
1545 	if (!mac_enforce_fs)
1546 		return (0);
1547 
1548 	error = vn_refreshlabel(dvp, cred);
1549 	if (error)
1550 		return (error);
1551 
1552 	MAC_CHECK(check_vnode_chroot, cred, dvp, &dvp->v_label);
1553 	return (error);
1554 }
1555 
1556 int
1557 mac_check_vnode_create(struct ucred *cred, struct vnode *dvp,
1558     struct componentname *cnp, struct vattr *vap)
1559 {
1560 	int error;
1561 
1562 	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_create");
1563 
1564 	if (!mac_enforce_fs)
1565 		return (0);
1566 
1567 	error = vn_refreshlabel(dvp, cred);
1568 	if (error)
1569 		return (error);
1570 
1571 	MAC_CHECK(check_vnode_create, cred, dvp, &dvp->v_label, cnp, vap);
1572 	return (error);
1573 }
1574 
1575 int
1576 mac_check_vnode_delete(struct ucred *cred, struct vnode *dvp, struct vnode *vp,
1577     struct componentname *cnp)
1578 {
1579 	int error;
1580 
1581 	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_delete");
1582 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_delete");
1583 
1584 	if (!mac_enforce_fs)
1585 		return (0);
1586 
1587 	error = vn_refreshlabel(dvp, cred);
1588 	if (error)
1589 		return (error);
1590 	error = vn_refreshlabel(vp, cred);
1591 	if (error)
1592 		return (error);
1593 
1594 	MAC_CHECK(check_vnode_delete, cred, dvp, &dvp->v_label, vp,
1595 	    &vp->v_label, cnp);
1596 	return (error);
1597 }
1598 
1599 int
1600 mac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
1601     acl_type_t type)
1602 {
1603 	int error;
1604 
1605 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_deleteacl");
1606 
1607 	if (!mac_enforce_fs)
1608 		return (0);
1609 
1610 	error = vn_refreshlabel(vp, cred);
1611 	if (error)
1612 		return (error);
1613 
1614 	MAC_CHECK(check_vnode_deleteacl, cred, vp, &vp->v_label, type);
1615 	return (error);
1616 }
1617 
1618 int
1619 mac_check_vnode_exec(struct ucred *cred, struct vnode *vp)
1620 {
1621 	int error;
1622 
1623 	if (!mac_enforce_process && !mac_enforce_fs)
1624 		return (0);
1625 
1626 	error = vn_refreshlabel(vp, cred);
1627 	if (error)
1628 		return (error);
1629 	MAC_CHECK(check_vnode_exec, cred, vp, &vp->v_label);
1630 
1631 	return (error);
1632 }
1633 
1634 int
1635 mac_check_vnode_getacl(struct ucred *cred, struct vnode *vp, acl_type_t type)
1636 {
1637 	int error;
1638 
1639 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getacl");
1640 
1641 	if (!mac_enforce_fs)
1642 		return (0);
1643 
1644 	error = vn_refreshlabel(vp, cred);
1645 	if (error)
1646 		return (error);
1647 
1648 	MAC_CHECK(check_vnode_getacl, cred, vp, &vp->v_label, type);
1649 	return (error);
1650 }
1651 
1652 int
1653 mac_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
1654     int attrnamespace, const char *name, struct uio *uio)
1655 {
1656 	int error;
1657 
1658 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getextattr");
1659 
1660 	if (!mac_enforce_fs)
1661 		return (0);
1662 
1663 	error = vn_refreshlabel(vp, cred);
1664 	if (error)
1665 		return (error);
1666 
1667 	MAC_CHECK(check_vnode_getextattr, cred, vp, &vp->v_label,
1668 	    attrnamespace, name, uio);
1669 	return (error);
1670 }
1671 
1672 int
1673 mac_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
1674     struct componentname *cnp)
1675 {
1676 	int error;
1677 
1678 	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_lookup");
1679 
1680 	if (!mac_enforce_fs)
1681 		return (0);
1682 
1683 	error = vn_refreshlabel(dvp, cred);
1684 	if (error)
1685 		return (error);
1686 
1687 	MAC_CHECK(check_vnode_lookup, cred, dvp, &dvp->v_label, cnp);
1688 	return (error);
1689 }
1690 
1691 vm_prot_t
1692 mac_check_vnode_mmap_prot(struct ucred *cred, struct vnode *vp, int newmapping)
1693 {
1694 	vm_prot_t result = VM_PROT_ALL;
1695 
1696 	/*
1697 	 * This should be some sort of MAC_BITWISE, maybe :)
1698 	 */
1699 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap_perms");
1700 	MAC_BOOLEAN(check_vnode_mmap_perms, &, cred, vp, &vp->v_label,
1701 	    newmapping);
1702 	return (result);
1703 }
1704 
1705 int
1706 mac_check_vnode_op(struct ucred *cred, struct vnode *vp, int op)
1707 {
1708 	int error;
1709 
1710 	if (!mac_enforce_fs)
1711 		return (0);
1712 
1713 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_op");
1714 
1715 	error = vn_refreshlabel(vp, cred);
1716 	if (error)
1717 		return (error);
1718 
1719 	MAC_CHECK(check_vnode_op, cred, vp, &vp->v_label, op);
1720 
1721 	return (error);
1722 }
1723 
1724 int
1725 mac_check_vnode_open(struct ucred *cred, struct vnode *vp, mode_t acc_mode)
1726 {
1727 	int error;
1728 
1729 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_open");
1730 
1731 	if (!mac_enforce_fs)
1732 		return (0);
1733 
1734 	error = vn_refreshlabel(vp, cred);
1735 	if (error)
1736 		return (error);
1737 
1738 	MAC_CHECK(check_vnode_open, cred, vp, &vp->v_label, acc_mode);
1739 	return (error);
1740 }
1741 
1742 int
1743 mac_check_vnode_readdir(struct ucred *cred, struct vnode *dvp)
1744 {
1745 	int error;
1746 
1747 	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_readdir");
1748 
1749 	if (!mac_enforce_fs)
1750 		return (0);
1751 
1752 	error = vn_refreshlabel(dvp, cred);
1753 	if (error)
1754 		return (error);
1755 
1756 	MAC_CHECK(check_vnode_readdir, cred, dvp, &dvp->v_label);
1757 	return (error);
1758 }
1759 
1760 int
1761 mac_check_vnode_readlink(struct ucred *cred, struct vnode *vp)
1762 {
1763 	int error;
1764 
1765 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_readlink");
1766 
1767 	if (!mac_enforce_fs)
1768 		return (0);
1769 
1770 	error = vn_refreshlabel(vp, cred);
1771 	if (error)
1772 		return (error);
1773 
1774 	MAC_CHECK(check_vnode_readlink, cred, vp, &vp->v_label);
1775 	return (error);
1776 }
1777 
1778 static int
1779 mac_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
1780     struct label *newlabel)
1781 {
1782 	int error;
1783 
1784 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_relabel");
1785 
1786 	error = vn_refreshlabel(vp, cred);
1787 	if (error)
1788 		return (error);
1789 
1790 	MAC_CHECK(check_vnode_relabel, cred, vp, &vp->v_label, newlabel);
1791 
1792 	return (error);
1793 }
1794 
1795 int
1796 mac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
1797     struct vnode *vp, struct componentname *cnp)
1798 {
1799 	int error;
1800 
1801 	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_from");
1802 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_from");
1803 
1804 	if (!mac_enforce_fs)
1805 		return (0);
1806 
1807 	error = vn_refreshlabel(dvp, cred);
1808 	if (error)
1809 		return (error);
1810 	error = vn_refreshlabel(vp, cred);
1811 	if (error)
1812 		return (error);
1813 
1814 	MAC_CHECK(check_vnode_rename_from, cred, dvp, &dvp->v_label, vp,
1815 	    &vp->v_label, cnp);
1816 	return (error);
1817 }
1818 
1819 int
1820 mac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
1821     struct vnode *vp, int samedir, struct componentname *cnp)
1822 {
1823 	int error;
1824 
1825 	ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_to");
1826 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_to");
1827 
1828 	if (!mac_enforce_fs)
1829 		return (0);
1830 
1831 	error = vn_refreshlabel(dvp, cred);
1832 	if (error)
1833 		return (error);
1834 	if (vp != NULL) {
1835 		error = vn_refreshlabel(vp, cred);
1836 		if (error)
1837 			return (error);
1838 	}
1839 	MAC_CHECK(check_vnode_rename_to, cred, dvp, &dvp->v_label, vp,
1840 	    vp != NULL ? &vp->v_label : NULL, samedir, cnp);
1841 	return (error);
1842 }
1843 
1844 int
1845 mac_check_vnode_revoke(struct ucred *cred, struct vnode *vp)
1846 {
1847 	int error;
1848 
1849 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_revoke");
1850 
1851 	if (!mac_enforce_fs)
1852 		return (0);
1853 
1854 	error = vn_refreshlabel(vp, cred);
1855 	if (error)
1856 		return (error);
1857 
1858 	MAC_CHECK(check_vnode_revoke, cred, vp, &vp->v_label);
1859 	return (error);
1860 }
1861 
1862 int
1863 mac_check_vnode_setacl(struct ucred *cred, struct vnode *vp, acl_type_t type,
1864     struct acl *acl)
1865 {
1866 	int error;
1867 
1868 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setacl");
1869 
1870 	if (!mac_enforce_fs)
1871 		return (0);
1872 
1873 	error = vn_refreshlabel(vp, cred);
1874 	if (error)
1875 		return (error);
1876 
1877 	MAC_CHECK(check_vnode_setacl, cred, vp, &vp->v_label, type, acl);
1878 	return (error);
1879 }
1880 
1881 int
1882 mac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
1883     int attrnamespace, const char *name, struct uio *uio)
1884 {
1885 	int error;
1886 
1887 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setextattr");
1888 
1889 	if (!mac_enforce_fs)
1890 		return (0);
1891 
1892 	error = vn_refreshlabel(vp, cred);
1893 	if (error)
1894 		return (error);
1895 
1896 	MAC_CHECK(check_vnode_setextattr, cred, vp, &vp->v_label,
1897 	    attrnamespace, name, uio);
1898 	return (error);
1899 }
1900 
1901 int
1902 mac_check_vnode_setflags(struct ucred *cred, struct vnode *vp, u_long flags)
1903 {
1904 	int error;
1905 
1906 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setflags");
1907 
1908 	if (!mac_enforce_fs)
1909 		return (0);
1910 
1911 	error = vn_refreshlabel(vp, cred);
1912 	if (error)
1913 		return (error);
1914 
1915 	MAC_CHECK(check_vnode_setflags, cred, vp, &vp->v_label, flags);
1916 	return (error);
1917 }
1918 
1919 int
1920 mac_check_vnode_setmode(struct ucred *cred, struct vnode *vp, mode_t mode)
1921 {
1922 	int error;
1923 
1924 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setmode");
1925 
1926 	if (!mac_enforce_fs)
1927 		return (0);
1928 
1929 	error = vn_refreshlabel(vp, cred);
1930 	if (error)
1931 		return (error);
1932 
1933 	MAC_CHECK(check_vnode_setmode, cred, vp, &vp->v_label, mode);
1934 	return (error);
1935 }
1936 
1937 int
1938 mac_check_vnode_setowner(struct ucred *cred, struct vnode *vp, uid_t uid,
1939     gid_t gid)
1940 {
1941 	int error;
1942 
1943 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setowner");
1944 
1945 	if (!mac_enforce_fs)
1946 		return (0);
1947 
1948 	error = vn_refreshlabel(vp, cred);
1949 	if (error)
1950 		return (error);
1951 
1952 	MAC_CHECK(check_vnode_setowner, cred, vp, &vp->v_label, uid, gid);
1953 	return (error);
1954 }
1955 
1956 int
1957 mac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
1958     struct timespec atime, struct timespec mtime)
1959 {
1960 	int error;
1961 
1962 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setutimes");
1963 
1964 	if (!mac_enforce_fs)
1965 		return (0);
1966 
1967 	error = vn_refreshlabel(vp, cred);
1968 	if (error)
1969 		return (error);
1970 
1971 	MAC_CHECK(check_vnode_setutimes, cred, vp, &vp->v_label, atime,
1972 	    mtime);
1973 	return (error);
1974 }
1975 
1976 int
1977 mac_check_vnode_stat(struct ucred *cred, struct vnode *vp)
1978 {
1979 	int error;
1980 
1981 	ASSERT_VOP_LOCKED(vp, "mac_check_vnode_stat");
1982 
1983 	if (!mac_enforce_fs)
1984 		return (0);
1985 
1986 	error = vn_refreshlabel(vp, cred);
1987 	if (error)
1988 		return (error);
1989 
1990 	MAC_CHECK(check_vnode_stat, cred, vp, &vp->v_label);
1991 	return (error);
1992 }
1993 
1994 /*
1995  * When relabeling a process, call out to the policies for the maximum
1996  * permission allowed for each object type we know about in its
1997  * memory space, and revoke access (in the least surprising ways we
1998  * know) when necessary.  The process lock is not held here.
1999  */
2000 static void
2001 mac_cred_mmapped_drop_perms(struct thread *td, struct ucred *cred)
2002 {
2003 
2004 	/* XXX freeze all other threads */
2005 	mtx_lock(&Giant);
2006 	mac_cred_mmapped_drop_perms_recurse(td, cred,
2007 	    &td->td_proc->p_vmspace->vm_map);
2008 	mtx_unlock(&Giant);
2009 	/* XXX allow other threads to continue */
2010 }
2011 
2012 static __inline const char *
2013 prot2str(vm_prot_t prot)
2014 {
2015 
2016 	switch (prot & VM_PROT_ALL) {
2017 	case VM_PROT_READ:
2018 		return ("r--");
2019 	case VM_PROT_READ | VM_PROT_WRITE:
2020 		return ("rw-");
2021 	case VM_PROT_READ | VM_PROT_EXECUTE:
2022 		return ("r-x");
2023 	case VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE:
2024 		return ("rwx");
2025 	case VM_PROT_WRITE:
2026 		return ("-w-");
2027 	case VM_PROT_EXECUTE:
2028 		return ("--x");
2029 	case VM_PROT_WRITE | VM_PROT_EXECUTE:
2030 		return ("-wx");
2031 	default:
2032 		return ("---");
2033 	}
2034 }
2035 
2036 static void
2037 mac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred,
2038     struct vm_map *map)
2039 {
2040 	struct vm_map_entry *vme;
2041 	vm_prot_t result, revokeperms;
2042 	vm_object_t object;
2043 	vm_ooffset_t offset;
2044 	struct vnode *vp;
2045 
2046 	vm_map_lock_read(map);
2047 	for (vme = map->header.next; vme != &map->header; vme = vme->next) {
2048 		if (vme->eflags & MAP_ENTRY_IS_SUB_MAP) {
2049 			mac_cred_mmapped_drop_perms_recurse(td, cred,
2050 			    vme->object.sub_map);
2051 			continue;
2052 		}
2053 		/*
2054 		 * Skip over entries that obviously are not shared.
2055 		 */
2056 		if (vme->eflags & (MAP_ENTRY_COW | MAP_ENTRY_NOSYNC) ||
2057 		    !vme->max_protection)
2058 			continue;
2059 		/*
2060 		 * Drill down to the deepest backing object.
2061 		 */
2062 		offset = vme->offset;
2063 		object = vme->object.vm_object;
2064 		if (object == NULL)
2065 			continue;
2066 		while (object->backing_object != NULL) {
2067 			object = object->backing_object;
2068 			offset += object->backing_object_offset;
2069 		}
2070 		/*
2071 		 * At the moment, vm_maps and objects aren't considered
2072 		 * by the MAC system, so only things with backing by a
2073 		 * normal object (read: vnodes) are checked.
2074 		 */
2075 		if (object->type != OBJT_VNODE)
2076 			continue;
2077 		vp = (struct vnode *)object->handle;
2078 		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
2079 		result = mac_check_vnode_mmap_prot(cred, vp, 0);
2080 		VOP_UNLOCK(vp, 0, td);
2081 		/*
2082 		 * Find out what maximum protection we may be allowing
2083 		 * now but a policy needs to get removed.
2084 		 */
2085 		revokeperms = vme->max_protection & ~result;
2086 		if (!revokeperms)
2087 			continue;
2088 		printf("pid %d: revoking %s perms from %#lx:%d "
2089 		    "(max %s/cur %s)\n", td->td_proc->p_pid,
2090 		    prot2str(revokeperms), vme->start, vme->end - vme->start,
2091 		    prot2str(vme->max_protection), prot2str(vme->protection));
2092 		vm_map_lock_upgrade(map);
2093 		/*
2094 		 * This is the really simple case: if a map has more
2095 		 * max_protection than is allowed, but it's not being
2096 		 * actually used (that is, the current protection is
2097 		 * still allowed), we can just wipe it out and do
2098 		 * nothing more.
2099 		 */
2100 		if ((vme->protection & revokeperms) == 0) {
2101 			vme->max_protection -= revokeperms;
2102 		} else {
2103 			if (revokeperms & VM_PROT_WRITE) {
2104 				/*
2105 				 * In the more complicated case, flush out all
2106 				 * pending changes to the object then turn it
2107 				 * copy-on-write.
2108 				 */
2109 				vm_object_reference(object);
2110 				vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
2111 				vm_object_page_clean(object,
2112 				    OFF_TO_IDX(offset),
2113 				    OFF_TO_IDX(offset + vme->end - vme->start +
2114 					PAGE_MASK),
2115 				    OBJPC_SYNC);
2116 				VOP_UNLOCK(vp, 0, td);
2117 				vm_object_deallocate(object);
2118 				/*
2119 				 * Why bother if there's no read permissions
2120 				 * anymore?  For the rest, we need to leave
2121 				 * the write permissions on for COW, or
2122 				 * remove them entirely if configured to.
2123 				 */
2124 				if (!mac_mmap_revocation_via_cow) {
2125 					vme->max_protection &= ~VM_PROT_WRITE;
2126 					vme->protection &= ~VM_PROT_WRITE;
2127 				} if ((revokeperms & VM_PROT_READ) == 0)
2128 					vme->eflags |= MAP_ENTRY_COW |
2129 					    MAP_ENTRY_NEEDS_COPY;
2130 			}
2131 			if (revokeperms & VM_PROT_EXECUTE) {
2132 				vme->max_protection &= ~VM_PROT_EXECUTE;
2133 				vme->protection &= ~VM_PROT_EXECUTE;
2134 			}
2135 			if (revokeperms & VM_PROT_READ) {
2136 				vme->max_protection = 0;
2137 				vme->protection = 0;
2138 			}
2139 			pmap_protect(map->pmap, vme->start, vme->end,
2140 			    vme->protection & ~revokeperms);
2141 			vm_map_simplify_entry(map, vme);
2142 		}
2143 		vm_map_lock_downgrade(map);
2144 	}
2145 	vm_map_unlock_read(map);
2146 }
2147 
2148 /*
2149  * When the subject's label changes, it may require revocation of privilege
2150  * to mapped objects.  This can't be done on-the-fly later with a unified
2151  * buffer cache.
2152  */
2153 static void
2154 mac_relabel_cred(struct ucred *cred, struct label *newlabel)
2155 {
2156 
2157 	MAC_PERFORM(relabel_cred, cred, newlabel);
2158 	mac_cred_mmapped_drop_perms(curthread, cred);
2159 }
2160 
2161 void
2162 mac_relabel_vnode(struct ucred *cred, struct vnode *vp, struct label *newlabel)
2163 {
2164 
2165 	MAC_PERFORM(relabel_vnode, cred, vp, &vp->v_label, newlabel);
2166 }
2167 
2168 void
2169 mac_create_ifnet(struct ifnet *ifnet)
2170 {
2171 
2172 	MAC_PERFORM(create_ifnet, ifnet, &ifnet->if_label);
2173 }
2174 
2175 void
2176 mac_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d)
2177 {
2178 
2179 	MAC_PERFORM(create_bpfdesc, cred, bpf_d, &bpf_d->bd_label);
2180 }
2181 
2182 void
2183 mac_create_socket(struct ucred *cred, struct socket *socket)
2184 {
2185 
2186 	MAC_PERFORM(create_socket, cred, socket, &socket->so_label);
2187 }
2188 
2189 void
2190 mac_create_pipe(struct ucred *cred, struct pipe *pipe)
2191 {
2192 
2193 	MAC_PERFORM(create_pipe, cred, pipe, pipe->pipe_label);
2194 }
2195 
2196 void
2197 mac_create_socket_from_socket(struct socket *oldsocket,
2198     struct socket *newsocket)
2199 {
2200 
2201 	MAC_PERFORM(create_socket_from_socket, oldsocket, &oldsocket->so_label,
2202 	    newsocket, &newsocket->so_label);
2203 }
2204 
2205 static void
2206 mac_relabel_socket(struct ucred *cred, struct socket *socket,
2207     struct label *newlabel)
2208 {
2209 
2210 	MAC_PERFORM(relabel_socket, cred, socket, &socket->so_label, newlabel);
2211 }
2212 
2213 static void
2214 mac_relabel_pipe(struct ucred *cred, struct pipe *pipe, struct label *newlabel)
2215 {
2216 
2217 	MAC_PERFORM(relabel_pipe, cred, pipe, pipe->pipe_label, newlabel);
2218 }
2219 
2220 void
2221 mac_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct socket *socket)
2222 {
2223 
2224 	MAC_PERFORM(set_socket_peer_from_mbuf, mbuf, &mbuf->m_pkthdr.label,
2225 	    socket, &socket->so_peerlabel);
2226 }
2227 
2228 void
2229 mac_set_socket_peer_from_socket(struct socket *oldsocket,
2230     struct socket *newsocket)
2231 {
2232 
2233 	MAC_PERFORM(set_socket_peer_from_socket, oldsocket,
2234 	    &oldsocket->so_label, newsocket, &newsocket->so_peerlabel);
2235 }
2236 
2237 void
2238 mac_create_datagram_from_ipq(struct ipq *ipq, struct mbuf *datagram)
2239 {
2240 
2241 	MAC_PERFORM(create_datagram_from_ipq, ipq, &ipq->ipq_label,
2242 	    datagram, &datagram->m_pkthdr.label);
2243 }
2244 
2245 void
2246 mac_create_fragment(struct mbuf *datagram, struct mbuf *fragment)
2247 {
2248 
2249 	MAC_PERFORM(create_fragment, datagram, &datagram->m_pkthdr.label,
2250 	    fragment, &fragment->m_pkthdr.label);
2251 }
2252 
2253 void
2254 mac_create_ipq(struct mbuf *fragment, struct ipq *ipq)
2255 {
2256 
2257 	MAC_PERFORM(create_ipq, fragment, &fragment->m_pkthdr.label, ipq,
2258 	    &ipq->ipq_label);
2259 }
2260 
2261 void
2262 mac_create_mbuf_from_mbuf(struct mbuf *oldmbuf, struct mbuf *newmbuf)
2263 {
2264 
2265 	MAC_PERFORM(create_mbuf_from_mbuf, oldmbuf, &oldmbuf->m_pkthdr.label,
2266 	    newmbuf, &newmbuf->m_pkthdr.label);
2267 }
2268 
2269 void
2270 mac_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct mbuf *mbuf)
2271 {
2272 
2273 	MAC_PERFORM(create_mbuf_from_bpfdesc, bpf_d, &bpf_d->bd_label, mbuf,
2274 	    &mbuf->m_pkthdr.label);
2275 }
2276 
2277 void
2278 mac_create_mbuf_linklayer(struct ifnet *ifnet, struct mbuf *mbuf)
2279 {
2280 
2281 	MAC_PERFORM(create_mbuf_linklayer, ifnet, &ifnet->if_label, mbuf,
2282 	    &mbuf->m_pkthdr.label);
2283 }
2284 
2285 void
2286 mac_create_mbuf_from_ifnet(struct ifnet *ifnet, struct mbuf *mbuf)
2287 {
2288 
2289 	MAC_PERFORM(create_mbuf_from_ifnet, ifnet, &ifnet->if_label, mbuf,
2290 	    &mbuf->m_pkthdr.label);
2291 }
2292 
2293 void
2294 mac_create_mbuf_multicast_encap(struct mbuf *oldmbuf, struct ifnet *ifnet,
2295     struct mbuf *newmbuf)
2296 {
2297 
2298 	MAC_PERFORM(create_mbuf_multicast_encap, oldmbuf,
2299 	    &oldmbuf->m_pkthdr.label, ifnet, &ifnet->if_label, newmbuf,
2300 	    &newmbuf->m_pkthdr.label);
2301 }
2302 
2303 void
2304 mac_create_mbuf_netlayer(struct mbuf *oldmbuf, struct mbuf *newmbuf)
2305 {
2306 
2307 	MAC_PERFORM(create_mbuf_netlayer, oldmbuf, &oldmbuf->m_pkthdr.label,
2308 	    newmbuf, &newmbuf->m_pkthdr.label);
2309 }
2310 
2311 int
2312 mac_fragment_match(struct mbuf *fragment, struct ipq *ipq)
2313 {
2314 	int result;
2315 
2316 	result = 1;
2317 	MAC_BOOLEAN(fragment_match, &&, fragment, &fragment->m_pkthdr.label,
2318 	    ipq, &ipq->ipq_label);
2319 
2320 	return (result);
2321 }
2322 
2323 void
2324 mac_update_ipq(struct mbuf *fragment, struct ipq *ipq)
2325 {
2326 
2327 	MAC_PERFORM(update_ipq, fragment, &fragment->m_pkthdr.label, ipq,
2328 	    &ipq->ipq_label);
2329 }
2330 
2331 void
2332 mac_create_mbuf_from_socket(struct socket *socket, struct mbuf *mbuf)
2333 {
2334 
2335 	MAC_PERFORM(create_mbuf_from_socket, socket, &socket->so_label, mbuf,
2336 	    &mbuf->m_pkthdr.label);
2337 }
2338 
2339 void
2340 mac_create_mount(struct ucred *cred, struct mount *mp)
2341 {
2342 
2343 	MAC_PERFORM(create_mount, cred, mp, &mp->mnt_mntlabel,
2344 	    &mp->mnt_fslabel);
2345 }
2346 
2347 void
2348 mac_create_root_mount(struct ucred *cred, struct mount *mp)
2349 {
2350 
2351 	MAC_PERFORM(create_root_mount, cred, mp, &mp->mnt_mntlabel,
2352 	    &mp->mnt_fslabel);
2353 }
2354 
2355 int
2356 mac_check_bpfdesc_receive(struct bpf_d *bpf_d, struct ifnet *ifnet)
2357 {
2358 	int error;
2359 
2360 	if (!mac_enforce_network)
2361 		return (0);
2362 
2363 	MAC_CHECK(check_bpfdesc_receive, bpf_d, &bpf_d->bd_label, ifnet,
2364 	    &ifnet->if_label);
2365 
2366 	return (error);
2367 }
2368 
2369 static int
2370 mac_check_cred_relabel(struct ucred *cred, struct label *newlabel)
2371 {
2372 	int error;
2373 
2374 	MAC_CHECK(check_cred_relabel, cred, newlabel);
2375 
2376 	return (error);
2377 }
2378 
2379 int
2380 mac_check_cred_visible(struct ucred *u1, struct ucred *u2)
2381 {
2382 	int error;
2383 
2384 	if (!mac_enforce_process)
2385 		return (0);
2386 
2387 	MAC_CHECK(check_cred_visible, u1, u2);
2388 
2389 	return (error);
2390 }
2391 
2392 int
2393 mac_check_ifnet_transmit(struct ifnet *ifnet, struct mbuf *mbuf)
2394 {
2395 	int error;
2396 
2397 	if (!mac_enforce_network)
2398 		return (0);
2399 
2400 	KASSERT(mbuf->m_flags & M_PKTHDR, ("packet has no pkthdr"));
2401 	if (!(mbuf->m_pkthdr.label.l_flags & MAC_FLAG_INITIALIZED))
2402 		printf("%s%d: not initialized\n", ifnet->if_name,
2403 		    ifnet->if_unit);
2404 
2405 	MAC_CHECK(check_ifnet_transmit, ifnet, &ifnet->if_label, mbuf,
2406 	    &mbuf->m_pkthdr.label);
2407 
2408 	return (error);
2409 }
2410 
2411 int
2412 mac_check_mount_stat(struct ucred *cred, struct mount *mount)
2413 {
2414 	int error;
2415 
2416 	if (!mac_enforce_fs)
2417 		return (0);
2418 
2419 	MAC_CHECK(check_mount_stat, cred, mount, &mount->mnt_mntlabel);
2420 
2421 	return (error);
2422 }
2423 
2424 int
2425 mac_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe, unsigned long cmd,
2426     void *data)
2427 {
2428 	int error;
2429 
2430 	MAC_CHECK(check_pipe_ioctl, cred, pipe, pipe->pipe_label, cmd, data);
2431 
2432 	return (error);
2433 }
2434 
2435 int
2436 mac_check_pipe_op(struct ucred *cred, struct pipe *pipe, int op)
2437 {
2438 	int error;
2439 
2440 	MAC_CHECK(check_pipe_op, cred, pipe, pipe->pipe_label, op);
2441 
2442 	return (error);
2443 }
2444 
2445 static int
2446 mac_check_pipe_relabel(struct ucred *cred, struct pipe *pipe,
2447     struct label *newlabel)
2448 {
2449 	int error;
2450 
2451 	MAC_CHECK(check_pipe_relabel, cred, pipe, pipe->pipe_label, newlabel);
2452 
2453 	return (error);
2454 }
2455 
2456 int
2457 mac_check_proc_debug(struct ucred *cred, struct proc *proc)
2458 {
2459 	int error;
2460 
2461 	if (!mac_enforce_process)
2462 		return (0);
2463 
2464 	MAC_CHECK(check_proc_debug, cred, proc);
2465 
2466 	return (error);
2467 }
2468 
2469 int
2470 mac_check_proc_sched(struct ucred *cred, struct proc *proc)
2471 {
2472 	int error;
2473 
2474 	if (!mac_enforce_process)
2475 		return (0);
2476 
2477 	MAC_CHECK(check_proc_sched, cred, proc);
2478 
2479 	return (error);
2480 }
2481 
2482 int
2483 mac_check_proc_signal(struct ucred *cred, struct proc *proc, int signum)
2484 {
2485 	int error;
2486 
2487 	if (!mac_enforce_process)
2488 		return (0);
2489 
2490 	MAC_CHECK(check_proc_signal, cred, proc, signum);
2491 
2492 	return (error);
2493 }
2494 
2495 int
2496 mac_check_socket_bind(struct ucred *ucred, struct socket *socket,
2497     struct sockaddr *sockaddr)
2498 {
2499 	int error;
2500 
2501 	if (!mac_enforce_socket)
2502 		return (0);
2503 
2504 	MAC_CHECK(check_socket_bind, ucred, socket, &socket->so_label,
2505 	    sockaddr);
2506 
2507 	return (error);
2508 }
2509 
2510 int
2511 mac_check_socket_connect(struct ucred *cred, struct socket *socket,
2512     struct sockaddr *sockaddr)
2513 {
2514 	int error;
2515 
2516 	if (!mac_enforce_socket)
2517 		return (0);
2518 
2519 	MAC_CHECK(check_socket_connect, cred, socket, &socket->so_label,
2520 	    sockaddr);
2521 
2522 	return (error);
2523 }
2524 
2525 int
2526 mac_check_socket_listen(struct ucred *cred, struct socket *socket)
2527 {
2528 	int error;
2529 
2530 	if (!mac_enforce_socket)
2531 		return (0);
2532 
2533 	MAC_CHECK(check_socket_listen, cred, socket, &socket->so_label);
2534 	return (error);
2535 }
2536 
2537 int
2538 mac_check_socket_receive(struct socket *socket, struct mbuf *mbuf)
2539 {
2540 	int error;
2541 
2542 	if (!mac_enforce_socket)
2543 		return (0);
2544 
2545 	MAC_CHECK(check_socket_receive, socket, &socket->so_label, mbuf,
2546 	    &mbuf->m_pkthdr.label);
2547 
2548 	return (error);
2549 }
2550 
2551 static int
2552 mac_check_socket_relabel(struct ucred *cred, struct socket *socket,
2553     struct label *newlabel)
2554 {
2555 	int error;
2556 
2557 	MAC_CHECK(check_socket_relabel, cred, socket, &socket->so_label,
2558 	    newlabel);
2559 
2560 	return (error);
2561 }
2562 
2563 int
2564 mac_check_socket_visible(struct ucred *cred, struct socket *socket)
2565 {
2566 	int error;
2567 
2568 	if (!mac_enforce_socket)
2569 		return (0);
2570 
2571 	MAC_CHECK(check_socket_visible, cred, socket, &socket->so_label);
2572 
2573 	return (error);
2574 }
2575 
2576 int
2577 mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr,
2578     struct ifnet *ifnet)
2579 {
2580 	struct mac label;
2581 	int error;
2582 
2583 	error = mac_externalize(&ifnet->if_label, &label);
2584 	if (error)
2585 		return (error);
2586 
2587 	return (copyout(&label, ifr->ifr_ifru.ifru_data, sizeof(label)));
2588 }
2589 
2590 int
2591 mac_ioctl_ifnet_set(struct ucred *cred, struct ifreq *ifr,
2592     struct ifnet *ifnet)
2593 {
2594 	struct mac newlabel;
2595 	struct label intlabel;
2596 	int error;
2597 
2598 	error = copyin(ifr->ifr_ifru.ifru_data, &newlabel, sizeof(newlabel));
2599 	if (error)
2600 		return (error);
2601 
2602 	error = mac_internalize(&intlabel, &newlabel);
2603 	if (error)
2604 		return (error);
2605 
2606 	/*
2607 	 * XXX: Note that this is a redundant privilege check, since
2608 	 * policies impose this check themselves if required by the
2609 	 * policy.  Eventually, this should go away.
2610 	 */
2611 	error = suser_cred(cred, 0);
2612 	if (error)
2613 		goto out;
2614 
2615 	MAC_CHECK(check_ifnet_relabel, cred, ifnet, &ifnet->if_label,
2616 	    &intlabel);
2617 	if (error)
2618 		goto out;
2619 
2620 	MAC_PERFORM(relabel_ifnet, cred, ifnet, &ifnet->if_label, &intlabel);
2621 
2622 out:
2623 	mac_destroy_temp(&intlabel);
2624 	return (error);
2625 }
2626 
2627 void
2628 mac_create_devfs_vnode(struct devfs_dirent *de, struct vnode *vp)
2629 {
2630 
2631 	MAC_PERFORM(create_devfs_vnode, de, &de->de_label, vp, &vp->v_label);
2632 }
2633 
2634 void
2635 mac_create_devfs_device(dev_t dev, struct devfs_dirent *de)
2636 {
2637 
2638 	MAC_PERFORM(create_devfs_device, dev, de, &de->de_label);
2639 }
2640 
2641 static int
2642 mac_stdcreatevnode_ea(struct vnode *vp)
2643 {
2644 	int error;
2645 
2646 	MAC_CHECK(stdcreatevnode_ea, vp, &vp->v_label);
2647 
2648 	return (error);
2649 }
2650 
2651 void
2652 mac_create_devfs_directory(char *dirname, int dirnamelen,
2653     struct devfs_dirent *de)
2654 {
2655 
2656 	MAC_PERFORM(create_devfs_directory, dirname, dirnamelen, de,
2657 	    &de->de_label);
2658 }
2659 
2660 /*
2661  * When a new vnode is created, this call will initialize its label.
2662  */
2663 void
2664 mac_create_vnode(struct ucred *cred, struct vnode *parent,
2665     struct vnode *child)
2666 {
2667 	int error;
2668 
2669 	ASSERT_VOP_LOCKED(parent, "mac_create_vnode");
2670 	ASSERT_VOP_LOCKED(child, "mac_create_vnode");
2671 
2672 	error = vn_refreshlabel(parent, cred);
2673 	if (error) {
2674 		printf("mac_create_vnode: vn_refreshlabel returned %d\n",
2675 		    error);
2676 		printf("mac_create_vnode: using old vnode label\n");
2677 	}
2678 
2679 	MAC_PERFORM(create_vnode, cred, parent, &parent->v_label, child,
2680 	    &child->v_label);
2681 }
2682 
2683 int
2684 mac_setsockopt_label_set(struct ucred *cred, struct socket *so,
2685     struct mac *extmac)
2686 {
2687 	struct label intlabel;
2688 	int error;
2689 
2690 	error = mac_internalize(&intlabel, extmac);
2691 	if (error)
2692 		return (error);
2693 
2694 	mac_check_socket_relabel(cred, so, &intlabel);
2695 	if (error) {
2696 		mac_destroy_temp(&intlabel);
2697 		return (error);
2698 	}
2699 
2700 	mac_relabel_socket(cred, so, &intlabel);
2701 
2702 	mac_destroy_temp(&intlabel);
2703 	return (0);
2704 }
2705 
2706 int
2707 mac_pipe_label_set(struct ucred *cred, struct pipe *pipe, struct label *label)
2708 {
2709 	int error;
2710 
2711 	error = mac_check_pipe_relabel(cred, pipe, label);
2712 	if (error)
2713 		return (error);
2714 
2715 	mac_relabel_pipe(cred, pipe, label);
2716 
2717 	return (0);
2718 }
2719 
2720 int
2721 mac_getsockopt_label_get(struct ucred *cred, struct socket *so,
2722     struct mac *extmac)
2723 {
2724 
2725 	return (mac_externalize(&so->so_label, extmac));
2726 }
2727 
2728 int
2729 mac_getsockopt_peerlabel_get(struct ucred *cred, struct socket *so,
2730     struct mac *extmac)
2731 {
2732 
2733 	return (mac_externalize(&so->so_peerlabel, extmac));
2734 }
2735 
2736 /*
2737  * Implementation of VOP_SETLABEL() that relies on extended attributes
2738  * to store label data.  Can be referenced by filesystems supporting
2739  * extended attributes.
2740  */
2741 int
2742 vop_stdsetlabel_ea(struct vop_setlabel_args *ap)
2743 {
2744 	struct vnode *vp = ap->a_vp;
2745 	struct label *intlabel = ap->a_label;
2746 	struct mac extmac;
2747 	int error;
2748 
2749 	ASSERT_VOP_LOCKED(vp, "vop_stdsetlabel_ea");
2750 
2751 	/*
2752 	 * XXX: Eventually call out to EA check/set calls here.
2753 	 * Be particularly careful to avoid race conditions,
2754 	 * consistency problems, and stability problems when
2755 	 * dealing with multiple EAs.  In particular, we require
2756 	 * the ability to write multiple EAs on the same file in
2757 	 * a single transaction, which the current EA interface
2758 	 * does not provide.
2759 	 */
2760 
2761 	error = mac_externalize(intlabel, &extmac);
2762 	if (error)
2763 		return (error);
2764 
2765 	error = vn_extattr_set(vp, IO_NODELOCKED,
2766 	    FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME,
2767 	    sizeof(extmac), (char *)&extmac, curthread);
2768 	if (error)
2769 		return (error);
2770 
2771 	mac_relabel_vnode(ap->a_cred, vp, intlabel);
2772 
2773 	vp->v_flag |= VCACHEDLABEL;
2774 
2775 	return (0);
2776 }
2777 
2778 static int
2779 vn_setlabel(struct vnode *vp, struct label *intlabel, struct ucred *cred)
2780 {
2781 	int error;
2782 
2783 	if (vp->v_mount == NULL) {
2784 		/* printf("vn_setlabel: null v_mount\n"); */
2785 		if (vp->v_tag != VT_NON)
2786 			printf("vn_setlabel: null v_mount with non-VT_NON\n");
2787 		return (EBADF);
2788 	}
2789 
2790 	if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0)
2791 		return (EOPNOTSUPP);
2792 
2793 	/*
2794 	 * Multi-phase commit.  First check the policies to confirm the
2795 	 * change is OK.  Then commit via the filesystem.  Finally,
2796 	 * update the actual vnode label.  Question: maybe the filesystem
2797 	 * should update the vnode at the end as part of VOP_SETLABEL()?
2798 	 */
2799 	error = mac_check_vnode_relabel(cred, vp, intlabel);
2800 	if (error)
2801 		return (error);
2802 
2803 	/*
2804 	 * VADMIN provides the opportunity for the filesystem to make
2805 	 * decisions about who is and is not able to modify labels
2806 	 * and protections on files.  This might not be right.  We can't
2807 	 * assume VOP_SETLABEL() will do it, because we might implement
2808 	 * that as part of vop_stdsetlabel_ea().
2809 	 */
2810 	error = VOP_ACCESS(vp, VADMIN, cred, curthread);
2811 	if (error)
2812 		return (error);
2813 
2814 	error = VOP_SETLABEL(vp, intlabel, cred, curthread);
2815 	if (error)
2816 		return (error);
2817 
2818 	return (0);
2819 }
2820 
2821 /*
2822  * MPSAFE
2823  */
2824 int
2825 __mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap)
2826 {
2827 	struct mac extmac;
2828 	int error;
2829 
2830 	error = mac_externalize(&td->td_ucred->cr_label, &extmac);
2831 	if (error == 0)
2832 		error = copyout(&extmac, SCARG(uap, mac_p), sizeof(extmac));
2833 
2834 	return (error);
2835 }
2836 
2837 /*
2838  * MPSAFE
2839  *
2840  * XXX: Needs to be re-written for proc locking.
2841  */
2842 int
2843 __mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap)
2844 {
2845 	struct ucred *newcred, *oldcred;
2846 	struct proc *p;
2847 	struct mac extmac;
2848 	struct label intlabel;
2849 	int error;
2850 
2851 	error = copyin(SCARG(uap, mac_p), &extmac, sizeof(extmac));
2852 	if (error)
2853 		return (error);
2854 
2855 	error = mac_internalize(&intlabel, &extmac);
2856 	if (error)
2857 		return (error);
2858 
2859 	newcred = crget();
2860 
2861 	p = td->td_proc;
2862 	PROC_LOCK(p);
2863 	oldcred = p->p_ucred;
2864 
2865 	error = mac_check_cred_relabel(oldcred, &intlabel);
2866 	if (error) {
2867 		PROC_UNLOCK(p);
2868 		mac_destroy_temp(&intlabel);
2869 		crfree(newcred);
2870 		return (error);
2871 	}
2872 
2873 	setsugid(p);
2874 	crcopy(newcred, oldcred);
2875 	PROC_UNLOCK(p);
2876 	mac_relabel_cred(newcred, &intlabel);
2877 
2878 	PROC_LOCK(p);
2879 	p->p_ucred = newcred;
2880 	PROC_UNLOCK(p);
2881 	crfree(oldcred);
2882 	mac_destroy_temp(&intlabel);
2883 	return (0);
2884 }
2885 
2886 /*
2887  * MPSAFE
2888  */
2889 int
2890 __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
2891 {
2892 	struct file *fp;
2893 	struct mac extmac;
2894 	struct vnode *vp;
2895 	struct pipe *pipe;
2896 	int error;
2897 
2898 	mtx_lock(&Giant);
2899 
2900 	error = fget(td, SCARG(uap, fd), &fp);
2901 	if (error)
2902 		goto out;
2903 
2904 	switch (fp->f_type) {
2905 	case DTYPE_FIFO:
2906 	case DTYPE_VNODE:
2907 		vp = (struct vnode *)fp->f_data;
2908 
2909 		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
2910 		error = vn_refreshlabel(vp, td->td_ucred);
2911 		if (error == 0)
2912 			error = mac_externalize(&vp->v_label, &extmac);
2913 		VOP_UNLOCK(vp, 0, td);
2914 		break;
2915 	case DTYPE_PIPE:
2916 		pipe = (struct pipe *)fp->f_data;
2917 		error = mac_externalize(pipe->pipe_label, &extmac);
2918 		break;
2919 	default:
2920 		error = EINVAL;
2921 	}
2922 
2923 	if (error == 0)
2924 		error = copyout(&extmac, SCARG(uap, mac_p), sizeof(extmac));
2925 
2926 	fdrop(fp, td);
2927 
2928 out:
2929 	mtx_unlock(&Giant);
2930 	return (error);
2931 }
2932 
2933 /*
2934  * MPSAFE
2935  */
2936 int
2937 __mac_get_file(struct thread *td, struct __mac_get_file_args *uap)
2938 {
2939 	struct nameidata nd;
2940 	struct mac extmac;
2941 	int error;
2942 
2943 	mtx_lock(&Giant);
2944 	NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE,
2945 	    SCARG(uap, path_p), td);
2946 	error = namei(&nd);
2947 	if (error)
2948 		goto out;
2949 
2950 	error = vn_refreshlabel(nd.ni_vp, td->td_ucred);
2951 	if (error == 0)
2952 		error = mac_externalize(&nd.ni_vp->v_label, &extmac);
2953 	NDFREE(&nd, 0);
2954 	if (error)
2955 		goto out;
2956 
2957 	error = copyout(&extmac, SCARG(uap, mac_p), sizeof(extmac));
2958 
2959 out:
2960 	mtx_unlock(&Giant);
2961 	return (error);
2962 }
2963 
2964 /*
2965  * MPSAFE
2966  */
2967 int
2968 __mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap)
2969 {
2970 	struct file *fp;
2971 	struct mac extmac;
2972 	struct label intlabel;
2973 	struct mount *mp;
2974 	struct vnode *vp;
2975 	struct pipe *pipe;
2976 	int error;
2977 
2978 	mtx_lock(&Giant);
2979 	error = fget(td, SCARG(uap, fd), &fp);
2980 	if (error)
2981 		goto out1;
2982 
2983 	error = copyin(SCARG(uap, mac_p), &extmac, sizeof(extmac));
2984 	if (error)
2985 		goto out2;
2986 
2987 	error = mac_internalize(&intlabel, &extmac);
2988 	if (error)
2989 		goto out2;
2990 
2991 	switch (fp->f_type) {
2992 	case DTYPE_FIFO:
2993 	case DTYPE_VNODE:
2994 		vp = (struct vnode *)fp->f_data;
2995 		error = vn_start_write(vp, &mp, V_WAIT | PCATCH);
2996 		if (error != 0)
2997 			break;
2998 
2999 		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
3000 		error = vn_setlabel(vp, &intlabel, td->td_ucred);
3001 		VOP_UNLOCK(vp, 0, td);
3002 		vn_finished_write(mp);
3003 		mac_destroy_temp(&intlabel);
3004 		break;
3005 	case DTYPE_PIPE:
3006 		pipe = (struct pipe *)fp->f_data;
3007 		error = mac_pipe_label_set(td->td_ucred, pipe, &intlabel);
3008 		break;
3009 	default:
3010 		error = EINVAL;
3011 	}
3012 
3013 out2:
3014 	fdrop(fp, td);
3015 out1:
3016 	mtx_unlock(&Giant);
3017 	return (error);
3018 }
3019 
3020 /*
3021  * MPSAFE
3022  */
3023 int
3024 __mac_set_file(struct thread *td, struct __mac_set_file_args *uap)
3025 {
3026 	struct nameidata nd;
3027 	struct mac extmac;
3028 	struct label intlabel;
3029 	struct mount *mp;
3030 	int error;
3031 
3032 	mtx_lock(&Giant);
3033 
3034 	error = copyin(SCARG(uap, mac_p), &extmac, sizeof(extmac));
3035 	if (error)
3036 		goto out;
3037 
3038 	error = mac_internalize(&intlabel, &extmac);
3039 	if (error)
3040 		goto out;
3041 
3042 	NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE,
3043 	    SCARG(uap, path_p), td);
3044 	error = namei(&nd);
3045 	if (error)
3046 		goto out2;
3047 	error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH);
3048 	if (error)
3049 		goto out2;
3050 
3051 	error = vn_setlabel(nd.ni_vp, &intlabel, td->td_ucred);
3052 
3053 	vn_finished_write(mp);
3054 out2:
3055 	mac_destroy_temp(&intlabel);
3056 	NDFREE(&nd, 0);
3057 out:
3058 	mtx_unlock(&Giant);
3059 	return (error);
3060 }
3061 
3062 SYSINIT(mac, SI_SUB_MAC, SI_ORDER_FIRST, mac_init, NULL);
3063 SYSINIT(mac_late, SI_SUB_MAC_LATE, SI_ORDER_FIRST, mac_late_init, NULL);
3064 
3065 #else /* !MAC */
3066 
3067 int
3068 __mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap)
3069 {
3070 
3071 	return (ENOSYS);
3072 }
3073 
3074 int
3075 __mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap)
3076 {
3077 
3078 	return (ENOSYS);
3079 }
3080 
3081 int
3082 __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
3083 {
3084 
3085 	return (ENOSYS);
3086 }
3087 
3088 int
3089 __mac_get_file(struct thread *td, struct __mac_get_file_args *uap)
3090 {
3091 
3092 	return (ENOSYS);
3093 }
3094 
3095 int
3096 __mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap)
3097 {
3098 
3099 	return (ENOSYS);
3100 }
3101 
3102 int
3103 __mac_set_file(struct thread *td, struct __mac_set_file_args *uap)
3104 {
3105 
3106 	return (ENOSYS);
3107 }
3108 
3109 #endif /* !MAC */
3110