Subject: Re: [PATCH net] netfilter: ctnetlink: fix use-after-free of exp->master in single expectation GET

From: Pablo Neira Ayuso <[email-masked]>
Date: Thu, 26 Mar 2026 22:30:47 +0100

On Sun, Mar 08, 2026 at 02:21:10AM +0900, Hyunwoo Kim wrote:
> ctnetlink_get_expect() in the non-dump path calls
> nf_ct_expect_find_get() which only takes a reference on the expectation
> itself, not on exp->master.  It then calls ctnetlink_exp_fill_info()
> which dereferences exp->master extensively (tuplehash, ct->ext via
> nfct_help()).
> 
> A concurrent conntrack deletion through NFNL_SUBSYS_CTNETLINK (a
> different nfnetlink subsystem mutex than NFNL_SUBSYS_CTNETLINK_EXP) can
> free the master conntrack while the single GET is in progress, leading
> to use-after-free.  In particular, kfree(ct->ext) is immediate and not
> RCU-deferred.
> 
> Fix this by taking a reference on exp->master under rcu_read_lock
> (required for SLAB_TYPESAFE_BY_RCU) before calling
> ctnetlink_exp_fill_info() and releasing it afterwards.

For the record, this was fixed by expanding the nf_conntrack_lock
section in ctnetlink_get_expect(). The observation is that
nf_ct_remove_expectations() holds the nf_conntrack_expect_lock while
called from the ct object release path, so the ct->ext area does not
go away until the nf_conntrack_expect_lock is released.

I'm archiving this patch.