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