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