netfilter: use function typedefs for __rcu NAT helper hook pointers

After commit 07919126ec ("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>
This commit is contained in:
Sun Jian
2026-03-03 18:15:25 +08:00
committed by Florian Westphal
parent b3e69fc319
commit 6e6f2b9b33
10 changed files with 51 additions and 60 deletions

View 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)

View 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 &&

View 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 */

View 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);

View 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);