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