| From c61346045b7b00ff8c2f29468d8a8b31e50f4a5a Mon Sep 17 00:00:00 2001 |
| From: Florian Westphal <fw@strlen.de> |
| Date: Tue, 23 Oct 2018 16:47:16 +0200 |
| Subject: netfilter: ipv6: fix oops when defragmenting locally generated |
| fragments |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| [ Upstream commit 61792b677415b77c8db04991c22966bb8de7603e ] |
| |
| Unlike ipv4 and normal ipv6 defrag, netfilter ipv6 defragmentation did |
| not save/restore skb->dst. |
| |
| This causes oops when handling locally generated ipv6 fragments, as |
| output path needs a valid dst. |
| |
| Reported-by: Maciej Żenczykowski <zenczykowski@gmail.com> |
| Fixes: 84379c9afe01 ("netfilter: ipv6: nf_defrag: drop skb dst before queueing") |
| Signed-off-by: Florian Westphal <fw@strlen.de> |
| Reviewed-by: Eric Dumazet <edumazet@google.com> |
| Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| net/ipv6/netfilter/nf_conntrack_reasm.c | 13 +++++++++---- |
| 1 file changed, 9 insertions(+), 4 deletions(-) |
| |
| diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c |
| index 8f68a518d9db..f76bd4d15704 100644 |
| --- a/net/ipv6/netfilter/nf_conntrack_reasm.c |
| +++ b/net/ipv6/netfilter/nf_conntrack_reasm.c |
| @@ -587,11 +587,16 @@ int nf_ct_frag6_gather(struct net *net, struct sk_buff *skb, u32 user) |
| */ |
| ret = -EINPROGRESS; |
| if (fq->q.flags == (INET_FRAG_FIRST_IN | INET_FRAG_LAST_IN) && |
| - fq->q.meat == fq->q.len && |
| - nf_ct_frag6_reasm(fq, skb, dev)) |
| - ret = 0; |
| - else |
| + fq->q.meat == fq->q.len) { |
| + unsigned long orefdst = skb->_skb_refdst; |
| + |
| + skb->_skb_refdst = 0UL; |
| + if (nf_ct_frag6_reasm(fq, skb, dev)) |
| + ret = 0; |
| + skb->_skb_refdst = orefdst; |
| + } else { |
| skb_dst_drop(skb); |
| + } |
| |
| out_unlock: |
| spin_unlock_bh(&fq->q.lock); |
| -- |
| 2.17.1 |
| |