1/* 2 * Copyright (c) 2007 Apple Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28/*- 29 * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson 30 * Copyright (c) 2001 Ilmar S. Habibulin 31 * Copyright (c) 2001, 2002, 2003, 2004 Networks Associates Technology, Inc. 32 * Copyright (c) 2005 SPARTA, Inc. 33 * 34 * This software was developed by Robert Watson and Ilmar Habibulin for the 35 * TrustedBSD Project. 36 * 37 * This software was developed for the FreeBSD Project in part by Network 38 * Associates Laboratories, the Security Research Division of Network 39 * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), 40 * as part of the DARPA CHATS research program. 41 * 42 * Redistribution and use in source and binary forms, with or without 43 * modification, are permitted provided that the following conditions 44 * are met: 45 * 1. Redistributions of source code must retain the above copyright 46 * notice, this list of conditions and the following disclaimer. 47 * 2. Redistributions in binary form must reproduce the above copyright 48 * notice, this list of conditions and the following disclaimer in the 49 * documentation and/or other materials provided with the distribution. 50 * 51 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 52 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 53 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 54 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 55 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 56 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 57 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 58 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 59 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 60 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 61 * SUCH DAMAGE. 62 * 63 */ 64 65#include <sys/param.h> 66#include <sys/systm.h> 67#include <sys/kernel.h> 68#include <sys/proc.h> 69#include <sys/kauth.h> 70 71#include <sys/file_internal.h> 72#include <sys/imgact.h> 73#include <sys/namei.h> 74#include <sys/mount_internal.h> 75#include <sys/pipe.h> 76#include <sys/posix_sem.h> 77#include <sys/posix_shm.h> 78#include <sys/uio_internal.h> 79#include <sys/vnode_internal.h> 80 81#include <miscfs/devfs/devfsdefs.h> 82#include <miscfs/devfs/fdesc.h> 83 84#include <security/mac_internal.h> 85 86/* convert {R,W,X}_OK values to V{READ,WRITE,EXEC} */ 87#define ACCESS_MODE_TO_VNODE_MASK(m) (m << 6) 88 89static struct label * 90mac_devfsdirent_label_alloc(void) 91{ 92 struct label *label; 93 94 label = mac_labelzone_alloc(MAC_WAITOK); 95 if (label == NULL) 96 return (NULL); 97 MAC_PERFORM(devfs_label_init, label); 98 return (label); 99} 100 101void 102mac_devfs_label_init(struct devnode *de) 103{ 104 105 de->dn_label = mac_devfsdirent_label_alloc(); 106} 107 108static struct label * 109mac_mount_label_alloc(void) 110{ 111 struct label *label; 112 113 label = mac_labelzone_alloc(MAC_WAITOK); 114 if (label == NULL) 115 return (NULL); 116 MAC_PERFORM(mount_label_init, label); 117 return (label); 118} 119 120void 121mac_mount_label_init(struct mount *mp) 122{ 123 124 mp->mnt_mntlabel = mac_mount_label_alloc(); 125} 126 127struct label * 128mac_vnode_label_alloc(void) 129{ 130 struct label *label; 131 132 label = mac_labelzone_alloc(MAC_WAITOK); 133 if (label == NULL) 134 return (NULL); 135 MAC_PERFORM(vnode_label_init, label); 136 return (label); 137} 138 139void 140mac_vnode_label_init(vnode_t vp) 141{ 142 vp->v_label = mac_vnode_label_alloc(); 143} 144 145int 146mac_vnode_label_init_needed(vnode_t vp) 147{ 148 return (mac_label_vnodes != 0 && vp->v_label == NULL); 149} 150 151/* 152 * vnode labels are allocated at the same time as vnodes, but vnodes are never 153 * freed. Instead, we want to remove any sensitive information before putting 154 * them on the free list for reuse. 155*/ 156void 157mac_vnode_label_recycle(vnode_t vp) 158{ 159 160 MAC_PERFORM(vnode_label_recycle, vp->v_label); 161} 162 163static void 164mac_devfs_label_free(struct label *label) 165{ 166 MAC_PERFORM(devfs_label_destroy, label); 167 mac_labelzone_free(label); 168} 169 170void 171mac_devfs_label_destroy(struct devnode *de) 172{ 173 if (de->dn_label != NULL) { 174 mac_devfs_label_free(de->dn_label); 175 de->dn_label = NULL; 176 } 177} 178 179static void 180mac_mount_label_free(struct label *label) 181{ 182 183 MAC_PERFORM(mount_label_destroy, label); 184 mac_labelzone_free(label); 185} 186 187void 188mac_mount_label_destroy(struct mount *mp) 189{ 190 if (mp->mnt_mntlabel != NULL) { 191 mac_mount_label_free(mp->mnt_mntlabel); 192 mp->mnt_mntlabel = NULL; 193 } 194} 195 196void 197mac_vnode_label_free(struct label *label) 198{ 199 MAC_PERFORM(vnode_label_destroy, label); 200 mac_labelzone_free(label); 201} 202 203#ifndef __APPLE__ 204void 205mac_vnode_label_destroy(struct vnode *vp) 206{ 207 if (vp->v_label != NULL) { 208 mac_vnode_label_free(vp->v_label); 209 vp->v_label = NULL; 210 } 211} 212#endif 213 214void 215mac_vnode_label_copy(struct label *src, struct label *dest) 216{ 217 if (src == NULL) { 218 MAC_PERFORM(vnode_label_init, dest); 219 } else { 220 MAC_PERFORM(vnode_label_copy, src, dest); 221 } 222} 223 224int 225mac_vnode_label_externalize_audit(struct vnode *vp, struct mac *mac) 226{ 227 int error; 228 229 /* It is assumed that any necessary vnode locking is done on entry */ 230 error = MAC_EXTERNALIZE_AUDIT(vnode, vp->v_label, 231 mac->m_string, mac->m_buflen); 232 233 return (error); 234} 235 236int 237mac_vnode_label_externalize(struct label *label, char *elements, 238 char *outbuf, size_t outbuflen, int flags __unused) 239{ 240 int error; 241 242 error = MAC_EXTERNALIZE(vnode, label, elements, outbuf, outbuflen); 243 244 return (error); 245} 246 247int 248mac_vnode_label_internalize(struct label *label, char *string) 249{ 250 int error; 251 252 error = MAC_INTERNALIZE(vnode, label, string); 253 254 return (error); 255} 256 257int 258mac_mount_label_internalize(struct label *label, char *string) 259{ 260 int error; 261 262 error = MAC_INTERNALIZE(mount, label, string); 263 264 return (error); 265} 266 267int 268mac_mount_label_externalize(struct label *label, char *elements, 269 char *outbuf, size_t outbuflen) 270{ 271 int error; 272 273 error = MAC_EXTERNALIZE(mount, label, elements, outbuf, outbuflen); 274 275 return (error); 276} 277 278void 279mac_devfs_label_copy(struct label *src, struct label *dest) 280{ 281 if (!mac_device_enforce) 282 return; 283 284 MAC_PERFORM(devfs_label_copy, src, dest); 285} 286 287void 288mac_devfs_label_update(struct mount *mp, struct devnode *de, 289 struct vnode *vp) 290{ 291 292 if (!mac_device_enforce) 293 return; 294 295 MAC_PERFORM(devfs_label_update, mp, de, de->dn_label, vp, 296 vp->v_label); 297} 298 299int 300mac_vnode_label_associate(struct mount *mp, struct vnode *vp, vfs_context_t ctx) 301{ 302 struct devnode *dnp; 303 struct fdescnode *fnp; 304 int error = 0; 305 306 if (!mac_vnode_enforce) 307 return (error); 308 309 /* XXX: should not inspect v_tag in kernel! */ 310 switch (vp->v_tag) { 311 case VT_DEVFS: 312 dnp = VTODN(vp); 313 mac_vnode_label_associate_devfs(mp, dnp, vp); 314 break; 315 case VT_FDESC: 316 fnp = VTOFDESC(vp); 317 error = mac_vnode_label_associate_fdesc(mp, fnp, vp, ctx); 318 break; 319 default: 320 error = mac_vnode_label_associate_extattr(mp, vp); 321 break; 322 } 323 324 return (error); 325} 326 327void 328mac_vnode_label_associate_devfs(struct mount *mp, struct devnode *de, 329 struct vnode *vp) 330{ 331 if (!mac_device_enforce) 332 return; 333 334 MAC_PERFORM(vnode_label_associate_devfs, 335 mp, mp ? mp->mnt_mntlabel : NULL, 336 de, de->dn_label, 337 vp, vp->v_label); 338} 339 340int 341mac_vnode_label_associate_extattr(struct mount *mp, struct vnode *vp) 342{ 343 int error; 344 345 MAC_CHECK(vnode_label_associate_extattr, mp, mp->mnt_mntlabel, vp, 346 vp->v_label); 347 348 return (error); 349} 350 351void 352mac_vnode_label_associate_singlelabel(struct mount *mp, struct vnode *vp) 353{ 354 355 if (!mac_vnode_enforce || !mac_label_vnodes) 356 return; 357 358 MAC_PERFORM(vnode_label_associate_singlelabel, mp, 359 mp ? mp->mnt_mntlabel : NULL, vp, vp->v_label); 360} 361 362int 363mac_vnode_notify_create(vfs_context_t ctx, struct mount *mp, 364 struct vnode *dvp, struct vnode *vp, struct componentname *cnp) 365{ 366 kauth_cred_t cred; 367 int error; 368 369 if (!mac_vnode_enforce || 370 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE)) 371 return (0); 372 373 cred = vfs_context_ucred(ctx); 374 MAC_CHECK(vnode_notify_create, cred, mp, mp->mnt_mntlabel, 375 dvp, dvp->v_label, vp, vp->v_label, cnp); 376 377 return (error); 378} 379 380void 381mac_vnode_notify_rename(vfs_context_t ctx, struct vnode *vp, 382 struct vnode *dvp, struct componentname *cnp) 383{ 384 kauth_cred_t cred; 385 386 if (!mac_vnode_enforce || 387 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE)) 388 return; 389 390 cred = vfs_context_ucred(ctx); 391 MAC_PERFORM(vnode_notify_rename, cred, vp, vp->v_label, 392 dvp, dvp->v_label, cnp); 393} 394 395void 396mac_vnode_notify_open(vfs_context_t ctx, struct vnode *vp, int acc_flags) 397{ 398 kauth_cred_t cred; 399 400 if (!mac_vnode_enforce || 401 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE)) 402 return; 403 404 cred = vfs_context_ucred(ctx); 405 MAC_PERFORM(vnode_notify_open, cred, vp, vp->v_label, acc_flags); 406} 407 408/* 409 * Extended attribute 'name' was updated via 410 * vn_setxattr() or vn_removexattr(). Allow the 411 * policy to update the vnode label. 412 */ 413void 414mac_vnode_label_update_extattr(struct mount *mp, struct vnode *vp, 415 const char *name) 416{ 417 int error = 0; 418 419 if (!mac_vnode_enforce || !mac_label_vnodes) 420 return; 421 422 MAC_PERFORM(vnode_label_update_extattr, mp, mp->mnt_mntlabel, vp, 423 vp->v_label, name); 424 if (error == 0) 425 return; 426 427 vnode_lock(vp); 428 vnode_relabel(vp); 429 vnode_unlock(vp); 430 return; 431} 432 433static int 434mac_vnode_label_store(vfs_context_t ctx, struct vnode *vp, 435 struct label *intlabel) 436{ 437 kauth_cred_t cred; 438 int error; 439 440 if (!mac_vnode_enforce || !mac_label_vnodes || 441 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE)) 442 return 0; 443 444 cred = vfs_context_ucred(ctx); 445 MAC_CHECK(vnode_label_store, cred, vp, vp->v_label, intlabel); 446 447 return (error); 448} 449 450int 451mac_cred_label_update_execve(vfs_context_t ctx, kauth_cred_t new, struct vnode *vp, 452 struct label *scriptvnodelabel, struct label *execl) 453{ 454 kauth_cred_t cred; 455 int disjoint = 0; 456 posix_cred_t pcred = posix_cred_get(new); 457 458 if (!mac_proc_enforce && !mac_vnode_enforce) 459 return disjoint; 460 461 /* mark the new cred to indicate "matching" includes the label */ 462 pcred->cr_flags |= CRF_MAC_ENFORCE; 463 464 cred = vfs_context_ucred(ctx); 465 MAC_PERFORM(cred_label_update_execve, cred, new, vp, vp->v_label, 466 scriptvnodelabel, execl, &disjoint); 467 468 return (disjoint); 469} 470 471int 472mac_cred_check_label_update_execve(vfs_context_t ctx, struct vnode *vp, 473 struct label *scriptvnodelabel, struct label *execlabel, struct proc *p) 474{ 475 kauth_cred_t cred; 476 int result = 0; 477 478 if (!mac_proc_enforce && !mac_vnode_enforce) 479 return result; 480 481 cred = vfs_context_ucred(ctx); 482 MAC_BOOLEAN(cred_check_label_update_execve, ||, cred, vp, vp->v_label, 483 scriptvnodelabel, execlabel, p); 484 485 return (result); 486} 487 488int 489mac_vnode_check_access(vfs_context_t ctx, struct vnode *vp, 490 int acc_mode) 491{ 492 kauth_cred_t cred; 493 int error; 494 int mask; 495 496 if (!mac_vnode_enforce || 497 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE)) 498 return 0; 499 500 cred = vfs_context_ucred(ctx); 501 /* Convert {R,W,X}_OK values to V{READ,WRITE,EXEC} for entry points */ 502 mask = ACCESS_MODE_TO_VNODE_MASK(acc_mode); 503 MAC_CHECK(vnode_check_access, cred, vp, vp->v_label, mask); 504 return (error); 505 } 506 507int 508mac_vnode_check_chdir(vfs_context_t ctx, struct vnode *dvp) 509{ 510 kauth_cred_t cred; 511 int error; 512 513 if (!mac_vnode_enforce || 514 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE)) 515 return (0); 516 517 cred = vfs_context_ucred(ctx); 518 MAC_CHECK(vnode_check_chdir, cred, dvp, dvp->v_label); 519 return (error); 520} 521 522int 523mac_vnode_check_chroot(vfs_context_t ctx, struct vnode *dvp, 524 struct componentname *cnp) 525{ 526 kauth_cred_t cred; 527 int error; 528 529 if (!mac_vnode_enforce || 530 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE)) 531 return (0); 532 533 cred = vfs_context_ucred(ctx); 534 MAC_CHECK(vnode_check_chroot, cred, dvp, dvp->v_label, cnp); 535 return (error); 536} 537 538int 539mac_vnode_check_create(vfs_context_t ctx, struct vnode *dvp, 540 struct componentname *cnp, struct vnode_attr *vap) 541{ 542 kauth_cred_t cred; 543 int error; 544 545 if (!mac_vnode_enforce || 546 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE)) 547 return (0); 548 549 cred = vfs_context_ucred(ctx); 550 MAC_CHECK(vnode_check_create, cred, dvp, dvp->v_label, cnp, vap); 551 return (error); 552} 553 554int 555mac_vnode_check_unlink(vfs_context_t ctx, struct vnode *dvp, struct vnode *vp, 556 struct componentname *cnp) 557{ 558 kauth_cred_t cred; 559 int error; 560 561 if (!mac_vnode_enforce || 562 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE)) 563 return (0); 564 565 cred = vfs_context_ucred(ctx); 566 MAC_CHECK(vnode_check_unlink, cred, dvp, dvp->v_label, vp, 567 vp->v_label, cnp); 568 return (error); 569} 570#if 0 571int 572mac_vnode_check_deleteacl(vfs_context_t ctx, struct vnode *vp, 573 acl_type_t type) 574{ 575 kauth_cred_t cred; 576 int error; 577 578 if (!mac_vnode_enforce || 579 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE)) 580 return (0); 581 582 cred = vfs_context_ucred(ctx); 583 MAC_CHECK(vnode_check_deleteacl, cred, vp, vp->v_label, type); 584 return (error); 585} 586#endif 587 588int 589mac_vnode_check_deleteextattr(vfs_context_t ctx, struct vnode *vp, 590 const char *name) 591{ 592 kauth_cred_t cred; 593 int error; 594 595 if (!mac_vnode_enforce || 596 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE)) 597 return (0); 598 599 cred = vfs_context_ucred(ctx); 600 MAC_CHECK(vnode_check_deleteextattr, cred, vp, vp->v_label, name); 601 return (error); 602} 603int 604mac_vnode_check_exchangedata(vfs_context_t ctx, 605 struct vnode *v1, struct vnode *v2) 606{ 607 kauth_cred_t cred; 608 int error; 609 610 if (!mac_vnode_enforce || 611 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE)) 612 return (0); 613 614 cred = vfs_context_ucred(ctx); 615 MAC_CHECK(vnode_check_exchangedata, cred, v1, v1->v_label, 616 v2, v2->v_label); 617 618 return (error); 619} 620 621#if 0 622int 623mac_vnode_check_getacl(vfs_context_t ctx, struct vnode *vp, acl_type_t type) 624{ 625 kauth_cred_t cred; 626 int error; 627 628 if (!mac_vnode_enforce || 629 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE)) 630 return (0); 631 632 cred = vfs_context_ucred(ctx); 633 MAC_CHECK(vnode_check_getacl, cred, vp, vp->v_label, type); 634 return (error); 635} 636#endif 637 638int 639mac_vnode_check_getattrlist(vfs_context_t ctx, struct vnode *vp, 640 struct attrlist *alist) 641{ 642 kauth_cred_t cred; 643 int error; 644 645 if (!mac_vnode_enforce || 646 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE)) 647 return (0); 648 649 cred = vfs_context_ucred(ctx); 650 MAC_CHECK(vnode_check_getattrlist, cred, vp, vp->v_label, alist); 651 652 /* Falsify results instead of returning error? */ 653 return (error); 654} 655 656int 657mac_vnode_check_exec(vfs_context_t ctx, struct vnode *vp, 658 struct image_params *imgp) 659{ 660 kauth_cred_t cred; 661 int error; 662 663 if (!mac_vnode_enforce || !mac_proc_enforce) 664 return (0); 665 666 cred = vfs_context_ucred(ctx); 667 MAC_CHECK(vnode_check_exec, cred, vp, vp->v_label, 668 (imgp != NULL) ? imgp->ip_execlabelp : NULL, 669 (imgp != NULL) ? &imgp->ip_ndp->ni_cnd : NULL, 670 (imgp != NULL) ? &imgp->ip_csflags : NULL); 671 return (error); 672} 673 674int 675mac_vnode_check_fsgetpath(vfs_context_t ctx, struct vnode *vp) 676{ 677 kauth_cred_t cred; 678 int error; 679 680 if (!mac_vnode_enforce || 681 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE)) 682 return (0); 683 684 cred = vfs_context_ucred(ctx); 685 MAC_CHECK(vnode_check_fsgetpath, cred, vp, vp->v_label); 686 return (error); 687} 688 689int 690mac_vnode_check_signature(struct vnode *vp, unsigned char *sha1, 691 void * signature, size_t size) 692{ 693 int error; 694 695 if (!mac_vnode_enforce || !mac_proc_enforce) 696 return (0); 697 698 MAC_CHECK(vnode_check_signature, vp, vp->v_label, sha1, signature, size); 699 return (error); 700} 701 702#if 0 703int 704mac_vnode_check_getacl(vfs_context_t ctx, struct vnode *vp, acl_type_t type) 705{ 706 kauth_cred_t cred; 707 int error; 708 709 if (!mac_vnode_enforce || 710 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE)) 711 return (0); 712 713 cred = vfs_context_ucred(ctx); 714 MAC_CHECK(vnode_check_getacl, cred, vp, vp->v_label, type); 715 return (error); 716} 717#endif 718 719int 720mac_vnode_check_getextattr(vfs_context_t ctx, struct vnode *vp, 721 const char *name, struct uio *uio) 722{ 723 kauth_cred_t cred; 724 int error; 725 726 if (!mac_vnode_enforce || 727 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE)) 728 return (0); 729 730 cred = vfs_context_ucred(ctx); 731 MAC_CHECK(vnode_check_getextattr, cred, vp, vp->v_label, 732 name, uio); 733 return (error); 734} 735 736int 737mac_vnode_check_ioctl(vfs_context_t ctx, struct vnode *vp, u_int cmd) 738{ 739 kauth_cred_t cred; 740 int error; 741 742 if (!mac_vnode_enforce || 743 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE)) 744 return (0); 745 746 cred = vfs_context_ucred(ctx); 747 MAC_CHECK(vnode_check_ioctl, cred, vp, vp->v_label, cmd); 748 return (error); 749} 750 751int 752mac_vnode_check_kqfilter(vfs_context_t ctx, kauth_cred_t file_cred, 753 struct knote *kn, struct vnode *vp) 754{ 755 kauth_cred_t cred; 756 int error; 757 758 if (!mac_vnode_enforce || 759 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE)) 760 return (0); 761 762 cred = vfs_context_ucred(ctx); 763 MAC_CHECK(vnode_check_kqfilter, cred, file_cred, kn, vp, 764 vp->v_label); 765 766 return (error); 767} 768 769int 770mac_vnode_check_link(vfs_context_t ctx, struct vnode *dvp, 771 struct vnode *vp, struct componentname *cnp) 772{ 773 kauth_cred_t cred; 774 int error; 775 776 if (!mac_vnode_enforce || 777 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE)) 778 return (0); 779 780 cred = vfs_context_ucred(ctx); 781 MAC_CHECK(vnode_check_link, cred, dvp, dvp->v_label, vp, 782 vp->v_label, cnp); 783 return (error); 784} 785 786int 787mac_vnode_check_listextattr(vfs_context_t ctx, struct vnode *vp) 788{ 789 kauth_cred_t cred; 790 int error; 791 792 if (!mac_vnode_enforce || 793 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE)) 794 return (0); 795 796 cred = vfs_context_ucred(ctx); 797 MAC_CHECK(vnode_check_listextattr, cred, vp, vp->v_label); 798 return (error); 799} 800 801int 802mac_vnode_check_lookup(vfs_context_t ctx, struct vnode *dvp, 803 struct componentname *cnp) 804{ 805 kauth_cred_t cred; 806 int error; 807 808 if (!mac_vnode_enforce || 809 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE)) 810 return (0); 811 812 cred = vfs_context_ucred(ctx); 813 MAC_CHECK(vnode_check_lookup, cred, dvp, dvp->v_label, cnp); 814 return (error); 815} 816 817int 818mac_vnode_check_open(vfs_context_t ctx, struct vnode *vp, int acc_mode) 819{ 820 kauth_cred_t cred; 821 int error; 822 823 if (!mac_vnode_enforce || 824 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE)) 825 return (0); 826 827 cred = vfs_context_ucred(ctx); 828 MAC_CHECK(vnode_check_open, cred, vp, vp->v_label, acc_mode); 829 return (error); 830} 831 832int 833mac_vnode_check_read(vfs_context_t ctx, struct ucred *file_cred, 834 struct vnode *vp) 835{ 836 kauth_cred_t cred; 837 int error; 838 839 if (!mac_vnode_enforce || 840 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE)) 841 return (0); 842 843 cred = vfs_context_ucred(ctx); 844 MAC_CHECK(vnode_check_read, cred, file_cred, vp, 845 vp->v_label); 846 847 return (error); 848} 849 850int 851mac_vnode_check_readdir(vfs_context_t ctx, struct vnode *dvp) 852{ 853 kauth_cred_t cred; 854 int error; 855 856 if (!mac_vnode_enforce || 857 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE)) 858 return (0); 859 860 cred = vfs_context_ucred(ctx); 861 MAC_CHECK(vnode_check_readdir, cred, dvp, dvp->v_label); 862 return (error); 863} 864 865int 866mac_vnode_check_readlink(vfs_context_t ctx, struct vnode *vp) 867{ 868 kauth_cred_t cred; 869 int error; 870 871 if (!mac_vnode_enforce || 872 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE)) 873 return (0); 874 875 cred = vfs_context_ucred(ctx); 876 MAC_CHECK(vnode_check_readlink, cred, vp, vp->v_label); 877 return (error); 878} 879 880int 881mac_vnode_check_label_update(vfs_context_t ctx, struct vnode *vp, 882 struct label *newlabel) 883{ 884 kauth_cred_t cred; 885 int error; 886 887 if (!mac_vnode_enforce || 888 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE)) 889 return (0); 890 891 cred = vfs_context_ucred(ctx); 892 MAC_CHECK(vnode_check_label_update, cred, vp, vp->v_label, newlabel); 893 894 return (error); 895} 896 897int 898mac_vnode_check_rename_from(vfs_context_t ctx, struct vnode *dvp, 899 struct vnode *vp, struct componentname *cnp) 900{ 901 kauth_cred_t cred; 902 int error; 903 904 if (!mac_vnode_enforce || 905 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE)) 906 return (0); 907 908 cred = vfs_context_ucred(ctx); 909 MAC_CHECK(vnode_check_rename_from, cred, dvp, dvp->v_label, vp, 910 vp->v_label, cnp); 911 return (error); 912} 913 914int 915mac_vnode_check_rename_to(vfs_context_t ctx, struct vnode *dvp, 916 struct vnode *vp, int samedir, struct componentname *cnp) 917{ 918 kauth_cred_t cred; 919 int error; 920 921 if (!mac_vnode_enforce || 922 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE)) 923 return (0); 924 925 cred = vfs_context_ucred(ctx); 926 MAC_CHECK(vnode_check_rename_to, cred, dvp, dvp->v_label, vp, 927 vp != NULL ? vp->v_label : NULL, samedir, cnp); 928 return (error); 929} 930 931int 932mac_vnode_check_revoke(vfs_context_t ctx, struct vnode *vp) 933{ 934 kauth_cred_t cred; 935 int error; 936 937 if (!mac_vnode_enforce || 938 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE)) 939 return (0); 940 941 cred = vfs_context_ucred(ctx); 942 MAC_CHECK(vnode_check_revoke, cred, vp, vp->v_label); 943 return (error); 944} 945 946int 947mac_vnode_check_searchfs(vfs_context_t ctx, struct vnode *vp, struct attrlist *alist) 948{ 949 kauth_cred_t cred; 950 int error; 951 952 if (!mac_vnode_enforce || 953 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE)) 954 return (0); 955 956 cred = vfs_context_ucred(ctx); 957 MAC_CHECK(vnode_check_searchfs, cred, vp, vp->v_label, alist); 958 return (error); 959} 960 961int 962mac_vnode_check_select(vfs_context_t ctx, struct vnode *vp, int which) 963{ 964 kauth_cred_t cred; 965 int error; 966 967 if (!mac_vnode_enforce || 968 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE)) 969 return (0); 970 971 cred = vfs_context_ucred(ctx); 972 MAC_CHECK(vnode_check_select, cred, vp, vp->v_label, which); 973 return (error); 974} 975 976#if 0 977int 978mac_vnode_check_setacl(vfs_context_t ctx, struct vnode *vp, acl_type_t type, 979 struct acl *acl) 980{ 981 kauth_cred_t cred; 982 int error; 983 984 if (!mac_vnode_enforce || 985 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE)) 986 return (0); 987 988 cred = vfs_context_ucred(ctx); 989 MAC_CHECK(vnode_check_setacl, cred, vp, vp->v_label, type, acl); 990 return (error); 991} 992#endif 993 994int 995mac_vnode_check_setattrlist(vfs_context_t ctx, struct vnode *vp, 996 struct attrlist *alist) 997{ 998 kauth_cred_t cred; 999 int error; 1000 1001 if (!mac_vnode_enforce || 1002 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE)) 1003 return (0); 1004 1005 cred = vfs_context_ucred(ctx); 1006 MAC_CHECK(vnode_check_setattrlist, cred, vp, vp->v_label, alist); 1007 return (error); 1008} 1009 1010int 1011mac_vnode_check_setextattr(vfs_context_t ctx, struct vnode *vp, 1012 const char *name, struct uio *uio) 1013{ 1014 kauth_cred_t cred; 1015 int error; 1016 1017 if (!mac_vnode_enforce || 1018 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE)) 1019 return (0); 1020 1021 cred = vfs_context_ucred(ctx); 1022 MAC_CHECK(vnode_check_setextattr, cred, vp, vp->v_label, 1023 name, uio); 1024 return (error); 1025} 1026 1027int 1028mac_vnode_check_setflags(vfs_context_t ctx, struct vnode *vp, u_long flags) 1029{ 1030 kauth_cred_t cred; 1031 int error; 1032 1033 if (!mac_vnode_enforce || 1034 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE)) 1035 return (0); 1036 1037 cred = vfs_context_ucred(ctx); 1038 MAC_CHECK(vnode_check_setflags, cred, vp, vp->v_label, flags); 1039 return (error); 1040} 1041 1042int 1043mac_vnode_check_setmode(vfs_context_t ctx, struct vnode *vp, mode_t mode) 1044{ 1045 kauth_cred_t cred; 1046 int error; 1047 1048 if (!mac_vnode_enforce || 1049 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE)) 1050 return (0); 1051 1052 cred = vfs_context_ucred(ctx); 1053 MAC_CHECK(vnode_check_setmode, cred, vp, vp->v_label, mode); 1054 return (error); 1055} 1056 1057int 1058mac_vnode_check_setowner(vfs_context_t ctx, struct vnode *vp, uid_t uid, 1059 gid_t gid) 1060{ 1061 kauth_cred_t cred; 1062 int error; 1063 1064 if (!mac_vnode_enforce || 1065 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE)) 1066 return (0); 1067 1068 cred = vfs_context_ucred(ctx); 1069 MAC_CHECK(vnode_check_setowner, cred, vp, vp->v_label, uid, gid); 1070 return (error); 1071} 1072 1073int 1074mac_vnode_check_setutimes(vfs_context_t ctx, struct vnode *vp, 1075 struct timespec atime, struct timespec mtime) 1076{ 1077 kauth_cred_t cred; 1078 int error; 1079 1080 if (!mac_vnode_enforce || 1081 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE)) 1082 return (0); 1083 1084 cred = vfs_context_ucred(ctx); 1085 MAC_CHECK(vnode_check_setutimes, cred, vp, vp->v_label, atime, 1086 mtime); 1087 return (error); 1088} 1089 1090int 1091mac_vnode_check_stat(vfs_context_t ctx, struct ucred *file_cred, 1092 struct vnode *vp) 1093{ 1094 kauth_cred_t cred; 1095 int error; 1096 1097 if (!mac_vnode_enforce || 1098 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE)) 1099 return (0); 1100 1101 cred = vfs_context_ucred(ctx); 1102 MAC_CHECK(vnode_check_stat, cred, file_cred, vp, 1103 vp->v_label); 1104 return (error); 1105} 1106 1107int 1108mac_vnode_check_truncate(vfs_context_t ctx, struct ucred *file_cred, 1109 struct vnode *vp) 1110{ 1111 kauth_cred_t cred; 1112 int error; 1113 1114 if (!mac_vnode_enforce || 1115 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE)) 1116 return (0); 1117 1118 cred = vfs_context_ucred(ctx); 1119 MAC_CHECK(vnode_check_truncate, cred, file_cred, vp, 1120 vp->v_label); 1121 1122 return (error); 1123} 1124 1125int 1126mac_vnode_check_write(vfs_context_t ctx, struct ucred *file_cred, 1127 struct vnode *vp) 1128{ 1129 kauth_cred_t cred; 1130 int error; 1131 1132 if (!mac_vnode_enforce || 1133 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE)) 1134 return (0); 1135 1136 cred = vfs_context_ucred(ctx); 1137 MAC_CHECK(vnode_check_write, cred, file_cred, vp, vp->v_label); 1138 1139 return (error); 1140} 1141 1142int 1143mac_vnode_check_uipc_bind(vfs_context_t ctx, struct vnode *dvp, 1144 struct componentname *cnp, struct vnode_attr *vap) 1145{ 1146 kauth_cred_t cred; 1147 int error; 1148 1149 if (!mac_vnode_enforce || 1150 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE)) 1151 return (0); 1152 1153 cred = vfs_context_ucred(ctx); 1154 MAC_CHECK(vnode_check_uipc_bind, cred, dvp, dvp->v_label, cnp, vap); 1155 return (error); 1156} 1157 1158int 1159mac_vnode_check_uipc_connect(vfs_context_t ctx, struct vnode *vp) 1160{ 1161 kauth_cred_t cred; 1162 int error; 1163 1164 if (!mac_vnode_enforce || 1165 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE)) 1166 return (0); 1167 1168 cred = vfs_context_ucred(ctx); 1169 MAC_CHECK(vnode_check_uipc_connect, cred, vp, vp->v_label); 1170 return (error); 1171} 1172 1173void 1174mac_vnode_label_update(vfs_context_t ctx, struct vnode *vp, struct label *newlabel) 1175{ 1176 kauth_cred_t cred = vfs_context_ucred(ctx); 1177 struct label *tmpl = NULL; 1178 1179 if (vp->v_label == NULL) 1180 tmpl = mac_vnode_label_alloc(); 1181 1182 vnode_lock(vp); 1183 1184 /* recheck after lock */ 1185 if (vp->v_label == NULL) { 1186 vp->v_label = tmpl; 1187 tmpl = NULL; 1188 } 1189 1190 MAC_PERFORM(vnode_label_update, cred, vp, vp->v_label, newlabel); 1191 vnode_unlock(vp); 1192 1193 if (tmpl != NULL) 1194 mac_vnode_label_free(tmpl); 1195} 1196 1197void 1198mac_mount_label_associate(vfs_context_t ctx, struct mount *mp) 1199{ 1200 kauth_cred_t cred = vfs_context_ucred(ctx); 1201 1202 /* XXX: eventually this logic may be handled by the policy? */ 1203 1204 /* We desire MULTILABEL for the root filesystem. */ 1205 if ((mp->mnt_flag & MNT_ROOTFS) && 1206 (strcmp(mp->mnt_vfsstat.f_fstypename, "hfs") == 0)) 1207 mp->mnt_flag |= MNT_MULTILABEL; 1208 1209 /* MULTILABEL on DEVFS. */ 1210 if (strcmp(mp->mnt_vfsstat.f_fstypename, "devfs") == 0) 1211 mp->mnt_flag |= MNT_MULTILABEL; 1212 1213 /* MULTILABEL on FDESC pseudo-filesystem. */ 1214 if (strcmp(mp->mnt_vfsstat.f_fstypename, "fdesc") == 0) 1215 mp->mnt_flag |= MNT_MULTILABEL; 1216 1217 /* MULTILABEL on all NFS filesystems. */ 1218 if (strcmp(mp->mnt_vfsstat.f_fstypename, "nfs") == 0) 1219 mp->mnt_flag |= MNT_MULTILABEL; 1220 1221 /* MULTILABEL on all AFP filesystems. */ 1222 if (strcmp(mp->mnt_vfsstat.f_fstypename, "afpfs") == 0) 1223 mp->mnt_flag |= MNT_MULTILABEL; 1224 1225 if (mp->mnt_vtable != NULL) { 1226 /* Any filesystem that supports native XATTRs. */ 1227 if ((mp->mnt_vtable->vfc_vfsflags & VFC_VFSNATIVEXATTR)) 1228 mp->mnt_flag |= MNT_MULTILABEL; 1229 1230 /* Filesystem does not support multilabel. */ 1231 if ((mp->mnt_vtable->vfc_vfsflags & VFC_VFSNOMACLABEL) && 1232 (mp->mnt_flag & MNT_MULTILABEL)) 1233 mp->mnt_flag &= ~MNT_MULTILABEL; 1234 } 1235 1236 MAC_PERFORM(mount_label_associate, cred, mp, mp->mnt_mntlabel); 1237#if DEBUG 1238 printf("MAC Framework enabling %s support: %s -> %s (%s)\n", 1239 mp->mnt_flag & MNT_MULTILABEL ? "multilabel" : "singlelabel", 1240 mp->mnt_vfsstat.f_mntfromname, 1241 mp->mnt_vfsstat.f_mntonname, 1242 mp->mnt_vfsstat.f_fstypename); 1243#endif 1244} 1245 1246int 1247mac_mount_check_mount(vfs_context_t ctx, struct vnode *vp, 1248 struct componentname *cnp, const char *vfc_name) 1249{ 1250 kauth_cred_t cred; 1251 int error; 1252 1253 if (!mac_vnode_enforce || 1254 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE)) 1255 return (0); 1256 1257 cred = vfs_context_ucred(ctx); 1258 MAC_CHECK(mount_check_mount, cred, vp, vp->v_label, cnp, vfc_name); 1259 1260 return (error); 1261} 1262 1263int 1264mac_mount_check_remount(vfs_context_t ctx, struct mount *mp) 1265{ 1266 kauth_cred_t cred; 1267 int error; 1268 1269 if (!mac_vnode_enforce || 1270 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE)) 1271 return (0); 1272 1273 cred = vfs_context_ucred(ctx); 1274 MAC_CHECK(mount_check_remount, cred, mp, mp->mnt_mntlabel); 1275 1276 return (error); 1277} 1278 1279int 1280mac_mount_check_umount(vfs_context_t ctx, struct mount *mp) 1281{ 1282 kauth_cred_t cred; 1283 int error; 1284 1285 if (!mac_vnode_enforce || 1286 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE)) 1287 return (0); 1288 1289 cred = vfs_context_ucred(ctx); 1290 MAC_CHECK(mount_check_umount, cred, mp, mp->mnt_mntlabel); 1291 1292 return (error); 1293} 1294 1295int 1296mac_mount_check_getattr(vfs_context_t ctx, struct mount *mp, 1297 struct vfs_attr *vfa) 1298{ 1299 kauth_cred_t cred; 1300 int error; 1301 1302 if (!mac_vnode_enforce || 1303 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE)) 1304 return (0); 1305 1306 cred = vfs_context_ucred(ctx); 1307 MAC_CHECK(mount_check_getattr, cred, mp, mp->mnt_mntlabel, vfa); 1308 return (error); 1309} 1310 1311int 1312mac_mount_check_setattr(vfs_context_t ctx, struct mount *mp, 1313 struct vfs_attr *vfa) 1314{ 1315 kauth_cred_t cred; 1316 int error; 1317 1318 if (!mac_vnode_enforce || 1319 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE)) 1320 return (0); 1321 1322 cred = vfs_context_ucred(ctx); 1323 MAC_CHECK(mount_check_setattr, cred, mp, mp->mnt_mntlabel, vfa); 1324 return (error); 1325} 1326 1327int 1328mac_mount_check_stat(vfs_context_t ctx, struct mount *mount) 1329{ 1330 kauth_cred_t cred; 1331 int error; 1332 1333 if (!mac_vnode_enforce || 1334 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE)) 1335 return (0); 1336 1337 cred = vfs_context_ucred(ctx); 1338 MAC_CHECK(mount_check_stat, cred, mount, mount->mnt_mntlabel); 1339 1340 return (error); 1341} 1342 1343int 1344mac_mount_check_label_update(vfs_context_t ctx, struct mount *mount) 1345{ 1346 kauth_cred_t cred; 1347 int error; 1348 1349 if (!mac_vnode_enforce || 1350 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE)) 1351 return (0); 1352 1353 cred = vfs_context_ucred(ctx); 1354 MAC_CHECK(mount_check_label_update, cred, mount, mount->mnt_mntlabel); 1355 1356 return (error); 1357} 1358 1359int 1360mac_mount_check_fsctl(vfs_context_t ctx, struct mount *mp, u_int cmd) 1361{ 1362 kauth_cred_t cred; 1363 int error; 1364 1365 if (!mac_vnode_enforce || 1366 !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE)) 1367 return (0); 1368 1369 cred = vfs_context_ucred(ctx); 1370 MAC_CHECK(mount_check_fsctl, cred, mp, mp->mnt_mntlabel, cmd); 1371 1372 return (error); 1373} 1374 1375void 1376mac_devfs_label_associate_device(dev_t dev, struct devnode *de, 1377 const char *fullpath) 1378{ 1379 if (!mac_device_enforce) 1380 return; 1381 1382 MAC_PERFORM(devfs_label_associate_device, dev, de, de->dn_label, 1383 fullpath); 1384} 1385 1386void 1387mac_devfs_label_associate_directory(const char *dirname, int dirnamelen, 1388 struct devnode *de, const char *fullpath) 1389{ 1390 if (!mac_device_enforce) 1391 return; 1392 1393 MAC_PERFORM(devfs_label_associate_directory, dirname, dirnamelen, de, 1394 de->dn_label, fullpath); 1395} 1396 1397int 1398vn_setlabel(struct vnode *vp, struct label *intlabel, vfs_context_t context) 1399{ 1400 int error; 1401 1402 if (!mac_vnode_enforce || !mac_label_vnodes) 1403 return (0); 1404 1405 if (vp->v_mount == NULL) { 1406 printf("vn_setlabel: null v_mount\n"); 1407 if (vp->v_type != VNON) 1408 printf("vn_setlabel: null v_mount with non-VNON\n"); 1409 return (EBADF); 1410 } 1411 1412 if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) 1413 return (ENOTSUP); 1414 1415 /* 1416 * Multi-phase commit. First check the policies to confirm the 1417 * change is OK. Then commit via the filesystem. Finally, 1418 * update the actual vnode label. Question: maybe the filesystem 1419 * should update the vnode at the end as part of VNOP_SETLABEL()? 1420 */ 1421 error = mac_vnode_check_label_update(context, vp, intlabel); 1422 if (error) 1423 return (error); 1424 1425 error = VNOP_SETLABEL(vp, intlabel, context); 1426 if (error == ENOTSUP) { 1427 error = mac_vnode_label_store(context, vp, 1428 intlabel); 1429 if (error) { 1430 printf("%s: mac_vnode_label_store failed %d\n", 1431 __func__, error); 1432 return (error); 1433 } 1434 mac_vnode_label_update(context, vp, intlabel); 1435 } else 1436 if (error) { 1437 printf("vn_setlabel: vop setlabel failed %d\n", error); 1438 return (error); 1439 } 1440 1441 return (0); 1442} 1443 1444int 1445mac_vnode_label_associate_fdesc(struct mount *mp, struct fdescnode *fnp, 1446 struct vnode *vp, vfs_context_t ctx) 1447{ 1448 struct fileproc *fp; 1449 struct socket *so; 1450 struct pipe *cpipe; 1451 struct vnode *fvp; 1452 struct proc *p; 1453 int error; 1454 1455 error = 0; 1456 1457 /* 1458 * If no backing file, let the policy choose which label to use. 1459 */ 1460 if (fnp->fd_fd == -1) { 1461 MAC_PERFORM(vnode_label_associate_file, vfs_context_ucred(ctx), 1462 mp, mp->mnt_mntlabel, NULL, NULL, vp, vp->v_label); 1463 return (0); 1464 } 1465 1466 p = vfs_context_proc(ctx); 1467 error = fp_lookup(p, fnp->fd_fd, &fp, 0); 1468 if (error) 1469 return (error); 1470 1471 if (fp->f_fglob == NULL) { 1472 error = EBADF; 1473 goto out; 1474 } 1475 1476 switch (fp->f_fglob->fg_type) { 1477 case DTYPE_VNODE: 1478 fvp = (struct vnode *)fp->f_fglob->fg_data; 1479 if ((error = vnode_getwithref(fvp))) 1480 goto out; 1481 MAC_PERFORM(vnode_label_copy, fvp->v_label, vp->v_label); 1482 (void)vnode_put(fvp); 1483 break; 1484 case DTYPE_SOCKET: 1485 so = (struct socket *)fp->f_fglob->fg_data; 1486 socket_lock(so, 1); 1487 MAC_PERFORM(vnode_label_associate_socket, 1488 vfs_context_ucred(ctx), (socket_t)so, so->so_label, 1489 vp, vp->v_label); 1490 socket_unlock(so, 1); 1491 break; 1492 case DTYPE_PSXSHM: 1493 pshm_label_associate(fp, vp, ctx); 1494 break; 1495 case DTYPE_PSXSEM: 1496 psem_label_associate(fp, vp, ctx); 1497 break; 1498 case DTYPE_PIPE: 1499 cpipe = (struct pipe *)fp->f_fglob->fg_data; 1500 /* kern/sys_pipe.c:pipe_select() suggests this test. */ 1501 if (cpipe == (struct pipe *)-1) { 1502 error = EINVAL; 1503 goto out; 1504 } 1505 PIPE_LOCK(cpipe); 1506 MAC_PERFORM(vnode_label_associate_pipe, vfs_context_ucred(ctx), 1507 cpipe, cpipe->pipe_label, vp, vp->v_label); 1508 PIPE_UNLOCK(cpipe); 1509 break; 1510 case DTYPE_KQUEUE: 1511 case DTYPE_FSEVENTS: 1512 default: 1513 MAC_PERFORM(vnode_label_associate_file, vfs_context_ucred(ctx), 1514 mp, mp->mnt_mntlabel, fp->f_fglob, fp->f_fglob->fg_label, 1515 vp, vp->v_label); 1516 break; 1517 } 1518out: 1519 fp_drop(p, fnp->fd_fd, fp, 0); 1520 return (error); 1521} 1522