mac_internal.h revision 104338
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 104338 2002-10-02 02:42:38Z rwatson $ 40 */ 41/* 42 * Developed by the TrustedBSD Project. 43 * 44 * Framework for extensible kernel access control. Kernel and userland 45 * interface to the framework, policy registration and composition. 46 */ 47 48#include "opt_mac.h" 49#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_THREAD_USERRET: 656 mpc->mpc_ops->mpo_thread_userret = 657 mpe->mpe_function; 658 break; 659 case MAC_CHECK_BPFDESC_RECEIVE: 660 mpc->mpc_ops->mpo_check_bpfdesc_receive = 661 mpe->mpe_function; 662 break; 663 case MAC_CHECK_CRED_RELABEL: 664 mpc->mpc_ops->mpo_check_cred_relabel = 665 mpe->mpe_function; 666 break; 667 case MAC_CHECK_CRED_VISIBLE: 668 mpc->mpc_ops->mpo_check_cred_visible = 669 mpe->mpe_function; 670 break; 671 case MAC_CHECK_IFNET_RELABEL: 672 mpc->mpc_ops->mpo_check_ifnet_relabel = 673 mpe->mpe_function; 674 break; 675 case MAC_CHECK_IFNET_TRANSMIT: 676 mpc->mpc_ops->mpo_check_ifnet_transmit = 677 mpe->mpe_function; 678 break; 679 case MAC_CHECK_MOUNT_STAT: 680 mpc->mpc_ops->mpo_check_mount_stat = 681 mpe->mpe_function; 682 break; 683 case MAC_CHECK_PIPE_IOCTL: 684 mpc->mpc_ops->mpo_check_pipe_ioctl = 685 mpe->mpe_function; 686 break; 687 case MAC_CHECK_PIPE_POLL: 688 mpc->mpc_ops->mpo_check_pipe_poll = 689 mpe->mpe_function; 690 break; 691 case MAC_CHECK_PIPE_READ: 692 mpc->mpc_ops->mpo_check_pipe_read = 693 mpe->mpe_function; 694 break; 695 case MAC_CHECK_PIPE_RELABEL: 696 mpc->mpc_ops->mpo_check_pipe_relabel = 697 mpe->mpe_function; 698 break; 699 case MAC_CHECK_PIPE_STAT: 700 mpc->mpc_ops->mpo_check_pipe_stat = 701 mpe->mpe_function; 702 break; 703 case MAC_CHECK_PIPE_WRITE: 704 mpc->mpc_ops->mpo_check_pipe_write = 705 mpe->mpe_function; 706 break; 707 case MAC_CHECK_PROC_DEBUG: 708 mpc->mpc_ops->mpo_check_proc_debug = 709 mpe->mpe_function; 710 break; 711 case MAC_CHECK_PROC_SCHED: 712 mpc->mpc_ops->mpo_check_proc_sched = 713 mpe->mpe_function; 714 break; 715 case MAC_CHECK_PROC_SIGNAL: 716 mpc->mpc_ops->mpo_check_proc_signal = 717 mpe->mpe_function; 718 break; 719 case MAC_CHECK_SOCKET_BIND: 720 mpc->mpc_ops->mpo_check_socket_bind = 721 mpe->mpe_function; 722 break; 723 case MAC_CHECK_SOCKET_CONNECT: 724 mpc->mpc_ops->mpo_check_socket_connect = 725 mpe->mpe_function; 726 break; 727 case MAC_CHECK_SOCKET_DELIVER: 728 mpc->mpc_ops->mpo_check_socket_deliver = 729 mpe->mpe_function; 730 break; 731 case MAC_CHECK_SOCKET_LISTEN: 732 mpc->mpc_ops->mpo_check_socket_listen = 733 mpe->mpe_function; 734 break; 735 case MAC_CHECK_SOCKET_RELABEL: 736 mpc->mpc_ops->mpo_check_socket_relabel = 737 mpe->mpe_function; 738 break; 739 case MAC_CHECK_SOCKET_VISIBLE: 740 mpc->mpc_ops->mpo_check_socket_visible = 741 mpe->mpe_function; 742 break; 743 case MAC_CHECK_VNODE_ACCESS: 744 mpc->mpc_ops->mpo_check_vnode_access = 745 mpe->mpe_function; 746 break; 747 case MAC_CHECK_VNODE_CHDIR: 748 mpc->mpc_ops->mpo_check_vnode_chdir = 749 mpe->mpe_function; 750 break; 751 case MAC_CHECK_VNODE_CHROOT: 752 mpc->mpc_ops->mpo_check_vnode_chroot = 753 mpe->mpe_function; 754 break; 755 case MAC_CHECK_VNODE_CREATE: 756 mpc->mpc_ops->mpo_check_vnode_create = 757 mpe->mpe_function; 758 break; 759 case MAC_CHECK_VNODE_DELETE: 760 mpc->mpc_ops->mpo_check_vnode_delete = 761 mpe->mpe_function; 762 break; 763 case MAC_CHECK_VNODE_DELETEACL: 764 mpc->mpc_ops->mpo_check_vnode_deleteacl = 765 mpe->mpe_function; 766 break; 767 case MAC_CHECK_VNODE_EXEC: 768 mpc->mpc_ops->mpo_check_vnode_exec = 769 mpe->mpe_function; 770 break; 771 case MAC_CHECK_VNODE_GETACL: 772 mpc->mpc_ops->mpo_check_vnode_getacl = 773 mpe->mpe_function; 774 break; 775 case MAC_CHECK_VNODE_GETEXTATTR: 776 mpc->mpc_ops->mpo_check_vnode_getextattr = 777 mpe->mpe_function; 778 break; 779 case MAC_CHECK_VNODE_LOOKUP: 780 mpc->mpc_ops->mpo_check_vnode_lookup = 781 mpe->mpe_function; 782 break; 783 case MAC_CHECK_VNODE_MMAP_PERMS: 784 mpc->mpc_ops->mpo_check_vnode_mmap_perms = 785 mpe->mpe_function; 786 break; 787 case MAC_CHECK_VNODE_OPEN: 788 mpc->mpc_ops->mpo_check_vnode_open = 789 mpe->mpe_function; 790 break; 791 case MAC_CHECK_VNODE_POLL: 792 mpc->mpc_ops->mpo_check_vnode_poll = 793 mpe->mpe_function; 794 break; 795 case MAC_CHECK_VNODE_READ: 796 mpc->mpc_ops->mpo_check_vnode_read = 797 mpe->mpe_function; 798 break; 799 case MAC_CHECK_VNODE_READDIR: 800 mpc->mpc_ops->mpo_check_vnode_readdir = 801 mpe->mpe_function; 802 break; 803 case MAC_CHECK_VNODE_READLINK: 804 mpc->mpc_ops->mpo_check_vnode_readlink = 805 mpe->mpe_function; 806 break; 807 case MAC_CHECK_VNODE_RELABEL: 808 mpc->mpc_ops->mpo_check_vnode_relabel = 809 mpe->mpe_function; 810 break; 811 case MAC_CHECK_VNODE_RENAME_FROM: 812 mpc->mpc_ops->mpo_check_vnode_rename_from = 813 mpe->mpe_function; 814 break; 815 case MAC_CHECK_VNODE_RENAME_TO: 816 mpc->mpc_ops->mpo_check_vnode_rename_to = 817 mpe->mpe_function; 818 break; 819 case MAC_CHECK_VNODE_REVOKE: 820 mpc->mpc_ops->mpo_check_vnode_revoke = 821 mpe->mpe_function; 822 break; 823 case MAC_CHECK_VNODE_SETACL: 824 mpc->mpc_ops->mpo_check_vnode_setacl = 825 mpe->mpe_function; 826 break; 827 case MAC_CHECK_VNODE_SETEXTATTR: 828 mpc->mpc_ops->mpo_check_vnode_setextattr = 829 mpe->mpe_function; 830 break; 831 case MAC_CHECK_VNODE_SETFLAGS: 832 mpc->mpc_ops->mpo_check_vnode_setflags = 833 mpe->mpe_function; 834 break; 835 case MAC_CHECK_VNODE_SETMODE: 836 mpc->mpc_ops->mpo_check_vnode_setmode = 837 mpe->mpe_function; 838 break; 839 case MAC_CHECK_VNODE_SETOWNER: 840 mpc->mpc_ops->mpo_check_vnode_setowner = 841 mpe->mpe_function; 842 break; 843 case MAC_CHECK_VNODE_SETUTIMES: 844 mpc->mpc_ops->mpo_check_vnode_setutimes = 845 mpe->mpe_function; 846 break; 847 case MAC_CHECK_VNODE_STAT: 848 mpc->mpc_ops->mpo_check_vnode_stat = 849 mpe->mpe_function; 850 break; 851 case MAC_CHECK_VNODE_WRITE: 852 mpc->mpc_ops->mpo_check_vnode_write = 853 mpe->mpe_function; 854 break; 855/* 856 default: 857 printf("MAC policy `%s': unknown operation %d\n", 858 mpc->mpc_name, mpe->mpe_constant); 859 return (EINVAL); 860*/ 861 } 862 } 863 MAC_POLICY_LIST_LOCK(); 864 if (mac_policy_list_busy > 0) { 865 MAC_POLICY_LIST_UNLOCK(); 866 FREE(mpc->mpc_ops, M_MACOPVEC); 867 mpc->mpc_ops = NULL; 868 return (EBUSY); 869 } 870 LIST_FOREACH(tmpc, &mac_policy_list, mpc_list) { 871 if (strcmp(tmpc->mpc_name, mpc->mpc_name) == 0) { 872 MAC_POLICY_LIST_UNLOCK(); 873 FREE(mpc->mpc_ops, M_MACOPVEC); 874 mpc->mpc_ops = NULL; 875 return (EEXIST); 876 } 877 } 878 if (mpc->mpc_field_off != NULL) { 879 slot = ffs(mac_policy_offsets_free); 880 if (slot == 0) { 881 MAC_POLICY_LIST_UNLOCK(); 882 FREE(mpc->mpc_ops, M_MACOPVEC); 883 mpc->mpc_ops = NULL; 884 return (ENOMEM); 885 } 886 slot--; 887 mac_policy_offsets_free &= ~(1 << slot); 888 *mpc->mpc_field_off = slot; 889 } 890 mpc->mpc_runtime_flags |= MPC_RUNTIME_FLAG_REGISTERED; 891 LIST_INSERT_HEAD(&mac_policy_list, mpc, mpc_list); 892 893 /* Per-policy initialization. */ 894 if (mpc->mpc_ops->mpo_init != NULL) 895 (*(mpc->mpc_ops->mpo_init))(mpc); 896 MAC_POLICY_LIST_UNLOCK(); 897 898 printf("Security policy loaded: %s (%s)\n", mpc->mpc_fullname, 899 mpc->mpc_name); 900 901 return (0); 902} 903 904static int 905mac_policy_unregister(struct mac_policy_conf *mpc) 906{ 907 908#if 0 909 /* 910 * Don't allow unloading modules with private data. 911 */ 912 if (mpc->mpc_field_off != NULL) 913 return (EBUSY); 914#endif 915 if ((mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_UNLOADOK) == 0) 916 return (EBUSY); 917 MAC_POLICY_LIST_LOCK(); 918 if (mac_policy_list_busy > 0) { 919 MAC_POLICY_LIST_UNLOCK(); 920 return (EBUSY); 921 } 922 if (mpc->mpc_ops->mpo_destroy != NULL) 923 (*(mpc->mpc_ops->mpo_destroy))(mpc); 924 925 LIST_REMOVE(mpc, mpc_list); 926 MAC_POLICY_LIST_UNLOCK(); 927 928 FREE(mpc->mpc_ops, M_MACOPVEC); 929 mpc->mpc_ops = NULL; 930 931 printf("Security policy unload: %s (%s)\n", mpc->mpc_fullname, 932 mpc->mpc_name); 933 934 return (0); 935} 936 937/* 938 * Define an error value precedence, and given two arguments, selects the 939 * value with the higher precedence. 940 */ 941static int 942error_select(int error1, int error2) 943{ 944 945 /* Certain decision-making errors take top priority. */ 946 if (error1 == EDEADLK || error2 == EDEADLK) 947 return (EDEADLK); 948 949 /* Invalid arguments should be reported where possible. */ 950 if (error1 == EINVAL || error2 == EINVAL) 951 return (EINVAL); 952 953 /* Precedence goes to "visibility", with both process and file. */ 954 if (error1 == ESRCH || error2 == ESRCH) 955 return (ESRCH); 956 957 if (error1 == ENOENT || error2 == ENOENT) 958 return (ENOENT); 959 960 /* Precedence goes to DAC/MAC protections. */ 961 if (error1 == EACCES || error2 == EACCES) 962 return (EACCES); 963 964 /* Precedence goes to privilege. */ 965 if (error1 == EPERM || error2 == EPERM) 966 return (EPERM); 967 968 /* Precedence goes to error over success; otherwise, arbitrary. */ 969 if (error1 != 0) 970 return (error1); 971 return (error2); 972} 973 974void 975mac_update_devfsdirent(struct devfs_dirent *de, struct vnode *vp) 976{ 977 978 MAC_PERFORM(update_devfsdirent, de, &de->de_label, vp, &vp->v_label); 979} 980 981void 982mac_update_procfsvnode(struct vnode *vp, struct ucred *cred) 983{ 984 985 MAC_PERFORM(update_procfsvnode, vp, &vp->v_label, cred); 986} 987 988/* 989 * Support callout for policies that manage their own externalization 990 * using extended attributes. 991 */ 992static int 993mac_update_vnode_from_extattr(struct vnode *vp, struct mount *mp) 994{ 995 int error; 996 997 MAC_CHECK(update_vnode_from_extattr, vp, &vp->v_label, mp, 998 &mp->mnt_fslabel); 999 1000 return (error); 1001} 1002 1003/* 1004 * Given an externalized mac label, internalize it and stamp it on a 1005 * vnode. 1006 */ 1007static int 1008mac_update_vnode_from_externalized(struct vnode *vp, struct mac *extmac) 1009{ 1010 int error; 1011 1012 MAC_CHECK(update_vnode_from_externalized, vp, &vp->v_label, extmac); 1013 1014 return (error); 1015} 1016 1017/* 1018 * Call out to individual policies to update the label in a vnode from 1019 * the mountpoint. 1020 */ 1021void 1022mac_update_vnode_from_mount(struct vnode *vp, struct mount *mp) 1023{ 1024 1025 MAC_PERFORM(update_vnode_from_mount, vp, &vp->v_label, mp, 1026 &mp->mnt_fslabel); 1027 1028 ASSERT_VOP_LOCKED(vp, "mac_update_vnode_from_mount"); 1029 if (mac_cache_fslabel_in_vnode) 1030 vp->v_vflag |= VV_CACHEDLABEL; 1031} 1032 1033/* 1034 * Implementation of VOP_REFRESHLABEL() that relies on extended attributes 1035 * to store label data. Can be referenced by filesystems supporting 1036 * extended attributes. 1037 */ 1038int 1039vop_stdrefreshlabel_ea(struct vop_refreshlabel_args *ap) 1040{ 1041 struct vnode *vp = ap->a_vp; 1042 struct mac extmac; 1043 int buflen, error; 1044 1045 ASSERT_VOP_LOCKED(vp, "vop_stdrefreshlabel_ea"); 1046 1047 /* 1048 * Call out to external policies first. Order doesn't really 1049 * matter, as long as failure of one assures failure of all. 1050 */ 1051 error = mac_update_vnode_from_extattr(vp, vp->v_mount); 1052 if (error) 1053 return (error); 1054 1055 buflen = sizeof(extmac); 1056 error = vn_extattr_get(vp, IO_NODELOCKED, 1057 FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME, &buflen, 1058 (char *)&extmac, curthread); 1059 switch (error) { 1060 case 0: 1061 /* Got it */ 1062 break; 1063 1064 case ENOATTR: 1065 /* 1066 * Use the label from the mount point. 1067 */ 1068 mac_update_vnode_from_mount(vp, vp->v_mount); 1069 return (0); 1070 1071 case EOPNOTSUPP: 1072 default: 1073 /* Fail horribly. */ 1074 return (error); 1075 } 1076 1077 if (buflen != sizeof(extmac)) 1078 error = EPERM; /* Fail very closed. */ 1079 if (error == 0) 1080 error = mac_update_vnode_from_externalized(vp, &extmac); 1081 if (error == 0) 1082 vp->v_vflag |= VV_CACHEDLABEL; 1083 else { 1084 struct vattr va; 1085 1086 printf("Corrupted label on %s", 1087 vp->v_mount->mnt_stat.f_mntonname); 1088 if (VOP_GETATTR(vp, &va, curthread->td_ucred, curthread) == 0) 1089 printf(" inum %ld", va.va_fileid); 1090#ifdef MAC_DEBUG 1091 if (mac_debug_label_fallback) { 1092 printf(", falling back.\n"); 1093 mac_update_vnode_from_mount(vp, vp->v_mount); 1094 error = 0; 1095 } else { 1096#endif 1097 printf(".\n"); 1098 error = EPERM; 1099#ifdef MAC_DEBUG 1100 } 1101#endif 1102 } 1103 1104 return (error); 1105} 1106 1107/* 1108 * Make sure the vnode label is up-to-date. If EOPNOTSUPP, then we handle 1109 * the labeling activity outselves. Filesystems should be careful not 1110 * to change their minds regarding whether they support vop_refreshlabel() 1111 * for a vnode or not. Don't cache the vnode here, allow the file 1112 * system code to determine if it's safe to cache. If we update from 1113 * the mount, don't cache since a change to the mount label should affect 1114 * all vnodes. 1115 */ 1116static int 1117vn_refreshlabel(struct vnode *vp, struct ucred *cred) 1118{ 1119 int error; 1120 1121 ASSERT_VOP_LOCKED(vp, "vn_refreshlabel"); 1122 1123 if (vp->v_mount == NULL) { 1124/* 1125 Eventually, we probably want to special-case refreshing 1126 of deadfs vnodes, and if there's a lock-free race somewhere, 1127 that case might be handled here. 1128 1129 mac_update_vnode_deadfs(vp); 1130 return (0); 1131 */ 1132 /* printf("vn_refreshlabel: null v_mount\n"); */ 1133 if (vp->v_type != VNON) 1134 printf( 1135 "vn_refreshlabel: null v_mount with non-VNON\n"); 1136 return (EBADF); 1137 } 1138 1139 if (vp->v_vflag & VV_CACHEDLABEL) { 1140 mac_vnode_label_cache_hits++; 1141 return (0); 1142 } else 1143 mac_vnode_label_cache_misses++; 1144 1145 if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) { 1146 mac_update_vnode_from_mount(vp, vp->v_mount); 1147 return (0); 1148 } 1149 1150 error = VOP_REFRESHLABEL(vp, cred, curthread); 1151 switch (error) { 1152 case EOPNOTSUPP: 1153 /* 1154 * If labels are not supported on this vnode, fall back to 1155 * the label in the mount and propagate it to the vnode. 1156 * There should probably be some sort of policy/flag/decision 1157 * about doing this. 1158 */ 1159 mac_update_vnode_from_mount(vp, vp->v_mount); 1160 error = 0; 1161 default: 1162 return (error); 1163 } 1164} 1165 1166/* 1167 * Helper function for file systems using the vop_std*_ea() calls. This 1168 * function must be called after EA service is available for the vnode, 1169 * but before it's hooked up to the namespace so that the node persists 1170 * if there's a crash, or before it can be accessed. On successful 1171 * commit of the label to disk (etc), do cache the label. 1172 */ 1173int 1174vop_stdcreatevnode_ea(struct vnode *dvp, struct vnode *tvp, struct ucred *cred) 1175{ 1176 struct mac extmac; 1177 int error; 1178 1179 ASSERT_VOP_LOCKED(tvp, "vop_stdcreatevnode_ea"); 1180 if ((dvp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) { 1181 mac_update_vnode_from_mount(tvp, tvp->v_mount); 1182 } else { 1183 error = vn_refreshlabel(dvp, cred); 1184 if (error) 1185 return (error); 1186 1187 /* 1188 * Stick the label in the vnode. Then try to write to 1189 * disk. If we fail, return a failure to abort the 1190 * create operation. Really, this failure shouldn't 1191 * happen except in fairly unusual circumstances (out 1192 * of disk, etc). 1193 */ 1194 mac_create_vnode(cred, dvp, tvp); 1195 1196 error = mac_stdcreatevnode_ea(tvp); 1197 if (error) 1198 return (error); 1199 1200 /* 1201 * XXX: Eventually this will go away and all policies will 1202 * directly manage their extended attributes. 1203 */ 1204 error = mac_externalize(&tvp->v_label, &extmac); 1205 if (error) 1206 return (error); 1207 1208 error = vn_extattr_set(tvp, IO_NODELOCKED, 1209 FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME, 1210 sizeof(extmac), (char *)&extmac, curthread); 1211 if (error == 0) 1212 tvp->v_vflag |= VV_CACHEDLABEL; 1213 else { 1214#if 0 1215 /* 1216 * In theory, we could have fall-back behavior here. 1217 * It would probably be incorrect. 1218 */ 1219#endif 1220 return (error); 1221 } 1222 } 1223 1224 return (0); 1225} 1226 1227void 1228mac_execve_transition(struct ucred *old, struct ucred *new, struct vnode *vp) 1229{ 1230 int error; 1231 1232 ASSERT_VOP_LOCKED(vp, "mac_execve_transition"); 1233 1234 error = vn_refreshlabel(vp, old); 1235 if (error) { 1236 printf("mac_execve_transition: vn_refreshlabel returned %d\n", 1237 error); 1238 printf("mac_execve_transition: using old vnode label\n"); 1239 } 1240 1241 MAC_PERFORM(execve_transition, old, new, vp, &vp->v_label); 1242} 1243 1244int 1245mac_execve_will_transition(struct ucred *old, struct vnode *vp) 1246{ 1247 int error, result; 1248 1249 error = vn_refreshlabel(vp, old); 1250 if (error) 1251 return (error); 1252 1253 result = 0; 1254 MAC_BOOLEAN(execve_will_transition, ||, old, vp, &vp->v_label); 1255 1256 return (result); 1257} 1258 1259static void 1260mac_init_label(struct label *label) 1261{ 1262 1263 bzero(label, sizeof(*label)); 1264 label->l_flags = MAC_FLAG_INITIALIZED; 1265} 1266 1267static void 1268mac_init_structmac(struct mac *mac) 1269{ 1270 1271 bzero(mac, sizeof(*mac)); 1272 mac->m_macflags = MAC_FLAG_INITIALIZED; 1273} 1274 1275static void 1276mac_destroy_label(struct label *label) 1277{ 1278 1279 KASSERT(label->l_flags & MAC_FLAG_INITIALIZED, 1280 ("destroying uninitialized label")); 1281 1282 bzero(label, sizeof(*label)); 1283 /* implicit: label->l_flags &= ~MAC_FLAG_INITIALIZED; */ 1284} 1285 1286int 1287mac_init_mbuf(struct mbuf *m, int how) 1288{ 1289 KASSERT(m->m_flags & M_PKTHDR, ("mac_init_mbuf on non-header mbuf")); 1290 1291 /* "how" is one of M_(TRY|DONT)WAIT */ 1292 mac_init_label(&m->m_pkthdr.label); 1293 MAC_PERFORM(init_mbuf, m, how, &m->m_pkthdr.label); 1294#ifdef MAC_DEBUG 1295 atomic_add_int(&nmacmbufs, 1); 1296#endif 1297 return (0); 1298} 1299 1300void 1301mac_destroy_mbuf(struct mbuf *m) 1302{ 1303 1304 MAC_PERFORM(destroy_mbuf, m, &m->m_pkthdr.label); 1305 mac_destroy_label(&m->m_pkthdr.label); 1306#ifdef MAC_DEBUG 1307 atomic_subtract_int(&nmacmbufs, 1); 1308#endif 1309} 1310 1311void 1312mac_init_cred(struct ucred *cr) 1313{ 1314 1315 mac_init_label(&cr->cr_label); 1316 MAC_PERFORM(init_cred, cr, &cr->cr_label); 1317#ifdef MAC_DEBUG 1318 atomic_add_int(&nmaccreds, 1); 1319#endif 1320} 1321 1322void 1323mac_destroy_cred(struct ucred *cr) 1324{ 1325 1326 MAC_PERFORM(destroy_cred, cr, &cr->cr_label); 1327 mac_destroy_label(&cr->cr_label); 1328#ifdef MAC_DEBUG 1329 atomic_subtract_int(&nmaccreds, 1); 1330#endif 1331} 1332 1333void 1334mac_init_ifnet(struct ifnet *ifp) 1335{ 1336 1337 mac_init_label(&ifp->if_label); 1338 MAC_PERFORM(init_ifnet, ifp, &ifp->if_label); 1339#ifdef MAC_DEBUG 1340 atomic_add_int(&nmacifnets, 1); 1341#endif 1342} 1343 1344void 1345mac_destroy_ifnet(struct ifnet *ifp) 1346{ 1347 1348 MAC_PERFORM(destroy_ifnet, ifp, &ifp->if_label); 1349 mac_destroy_label(&ifp->if_label); 1350#ifdef MAC_DEBUG 1351 atomic_subtract_int(&nmacifnets, 1); 1352#endif 1353} 1354 1355void 1356mac_init_ipq(struct ipq *ipq) 1357{ 1358 1359 mac_init_label(&ipq->ipq_label); 1360 MAC_PERFORM(init_ipq, ipq, &ipq->ipq_label); 1361#ifdef MAC_DEBUG 1362 atomic_add_int(&nmacipqs, 1); 1363#endif 1364} 1365 1366void 1367mac_destroy_ipq(struct ipq *ipq) 1368{ 1369 1370 MAC_PERFORM(destroy_ipq, ipq, &ipq->ipq_label); 1371 mac_destroy_label(&ipq->ipq_label); 1372#ifdef MAC_DEBUG 1373 atomic_subtract_int(&nmacipqs, 1); 1374#endif 1375} 1376 1377void 1378mac_init_socket(struct socket *socket) 1379{ 1380 1381 mac_init_label(&socket->so_label); 1382 mac_init_label(&socket->so_peerlabel); 1383 MAC_PERFORM(init_socket, socket, &socket->so_label, 1384 &socket->so_peerlabel); 1385#ifdef MAC_DEBUG 1386 atomic_add_int(&nmacsockets, 1); 1387#endif 1388} 1389 1390void 1391mac_destroy_socket(struct socket *socket) 1392{ 1393 1394 MAC_PERFORM(destroy_socket, socket, &socket->so_label, 1395 &socket->so_peerlabel); 1396 mac_destroy_label(&socket->so_label); 1397 mac_destroy_label(&socket->so_peerlabel); 1398#ifdef MAC_DEBUG 1399 atomic_subtract_int(&nmacsockets, 1); 1400#endif 1401} 1402 1403void 1404mac_init_pipe(struct pipe *pipe) 1405{ 1406 struct label *label; 1407 1408 label = malloc(sizeof(struct label), M_MACPIPELABEL, M_ZERO|M_WAITOK); 1409 mac_init_label(label); 1410 pipe->pipe_label = label; 1411 pipe->pipe_peer->pipe_label = label; 1412 MAC_PERFORM(init_pipe, pipe, pipe->pipe_label); 1413#ifdef MAC_DEBUG 1414 atomic_add_int(&nmacpipes, 1); 1415#endif 1416} 1417 1418void 1419mac_destroy_pipe(struct pipe *pipe) 1420{ 1421 1422 MAC_PERFORM(destroy_pipe, pipe, pipe->pipe_label); 1423 mac_destroy_label(pipe->pipe_label); 1424 free(pipe->pipe_label, M_MACPIPELABEL); 1425#ifdef MAC_DEBUG 1426 atomic_subtract_int(&nmacpipes, 1); 1427#endif 1428} 1429 1430void 1431mac_init_bpfdesc(struct bpf_d *bpf_d) 1432{ 1433 1434 mac_init_label(&bpf_d->bd_label); 1435 MAC_PERFORM(init_bpfdesc, bpf_d, &bpf_d->bd_label); 1436#ifdef MAC_DEBUG 1437 atomic_add_int(&nmacbpfdescs, 1); 1438#endif 1439} 1440 1441void 1442mac_destroy_bpfdesc(struct bpf_d *bpf_d) 1443{ 1444 1445 MAC_PERFORM(destroy_bpfdesc, bpf_d, &bpf_d->bd_label); 1446 mac_destroy_label(&bpf_d->bd_label); 1447#ifdef MAC_DEBUG 1448 atomic_subtract_int(&nmacbpfdescs, 1); 1449#endif 1450} 1451 1452void 1453mac_init_mount(struct mount *mp) 1454{ 1455 1456 mac_init_label(&mp->mnt_mntlabel); 1457 mac_init_label(&mp->mnt_fslabel); 1458 MAC_PERFORM(init_mount, mp, &mp->mnt_mntlabel, &mp->mnt_fslabel); 1459#ifdef MAC_DEBUG 1460 atomic_add_int(&nmacmounts, 1); 1461#endif 1462} 1463 1464void 1465mac_destroy_mount(struct mount *mp) 1466{ 1467 1468 MAC_PERFORM(destroy_mount, mp, &mp->mnt_mntlabel, &mp->mnt_fslabel); 1469 mac_destroy_label(&mp->mnt_fslabel); 1470 mac_destroy_label(&mp->mnt_mntlabel); 1471#ifdef MAC_DEBUG 1472 atomic_subtract_int(&nmacmounts, 1); 1473#endif 1474} 1475 1476static void 1477mac_init_temp(struct label *label) 1478{ 1479 1480 mac_init_label(label); 1481 MAC_PERFORM(init_temp, label); 1482#ifdef MAC_DEBUG 1483 atomic_add_int(&nmactemp, 1); 1484#endif 1485} 1486 1487static void 1488mac_destroy_temp(struct label *label) 1489{ 1490 1491 MAC_PERFORM(destroy_temp, label); 1492 mac_destroy_label(label); 1493#ifdef MAC_DEBUG 1494 atomic_subtract_int(&nmactemp, 1); 1495#endif 1496} 1497 1498void 1499mac_init_vnode(struct vnode *vp) 1500{ 1501 1502 mac_init_label(&vp->v_label); 1503 MAC_PERFORM(init_vnode, vp, &vp->v_label); 1504#ifdef MAC_DEBUG 1505 atomic_add_int(&nmacvnodes, 1); 1506#endif 1507} 1508 1509void 1510mac_destroy_vnode(struct vnode *vp) 1511{ 1512 1513 MAC_PERFORM(destroy_vnode, vp, &vp->v_label); 1514 mac_destroy_label(&vp->v_label); 1515#ifdef MAC_DEBUG 1516 atomic_subtract_int(&nmacvnodes, 1); 1517#endif 1518} 1519 1520void 1521mac_init_devfsdirent(struct devfs_dirent *de) 1522{ 1523 1524 mac_init_label(&de->de_label); 1525 MAC_PERFORM(init_devfsdirent, de, &de->de_label); 1526#ifdef MAC_DEBUG 1527 atomic_add_int(&nmacdevfsdirents, 1); 1528#endif 1529} 1530 1531void 1532mac_destroy_devfsdirent(struct devfs_dirent *de) 1533{ 1534 1535 MAC_PERFORM(destroy_devfsdirent, de, &de->de_label); 1536 mac_destroy_label(&de->de_label); 1537#ifdef MAC_DEBUG 1538 atomic_subtract_int(&nmacdevfsdirents, 1); 1539#endif 1540} 1541 1542static int 1543mac_externalize(struct label *label, struct mac *mac) 1544{ 1545 int error; 1546 1547 mac_init_structmac(mac); 1548 MAC_CHECK(externalize, label, mac); 1549 1550 return (error); 1551} 1552 1553static int 1554mac_internalize(struct label *label, struct mac *mac) 1555{ 1556 int error; 1557 1558 mac_init_temp(label); 1559 MAC_CHECK(internalize, label, mac); 1560 if (error) 1561 mac_destroy_temp(label); 1562 1563 return (error); 1564} 1565 1566/* 1567 * Initialize MAC label for the first kernel process, from which other 1568 * kernel processes and threads are spawned. 1569 */ 1570void 1571mac_create_proc0(struct ucred *cred) 1572{ 1573 1574 MAC_PERFORM(create_proc0, cred); 1575} 1576 1577/* 1578 * Initialize MAC label for the first userland process, from which other 1579 * userland processes and threads are spawned. 1580 */ 1581void 1582mac_create_proc1(struct ucred *cred) 1583{ 1584 1585 MAC_PERFORM(create_proc1, cred); 1586} 1587 1588void 1589mac_thread_userret(struct thread *td) 1590{ 1591 1592 MAC_PERFORM(thread_userret, td); 1593} 1594 1595/* 1596 * When a new process is created, its label must be initialized. Generally, 1597 * this involves inheritence from the parent process, modulo possible 1598 * deltas. This function allows that processing to take place. 1599 */ 1600void 1601mac_create_cred(struct ucred *parent_cred, struct ucred *child_cred) 1602{ 1603 1604 MAC_PERFORM(create_cred, parent_cred, child_cred); 1605} 1606 1607int 1608mac_check_vnode_access(struct ucred *cred, struct vnode *vp, int flags) 1609{ 1610 int error; 1611 1612 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_access"); 1613 1614 if (!mac_enforce_fs) 1615 return (0); 1616 1617 error = vn_refreshlabel(vp, cred); 1618 if (error) 1619 return (error); 1620 1621 MAC_CHECK(check_vnode_access, cred, vp, &vp->v_label, flags); 1622 return (error); 1623} 1624 1625int 1626mac_check_vnode_chdir(struct ucred *cred, struct vnode *dvp) 1627{ 1628 int error; 1629 1630 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chdir"); 1631 1632 if (!mac_enforce_fs) 1633 return (0); 1634 1635 error = vn_refreshlabel(dvp, cred); 1636 if (error) 1637 return (error); 1638 1639 MAC_CHECK(check_vnode_chdir, cred, dvp, &dvp->v_label); 1640 return (error); 1641} 1642 1643int 1644mac_check_vnode_chroot(struct ucred *cred, struct vnode *dvp) 1645{ 1646 int error; 1647 1648 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chroot"); 1649 1650 if (!mac_enforce_fs) 1651 return (0); 1652 1653 error = vn_refreshlabel(dvp, cred); 1654 if (error) 1655 return (error); 1656 1657 MAC_CHECK(check_vnode_chroot, cred, dvp, &dvp->v_label); 1658 return (error); 1659} 1660 1661int 1662mac_check_vnode_create(struct ucred *cred, struct vnode *dvp, 1663 struct componentname *cnp, struct vattr *vap) 1664{ 1665 int error; 1666 1667 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_create"); 1668 1669 if (!mac_enforce_fs) 1670 return (0); 1671 1672 error = vn_refreshlabel(dvp, cred); 1673 if (error) 1674 return (error); 1675 1676 MAC_CHECK(check_vnode_create, cred, dvp, &dvp->v_label, cnp, vap); 1677 return (error); 1678} 1679 1680int 1681mac_check_vnode_delete(struct ucred *cred, struct vnode *dvp, struct vnode *vp, 1682 struct componentname *cnp) 1683{ 1684 int error; 1685 1686 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_delete"); 1687 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_delete"); 1688 1689 if (!mac_enforce_fs) 1690 return (0); 1691 1692 error = vn_refreshlabel(dvp, cred); 1693 if (error) 1694 return (error); 1695 error = vn_refreshlabel(vp, cred); 1696 if (error) 1697 return (error); 1698 1699 MAC_CHECK(check_vnode_delete, cred, dvp, &dvp->v_label, vp, 1700 &vp->v_label, cnp); 1701 return (error); 1702} 1703 1704int 1705mac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 1706 acl_type_t type) 1707{ 1708 int error; 1709 1710 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_deleteacl"); 1711 1712 if (!mac_enforce_fs) 1713 return (0); 1714 1715 error = vn_refreshlabel(vp, cred); 1716 if (error) 1717 return (error); 1718 1719 MAC_CHECK(check_vnode_deleteacl, cred, vp, &vp->v_label, type); 1720 return (error); 1721} 1722 1723int 1724mac_check_vnode_exec(struct ucred *cred, struct vnode *vp) 1725{ 1726 int error; 1727 1728 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_exec"); 1729 1730 if (!mac_enforce_process && !mac_enforce_fs) 1731 return (0); 1732 1733 error = vn_refreshlabel(vp, cred); 1734 if (error) 1735 return (error); 1736 MAC_CHECK(check_vnode_exec, cred, vp, &vp->v_label); 1737 1738 return (error); 1739} 1740 1741int 1742mac_check_vnode_getacl(struct ucred *cred, struct vnode *vp, acl_type_t type) 1743{ 1744 int error; 1745 1746 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getacl"); 1747 1748 if (!mac_enforce_fs) 1749 return (0); 1750 1751 error = vn_refreshlabel(vp, cred); 1752 if (error) 1753 return (error); 1754 1755 MAC_CHECK(check_vnode_getacl, cred, vp, &vp->v_label, type); 1756 return (error); 1757} 1758 1759int 1760mac_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 1761 int attrnamespace, const char *name, struct uio *uio) 1762{ 1763 int error; 1764 1765 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getextattr"); 1766 1767 if (!mac_enforce_fs) 1768 return (0); 1769 1770 error = vn_refreshlabel(vp, cred); 1771 if (error) 1772 return (error); 1773 1774 MAC_CHECK(check_vnode_getextattr, cred, vp, &vp->v_label, 1775 attrnamespace, name, uio); 1776 return (error); 1777} 1778 1779int 1780mac_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 1781 struct componentname *cnp) 1782{ 1783 int error; 1784 1785 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_lookup"); 1786 1787 if (!mac_enforce_fs) 1788 return (0); 1789 1790 error = vn_refreshlabel(dvp, cred); 1791 if (error) 1792 return (error); 1793 1794 MAC_CHECK(check_vnode_lookup, cred, dvp, &dvp->v_label, cnp); 1795 return (error); 1796} 1797 1798vm_prot_t 1799mac_check_vnode_mmap_prot(struct ucred *cred, struct vnode *vp, int newmapping) 1800{ 1801 vm_prot_t result = VM_PROT_ALL; 1802 1803 if (!mac_enforce_vm) 1804 return (result); 1805 1806 /* 1807 * This should be some sort of MAC_BITWISE, maybe :) 1808 */ 1809 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap_perms"); 1810 MAC_BOOLEAN(check_vnode_mmap_perms, &, cred, vp, &vp->v_label, 1811 newmapping); 1812 return (result); 1813} 1814 1815int 1816mac_check_vnode_open(struct ucred *cred, struct vnode *vp, mode_t acc_mode) 1817{ 1818 int error; 1819 1820 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_open"); 1821 1822 if (!mac_enforce_fs) 1823 return (0); 1824 1825 error = vn_refreshlabel(vp, cred); 1826 if (error) 1827 return (error); 1828 1829 MAC_CHECK(check_vnode_open, cred, vp, &vp->v_label, acc_mode); 1830 return (error); 1831} 1832 1833int 1834mac_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, 1835 struct vnode *vp) 1836{ 1837 int error; 1838 1839 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_poll"); 1840 1841 if (!mac_enforce_fs) 1842 return (0); 1843 1844 error = vn_refreshlabel(vp, active_cred); 1845 if (error) 1846 return (error); 1847 1848 MAC_CHECK(check_vnode_poll, active_cred, file_cred, vp, 1849 &vp->v_label); 1850 1851 return (error); 1852} 1853 1854int 1855mac_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 1856 struct vnode *vp) 1857{ 1858 int error; 1859 1860 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_read"); 1861 1862 if (!mac_enforce_fs) 1863 return (0); 1864 1865 error = vn_refreshlabel(vp, active_cred); 1866 if (error) 1867 return (error); 1868 1869 MAC_CHECK(check_vnode_read, active_cred, file_cred, vp, 1870 &vp->v_label); 1871 1872 return (error); 1873} 1874 1875int 1876mac_check_vnode_readdir(struct ucred *cred, struct vnode *dvp) 1877{ 1878 int error; 1879 1880 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_readdir"); 1881 1882 if (!mac_enforce_fs) 1883 return (0); 1884 1885 error = vn_refreshlabel(dvp, cred); 1886 if (error) 1887 return (error); 1888 1889 MAC_CHECK(check_vnode_readdir, cred, dvp, &dvp->v_label); 1890 return (error); 1891} 1892 1893int 1894mac_check_vnode_readlink(struct ucred *cred, struct vnode *vp) 1895{ 1896 int error; 1897 1898 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_readlink"); 1899 1900 if (!mac_enforce_fs) 1901 return (0); 1902 1903 error = vn_refreshlabel(vp, cred); 1904 if (error) 1905 return (error); 1906 1907 MAC_CHECK(check_vnode_readlink, cred, vp, &vp->v_label); 1908 return (error); 1909} 1910 1911static int 1912mac_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 1913 struct label *newlabel) 1914{ 1915 int error; 1916 1917 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_relabel"); 1918 1919 error = vn_refreshlabel(vp, cred); 1920 if (error) 1921 return (error); 1922 1923 MAC_CHECK(check_vnode_relabel, cred, vp, &vp->v_label, newlabel); 1924 1925 return (error); 1926} 1927 1928int 1929mac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 1930 struct vnode *vp, struct componentname *cnp) 1931{ 1932 int error; 1933 1934 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_from"); 1935 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_from"); 1936 1937 if (!mac_enforce_fs) 1938 return (0); 1939 1940 error = vn_refreshlabel(dvp, cred); 1941 if (error) 1942 return (error); 1943 error = vn_refreshlabel(vp, cred); 1944 if (error) 1945 return (error); 1946 1947 MAC_CHECK(check_vnode_rename_from, cred, dvp, &dvp->v_label, vp, 1948 &vp->v_label, cnp); 1949 return (error); 1950} 1951 1952int 1953mac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 1954 struct vnode *vp, int samedir, struct componentname *cnp) 1955{ 1956 int error; 1957 1958 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_to"); 1959 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_to"); 1960 1961 if (!mac_enforce_fs) 1962 return (0); 1963 1964 error = vn_refreshlabel(dvp, cred); 1965 if (error) 1966 return (error); 1967 if (vp != NULL) { 1968 error = vn_refreshlabel(vp, cred); 1969 if (error) 1970 return (error); 1971 } 1972 MAC_CHECK(check_vnode_rename_to, cred, dvp, &dvp->v_label, vp, 1973 vp != NULL ? &vp->v_label : NULL, samedir, cnp); 1974 return (error); 1975} 1976 1977int 1978mac_check_vnode_revoke(struct ucred *cred, struct vnode *vp) 1979{ 1980 int error; 1981 1982 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_revoke"); 1983 1984 if (!mac_enforce_fs) 1985 return (0); 1986 1987 error = vn_refreshlabel(vp, cred); 1988 if (error) 1989 return (error); 1990 1991 MAC_CHECK(check_vnode_revoke, cred, vp, &vp->v_label); 1992 return (error); 1993} 1994 1995int 1996mac_check_vnode_setacl(struct ucred *cred, struct vnode *vp, acl_type_t type, 1997 struct acl *acl) 1998{ 1999 int error; 2000 2001 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setacl"); 2002 2003 if (!mac_enforce_fs) 2004 return (0); 2005 2006 error = vn_refreshlabel(vp, cred); 2007 if (error) 2008 return (error); 2009 2010 MAC_CHECK(check_vnode_setacl, cred, vp, &vp->v_label, type, acl); 2011 return (error); 2012} 2013 2014int 2015mac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 2016 int attrnamespace, const char *name, struct uio *uio) 2017{ 2018 int error; 2019 2020 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setextattr"); 2021 2022 if (!mac_enforce_fs) 2023 return (0); 2024 2025 error = vn_refreshlabel(vp, cred); 2026 if (error) 2027 return (error); 2028 2029 MAC_CHECK(check_vnode_setextattr, cred, vp, &vp->v_label, 2030 attrnamespace, name, uio); 2031 return (error); 2032} 2033 2034int 2035mac_check_vnode_setflags(struct ucred *cred, struct vnode *vp, u_long flags) 2036{ 2037 int error; 2038 2039 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setflags"); 2040 2041 if (!mac_enforce_fs) 2042 return (0); 2043 2044 error = vn_refreshlabel(vp, cred); 2045 if (error) 2046 return (error); 2047 2048 MAC_CHECK(check_vnode_setflags, cred, vp, &vp->v_label, flags); 2049 return (error); 2050} 2051 2052int 2053mac_check_vnode_setmode(struct ucred *cred, struct vnode *vp, mode_t mode) 2054{ 2055 int error; 2056 2057 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setmode"); 2058 2059 if (!mac_enforce_fs) 2060 return (0); 2061 2062 error = vn_refreshlabel(vp, cred); 2063 if (error) 2064 return (error); 2065 2066 MAC_CHECK(check_vnode_setmode, cred, vp, &vp->v_label, mode); 2067 return (error); 2068} 2069 2070int 2071mac_check_vnode_setowner(struct ucred *cred, struct vnode *vp, uid_t uid, 2072 gid_t gid) 2073{ 2074 int error; 2075 2076 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setowner"); 2077 2078 if (!mac_enforce_fs) 2079 return (0); 2080 2081 error = vn_refreshlabel(vp, cred); 2082 if (error) 2083 return (error); 2084 2085 MAC_CHECK(check_vnode_setowner, cred, vp, &vp->v_label, uid, gid); 2086 return (error); 2087} 2088 2089int 2090mac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 2091 struct timespec atime, struct timespec mtime) 2092{ 2093 int error; 2094 2095 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setutimes"); 2096 2097 if (!mac_enforce_fs) 2098 return (0); 2099 2100 error = vn_refreshlabel(vp, cred); 2101 if (error) 2102 return (error); 2103 2104 MAC_CHECK(check_vnode_setutimes, cred, vp, &vp->v_label, atime, 2105 mtime); 2106 return (error); 2107} 2108 2109int 2110mac_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, 2111 struct vnode *vp) 2112{ 2113 int error; 2114 2115 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_stat"); 2116 2117 if (!mac_enforce_fs) 2118 return (0); 2119 2120 error = vn_refreshlabel(vp, active_cred); 2121 if (error) 2122 return (error); 2123 2124 MAC_CHECK(check_vnode_stat, active_cred, file_cred, vp, 2125 &vp->v_label); 2126 return (error); 2127} 2128 2129int 2130mac_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred, 2131 struct vnode *vp) 2132{ 2133 int error; 2134 2135 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_write"); 2136 2137 if (!mac_enforce_fs) 2138 return (0); 2139 2140 error = vn_refreshlabel(vp, active_cred); 2141 if (error) 2142 return (error); 2143 2144 MAC_CHECK(check_vnode_write, active_cred, file_cred, vp, 2145 &vp->v_label); 2146 2147 return (error); 2148} 2149 2150/* 2151 * When relabeling a process, call out to the policies for the maximum 2152 * permission allowed for each object type we know about in its 2153 * memory space, and revoke access (in the least surprising ways we 2154 * know) when necessary. The process lock is not held here. 2155 */ 2156static void 2157mac_cred_mmapped_drop_perms(struct thread *td, struct ucred *cred) 2158{ 2159 2160 /* XXX freeze all other threads */ 2161 mac_cred_mmapped_drop_perms_recurse(td, cred, 2162 &td->td_proc->p_vmspace->vm_map); 2163 /* XXX allow other threads to continue */ 2164} 2165 2166static __inline const char * 2167prot2str(vm_prot_t prot) 2168{ 2169 2170 switch (prot & VM_PROT_ALL) { 2171 case VM_PROT_READ: 2172 return ("r--"); 2173 case VM_PROT_READ | VM_PROT_WRITE: 2174 return ("rw-"); 2175 case VM_PROT_READ | VM_PROT_EXECUTE: 2176 return ("r-x"); 2177 case VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE: 2178 return ("rwx"); 2179 case VM_PROT_WRITE: 2180 return ("-w-"); 2181 case VM_PROT_EXECUTE: 2182 return ("--x"); 2183 case VM_PROT_WRITE | VM_PROT_EXECUTE: 2184 return ("-wx"); 2185 default: 2186 return ("---"); 2187 } 2188} 2189 2190static void 2191mac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred, 2192 struct vm_map *map) 2193{ 2194 struct vm_map_entry *vme; 2195 vm_prot_t result, revokeperms; 2196 vm_object_t object; 2197 vm_ooffset_t offset; 2198 struct vnode *vp; 2199 2200 if (!mac_mmap_revocation) 2201 return; 2202 2203 vm_map_lock_read(map); 2204 for (vme = map->header.next; vme != &map->header; vme = vme->next) { 2205 if (vme->eflags & MAP_ENTRY_IS_SUB_MAP) { 2206 mac_cred_mmapped_drop_perms_recurse(td, cred, 2207 vme->object.sub_map); 2208 continue; 2209 } 2210 /* 2211 * Skip over entries that obviously are not shared. 2212 */ 2213 if (vme->eflags & (MAP_ENTRY_COW | MAP_ENTRY_NOSYNC) || 2214 !vme->max_protection) 2215 continue; 2216 /* 2217 * Drill down to the deepest backing object. 2218 */ 2219 offset = vme->offset; 2220 object = vme->object.vm_object; 2221 if (object == NULL) 2222 continue; 2223 while (object->backing_object != NULL) { 2224 object = object->backing_object; 2225 offset += object->backing_object_offset; 2226 } 2227 /* 2228 * At the moment, vm_maps and objects aren't considered 2229 * by the MAC system, so only things with backing by a 2230 * normal object (read: vnodes) are checked. 2231 */ 2232 if (object->type != OBJT_VNODE) 2233 continue; 2234 vp = (struct vnode *)object->handle; 2235 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 2236 result = mac_check_vnode_mmap_prot(cred, vp, 0); 2237 VOP_UNLOCK(vp, 0, td); 2238 /* 2239 * Find out what maximum protection we may be allowing 2240 * now but a policy needs to get removed. 2241 */ 2242 revokeperms = vme->max_protection & ~result; 2243 if (!revokeperms) 2244 continue; 2245 printf("pid %ld: revoking %s perms from %#lx:%ld " 2246 "(max %s/cur %s)\n", (long)td->td_proc->p_pid, 2247 prot2str(revokeperms), (u_long)vme->start, 2248 (long)(vme->end - vme->start), 2249 prot2str(vme->max_protection), prot2str(vme->protection)); 2250 vm_map_lock_upgrade(map); 2251 /* 2252 * This is the really simple case: if a map has more 2253 * max_protection than is allowed, but it's not being 2254 * actually used (that is, the current protection is 2255 * still allowed), we can just wipe it out and do 2256 * nothing more. 2257 */ 2258 if ((vme->protection & revokeperms) == 0) { 2259 vme->max_protection -= revokeperms; 2260 } else { 2261 if (revokeperms & VM_PROT_WRITE) { 2262 /* 2263 * In the more complicated case, flush out all 2264 * pending changes to the object then turn it 2265 * copy-on-write. 2266 */ 2267 vm_object_reference(object); 2268 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 2269 vm_object_page_clean(object, 2270 OFF_TO_IDX(offset), 2271 OFF_TO_IDX(offset + vme->end - vme->start + 2272 PAGE_MASK), 2273 OBJPC_SYNC); 2274 VOP_UNLOCK(vp, 0, td); 2275 vm_object_deallocate(object); 2276 /* 2277 * Why bother if there's no read permissions 2278 * anymore? For the rest, we need to leave 2279 * the write permissions on for COW, or 2280 * remove them entirely if configured to. 2281 */ 2282 if (!mac_mmap_revocation_via_cow) { 2283 vme->max_protection &= ~VM_PROT_WRITE; 2284 vme->protection &= ~VM_PROT_WRITE; 2285 } if ((revokeperms & VM_PROT_READ) == 0) 2286 vme->eflags |= MAP_ENTRY_COW | 2287 MAP_ENTRY_NEEDS_COPY; 2288 } 2289 if (revokeperms & VM_PROT_EXECUTE) { 2290 vme->max_protection &= ~VM_PROT_EXECUTE; 2291 vme->protection &= ~VM_PROT_EXECUTE; 2292 } 2293 if (revokeperms & VM_PROT_READ) { 2294 vme->max_protection = 0; 2295 vme->protection = 0; 2296 } 2297 pmap_protect(map->pmap, vme->start, vme->end, 2298 vme->protection & ~revokeperms); 2299 vm_map_simplify_entry(map, vme); 2300 } 2301 vm_map_lock_downgrade(map); 2302 } 2303 vm_map_unlock_read(map); 2304} 2305 2306/* 2307 * When the subject's label changes, it may require revocation of privilege 2308 * to mapped objects. This can't be done on-the-fly later with a unified 2309 * buffer cache. 2310 */ 2311static void 2312mac_relabel_cred(struct ucred *cred, struct label *newlabel) 2313{ 2314 2315 MAC_PERFORM(relabel_cred, cred, newlabel); 2316} 2317 2318void 2319mac_relabel_vnode(struct ucred *cred, struct vnode *vp, struct label *newlabel) 2320{ 2321 2322 MAC_PERFORM(relabel_vnode, cred, vp, &vp->v_label, newlabel); 2323} 2324 2325void 2326mac_create_ifnet(struct ifnet *ifnet) 2327{ 2328 2329 MAC_PERFORM(create_ifnet, ifnet, &ifnet->if_label); 2330} 2331 2332void 2333mac_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d) 2334{ 2335 2336 MAC_PERFORM(create_bpfdesc, cred, bpf_d, &bpf_d->bd_label); 2337} 2338 2339void 2340mac_create_socket(struct ucred *cred, struct socket *socket) 2341{ 2342 2343 MAC_PERFORM(create_socket, cred, socket, &socket->so_label); 2344} 2345 2346void 2347mac_create_pipe(struct ucred *cred, struct pipe *pipe) 2348{ 2349 2350 MAC_PERFORM(create_pipe, cred, pipe, pipe->pipe_label); 2351} 2352 2353void 2354mac_create_socket_from_socket(struct socket *oldsocket, 2355 struct socket *newsocket) 2356{ 2357 2358 MAC_PERFORM(create_socket_from_socket, oldsocket, &oldsocket->so_label, 2359 newsocket, &newsocket->so_label); 2360} 2361 2362static void 2363mac_relabel_socket(struct ucred *cred, struct socket *socket, 2364 struct label *newlabel) 2365{ 2366 2367 MAC_PERFORM(relabel_socket, cred, socket, &socket->so_label, newlabel); 2368} 2369 2370static void 2371mac_relabel_pipe(struct ucred *cred, struct pipe *pipe, struct label *newlabel) 2372{ 2373 2374 MAC_PERFORM(relabel_pipe, cred, pipe, pipe->pipe_label, newlabel); 2375} 2376 2377void 2378mac_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct socket *socket) 2379{ 2380 2381 MAC_PERFORM(set_socket_peer_from_mbuf, mbuf, &mbuf->m_pkthdr.label, 2382 socket, &socket->so_peerlabel); 2383} 2384 2385void 2386mac_set_socket_peer_from_socket(struct socket *oldsocket, 2387 struct socket *newsocket) 2388{ 2389 2390 MAC_PERFORM(set_socket_peer_from_socket, oldsocket, 2391 &oldsocket->so_label, newsocket, &newsocket->so_peerlabel); 2392} 2393 2394void 2395mac_create_datagram_from_ipq(struct ipq *ipq, struct mbuf *datagram) 2396{ 2397 2398 MAC_PERFORM(create_datagram_from_ipq, ipq, &ipq->ipq_label, 2399 datagram, &datagram->m_pkthdr.label); 2400} 2401 2402void 2403mac_create_fragment(struct mbuf *datagram, struct mbuf *fragment) 2404{ 2405 2406 MAC_PERFORM(create_fragment, datagram, &datagram->m_pkthdr.label, 2407 fragment, &fragment->m_pkthdr.label); 2408} 2409 2410void 2411mac_create_ipq(struct mbuf *fragment, struct ipq *ipq) 2412{ 2413 2414 MAC_PERFORM(create_ipq, fragment, &fragment->m_pkthdr.label, ipq, 2415 &ipq->ipq_label); 2416} 2417 2418void 2419mac_create_mbuf_from_mbuf(struct mbuf *oldmbuf, struct mbuf *newmbuf) 2420{ 2421 2422 MAC_PERFORM(create_mbuf_from_mbuf, oldmbuf, &oldmbuf->m_pkthdr.label, 2423 newmbuf, &newmbuf->m_pkthdr.label); 2424} 2425 2426void 2427mac_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct mbuf *mbuf) 2428{ 2429 2430 MAC_PERFORM(create_mbuf_from_bpfdesc, bpf_d, &bpf_d->bd_label, mbuf, 2431 &mbuf->m_pkthdr.label); 2432} 2433 2434void 2435mac_create_mbuf_linklayer(struct ifnet *ifnet, struct mbuf *mbuf) 2436{ 2437 2438 MAC_PERFORM(create_mbuf_linklayer, ifnet, &ifnet->if_label, mbuf, 2439 &mbuf->m_pkthdr.label); 2440} 2441 2442void 2443mac_create_mbuf_from_ifnet(struct ifnet *ifnet, struct mbuf *mbuf) 2444{ 2445 2446 MAC_PERFORM(create_mbuf_from_ifnet, ifnet, &ifnet->if_label, mbuf, 2447 &mbuf->m_pkthdr.label); 2448} 2449 2450void 2451mac_create_mbuf_multicast_encap(struct mbuf *oldmbuf, struct ifnet *ifnet, 2452 struct mbuf *newmbuf) 2453{ 2454 2455 MAC_PERFORM(create_mbuf_multicast_encap, oldmbuf, 2456 &oldmbuf->m_pkthdr.label, ifnet, &ifnet->if_label, newmbuf, 2457 &newmbuf->m_pkthdr.label); 2458} 2459 2460void 2461mac_create_mbuf_netlayer(struct mbuf *oldmbuf, struct mbuf *newmbuf) 2462{ 2463 2464 MAC_PERFORM(create_mbuf_netlayer, oldmbuf, &oldmbuf->m_pkthdr.label, 2465 newmbuf, &newmbuf->m_pkthdr.label); 2466} 2467 2468int 2469mac_fragment_match(struct mbuf *fragment, struct ipq *ipq) 2470{ 2471 int result; 2472 2473 result = 1; 2474 MAC_BOOLEAN(fragment_match, &&, fragment, &fragment->m_pkthdr.label, 2475 ipq, &ipq->ipq_label); 2476 2477 return (result); 2478} 2479 2480void 2481mac_update_ipq(struct mbuf *fragment, struct ipq *ipq) 2482{ 2483 2484 MAC_PERFORM(update_ipq, fragment, &fragment->m_pkthdr.label, ipq, 2485 &ipq->ipq_label); 2486} 2487 2488void 2489mac_create_mbuf_from_socket(struct socket *socket, struct mbuf *mbuf) 2490{ 2491 2492 MAC_PERFORM(create_mbuf_from_socket, socket, &socket->so_label, mbuf, 2493 &mbuf->m_pkthdr.label); 2494} 2495 2496void 2497mac_create_mount(struct ucred *cred, struct mount *mp) 2498{ 2499 2500 MAC_PERFORM(create_mount, cred, mp, &mp->mnt_mntlabel, 2501 &mp->mnt_fslabel); 2502} 2503 2504void 2505mac_create_root_mount(struct ucred *cred, struct mount *mp) 2506{ 2507 2508 MAC_PERFORM(create_root_mount, cred, mp, &mp->mnt_mntlabel, 2509 &mp->mnt_fslabel); 2510} 2511 2512int 2513mac_check_bpfdesc_receive(struct bpf_d *bpf_d, struct ifnet *ifnet) 2514{ 2515 int error; 2516 2517 if (!mac_enforce_network) 2518 return (0); 2519 2520 MAC_CHECK(check_bpfdesc_receive, bpf_d, &bpf_d->bd_label, ifnet, 2521 &ifnet->if_label); 2522 2523 return (error); 2524} 2525 2526static int 2527mac_check_cred_relabel(struct ucred *cred, struct label *newlabel) 2528{ 2529 int error; 2530 2531 MAC_CHECK(check_cred_relabel, cred, newlabel); 2532 2533 return (error); 2534} 2535 2536int 2537mac_check_cred_visible(struct ucred *u1, struct ucred *u2) 2538{ 2539 int error; 2540 2541 if (!mac_enforce_process) 2542 return (0); 2543 2544 MAC_CHECK(check_cred_visible, u1, u2); 2545 2546 return (error); 2547} 2548 2549int 2550mac_check_ifnet_transmit(struct ifnet *ifnet, struct mbuf *mbuf) 2551{ 2552 int error; 2553 2554 if (!mac_enforce_network) 2555 return (0); 2556 2557 KASSERT(mbuf->m_flags & M_PKTHDR, ("packet has no pkthdr")); 2558 if (!(mbuf->m_pkthdr.label.l_flags & MAC_FLAG_INITIALIZED)) 2559 printf("%s%d: not initialized\n", ifnet->if_name, 2560 ifnet->if_unit); 2561 2562 MAC_CHECK(check_ifnet_transmit, ifnet, &ifnet->if_label, mbuf, 2563 &mbuf->m_pkthdr.label); 2564 2565 return (error); 2566} 2567 2568int 2569mac_check_mount_stat(struct ucred *cred, struct mount *mount) 2570{ 2571 int error; 2572 2573 if (!mac_enforce_fs) 2574 return (0); 2575 2576 MAC_CHECK(check_mount_stat, cred, mount, &mount->mnt_mntlabel); 2577 2578 return (error); 2579} 2580 2581int 2582mac_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe, unsigned long cmd, 2583 void *data) 2584{ 2585 int error; 2586 2587 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2588 2589 if (!mac_enforce_pipe) 2590 return (0); 2591 2592 MAC_CHECK(check_pipe_ioctl, cred, pipe, pipe->pipe_label, cmd, data); 2593 2594 return (error); 2595} 2596 2597int 2598mac_check_pipe_poll(struct ucred *cred, struct pipe *pipe) 2599{ 2600 int error; 2601 2602 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2603 2604 if (!mac_enforce_pipe) 2605 return (0); 2606 2607 MAC_CHECK(check_pipe_poll, cred, pipe, pipe->pipe_label); 2608 2609 return (error); 2610} 2611 2612int 2613mac_check_pipe_read(struct ucred *cred, struct pipe *pipe) 2614{ 2615 int error; 2616 2617 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2618 2619 if (!mac_enforce_pipe) 2620 return (0); 2621 2622 MAC_CHECK(check_pipe_read, cred, pipe, pipe->pipe_label); 2623 2624 return (error); 2625} 2626 2627static int 2628mac_check_pipe_relabel(struct ucred *cred, struct pipe *pipe, 2629 struct label *newlabel) 2630{ 2631 int error; 2632 2633 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2634 2635 if (!mac_enforce_pipe) 2636 return (0); 2637 2638 MAC_CHECK(check_pipe_relabel, cred, pipe, pipe->pipe_label, newlabel); 2639 2640 return (error); 2641} 2642 2643int 2644mac_check_pipe_stat(struct ucred *cred, struct pipe *pipe) 2645{ 2646 int error; 2647 2648 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2649 2650 if (!mac_enforce_pipe) 2651 return (0); 2652 2653 MAC_CHECK(check_pipe_stat, cred, pipe, pipe->pipe_label); 2654 2655 return (error); 2656} 2657 2658int 2659mac_check_pipe_write(struct ucred *cred, struct pipe *pipe) 2660{ 2661 int error; 2662 2663 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2664 2665 if (!mac_enforce_pipe) 2666 return (0); 2667 2668 MAC_CHECK(check_pipe_write, cred, pipe, pipe->pipe_label); 2669 2670 return (error); 2671} 2672 2673int 2674mac_check_proc_debug(struct ucred *cred, struct proc *proc) 2675{ 2676 int error; 2677 2678 PROC_LOCK_ASSERT(proc, MA_OWNED); 2679 2680 if (!mac_enforce_process) 2681 return (0); 2682 2683 MAC_CHECK(check_proc_debug, cred, proc); 2684 2685 return (error); 2686} 2687 2688int 2689mac_check_proc_sched(struct ucred *cred, struct proc *proc) 2690{ 2691 int error; 2692 2693 PROC_LOCK_ASSERT(proc, MA_OWNED); 2694 2695 if (!mac_enforce_process) 2696 return (0); 2697 2698 MAC_CHECK(check_proc_sched, cred, proc); 2699 2700 return (error); 2701} 2702 2703int 2704mac_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) 2705{ 2706 int error; 2707 2708 PROC_LOCK_ASSERT(proc, MA_OWNED); 2709 2710 if (!mac_enforce_process) 2711 return (0); 2712 2713 MAC_CHECK(check_proc_signal, cred, proc, signum); 2714 2715 return (error); 2716} 2717 2718int 2719mac_check_socket_bind(struct ucred *ucred, struct socket *socket, 2720 struct sockaddr *sockaddr) 2721{ 2722 int error; 2723 2724 if (!mac_enforce_socket) 2725 return (0); 2726 2727 MAC_CHECK(check_socket_bind, ucred, socket, &socket->so_label, 2728 sockaddr); 2729 2730 return (error); 2731} 2732 2733int 2734mac_check_socket_connect(struct ucred *cred, struct socket *socket, 2735 struct sockaddr *sockaddr) 2736{ 2737 int error; 2738 2739 if (!mac_enforce_socket) 2740 return (0); 2741 2742 MAC_CHECK(check_socket_connect, cred, socket, &socket->so_label, 2743 sockaddr); 2744 2745 return (error); 2746} 2747 2748int 2749mac_check_socket_deliver(struct socket *socket, struct mbuf *mbuf) 2750{ 2751 int error; 2752 2753 if (!mac_enforce_socket) 2754 return (0); 2755 2756 MAC_CHECK(check_socket_deliver, socket, &socket->so_label, mbuf, 2757 &mbuf->m_pkthdr.label); 2758 2759 return (error); 2760} 2761 2762int 2763mac_check_socket_listen(struct ucred *cred, struct socket *socket) 2764{ 2765 int error; 2766 2767 if (!mac_enforce_socket) 2768 return (0); 2769 2770 MAC_CHECK(check_socket_listen, cred, socket, &socket->so_label); 2771 return (error); 2772} 2773 2774static int 2775mac_check_socket_relabel(struct ucred *cred, struct socket *socket, 2776 struct label *newlabel) 2777{ 2778 int error; 2779 2780 MAC_CHECK(check_socket_relabel, cred, socket, &socket->so_label, 2781 newlabel); 2782 2783 return (error); 2784} 2785 2786int 2787mac_check_socket_visible(struct ucred *cred, struct socket *socket) 2788{ 2789 int error; 2790 2791 if (!mac_enforce_socket) 2792 return (0); 2793 2794 MAC_CHECK(check_socket_visible, cred, socket, &socket->so_label); 2795 2796 return (error); 2797} 2798 2799int 2800mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr, 2801 struct ifnet *ifnet) 2802{ 2803 struct mac label; 2804 int error; 2805 2806 error = mac_externalize(&ifnet->if_label, &label); 2807 if (error) 2808 return (error); 2809 2810 return (copyout(&label, ifr->ifr_ifru.ifru_data, sizeof(label))); 2811} 2812 2813int 2814mac_ioctl_ifnet_set(struct ucred *cred, struct ifreq *ifr, 2815 struct ifnet *ifnet) 2816{ 2817 struct mac newlabel; 2818 struct label intlabel; 2819 int error; 2820 2821 error = copyin(ifr->ifr_ifru.ifru_data, &newlabel, sizeof(newlabel)); 2822 if (error) 2823 return (error); 2824 2825 error = mac_internalize(&intlabel, &newlabel); 2826 if (error) 2827 return (error); 2828 2829 /* 2830 * XXX: Note that this is a redundant privilege check, since 2831 * policies impose this check themselves if required by the 2832 * policy. Eventually, this should go away. 2833 */ 2834 error = suser_cred(cred, 0); 2835 if (error) 2836 goto out; 2837 2838 MAC_CHECK(check_ifnet_relabel, cred, ifnet, &ifnet->if_label, 2839 &intlabel); 2840 if (error) 2841 goto out; 2842 2843 MAC_PERFORM(relabel_ifnet, cred, ifnet, &ifnet->if_label, &intlabel); 2844 2845out: 2846 mac_destroy_temp(&intlabel); 2847 return (error); 2848} 2849 2850void 2851mac_create_devfs_vnode(struct devfs_dirent *de, struct vnode *vp) 2852{ 2853 2854 MAC_PERFORM(create_devfs_vnode, de, &de->de_label, vp, &vp->v_label); 2855} 2856 2857void 2858mac_create_devfs_device(dev_t dev, struct devfs_dirent *de) 2859{ 2860 2861 MAC_PERFORM(create_devfs_device, dev, de, &de->de_label); 2862} 2863 2864static int 2865mac_stdcreatevnode_ea(struct vnode *vp) 2866{ 2867 int error; 2868 2869 MAC_CHECK(stdcreatevnode_ea, vp, &vp->v_label); 2870 2871 return (error); 2872} 2873 2874void 2875mac_create_devfs_directory(char *dirname, int dirnamelen, 2876 struct devfs_dirent *de) 2877{ 2878 2879 MAC_PERFORM(create_devfs_directory, dirname, dirnamelen, de, 2880 &de->de_label); 2881} 2882 2883/* 2884 * When a new vnode is created, this call will initialize its label. 2885 */ 2886void 2887mac_create_vnode(struct ucred *cred, struct vnode *parent, 2888 struct vnode *child) 2889{ 2890 int error; 2891 2892 ASSERT_VOP_LOCKED(parent, "mac_create_vnode"); 2893 ASSERT_VOP_LOCKED(child, "mac_create_vnode"); 2894 2895 error = vn_refreshlabel(parent, cred); 2896 if (error) { 2897 printf("mac_create_vnode: vn_refreshlabel returned %d\n", 2898 error); 2899 printf("mac_create_vnode: using old vnode label\n"); 2900 } 2901 2902 MAC_PERFORM(create_vnode, cred, parent, &parent->v_label, child, 2903 &child->v_label); 2904} 2905 2906int 2907mac_setsockopt_label_set(struct ucred *cred, struct socket *so, 2908 struct mac *extmac) 2909{ 2910 struct label intlabel; 2911 int error; 2912 2913 error = mac_internalize(&intlabel, extmac); 2914 if (error) 2915 return (error); 2916 2917 mac_check_socket_relabel(cred, so, &intlabel); 2918 if (error) { 2919 mac_destroy_temp(&intlabel); 2920 return (error); 2921 } 2922 2923 mac_relabel_socket(cred, so, &intlabel); 2924 2925 mac_destroy_temp(&intlabel); 2926 return (0); 2927} 2928 2929int 2930mac_pipe_label_set(struct ucred *cred, struct pipe *pipe, struct label *label) 2931{ 2932 int error; 2933 2934 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2935 2936 error = mac_check_pipe_relabel(cred, pipe, label); 2937 if (error) 2938 return (error); 2939 2940 mac_relabel_pipe(cred, pipe, label); 2941 2942 return (0); 2943} 2944 2945int 2946mac_getsockopt_label_get(struct ucred *cred, struct socket *so, 2947 struct mac *extmac) 2948{ 2949 2950 return (mac_externalize(&so->so_label, extmac)); 2951} 2952 2953int 2954mac_getsockopt_peerlabel_get(struct ucred *cred, struct socket *so, 2955 struct mac *extmac) 2956{ 2957 2958 return (mac_externalize(&so->so_peerlabel, extmac)); 2959} 2960 2961/* 2962 * Implementation of VOP_SETLABEL() that relies on extended attributes 2963 * to store label data. Can be referenced by filesystems supporting 2964 * extended attributes. 2965 */ 2966int 2967vop_stdsetlabel_ea(struct vop_setlabel_args *ap) 2968{ 2969 struct vnode *vp = ap->a_vp; 2970 struct label *intlabel = ap->a_label; 2971 struct mac extmac; 2972 int error; 2973 2974 ASSERT_VOP_LOCKED(vp, "vop_stdsetlabel_ea"); 2975 2976 /* 2977 * XXX: Eventually call out to EA check/set calls here. 2978 * Be particularly careful to avoid race conditions, 2979 * consistency problems, and stability problems when 2980 * dealing with multiple EAs. In particular, we require 2981 * the ability to write multiple EAs on the same file in 2982 * a single transaction, which the current EA interface 2983 * does not provide. 2984 */ 2985 2986 error = mac_externalize(intlabel, &extmac); 2987 if (error) 2988 return (error); 2989 2990 error = vn_extattr_set(vp, IO_NODELOCKED, 2991 FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME, 2992 sizeof(extmac), (char *)&extmac, curthread); 2993 if (error) 2994 return (error); 2995 2996 mac_relabel_vnode(ap->a_cred, vp, intlabel); 2997 2998 vp->v_vflag |= VV_CACHEDLABEL; 2999 3000 return (0); 3001} 3002 3003static int 3004vn_setlabel(struct vnode *vp, struct label *intlabel, struct ucred *cred) 3005{ 3006 int error; 3007 3008 if (vp->v_mount == NULL) { 3009 /* printf("vn_setlabel: null v_mount\n"); */ 3010 if (vp->v_type != VNON) 3011 printf("vn_setlabel: null v_mount with non-VNON\n"); 3012 return (EBADF); 3013 } 3014 3015 if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) 3016 return (EOPNOTSUPP); 3017 3018 /* 3019 * Multi-phase commit. First check the policies to confirm the 3020 * change is OK. Then commit via the filesystem. Finally, 3021 * update the actual vnode label. Question: maybe the filesystem 3022 * should update the vnode at the end as part of VOP_SETLABEL()? 3023 */ 3024 error = mac_check_vnode_relabel(cred, vp, intlabel); 3025 if (error) 3026 return (error); 3027 3028 /* 3029 * VADMIN provides the opportunity for the filesystem to make 3030 * decisions about who is and is not able to modify labels 3031 * and protections on files. This might not be right. We can't 3032 * assume VOP_SETLABEL() will do it, because we might implement 3033 * that as part of vop_stdsetlabel_ea(). 3034 */ 3035 error = VOP_ACCESS(vp, VADMIN, cred, curthread); 3036 if (error) 3037 return (error); 3038 3039 error = VOP_SETLABEL(vp, intlabel, cred, curthread); 3040 if (error) 3041 return (error); 3042 3043 return (0); 3044} 3045 3046/* 3047 * MPSAFE 3048 */ 3049int 3050__mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap) 3051{ 3052 struct mac extmac; 3053 int error; 3054 3055 error = mac_externalize(&td->td_ucred->cr_label, &extmac); 3056 if (error == 0) 3057 error = copyout(&extmac, SCARG(uap, mac_p), sizeof(extmac)); 3058 3059 return (error); 3060} 3061 3062/* 3063 * MPSAFE 3064 */ 3065int 3066__mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) 3067{ 3068 struct ucred *newcred, *oldcred; 3069 struct proc *p; 3070 struct mac extmac; 3071 struct label intlabel; 3072 int error; 3073 3074 error = copyin(SCARG(uap, mac_p), &extmac, sizeof(extmac)); 3075 if (error) 3076 return (error); 3077 3078 error = mac_internalize(&intlabel, &extmac); 3079 if (error) 3080 return (error); 3081 3082 newcred = crget(); 3083 3084 p = td->td_proc; 3085 PROC_LOCK(p); 3086 oldcred = p->p_ucred; 3087 3088 error = mac_check_cred_relabel(oldcred, &intlabel); 3089 if (error) { 3090 PROC_UNLOCK(p); 3091 mac_destroy_temp(&intlabel); 3092 crfree(newcred); 3093 return (error); 3094 } 3095 3096 setsugid(p); 3097 crcopy(newcred, oldcred); 3098 mac_relabel_cred(newcred, &intlabel); 3099 p->p_ucred = newcred; 3100 3101 /* 3102 * Grab additional reference for use while revoking mmaps, prior 3103 * to releasing the proc lock and sharing the cred. 3104 */ 3105 crhold(newcred); 3106 PROC_UNLOCK(p); 3107 3108 mtx_lock(&Giant); 3109 mac_cred_mmapped_drop_perms(td, newcred); 3110 mtx_unlock(&Giant); 3111 3112 crfree(newcred); /* Free revocation reference. */ 3113 crfree(oldcred); 3114 mac_destroy_temp(&intlabel); 3115 return (0); 3116} 3117 3118/* 3119 * MPSAFE 3120 */ 3121int 3122__mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) 3123{ 3124 struct file *fp; 3125 struct mac extmac; 3126 struct vnode *vp; 3127 struct pipe *pipe; 3128 int error; 3129 3130 mtx_lock(&Giant); 3131 3132 error = fget(td, SCARG(uap, fd), &fp); 3133 if (error) 3134 goto out; 3135 3136 switch (fp->f_type) { 3137 case DTYPE_FIFO: 3138 case DTYPE_VNODE: 3139 vp = (struct vnode *)fp->f_data; 3140 3141 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 3142 error = vn_refreshlabel(vp, td->td_ucred); 3143 if (error == 0) 3144 error = mac_externalize(&vp->v_label, &extmac); 3145 VOP_UNLOCK(vp, 0, td); 3146 break; 3147 case DTYPE_PIPE: 3148 pipe = (struct pipe *)fp->f_data; 3149 error = mac_externalize(pipe->pipe_label, &extmac); 3150 break; 3151 default: 3152 error = EINVAL; 3153 } 3154 3155 if (error == 0) 3156 error = copyout(&extmac, SCARG(uap, mac_p), sizeof(extmac)); 3157 3158 fdrop(fp, td); 3159 3160out: 3161 mtx_unlock(&Giant); 3162 return (error); 3163} 3164 3165/* 3166 * MPSAFE 3167 */ 3168int 3169__mac_get_file(struct thread *td, struct __mac_get_file_args *uap) 3170{ 3171 struct nameidata nd; 3172 struct mac extmac; 3173 int error; 3174 3175 mtx_lock(&Giant); 3176 NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, 3177 SCARG(uap, path_p), td); 3178 error = namei(&nd); 3179 if (error) 3180 goto out; 3181 3182 error = vn_refreshlabel(nd.ni_vp, td->td_ucred); 3183 if (error == 0) 3184 error = mac_externalize(&nd.ni_vp->v_label, &extmac); 3185 NDFREE(&nd, 0); 3186 if (error) 3187 goto out; 3188 3189 error = copyout(&extmac, SCARG(uap, mac_p), sizeof(extmac)); 3190 3191out: 3192 mtx_unlock(&Giant); 3193 return (error); 3194} 3195 3196/* 3197 * MPSAFE 3198 */ 3199int 3200__mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) 3201{ 3202 struct file *fp; 3203 struct mac extmac; 3204 struct label intlabel; 3205 struct mount *mp; 3206 struct vnode *vp; 3207 struct pipe *pipe; 3208 int error; 3209 3210 mtx_lock(&Giant); 3211 error = fget(td, SCARG(uap, fd), &fp); 3212 if (error) 3213 goto out1; 3214 3215 error = copyin(SCARG(uap, mac_p), &extmac, sizeof(extmac)); 3216 if (error) 3217 goto out2; 3218 3219 error = mac_internalize(&intlabel, &extmac); 3220 if (error) 3221 goto out2; 3222 3223 switch (fp->f_type) { 3224 case DTYPE_FIFO: 3225 case DTYPE_VNODE: 3226 vp = (struct vnode *)fp->f_data; 3227 error = vn_start_write(vp, &mp, V_WAIT | PCATCH); 3228 if (error != 0) 3229 break; 3230 3231 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 3232 error = vn_setlabel(vp, &intlabel, td->td_ucred); 3233 VOP_UNLOCK(vp, 0, td); 3234 vn_finished_write(mp); 3235 mac_destroy_temp(&intlabel); 3236 break; 3237 case DTYPE_PIPE: 3238 pipe = (struct pipe *)fp->f_data; 3239 PIPE_LOCK(pipe); 3240 error = mac_pipe_label_set(td->td_ucred, pipe, &intlabel); 3241 PIPE_UNLOCK(pipe); 3242 break; 3243 default: 3244 error = EINVAL; 3245 } 3246 3247out2: 3248 fdrop(fp, td); 3249out1: 3250 mtx_unlock(&Giant); 3251 return (error); 3252} 3253 3254/* 3255 * MPSAFE 3256 */ 3257int 3258__mac_set_file(struct thread *td, struct __mac_set_file_args *uap) 3259{ 3260 struct nameidata nd; 3261 struct mac extmac; 3262 struct label intlabel; 3263 struct mount *mp; 3264 int error; 3265 3266 mtx_lock(&Giant); 3267 3268 error = copyin(SCARG(uap, mac_p), &extmac, sizeof(extmac)); 3269 if (error) 3270 goto out; 3271 3272 error = mac_internalize(&intlabel, &extmac); 3273 if (error) 3274 goto out; 3275 3276 NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, 3277 SCARG(uap, path_p), td); 3278 error = namei(&nd); 3279 if (error) 3280 goto out2; 3281 error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); 3282 if (error) 3283 goto out2; 3284 3285 error = vn_setlabel(nd.ni_vp, &intlabel, td->td_ucred); 3286 3287 vn_finished_write(mp); 3288out2: 3289 mac_destroy_temp(&intlabel); 3290 NDFREE(&nd, 0); 3291out: 3292 mtx_unlock(&Giant); 3293 return (error); 3294} 3295 3296int 3297mac_syscall(struct thread *td, struct mac_syscall_args *uap) 3298{ 3299 struct mac_policy_conf *mpc; 3300 char target[MAC_MAX_POLICY_NAME]; 3301 int error; 3302 3303 error = copyinstr(SCARG(uap, policy), target, sizeof(target), NULL); 3304 if (error) 3305 return (error); 3306 3307 error = ENOSYS; 3308 MAC_POLICY_LIST_BUSY(); 3309 LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { 3310 if (strcmp(mpc->mpc_name, target) == 0 && 3311 mpc->mpc_ops->mpo_syscall != NULL) { 3312 error = mpc->mpc_ops->mpo_syscall(td, 3313 SCARG(uap, call), SCARG(uap, arg)); 3314 goto out; 3315 } 3316 } 3317 3318out: 3319 MAC_POLICY_LIST_UNBUSY(); 3320 return (error); 3321} 3322 3323SYSINIT(mac, SI_SUB_MAC, SI_ORDER_FIRST, mac_init, NULL); 3324SYSINIT(mac_late, SI_SUB_MAC_LATE, SI_ORDER_FIRST, mac_late_init, NULL); 3325 3326#else /* !MAC */ 3327 3328int 3329__mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap) 3330{ 3331 3332 return (ENOSYS); 3333} 3334 3335int 3336__mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) 3337{ 3338 3339 return (ENOSYS); 3340} 3341 3342int 3343__mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) 3344{ 3345 3346 return (ENOSYS); 3347} 3348 3349int 3350__mac_get_file(struct thread *td, struct __mac_get_file_args *uap) 3351{ 3352 3353 return (ENOSYS); 3354} 3355 3356int 3357__mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) 3358{ 3359 3360 return (ENOSYS); 3361} 3362 3363int 3364__mac_set_file(struct thread *td, struct __mac_set_file_args *uap) 3365{ 3366 3367 return (ENOSYS); 3368} 3369 3370int 3371mac_syscall(struct thread *td, struct mac_syscall_args *uap) 3372{ 3373 3374 return (ENOSYS); 3375} 3376 3377#endif /* !MAC */ 3378