aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAtul Gupta <atul.gupta@chelsio.com>2018-05-27 11:45:19 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2018-05-30 12:13:58 -0400
commit3b8305f5c844685d00637a0ad155e90e423a4445 (patch)
tree7f9eefab8b29dbd5488af16d09d19b5828f67792
parent09e53d8289477449ddd74cfff640792ca02fa90d (diff)
crypto: chtls - wait for memory sendmsg, sendpage
address suspicious code <gustavo@embeddedor.com> 1210 set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); 1211 } The issue is that in the code above, set_bit is never reached due to the 'continue' statement at line 1208. Also reported by bug report:<dan.carpenter@oracle.com> 1210 set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Not reachable. Its required to wait for buffer in the send path and takes care of unaddress and un-handled SOCK_NOSPACE. v2: use csk_mem_free where appropriate proper indent of goto do_nonblock replace out with do_rm_wq Reported-by: Gustavo A. R. Silva <gustavo@embeddedor.com> Reported-by: Dan Carpenter <dan.carpenter@oracle.com> Signed-off-by: Atul Gupta <atul.gupta@chelsio.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r--drivers/crypto/chelsio/chtls/chtls.h1
-rw-r--r--drivers/crypto/chelsio/chtls/chtls_io.c90
-rw-r--r--drivers/crypto/chelsio/chtls/chtls_main.c1
3 files changed, 89 insertions, 3 deletions
diff --git a/drivers/crypto/chelsio/chtls/chtls.h b/drivers/crypto/chelsio/chtls/chtls.h
index 1b2f43ccb11e..a53a0e6ba024 100644
--- a/drivers/crypto/chelsio/chtls/chtls.h
+++ b/drivers/crypto/chelsio/chtls/chtls.h
@@ -144,6 +144,7 @@ struct chtls_dev {
144 struct list_head rcu_node; 144 struct list_head rcu_node;
145 struct list_head na_node; 145 struct list_head na_node;
146 unsigned int send_page_order; 146 unsigned int send_page_order;
147 int max_host_sndbuf;
147 struct key_map kmap; 148 struct key_map kmap;
148}; 149};
149 150
diff --git a/drivers/crypto/chelsio/chtls/chtls_io.c b/drivers/crypto/chelsio/chtls/chtls_io.c
index 840dd0100c2f..7aa5d90c6ebd 100644
--- a/drivers/crypto/chelsio/chtls/chtls_io.c
+++ b/drivers/crypto/chelsio/chtls/chtls_io.c
@@ -914,6 +914,78 @@ static u16 tls_header_read(struct tls_hdr *thdr, struct iov_iter *from)
914 return (__force u16)cpu_to_be16(thdr->length); 914 return (__force u16)cpu_to_be16(thdr->length);
915} 915}
916 916
917static int csk_mem_free(struct chtls_dev *cdev, struct sock *sk)
918{
919 return (cdev->max_host_sndbuf - sk->sk_wmem_queued);
920}
921
922static int csk_wait_memory(struct chtls_dev *cdev,
923 struct sock *sk, long *timeo_p)
924{
925 DEFINE_WAIT_FUNC(wait, woken_wake_function);
926 int sndbuf, err = 0;
927 long current_timeo;
928 long vm_wait = 0;
929 bool noblock;
930
931 current_timeo = *timeo_p;
932 noblock = (*timeo_p ? false : true);
933 sndbuf = cdev->max_host_sndbuf;
934 if (csk_mem_free(cdev, sk)) {
935 current_timeo = (prandom_u32() % (HZ / 5)) + 2;
936 vm_wait = (prandom_u32() % (HZ / 5)) + 2;
937 }
938
939 add_wait_queue(sk_sleep(sk), &wait);
940 while (1) {
941 sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk);
942
943 if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN))
944 goto do_error;
945 if (!*timeo_p) {
946 if (noblock)
947 set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
948 goto do_nonblock;
949 }
950 if (signal_pending(current))
951 goto do_interrupted;
952 sk_clear_bit(SOCKWQ_ASYNC_NOSPACE, sk);
953 if (csk_mem_free(cdev, sk) && !vm_wait)
954 break;
955
956 set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
957 sk->sk_write_pending++;
958 sk_wait_event(sk, &current_timeo, sk->sk_err ||
959 (sk->sk_shutdown & SEND_SHUTDOWN) ||
960 (csk_mem_free(cdev, sk) && !vm_wait), &wait);
961 sk->sk_write_pending--;
962
963 if (vm_wait) {
964 vm_wait -= current_timeo;
965 current_timeo = *timeo_p;
966 if (current_timeo != MAX_SCHEDULE_TIMEOUT) {
967 current_timeo -= vm_wait;
968 if (current_timeo < 0)
969 current_timeo = 0;
970 }
971 vm_wait = 0;
972 }
973 *timeo_p = current_timeo;
974 }
975do_rm_wq:
976 remove_wait_queue(sk_sleep(sk), &wait);
977 return err;
978do_error:
979 err = -EPIPE;
980 goto do_rm_wq;
981do_nonblock:
982 err = -EAGAIN;
983 goto do_rm_wq;
984do_interrupted:
985 err = sock_intr_errno(*timeo_p);
986 goto do_rm_wq;
987}
988
917int chtls_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) 989int chtls_sendmsg(struct sock *sk, struct msghdr *msg, size_t size)
918{ 990{
919 struct chtls_sock *csk = rcu_dereference_sk_user_data(sk); 991 struct chtls_sock *csk = rcu_dereference_sk_user_data(sk);
@@ -952,6 +1024,8 @@ int chtls_sendmsg(struct sock *sk, struct msghdr *msg, size_t size)
952 copy = mss - skb->len; 1024 copy = mss - skb->len;
953 skb->ip_summed = CHECKSUM_UNNECESSARY; 1025 skb->ip_summed = CHECKSUM_UNNECESSARY;
954 } 1026 }
1027 if (!csk_mem_free(cdev, sk))
1028 goto wait_for_sndbuf;
955 1029
956 if (is_tls_tx(csk) && !csk->tlshws.txleft) { 1030 if (is_tls_tx(csk) && !csk->tlshws.txleft) {
957 struct tls_hdr hdr; 1031 struct tls_hdr hdr;
@@ -1099,8 +1173,10 @@ copy:
1099 if (ULP_SKB_CB(skb)->flags & ULPCB_FLAG_NO_APPEND) 1173 if (ULP_SKB_CB(skb)->flags & ULPCB_FLAG_NO_APPEND)
1100 push_frames_if_head(sk); 1174 push_frames_if_head(sk);
1101 continue; 1175 continue;
1176wait_for_sndbuf:
1177 set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
1102wait_for_memory: 1178wait_for_memory:
1103 err = sk_stream_wait_memory(sk, &timeo); 1179 err = csk_wait_memory(cdev, sk, &timeo);
1104 if (err) 1180 if (err)
1105 goto do_error; 1181 goto do_error;
1106 } 1182 }
@@ -1131,6 +1207,7 @@ int chtls_sendpage(struct sock *sk, struct page *page,
1131 int offset, size_t size, int flags) 1207 int offset, size_t size, int flags)
1132{ 1208{
1133 struct chtls_sock *csk; 1209 struct chtls_sock *csk;
1210 struct chtls_dev *cdev;
1134 int mss, err, copied; 1211 int mss, err, copied;
1135 struct tcp_sock *tp; 1212 struct tcp_sock *tp;
1136 long timeo; 1213 long timeo;
@@ -1138,6 +1215,7 @@ int chtls_sendpage(struct sock *sk, struct page *page,
1138 tp = tcp_sk(sk); 1215 tp = tcp_sk(sk);
1139 copied = 0; 1216 copied = 0;
1140 csk = rcu_dereference_sk_user_data(sk); 1217 csk = rcu_dereference_sk_user_data(sk);
1218 cdev = csk->cdev;
1141 timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT); 1219 timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT);
1142 1220
1143 err = sk_stream_wait_connect(sk, &timeo); 1221 err = sk_stream_wait_connect(sk, &timeo);
@@ -1156,6 +1234,8 @@ int chtls_sendpage(struct sock *sk, struct page *page,
1156 if (!skb || (ULP_SKB_CB(skb)->flags & ULPCB_FLAG_NO_APPEND) || 1234 if (!skb || (ULP_SKB_CB(skb)->flags & ULPCB_FLAG_NO_APPEND) ||
1157 copy <= 0) { 1235 copy <= 0) {
1158new_buf: 1236new_buf:
1237 if (!csk_mem_free(cdev, sk))
1238 goto wait_for_sndbuf;
1159 1239
1160 if (is_tls_tx(csk)) { 1240 if (is_tls_tx(csk)) {
1161 skb = get_record_skb(sk, 1241 skb = get_record_skb(sk,
@@ -1167,7 +1247,7 @@ new_buf:
1167 skb = get_tx_skb(sk, 0); 1247 skb = get_tx_skb(sk, 0);
1168 } 1248 }
1169 if (!skb) 1249 if (!skb)
1170 goto do_error; 1250 goto wait_for_memory;
1171 copy = mss; 1251 copy = mss;
1172 } 1252 }
1173 if (copy > size) 1253 if (copy > size)
@@ -1206,8 +1286,12 @@ new_buf:
1206 if (unlikely(ULP_SKB_CB(skb)->flags & ULPCB_FLAG_NO_APPEND)) 1286 if (unlikely(ULP_SKB_CB(skb)->flags & ULPCB_FLAG_NO_APPEND))
1207 push_frames_if_head(sk); 1287 push_frames_if_head(sk);
1208 continue; 1288 continue;
1209 1289wait_for_sndbuf:
1210 set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); 1290 set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
1291wait_for_memory:
1292 err = csk_wait_memory(cdev, sk, &timeo);
1293 if (err)
1294 goto do_error;
1211 } 1295 }
1212out: 1296out:
1213 csk_reset_flag(csk, CSK_TX_MORE_DATA); 1297 csk_reset_flag(csk, CSK_TX_MORE_DATA);
diff --git a/drivers/crypto/chelsio/chtls/chtls_main.c b/drivers/crypto/chelsio/chtls/chtls_main.c
index 53ffb00d45bf..273afd3b6537 100644
--- a/drivers/crypto/chelsio/chtls/chtls_main.c
+++ b/drivers/crypto/chelsio/chtls/chtls_main.c
@@ -238,6 +238,7 @@ static void *chtls_uld_add(const struct cxgb4_lld_info *info)
238 spin_lock_init(&cdev->idr_lock); 238 spin_lock_init(&cdev->idr_lock);
239 cdev->send_page_order = min_t(uint, get_order(32768), 239 cdev->send_page_order = min_t(uint, get_order(32768),
240 send_page_order); 240 send_page_order);
241 cdev->max_host_sndbuf = 48 * 1024;
241 242
242 if (lldi->vr->key.size) 243 if (lldi->vr->key.size)
243 if (chtls_init_kmap(cdev, lldi)) 244 if (chtls_init_kmap(cdev, lldi))