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