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