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