mac_vfs.c revision 165601
1/*- 2 * Copyright (c) 1999-2002 Robert N. M. Watson 3 * Copyright (c) 2001 Ilmar S. Habibulin 4 * Copyright (c) 2001-2005 McAfee, Inc. 5 * Copyright (c) 2005 SPARTA, Inc. 6 * All rights reserved. 7 * 8 * This software was developed by Robert Watson and Ilmar Habibulin for the 9 * TrustedBSD Project. 10 * 11 * This software was developed for the FreeBSD Project in part by McAfee 12 * Research, the Security Research Division of McAfee, Inc. under 13 * DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA 14 * CHATS research program. 15 * 16 * This software was enhanced by SPARTA ISSO under SPAWAR contract 17 * N66001-04-C-6019 ("SEFOS"). 18 * 19 * Redistribution and use in source and binary forms, with or without 20 * modification, are permitted provided that the following conditions 21 * are met: 22 * 1. Redistributions of source code must retain the above copyright 23 * notice, this list of conditions and the following disclaimer. 24 * 2. Redistributions in binary form must reproduce the above copyright 25 * notice, this list of conditions and the following disclaimer in the 26 * documentation and/or other materials provided with the distribution. 27 * 28 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 31 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 38 * SUCH DAMAGE. 39 */ 40 41#include <sys/cdefs.h> 42__FBSDID("$FreeBSD: head/sys/security/mac/mac_vfs.c 165601 2006-12-28 22:02:59Z rwatson $"); 43 44#include "opt_mac.h" 45 46#include <sys/param.h> 47#include <sys/condvar.h> 48#include <sys/extattr.h> 49#include <sys/imgact.h> 50#include <sys/kernel.h> 51#include <sys/lock.h> 52#include <sys/malloc.h> 53#include <sys/mutex.h> 54#include <sys/mac.h> 55#include <sys/proc.h> 56#include <sys/sbuf.h> 57#include <sys/systm.h> 58#include <sys/vnode.h> 59#include <sys/mount.h> 60#include <sys/file.h> 61#include <sys/namei.h> 62#include <sys/sysctl.h> 63 64#include <vm/vm.h> 65#include <vm/pmap.h> 66#include <vm/vm_map.h> 67#include <vm/vm_object.h> 68 69#include <fs/devfs/devfs.h> 70 71#include <security/mac/mac_framework.h> 72#include <security/mac/mac_internal.h> 73#include <security/mac/mac_policy.h> 74 75/* 76 * Warn about EA transactions only the first time they happen. No locking on 77 * this variable. 78 */ 79static int ea_warn_once = 0; 80 81static int mac_setlabel_vnode_extattr(struct ucred *cred, 82 struct vnode *vp, struct label *intlabel); 83 84static struct label * 85mac_devfsdirent_label_alloc(void) 86{ 87 struct label *label; 88 89 label = mac_labelzone_alloc(M_WAITOK); 90 MAC_PERFORM(init_devfsdirent_label, label); 91 return (label); 92} 93 94void 95mac_init_devfsdirent(struct devfs_dirent *de) 96{ 97 98 de->de_label = mac_devfsdirent_label_alloc(); 99} 100 101static struct label * 102mac_mount_label_alloc(void) 103{ 104 struct label *label; 105 106 label = mac_labelzone_alloc(M_WAITOK); 107 MAC_PERFORM(init_mount_label, label); 108 return (label); 109} 110 111static struct label * 112mac_mount_fs_label_alloc(void) 113{ 114 struct label *label; 115 116 label = mac_labelzone_alloc(M_WAITOK); 117 MAC_PERFORM(init_mount_fs_label, label); 118 return (label); 119} 120 121void 122mac_init_mount(struct mount *mp) 123{ 124 125 mp->mnt_mntlabel = mac_mount_label_alloc(); 126 mp->mnt_fslabel = mac_mount_fs_label_alloc(); 127} 128 129struct label * 130mac_vnode_label_alloc(void) 131{ 132 struct label *label; 133 134 label = mac_labelzone_alloc(M_WAITOK); 135 MAC_PERFORM(init_vnode_label, label); 136 return (label); 137} 138 139void 140mac_init_vnode(struct vnode *vp) 141{ 142 143 vp->v_label = mac_vnode_label_alloc(); 144} 145 146static void 147mac_devfsdirent_label_free(struct label *label) 148{ 149 150 MAC_PERFORM(destroy_devfsdirent_label, label); 151 mac_labelzone_free(label); 152} 153 154void 155mac_destroy_devfsdirent(struct devfs_dirent *de) 156{ 157 158 mac_devfsdirent_label_free(de->de_label); 159 de->de_label = NULL; 160} 161 162static void 163mac_mount_label_free(struct label *label) 164{ 165 166 MAC_PERFORM(destroy_mount_label, label); 167 mac_labelzone_free(label); 168} 169 170static void 171mac_mount_fs_label_free(struct label *label) 172{ 173 174 MAC_PERFORM(destroy_mount_fs_label, label); 175 mac_labelzone_free(label); 176} 177 178void 179mac_destroy_mount(struct mount *mp) 180{ 181 182 mac_mount_fs_label_free(mp->mnt_fslabel); 183 mp->mnt_fslabel = NULL; 184 mac_mount_label_free(mp->mnt_mntlabel); 185 mp->mnt_mntlabel = NULL; 186} 187 188void 189mac_vnode_label_free(struct label *label) 190{ 191 192 MAC_PERFORM(destroy_vnode_label, label); 193 mac_labelzone_free(label); 194} 195 196void 197mac_destroy_vnode(struct vnode *vp) 198{ 199 200 mac_vnode_label_free(vp->v_label); 201 vp->v_label = NULL; 202} 203 204void 205mac_copy_vnode_label(struct label *src, struct label *dest) 206{ 207 208 MAC_PERFORM(copy_vnode_label, src, dest); 209} 210 211int 212mac_externalize_vnode_label(struct label *label, char *elements, 213 char *outbuf, size_t outbuflen) 214{ 215 int error; 216 217 MAC_EXTERNALIZE(vnode, label, elements, outbuf, outbuflen); 218 219 return (error); 220} 221 222int 223mac_internalize_vnode_label(struct label *label, char *string) 224{ 225 int error; 226 227 MAC_INTERNALIZE(vnode, label, string); 228 229 return (error); 230} 231 232void 233mac_update_devfsdirent(struct mount *mp, struct devfs_dirent *de, 234 struct vnode *vp) 235{ 236 237 MAC_PERFORM(update_devfsdirent, mp, de, de->de_label, vp, 238 vp->v_label); 239} 240 241void 242mac_associate_vnode_devfs(struct mount *mp, struct devfs_dirent *de, 243 struct vnode *vp) 244{ 245 246 MAC_PERFORM(associate_vnode_devfs, mp, mp->mnt_fslabel, de, 247 de->de_label, vp, vp->v_label); 248} 249 250int 251mac_associate_vnode_extattr(struct mount *mp, struct vnode *vp) 252{ 253 int error; 254 255 ASSERT_VOP_LOCKED(vp, "mac_associate_vnode_extattr"); 256 257 MAC_CHECK(associate_vnode_extattr, mp, mp->mnt_fslabel, vp, 258 vp->v_label); 259 260 return (error); 261} 262 263void 264mac_associate_vnode_singlelabel(struct mount *mp, struct vnode *vp) 265{ 266 267 MAC_PERFORM(associate_vnode_singlelabel, mp, mp->mnt_fslabel, vp, 268 vp->v_label); 269} 270 271/* 272 * Functions implementing extended-attribute backed labels for file systems 273 * that support it. 274 * 275 * Where possible, we use EA transactions to make writes to multiple 276 * attributes across difference policies mutually atomic. We allow work to 277 * continue on file systems not supporting EA transactions, but generate a 278 * printf warning. 279 */ 280int 281mac_create_vnode_extattr(struct ucred *cred, struct mount *mp, 282 struct vnode *dvp, struct vnode *vp, struct componentname *cnp) 283{ 284 int error; 285 286 ASSERT_VOP_LOCKED(dvp, "mac_create_vnode_extattr"); 287 ASSERT_VOP_LOCKED(vp, "mac_create_vnode_extattr"); 288 289 error = VOP_OPENEXTATTR(vp, cred, curthread); 290 if (error == EOPNOTSUPP) { 291 if (ea_warn_once == 0) { 292 printf("Warning: transactions not supported " 293 "in EA write.\n"); 294 ea_warn_once = 1; 295 } 296 } else if (error) 297 return (error); 298 299 MAC_CHECK(create_vnode_extattr, cred, mp, mp->mnt_fslabel, 300 dvp, dvp->v_label, vp, vp->v_label, cnp); 301 302 if (error) { 303 VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread); 304 return (error); 305 } 306 307 error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread); 308 if (error == EOPNOTSUPP) 309 error = 0; 310 311 return (error); 312} 313 314static int 315mac_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp, 316 struct label *intlabel) 317{ 318 int error; 319 320 ASSERT_VOP_LOCKED(vp, "mac_setlabel_vnode_extattr"); 321 322 error = VOP_OPENEXTATTR(vp, cred, curthread); 323 if (error == EOPNOTSUPP) { 324 if (ea_warn_once == 0) { 325 printf("Warning: transactions not supported " 326 "in EA write.\n"); 327 ea_warn_once = 1; 328 } 329 } else if (error) 330 return (error); 331 332 MAC_CHECK(setlabel_vnode_extattr, cred, vp, vp->v_label, intlabel); 333 334 if (error) { 335 VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread); 336 return (error); 337 } 338 339 error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread); 340 if (error == EOPNOTSUPP) 341 error = 0; 342 343 return (error); 344} 345 346void 347mac_execve_transition(struct ucred *old, struct ucred *new, struct vnode *vp, 348 struct label *interpvnodelabel, struct image_params *imgp) 349{ 350 351 ASSERT_VOP_LOCKED(vp, "mac_execve_transition"); 352 353 MAC_PERFORM(execve_transition, old, new, vp, vp->v_label, 354 interpvnodelabel, imgp, imgp->execlabel); 355} 356 357int 358mac_execve_will_transition(struct ucred *old, struct vnode *vp, 359 struct label *interpvnodelabel, struct image_params *imgp) 360{ 361 int result; 362 363 ASSERT_VOP_LOCKED(vp, "mac_execve_will_transition"); 364 365 result = 0; 366 MAC_BOOLEAN(execve_will_transition, ||, old, vp, vp->v_label, 367 interpvnodelabel, imgp, imgp->execlabel); 368 369 return (result); 370} 371 372int 373mac_check_vnode_access(struct ucred *cred, struct vnode *vp, int acc_mode) 374{ 375 int error; 376 377 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_access"); 378 379 MAC_CHECK(check_vnode_access, cred, vp, vp->v_label, acc_mode); 380 return (error); 381} 382 383int 384mac_check_vnode_chdir(struct ucred *cred, struct vnode *dvp) 385{ 386 int error; 387 388 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chdir"); 389 390 MAC_CHECK(check_vnode_chdir, cred, dvp, dvp->v_label); 391 return (error); 392} 393 394int 395mac_check_vnode_chroot(struct ucred *cred, struct vnode *dvp) 396{ 397 int error; 398 399 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chroot"); 400 401 MAC_CHECK(check_vnode_chroot, cred, dvp, dvp->v_label); 402 return (error); 403} 404 405int 406mac_check_vnode_create(struct ucred *cred, struct vnode *dvp, 407 struct componentname *cnp, struct vattr *vap) 408{ 409 int error; 410 411 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_create"); 412 413 MAC_CHECK(check_vnode_create, cred, dvp, dvp->v_label, cnp, vap); 414 return (error); 415} 416 417int 418mac_check_vnode_delete(struct ucred *cred, struct vnode *dvp, struct vnode *vp, 419 struct componentname *cnp) 420{ 421 int error; 422 423 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_delete"); 424 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_delete"); 425 426 MAC_CHECK(check_vnode_delete, cred, dvp, dvp->v_label, vp, 427 vp->v_label, cnp); 428 return (error); 429} 430 431int 432mac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 433 acl_type_t type) 434{ 435 int error; 436 437 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_deleteacl"); 438 439 MAC_CHECK(check_vnode_deleteacl, cred, vp, vp->v_label, type); 440 return (error); 441} 442 443int 444mac_check_vnode_deleteextattr(struct ucred *cred, struct vnode *vp, 445 int attrnamespace, const char *name) 446{ 447 int error; 448 449 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_deleteextattr"); 450 451 MAC_CHECK(check_vnode_deleteextattr, cred, vp, vp->v_label, 452 attrnamespace, name); 453 return (error); 454} 455 456int 457mac_check_vnode_exec(struct ucred *cred, struct vnode *vp, 458 struct image_params *imgp) 459{ 460 int error; 461 462 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_exec"); 463 464 MAC_CHECK(check_vnode_exec, cred, vp, vp->v_label, imgp, 465 imgp->execlabel); 466 467 return (error); 468} 469 470int 471mac_check_vnode_getacl(struct ucred *cred, struct vnode *vp, acl_type_t type) 472{ 473 int error; 474 475 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getacl"); 476 477 MAC_CHECK(check_vnode_getacl, cred, vp, vp->v_label, type); 478 return (error); 479} 480 481int 482mac_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 483 int attrnamespace, const char *name, struct uio *uio) 484{ 485 int error; 486 487 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getextattr"); 488 489 MAC_CHECK(check_vnode_getextattr, cred, vp, vp->v_label, 490 attrnamespace, name, uio); 491 return (error); 492} 493 494int 495mac_check_vnode_link(struct ucred *cred, struct vnode *dvp, 496 struct vnode *vp, struct componentname *cnp) 497{ 498 int error; 499 500 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_link"); 501 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_link"); 502 503 MAC_CHECK(check_vnode_link, cred, dvp, dvp->v_label, vp, 504 vp->v_label, cnp); 505 return (error); 506} 507 508int 509mac_check_vnode_listextattr(struct ucred *cred, struct vnode *vp, 510 int attrnamespace) 511{ 512 int error; 513 514 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_listextattr"); 515 516 MAC_CHECK(check_vnode_listextattr, cred, vp, vp->v_label, 517 attrnamespace); 518 return (error); 519} 520 521int 522mac_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 523 struct componentname *cnp) 524{ 525 int error; 526 527 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_lookup"); 528 529 MAC_CHECK(check_vnode_lookup, cred, dvp, dvp->v_label, cnp); 530 return (error); 531} 532 533int 534mac_check_vnode_mmap(struct ucred *cred, struct vnode *vp, 535 int prot, int flags) 536{ 537 int error; 538 539 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap"); 540 541 MAC_CHECK(check_vnode_mmap, cred, vp, vp->v_label, prot, flags); 542 return (error); 543} 544 545void 546mac_check_vnode_mmap_downgrade(struct ucred *cred, struct vnode *vp, int *prot) 547{ 548 int result = *prot; 549 550 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap_downgrade"); 551 552 MAC_PERFORM(check_vnode_mmap_downgrade, cred, vp, vp->v_label, 553 &result); 554 555 *prot = result; 556} 557 558int 559mac_check_vnode_mprotect(struct ucred *cred, struct vnode *vp, int prot) 560{ 561 int error; 562 563 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mprotect"); 564 565 MAC_CHECK(check_vnode_mprotect, cred, vp, vp->v_label, prot); 566 return (error); 567} 568 569int 570mac_check_vnode_open(struct ucred *cred, struct vnode *vp, int acc_mode) 571{ 572 int error; 573 574 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_open"); 575 576 MAC_CHECK(check_vnode_open, cred, vp, vp->v_label, acc_mode); 577 return (error); 578} 579 580int 581mac_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, 582 struct vnode *vp) 583{ 584 int error; 585 586 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_poll"); 587 588 MAC_CHECK(check_vnode_poll, active_cred, file_cred, vp, 589 vp->v_label); 590 591 return (error); 592} 593 594int 595mac_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 596 struct vnode *vp) 597{ 598 int error; 599 600 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_read"); 601 602 MAC_CHECK(check_vnode_read, active_cred, file_cred, vp, 603 vp->v_label); 604 605 return (error); 606} 607 608int 609mac_check_vnode_readdir(struct ucred *cred, struct vnode *dvp) 610{ 611 int error; 612 613 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_readdir"); 614 615 MAC_CHECK(check_vnode_readdir, cred, dvp, dvp->v_label); 616 return (error); 617} 618 619int 620mac_check_vnode_readlink(struct ucred *cred, struct vnode *vp) 621{ 622 int error; 623 624 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_readlink"); 625 626 MAC_CHECK(check_vnode_readlink, cred, vp, vp->v_label); 627 return (error); 628} 629 630static int 631mac_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 632 struct label *newlabel) 633{ 634 int error; 635 636 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_relabel"); 637 638 MAC_CHECK(check_vnode_relabel, cred, vp, vp->v_label, newlabel); 639 640 return (error); 641} 642 643int 644mac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 645 struct vnode *vp, struct componentname *cnp) 646{ 647 int error; 648 649 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_from"); 650 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_from"); 651 652 MAC_CHECK(check_vnode_rename_from, cred, dvp, dvp->v_label, vp, 653 vp->v_label, cnp); 654 return (error); 655} 656 657int 658mac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 659 struct vnode *vp, int samedir, struct componentname *cnp) 660{ 661 int error; 662 663 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_to"); 664 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_to"); 665 666 MAC_CHECK(check_vnode_rename_to, cred, dvp, dvp->v_label, vp, 667 vp != NULL ? vp->v_label : NULL, samedir, cnp); 668 return (error); 669} 670 671int 672mac_check_vnode_revoke(struct ucred *cred, struct vnode *vp) 673{ 674 int error; 675 676 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_revoke"); 677 678 MAC_CHECK(check_vnode_revoke, cred, vp, vp->v_label); 679 return (error); 680} 681 682int 683mac_check_vnode_setacl(struct ucred *cred, struct vnode *vp, acl_type_t type, 684 struct acl *acl) 685{ 686 int error; 687 688 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setacl"); 689 690 MAC_CHECK(check_vnode_setacl, cred, vp, vp->v_label, type, acl); 691 return (error); 692} 693 694int 695mac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 696 int attrnamespace, const char *name, struct uio *uio) 697{ 698 int error; 699 700 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setextattr"); 701 702 MAC_CHECK(check_vnode_setextattr, cred, vp, vp->v_label, 703 attrnamespace, name, uio); 704 return (error); 705} 706 707int 708mac_check_vnode_setflags(struct ucred *cred, struct vnode *vp, u_long flags) 709{ 710 int error; 711 712 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setflags"); 713 714 MAC_CHECK(check_vnode_setflags, cred, vp, vp->v_label, flags); 715 return (error); 716} 717 718int 719mac_check_vnode_setmode(struct ucred *cred, struct vnode *vp, mode_t mode) 720{ 721 int error; 722 723 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setmode"); 724 725 MAC_CHECK(check_vnode_setmode, cred, vp, vp->v_label, mode); 726 return (error); 727} 728 729int 730mac_check_vnode_setowner(struct ucred *cred, struct vnode *vp, uid_t uid, 731 gid_t gid) 732{ 733 int error; 734 735 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setowner"); 736 737 MAC_CHECK(check_vnode_setowner, cred, vp, vp->v_label, uid, gid); 738 return (error); 739} 740 741int 742mac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 743 struct timespec atime, struct timespec mtime) 744{ 745 int error; 746 747 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setutimes"); 748 749 MAC_CHECK(check_vnode_setutimes, cred, vp, vp->v_label, atime, 750 mtime); 751 return (error); 752} 753 754int 755mac_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, 756 struct vnode *vp) 757{ 758 int error; 759 760 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_stat"); 761 762 MAC_CHECK(check_vnode_stat, active_cred, file_cred, vp, 763 vp->v_label); 764 return (error); 765} 766 767int 768mac_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred, 769 struct vnode *vp) 770{ 771 int error; 772 773 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_write"); 774 775 MAC_CHECK(check_vnode_write, active_cred, file_cred, vp, 776 vp->v_label); 777 778 return (error); 779} 780 781void 782mac_relabel_vnode(struct ucred *cred, struct vnode *vp, struct label *newlabel) 783{ 784 785 MAC_PERFORM(relabel_vnode, cred, vp, vp->v_label, newlabel); 786} 787 788void 789mac_create_mount(struct ucred *cred, struct mount *mp) 790{ 791 792 MAC_PERFORM(create_mount, cred, mp, mp->mnt_mntlabel, 793 mp->mnt_fslabel); 794} 795 796int 797mac_check_mount_stat(struct ucred *cred, struct mount *mount) 798{ 799 int error; 800 801 MAC_CHECK(check_mount_stat, cred, mount, mount->mnt_mntlabel); 802 803 return (error); 804} 805 806void 807mac_create_devfs_device(struct ucred *cred, struct mount *mp, 808 struct cdev *dev, struct devfs_dirent *de) 809{ 810 811 MAC_PERFORM(create_devfs_device, cred, mp, dev, de, de->de_label); 812} 813 814void 815mac_create_devfs_symlink(struct ucred *cred, struct mount *mp, 816 struct devfs_dirent *dd, struct devfs_dirent *de) 817{ 818 819 MAC_PERFORM(create_devfs_symlink, cred, mp, dd, dd->de_label, de, 820 de->de_label); 821} 822 823void 824mac_create_devfs_directory(struct mount *mp, char *dirname, int dirnamelen, 825 struct devfs_dirent *de) 826{ 827 828 MAC_PERFORM(create_devfs_directory, mp, dirname, dirnamelen, de, 829 de->de_label); 830} 831 832/* 833 * Implementation of VOP_SETLABEL() that relies on extended attributes 834 * to store label data. Can be referenced by filesystems supporting 835 * extended attributes. 836 */ 837int 838vop_stdsetlabel_ea(struct vop_setlabel_args *ap) 839{ 840 struct vnode *vp = ap->a_vp; 841 struct label *intlabel = ap->a_label; 842 int error; 843 844 ASSERT_VOP_LOCKED(vp, "vop_stdsetlabel_ea"); 845 846 if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) 847 return (EOPNOTSUPP); 848 849 error = mac_setlabel_vnode_extattr(ap->a_cred, vp, intlabel); 850 if (error) 851 return (error); 852 853 mac_relabel_vnode(ap->a_cred, vp, intlabel); 854 855 return (0); 856} 857 858int 859vn_setlabel(struct vnode *vp, struct label *intlabel, struct ucred *cred) 860{ 861 int error; 862 863 if (vp->v_mount == NULL) { 864 /* printf("vn_setlabel: null v_mount\n"); */ 865 if (vp->v_type != VNON) 866 printf("vn_setlabel: null v_mount with non-VNON\n"); 867 return (EBADF); 868 } 869 870 if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) 871 return (EOPNOTSUPP); 872 873 /* 874 * Multi-phase commit. First check the policies to confirm the 875 * change is OK. Then commit via the filesystem. Finally, update 876 * the actual vnode label. 877 * 878 * Question: maybe the filesystem should update the vnode at the end 879 * as part of VOP_SETLABEL()? 880 */ 881 error = mac_check_vnode_relabel(cred, vp, intlabel); 882 if (error) 883 return (error); 884 885 /* 886 * VADMIN provides the opportunity for the filesystem to make 887 * decisions about who is and is not able to modify labels and 888 * protections on files. This might not be right. We can't assume 889 * VOP_SETLABEL() will do it, because we might implement that as 890 * part of vop_stdsetlabel_ea(). 891 */ 892 error = VOP_ACCESS(vp, VADMIN, cred, curthread); 893 if (error) 894 return (error); 895 896 error = VOP_SETLABEL(vp, intlabel, cred, curthread); 897 if (error) 898 return (error); 899 900 return (0); 901} 902 903/* 904 * When a thread becomes an NFS server daemon, its credential may need to be 905 * updated to reflect this so that policies can recognize when file system 906 * operations originate from the network. 907 * 908 * At some point, it would be desirable if the credential used for each NFS 909 * RPC could be set based on the RPC context (i.e., source system, etc) to 910 * provide more fine-grained access control. 911 */ 912void 913mac_associate_nfsd_label(struct ucred *cred) 914{ 915 916 MAC_PERFORM(associate_nfsd_label, cred); 917} 918