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