aboutsummaryrefslogtreecommitdiffstats
path: root/security/smack/smack_lsm.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/smack/smack_lsm.c')
-rw-r--r--security/smack/smack_lsm.c126
1 files changed, 77 insertions, 49 deletions
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index b9c5e149903b..fb915163f967 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -516,6 +516,8 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir,
516 const struct qstr *qstr, char **name, 516 const struct qstr *qstr, char **name,
517 void **value, size_t *len) 517 void **value, size_t *len)
518{ 518{
519 struct smack_known *skp;
520 char *csp = smk_of_current();
519 char *isp = smk_of_inode(inode); 521 char *isp = smk_of_inode(inode);
520 char *dsp = smk_of_inode(dir); 522 char *dsp = smk_of_inode(dir);
521 int may; 523 int may;
@@ -527,8 +529,9 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir,
527 } 529 }
528 530
529 if (value) { 531 if (value) {
532 skp = smk_find_entry(csp);
530 rcu_read_lock(); 533 rcu_read_lock();
531 may = smk_access_entry(smk_of_current(), dsp, &smack_rule_list); 534 may = smk_access_entry(csp, dsp, &skp->smk_rules);
532 rcu_read_unlock(); 535 rcu_read_unlock();
533 536
534 /* 537 /*
@@ -1138,6 +1141,7 @@ static int smack_file_mmap(struct file *file,
1138 unsigned long flags, unsigned long addr, 1141 unsigned long flags, unsigned long addr,
1139 unsigned long addr_only) 1142 unsigned long addr_only)
1140{ 1143{
1144 struct smack_known *skp;
1141 struct smack_rule *srp; 1145 struct smack_rule *srp;
1142 struct task_smack *tsp; 1146 struct task_smack *tsp;
1143 char *sp; 1147 char *sp;
@@ -1170,6 +1174,7 @@ static int smack_file_mmap(struct file *file,
1170 1174
1171 tsp = current_security(); 1175 tsp = current_security();
1172 sp = smk_of_current(); 1176 sp = smk_of_current();
1177 skp = smk_find_entry(sp);
1173 rc = 0; 1178 rc = 0;
1174 1179
1175 rcu_read_lock(); 1180 rcu_read_lock();
@@ -1177,15 +1182,8 @@ static int smack_file_mmap(struct file *file,
1177 * For each Smack rule associated with the subject 1182 * For each Smack rule associated with the subject
1178 * label verify that the SMACK64MMAP also has access 1183 * label verify that the SMACK64MMAP also has access
1179 * to that rule's object label. 1184 * to that rule's object label.
1180 *
1181 * Because neither of the labels comes
1182 * from the networking code it is sufficient
1183 * to compare pointers.
1184 */ 1185 */
1185 list_for_each_entry_rcu(srp, &smack_rule_list, list) { 1186 list_for_each_entry_rcu(srp, &skp->smk_rules, list) {
1186 if (srp->smk_subject != sp)
1187 continue;
1188
1189 osmack = srp->smk_object; 1187 osmack = srp->smk_object;
1190 /* 1188 /*
1191 * Matching labels always allows access. 1189 * Matching labels always allows access.
@@ -1214,7 +1212,8 @@ static int smack_file_mmap(struct file *file,
1214 * If there isn't one a SMACK64MMAP subject 1212 * If there isn't one a SMACK64MMAP subject
1215 * can't have as much access as current. 1213 * can't have as much access as current.
1216 */ 1214 */
1217 mmay = smk_access_entry(msmack, osmack, &smack_rule_list); 1215 skp = smk_find_entry(msmack);
1216 mmay = smk_access_entry(msmack, osmack, &skp->smk_rules);
1218 if (mmay == -ENOENT) { 1217 if (mmay == -ENOENT) {
1219 rc = -EACCES; 1218 rc = -EACCES;
1220 break; 1219 break;
@@ -1711,7 +1710,7 @@ static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags)
1711 1710
1712 ssp->smk_in = csp; 1711 ssp->smk_in = csp;
1713 ssp->smk_out = csp; 1712 ssp->smk_out = csp;
1714 ssp->smk_packet[0] = '\0'; 1713 ssp->smk_packet = NULL;
1715 1714
1716 sk->sk_security = ssp; 1715 sk->sk_security = ssp;
1717 1716
@@ -2813,16 +2812,17 @@ static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg,
2813 return smack_netlabel_send(sock->sk, sip); 2812 return smack_netlabel_send(sock->sk, sip);
2814} 2813}
2815 2814
2816
2817/** 2815/**
2818 * smack_from_secattr - Convert a netlabel attr.mls.lvl/attr.mls.cat pair to smack 2816 * smack_from_secattr - Convert a netlabel attr.mls.lvl/attr.mls.cat pair to smack
2819 * @sap: netlabel secattr 2817 * @sap: netlabel secattr
2820 * @sip: where to put the result 2818 * @ssp: socket security information
2821 * 2819 *
2822 * Copies a smack label into sip 2820 * Returns a pointer to a Smack label found on the label list.
2823 */ 2821 */
2824static void smack_from_secattr(struct netlbl_lsm_secattr *sap, char *sip) 2822static char *smack_from_secattr(struct netlbl_lsm_secattr *sap,
2823 struct socket_smack *ssp)
2825{ 2824{
2825 struct smack_known *skp;
2826 char smack[SMK_LABELLEN]; 2826 char smack[SMK_LABELLEN];
2827 char *sp; 2827 char *sp;
2828 int pcat; 2828 int pcat;
@@ -2852,15 +2852,43 @@ static void smack_from_secattr(struct netlbl_lsm_secattr *sap, char *sip)
2852 * we are already done. WeeHee. 2852 * we are already done. WeeHee.
2853 */ 2853 */
2854 if (sap->attr.mls.lvl == smack_cipso_direct) { 2854 if (sap->attr.mls.lvl == smack_cipso_direct) {
2855 memcpy(sip, smack, SMK_MAXLEN); 2855 /*
2856 return; 2856 * The label sent is usually on the label list.
2857 *
2858 * If it is not we may still want to allow the
2859 * delivery.
2860 *
2861 * If the recipient is accepting all packets
2862 * because it is using the star ("*") label
2863 * for SMACK64IPIN provide the web ("@") label
2864 * so that a directed response will succeed.
2865 * This is not very correct from a MAC point
2866 * of view, but gets around the problem that
2867 * locking prevents adding the newly discovered
2868 * label to the list.
2869 * The case where the recipient is not using
2870 * the star label should obviously fail.
2871 * The easy way to do this is to provide the
2872 * star label as the subject label.
2873 */
2874 skp = smk_find_entry(smack);
2875 if (skp != NULL)
2876 return skp->smk_known;
2877 if (ssp != NULL &&
2878 ssp->smk_in == smack_known_star.smk_known)
2879 return smack_known_web.smk_known;
2880 return smack_known_star.smk_known;
2857 } 2881 }
2858 /* 2882 /*
2859 * Look it up in the supplied table if it is not 2883 * Look it up in the supplied table if it is not
2860 * a direct mapping. 2884 * a direct mapping.
2861 */ 2885 */
2862 smack_from_cipso(sap->attr.mls.lvl, smack, sip); 2886 sp = smack_from_cipso(sap->attr.mls.lvl, smack);
2863 return; 2887 if (sp != NULL)
2888 return sp;
2889 if (ssp != NULL && ssp->smk_in == smack_known_star.smk_known)
2890 return smack_known_web.smk_known;
2891 return smack_known_star.smk_known;
2864 } 2892 }
2865 if ((sap->flags & NETLBL_SECATTR_SECID) != 0) { 2893 if ((sap->flags & NETLBL_SECATTR_SECID) != 0) {
2866 /* 2894 /*
@@ -2875,16 +2903,14 @@ static void smack_from_secattr(struct netlbl_lsm_secattr *sap, char *sip)
2875 * secid is from a fallback. 2903 * secid is from a fallback.
2876 */ 2904 */
2877 BUG_ON(sp == NULL); 2905 BUG_ON(sp == NULL);
2878 strncpy(sip, sp, SMK_MAXLEN); 2906 return sp;
2879 return;
2880 } 2907 }
2881 /* 2908 /*
2882 * Without guidance regarding the smack value 2909 * Without guidance regarding the smack value
2883 * for the packet fall back on the network 2910 * for the packet fall back on the network
2884 * ambient value. 2911 * ambient value.
2885 */ 2912 */
2886 strncpy(sip, smack_net_ambient, SMK_MAXLEN); 2913 return smack_net_ambient;
2887 return;
2888} 2914}
2889 2915
2890/** 2916/**
@@ -2898,7 +2924,6 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
2898{ 2924{
2899 struct netlbl_lsm_secattr secattr; 2925 struct netlbl_lsm_secattr secattr;
2900 struct socket_smack *ssp = sk->sk_security; 2926 struct socket_smack *ssp = sk->sk_security;
2901 char smack[SMK_LABELLEN];
2902 char *csp; 2927 char *csp;
2903 int rc; 2928 int rc;
2904 struct smk_audit_info ad; 2929 struct smk_audit_info ad;
@@ -2911,10 +2936,9 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
2911 netlbl_secattr_init(&secattr); 2936 netlbl_secattr_init(&secattr);
2912 2937
2913 rc = netlbl_skbuff_getattr(skb, sk->sk_family, &secattr); 2938 rc = netlbl_skbuff_getattr(skb, sk->sk_family, &secattr);
2914 if (rc == 0) { 2939 if (rc == 0)
2915 smack_from_secattr(&secattr, smack); 2940 csp = smack_from_secattr(&secattr, ssp);
2916 csp = smack; 2941 else
2917 } else
2918 csp = smack_net_ambient; 2942 csp = smack_net_ambient;
2919 2943
2920 netlbl_secattr_destroy(&secattr); 2944 netlbl_secattr_destroy(&secattr);
@@ -2951,15 +2975,19 @@ static int smack_socket_getpeersec_stream(struct socket *sock,
2951 int __user *optlen, unsigned len) 2975 int __user *optlen, unsigned len)
2952{ 2976{
2953 struct socket_smack *ssp; 2977 struct socket_smack *ssp;
2954 int slen; 2978 char *rcp = "";
2979 int slen = 1;
2955 int rc = 0; 2980 int rc = 0;
2956 2981
2957 ssp = sock->sk->sk_security; 2982 ssp = sock->sk->sk_security;
2958 slen = strlen(ssp->smk_packet) + 1; 2983 if (ssp->smk_packet != NULL) {
2984 rcp = ssp->smk_packet;
2985 slen = strlen(rcp) + 1;
2986 }
2959 2987
2960 if (slen > len) 2988 if (slen > len)
2961 rc = -ERANGE; 2989 rc = -ERANGE;
2962 else if (copy_to_user(optval, ssp->smk_packet, slen) != 0) 2990 else if (copy_to_user(optval, rcp, slen) != 0)
2963 rc = -EFAULT; 2991 rc = -EFAULT;
2964 2992
2965 if (put_user(slen, optlen) != 0) 2993 if (put_user(slen, optlen) != 0)
@@ -2982,8 +3010,8 @@ static int smack_socket_getpeersec_dgram(struct socket *sock,
2982 3010
2983{ 3011{
2984 struct netlbl_lsm_secattr secattr; 3012 struct netlbl_lsm_secattr secattr;
2985 struct socket_smack *sp; 3013 struct socket_smack *ssp = NULL;
2986 char smack[SMK_LABELLEN]; 3014 char *sp;
2987 int family = PF_UNSPEC; 3015 int family = PF_UNSPEC;
2988 u32 s = 0; /* 0 is the invalid secid */ 3016 u32 s = 0; /* 0 is the invalid secid */
2989 int rc; 3017 int rc;
@@ -2998,17 +3026,19 @@ static int smack_socket_getpeersec_dgram(struct socket *sock,
2998 family = sock->sk->sk_family; 3026 family = sock->sk->sk_family;
2999 3027
3000 if (family == PF_UNIX) { 3028 if (family == PF_UNIX) {
3001 sp = sock->sk->sk_security; 3029 ssp = sock->sk->sk_security;
3002 s = smack_to_secid(sp->smk_out); 3030 s = smack_to_secid(ssp->smk_out);
3003 } else if (family == PF_INET || family == PF_INET6) { 3031 } else if (family == PF_INET || family == PF_INET6) {
3004 /* 3032 /*
3005 * Translate what netlabel gave us. 3033 * Translate what netlabel gave us.
3006 */ 3034 */
3035 if (sock != NULL && sock->sk != NULL)
3036 ssp = sock->sk->sk_security;
3007 netlbl_secattr_init(&secattr); 3037 netlbl_secattr_init(&secattr);
3008 rc = netlbl_skbuff_getattr(skb, family, &secattr); 3038 rc = netlbl_skbuff_getattr(skb, family, &secattr);
3009 if (rc == 0) { 3039 if (rc == 0) {
3010 smack_from_secattr(&secattr, smack); 3040 sp = smack_from_secattr(&secattr, ssp);
3011 s = smack_to_secid(smack); 3041 s = smack_to_secid(sp);
3012 } 3042 }
3013 netlbl_secattr_destroy(&secattr); 3043 netlbl_secattr_destroy(&secattr);
3014 } 3044 }
@@ -3056,7 +3086,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
3056 struct netlbl_lsm_secattr secattr; 3086 struct netlbl_lsm_secattr secattr;
3057 struct sockaddr_in addr; 3087 struct sockaddr_in addr;
3058 struct iphdr *hdr; 3088 struct iphdr *hdr;
3059 char smack[SMK_LABELLEN]; 3089 char *sp;
3060 int rc; 3090 int rc;
3061 struct smk_audit_info ad; 3091 struct smk_audit_info ad;
3062 3092
@@ -3067,9 +3097,9 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
3067 netlbl_secattr_init(&secattr); 3097 netlbl_secattr_init(&secattr);
3068 rc = netlbl_skbuff_getattr(skb, family, &secattr); 3098 rc = netlbl_skbuff_getattr(skb, family, &secattr);
3069 if (rc == 0) 3099 if (rc == 0)
3070 smack_from_secattr(&secattr, smack); 3100 sp = smack_from_secattr(&secattr, ssp);
3071 else 3101 else
3072 strncpy(smack, smack_known_huh.smk_known, SMK_MAXLEN); 3102 sp = smack_known_huh.smk_known;
3073 netlbl_secattr_destroy(&secattr); 3103 netlbl_secattr_destroy(&secattr);
3074 3104
3075#ifdef CONFIG_AUDIT 3105#ifdef CONFIG_AUDIT
@@ -3082,7 +3112,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
3082 * Receiving a packet requires that the other end be able to write 3112 * Receiving a packet requires that the other end be able to write
3083 * here. Read access is not required. 3113 * here. Read access is not required.
3084 */ 3114 */
3085 rc = smk_access(smack, ssp->smk_in, MAY_WRITE, &ad); 3115 rc = smk_access(sp, ssp->smk_in, MAY_WRITE, &ad);
3086 if (rc != 0) 3116 if (rc != 0)
3087 return rc; 3117 return rc;
3088 3118
@@ -3090,7 +3120,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
3090 * Save the peer's label in the request_sock so we can later setup 3120 * Save the peer's label in the request_sock so we can later setup
3091 * smk_packet in the child socket so that SO_PEERCRED can report it. 3121 * smk_packet in the child socket so that SO_PEERCRED can report it.
3092 */ 3122 */
3093 req->peer_secid = smack_to_secid(smack); 3123 req->peer_secid = smack_to_secid(sp);
3094 3124
3095 /* 3125 /*
3096 * We need to decide if we want to label the incoming connection here 3126 * We need to decide if we want to label the incoming connection here
@@ -3103,7 +3133,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
3103 if (smack_host_label(&addr) == NULL) { 3133 if (smack_host_label(&addr) == NULL) {
3104 rcu_read_unlock(); 3134 rcu_read_unlock();
3105 netlbl_secattr_init(&secattr); 3135 netlbl_secattr_init(&secattr);
3106 smack_to_secattr(smack, &secattr); 3136 smack_to_secattr(sp, &secattr);
3107 rc = netlbl_req_setattr(req, &secattr); 3137 rc = netlbl_req_setattr(req, &secattr);
3108 netlbl_secattr_destroy(&secattr); 3138 netlbl_secattr_destroy(&secattr);
3109 } else { 3139 } else {
@@ -3125,13 +3155,11 @@ static void smack_inet_csk_clone(struct sock *sk,
3125 const struct request_sock *req) 3155 const struct request_sock *req)
3126{ 3156{
3127 struct socket_smack *ssp = sk->sk_security; 3157 struct socket_smack *ssp = sk->sk_security;
3128 char *smack;
3129 3158
3130 if (req->peer_secid != 0) { 3159 if (req->peer_secid != 0)
3131 smack = smack_from_secid(req->peer_secid); 3160 ssp->smk_packet = smack_from_secid(req->peer_secid);
3132 strncpy(ssp->smk_packet, smack, SMK_MAXLEN); 3161 else
3133 } else 3162 ssp->smk_packet = NULL;
3134 ssp->smk_packet[0] = '\0';
3135} 3163}
3136 3164
3137/* 3165/*