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