Commit 86577c661bc01d5c4e477d74567df4470d6c5138
Committed by
David S. Miller
1 parent
b2155e7f70
[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>
Showing 3 changed files with 6 additions and 5 deletions Side-by-side Diff
include/net/netfilter/nf_conntrack_extend.h
net/ipv4/netfilter/nf_nat_core.c
... | ... | @@ -600,10 +600,10 @@ |
600 | 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); | |
606 | - struct nf_conn_nat *old_nat = (struct nf_conn_nat *)old; | |
605 | + struct nf_conn_nat *new_nat = new; | |
606 | + struct nf_conn_nat *old_nat = old; | |
607 | 607 | struct nf_conn *ct = old_nat->ct; |
608 | 608 | |
609 | 609 | if (!ct || !(ct->status & IPS_NAT_DONE_MASK)) |
net/netfilter/nf_conntrack_extend.c
... | ... | @@ -109,7 +109,8 @@ |
109 | 109 | rcu_read_lock(); |
110 | 110 | t = rcu_dereference(nf_ct_ext_types[i]); |
111 | 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 | 114 | rcu_read_unlock(); |
114 | 115 | } |
115 | 116 | kfree(ct->ext); |