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