diff options
author | Patrick McHardy <kaber@trash.net> | 2008-02-07 20:56:34 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-02-07 20:56:34 -0500 |
commit | 86577c661bc01d5c4e477d74567df4470d6c5138 (patch) | |
tree | bbe853c912e959be44b61d2a3c14a761fe9226ac /net | |
parent | b2155e7f70b3f058efe94c0c459db023b05057bd (diff) |
[NETFILTER]: nf_conntrack: fix ct_extend ->move operation
The ->move operation has two bugs:
- It is called with the same extension as source and destination,
so it doesn't update the new extension.
- The address of the old extension is calculated incorrectly,
instead of (void *)ct->ext + ct->ext->offset[i] it uses
ct->ext + ct->ext->offset[i].
Fixes a crash on x86_64 reported by Chuck Ebbert <cebbert@redhat.com>
and Thomas Woerner <twoerner@redhat.com>.
Tested-by: Thomas Woerner <twoerner@redhat.com>
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/netfilter/nf_nat_core.c | 6 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_extend.c | 3 |
2 files changed, 5 insertions, 4 deletions
diff --git a/net/ipv4/netfilter/nf_nat_core.c b/net/ipv4/netfilter/nf_nat_core.c index dd07362d2b8f..0d5fa3a54d04 100644 --- a/net/ipv4/netfilter/nf_nat_core.c +++ b/net/ipv4/netfilter/nf_nat_core.c | |||
@@ -600,10 +600,10 @@ static void nf_nat_cleanup_conntrack(struct nf_conn *ct) | |||
600 | spin_unlock_bh(&nf_nat_lock); | 600 | spin_unlock_bh(&nf_nat_lock); |
601 | } | 601 | } |
602 | 602 | ||
603 | static void nf_nat_move_storage(struct nf_conn *conntrack, void *old) | 603 | static void nf_nat_move_storage(void *new, void *old) |
604 | { | 604 | { |
605 | struct nf_conn_nat *new_nat = nf_ct_ext_find(conntrack, NF_CT_EXT_NAT); | 605 | struct nf_conn_nat *new_nat = new; |
606 | struct nf_conn_nat *old_nat = (struct nf_conn_nat *)old; | 606 | struct nf_conn_nat *old_nat = old; |
607 | struct nf_conn *ct = old_nat->ct; | 607 | struct nf_conn *ct = old_nat->ct; |
608 | 608 | ||
609 | if (!ct || !(ct->status & IPS_NAT_DONE_MASK)) | 609 | if (!ct || !(ct->status & IPS_NAT_DONE_MASK)) |
diff --git a/net/netfilter/nf_conntrack_extend.c b/net/netfilter/nf_conntrack_extend.c index cf6ba6659a80..8b9be1e978cd 100644 --- a/net/netfilter/nf_conntrack_extend.c +++ b/net/netfilter/nf_conntrack_extend.c | |||
@@ -109,7 +109,8 @@ void *__nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp) | |||
109 | rcu_read_lock(); | 109 | rcu_read_lock(); |
110 | t = rcu_dereference(nf_ct_ext_types[i]); | 110 | t = rcu_dereference(nf_ct_ext_types[i]); |
111 | if (t && t->move) | 111 | if (t && t->move) |
112 | t->move(ct, ct->ext + ct->ext->offset[i]); | 112 | t->move((void *)new + new->offset[i], |
113 | (void *)ct->ext + ct->ext->offset[i]); | ||
113 | rcu_read_unlock(); | 114 | rcu_read_unlock(); |
114 | } | 115 | } |
115 | kfree(ct->ext); | 116 | kfree(ct->ext); |