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