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