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