All of lore.kernel.org
 help / color / mirror / Atom feed
From: Patrick McHardy <kaber@trash.net>
To: Dmitry Mishin <dim@openvz.org>
Cc: Jan Engelhardt <jengelh@linux01.gwdg.de>,
	sparclinux@vger.kernel.org,
	Netfilter Developer Mailing List
	<netfilter-devel@lists.netfilter.org>
Subject: Re: iptables throws unknown error - suspecting 32/64 compat issue
Date: Sun, 03 Jun 2007 18:57:13 +0200	[thread overview]
Message-ID: <4662F2E9.1090903@trash.net> (raw)
In-Reply-To: <200706031047.44848.dim@openvz.org>

[-- Attachment #1: Type: text/plain, Size: 385 bytes --]

Dmitry Mishin wrote:
> On Saturday 02 June 2007 16:54, Patrick McHardy wrote:
> 
>>Here it is, could you please test whether it fixes the crash by
>>backing out the hashlimit compat patch and triggering the size
>>error again? Thanks.
> 
> Patrick, 
> it looks like translate_compat_table() should be fixed also.


You're right, thanks for catching this. This patch should be
better.


[-- Attachment #2: x --]
[-- Type: text/plain, Size: 3737 bytes --]

[NETFILTER]: ip_tables: fix compat related crash

check_compat_entry_size_and_hooks iterates over the matches and calls
compat_check_calc_match, which loads the match and calculates the
compat offsets, but unlike the non-compat version, doesn't call
->checkentry yet. On error however it calls cleanup_matches, which in
turn calls ->destroy, which can result in crashes if the destroy
function (validly) expects to only get called after the checkentry
function.

Add a compat_release_match function that only drops the module reference
on error and rename compat_check_calc_match to compat_find_calc_match to
reflect the fact that it doesn't call the checkentry function.

Reported by Jan Engelhardt <jengelh@linux01.gwdg.de>

Signed-off-by: Patrick McHardy <kaber@trash.net>

---
commit b2b15a77343e2baadee22a5e64f691732874b10b
tree 7d82cf0a9fd3cf77933205a7a1834e958293e293
parent e7d815ef75f70dcdf55001f1f88ae7ae8827a7ba
author Patrick McHardy <kaber@trash.net> Sun, 03 Jun 2007 18:57:04 +0200
committer Patrick McHardy <kaber@trash.net> Sun, 03 Jun 2007 18:57:04 +0200

 net/ipv4/netfilter/ip_tables.c |   41 ++++++++++++++++++++++++++++++++--------
 1 files changed, 33 insertions(+), 8 deletions(-)

diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index e3f83bf..0a35639 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -1425,7 +1425,7 @@ out:
 }
 
 static inline int
-compat_check_calc_match(struct ipt_entry_match *m,
+compat_find_calc_match(struct ipt_entry_match *m,
 	    const char *name,
 	    const struct ipt_ip *ip,
 	    unsigned int hookmask,
@@ -1449,6 +1449,31 @@ compat_check_calc_match(struct ipt_entry_match *m,
 }
 
 static inline int
+compat_release_match(struct ipt_entry_match *m, unsigned int *i)
+{
+	if (i && (*i)-- == 0)
+		return 1;
+
+	module_put(m->u.kernel.match->me);
+	return 0;
+}
+
+static inline int
+compat_release_entry(struct ipt_entry *e, unsigned int *i)
+{
+	struct ipt_entry_target *t;
+
+	if (i && (*i)-- == 0)
+		return 1;
+
+	/* Cleanup all matches */
+	IPT_MATCH_ITERATE(e, compat_release_match, NULL);
+	t = ipt_get_target(e);
+	module_put(t->u.kernel.target->me);
+	return 0;
+}
+
+static inline int
 check_compat_entry_size_and_hooks(struct ipt_entry *e,
 			   struct xt_table_info *newinfo,
 			   unsigned int *size,
@@ -1485,10 +1510,10 @@ check_compat_entry_size_and_hooks(struct ipt_entry *e,
 	off = 0;
 	entry_offset = (void *)e - (void *)base;
 	j = 0;
-	ret = IPT_MATCH_ITERATE(e, compat_check_calc_match, name, &e->ip,
+	ret = IPT_MATCH_ITERATE(e, compat_find_calc_match, name, &e->ip,
 			e->comefrom, &off, &j);
 	if (ret != 0)
-		goto cleanup_matches;
+		goto release_matches;
 
 	t = ipt_get_target(e);
 	target = try_then_request_module(xt_find_target(AF_INET,
@@ -1499,7 +1524,7 @@ check_compat_entry_size_and_hooks(struct ipt_entry *e,
 		duprintf("check_compat_entry_size_and_hooks: `%s' not found\n",
 							t->u.user.name);
 		ret = target ? PTR_ERR(target) : -ENOENT;
-		goto cleanup_matches;
+		goto release_matches;
 	}
 	t->u.kernel.target = target;
 
@@ -1526,8 +1551,8 @@ check_compat_entry_size_and_hooks(struct ipt_entry *e,
 
 out:
 	module_put(t->u.kernel.target->me);
-cleanup_matches:
-	IPT_MATCH_ITERATE(e, cleanup_match, &j);
+release_matches:
+	IPT_MATCH_ITERATE(e, compat_release_match, &j);
 	return ret;
 }
 
@@ -1690,13 +1715,13 @@ translate_compat_table(const char *name,
 
 free_newinfo:
 	xt_free_table_info(newinfo);
-out:
 	IPT_ENTRY_ITERATE(entry0, total_size, cleanup_entry, &j);
 	return ret;
 out_unlock:
 	compat_flush_offsets();
 	xt_compat_unlock(AF_INET);
-	goto out;
+	IPT_ENTRY_ITERATE(entry0, total_size, compat_release_entry, &j);
+	return ret;
 }
 
 static int

WARNING: multiple messages have this Message-ID (diff)
From: Patrick McHardy <kaber@trash.net>
To: Dmitry Mishin <dim@openvz.org>
Cc: Jan Engelhardt <jengelh@linux01.gwdg.de>,
	sparclinux@vger.kernel.org,
	Netfilter Developer Mailing List
	<netfilter-devel@lists.netfilter.org>
Subject: Re: iptables throws unknown error - suspecting 32/64 compat issue
Date: Sun, 03 Jun 2007 16:57:13 +0000	[thread overview]
Message-ID: <4662F2E9.1090903@trash.net> (raw)
In-Reply-To: <200706031047.44848.dim@openvz.org>

[-- Attachment #1: Type: text/plain, Size: 385 bytes --]

Dmitry Mishin wrote:
> On Saturday 02 June 2007 16:54, Patrick McHardy wrote:
> 
>>Here it is, could you please test whether it fixes the crash by
>>backing out the hashlimit compat patch and triggering the size
>>error again? Thanks.
> 
> Patrick, 
> it looks like translate_compat_table() should be fixed also.


You're right, thanks for catching this. This patch should be
better.


[-- Attachment #2: x --]
[-- Type: text/plain, Size: 3737 bytes --]

[NETFILTER]: ip_tables: fix compat related crash

check_compat_entry_size_and_hooks iterates over the matches and calls
compat_check_calc_match, which loads the match and calculates the
compat offsets, but unlike the non-compat version, doesn't call
->checkentry yet. On error however it calls cleanup_matches, which in
turn calls ->destroy, which can result in crashes if the destroy
function (validly) expects to only get called after the checkentry
function.

Add a compat_release_match function that only drops the module reference
on error and rename compat_check_calc_match to compat_find_calc_match to
reflect the fact that it doesn't call the checkentry function.

Reported by Jan Engelhardt <jengelh@linux01.gwdg.de>

Signed-off-by: Patrick McHardy <kaber@trash.net>

---
commit b2b15a77343e2baadee22a5e64f691732874b10b
tree 7d82cf0a9fd3cf77933205a7a1834e958293e293
parent e7d815ef75f70dcdf55001f1f88ae7ae8827a7ba
author Patrick McHardy <kaber@trash.net> Sun, 03 Jun 2007 18:57:04 +0200
committer Patrick McHardy <kaber@trash.net> Sun, 03 Jun 2007 18:57:04 +0200

 net/ipv4/netfilter/ip_tables.c |   41 ++++++++++++++++++++++++++++++++--------
 1 files changed, 33 insertions(+), 8 deletions(-)

diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index e3f83bf..0a35639 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -1425,7 +1425,7 @@ out:
 }
 
 static inline int
-compat_check_calc_match(struct ipt_entry_match *m,
+compat_find_calc_match(struct ipt_entry_match *m,
 	    const char *name,
 	    const struct ipt_ip *ip,
 	    unsigned int hookmask,
@@ -1449,6 +1449,31 @@ compat_check_calc_match(struct ipt_entry_match *m,
 }
 
 static inline int
+compat_release_match(struct ipt_entry_match *m, unsigned int *i)
+{
+	if (i && (*i)-- == 0)
+		return 1;
+
+	module_put(m->u.kernel.match->me);
+	return 0;
+}
+
+static inline int
+compat_release_entry(struct ipt_entry *e, unsigned int *i)
+{
+	struct ipt_entry_target *t;
+
+	if (i && (*i)-- == 0)
+		return 1;
+
+	/* Cleanup all matches */
+	IPT_MATCH_ITERATE(e, compat_release_match, NULL);
+	t = ipt_get_target(e);
+	module_put(t->u.kernel.target->me);
+	return 0;
+}
+
+static inline int
 check_compat_entry_size_and_hooks(struct ipt_entry *e,
 			   struct xt_table_info *newinfo,
 			   unsigned int *size,
@@ -1485,10 +1510,10 @@ check_compat_entry_size_and_hooks(struct ipt_entry *e,
 	off = 0;
 	entry_offset = (void *)e - (void *)base;
 	j = 0;
-	ret = IPT_MATCH_ITERATE(e, compat_check_calc_match, name, &e->ip,
+	ret = IPT_MATCH_ITERATE(e, compat_find_calc_match, name, &e->ip,
 			e->comefrom, &off, &j);
 	if (ret != 0)
-		goto cleanup_matches;
+		goto release_matches;
 
 	t = ipt_get_target(e);
 	target = try_then_request_module(xt_find_target(AF_INET,
@@ -1499,7 +1524,7 @@ check_compat_entry_size_and_hooks(struct ipt_entry *e,
 		duprintf("check_compat_entry_size_and_hooks: `%s' not found\n",
 							t->u.user.name);
 		ret = target ? PTR_ERR(target) : -ENOENT;
-		goto cleanup_matches;
+		goto release_matches;
 	}
 	t->u.kernel.target = target;
 
@@ -1526,8 +1551,8 @@ check_compat_entry_size_and_hooks(struct ipt_entry *e,
 
 out:
 	module_put(t->u.kernel.target->me);
-cleanup_matches:
-	IPT_MATCH_ITERATE(e, cleanup_match, &j);
+release_matches:
+	IPT_MATCH_ITERATE(e, compat_release_match, &j);
 	return ret;
 }
 
@@ -1690,13 +1715,13 @@ translate_compat_table(const char *name,
 
 free_newinfo:
 	xt_free_table_info(newinfo);
-out:
 	IPT_ENTRY_ITERATE(entry0, total_size, cleanup_entry, &j);
 	return ret;
 out_unlock:
 	compat_flush_offsets();
 	xt_compat_unlock(AF_INET);
-	goto out;
+	IPT_ENTRY_ITERATE(entry0, total_size, compat_release_entry, &j);
+	return ret;
 }
 
 static int

  reply	other threads:[~2007-06-03 16:57 UTC|newest]

Thread overview: 48+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-05-10  6:27 iptables throws unknown error - suspecting 32/64 compat issue Jan Engelhardt
2007-05-10  6:27 ` Jan Engelhardt
2007-05-10  6:34 ` Jan Engelhardt
2007-05-10  6:34   ` Jan Engelhardt
2007-05-10  7:16   ` David Miller
2007-05-10  7:16     ` David Miller
2007-05-10 13:20   ` Patrick McHardy
2007-05-10 13:20     ` Patrick McHardy
2007-05-10 13:24     ` Jan Engelhardt
2007-05-10 13:24       ` Jan Engelhardt
2007-05-10 14:02       ` Patrick McHardy
2007-05-10 14:02         ` Patrick McHardy
2007-05-10 14:05         ` Jan Engelhardt
2007-05-10 14:05           ` Jan Engelhardt
2007-05-29 21:36           ` Jan Engelhardt
2007-05-29 21:36             ` Jan Engelhardt
2007-05-29 22:29             ` Patrick McHardy
2007-05-29 22:29               ` Patrick McHardy
2007-06-02 12:54               ` Patrick McHardy
2007-06-02 12:54                 ` Patrick McHardy
2007-06-02 13:29                 ` Jan Engelhardt
2007-06-02 13:29                   ` Jan Engelhardt
2007-06-02 13:53                   ` Patrick McHardy
2007-06-02 13:53                     ` Patrick McHardy
2007-06-02 14:25                 ` Jan Engelhardt
2007-06-02 14:25                   ` Jan Engelhardt
2007-06-02 14:43                   ` Patrick McHardy
2007-06-02 14:43                     ` Patrick McHardy
2007-06-03  6:47                 ` Dmitry Mishin
2007-06-03  6:47                   ` Dmitry Mishin
2007-06-03 16:57                   ` Patrick McHardy [this message]
2007-06-03 16:57                     ` Patrick McHardy
2007-06-03 17:29                     ` Jan Engelhardt
2007-06-03 17:29                       ` Jan Engelhardt
2007-06-03 17:31                       ` Patrick McHardy
2007-06-03 17:31                         ` Patrick McHardy
2007-06-03 18:11                         ` Jan Engelhardt
2007-06-03 18:11                           ` Jan Engelhardt
2007-06-04  7:54                     ` Dmitry Mishin
2007-06-04  7:54                       ` Dmitry Mishin
2007-06-05 12:16                       ` Patrick McHardy
2007-06-05 12:16                         ` Patrick McHardy
2007-06-05 13:32                         ` Patrick McHardy
2007-06-05 13:32                           ` Patrick McHardy
2007-06-05 13:50                           ` Dmitry Mishin
2007-06-05 13:50                             ` Dmitry Mishin
2007-05-10 12:58 ` Patrick McHardy
2007-05-10 12:58   ` Patrick McHardy

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=4662F2E9.1090903@trash.net \
    --to=kaber@trash.net \
    --cc=dim@openvz.org \
    --cc=jengelh@linux01.gwdg.de \
    --cc=netfilter-devel@lists.netfilter.org \
    --cc=sparclinux@vger.kernel.org \
    /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.