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