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