Commit 86577c66 authored by Patrick McHardy's avatar Patrick McHardy Committed by David S. Miller

[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: default avatarThomas Woerner <twoerner@redhat.com>
Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent b2155e7f
...@@ -67,7 +67,7 @@ struct nf_ct_ext_type ...@@ -67,7 +67,7 @@ struct nf_ct_ext_type
void (*destroy)(struct nf_conn *ct); void (*destroy)(struct nf_conn *ct);
/* Called when realloacted (can be NULL). /* Called when realloacted (can be NULL).
Contents has already been moved. */ 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; enum nf_ct_ext_id id;
......
...@@ -600,10 +600,10 @@ static void nf_nat_cleanup_conntrack(struct nf_conn *ct) ...@@ -600,10 +600,10 @@ static void nf_nat_cleanup_conntrack(struct nf_conn *ct)
spin_unlock_bh(&nf_nat_lock); 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 *new_nat = new;
struct nf_conn_nat *old_nat = (struct nf_conn_nat *)old; struct nf_conn_nat *old_nat = old;
struct nf_conn *ct = old_nat->ct; struct nf_conn *ct = old_nat->ct;
if (!ct || !(ct->status & IPS_NAT_DONE_MASK)) if (!ct || !(ct->status & IPS_NAT_DONE_MASK))
......
...@@ -109,7 +109,8 @@ void *__nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp) ...@@ -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(); rcu_read_lock();
t = rcu_dereference(nf_ct_ext_types[i]); t = rcu_dereference(nf_ct_ext_types[i]);
if (t && t->move) 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(); rcu_read_unlock();
} }
kfree(ct->ext); kfree(ct->ext);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment