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