]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
netfilter: nf_conntrack_helper: fix possible null deref during error log
authorFlorian Westphal <fw@strlen.de>
Sat, 9 May 2026 08:27:06 +0000 (10:27 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Sat, 16 May 2026 10:19:56 +0000 (12:19 +0200)
Reported by sashiko: there is a small race window.

If a helper module is unloaded or a userspace-defined helper is
removed, nf_conntrack_helper_unregister() sets ->helper to NULL.

Handle this safely.  This needs a second patch to close related
race during nf_conntrack_helper_unregister().

Fixes: b20ab9cc63ca ("netfilter: nf_ct_helper: better logging for dropped packets")
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
net/netfilter/nf_conntrack_helper.c

index b594cd244fe1d459adc24ca70b618a9d09b67648..17e971bd4c74655bd6c6303d6e8ff5cd3a10ed22 100644 (file)
@@ -321,8 +321,8 @@ __printf(3, 4)
 void nf_ct_helper_log(struct sk_buff *skb, const struct nf_conn *ct,
                      const char *fmt, ...)
 {
+       const char *helper_name = "(null)";
        const struct nf_conn_help *help;
-       const struct nf_conntrack_helper *helper;
        struct va_format vaf;
        va_list args;
 
@@ -331,14 +331,17 @@ void nf_ct_helper_log(struct sk_buff *skb, const struct nf_conn *ct,
        vaf.fmt = fmt;
        vaf.va = &args;
 
-       /* Called from the helper function, this call never fails */
        help = nfct_help(ct);
+       if (help) {
+               const struct nf_conntrack_helper *helper;
 
-       /* rcu_read_lock()ed by nf_hook_thresh */
-       helper = rcu_dereference(help->helper);
+               helper = rcu_dereference(help->helper);
+               if (helper)
+                       helper_name = helper->name;
+       }
 
        nf_log_packet(nf_ct_net(ct), nf_ct_l3num(ct), 0, skb, NULL, NULL, NULL,
-                     "nf_ct_%s: dropping packet: %pV ", helper->name, &vaf);
+                     "helper %s dropping packet: %pV ", helper_name, &vaf);
 
        va_end(args);
 }