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