aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorYan, Zheng <zheng.z.yan@intel.com>2011-09-29 13:10:10 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2011-11-11 12:36:27 -0500
commit37c88f5fe7f287a945949e6f4570700c210ebe0f (patch)
tree70ee5416e53203a4186d46fd493fb0ee02a8c74c /net/ipv6
parent18743353b3154f0ff7c29f3c5ae3a8466a70d73a (diff)
tcp: properly handle md5sig_pool references
[ Upstream commit 260fcbeb1ae9e768a44c9925338fbacb0d7e5ba9 ] 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 <zheng.z.yan@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/tcp_ipv6.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 7c43e861475..af78a16c830 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -605,7 +605,8 @@ static int tcp_v6_md5_do_add(struct sock *sk, const struct in6_addr *peer,
605 } 605 }
606 sk_nocaps_add(sk, NETIF_F_GSO_MASK); 606 sk_nocaps_add(sk, NETIF_F_GSO_MASK);
607 } 607 }
608 if (tcp_alloc_md5sig_pool(sk) == NULL) { 608 if (tp->md5sig_info->entries6 == 0 &&
609 tcp_alloc_md5sig_pool(sk) == NULL) {
609 kfree(newkey); 610 kfree(newkey);
610 return -ENOMEM; 611 return -ENOMEM;
611 } 612 }
@@ -614,8 +615,9 @@ static int tcp_v6_md5_do_add(struct sock *sk, const struct in6_addr *peer,
614 (tp->md5sig_info->entries6 + 1)), GFP_ATOMIC); 615 (tp->md5sig_info->entries6 + 1)), GFP_ATOMIC);
615 616
616 if (!keys) { 617 if (!keys) {
617 tcp_free_md5sig_pool();
618 kfree(newkey); 618 kfree(newkey);
619 if (tp->md5sig_info->entries6 == 0)
620 tcp_free_md5sig_pool();
619 return -ENOMEM; 621 return -ENOMEM;
620 } 622 }
621 623
@@ -661,6 +663,7 @@ static int tcp_v6_md5_do_del(struct sock *sk, const struct in6_addr *peer)
661 kfree(tp->md5sig_info->keys6); 663 kfree(tp->md5sig_info->keys6);
662 tp->md5sig_info->keys6 = NULL; 664 tp->md5sig_info->keys6 = NULL;
663 tp->md5sig_info->alloced6 = 0; 665 tp->md5sig_info->alloced6 = 0;
666 tcp_free_md5sig_pool();
664 } else { 667 } else {
665 /* shrink the database */ 668 /* shrink the database */
666 if (tp->md5sig_info->entries6 != i) 669 if (tp->md5sig_info->entries6 != i)
@@ -669,7 +672,6 @@ static int tcp_v6_md5_do_del(struct sock *sk, const struct in6_addr *peer)
669 (tp->md5sig_info->entries6 - i) 672 (tp->md5sig_info->entries6 - i)
670 * sizeof (tp->md5sig_info->keys6[0])); 673 * sizeof (tp->md5sig_info->keys6[0]));
671 } 674 }
672 tcp_free_md5sig_pool();
673 return 0; 675 return 0;
674 } 676 }
675 } 677 }