[NETFILTER]: nf_conntrack: fix ct_extend ->move operation
authorPatrick McHardy <kaber@trash.net>
Fri, 8 Feb 2008 01:56:34 +0000 (17:56 -0800)
committerDavid S. Miller <davem@davemloft.net>
Fri, 8 Feb 2008 01:56:34 +0000 (17:56 -0800)
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>
include/net/netfilter/nf_conntrack_extend.h
net/ipv4/netfilter/nf_nat_core.c
net/netfilter/nf_conntrack_extend.c

index 73b5711faf32f4e47b81044ec0c54b0978c669ca..49aac6323fbeaf7c4dacbb16c8194d91246977bf 100644 (file)
@@ -67,7 +67,7 @@ struct nf_ct_ext_type
        void (*destroy)(struct nf_conn *ct);
        /* Called when realloacted (can be NULL).
           Contents has already been moved. */
-       void (*move)(struct nf_conn *ct, void *old);
+       void (*move)(void *new, void *old);
 
        enum nf_ct_ext_id id;
 
index dd07362d2b8f42e5303419d509a0a1136e51cd42..0d5fa3a54d04053f8068ce685c157ffa554c8539 100644 (file)
@@ -600,10 +600,10 @@ static void nf_nat_cleanup_conntrack(struct nf_conn *ct)
        spin_unlock_bh(&nf_nat_lock);
 }
 
-static void nf_nat_move_storage(struct nf_conn *conntrack, void *old)
+static void nf_nat_move_storage(void *new, void *old)
 {
-       struct nf_conn_nat *new_nat = nf_ct_ext_find(conntrack, NF_CT_EXT_NAT);
-       struct nf_conn_nat *old_nat = (struct nf_conn_nat *)old;
+       struct nf_conn_nat *new_nat = new;
+       struct nf_conn_nat *old_nat = old;
        struct nf_conn *ct = old_nat->ct;
 
        if (!ct || !(ct->status & IPS_NAT_DONE_MASK))
index cf6ba6659a8080938b3aaaa44c6ef46d0a47ad72..8b9be1e978cda3dc00c01050d69e495ac8c610ad 100644 (file)
@@ -109,7 +109,8 @@ void *__nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp)
                        rcu_read_lock();
                        t = rcu_dereference(nf_ct_ext_types[i]);
                        if (t && t->move)
-                               t->move(ct, ct->ext + ct->ext->offset[i]);
+                               t->move((void *)new + new->offset[i],
+                                       (void *)ct->ext + ct->ext->offset[i]);
                        rcu_read_unlock();
                }
                kfree(ct->ext);