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