]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/security/mac/mac_vfs.c
This commit was generated by cvs2svn to compensate for changes in r102528,
[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  * When relabeling a process, call out to the policies for the maximum
2125  * permission allowed for each object type we know about in its
2126  * memory space, and revoke access (in the least surprising ways we
2127  * know) when necessary.  The process lock is not held here.
2128  */
2129 static void
2130 mac_cred_mmapped_drop_perms(struct thread *td, struct ucred *cred)
2131 {
2132
2133         /* XXX freeze all other threads */
2134         mtx_lock(&Giant);
2135         mac_cred_mmapped_drop_perms_recurse(td, cred,
2136             &td->td_proc->p_vmspace->vm_map);
2137         mtx_unlock(&Giant);
2138         /* XXX allow other threads to continue */
2139 }
2140
2141 static __inline const char *
2142 prot2str(vm_prot_t prot)
2143 {
2144
2145         switch (prot & VM_PROT_ALL) {
2146         case VM_PROT_READ:
2147                 return ("r--");
2148         case VM_PROT_READ | VM_PROT_WRITE:
2149                 return ("rw-");
2150         case VM_PROT_READ | VM_PROT_EXECUTE:
2151                 return ("r-x");
2152         case VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE:
2153                 return ("rwx");
2154         case VM_PROT_WRITE:
2155                 return ("-w-");
2156         case VM_PROT_EXECUTE:
2157                 return ("--x");
2158         case VM_PROT_WRITE | VM_PROT_EXECUTE:
2159                 return ("-wx");
2160         default:
2161                 return ("---");
2162         }
2163 }
2164
2165 static void
2166 mac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred,
2167     struct vm_map *map)
2168 {
2169         struct vm_map_entry *vme;
2170         vm_prot_t result, revokeperms;
2171         vm_object_t object;
2172         vm_ooffset_t offset;
2173         struct vnode *vp;
2174
2175         vm_map_lock_read(map);
2176         for (vme = map->header.next; vme != &map->header; vme = vme->next) {
2177                 if (vme->eflags & MAP_ENTRY_IS_SUB_MAP) {
2178                         mac_cred_mmapped_drop_perms_recurse(td, cred,
2179                             vme->object.sub_map);
2180                         continue;
2181                 }
2182                 /*
2183                  * Skip over entries that obviously are not shared.
2184                  */
2185                 if (vme->eflags & (MAP_ENTRY_COW | MAP_ENTRY_NOSYNC) ||
2186                     !vme->max_protection)
2187                         continue;
2188                 /*
2189                  * Drill down to the deepest backing object.
2190                  */
2191                 offset = vme->offset;
2192                 object = vme->object.vm_object;
2193                 if (object == NULL)
2194                         continue;
2195                 while (object->backing_object != NULL) {
2196                         object = object->backing_object;
2197                         offset += object->backing_object_offset;
2198                 }
2199                 /*
2200                  * At the moment, vm_maps and objects aren't considered
2201                  * by the MAC system, so only things with backing by a
2202                  * normal object (read: vnodes) are checked.
2203                  */
2204                 if (object->type != OBJT_VNODE)
2205                         continue;
2206                 vp = (struct vnode *)object->handle;
2207                 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
2208                 result = mac_check_vnode_mmap_prot(cred, vp, 0);
2209                 VOP_UNLOCK(vp, 0, td);
2210                 /*
2211                  * Find out what maximum protection we may be allowing
2212                  * now but a policy needs to get removed.
2213                  */
2214                 revokeperms = vme->max_protection & ~result;
2215                 if (!revokeperms)
2216                         continue;
2217                 printf("pid %d: revoking %s perms from %#lx:%d "
2218                     "(max %s/cur %s)\n", td->td_proc->p_pid,
2219                     prot2str(revokeperms), vme->start, vme->end - vme->start,
2220                     prot2str(vme->max_protection), prot2str(vme->protection));
2221                 vm_map_lock_upgrade(map);
2222                 /*
2223                  * This is the really simple case: if a map has more
2224                  * max_protection than is allowed, but it's not being
2225                  * actually used (that is, the current protection is
2226                  * still allowed), we can just wipe it out and do
2227                  * nothing more.
2228                  */
2229                 if ((vme->protection & revokeperms) == 0) {
2230                         vme->max_protection -= revokeperms;
2231                 } else {
2232                         if (revokeperms & VM_PROT_WRITE) {
2233                                 /*
2234                                  * In the more complicated case, flush out all
2235                                  * pending changes to the object then turn it
2236                                  * copy-on-write.
2237                                  */
2238                                 vm_object_reference(object);
2239                                 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
2240                                 vm_object_page_clean(object,
2241                                     OFF_TO_IDX(offset),
2242                                     OFF_TO_IDX(offset + vme->end - vme->start +
2243                                         PAGE_MASK),
2244                                     OBJPC_SYNC);
2245                                 VOP_UNLOCK(vp, 0, td);
2246                                 vm_object_deallocate(object);
2247                                 /*
2248                                  * Why bother if there's no read permissions
2249                                  * anymore?  For the rest, we need to leave
2250                                  * the write permissions on for COW, or
2251                                  * remove them entirely if configured to.
2252                                  */
2253                                 if (!mac_mmap_revocation_via_cow) {
2254                                         vme->max_protection &= ~VM_PROT_WRITE;
2255                                         vme->protection &= ~VM_PROT_WRITE;
2256                                 } if ((revokeperms & VM_PROT_READ) == 0)
2257                                         vme->eflags |= MAP_ENTRY_COW |
2258                                             MAP_ENTRY_NEEDS_COPY;
2259                         }
2260                         if (revokeperms & VM_PROT_EXECUTE) {
2261                                 vme->max_protection &= ~VM_PROT_EXECUTE;
2262                                 vme->protection &= ~VM_PROT_EXECUTE;
2263                         }
2264                         if (revokeperms & VM_PROT_READ) {
2265                                 vme->max_protection = 0;
2266                                 vme->protection = 0;
2267                         }
2268                         pmap_protect(map->pmap, vme->start, vme->end,
2269                             vme->protection & ~revokeperms);
2270                         vm_map_simplify_entry(map, vme);
2271                 }
2272                 vm_map_lock_downgrade(map);
2273         }
2274         vm_map_unlock_read(map);
2275 }
2276
2277 /*
2278  * When the subject's label changes, it may require revocation of privilege
2279  * to mapped objects.  This can't be done on-the-fly later with a unified
2280  * buffer cache.
2281  */
2282 static void
2283 mac_relabel_cred(struct ucred *cred, struct label *newlabel)
2284 {
2285
2286         MAC_PERFORM(relabel_cred, cred, newlabel);
2287 }
2288
2289 void
2290 mac_relabel_vnode(struct ucred *cred, struct vnode *vp, struct label *newlabel)
2291 {
2292
2293         MAC_PERFORM(relabel_vnode, cred, vp, &vp->v_label, newlabel);
2294 }
2295
2296 void
2297 mac_create_ifnet(struct ifnet *ifnet)
2298 {
2299
2300         MAC_PERFORM(create_ifnet, ifnet, &ifnet->if_label);
2301 }
2302
2303 void
2304 mac_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d)
2305 {
2306
2307         MAC_PERFORM(create_bpfdesc, cred, bpf_d, &bpf_d->bd_label);
2308 }
2309
2310 void
2311 mac_create_socket(struct ucred *cred, struct socket *socket)
2312 {
2313
2314         MAC_PERFORM(create_socket, cred, socket, &socket->so_label);
2315 }
2316
2317 void
2318 mac_create_pipe(struct ucred *cred, struct pipe *pipe)
2319 {
2320
2321         MAC_PERFORM(create_pipe, cred, pipe, pipe->pipe_label);
2322 }
2323
2324 void
2325 mac_create_socket_from_socket(struct socket *oldsocket,
2326     struct socket *newsocket)
2327 {
2328
2329         MAC_PERFORM(create_socket_from_socket, oldsocket, &oldsocket->so_label,
2330             newsocket, &newsocket->so_label);
2331 }
2332
2333 static void
2334 mac_relabel_socket(struct ucred *cred, struct socket *socket,
2335     struct label *newlabel)
2336 {
2337
2338         MAC_PERFORM(relabel_socket, cred, socket, &socket->so_label, newlabel);
2339 }
2340
2341 static void
2342 mac_relabel_pipe(struct ucred *cred, struct pipe *pipe, struct label *newlabel)
2343 {
2344
2345         MAC_PERFORM(relabel_pipe, cred, pipe, pipe->pipe_label, newlabel);
2346 }
2347
2348 void
2349 mac_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct socket *socket)
2350 {
2351
2352         MAC_PERFORM(set_socket_peer_from_mbuf, mbuf, &mbuf->m_pkthdr.label,
2353             socket, &socket->so_peerlabel);
2354 }
2355
2356 void
2357 mac_set_socket_peer_from_socket(struct socket *oldsocket,
2358     struct socket *newsocket)
2359 {
2360
2361         MAC_PERFORM(set_socket_peer_from_socket, oldsocket,
2362             &oldsocket->so_label, newsocket, &newsocket->so_peerlabel);
2363 }
2364
2365 void
2366 mac_create_datagram_from_ipq(struct ipq *ipq, struct mbuf *datagram)
2367 {
2368
2369         MAC_PERFORM(create_datagram_from_ipq, ipq, &ipq->ipq_label,
2370             datagram, &datagram->m_pkthdr.label);
2371 }
2372
2373 void
2374 mac_create_fragment(struct mbuf *datagram, struct mbuf *fragment)
2375 {
2376
2377         MAC_PERFORM(create_fragment, datagram, &datagram->m_pkthdr.label,
2378             fragment, &fragment->m_pkthdr.label);
2379 }
2380
2381 void
2382 mac_create_ipq(struct mbuf *fragment, struct ipq *ipq)
2383 {
2384
2385         MAC_PERFORM(create_ipq, fragment, &fragment->m_pkthdr.label, ipq,
2386             &ipq->ipq_label);
2387 }
2388
2389 void
2390 mac_create_mbuf_from_mbuf(struct mbuf *oldmbuf, struct mbuf *newmbuf)
2391 {
2392
2393         MAC_PERFORM(create_mbuf_from_mbuf, oldmbuf, &oldmbuf->m_pkthdr.label,
2394             newmbuf, &newmbuf->m_pkthdr.label);
2395 }
2396
2397 void
2398 mac_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct mbuf *mbuf)
2399 {
2400
2401         MAC_PERFORM(create_mbuf_from_bpfdesc, bpf_d, &bpf_d->bd_label, mbuf,
2402             &mbuf->m_pkthdr.label);
2403 }
2404
2405 void
2406 mac_create_mbuf_linklayer(struct ifnet *ifnet, struct mbuf *mbuf)
2407 {
2408
2409         MAC_PERFORM(create_mbuf_linklayer, ifnet, &ifnet->if_label, mbuf,
2410             &mbuf->m_pkthdr.label);
2411 }
2412
2413 void
2414 mac_create_mbuf_from_ifnet(struct ifnet *ifnet, struct mbuf *mbuf)
2415 {
2416
2417         MAC_PERFORM(create_mbuf_from_ifnet, ifnet, &ifnet->if_label, mbuf,
2418             &mbuf->m_pkthdr.label);
2419 }
2420
2421 void
2422 mac_create_mbuf_multicast_encap(struct mbuf *oldmbuf, struct ifnet *ifnet,
2423     struct mbuf *newmbuf)
2424 {
2425
2426         MAC_PERFORM(create_mbuf_multicast_encap, oldmbuf,
2427             &oldmbuf->m_pkthdr.label, ifnet, &ifnet->if_label, newmbuf,
2428             &newmbuf->m_pkthdr.label);
2429 }
2430
2431 void
2432 mac_create_mbuf_netlayer(struct mbuf *oldmbuf, struct mbuf *newmbuf)
2433 {
2434
2435         MAC_PERFORM(create_mbuf_netlayer, oldmbuf, &oldmbuf->m_pkthdr.label,
2436             newmbuf, &newmbuf->m_pkthdr.label);
2437 }
2438
2439 int
2440 mac_fragment_match(struct mbuf *fragment, struct ipq *ipq)
2441 {
2442         int result;
2443
2444         result = 1;
2445         MAC_BOOLEAN(fragment_match, &&, fragment, &fragment->m_pkthdr.label,
2446             ipq, &ipq->ipq_label);
2447
2448         return (result);
2449 }
2450
2451 void
2452 mac_update_ipq(struct mbuf *fragment, struct ipq *ipq)
2453 {
2454
2455         MAC_PERFORM(update_ipq, fragment, &fragment->m_pkthdr.label, ipq,
2456             &ipq->ipq_label);
2457 }
2458
2459 void
2460 mac_create_mbuf_from_socket(struct socket *socket, struct mbuf *mbuf)
2461 {
2462
2463         MAC_PERFORM(create_mbuf_from_socket, socket, &socket->so_label, mbuf,
2464             &mbuf->m_pkthdr.label);
2465 }
2466
2467 void
2468 mac_create_mount(struct ucred *cred, struct mount *mp)
2469 {
2470
2471         MAC_PERFORM(create_mount, cred, mp, &mp->mnt_mntlabel,
2472             &mp->mnt_fslabel);
2473 }
2474
2475 void
2476 mac_create_root_mount(struct ucred *cred, struct mount *mp)
2477 {
2478
2479         MAC_PERFORM(create_root_mount, cred, mp, &mp->mnt_mntlabel,
2480             &mp->mnt_fslabel);
2481 }
2482
2483 int
2484 mac_check_bpfdesc_receive(struct bpf_d *bpf_d, struct ifnet *ifnet)
2485 {
2486         int error;
2487
2488         if (!mac_enforce_network)
2489                 return (0);
2490
2491         MAC_CHECK(check_bpfdesc_receive, bpf_d, &bpf_d->bd_label, ifnet,
2492             &ifnet->if_label);
2493
2494         return (error);
2495 }
2496
2497 static int
2498 mac_check_cred_relabel(struct ucred *cred, struct label *newlabel)
2499 {
2500         int error;
2501
2502         MAC_CHECK(check_cred_relabel, cred, newlabel);
2503
2504         return (error);
2505 }
2506
2507 int
2508 mac_check_cred_visible(struct ucred *u1, struct ucred *u2)
2509 {
2510         int error;
2511
2512         if (!mac_enforce_process)
2513                 return (0);
2514
2515         MAC_CHECK(check_cred_visible, u1, u2);
2516
2517         return (error);
2518 }
2519
2520 int
2521 mac_check_ifnet_transmit(struct ifnet *ifnet, struct mbuf *mbuf)
2522 {
2523         int error;
2524
2525         if (!mac_enforce_network)
2526                 return (0);
2527
2528         KASSERT(mbuf->m_flags & M_PKTHDR, ("packet has no pkthdr"));
2529         if (!(mbuf->m_pkthdr.label.l_flags & MAC_FLAG_INITIALIZED))
2530                 printf("%s%d: not initialized\n", ifnet->if_name,
2531                     ifnet->if_unit);
2532
2533         MAC_CHECK(check_ifnet_transmit, ifnet, &ifnet->if_label, mbuf,
2534             &mbuf->m_pkthdr.label);
2535
2536         return (error);
2537 }
2538
2539 int
2540 mac_check_mount_stat(struct ucred *cred, struct mount *mount)
2541 {
2542         int error;
2543
2544         if (!mac_enforce_fs)
2545                 return (0);
2546
2547         MAC_CHECK(check_mount_stat, cred, mount, &mount->mnt_mntlabel);
2548
2549         return (error);
2550 }
2551
2552 int
2553 mac_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe, unsigned long cmd,
2554     void *data)
2555 {
2556         int error;
2557
2558         MAC_CHECK(check_pipe_ioctl, cred, pipe, pipe->pipe_label, cmd, data);
2559
2560         return (error);
2561 }
2562
2563 int
2564 mac_check_pipe_poll(struct ucred *cred, struct pipe *pipe)
2565 {
2566         int error;
2567
2568         MAC_CHECK(check_pipe_poll, cred, pipe, pipe->pipe_label);
2569
2570         return (error);
2571 }
2572
2573 int
2574 mac_check_pipe_read(struct ucred *cred, struct pipe *pipe)
2575 {
2576         int error;
2577
2578         MAC_CHECK(check_pipe_read, cred, pipe, pipe->pipe_label);
2579
2580         return (error);
2581 }
2582
2583 static int
2584 mac_check_pipe_relabel(struct ucred *cred, struct pipe *pipe,
2585     struct label *newlabel)
2586 {
2587         int error;
2588
2589         MAC_CHECK(check_pipe_relabel, cred, pipe, pipe->pipe_label, newlabel);
2590
2591         return (error);
2592 }
2593
2594 int
2595 mac_check_pipe_stat(struct ucred *cred, struct pipe *pipe)
2596 {
2597         int error;
2598
2599         MAC_CHECK(check_pipe_stat, cred, pipe, pipe->pipe_label);
2600
2601         return (error);
2602 }
2603
2604 int
2605 mac_check_pipe_write(struct ucred *cred, struct pipe *pipe)
2606 {
2607         int error;
2608
2609         MAC_CHECK(check_pipe_write, cred, pipe, pipe->pipe_label);
2610
2611         return (error);
2612 }
2613
2614 int
2615 mac_check_proc_debug(struct ucred *cred, struct proc *proc)
2616 {
2617         int error;
2618
2619         PROC_LOCK_ASSERT(proc, MA_OWNED);
2620
2621         if (!mac_enforce_process)
2622                 return (0);
2623
2624         MAC_CHECK(check_proc_debug, cred, proc);
2625
2626         return (error);
2627 }
2628
2629 int
2630 mac_check_proc_sched(struct ucred *cred, struct proc *proc)
2631 {
2632         int error;
2633
2634         PROC_LOCK_ASSERT(proc, MA_OWNED);
2635
2636         if (!mac_enforce_process)
2637                 return (0);
2638
2639         MAC_CHECK(check_proc_sched, cred, proc);
2640
2641         return (error);
2642 }
2643
2644 int
2645 mac_check_proc_signal(struct ucred *cred, struct proc *proc, int signum)
2646 {
2647         int error;
2648
2649         PROC_LOCK_ASSERT(proc, MA_OWNED);
2650
2651         if (!mac_enforce_process)
2652                 return (0);
2653
2654         MAC_CHECK(check_proc_signal, cred, proc, signum);
2655
2656         return (error);
2657 }
2658
2659 int
2660 mac_check_socket_bind(struct ucred *ucred, struct socket *socket,
2661     struct sockaddr *sockaddr)
2662 {
2663         int error;
2664
2665         if (!mac_enforce_socket)
2666                 return (0);
2667
2668         MAC_CHECK(check_socket_bind, ucred, socket, &socket->so_label,
2669             sockaddr);
2670
2671         return (error);
2672 }
2673
2674 int
2675 mac_check_socket_connect(struct ucred *cred, struct socket *socket,
2676     struct sockaddr *sockaddr)
2677 {
2678         int error;
2679
2680         if (!mac_enforce_socket)
2681                 return (0);
2682
2683         MAC_CHECK(check_socket_connect, cred, socket, &socket->so_label,
2684             sockaddr);
2685
2686         return (error);
2687 }
2688
2689 int
2690 mac_check_socket_deliver(struct socket *socket, struct mbuf *mbuf)
2691 {
2692         int error;
2693
2694         if (!mac_enforce_socket)
2695                 return (0);
2696
2697         MAC_CHECK(check_socket_deliver, socket, &socket->so_label, mbuf,
2698             &mbuf->m_pkthdr.label);
2699
2700         return (error);
2701 }
2702
2703 int
2704 mac_check_socket_listen(struct ucred *cred, struct socket *socket)
2705 {
2706         int error;
2707
2708         if (!mac_enforce_socket)
2709                 return (0);
2710
2711         MAC_CHECK(check_socket_listen, cred, socket, &socket->so_label);
2712         return (error);
2713 }
2714
2715 static int
2716 mac_check_socket_relabel(struct ucred *cred, struct socket *socket,
2717     struct label *newlabel)
2718 {
2719         int error;
2720
2721         MAC_CHECK(check_socket_relabel, cred, socket, &socket->so_label,
2722             newlabel);
2723
2724         return (error);
2725 }
2726
2727 int
2728 mac_check_socket_visible(struct ucred *cred, struct socket *socket)
2729 {
2730         int error;
2731
2732         if (!mac_enforce_socket)
2733                 return (0);
2734                 
2735         MAC_CHECK(check_socket_visible, cred, socket, &socket->so_label);
2736                             
2737         return (error);
2738 }
2739
2740 int
2741 mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr,
2742     struct ifnet *ifnet)
2743 {
2744         struct mac label;
2745         int error;
2746
2747         error = mac_externalize(&ifnet->if_label, &label);
2748         if (error)
2749                 return (error);
2750
2751         return (copyout(&label, ifr->ifr_ifru.ifru_data, sizeof(label)));
2752 }
2753
2754 int
2755 mac_ioctl_ifnet_set(struct ucred *cred, struct ifreq *ifr,
2756     struct ifnet *ifnet)
2757 {
2758         struct mac newlabel;
2759         struct label intlabel;
2760         int error;
2761
2762         error = copyin(ifr->ifr_ifru.ifru_data, &newlabel, sizeof(newlabel));
2763         if (error)
2764                 return (error);
2765
2766         error = mac_internalize(&intlabel, &newlabel);
2767         if (error)
2768                 return (error);
2769
2770         /*
2771          * XXX: Note that this is a redundant privilege check, since
2772          * policies impose this check themselves if required by the
2773          * policy.  Eventually, this should go away.
2774          */
2775         error = suser_cred(cred, 0);
2776         if (error)
2777                 goto out;
2778
2779         MAC_CHECK(check_ifnet_relabel, cred, ifnet, &ifnet->if_label,
2780             &intlabel);
2781         if (error)
2782                 goto out;
2783
2784         MAC_PERFORM(relabel_ifnet, cred, ifnet, &ifnet->if_label, &intlabel);
2785
2786 out:
2787         mac_destroy_temp(&intlabel);
2788         return (error);
2789 }
2790
2791 void
2792 mac_create_devfs_vnode(struct devfs_dirent *de, struct vnode *vp)
2793 {
2794
2795         MAC_PERFORM(create_devfs_vnode, de, &de->de_label, vp, &vp->v_label);
2796 }
2797
2798 void
2799 mac_create_devfs_device(dev_t dev, struct devfs_dirent *de)
2800 {
2801
2802         MAC_PERFORM(create_devfs_device, dev, de, &de->de_label);
2803 }
2804
2805 static int
2806 mac_stdcreatevnode_ea(struct vnode *vp)
2807 {
2808         int error;
2809
2810         MAC_CHECK(stdcreatevnode_ea, vp, &vp->v_label);
2811
2812         return (error);
2813 }
2814
2815 void
2816 mac_create_devfs_directory(char *dirname, int dirnamelen,
2817     struct devfs_dirent *de)
2818 {
2819
2820         MAC_PERFORM(create_devfs_directory, dirname, dirnamelen, de,
2821             &de->de_label);
2822 }
2823
2824 /*
2825  * When a new vnode is created, this call will initialize its label.
2826  */
2827 void
2828 mac_create_vnode(struct ucred *cred, struct vnode *parent,
2829     struct vnode *child)
2830 {
2831         int error;
2832
2833         ASSERT_VOP_LOCKED(parent, "mac_create_vnode");
2834         ASSERT_VOP_LOCKED(child, "mac_create_vnode");
2835
2836         error = vn_refreshlabel(parent, cred);
2837         if (error) {
2838                 printf("mac_create_vnode: vn_refreshlabel returned %d\n",
2839                     error);
2840                 printf("mac_create_vnode: using old vnode label\n");
2841         }
2842
2843         MAC_PERFORM(create_vnode, cred, parent, &parent->v_label, child,
2844             &child->v_label);
2845 }
2846
2847 int
2848 mac_setsockopt_label_set(struct ucred *cred, struct socket *so,
2849     struct mac *extmac)
2850 {
2851         struct label intlabel;
2852         int error;
2853
2854         error = mac_internalize(&intlabel, extmac);
2855         if (error)
2856                 return (error);
2857
2858         mac_check_socket_relabel(cred, so, &intlabel);
2859         if (error) {
2860                 mac_destroy_temp(&intlabel);
2861                 return (error);
2862         }
2863
2864         mac_relabel_socket(cred, so, &intlabel);
2865
2866         mac_destroy_temp(&intlabel);
2867         return (0);
2868 }
2869
2870 int
2871 mac_pipe_label_set(struct ucred *cred, struct pipe *pipe, struct label *label)
2872 {
2873         int error;
2874
2875         error = mac_check_pipe_relabel(cred, pipe, label);
2876         if (error)
2877                 return (error);
2878
2879         mac_relabel_pipe(cred, pipe, label);
2880
2881         return (0);
2882 }
2883
2884 int
2885 mac_getsockopt_label_get(struct ucred *cred, struct socket *so,
2886     struct mac *extmac)
2887 {
2888
2889         return (mac_externalize(&so->so_label, extmac));
2890 }
2891
2892 int
2893 mac_getsockopt_peerlabel_get(struct ucred *cred, struct socket *so,
2894     struct mac *extmac)
2895 {
2896
2897         return (mac_externalize(&so->so_peerlabel, extmac));
2898 }
2899
2900 /*
2901  * Implementation of VOP_SETLABEL() that relies on extended attributes
2902  * to store label data.  Can be referenced by filesystems supporting
2903  * extended attributes.
2904  */
2905 int
2906 vop_stdsetlabel_ea(struct vop_setlabel_args *ap)
2907 {
2908         struct vnode *vp = ap->a_vp;
2909         struct label *intlabel = ap->a_label;
2910         struct mac extmac;
2911         int error;
2912
2913         ASSERT_VOP_LOCKED(vp, "vop_stdsetlabel_ea");
2914
2915         /*
2916          * XXX: Eventually call out to EA check/set calls here.
2917          * Be particularly careful to avoid race conditions,
2918          * consistency problems, and stability problems when
2919          * dealing with multiple EAs.  In particular, we require
2920          * the ability to write multiple EAs on the same file in
2921          * a single transaction, which the current EA interface
2922          * does not provide.
2923          */
2924
2925         error = mac_externalize(intlabel, &extmac);
2926         if (error)
2927                 return (error);
2928
2929         error = vn_extattr_set(vp, IO_NODELOCKED,
2930             FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME,
2931             sizeof(extmac), (char *)&extmac, curthread);
2932         if (error)
2933                 return (error);
2934
2935         mac_relabel_vnode(ap->a_cred, vp, intlabel);
2936
2937         vp->v_vflag |= VV_CACHEDLABEL;
2938
2939         return (0);
2940 }
2941
2942 static int
2943 vn_setlabel(struct vnode *vp, struct label *intlabel, struct ucred *cred)
2944 {
2945         int error;
2946
2947         if (vp->v_mount == NULL) {
2948                 /* printf("vn_setlabel: null v_mount\n"); */
2949                 if (vp->v_tag != VT_NON)
2950                         printf("vn_setlabel: null v_mount with non-VT_NON\n");
2951                 return (EBADF);
2952         }
2953
2954         if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0)
2955                 return (EOPNOTSUPP);
2956
2957         /*
2958          * Multi-phase commit.  First check the policies to confirm the
2959          * change is OK.  Then commit via the filesystem.  Finally,
2960          * update the actual vnode label.  Question: maybe the filesystem
2961          * should update the vnode at the end as part of VOP_SETLABEL()?
2962          */
2963         error = mac_check_vnode_relabel(cred, vp, intlabel);
2964         if (error)
2965                 return (error);
2966
2967         /*
2968          * VADMIN provides the opportunity for the filesystem to make
2969          * decisions about who is and is not able to modify labels
2970          * and protections on files.  This might not be right.  We can't
2971          * assume VOP_SETLABEL() will do it, because we might implement
2972          * that as part of vop_stdsetlabel_ea().
2973          */
2974         error = VOP_ACCESS(vp, VADMIN, cred, curthread);
2975         if (error)
2976                 return (error);
2977
2978         error = VOP_SETLABEL(vp, intlabel, cred, curthread);
2979         if (error)
2980                 return (error);
2981
2982         return (0);
2983 }
2984
2985 /*
2986  * MPSAFE
2987  */
2988 int
2989 __mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap)
2990 {
2991         struct mac extmac;
2992         int error;
2993
2994         error = mac_externalize(&td->td_ucred->cr_label, &extmac);
2995         if (error == 0)
2996                 error = copyout(&extmac, SCARG(uap, mac_p), sizeof(extmac));
2997
2998         return (error);
2999 }
3000
3001 /*
3002  * MPSAFE
3003  */
3004 int
3005 __mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap)
3006 {
3007         struct ucred *newcred, *oldcred;
3008         struct proc *p;
3009         struct mac extmac;
3010         struct label intlabel;
3011         int error;
3012
3013         error = copyin(SCARG(uap, mac_p), &extmac, sizeof(extmac));
3014         if (error)
3015                 return (error);
3016
3017         error = mac_internalize(&intlabel, &extmac);
3018         if (error)
3019                 return (error);
3020
3021         newcred = crget();
3022
3023         p = td->td_proc;
3024         PROC_LOCK(p);
3025         oldcred = p->p_ucred;
3026
3027         error = mac_check_cred_relabel(oldcred, &intlabel);
3028         if (error) {
3029                 PROC_UNLOCK(p);
3030                 mac_destroy_temp(&intlabel);
3031                 crfree(newcred);
3032                 return (error);
3033         }
3034
3035         setsugid(p);
3036         crcopy(newcred, oldcred);
3037         mac_relabel_cred(newcred, &intlabel);
3038         p->p_ucred = newcred;
3039
3040         /*
3041          * Grab additional reference for use while revoking mmaps, prior
3042          * to releasing the proc lock and sharing the cred.
3043          */
3044         crhold(newcred);
3045         PROC_UNLOCK(p);
3046
3047         mac_cred_mmapped_drop_perms(td, newcred);
3048
3049         crfree(newcred);        /* Free revocation reference. */
3050         crfree(oldcred);
3051         mac_destroy_temp(&intlabel);
3052         return (0);
3053 }
3054
3055 /*
3056  * MPSAFE
3057  */
3058 int
3059 __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
3060 {
3061         struct file *fp;
3062         struct mac extmac;
3063         struct vnode *vp;
3064         struct pipe *pipe;
3065         int error;
3066
3067         mtx_lock(&Giant);
3068
3069         error = fget(td, SCARG(uap, fd), &fp);
3070         if (error)
3071                 goto out;
3072
3073         switch (fp->f_type) {
3074         case DTYPE_FIFO:
3075         case DTYPE_VNODE:
3076                 vp = (struct vnode *)fp->f_data;
3077
3078                 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
3079                 error = vn_refreshlabel(vp, td->td_ucred);
3080                 if (error == 0)
3081                         error = mac_externalize(&vp->v_label, &extmac);
3082                 VOP_UNLOCK(vp, 0, td);
3083                 break;
3084         case DTYPE_PIPE:
3085                 pipe = (struct pipe *)fp->f_data;
3086                 error = mac_externalize(pipe->pipe_label, &extmac);
3087                 break;
3088         default:
3089                 error = EINVAL;
3090         }
3091
3092         if (error == 0)
3093                 error = copyout(&extmac, SCARG(uap, mac_p), sizeof(extmac));
3094
3095         fdrop(fp, td);
3096
3097 out:
3098         mtx_unlock(&Giant);
3099         return (error);
3100 }
3101
3102 /*
3103  * MPSAFE
3104  */
3105 int
3106 __mac_get_file(struct thread *td, struct __mac_get_file_args *uap)
3107 {
3108         struct nameidata nd;
3109         struct mac extmac;
3110         int error;
3111
3112         mtx_lock(&Giant);
3113         NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE,
3114             SCARG(uap, path_p), td);
3115         error = namei(&nd);
3116         if (error)
3117                 goto out;
3118
3119         error = vn_refreshlabel(nd.ni_vp, td->td_ucred);
3120         if (error == 0)
3121                 error = mac_externalize(&nd.ni_vp->v_label, &extmac);
3122         NDFREE(&nd, 0);
3123         if (error)
3124                 goto out;
3125
3126         error = copyout(&extmac, SCARG(uap, mac_p), sizeof(extmac));
3127
3128 out:
3129         mtx_unlock(&Giant);
3130         return (error);
3131 }
3132
3133 /*
3134  * MPSAFE
3135  */
3136 int
3137 __mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap)
3138 {
3139         struct file *fp;
3140         struct mac extmac;
3141         struct label intlabel;
3142         struct mount *mp;
3143         struct vnode *vp;
3144         struct pipe *pipe;
3145         int error;
3146
3147         mtx_lock(&Giant);
3148         error = fget(td, SCARG(uap, fd), &fp);
3149         if (error)
3150                 goto out1;
3151
3152         error = copyin(SCARG(uap, mac_p), &extmac, sizeof(extmac));
3153         if (error)
3154                 goto out2;
3155
3156         error = mac_internalize(&intlabel, &extmac);
3157         if (error)
3158                 goto out2;
3159
3160         switch (fp->f_type) {
3161         case DTYPE_FIFO:
3162         case DTYPE_VNODE:
3163                 vp = (struct vnode *)fp->f_data;
3164                 error = vn_start_write(vp, &mp, V_WAIT | PCATCH);
3165                 if (error != 0)
3166                         break;
3167
3168                 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
3169                 error = vn_setlabel(vp, &intlabel, td->td_ucred);
3170                 VOP_UNLOCK(vp, 0, td);
3171                 vn_finished_write(mp);
3172                 mac_destroy_temp(&intlabel);
3173                 break;
3174         case DTYPE_PIPE:
3175                 pipe = (struct pipe *)fp->f_data;
3176                 error = mac_pipe_label_set(td->td_ucred, pipe, &intlabel);
3177                 break;
3178         default:
3179                 error = EINVAL;
3180         }
3181
3182 out2:
3183         fdrop(fp, td);
3184 out1:
3185         mtx_unlock(&Giant);
3186         return (error);
3187 }
3188
3189 /*
3190  * MPSAFE
3191  */
3192 int
3193 __mac_set_file(struct thread *td, struct __mac_set_file_args *uap)
3194 {
3195         struct nameidata nd;
3196         struct mac extmac;
3197         struct label intlabel;
3198         struct mount *mp;
3199         int error;
3200
3201         mtx_lock(&Giant);
3202
3203         error = copyin(SCARG(uap, mac_p), &extmac, sizeof(extmac));
3204         if (error)
3205                 goto out;
3206
3207         error = mac_internalize(&intlabel, &extmac);
3208         if (error)
3209                 goto out;
3210
3211         NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE,
3212             SCARG(uap, path_p), td);
3213         error = namei(&nd);
3214         if (error)
3215                 goto out2;
3216         error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH);
3217         if (error)
3218                 goto out2;
3219
3220         error = vn_setlabel(nd.ni_vp, &intlabel, td->td_ucred);
3221
3222         vn_finished_write(mp);
3223 out2:
3224         mac_destroy_temp(&intlabel);
3225         NDFREE(&nd, 0);
3226 out:
3227         mtx_unlock(&Giant);
3228         return (error);
3229 }
3230
3231 int
3232 mac_syscall(struct thread *td, struct mac_syscall_args *uap)
3233 {
3234         struct mac_policy_conf *mpc;
3235         char target[MAC_MAX_POLICY_NAME];
3236         int error;
3237
3238         error = copyinstr(SCARG(uap, policy), target, sizeof(target), NULL);
3239         if (error)
3240                 return (error);
3241
3242         error = ENOSYS;
3243         MAC_POLICY_LIST_BUSY();
3244         LIST_FOREACH(mpc, &mac_policy_list, mpc_list) {
3245                 if (strcmp(mpc->mpc_name, target) == 0 &&
3246                     mpc->mpc_ops->mpo_syscall != NULL) {
3247                         error = mpc->mpc_ops->mpo_syscall(td,
3248                             SCARG(uap, call), SCARG(uap, arg));
3249                         goto out;
3250                 }
3251         }
3252
3253 out:
3254         MAC_POLICY_LIST_UNBUSY();
3255         return (error);
3256 }
3257
3258 SYSINIT(mac, SI_SUB_MAC, SI_ORDER_FIRST, mac_init, NULL);
3259 SYSINIT(mac_late, SI_SUB_MAC_LATE, SI_ORDER_FIRST, mac_late_init, NULL);
3260
3261 #else /* !MAC */
3262
3263 int
3264 __mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap)
3265 {
3266
3267         return (ENOSYS);
3268 }
3269
3270 int
3271 __mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap)
3272 {
3273
3274         return (ENOSYS);
3275 }
3276
3277 int
3278 __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
3279 {
3280
3281         return (ENOSYS);
3282 }
3283
3284 int
3285 __mac_get_file(struct thread *td, struct __mac_get_file_args *uap)
3286 {
3287
3288         return (ENOSYS);
3289 }
3290
3291 int
3292 __mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap)
3293 {
3294
3295         return (ENOSYS);
3296 }
3297
3298 int
3299 __mac_set_file(struct thread *td, struct __mac_set_file_args *uap)
3300 {
3301
3302         return (ENOSYS);
3303 }
3304
3305 int
3306 mac_syscall(struct thread *td, struct mac_syscall_args *uap)
3307 {
3308
3309         return (ENOSYS);
3310 }
3311
3312 #endif /* !MAC */