| From a770ad82dd35b088dfd792a51c5807378a580fe8 Mon Sep 17 00:00:00 2001 |
| From: Wei Wang <weiwan@google.com> |
| Date: Tue, 25 Apr 2017 17:38:02 -0700 |
| Subject: [PATCH] tcp: memset ca_priv data to 0 properly |
| |
| commit c1201444075009507a6818de6518e2822b9a87c8 upstream. |
| |
| Always zero out ca_priv data in tcp_assign_congestion_control() so that |
| ca_priv data is cleared out during socket creation. |
| Also always zero out ca_priv data in tcp_reinit_congestion_control() so |
| that when cc algorithm is changed, ca_priv data is cleared out as well. |
| We should still zero out ca_priv data even in TCP_CLOSE state because |
| user could call connect() on AF_UNSPEC to disconnect the socket and |
| leave it in TCP_CLOSE state and later call setsockopt() to switch cc |
| algorithm on this socket. |
| |
| Fixes: 2b0a8c9ee ("tcp: add CDG congestion control") |
| Reported-by: Andrey Konovalov <andreyknvl@google.com> |
| Signed-off-by: Wei Wang <weiwan@google.com> |
| Acked-by: Eric Dumazet <edumazet@google.com> |
| Acked-by: Yuchung Cheng <ycheng@google.com> |
| Acked-by: Neal Cardwell <ncardwell@google.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| [PG: 4.8 diffstat is smaller, due to no need for {...} removal.] |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c |
| index 882caa4e72bc..e5148d64a064 100644 |
| --- a/net/ipv4/tcp_cong.c |
| +++ b/net/ipv4/tcp_cong.c |
| @@ -167,12 +167,8 @@ void tcp_assign_congestion_control(struct sock *sk) |
| } |
| out: |
| rcu_read_unlock(); |
| + memset(icsk->icsk_ca_priv, 0, sizeof(icsk->icsk_ca_priv)); |
| |
| - /* Clear out private data before diag gets it and |
| - * the ca has not been initialized. |
| - */ |
| - if (ca->get_info) |
| - memset(icsk->icsk_ca_priv, 0, sizeof(icsk->icsk_ca_priv)); |
| if (ca->flags & TCP_CONG_NEEDS_ECN) |
| INET_ECN_xmit(sk); |
| else |
| @@ -199,6 +195,7 @@ static void tcp_reinit_congestion_control(struct sock *sk, |
| tcp_cleanup_congestion_control(sk); |
| icsk->icsk_ca_ops = ca; |
| icsk->icsk_ca_setsockopt = 1; |
| + memset(icsk->icsk_ca_priv, 0, sizeof(icsk->icsk_ca_priv)); |
| |
| if (sk->sk_state != TCP_CLOSE) |
| tcp_init_congestion_control(sk); |
| -- |
| 2.12.0 |
| |