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