All of lore.kernel.org
 help / color / mirror / Atom feed
From: Liping Zhang <zlpnobody@163.com>
To: pablo@netfilter.org
Cc: netfilter-devel@vger.kernel.org, Liping Zhang <zlpnobody@gmail.com>
Subject: [PATCH nf 4/5] netfilter: nfnl_cthelper: fix memory leak when do update
Date: Sun, 19 Mar 2017 22:36:01 +0800	[thread overview]
Message-ID: <1489934162-7415-5-git-send-email-zlpnobody@163.com> (raw)
In-Reply-To: <1489934162-7415-1-git-send-email-zlpnobody@163.com>

From: Liping Zhang <zlpnobody@gmail.com>

When invoke nfnl_cthelper_update, we will malloc a new expect_policy,
then only point the helper->expect_policy to the new one but ignore
the old one, so it will be leaked forever.

Another issue is that the user can modify the expect_class_max to a
new value, for example, decrease the expect_class_max from 3 to 0.
Then, exp->class created by ctnetlink_alloc_expect may become invalid,
and out of bound access will happen.

So keep it simple, when update the cthelper, reject to modify the
expect_class_max, and we can modify the struct nf_conntrack_expect_policy
directly instead of allocing a new object, then memory leak does not
exist anymore.

Signed-off-by: Liping Zhang <zlpnobody@gmail.com>
---
 net/netfilter/nfnetlink_cthelper.c | 35 +++++++++++++++++++++++------------
 1 file changed, 23 insertions(+), 12 deletions(-)

diff --git a/net/netfilter/nfnetlink_cthelper.c b/net/netfilter/nfnetlink_cthelper.c
index cc70dd5..fc4733f 100644
--- a/net/netfilter/nfnetlink_cthelper.c
+++ b/net/netfilter/nfnetlink_cthelper.c
@@ -156,7 +156,7 @@ nfnl_cthelper_expect_policy_set[NFCTH_POLICY_SET_MAX+1] = {
 
 static int
 nfnl_cthelper_parse_expect_policy(struct nf_conntrack_helper *helper,
-				  const struct nlattr *attr)
+				  const struct nlattr *attr, bool update)
 {
 	int i, ret;
 	struct nf_conntrack_expect_policy *expect_policy;
@@ -172,15 +172,23 @@ nfnl_cthelper_parse_expect_policy(struct nf_conntrack_helper *helper,
 		return -EINVAL;
 
 	class_max = ntohl(nla_get_be32(tb[NFCTH_POLICY_SET_NUM]));
-	if (class_max == 0)
-		return -EINVAL;
-	if (class_max > NF_CT_MAX_EXPECT_CLASSES)
-		return -EOVERFLOW;
 
-	expect_policy = kzalloc(sizeof(struct nf_conntrack_expect_policy) *
-				class_max, GFP_KERNEL);
-	if (expect_policy == NULL)
-		return -ENOMEM;
+	if (update) {
+		if (helper->expect_class_max + 1 != class_max)
+			return -EINVAL;
+
+		expect_policy = helper->expect_policy;
+	} else {
+		if (class_max == 0)
+			return -EINVAL;
+		if (class_max > NF_CT_MAX_EXPECT_CLASSES)
+			return -EOVERFLOW;
+
+		expect_policy = kcalloc(class_max, sizeof(*expect_policy),
+					GFP_KERNEL);
+		if (expect_policy == NULL)
+			return -ENOMEM;
+	}
 
 	for (i = 0; i < class_max; i++) {
 		if (!tb[NFCTH_POLICY_SET+i])
@@ -196,7 +204,8 @@ nfnl_cthelper_parse_expect_policy(struct nf_conntrack_helper *helper,
 	helper->expect_policy = expect_policy;
 	return 0;
 err:
-	kfree(expect_policy);
+	if (!update)
+		kfree(expect_policy);
 	return -EINVAL;
 }
 
@@ -214,7 +223,8 @@ nfnl_cthelper_create(const struct nlattr * const tb[],
 	if (helper == NULL)
 		return -ENOMEM;
 
-	ret = nfnl_cthelper_parse_expect_policy(helper, tb[NFCTH_POLICY]);
+	ret = nfnl_cthelper_parse_expect_policy(helper, tb[NFCTH_POLICY],
+						false);
 	if (ret < 0)
 		goto err1;
 
@@ -269,7 +279,8 @@ nfnl_cthelper_update(const struct nlattr * const tb[],
 
 	if (tb[NFCTH_POLICY]) {
 		ret = nfnl_cthelper_parse_expect_policy(helper,
-							tb[NFCTH_POLICY]);
+							tb[NFCTH_POLICY],
+							true);
 		if (ret < 0)
 			return ret;
 	}
-- 
2.5.5



  parent reply	other threads:[~2017-03-19 14:54 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-03-19 14:35 [PATCH nf 0/5] netfilter: nfnl_cthelper: fix some bugs Liping Zhang
2017-03-19 14:35 ` [PATCH nf 1/5] netfilter: nfnl_cthelper: don't report error if NFCTH_PRIV_DATA_LEN is empty Liping Zhang
2017-03-21 10:18   ` Pablo Neira Ayuso
2017-03-21 14:26     ` Liping Zhang
2017-03-19 14:35 ` [PATCH nf 2/5] netfilter: nfnl_cthelper: fix incorrect helper->expect_class_max Liping Zhang
2017-03-21 10:27   ` Pablo Neira Ayuso
2017-03-21 14:35     ` Liping Zhang
2017-03-21 14:49       ` Pablo Neira Ayuso
2017-03-19 14:36 ` [PATCH nf 3/5] netfilter: drop const qualifier from struct nf_conntrack_expect_policy Liping Zhang
2017-03-21 10:34   ` Pablo Neira Ayuso
2017-03-21 15:00     ` Liping Zhang
2017-03-21 15:03       ` Pablo Neira Ayuso
2017-03-19 14:36 ` Liping Zhang [this message]
2017-03-21 10:32   ` [PATCH nf 4/5] netfilter: nfnl_cthelper: fix memory leak when do update Pablo Neira Ayuso
2017-03-21 13:23     ` Pablo Neira Ayuso
2017-03-19 14:36 ` [PATCH nf 5/5] netfilter: nfnl_cthelper: fix a race when walk the nf_ct_helper_hash table Liping Zhang
2017-03-21 10:33   ` Pablo Neira Ayuso
2017-03-21 14:48     ` Liping Zhang
2017-03-21 15:19       ` Liping Zhang
2017-03-21 15:26         ` Pablo Neira Ayuso
2017-03-22  0:06           ` Liping Zhang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1489934162-7415-5-git-send-email-zlpnobody@163.com \
    --to=zlpnobody@163.com \
    --cc=netfilter-devel@vger.kernel.org \
    --cc=pablo@netfilter.org \
    --cc=zlpnobody@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.