diff options
author | Rusty Russell <rusty@rustcorp.com.au> | 2005-07-21 16:14:46 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2005-07-21 16:14:46 -0400 |
commit | 4acdbdbe5089c06d5e0c7e96783fcc4414ded00a (patch) | |
tree | 77629aef70bd92983518b6f5dd13c70a222c4cbb /include | |
parent | 4aa49d130df9209707a97786a55a3f584b7345e9 (diff) |
[NETFILTER]: ip_conntrack_expect_related must not free expectation
If a connection tracking helper tells us to expect a connection, and
we're already expecting that connection, we simply free the one they
gave us and return success.
The problem is that NAT helpers (eg. FTP) have to allocate the
expectation first (to see what port is available) then rewrite the
packet. If that rewrite fails, they try to remove the expectation,
but it was freed in ip_conntrack_expect_related.
This is one example of a larger problem: having registered the
expectation, the pointer is no longer ours to use. Reference counting
is needed for ctnetlink anyway, so introduce it now.
To have a single "put" path, we need to grab the reference to the
connection on creation, rather than open-coding it in the caller.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/netfilter_ipv4/ip_conntrack.h | 3 | ||||
-rw-r--r-- | include/linux/netfilter_ipv4/ip_conntrack_helper.h | 7 |
2 files changed, 7 insertions, 3 deletions
diff --git a/include/linux/netfilter_ipv4/ip_conntrack.h b/include/linux/netfilter_ipv4/ip_conntrack.h index 3781192ce159..f8da7ddeff3a 100644 --- a/include/linux/netfilter_ipv4/ip_conntrack.h +++ b/include/linux/netfilter_ipv4/ip_conntrack.h | |||
@@ -197,6 +197,9 @@ struct ip_conntrack_expect | |||
197 | /* Timer function; deletes the expectation. */ | 197 | /* Timer function; deletes the expectation. */ |
198 | struct timer_list timeout; | 198 | struct timer_list timeout; |
199 | 199 | ||
200 | /* Usage count. */ | ||
201 | atomic_t use; | ||
202 | |||
200 | #ifdef CONFIG_IP_NF_NAT_NEEDED | 203 | #ifdef CONFIG_IP_NF_NAT_NEEDED |
201 | /* This is the original per-proto part, used to map the | 204 | /* This is the original per-proto part, used to map the |
202 | * expected connection the way the recipient expects. */ | 205 | * expected connection the way the recipient expects. */ |
diff --git a/include/linux/netfilter_ipv4/ip_conntrack_helper.h b/include/linux/netfilter_ipv4/ip_conntrack_helper.h index b1bbba0a12cb..3692daa93dec 100644 --- a/include/linux/netfilter_ipv4/ip_conntrack_helper.h +++ b/include/linux/netfilter_ipv4/ip_conntrack_helper.h | |||
@@ -30,9 +30,10 @@ extern int ip_conntrack_helper_register(struct ip_conntrack_helper *); | |||
30 | extern void ip_conntrack_helper_unregister(struct ip_conntrack_helper *); | 30 | extern void ip_conntrack_helper_unregister(struct ip_conntrack_helper *); |
31 | 31 | ||
32 | /* Allocate space for an expectation: this is mandatory before calling | 32 | /* Allocate space for an expectation: this is mandatory before calling |
33 | ip_conntrack_expect_related. */ | 33 | ip_conntrack_expect_related. You will have to call put afterwards. */ |
34 | extern struct ip_conntrack_expect *ip_conntrack_expect_alloc(void); | 34 | extern struct ip_conntrack_expect * |
35 | extern void ip_conntrack_expect_free(struct ip_conntrack_expect *exp); | 35 | ip_conntrack_expect_alloc(struct ip_conntrack *master); |
36 | extern void ip_conntrack_expect_put(struct ip_conntrack_expect *exp); | ||
36 | 37 | ||
37 | /* Add an expected connection: can have more than one per connection */ | 38 | /* Add an expected connection: can have more than one per connection */ |
38 | extern int ip_conntrack_expect_related(struct ip_conntrack_expect *exp); | 39 | extern int ip_conntrack_expect_related(struct ip_conntrack_expect *exp); |