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