summaryrefslogtreecommitdiffstats
path: root/net/sctp
diff options
context:
space:
mode:
authorWei Yongjun <yjwei@cn.fujitsu.com>2011-05-24 21:48:02 +0000
committerDavid S. Miller <davem@davemloft.net>2011-05-25 17:55:32 -0400
commit8b4472cc13136d04727e399c6fdadf58d2218b0a (patch)
treecad3cdcca69d8a701558386fef36f2f158a570a5 /net/sctp
parentf11970e383acd6f505f492f1bc07fb1a4d884829 (diff)
downloadlinux-8b4472cc13136d04727e399c6fdadf58d2218b0a.tar.gz
linux-8b4472cc13136d04727e399c6fdadf58d2218b0a.tar.bz2
linux-8b4472cc13136d04727e399c6fdadf58d2218b0a.zip
sctp: fix memory leak of the ASCONF queue when free asoc
If an ASCONF chunk is outstanding, then the following ASCONF chunk will be queued for later transmission. But when we free the asoc, we forget to free the ASCONF queue at the same time, this will cause memory leak. Signed-off-by: Wei Yongjun <yjwei@cn.fujitsu.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sctp')
-rw-r--r--net/sctp/associola.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index 1a21c571aa03..525f97c467e9 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -64,6 +64,7 @@
/* Forward declarations for internal functions. */
static void sctp_assoc_bh_rcv(struct work_struct *work);
static void sctp_assoc_free_asconf_acks(struct sctp_association *asoc);
+static void sctp_assoc_free_asconf_queue(struct sctp_association *asoc);
/* Keep track of the new idr low so that we don't re-use association id
* numbers too fast. It is protected by they idr spin lock is in the
@@ -446,6 +447,9 @@ void sctp_association_free(struct sctp_association *asoc)
/* Free any cached ASCONF_ACK chunk. */
sctp_assoc_free_asconf_acks(asoc);
+ /* Free the ASCONF queue. */
+ sctp_assoc_free_asconf_queue(asoc);
+
/* Free any cached ASCONF chunk. */
if (asoc->addip_last_asconf)
sctp_chunk_free(asoc->addip_last_asconf);
@@ -1578,6 +1582,18 @@ retry:
return error;
}
+/* Free the ASCONF queue */
+static void sctp_assoc_free_asconf_queue(struct sctp_association *asoc)
+{
+ struct sctp_chunk *asconf;
+ struct sctp_chunk *tmp;
+
+ list_for_each_entry_safe(asconf, tmp, &asoc->addip_chunk_list, list) {
+ list_del_init(&asconf->list);
+ sctp_chunk_free(asconf);
+ }
+}
+
/* Free asconf_ack cache */
static void sctp_assoc_free_asconf_acks(struct sctp_association *asoc)
{