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