1/*- 2 * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson 3 * Copyright (c) 2001 Ilmar S. Habibulin 4 * Copyright (c) 2001, 2002, 2003 Networks Associates Technology, Inc. 5 * All rights reserved. 6 * 7 * This software was developed by Robert Watson and Ilmar Habibulin for the 8 * TrustedBSD Project. --- 28 unchanged lines hidden (view full) --- 37/*- 38 * Framework for extensible kernel access control. This file contains 39 * Kernel and userland interface to the framework, policy registration 40 * and composition. Per-object interfaces, controls, and labeling may be 41 * found in src/sys/mac/. Sample policies may be found in src/sys/mac*. 42 */ 43 44#include <sys/cdefs.h> |
45__FBSDID("$FreeBSD: head/sys/security/mac/mac_framework.c 122524 2003-11-12 03:14:31Z rwatson $"); |
46 47#include "opt_mac.h" 48#include "opt_devfs.h" 49 50#include <sys/param.h> 51#include <sys/condvar.h> 52#include <sys/extattr.h> 53#include <sys/imgact.h> --- 197 unchanged lines hidden (view full) --- 251 * Initialize the MAC subsystem, including appropriate SMP locks. 252 */ 253static void 254mac_init(void) 255{ 256 257 LIST_INIT(&mac_static_policy_list); 258 LIST_INIT(&mac_policy_list); |
259 mac_labelzone_init(); |
260 261 mtx_init(&mac_policy_mtx, "mac_policy_mtx", NULL, MTX_DEF); 262 cv_init(&mac_policy_cv, "mac_policy_cv"); 263} 264 265/* 266 * For the purposes of modules that want to know if they were loaded 267 * "early", set the mac_late flag once we've processed modules either --- 293 unchanged lines hidden (view full) --- 561 error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 562 if (error) { 563 free(elements, M_MACTEMP); 564 crfree(tcred); 565 return (error); 566 } 567 568 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); |
569 error = mac_externalize_cred_label(tcred->cr_label, elements, |
570 buffer, mac.m_buflen); 571 if (error == 0) 572 error = copyout(buffer, mac.m_string, strlen(buffer)+1); 573 574 free(buffer, M_MACTEMP); 575 free(elements, M_MACTEMP); 576 crfree(tcred); 577 return (error); --- 20 unchanged lines hidden (view full) --- 598 elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 599 error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 600 if (error) { 601 free(elements, M_MACTEMP); 602 return (error); 603 } 604 605 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); |
606 error = mac_externalize_cred_label(td->td_ucred->cr_label, |
607 elements, buffer, mac.m_buflen); 608 if (error == 0) 609 error = copyout(buffer, mac.m_string, strlen(buffer)+1); 610 611 free(buffer, M_MACTEMP); 612 free(elements, M_MACTEMP); 613 return (error); 614} 615 616/* 617 * MPSAFE 618 */ 619int 620__mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) 621{ 622 struct ucred *newcred, *oldcred; |
623 struct label *intlabel; |
624 struct proc *p; 625 struct mac mac; 626 char *buffer; 627 int error; 628 629 error = copyin(uap->mac_p, &mac, sizeof(mac)); 630 if (error) 631 return (error); --- 4 unchanged lines hidden (view full) --- 636 637 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 638 error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 639 if (error) { 640 free(buffer, M_MACTEMP); 641 return (error); 642 } 643 |
644 intlabel = mac_cred_label_alloc(); 645 error = mac_internalize_cred_label(intlabel, buffer); |
646 free(buffer, M_MACTEMP); |
647 if (error) 648 goto out; |
649 650 newcred = crget(); 651 652 p = td->td_proc; 653 PROC_LOCK(p); 654 oldcred = p->p_ucred; 655 |
656 error = mac_check_cred_relabel(oldcred, intlabel); |
657 if (error) { 658 PROC_UNLOCK(p); 659 crfree(newcred); 660 goto out; 661 } 662 663 setsugid(p); 664 crcopy(newcred, oldcred); |
665 mac_relabel_cred(newcred, intlabel); |
666 p->p_ucred = newcred; 667 668 /* 669 * Grab additional reference for use while revoking mmaps, prior 670 * to releasing the proc lock and sharing the cred. 671 */ 672 crhold(newcred); 673 PROC_UNLOCK(p); 674 675 if (mac_enforce_vm) { 676 mtx_lock(&Giant); 677 mac_cred_mmapped_drop_perms(td, newcred); 678 mtx_unlock(&Giant); 679 } 680 681 crfree(newcred); /* Free revocation reference. */ 682 crfree(oldcred); 683 684out: |
685 mac_cred_label_free(intlabel); |
686 return (error); 687} 688 689/* 690 * MPSAFE 691 */ 692int 693__mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) 694{ 695 char *elements, *buffer; |
696 struct label *intlabel; |
697 struct file *fp; 698 struct mac mac; 699 struct vnode *vp; 700 struct pipe *pipe; 701 short label_type; 702 int error; 703 704 error = copyin(uap->mac_p, &mac, sizeof(mac)); --- 18 unchanged lines hidden (view full) --- 723 goto out; 724 725 label_type = fp->f_type; 726 switch (fp->f_type) { 727 case DTYPE_FIFO: 728 case DTYPE_VNODE: 729 vp = fp->f_vnode; 730 |
731 intlabel = mac_vnode_label_alloc(); |
732 733 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); |
734 mac_copy_vnode_label(vp->v_label, intlabel); |
735 VOP_UNLOCK(vp, 0, td); 736 737 break; 738 case DTYPE_PIPE: 739 pipe = fp->f_data; 740 |
741 intlabel = mac_pipe_label_alloc(); |
742 743 PIPE_LOCK(pipe); |
744 mac_copy_pipe_label(pipe->pipe_label, intlabel); |
745 PIPE_UNLOCK(pipe); 746 break; 747 default: 748 error = EINVAL; 749 fdrop(fp, td); 750 goto out; 751 } 752 fdrop(fp, td); 753 754 switch (label_type) { 755 case DTYPE_FIFO: 756 case DTYPE_VNODE: 757 if (error == 0) |
758 error = mac_externalize_vnode_label(intlabel, |
759 elements, buffer, mac.m_buflen); |
760 mac_vnode_label_free(intlabel); |
761 break; 762 case DTYPE_PIPE: |
763 error = mac_externalize_pipe_label(intlabel, elements, |
764 buffer, mac.m_buflen); |
765 mac_pipe_label_free(intlabel); |
766 break; 767 default: 768 panic("__mac_get_fd: corrupted label_type"); 769 } 770 771 if (error == 0) 772 error = copyout(buffer, mac.m_string, strlen(buffer)+1); 773 --- 8 unchanged lines hidden (view full) --- 782/* 783 * MPSAFE 784 */ 785int 786__mac_get_file(struct thread *td, struct __mac_get_file_args *uap) 787{ 788 char *elements, *buffer; 789 struct nameidata nd; |
790 struct label *intlabel; |
791 struct mac mac; 792 int error; 793 794 error = copyin(uap->mac_p, &mac, sizeof(mac)); 795 if (error) 796 return (error); 797 798 error = mac_check_structmac_consistent(&mac); --- 10 unchanged lines hidden (view full) --- 809 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 810 mtx_lock(&Giant); /* VFS */ 811 NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, uap->path_p, 812 td); 813 error = namei(&nd); 814 if (error) 815 goto out; 816 |
817 intlabel = mac_vnode_label_alloc(); 818 mac_copy_vnode_label(nd.ni_vp->v_label, intlabel); 819 error = mac_externalize_vnode_label(intlabel, elements, buffer, |
820 mac.m_buflen); 821 822 NDFREE(&nd, 0); |
823 mac_vnode_label_free(intlabel); |
824 825 if (error == 0) 826 error = copyout(buffer, mac.m_string, strlen(buffer)+1); 827 828out: 829 mtx_unlock(&Giant); /* VFS */ 830 831 free(buffer, M_MACTEMP); --- 5 unchanged lines hidden (view full) --- 837/* 838 * MPSAFE 839 */ 840int 841__mac_get_link(struct thread *td, struct __mac_get_link_args *uap) 842{ 843 char *elements, *buffer; 844 struct nameidata nd; |
845 struct label *intlabel; |
846 struct mac mac; 847 int error; 848 849 error = copyin(uap->mac_p, &mac, sizeof(mac)); 850 if (error) 851 return (error); 852 853 error = mac_check_structmac_consistent(&mac); --- 10 unchanged lines hidden (view full) --- 864 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 865 mtx_lock(&Giant); /* VFS */ 866 NDINIT(&nd, LOOKUP, LOCKLEAF | NOFOLLOW, UIO_USERSPACE, uap->path_p, 867 td); 868 error = namei(&nd); 869 if (error) 870 goto out; 871 |
872 intlabel = mac_vnode_label_alloc(); 873 mac_copy_vnode_label(nd.ni_vp->v_label, intlabel); 874 error = mac_externalize_vnode_label(intlabel, elements, buffer, |
875 mac.m_buflen); 876 NDFREE(&nd, 0); |
877 mac_vnode_label_free(intlabel); |
878 879 if (error == 0) 880 error = copyout(buffer, mac.m_string, strlen(buffer)+1); 881 882out: 883 mtx_unlock(&Giant); /* VFS */ 884 885 free(buffer, M_MACTEMP); 886 free(elements, M_MACTEMP); 887 888 return (error); 889} 890 891/* 892 * MPSAFE 893 */ 894int 895__mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) 896{ |
897 struct label *intlabel; |
898 struct pipe *pipe; 899 struct file *fp; 900 struct mount *mp; 901 struct vnode *vp; 902 struct mac mac; 903 char *buffer; 904 int error; 905 --- 16 unchanged lines hidden (view full) --- 922 923 error = fget(td, uap->fd, &fp); 924 if (error) 925 goto out; 926 927 switch (fp->f_type) { 928 case DTYPE_FIFO: 929 case DTYPE_VNODE: |
930 intlabel = mac_vnode_label_alloc(); 931 error = mac_internalize_vnode_label(intlabel, buffer); |
932 if (error) { |
933 mac_vnode_label_free(intlabel); |
934 break; 935 } 936 937 vp = fp->f_vnode; 938 error = vn_start_write(vp, &mp, V_WAIT | PCATCH); 939 if (error != 0) { |
940 mac_vnode_label_free(intlabel); |
941 break; 942 } 943 944 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); |
945 error = vn_setlabel(vp, intlabel, td->td_ucred); |
946 VOP_UNLOCK(vp, 0, td); 947 vn_finished_write(mp); 948 |
949 mac_vnode_label_free(intlabel); |
950 break; 951 952 case DTYPE_PIPE: |
953 intlabel = mac_pipe_label_alloc(); 954 error = mac_internalize_pipe_label(intlabel, buffer); |
955 if (error == 0) { 956 pipe = fp->f_data; 957 PIPE_LOCK(pipe); 958 error = mac_pipe_label_set(td->td_ucred, pipe, |
959 intlabel); |
960 PIPE_UNLOCK(pipe); 961 } 962 |
963 mac_pipe_label_free(intlabel); |
964 break; 965 966 default: 967 error = EINVAL; 968 } 969 970 fdrop(fp, td); 971out: --- 5 unchanged lines hidden (view full) --- 977} 978 979/* 980 * MPSAFE 981 */ 982int 983__mac_set_file(struct thread *td, struct __mac_set_file_args *uap) 984{ |
985 struct label *intlabel; |
986 struct nameidata nd; 987 struct mount *mp; 988 struct mac mac; 989 char *buffer; 990 int error; 991 992 error = copyin(uap->mac_p, &mac, sizeof(mac)); 993 if (error) --- 5 unchanged lines hidden (view full) --- 999 1000 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 1001 error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 1002 if (error) { 1003 free(buffer, M_MACTEMP); 1004 return (error); 1005 } 1006 |
1007 intlabel = mac_vnode_label_alloc(); 1008 error = mac_internalize_vnode_label(intlabel, buffer); |
1009 free(buffer, M_MACTEMP); |
1010 if (error) 1011 goto out; |
1012 1013 mtx_lock(&Giant); /* VFS */ 1014 1015 NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, uap->path_p, 1016 td); 1017 error = namei(&nd); 1018 if (error == 0) { 1019 error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); 1020 if (error == 0) |
1021 error = vn_setlabel(nd.ni_vp, intlabel, |
1022 td->td_ucred); 1023 vn_finished_write(mp); 1024 } 1025 1026 NDFREE(&nd, 0); 1027 mtx_unlock(&Giant); /* VFS */ |
1028out: 1029 mac_vnode_label_free(intlabel); |
1030 return (error); 1031} 1032 1033/* 1034 * MPSAFE 1035 */ 1036int 1037__mac_set_link(struct thread *td, struct __mac_set_link_args *uap) 1038{ |
1039 struct label *intlabel; |
1040 struct nameidata nd; 1041 struct mount *mp; 1042 struct mac mac; 1043 char *buffer; 1044 int error; 1045 1046 error = copyin(uap->mac_p, &mac, sizeof(mac)); 1047 if (error) --- 5 unchanged lines hidden (view full) --- 1053 1054 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 1055 error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 1056 if (error) { 1057 free(buffer, M_MACTEMP); 1058 return (error); 1059 } 1060 |
1061 intlabel = mac_vnode_label_alloc(); 1062 error = mac_internalize_vnode_label(intlabel, buffer); |
1063 free(buffer, M_MACTEMP); |
1064 if (error) 1065 goto out; |
1066 1067 mtx_lock(&Giant); /* VFS */ 1068 1069 NDINIT(&nd, LOOKUP, LOCKLEAF | NOFOLLOW, UIO_USERSPACE, uap->path_p, 1070 td); 1071 error = namei(&nd); 1072 if (error == 0) { 1073 error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); 1074 if (error == 0) |
1075 error = vn_setlabel(nd.ni_vp, intlabel, |
1076 td->td_ucred); 1077 vn_finished_write(mp); 1078 } 1079 1080 NDFREE(&nd, 0); 1081 mtx_unlock(&Giant); /* VFS */ |
1082out: 1083 mac_vnode_label_free(intlabel); |
1084 return (error); 1085} 1086 1087/* 1088 * MPSAFE 1089 */ 1090int 1091mac_syscall(struct thread *td, struct mac_syscall_args *uap) --- 110 unchanged lines hidden --- |