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