diff options
Diffstat (limited to 'security/apparmor/lsm.c')
-rw-r--r-- | security/apparmor/lsm.c | 387 |
1 files changed, 0 insertions, 387 deletions
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index 72b915dfcaf7..1346ee5be04f 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c | |||
@@ -33,7 +33,6 @@ | |||
33 | #include "include/context.h" | 33 | #include "include/context.h" |
34 | #include "include/file.h" | 34 | #include "include/file.h" |
35 | #include "include/ipc.h" | 35 | #include "include/ipc.h" |
36 | #include "include/net.h" | ||
37 | #include "include/path.h" | 36 | #include "include/path.h" |
38 | #include "include/label.h" | 37 | #include "include/label.h" |
39 | #include "include/policy.h" | 38 | #include "include/policy.h" |
@@ -737,368 +736,6 @@ static int apparmor_task_kill(struct task_struct *target, struct siginfo *info, | |||
737 | return error; | 736 | return error; |
738 | } | 737 | } |
739 | 738 | ||
740 | /** | ||
741 | * apparmor_sk_alloc_security - allocate and attach the sk_security field | ||
742 | */ | ||
743 | static int apparmor_sk_alloc_security(struct sock *sk, int family, gfp_t flags) | ||
744 | { | ||
745 | struct aa_sk_ctx *ctx; | ||
746 | |||
747 | ctx = kzalloc(sizeof(*ctx), flags); | ||
748 | if (!ctx) | ||
749 | return -ENOMEM; | ||
750 | |||
751 | SK_CTX(sk) = ctx; | ||
752 | |||
753 | return 0; | ||
754 | } | ||
755 | |||
756 | /** | ||
757 | * apparmor_sk_free_security - free the sk_security field | ||
758 | */ | ||
759 | static void apparmor_sk_free_security(struct sock *sk) | ||
760 | { | ||
761 | struct aa_sk_ctx *ctx = SK_CTX(sk); | ||
762 | |||
763 | SK_CTX(sk) = NULL; | ||
764 | aa_put_label(ctx->label); | ||
765 | aa_put_label(ctx->peer); | ||
766 | path_put(&ctx->path); | ||
767 | kfree(ctx); | ||
768 | } | ||
769 | |||
770 | /** | ||
771 | * apparmor_clone_security - clone the sk_security field | ||
772 | */ | ||
773 | static void apparmor_sk_clone_security(const struct sock *sk, | ||
774 | struct sock *newsk) | ||
775 | { | ||
776 | struct aa_sk_ctx *ctx = SK_CTX(sk); | ||
777 | struct aa_sk_ctx *new = SK_CTX(newsk); | ||
778 | |||
779 | new->label = aa_get_label(ctx->label); | ||
780 | new->peer = aa_get_label(ctx->peer); | ||
781 | new->path = ctx->path; | ||
782 | path_get(&new->path); | ||
783 | } | ||
784 | |||
785 | static int aa_sock_create_perm(struct aa_label *label, int family, int type, | ||
786 | int protocol) | ||
787 | { | ||
788 | AA_BUG(!label); | ||
789 | AA_BUG(in_interrupt()); | ||
790 | |||
791 | return aa_af_perm(label, OP_CREATE, AA_MAY_CREATE, family, type, | ||
792 | protocol); | ||
793 | } | ||
794 | |||
795 | |||
796 | /** | ||
797 | * apparmor_socket_create - check perms before creating a new socket | ||
798 | */ | ||
799 | static int apparmor_socket_create(int family, int type, int protocol, int kern) | ||
800 | { | ||
801 | struct aa_label *label; | ||
802 | int error = 0; | ||
803 | |||
804 | label = begin_current_label_crit_section(); | ||
805 | if (!(kern || unconfined(label))) | ||
806 | error = aa_sock_create_perm(label, family, type, protocol); | ||
807 | end_current_label_crit_section(label); | ||
808 | |||
809 | return error; | ||
810 | } | ||
811 | |||
812 | /** | ||
813 | * apparmor_socket_post_create - setup the per-socket security struct | ||
814 | * | ||
815 | * Note: | ||
816 | * - kernel sockets currently labeled unconfined but we may want to | ||
817 | * move to a special kernel label | ||
818 | * - socket may not have sk here if created with sock_create_lite or | ||
819 | * sock_alloc. These should be accept cases which will be handled in | ||
820 | * sock_graft. | ||
821 | */ | ||
822 | static int apparmor_socket_post_create(struct socket *sock, int family, | ||
823 | int type, int protocol, int kern) | ||
824 | { | ||
825 | struct aa_label *label; | ||
826 | |||
827 | if (kern) { | ||
828 | struct aa_ns *ns = aa_get_current_ns(); | ||
829 | |||
830 | label = aa_get_label(ns_unconfined(ns)); | ||
831 | aa_put_ns(ns); | ||
832 | } else | ||
833 | label = aa_get_current_label(); | ||
834 | |||
835 | if (sock->sk) { | ||
836 | struct aa_sk_ctx *ctx = SK_CTX(sock->sk); | ||
837 | |||
838 | aa_put_label(ctx->label); | ||
839 | ctx->label = aa_get_label(label); | ||
840 | } | ||
841 | aa_put_label(label); | ||
842 | |||
843 | return 0; | ||
844 | } | ||
845 | |||
846 | /** | ||
847 | * apparmor_socket_bind - check perms before bind addr to socket | ||
848 | */ | ||
849 | static int apparmor_socket_bind(struct socket *sock, | ||
850 | struct sockaddr *address, int addrlen) | ||
851 | { | ||
852 | AA_BUG(!sock); | ||
853 | AA_BUG(!sock->sk); | ||
854 | AA_BUG(!address); | ||
855 | AA_BUG(in_interrupt()); | ||
856 | |||
857 | return aa_sk_perm(OP_BIND, AA_MAY_BIND, sock->sk); | ||
858 | } | ||
859 | |||
860 | /** | ||
861 | * apparmor_socket_connect - check perms before connecting @sock to @address | ||
862 | */ | ||
863 | static int apparmor_socket_connect(struct socket *sock, | ||
864 | struct sockaddr *address, int addrlen) | ||
865 | { | ||
866 | AA_BUG(!sock); | ||
867 | AA_BUG(!sock->sk); | ||
868 | AA_BUG(!address); | ||
869 | AA_BUG(in_interrupt()); | ||
870 | |||
871 | return aa_sk_perm(OP_CONNECT, AA_MAY_CONNECT, sock->sk); | ||
872 | } | ||
873 | |||
874 | /** | ||
875 | * apparmor_socket_list - check perms before allowing listen | ||
876 | */ | ||
877 | static int apparmor_socket_listen(struct socket *sock, int backlog) | ||
878 | { | ||
879 | AA_BUG(!sock); | ||
880 | AA_BUG(!sock->sk); | ||
881 | AA_BUG(in_interrupt()); | ||
882 | |||
883 | return aa_sk_perm(OP_LISTEN, AA_MAY_LISTEN, sock->sk); | ||
884 | } | ||
885 | |||
886 | /** | ||
887 | * apparmor_socket_accept - check perms before accepting a new connection. | ||
888 | * | ||
889 | * Note: while @newsock is created and has some information, the accept | ||
890 | * has not been done. | ||
891 | */ | ||
892 | static int apparmor_socket_accept(struct socket *sock, struct socket *newsock) | ||
893 | { | ||
894 | AA_BUG(!sock); | ||
895 | AA_BUG(!sock->sk); | ||
896 | AA_BUG(!newsock); | ||
897 | AA_BUG(in_interrupt()); | ||
898 | |||
899 | return aa_sk_perm(OP_ACCEPT, AA_MAY_ACCEPT, sock->sk); | ||
900 | } | ||
901 | |||
902 | static int aa_sock_msg_perm(const char *op, u32 request, struct socket *sock, | ||
903 | struct msghdr *msg, int size) | ||
904 | { | ||
905 | AA_BUG(!sock); | ||
906 | AA_BUG(!sock->sk); | ||
907 | AA_BUG(!msg); | ||
908 | AA_BUG(in_interrupt()); | ||
909 | |||
910 | return aa_sk_perm(op, request, sock->sk); | ||
911 | } | ||
912 | |||
913 | /** | ||
914 | * apparmor_socket_sendmsg - check perms before sending msg to another socket | ||
915 | */ | ||
916 | static int apparmor_socket_sendmsg(struct socket *sock, | ||
917 | struct msghdr *msg, int size) | ||
918 | { | ||
919 | return aa_sock_msg_perm(OP_SENDMSG, AA_MAY_SEND, sock, msg, size); | ||
920 | } | ||
921 | |||
922 | /** | ||
923 | * apparmor_socket_recvmsg - check perms before receiving a message | ||
924 | */ | ||
925 | static int apparmor_socket_recvmsg(struct socket *sock, | ||
926 | struct msghdr *msg, int size, int flags) | ||
927 | { | ||
928 | return aa_sock_msg_perm(OP_RECVMSG, AA_MAY_RECEIVE, sock, msg, size); | ||
929 | } | ||
930 | |||
931 | /* revaliation, get/set attr, shutdown */ | ||
932 | static int aa_sock_perm(const char *op, u32 request, struct socket *sock) | ||
933 | { | ||
934 | AA_BUG(!sock); | ||
935 | AA_BUG(!sock->sk); | ||
936 | AA_BUG(in_interrupt()); | ||
937 | |||
938 | return aa_sk_perm(op, request, sock->sk); | ||
939 | } | ||
940 | |||
941 | /** | ||
942 | * apparmor_socket_getsockname - check perms before getting the local address | ||
943 | */ | ||
944 | static int apparmor_socket_getsockname(struct socket *sock) | ||
945 | { | ||
946 | return aa_sock_perm(OP_GETSOCKNAME, AA_MAY_GETATTR, sock); | ||
947 | } | ||
948 | |||
949 | /** | ||
950 | * apparmor_socket_getpeername - check perms before getting remote address | ||
951 | */ | ||
952 | static int apparmor_socket_getpeername(struct socket *sock) | ||
953 | { | ||
954 | return aa_sock_perm(OP_GETPEERNAME, AA_MAY_GETATTR, sock); | ||
955 | } | ||
956 | |||
957 | /* revaliation, get/set attr, opt */ | ||
958 | static int aa_sock_opt_perm(const char *op, u32 request, struct socket *sock, | ||
959 | int level, int optname) | ||
960 | { | ||
961 | AA_BUG(!sock); | ||
962 | AA_BUG(!sock->sk); | ||
963 | AA_BUG(in_interrupt()); | ||
964 | |||
965 | return aa_sk_perm(op, request, sock->sk); | ||
966 | } | ||
967 | |||
968 | /** | ||
969 | * apparmor_getsockopt - check perms before getting socket options | ||
970 | */ | ||
971 | static int apparmor_socket_getsockopt(struct socket *sock, int level, | ||
972 | int optname) | ||
973 | { | ||
974 | return aa_sock_opt_perm(OP_GETSOCKOPT, AA_MAY_GETOPT, sock, | ||
975 | level, optname); | ||
976 | } | ||
977 | |||
978 | /** | ||
979 | * apparmor_setsockopt - check perms before setting socket options | ||
980 | */ | ||
981 | static int apparmor_socket_setsockopt(struct socket *sock, int level, | ||
982 | int optname) | ||
983 | { | ||
984 | return aa_sock_opt_perm(OP_SETSOCKOPT, AA_MAY_SETOPT, sock, | ||
985 | level, optname); | ||
986 | } | ||
987 | |||
988 | /** | ||
989 | * apparmor_socket_shutdown - check perms before shutting down @sock conn | ||
990 | */ | ||
991 | static int apparmor_socket_shutdown(struct socket *sock, int how) | ||
992 | { | ||
993 | return aa_sock_perm(OP_SHUTDOWN, AA_MAY_SHUTDOWN, sock); | ||
994 | } | ||
995 | |||
996 | /** | ||
997 | * apparmor_socket_sock_recv_skb - check perms before associating skb to sk | ||
998 | * | ||
999 | * Note: can not sleep may be called with locks held | ||
1000 | * | ||
1001 | * dont want protocol specific in __skb_recv_datagram() | ||
1002 | * to deny an incoming connection socket_sock_rcv_skb() | ||
1003 | */ | ||
1004 | static int apparmor_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) | ||
1005 | { | ||
1006 | return 0; | ||
1007 | } | ||
1008 | |||
1009 | |||
1010 | static struct aa_label *sk_peer_label(struct sock *sk) | ||
1011 | { | ||
1012 | struct aa_sk_ctx *ctx = SK_CTX(sk); | ||
1013 | |||
1014 | if (ctx->peer) | ||
1015 | return ctx->peer; | ||
1016 | |||
1017 | return ERR_PTR(-ENOPROTOOPT); | ||
1018 | } | ||
1019 | |||
1020 | /** | ||
1021 | * apparmor_socket_getpeersec_stream - get security context of peer | ||
1022 | * | ||
1023 | * Note: for tcp only valid if using ipsec or cipso on lan | ||
1024 | */ | ||
1025 | static int apparmor_socket_getpeersec_stream(struct socket *sock, | ||
1026 | char __user *optval, | ||
1027 | int __user *optlen, | ||
1028 | unsigned int len) | ||
1029 | { | ||
1030 | char *name; | ||
1031 | int slen, error = 0; | ||
1032 | struct aa_label *label; | ||
1033 | struct aa_label *peer; | ||
1034 | |||
1035 | label = begin_current_label_crit_section(); | ||
1036 | peer = sk_peer_label(sock->sk); | ||
1037 | if (IS_ERR(peer)) { | ||
1038 | error = PTR_ERR(peer); | ||
1039 | goto done; | ||
1040 | } | ||
1041 | slen = aa_label_asxprint(&name, labels_ns(label), peer, | ||
1042 | FLAG_SHOW_MODE | FLAG_VIEW_SUBNS | | ||
1043 | FLAG_HIDDEN_UNCONFINED, GFP_KERNEL); | ||
1044 | /* don't include terminating \0 in slen, it breaks some apps */ | ||
1045 | if (slen < 0) { | ||
1046 | error = -ENOMEM; | ||
1047 | } else { | ||
1048 | if (slen > len) { | ||
1049 | error = -ERANGE; | ||
1050 | } else if (copy_to_user(optval, name, slen)) { | ||
1051 | error = -EFAULT; | ||
1052 | goto out; | ||
1053 | } | ||
1054 | if (put_user(slen, optlen)) | ||
1055 | error = -EFAULT; | ||
1056 | out: | ||
1057 | kfree(name); | ||
1058 | |||
1059 | } | ||
1060 | |||
1061 | done: | ||
1062 | end_current_label_crit_section(label); | ||
1063 | |||
1064 | return error; | ||
1065 | } | ||
1066 | |||
1067 | /** | ||
1068 | * apparmor_socket_getpeersec_dgram - get security label of packet | ||
1069 | * @sock: the peer socket | ||
1070 | * @skb: packet data | ||
1071 | * @secid: pointer to where to put the secid of the packet | ||
1072 | * | ||
1073 | * Sets the netlabel socket state on sk from parent | ||
1074 | */ | ||
1075 | static int apparmor_socket_getpeersec_dgram(struct socket *sock, | ||
1076 | struct sk_buff *skb, u32 *secid) | ||
1077 | |||
1078 | { | ||
1079 | /* TODO: requires secid support */ | ||
1080 | return -ENOPROTOOPT; | ||
1081 | } | ||
1082 | |||
1083 | /** | ||
1084 | * apparmor_sock_graft - Initialize newly created socket | ||
1085 | * @sk: child sock | ||
1086 | * @parent: parent socket | ||
1087 | * | ||
1088 | * Note: could set off of SOCK_CTX(parent) but need to track inode and we can | ||
1089 | * just set sk security information off of current creating process label | ||
1090 | * Labeling of sk for accept case - probably should be sock based | ||
1091 | * instead of task, because of the case where an implicitly labeled | ||
1092 | * socket is shared by different tasks. | ||
1093 | */ | ||
1094 | static void apparmor_sock_graft(struct sock *sk, struct socket *parent) | ||
1095 | { | ||
1096 | struct aa_sk_ctx *ctx = SK_CTX(sk); | ||
1097 | |||
1098 | if (!ctx->label) | ||
1099 | ctx->label = aa_get_current_label(); | ||
1100 | } | ||
1101 | |||
1102 | static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = { | 739 | static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = { |
1103 | LSM_HOOK_INIT(ptrace_access_check, apparmor_ptrace_access_check), | 740 | LSM_HOOK_INIT(ptrace_access_check, apparmor_ptrace_access_check), |
1104 | LSM_HOOK_INIT(ptrace_traceme, apparmor_ptrace_traceme), | 741 | LSM_HOOK_INIT(ptrace_traceme, apparmor_ptrace_traceme), |
@@ -1133,30 +770,6 @@ static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = { | |||
1133 | LSM_HOOK_INIT(getprocattr, apparmor_getprocattr), | 770 | LSM_HOOK_INIT(getprocattr, apparmor_getprocattr), |
1134 | LSM_HOOK_INIT(setprocattr, apparmor_setprocattr), | 771 | LSM_HOOK_INIT(setprocattr, apparmor_setprocattr), |
1135 | 772 | ||
1136 | LSM_HOOK_INIT(sk_alloc_security, apparmor_sk_alloc_security), | ||
1137 | LSM_HOOK_INIT(sk_free_security, apparmor_sk_free_security), | ||
1138 | LSM_HOOK_INIT(sk_clone_security, apparmor_sk_clone_security), | ||
1139 | |||
1140 | LSM_HOOK_INIT(socket_create, apparmor_socket_create), | ||
1141 | LSM_HOOK_INIT(socket_post_create, apparmor_socket_post_create), | ||
1142 | LSM_HOOK_INIT(socket_bind, apparmor_socket_bind), | ||
1143 | LSM_HOOK_INIT(socket_connect, apparmor_socket_connect), | ||
1144 | LSM_HOOK_INIT(socket_listen, apparmor_socket_listen), | ||
1145 | LSM_HOOK_INIT(socket_accept, apparmor_socket_accept), | ||
1146 | LSM_HOOK_INIT(socket_sendmsg, apparmor_socket_sendmsg), | ||
1147 | LSM_HOOK_INIT(socket_recvmsg, apparmor_socket_recvmsg), | ||
1148 | LSM_HOOK_INIT(socket_getsockname, apparmor_socket_getsockname), | ||
1149 | LSM_HOOK_INIT(socket_getpeername, apparmor_socket_getpeername), | ||
1150 | LSM_HOOK_INIT(socket_getsockopt, apparmor_socket_getsockopt), | ||
1151 | LSM_HOOK_INIT(socket_setsockopt, apparmor_socket_setsockopt), | ||
1152 | LSM_HOOK_INIT(socket_shutdown, apparmor_socket_shutdown), | ||
1153 | LSM_HOOK_INIT(socket_sock_rcv_skb, apparmor_socket_sock_rcv_skb), | ||
1154 | LSM_HOOK_INIT(socket_getpeersec_stream, | ||
1155 | apparmor_socket_getpeersec_stream), | ||
1156 | LSM_HOOK_INIT(socket_getpeersec_dgram, | ||
1157 | apparmor_socket_getpeersec_dgram), | ||
1158 | LSM_HOOK_INIT(sock_graft, apparmor_sock_graft), | ||
1159 | |||
1160 | LSM_HOOK_INIT(cred_alloc_blank, apparmor_cred_alloc_blank), | 773 | LSM_HOOK_INIT(cred_alloc_blank, apparmor_cred_alloc_blank), |
1161 | LSM_HOOK_INIT(cred_free, apparmor_cred_free), | 774 | LSM_HOOK_INIT(cred_free, apparmor_cred_free), |
1162 | LSM_HOOK_INIT(cred_prepare, apparmor_cred_prepare), | 775 | LSM_HOOK_INIT(cred_prepare, apparmor_cred_prepare), |