diff mbox series

[nf-next] netfilter: conntrack: re-fetch conntrack after insertion

Message ID 20220517194918.20555-1-fw@strlen.de
State Accepted
Delegated to: Pablo Neira
Headers show
Series [nf-next] netfilter: conntrack: re-fetch conntrack after insertion | expand

Commit Message

Florian Westphal May 17, 2022, 7:49 p.m. UTC
In case the conntrack is clashing, insertion can free skb->_nfct and
set skb->_nfct to the already-confirmed entry.

This wasn't found before because the conntrack entry and the extension
space used to free'd after an rcu grace period, plus the race needs
events enabled to trigger.

Reported-by: <syzbot+793a590957d9c1b96620@syzkaller.appspotmail.com>
Fixes: 71d8c47fc653 ("netfilter: conntrack: introduce clash resolution on insertion race")
Fixes: 2ad9d7747c10 ("netfilter: conntrack: free extension area immediately")
Signed-off-by: Florian Westphal <fw@strlen.de>
---
 include/net/netfilter/nf_conntrack_core.h | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

Comments

Pablo Neira Ayuso May 19, 2022, 8:40 p.m. UTC | #1
On Tue, May 17, 2022 at 09:49:18PM +0200, Florian Westphal wrote:
> In case the conntrack is clashing, insertion can free skb->_nfct and
> set skb->_nfct to the already-confirmed entry.
> 
> This wasn't found before because the conntrack entry and the extension
> space used to free'd after an rcu grace period, plus the race needs
> events enabled to trigger.

Applied, thanks
diff mbox series

Patch

diff --git a/include/net/netfilter/nf_conntrack_core.h b/include/net/netfilter/nf_conntrack_core.h
index 6406cfee34c2..37866c8386e2 100644
--- a/include/net/netfilter/nf_conntrack_core.h
+++ b/include/net/netfilter/nf_conntrack_core.h
@@ -58,8 +58,13 @@  static inline int nf_conntrack_confirm(struct sk_buff *skb)
 	int ret = NF_ACCEPT;
 
 	if (ct) {
-		if (!nf_ct_is_confirmed(ct))
+		if (!nf_ct_is_confirmed(ct)) {
 			ret = __nf_conntrack_confirm(skb);
+
+			if (ret == NF_ACCEPT)
+				ct = (struct nf_conn *)skb_nfct(skb);
+		}
+
 		if (ret == NF_ACCEPT && nf_ct_ecache_exist(ct))
 			nf_ct_deliver_cached_events(ct);
 	}