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