tcp: properly handle md5sig_pool references
Subsystems (3)
PATCH v2 1/1 tcp: properly handle md5sig_pool references
tcp_v4_clear_md5_list() assumes that multiple tcp md5sig peers only hold one reference to md5sig_pool. but tcp_v4_md5_do_add() increases use count of md5sig_pool for each peer. This patch makes tcp_v4_md5_do_add() only increases use count for the first tcp md5sig peer.
Signed-off-by Zheng Yan <[email protected]>
---
Changes since v1:
Fix a line over 80 characters warning
net/ipv4/tcp_ipv4.c | 11 +++++++---- net/ipv6/tcp_ipv6.c | 8 +++++--- 2 files changed, 12 insertions(+), 7 deletions(-)
net/ipv4/tcp_ipv4.c +7 -4
@@ -927,18 +927,21 @@ int tcp_v4_md5_do_add(struct sock *sk, __be32 addr, }sk_nocaps_add (sk,NETIF_F_GSO_MASK ); } -if (tcp_alloc_md5sig_pool (sk) ==NULL ) { + + md5sig = tp->md5sig_info; +if (md5sig->entries4 ==0 && +tcp_alloc_md5sig_pool (sk) ==NULL ) {kfree (newkey);return -ENOMEM ; } - md5sig = tp->md5sig_info;if (md5sig->alloced4 == md5sig->entries4) { keys =kmalloc ((sizeof (*keys) * (md5sig->entries4 +1 )),GFP_ATOMIC );if (!keys) {kfree (newkey); -tcp_free_md5sig_pool (); +if (md5sig->entries4 ==0 ) +tcp_free_md5sig_pool ();return -ENOMEM ; }
@@ -982,6 +985,7 @@ int tcp_v4_md5_do_del(struct sock *sk, __be32 addr)kfree (tp->md5sig_info->keys4); tp->md5sig_info->keys4 =NULL ; tp->md5sig_info->alloced4 =0 ; +tcp_free_md5sig_pool (); }else if (tp->md5sig_info->entries4 != i) {/* Need to do some manipulation */ memmove(&tp->md5sig_info->keys4[i],
@@ -989,7 +993,6 @@ int tcp_v4_md5_do_del(struct sock *sk, __be32 addr) (tp->md5sig_info->entries4 - i) * sizeof(struct tcp4_md5sig_key)); } -tcp_free_md5sig_pool ();return 0 ; } }
net/ipv6/tcp_ipv6.c +5 -3
@@ -591,7 +591,8 @@ static int tcp_v6_md5_do_add(struct sock *sk, const struct in6_addr *peer, }sk_nocaps_add (sk,NETIF_F_GSO_MASK ); } -if (tcp_alloc_md5sig_pool (sk) ==NULL ) { +if (tp->md5sig_info->entries6 ==0 && +tcp_alloc_md5sig_pool (sk) ==NULL ) {kfree (newkey);return -ENOMEM ; }
@@ -600,8 +601,9 @@ static int tcp_v6_md5_do_add(struct sock *sk, const struct in6_addr *peer, (tp->md5sig_info->entries6 + 1)), GFP_ATOMIC);if (!keys) { -tcp_free_md5sig_pool ();kfree (newkey); +if (tp->md5sig_info->entries6 ==0 ) +tcp_free_md5sig_pool ();return -ENOMEM ; }
@@ -647,6 +649,7 @@ static int tcp_v6_md5_do_del(struct sock *sk, const struct in6_addr *peer)kfree (tp->md5sig_info->keys6); tp->md5sig_info->keys6 =NULL ; tp->md5sig_info->alloced6 =0 ; +tcp_free_md5sig_pool (); }else {/* shrink the database */ if (tp->md5sig_info->entries6 != i)
@@ -655,7 +658,6 @@ static int tcp_v6_md5_do_del(struct sock *sk, const struct in6_addr *peer) (tp->md5sig_info->entries6 - i) * sizeof (tp->md5sig_info->keys6[0])); } -tcp_free_md5sig_pool ();return 0 ; } }
From: "Yan, Zheng" <[email protected]>
Date: Fri, 30 Sep 2011 11:10:10 +0800
Quoted 7 lines
tcp_v4_clear_md5_list()assumes that multiple tcp md5sig peers only hold one reference tomd5sig_pool. buttcp_v4_md5_do_add()increases use count ofmd5sig_poolfor each peer. This patch makestcp_v4_md5_do_add()only increases use count for the first tcp md5sig peer.Signed-off-by Zheng Yan <[email protected]>
Applied, thanks.