mac_vfs.c revision 189503
1/*- 2 * Copyright (c) 1999-2002, 2009 Robert N. M. Watson 3 * Copyright (c) 2001 Ilmar S. Habibulin 4 * Copyright (c) 2001-2005 McAfee, Inc. 5 * Copyright (c) 2005-2006 SPARTA, Inc. 6 * Copyright (c) 2008 Apple Inc. 7 * All rights reserved. 8 * 9 * This software was developed by Robert Watson and Ilmar Habibulin for the 10 * TrustedBSD Project. 11 * 12 * This software was developed for the FreeBSD Project in part by McAfee 13 * Research, the Security Research Division of McAfee, Inc. under 14 * DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA 15 * CHATS research program. 16 * 17 * This software was enhanced by SPARTA ISSO under SPAWAR contract 18 * N66001-04-C-6019 ("SEFOS"). 19 * 20 * This software was developed at the University of Cambridge Computer 21 * Laboratory with support from a grant from Google, Inc. 22 * 23 * Redistribution and use in source and binary forms, with or without 24 * modification, are permitted provided that the following conditions 25 * are met: 26 * 1. Redistributions of source code must retain the above copyright 27 * notice, this list of conditions and the following disclaimer. 28 * 2. Redistributions in binary form must reproduce the above copyright 29 * notice, this list of conditions and the following disclaimer in the 30 * documentation and/or other materials provided with the distribution. 31 * 32 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 33 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 34 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 35 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 36 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 40 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 41 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 42 * SUCH DAMAGE. 43 */ 44 45#include <sys/cdefs.h> 46__FBSDID("$FreeBSD: head/sys/security/mac/mac_vfs.c 189503 2009-03-08 00:50:37Z rwatson $"); 47 48#include "opt_kdtrace.h" 49#include "opt_mac.h" 50 51#include <sys/param.h> 52#include <sys/condvar.h> 53#include <sys/extattr.h> 54#include <sys/imgact.h> 55#include <sys/kernel.h> 56#include <sys/lock.h> 57#include <sys/malloc.h> 58#include <sys/mutex.h> 59#include <sys/proc.h> 60#include <sys/sbuf.h> 61#include <sys/systm.h> 62#include <sys/vnode.h> 63#include <sys/mount.h> 64#include <sys/file.h> 65#include <sys/namei.h> 66#include <sys/sdt.h> 67#include <sys/sysctl.h> 68 69#include <vm/vm.h> 70#include <vm/pmap.h> 71#include <vm/vm_map.h> 72#include <vm/vm_object.h> 73 74#include <fs/devfs/devfs.h> 75 76#include <security/mac/mac_framework.h> 77#include <security/mac/mac_internal.h> 78#include <security/mac/mac_policy.h> 79 80/* 81 * Warn about EA transactions only the first time they happen. No locking on 82 * this variable. 83 */ 84static int ea_warn_once = 0; 85 86static int mac_vnode_setlabel_extattr(struct ucred *cred, 87 struct vnode *vp, struct label *intlabel); 88 89static struct label * 90mac_devfs_label_alloc(void) 91{ 92 struct label *label; 93 94 label = mac_labelzone_alloc(M_WAITOK); 95 MAC_PERFORM(devfs_init_label, label); 96 return (label); 97} 98 99void 100mac_devfs_init(struct devfs_dirent *de) 101{ 102 103 if (mac_labeled & MPC_OBJECT_DEVFS) 104 de->de_label = mac_devfs_label_alloc(); 105 else 106 de->de_label = NULL; 107} 108 109static struct label * 110mac_mount_label_alloc(void) 111{ 112 struct label *label; 113 114 label = mac_labelzone_alloc(M_WAITOK); 115 MAC_PERFORM(mount_init_label, label); 116 return (label); 117} 118 119void 120mac_mount_init(struct mount *mp) 121{ 122 123 if (mac_labeled & MPC_OBJECT_MOUNT) 124 mp->mnt_label = mac_mount_label_alloc(); 125 else 126 mp->mnt_label = NULL; 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(vnode_init_label, label); 136 return (label); 137} 138 139void 140mac_vnode_init(struct vnode *vp) 141{ 142 143 if (mac_labeled & MPC_OBJECT_VNODE) 144 vp->v_label = mac_vnode_label_alloc(); 145 else 146 vp->v_label = NULL; 147} 148 149static void 150mac_devfs_label_free(struct label *label) 151{ 152 153 MAC_PERFORM(devfs_destroy_label, label); 154 mac_labelzone_free(label); 155} 156 157void 158mac_devfs_destroy(struct devfs_dirent *de) 159{ 160 161 if (de->de_label != NULL) { 162 mac_devfs_label_free(de->de_label); 163 de->de_label = NULL; 164 } 165} 166 167static void 168mac_mount_label_free(struct label *label) 169{ 170 171 MAC_PERFORM(mount_destroy_label, label); 172 mac_labelzone_free(label); 173} 174 175void 176mac_mount_destroy(struct mount *mp) 177{ 178 179 if (mp->mnt_label != NULL) { 180 mac_mount_label_free(mp->mnt_label); 181 mp->mnt_label = NULL; 182 } 183} 184 185void 186mac_vnode_label_free(struct label *label) 187{ 188 189 MAC_PERFORM(vnode_destroy_label, label); 190 mac_labelzone_free(label); 191} 192 193void 194mac_vnode_destroy(struct vnode *vp) 195{ 196 197 if (vp->v_label != NULL) { 198 mac_vnode_label_free(vp->v_label); 199 vp->v_label = NULL; 200 } 201} 202 203void 204mac_vnode_copy_label(struct label *src, struct label *dest) 205{ 206 207 MAC_PERFORM(vnode_copy_label, src, dest); 208} 209 210int 211mac_vnode_externalize_label(struct label *label, char *elements, 212 char *outbuf, size_t outbuflen) 213{ 214 int error; 215 216 MAC_EXTERNALIZE(vnode, label, elements, outbuf, outbuflen); 217 218 return (error); 219} 220 221int 222mac_vnode_internalize_label(struct label *label, char *string) 223{ 224 int error; 225 226 MAC_INTERNALIZE(vnode, label, string); 227 228 return (error); 229} 230 231void 232mac_devfs_update(struct mount *mp, struct devfs_dirent *de, struct vnode *vp) 233{ 234 235 MAC_PERFORM(devfs_update, mp, de, de->de_label, vp, vp->v_label); 236} 237 238void 239mac_devfs_vnode_associate(struct mount *mp, struct devfs_dirent *de, 240 struct vnode *vp) 241{ 242 243 MAC_PERFORM(devfs_vnode_associate, mp, mp->mnt_label, de, 244 de->de_label, vp, vp->v_label); 245} 246 247int 248mac_vnode_associate_extattr(struct mount *mp, struct vnode *vp) 249{ 250 int error; 251 252 ASSERT_VOP_LOCKED(vp, "mac_vnode_associate_extattr"); 253 254 MAC_CHECK(vnode_associate_extattr, mp, mp->mnt_label, vp, 255 vp->v_label); 256 257 return (error); 258} 259 260void 261mac_vnode_associate_singlelabel(struct mount *mp, struct vnode *vp) 262{ 263 264 MAC_PERFORM(vnode_associate_singlelabel, mp, mp->mnt_label, vp, 265 vp->v_label); 266} 267 268/* 269 * Functions implementing extended-attribute backed labels for file systems 270 * that support it. 271 * 272 * Where possible, we use EA transactions to make writes to multiple 273 * attributes across difference policies mutually atomic. We allow work to 274 * continue on file systems not supporting EA transactions, but generate a 275 * printf warning. 276 */ 277int 278mac_vnode_create_extattr(struct ucred *cred, struct mount *mp, 279 struct vnode *dvp, struct vnode *vp, struct componentname *cnp) 280{ 281 int error; 282 283 ASSERT_VOP_LOCKED(dvp, "mac_vnode_create_extattr"); 284 ASSERT_VOP_LOCKED(vp, "mac_vnode_create_extattr"); 285 286 error = VOP_OPENEXTATTR(vp, cred, curthread); 287 if (error == EOPNOTSUPP) { 288 if (ea_warn_once == 0) { 289 printf("Warning: transactions not supported " 290 "in EA write.\n"); 291 ea_warn_once = 1; 292 } 293 } else if (error) 294 return (error); 295 296 MAC_CHECK(vnode_create_extattr, cred, mp, mp->mnt_label, dvp, 297 dvp->v_label, vp, vp->v_label, cnp); 298 299 if (error) { 300 VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread); 301 return (error); 302 } 303 304 error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread); 305 if (error == EOPNOTSUPP) 306 error = 0; 307 308 return (error); 309} 310 311static int 312mac_vnode_setlabel_extattr(struct ucred *cred, struct vnode *vp, 313 struct label *intlabel) 314{ 315 int error; 316 317 ASSERT_VOP_LOCKED(vp, "mac_vnode_setlabel_extattr"); 318 319 error = VOP_OPENEXTATTR(vp, cred, curthread); 320 if (error == EOPNOTSUPP) { 321 if (ea_warn_once == 0) { 322 printf("Warning: transactions not supported " 323 "in EA write.\n"); 324 ea_warn_once = 1; 325 } 326 } else if (error) 327 return (error); 328 329 MAC_CHECK(vnode_setlabel_extattr, cred, vp, vp->v_label, intlabel); 330 331 if (error) { 332 VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread); 333 return (error); 334 } 335 336 error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread); 337 if (error == EOPNOTSUPP) 338 error = 0; 339 340 return (error); 341} 342 343void 344mac_vnode_execve_transition(struct ucred *old, struct ucred *new, 345 struct vnode *vp, struct label *interpvplabel, struct image_params *imgp) 346{ 347 348 ASSERT_VOP_LOCKED(vp, "mac_vnode_execve_transition"); 349 350 MAC_PERFORM(vnode_execve_transition, old, new, vp, vp->v_label, 351 interpvplabel, imgp, imgp->execlabel); 352} 353 354int 355mac_vnode_execve_will_transition(struct ucred *old, struct vnode *vp, 356 struct label *interpvplabel, struct image_params *imgp) 357{ 358 int result; 359 360 ASSERT_VOP_LOCKED(vp, "mac_vnode_execve_will_transition"); 361 362 result = 0; 363 MAC_BOOLEAN(vnode_execve_will_transition, ||, old, vp, vp->v_label, 364 interpvplabel, imgp, imgp->execlabel); 365 366 return (result); 367} 368 369MAC_CHECK_PROBE_DEFINE3(vnode_check_access, "struct ucred *", 370 "struct vnode *", "accmode_t"); 371 372int 373mac_vnode_check_access(struct ucred *cred, struct vnode *vp, accmode_t accmode) 374{ 375 int error; 376 377 ASSERT_VOP_LOCKED(vp, "mac_vnode_check_access"); 378 379 MAC_CHECK(vnode_check_access, cred, vp, vp->v_label, accmode); 380 MAC_CHECK_PROBE3(vnode_check_access, error, cred, vp, accmode); 381 382 return (error); 383} 384 385MAC_CHECK_PROBE_DEFINE2(vnode_check_chdir, "struct ucred *", 386 "struct vnode *"); 387 388int 389mac_vnode_check_chdir(struct ucred *cred, struct vnode *dvp) 390{ 391 int error; 392 393 ASSERT_VOP_LOCKED(dvp, "mac_vnode_check_chdir"); 394 395 MAC_CHECK(vnode_check_chdir, cred, dvp, dvp->v_label); 396 MAC_CHECK_PROBE2(vnode_check_chdir, error, cred, dvp); 397 398 return (error); 399} 400 401MAC_CHECK_PROBE_DEFINE2(vnode_check_chroot, "struct ucred *", 402 "struct vnode *"); 403 404int 405mac_vnode_check_chroot(struct ucred *cred, struct vnode *dvp) 406{ 407 int error; 408 409 ASSERT_VOP_LOCKED(dvp, "mac_vnode_check_chroot"); 410 411 MAC_CHECK(vnode_check_chroot, cred, dvp, dvp->v_label); 412 MAC_CHECK_PROBE2(vnode_check_chroot, error, cred, dvp); 413 414 return (error); 415} 416 417MAC_CHECK_PROBE_DEFINE4(vnode_check_create, "struct ucred *", 418 "struct vnode *", "struct componentname *", "struct vattr *"); 419 420int 421mac_vnode_check_create(struct ucred *cred, struct vnode *dvp, 422 struct componentname *cnp, struct vattr *vap) 423{ 424 int error; 425 426 ASSERT_VOP_LOCKED(dvp, "mac_vnode_check_create"); 427 428 MAC_CHECK(vnode_check_create, cred, dvp, dvp->v_label, cnp, vap); 429 MAC_CHECK_PROBE4(vnode_check_create, error, cred, dvp, cnp, vap); 430 431 return (error); 432} 433 434MAC_CHECK_PROBE_DEFINE3(vnode_check_deleteacl, "struct ucred *", 435 "struct vnode *", "acl_type_t"); 436 437int 438mac_vnode_check_deleteacl(struct ucred *cred, struct vnode *vp, 439 acl_type_t type) 440{ 441 int error; 442 443 ASSERT_VOP_LOCKED(vp, "mac_vnode_check_deleteacl"); 444 445 MAC_CHECK(vnode_check_deleteacl, cred, vp, vp->v_label, type); 446 MAC_CHECK_PROBE3(vnode_check_deleteacl, error, cred, vp, type); 447 448 return (error); 449} 450 451MAC_CHECK_PROBE_DEFINE4(vnode_check_deleteextattr, "struct ucred *", 452 "struct vnode *", "int", "const char *"); 453 454int 455mac_vnode_check_deleteextattr(struct ucred *cred, struct vnode *vp, 456 int attrnamespace, const char *name) 457{ 458 int error; 459 460 ASSERT_VOP_LOCKED(vp, "mac_vnode_check_deleteextattr"); 461 462 MAC_CHECK(vnode_check_deleteextattr, cred, vp, vp->v_label, 463 attrnamespace, name); 464 MAC_CHECK_PROBE4(vnode_check_deleteextattr, error, cred, vp, 465 attrnamespace, name); 466 467 return (error); 468} 469 470MAC_CHECK_PROBE_DEFINE3(vnode_check_exec, "struct ucred *", "struct vnode *", 471 "struct image_params *"); 472 473int 474mac_vnode_check_exec(struct ucred *cred, struct vnode *vp, 475 struct image_params *imgp) 476{ 477 int error; 478 479 ASSERT_VOP_LOCKED(vp, "mac_vnode_check_exec"); 480 481 MAC_CHECK(vnode_check_exec, cred, vp, vp->v_label, imgp, 482 imgp->execlabel); 483 MAC_CHECK_PROBE3(vnode_check_exec, error, cred, vp, imgp); 484 485 return (error); 486} 487 488MAC_CHECK_PROBE_DEFINE3(vnode_check_getacl, "struct ucred *", 489 "struct vnode *", "acl_type_t"); 490 491int 492mac_vnode_check_getacl(struct ucred *cred, struct vnode *vp, acl_type_t type) 493{ 494 int error; 495 496 ASSERT_VOP_LOCKED(vp, "mac_vnode_check_getacl"); 497 498 MAC_CHECK(vnode_check_getacl, cred, vp, vp->v_label, type); 499 MAC_CHECK_PROBE3(vnode_check_getacl, error, cred, vp, type); 500 501 return (error); 502} 503 504MAC_CHECK_PROBE_DEFINE4(vnode_check_getextattr, "struct ucred *", 505 "struct vnode *", "int", "const char *"); 506 507int 508mac_vnode_check_getextattr(struct ucred *cred, struct vnode *vp, 509 int attrnamespace, const char *name, struct uio *uio) 510{ 511 int error; 512 513 ASSERT_VOP_LOCKED(vp, "mac_vnode_check_getextattr"); 514 515 MAC_CHECK(vnode_check_getextattr, cred, vp, vp->v_label, 516 attrnamespace, name, uio); 517 MAC_CHECK_PROBE4(vnode_check_getextattr, error, cred, vp, 518 attrnamespace, name); 519 520 return (error); 521} 522 523MAC_CHECK_PROBE_DEFINE4(vnode_check_link, "struct ucred *", "struct vnode *", 524 "struct vnode *", "struct componentname *"); 525 526int 527mac_vnode_check_link(struct ucred *cred, struct vnode *dvp, 528 struct vnode *vp, struct componentname *cnp) 529{ 530 int error; 531 532 ASSERT_VOP_LOCKED(dvp, "mac_vnode_check_link"); 533 ASSERT_VOP_LOCKED(vp, "mac_vnode_check_link"); 534 535 MAC_CHECK(vnode_check_link, cred, dvp, dvp->v_label, vp, 536 vp->v_label, cnp); 537 MAC_CHECK_PROBE4(vnode_check_link, error, cred, dvp, vp, cnp); 538 539 return (error); 540} 541 542MAC_CHECK_PROBE_DEFINE3(vnode_check_listextattr, "struct ucred *", 543 "struct vnode *", "int"); 544 545int 546mac_vnode_check_listextattr(struct ucred *cred, struct vnode *vp, 547 int attrnamespace) 548{ 549 int error; 550 551 ASSERT_VOP_LOCKED(vp, "mac_vnode_check_listextattr"); 552 553 MAC_CHECK(vnode_check_listextattr, cred, vp, vp->v_label, 554 attrnamespace); 555 MAC_CHECK_PROBE3(vnode_check_listextattr, error, cred, vp, 556 attrnamespace); 557 558 return (error); 559} 560 561MAC_CHECK_PROBE_DEFINE3(vnode_check_lookup, "struct ucred *", 562 "struct vnode *", "struct componentname *"); 563 564int 565mac_vnode_check_lookup(struct ucred *cred, struct vnode *dvp, 566 struct componentname *cnp) 567{ 568 int error; 569 570 ASSERT_VOP_LOCKED(dvp, "mac_vnode_check_lookup"); 571 572 MAC_CHECK(vnode_check_lookup, cred, dvp, dvp->v_label, cnp); 573 MAC_CHECK_PROBE3(vnode_check_lookup, error, cred, dvp, cnp); 574 575 return (error); 576} 577 578MAC_CHECK_PROBE_DEFINE4(vnode_check_mmap, "struct ucred *", "struct vnode *", 579 "int", "int"); 580 581int 582mac_vnode_check_mmap(struct ucred *cred, struct vnode *vp, int prot, 583 int flags) 584{ 585 int error; 586 587 ASSERT_VOP_LOCKED(vp, "mac_vnode_check_mmap"); 588 589 MAC_CHECK(vnode_check_mmap, cred, vp, vp->v_label, prot, flags); 590 MAC_CHECK_PROBE4(vnode_check_mmap, error, cred, vp, prot, flags); 591 592 return (error); 593} 594 595void 596mac_vnode_check_mmap_downgrade(struct ucred *cred, struct vnode *vp, 597 int *prot) 598{ 599 int result = *prot; 600 601 ASSERT_VOP_LOCKED(vp, "mac_vnode_check_mmap_downgrade"); 602 603 MAC_PERFORM(vnode_check_mmap_downgrade, cred, vp, vp->v_label, 604 &result); 605 606 *prot = result; 607} 608 609MAC_CHECK_PROBE_DEFINE3(vnode_check_mprotect, "struct ucred *", 610 "struct vnode *", "int"); 611 612int 613mac_vnode_check_mprotect(struct ucred *cred, struct vnode *vp, int prot) 614{ 615 int error; 616 617 ASSERT_VOP_LOCKED(vp, "mac_vnode_check_mprotect"); 618 619 MAC_CHECK(vnode_check_mprotect, cred, vp, vp->v_label, prot); 620 MAC_CHECK_PROBE3(vnode_check_mprotect, error, cred, vp, prot); 621 622 return (error); 623} 624 625MAC_CHECK_PROBE_DEFINE3(vnode_check_open, "struct ucred *", "struct vnode *", 626 "accmode_t"); 627 628int 629mac_vnode_check_open(struct ucred *cred, struct vnode *vp, accmode_t accmode) 630{ 631 int error; 632 633 ASSERT_VOP_LOCKED(vp, "mac_vnode_check_open"); 634 635 MAC_CHECK(vnode_check_open, cred, vp, vp->v_label, accmode); 636 return (error); 637} 638 639MAC_CHECK_PROBE_DEFINE3(vnode_check_poll, "struct ucred *", "struct ucred *", 640 "struct vnode *"); 641 642int 643mac_vnode_check_poll(struct ucred *active_cred, struct ucred *file_cred, 644 struct vnode *vp) 645{ 646 int error; 647 648 ASSERT_VOP_LOCKED(vp, "mac_vnode_check_poll"); 649 650 MAC_CHECK(vnode_check_poll, active_cred, file_cred, vp, 651 vp->v_label); 652 MAC_CHECK_PROBE3(vnode_check_poll, error, active_cred, file_cred, 653 vp); 654 655 return (error); 656} 657 658MAC_CHECK_PROBE_DEFINE3(vnode_check_read, "struct ucred *", "struct ucred *", 659 "struct vnode *"); 660 661int 662mac_vnode_check_read(struct ucred *active_cred, struct ucred *file_cred, 663 struct vnode *vp) 664{ 665 int error; 666 667 ASSERT_VOP_LOCKED(vp, "mac_vnode_check_read"); 668 669 MAC_CHECK(vnode_check_read, active_cred, file_cred, vp, 670 vp->v_label); 671 MAC_CHECK_PROBE3(vnode_check_read, error, active_cred, file_cred, 672 vp); 673 674 return (error); 675} 676 677MAC_CHECK_PROBE_DEFINE2(vnode_check_readdir, "struct ucred *", 678 "struct vnode *"); 679 680int 681mac_vnode_check_readdir(struct ucred *cred, struct vnode *dvp) 682{ 683 int error; 684 685 ASSERT_VOP_LOCKED(dvp, "mac_vnode_check_readdir"); 686 687 MAC_CHECK(vnode_check_readdir, cred, dvp, dvp->v_label); 688 MAC_CHECK_PROBE2(vnode_check_readdir, error, cred, dvp); 689 690 return (error); 691} 692 693MAC_CHECK_PROBE_DEFINE2(vnode_check_readlink, "struct ucred *", 694 "struct vnode *"); 695 696int 697mac_vnode_check_readlink(struct ucred *cred, struct vnode *vp) 698{ 699 int error; 700 701 ASSERT_VOP_LOCKED(vp, "mac_vnode_check_readlink"); 702 703 MAC_CHECK(vnode_check_readlink, cred, vp, vp->v_label); 704 MAC_CHECK_PROBE2(vnode_check_readlink, error, cred, vp); 705 706 return (error); 707} 708 709MAC_CHECK_PROBE_DEFINE3(vnode_check_relabel, "struct ucred *", 710 "struct vnode *", "struct label *"); 711 712static int 713mac_vnode_check_relabel(struct ucred *cred, struct vnode *vp, 714 struct label *newlabel) 715{ 716 int error; 717 718 ASSERT_VOP_LOCKED(vp, "mac_vnode_check_relabel"); 719 720 MAC_CHECK(vnode_check_relabel, cred, vp, vp->v_label, newlabel); 721 MAC_CHECK_PROBE3(vnode_check_relabel, error, cred, vp, newlabel); 722 723 return (error); 724} 725 726MAC_CHECK_PROBE_DEFINE4(vnode_check_rename_from, "struct ucred *", 727 "struct vnode *", "struct vnode *", "struct componentname *"); 728 729int 730mac_vnode_check_rename_from(struct ucred *cred, struct vnode *dvp, 731 struct vnode *vp, struct componentname *cnp) 732{ 733 int error; 734 735 ASSERT_VOP_LOCKED(dvp, "mac_vnode_check_rename_from"); 736 ASSERT_VOP_LOCKED(vp, "mac_vnode_check_rename_from"); 737 738 MAC_CHECK(vnode_check_rename_from, cred, dvp, dvp->v_label, vp, 739 vp->v_label, cnp); 740 MAC_CHECK_PROBE4(vnode_check_rename_from, error, cred, dvp, vp, cnp); 741 742 return (error); 743} 744 745MAC_CHECK_PROBE_DEFINE4(vnode_check_rename_to, "struct ucred *", 746 "struct vnode *", "struct vnode *", "struct componentname *"); 747 748int 749mac_vnode_check_rename_to(struct ucred *cred, struct vnode *dvp, 750 struct vnode *vp, int samedir, struct componentname *cnp) 751{ 752 int error; 753 754 ASSERT_VOP_LOCKED(dvp, "mac_vnode_check_rename_to"); 755 ASSERT_VOP_LOCKED(vp, "mac_vnode_check_rename_to"); 756 757 MAC_CHECK(vnode_check_rename_to, cred, dvp, dvp->v_label, vp, 758 vp != NULL ? vp->v_label : NULL, samedir, cnp); 759 MAC_CHECK_PROBE4(vnode_check_rename_to, error, cred, dvp, vp, cnp); 760 return (error); 761} 762 763MAC_CHECK_PROBE_DEFINE2(vnode_check_revoke, "struct ucred *", 764 "struct vnode *"); 765 766int 767mac_vnode_check_revoke(struct ucred *cred, struct vnode *vp) 768{ 769 int error; 770 771 ASSERT_VOP_LOCKED(vp, "mac_vnode_check_revoke"); 772 773 MAC_CHECK(vnode_check_revoke, cred, vp, vp->v_label); 774 MAC_CHECK_PROBE2(vnode_check_revoke, error, cred, vp); 775 776 return (error); 777} 778 779MAC_CHECK_PROBE_DEFINE4(vnode_check_setacl, "struct ucred *", 780 "struct vnode *", "acl_tpe_t", "struct acl *"); 781 782int 783mac_vnode_check_setacl(struct ucred *cred, struct vnode *vp, acl_type_t type, 784 struct acl *acl) 785{ 786 int error; 787 788 ASSERT_VOP_LOCKED(vp, "mac_vnode_check_setacl"); 789 790 MAC_CHECK(vnode_check_setacl, cred, vp, vp->v_label, type, acl); 791 MAC_CHECK_PROBE4(vnode_check_setacl, error, cred, vp, type, acl); 792 793 return (error); 794} 795 796MAC_CHECK_PROBE_DEFINE4(vnode_check_setextattr, "struct ucred *", 797 "struct vnode *", "int", "const char *"); 798 799int 800mac_vnode_check_setextattr(struct ucred *cred, struct vnode *vp, 801 int attrnamespace, const char *name, struct uio *uio) 802{ 803 int error; 804 805 ASSERT_VOP_LOCKED(vp, "mac_vnode_check_setextattr"); 806 807 MAC_CHECK(vnode_check_setextattr, cred, vp, vp->v_label, 808 attrnamespace, name, uio); 809 MAC_CHECK_PROBE4(vnode_check_setextattr, error, cred, vp, 810 attrnamespace, name); 811 812 return (error); 813} 814 815MAC_CHECK_PROBE_DEFINE3(vnode_check_setflags, "struct ucred *", 816 "struct vnode *", "u_long"); 817 818int 819mac_vnode_check_setflags(struct ucred *cred, struct vnode *vp, u_long flags) 820{ 821 int error; 822 823 ASSERT_VOP_LOCKED(vp, "mac_vnode_check_setflags"); 824 825 MAC_CHECK(vnode_check_setflags, cred, vp, vp->v_label, flags); 826 MAC_CHECK_PROBE3(vnode_check_setflags, error, cred, vp, flags); 827 828 return (error); 829} 830 831MAC_CHECK_PROBE_DEFINE3(vnode_check_setmode, "struct ucred *", 832 "struct vnode *", "mode_t"); 833 834int 835mac_vnode_check_setmode(struct ucred *cred, struct vnode *vp, mode_t mode) 836{ 837 int error; 838 839 ASSERT_VOP_LOCKED(vp, "mac_vnode_check_setmode"); 840 841 MAC_CHECK(vnode_check_setmode, cred, vp, vp->v_label, mode); 842 MAC_CHECK_PROBE3(vnode_check_setmode, error, cred, vp, mode); 843 844 return (error); 845} 846 847MAC_CHECK_PROBE_DEFINE4(vnode_check_setowner, "struct ucred *", 848 "struct vnode *", "uid_t", "gid_t"); 849 850int 851mac_vnode_check_setowner(struct ucred *cred, struct vnode *vp, uid_t uid, 852 gid_t gid) 853{ 854 int error; 855 856 ASSERT_VOP_LOCKED(vp, "mac_vnode_check_setowner"); 857 858 MAC_CHECK(vnode_check_setowner, cred, vp, vp->v_label, uid, gid); 859 MAC_CHECK_PROBE4(vnode_check_setowner, error, cred, vp, uid, gid); 860 861 return (error); 862} 863 864MAC_CHECK_PROBE_DEFINE4(vnode_check_setutimes, "struct ucred *", 865 "struct vnode *", "struct timespec *", "struct timespec *"); 866 867int 868mac_vnode_check_setutimes(struct ucred *cred, struct vnode *vp, 869 struct timespec atime, struct timespec mtime) 870{ 871 int error; 872 873 ASSERT_VOP_LOCKED(vp, "mac_vnode_check_setutimes"); 874 875 MAC_CHECK(vnode_check_setutimes, cred, vp, vp->v_label, atime, 876 mtime); 877 MAC_CHECK_PROBE4(vnode_check_setutimes, error, cred, vp, &atime, 878 &mtime); 879 880 return (error); 881} 882 883MAC_CHECK_PROBE_DEFINE3(vnode_check_stat, "struct ucred *", "struct ucred *", 884 "struct vnode *"); 885 886int 887mac_vnode_check_stat(struct ucred *active_cred, struct ucred *file_cred, 888 struct vnode *vp) 889{ 890 int error; 891 892 ASSERT_VOP_LOCKED(vp, "mac_vnode_check_stat"); 893 894 MAC_CHECK(vnode_check_stat, active_cred, file_cred, vp, 895 vp->v_label); 896 MAC_CHECK_PROBE3(vnode_check_stat, error, active_cred, file_cred, 897 vp); 898 899 return (error); 900} 901 902MAC_CHECK_PROBE_DEFINE4(vnode_check_unlink, "struct ucred *", 903 "struct vnode *", "struct vnode *", "struct componentname *"); 904 905int 906mac_vnode_check_unlink(struct ucred *cred, struct vnode *dvp, 907 struct vnode *vp, struct componentname *cnp) 908{ 909 int error; 910 911 ASSERT_VOP_LOCKED(dvp, "mac_vnode_check_unlink"); 912 ASSERT_VOP_LOCKED(vp, "mac_vnode_check_unlink"); 913 914 MAC_CHECK(vnode_check_unlink, cred, dvp, dvp->v_label, vp, 915 vp->v_label, cnp); 916 MAC_CHECK_PROBE4(vnode_check_unlink, error, cred, dvp, vp, cnp); 917 918 return (error); 919} 920 921MAC_CHECK_PROBE_DEFINE3(vnode_check_write, "struct ucred *", 922 "struct ucred *", "struct vnode *"); 923 924int 925mac_vnode_check_write(struct ucred *active_cred, struct ucred *file_cred, 926 struct vnode *vp) 927{ 928 int error; 929 930 ASSERT_VOP_LOCKED(vp, "mac_vnode_check_write"); 931 932 MAC_CHECK(vnode_check_write, active_cred, file_cred, vp, 933 vp->v_label); 934 MAC_CHECK_PROBE3(vnode_check_write, error, active_cred, file_cred, 935 vp); 936 937 return (error); 938} 939 940void 941mac_vnode_relabel(struct ucred *cred, struct vnode *vp, 942 struct label *newlabel) 943{ 944 945 MAC_PERFORM(vnode_relabel, cred, vp, vp->v_label, newlabel); 946} 947 948void 949mac_mount_create(struct ucred *cred, struct mount *mp) 950{ 951 952 MAC_PERFORM(mount_create, cred, mp, mp->mnt_label); 953} 954 955MAC_CHECK_PROBE_DEFINE2(mount_check_stat, "struct ucred *", 956 "struct mount *"); 957 958int 959mac_mount_check_stat(struct ucred *cred, struct mount *mount) 960{ 961 int error; 962 963 MAC_CHECK(mount_check_stat, cred, mount, mount->mnt_label); 964 MAC_CHECK_PROBE2(mount_check_stat, error, cred, mount); 965 966 return (error); 967} 968 969void 970mac_devfs_create_device(struct ucred *cred, struct mount *mp, 971 struct cdev *dev, struct devfs_dirent *de) 972{ 973 974 MAC_PERFORM(devfs_create_device, cred, mp, dev, de, de->de_label); 975} 976 977void 978mac_devfs_create_symlink(struct ucred *cred, struct mount *mp, 979 struct devfs_dirent *dd, struct devfs_dirent *de) 980{ 981 982 MAC_PERFORM(devfs_create_symlink, cred, mp, dd, dd->de_label, de, 983 de->de_label); 984} 985 986void 987mac_devfs_create_directory(struct mount *mp, char *dirname, int dirnamelen, 988 struct devfs_dirent *de) 989{ 990 991 MAC_PERFORM(devfs_create_directory, mp, dirname, dirnamelen, de, 992 de->de_label); 993} 994 995/* 996 * Implementation of VOP_SETLABEL() that relies on extended attributes to 997 * store label data. Can be referenced by filesystems supporting extended 998 * attributes. 999 */ 1000int 1001vop_stdsetlabel_ea(struct vop_setlabel_args *ap) 1002{ 1003 struct vnode *vp = ap->a_vp; 1004 struct label *intlabel = ap->a_label; 1005 int error; 1006 1007 ASSERT_VOP_LOCKED(vp, "vop_stdsetlabel_ea"); 1008 1009 if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) 1010 return (EOPNOTSUPP); 1011 1012 error = mac_vnode_setlabel_extattr(ap->a_cred, vp, intlabel); 1013 if (error) 1014 return (error); 1015 1016 mac_vnode_relabel(ap->a_cred, vp, intlabel); 1017 1018 return (0); 1019} 1020 1021int 1022vn_setlabel(struct vnode *vp, struct label *intlabel, struct ucred *cred) 1023{ 1024 int error; 1025 1026 if (vp->v_mount == NULL) { 1027 /* printf("vn_setlabel: null v_mount\n"); */ 1028 if (vp->v_type != VNON) 1029 printf("vn_setlabel: null v_mount with non-VNON\n"); 1030 return (EBADF); 1031 } 1032 1033 if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) 1034 return (EOPNOTSUPP); 1035 1036 /* 1037 * Multi-phase commit. First check the policies to confirm the 1038 * change is OK. Then commit via the filesystem. Finally, update 1039 * the actual vnode label. 1040 * 1041 * Question: maybe the filesystem should update the vnode at the end 1042 * as part of VOP_SETLABEL()? 1043 */ 1044 error = mac_vnode_check_relabel(cred, vp, intlabel); 1045 if (error) 1046 return (error); 1047 1048 /* 1049 * VADMIN provides the opportunity for the filesystem to make 1050 * decisions about who is and is not able to modify labels and 1051 * protections on files. This might not be right. We can't assume 1052 * VOP_SETLABEL() will do it, because we might implement that as part 1053 * of vop_stdsetlabel_ea(). 1054 */ 1055 error = VOP_ACCESS(vp, VADMIN, cred, curthread); 1056 if (error) 1057 return (error); 1058 1059 error = VOP_SETLABEL(vp, intlabel, cred, curthread); 1060 if (error) 1061 return (error); 1062 1063 return (0); 1064} 1065