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/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 */
/* 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 */
#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 */
#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 */
#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 */
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 {
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)
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 *,
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 &&
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"
__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 */
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);
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,
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);