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