When deleting an xt_CT rule, its per-rule template conntrack is freed via nf_ct_destroy() -> nf_ct_tmpl_free(). If an expectation was created with that template as its master, the expectation's timeout/flush later calls nf_ct_unlink_expect_report() and dereferences exp->master, which now points to freed memory, leading to a NULL/poison deref and crash. Move nf_ct_remove_expectations(ct) before the template early-return in nf_ct_destroy() so that any expectations attached to a template are removed (and their timers cancelled) before the template's extensions are torn down. Signed-off-by: Qingjie Xing --- net/netfilter/nf_conntrack_core.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 344f88295976..7f6b95404907 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c @@ -577,6 +577,13 @@ void nf_ct_destroy(struct nf_conntrack *nfct) WARN_ON(refcount_read(&nfct->use) != 0); + /* Expectations will have been removed in clean_from_lists, + * except TFTP can create an expectation on the first packet, + * before connection is in the list, so we need to clean here, + * too. + */ + nf_ct_remove_expectations(ct); + if (unlikely(nf_ct_is_template(ct))) { nf_ct_tmpl_free(ct); return; @@ -585,13 +592,6 @@ void nf_ct_destroy(struct nf_conntrack *nfct) if (unlikely(nf_ct_protonum(ct) == IPPROTO_GRE)) destroy_gre_conntrack(ct); - /* Expectations will have been removed in clean_from_lists, - * except TFTP can create an expectation on the first packet, - * before connection is in the list, so we need to clean here, - * too. - */ - nf_ct_remove_expectations(ct); - if (ct->master) nf_ct_put(ct->master); base-commit: 01792bc3e5bdafa171dd83c7073f00e7de93a653 -- 2.25.1