diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 9b4e29557..d2ce1cc1a 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -3390,7 +3390,14 @@ static bool expect_iter_name(struct nf_conntrack_expect *exp, void *data) struct nf_conntrack_helper *helper; const char *name = data; - helper = rcu_dereference(exp->helper); + /* + * This runs from nf_ct_expect_iterate_net() with the + * nf_conntrack_expect_lock held. A helper is only released after all + * expectations referring to it have been unlinked under that same lock, + * so the lock (not an RCU read-side section) keeps exp->helper valid. + */ + helper = rcu_dereference_protected(exp->helper, + lockdep_is_held(&nf_conntrack_expect_lock)); if (!helper) return false;