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