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