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