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