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