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