Deleted Added
sdiff udiff text old ( 122454 ) new ( 122524 )
full compact
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 ---