]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
netfilter: use function typedefs for __rcu NAT helper hook pointers
authorSun Jian <sun.jian.kdev@gmail.com>
Tue, 3 Mar 2026 10:15:25 +0000 (18:15 +0800)
committerFlorian Westphal <fw@strlen.de>
Wed, 8 Apr 2026 05:51:26 +0000 (07:51 +0200)
After commit 07919126ecfc ("netfilter: annotate NAT helper hook pointers
with __rcu"), sparse can warn about type/address-space mismatches when
RCU-dereferencing NAT helper hook function pointers.

The hooks are __rcu-annotated and accessed via rcu_dereference(), but the
combination of complex function pointer declarators and the WRITE_ONCE()
machinery used by RCU_INIT_POINTER()/rcu_assign_pointer() can confuse
sparse and trigger false positives.

Introduce typedefs for the NAT helper function types, so __rcu applies to
a simple "fn_t __rcu *" pointer form. Also replace local typeof(hook)
variables with "fn_t *" to avoid propagating __rcu address space into
temporaries.

No functional change intended.

Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202603022359.3dGE9fwI-lkp@intel.com/
Signed-off-by: Sun Jian <sun.jian.kdev@gmail.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
include/linux/netfilter/nf_conntrack_amanda.h
include/linux/netfilter/nf_conntrack_ftp.h
include/linux/netfilter/nf_conntrack_irc.h
include/linux/netfilter/nf_conntrack_snmp.h
include/linux/netfilter/nf_conntrack_tftp.h
net/netfilter/nf_conntrack_amanda.c
net/netfilter/nf_conntrack_ftp.c
net/netfilter/nf_conntrack_irc.c
net/netfilter/nf_conntrack_snmp.c
net/netfilter/nf_conntrack_tftp.c

index dfe89f38d1f7e213fcae1248e012ca9598bcb2e8..1719987e8fd8387789453d16ac5408a5be31f173 100644 (file)
@@ -7,10 +7,13 @@
 #include <linux/skbuff.h>
 #include <net/netfilter/nf_conntrack_expect.h>
 
-extern unsigned int (__rcu *nf_nat_amanda_hook)(struct sk_buff *skb,
-                                         enum ip_conntrack_info ctinfo,
-                                         unsigned int protoff,
-                                         unsigned int matchoff,
-                                         unsigned int matchlen,
-                                         struct nf_conntrack_expect *exp);
+typedef unsigned int
+nf_nat_amanda_hook_fn(struct sk_buff *skb,
+                     enum ip_conntrack_info ctinfo,
+                     unsigned int protoff,
+                     unsigned int matchoff,
+                     unsigned int matchlen,
+                     struct nf_conntrack_expect *exp);
+
+extern nf_nat_amanda_hook_fn __rcu *nf_nat_amanda_hook;
 #endif /* _NF_CONNTRACK_AMANDA_H */
index f312926420359b841bf9c3ef9b45d97f841e4aed..7b62446ccec4f4e07b230f11b7de7ad6a527fb90 100644 (file)
@@ -26,11 +26,14 @@ struct nf_ct_ftp_master {
 
 /* For NAT to hook in when we find a packet which describes what other
  * connection we should expect. */
-extern unsigned int (__rcu *nf_nat_ftp_hook)(struct sk_buff *skb,
-                                      enum ip_conntrack_info ctinfo,
-                                      enum nf_ct_ftp_type type,
-                                      unsigned int protoff,
-                                      unsigned int matchoff,
-                                      unsigned int matchlen,
-                                      struct nf_conntrack_expect *exp);
+typedef unsigned int
+nf_nat_ftp_hook_fn(struct sk_buff *skb,
+                  enum ip_conntrack_info ctinfo,
+                  enum nf_ct_ftp_type type,
+                  unsigned int protoff,
+                  unsigned int matchoff,
+                  unsigned int matchlen,
+                  struct nf_conntrack_expect *exp);
+
+extern nf_nat_ftp_hook_fn __rcu *nf_nat_ftp_hook;
 #endif /* _NF_CONNTRACK_FTP_H */
index 4f3ca562199807c40f1fca44df57c3aa4a26adbd..ce07250afb4e9e798ff9952145cb568970909d01 100644 (file)
@@ -8,11 +8,14 @@
 
 #define IRC_PORT       6667
 
-extern unsigned int (__rcu *nf_nat_irc_hook)(struct sk_buff *skb,
-                                      enum ip_conntrack_info ctinfo,
-                                      unsigned int protoff,
-                                      unsigned int matchoff,
-                                      unsigned int matchlen,
-                                      struct nf_conntrack_expect *exp);
+typedef unsigned int
+nf_nat_irc_hook_fn(struct sk_buff *skb,
+                  enum ip_conntrack_info ctinfo,
+                  unsigned int protoff,
+                  unsigned int matchoff,
+                  unsigned int matchlen,
+                  struct nf_conntrack_expect *exp);
+
+extern nf_nat_irc_hook_fn __rcu *nf_nat_irc_hook;
 
 #endif /* _NF_CONNTRACK_IRC_H */
index 99107e4f5234c516092841700c68980051c7e25e..bb39f04a9977e8b64b8d73f6953b79a654ba2c89 100644 (file)
@@ -5,9 +5,12 @@
 #include <linux/netfilter.h>
 #include <linux/skbuff.h>
 
-extern int (__rcu *nf_nat_snmp_hook)(struct sk_buff *skb,
-                               unsigned int protoff,
-                               struct nf_conn *ct,
-                               enum ip_conntrack_info ctinfo);
+typedef int
+nf_nat_snmp_hook_fn(struct sk_buff *skb,
+                   unsigned int protoff,
+                   struct nf_conn *ct,
+                   enum ip_conntrack_info ctinfo);
+
+extern nf_nat_snmp_hook_fn __rcu *nf_nat_snmp_hook;
 
 #endif /* _NF_CONNTRACK_SNMP_H */
index 1490b68dd7d189e3a7774e0899dd2f3f5189659a..90b334bbce3ce6ab5b0e232c567a97ac78e8e1b3 100644 (file)
@@ -19,8 +19,11 @@ struct tftphdr {
 #define TFTP_OPCODE_ACK                4
 #define TFTP_OPCODE_ERROR      5
 
-extern unsigned int (__rcu *nf_nat_tftp_hook)(struct sk_buff *skb,
-                                       enum ip_conntrack_info ctinfo,
-                                       struct nf_conntrack_expect *exp);
+typedef unsigned int
+nf_nat_tftp_hook_fn(struct sk_buff *skb,
+                   enum ip_conntrack_info ctinfo,
+                   struct nf_conntrack_expect *exp);
+
+extern nf_nat_tftp_hook_fn __rcu *nf_nat_tftp_hook;
 
 #endif /* _NF_CONNTRACK_TFTP_H */
index c0132559f6af5ea5f171df3849b7ff497e8f0df2..d2c09e8dd87266d3df1e32471bc1bb45890d5ea5 100644 (file)
@@ -37,13 +37,7 @@ MODULE_PARM_DESC(master_timeout, "timeout for the master connection");
 module_param(ts_algo, charp, 0400);
 MODULE_PARM_DESC(ts_algo, "textsearch algorithm to use (default kmp)");
 
-unsigned int (__rcu *nf_nat_amanda_hook)(struct sk_buff *skb,
-                                        enum ip_conntrack_info ctinfo,
-                                        unsigned int protoff,
-                                        unsigned int matchoff,
-                                        unsigned int matchlen,
-                                        struct nf_conntrack_expect *exp)
-                                        __read_mostly;
+nf_nat_amanda_hook_fn __rcu *nf_nat_amanda_hook __read_mostly;
 EXPORT_SYMBOL_GPL(nf_nat_amanda_hook);
 
 enum amanda_strings {
@@ -98,7 +92,7 @@ static int amanda_help(struct sk_buff *skb,
        u_int16_t len;
        __be16 port;
        int ret = NF_ACCEPT;
-       typeof(nf_nat_amanda_hook) nf_nat_amanda;
+       nf_nat_amanda_hook_fn *nf_nat_amanda;
 
        /* Only look at packets from the Amanda server */
        if (CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL)
index 5e00f9123c38ea2fe650a3fe1ee40a1045f7bfbe..de83bf9e6c61ac9523632e4f42b8976583492051 100644 (file)
@@ -43,13 +43,7 @@ module_param_array(ports, ushort, &ports_c, 0400);
 static bool loose;
 module_param(loose, bool, 0600);
 
-unsigned int (__rcu *nf_nat_ftp_hook)(struct sk_buff *skb,
-                                     enum ip_conntrack_info ctinfo,
-                                     enum nf_ct_ftp_type type,
-                                     unsigned int protoff,
-                                     unsigned int matchoff,
-                                     unsigned int matchlen,
-                                     struct nf_conntrack_expect *exp);
+nf_nat_ftp_hook_fn __rcu *nf_nat_ftp_hook;
 EXPORT_SYMBOL_GPL(nf_nat_ftp_hook);
 
 static int try_rfc959(const char *, size_t, struct nf_conntrack_man *,
@@ -385,7 +379,7 @@ static int help(struct sk_buff *skb,
        struct nf_conntrack_man cmd = {};
        unsigned int i;
        int found = 0, ends_in_nl;
-       typeof(nf_nat_ftp_hook) nf_nat_ftp;
+       nf_nat_ftp_hook_fn *nf_nat_ftp;
 
        /* Until there's been traffic both ways, don't look in packets. */
        if (ctinfo != IP_CT_ESTABLISHED &&
index b8e6d724acd155655d6c4d0af3d515e890b11612..522183b9a60465884a82f24429ac18e4fcf541b3 100644 (file)
@@ -30,13 +30,7 @@ static unsigned int dcc_timeout __read_mostly = 300;
 static char *irc_buffer;
 static DEFINE_SPINLOCK(irc_buffer_lock);
 
-unsigned int (__rcu *nf_nat_irc_hook)(struct sk_buff *skb,
-                                     enum ip_conntrack_info ctinfo,
-                                     unsigned int protoff,
-                                     unsigned int matchoff,
-                                     unsigned int matchlen,
-                                     struct nf_conntrack_expect *exp)
-                                     __read_mostly;
+nf_nat_irc_hook_fn __rcu *nf_nat_irc_hook __read_mostly;
 EXPORT_SYMBOL_GPL(nf_nat_irc_hook);
 
 #define HELPER_NAME "irc"
@@ -122,7 +116,7 @@ static int help(struct sk_buff *skb, unsigned int protoff,
        __be16 port;
        int i, ret = NF_ACCEPT;
        char *addr_beg_p, *addr_end_p;
-       typeof(nf_nat_irc_hook) nf_nat_irc;
+       nf_nat_irc_hook_fn *nf_nat_irc;
        unsigned int datalen;
 
        /* If packet is coming from IRC server */
index 387dd6e58f8831be547f30032a198fb6d8252a5b..7b7eed43c54f1fb58cdc780d2c808fc30cc5bb8e 100644 (file)
@@ -25,17 +25,14 @@ static unsigned int timeout __read_mostly = 30;
 module_param(timeout, uint, 0400);
 MODULE_PARM_DESC(timeout, "timeout for master connection/replies in seconds");
 
-int (__rcu *nf_nat_snmp_hook)(struct sk_buff *skb,
-                             unsigned int protoff,
-                             struct nf_conn *ct,
-                             enum ip_conntrack_info ctinfo);
+nf_nat_snmp_hook_fn __rcu *nf_nat_snmp_hook;
 EXPORT_SYMBOL_GPL(nf_nat_snmp_hook);
 
 static int snmp_conntrack_help(struct sk_buff *skb, unsigned int protoff,
                               struct nf_conn *ct,
                               enum ip_conntrack_info ctinfo)
 {
-       typeof(nf_nat_snmp_hook) nf_nat_snmp;
+       nf_nat_snmp_hook_fn *nf_nat_snmp;
 
        nf_conntrack_broadcast_help(skb, ct, ctinfo, timeout);
 
index 89e9914e5d037859ca85c58ee060092439236abc..a2e6833a0bf76a2caaa8b3eb21d66c8b404ac48e 100644 (file)
@@ -32,10 +32,7 @@ static unsigned int ports_c;
 module_param_array(ports, ushort, &ports_c, 0400);
 MODULE_PARM_DESC(ports, "Port numbers of TFTP servers");
 
-unsigned int (__rcu *nf_nat_tftp_hook)(struct sk_buff *skb,
-                                      enum ip_conntrack_info ctinfo,
-                                      struct nf_conntrack_expect *exp)
-                                      __read_mostly;
+nf_nat_tftp_hook_fn __rcu *nf_nat_tftp_hook __read_mostly;
 EXPORT_SYMBOL_GPL(nf_nat_tftp_hook);
 
 static int tftp_help(struct sk_buff *skb,
@@ -48,7 +45,7 @@ static int tftp_help(struct sk_buff *skb,
        struct nf_conntrack_expect *exp;
        struct nf_conntrack_tuple *tuple;
        unsigned int ret = NF_ACCEPT;
-       typeof(nf_nat_tftp_hook) nf_nat_tftp;
+       nf_nat_tftp_hook_fn *nf_nat_tftp;
 
        tfh = skb_header_pointer(skb, protoff + sizeof(struct udphdr),
                                 sizeof(_tftph), &_tftph);