* [PATCH net,v2 0/9] Netfilter/IPVS fixes for net
@ 2026-09-07 17:17 Pablo Neira Ayuso
2026-09-07 17:17 ` [PATCH net 1/9] ipvs: reject invalid states in connection template sync records Pablo Neira Ayuso
` (8 more replies)
0 siblings, 9 replies; 18+ messages in thread
From: Pablo Neira Ayuso @ 2026-09-07 17:17 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev, kuba, pabeni, edumazet, horms, fw, ja
v2: Keep back all the patches that Jakub's LLMs are complaining
about.
-o-
The following patchset contains Netfilter/IPVS fixes for net:
1) Reject malformed messages in IPVS sync, from Kyle Zeng.
2) Fix possible stale infoleak in IPVS sync, also from Kyle Zeng.
3) Out-of-bound read in the SIP conntrack helper, from
Joas Antonio dos Santos.
4) UaF on cttimeout module removal, from Chengfeng Ye.
5) Unregister nf_loggers before netns teardown to fix UaF,
also from Chengfeng Ye.
6) Fix race in nfnetlink_log due to concurrent instance destruction,
from Florian Westphal.
7) Remove arp_table 32bit compat interface, this is already off in
many distributions, from Florian Westphal.
8) Set IP6T_F_PROTO flag is e->ipv6.proto is set on to deal with
insufficient validation of xtables extensions when used from
legacy ip6tables, from Florian.
9) Set on the NLM_F_DUMP_FILTERED flag when all is filtering out
in ctnetlink, from Ilya Maximets.
Please, pull these changes from:
git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf.git nf-26-09-07
Thanks.
----------------------------------------------------------------
The following changes since commit 1d2929d0850fff683b8aff051275945e65f082c8:
net: psp: do not inherit the Rx association on clone (2026-09-01 15:12:24 +0200)
are available in the Git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf.git nf-26-09-07
for you to fetch changes up to 7a099b347fef536a84068076e2d384f044e5cfc5:
netfilter: report NLM_F_DUMP_FILTERED when all is filtered out (2026-09-07 18:48:56 +0200)
----------------------------------------------------------------
netfilter pull request 26-09-07
----------------------------------------------------------------
Chengfeng Ye (2):
netfilter: cttimeout: prevent UAF during module unload
netfilter: nf_log: unregister loggers before per-net teardown
Florian Westphal (3):
netfilter: nfnetlink_log: cope with concurrent instance destruction
netfilter: arp_tables: remove the 32bit compat interface
netfilter: ip6_tables: set F_PROTO when proto value is nonzero
Ilya Maximets (1):
netfilter: report NLM_F_DUMP_FILTERED when all is filtered out
Joas Antonio dos Santos (1):
netfilter: nf_conntrack_sip: fix OOB read in sip_skip_whitespace()
Kyle Zeng (2):
ipvs: reject invalid states in connection template sync records
ipvs: fix reversed sequence option serialization
include/linux/netfilter_arp/arp_tables.h | 19 --
net/ipv4/netfilter/arp_tables.c | 472 +------------------------------
net/ipv6/netfilter/ip6_tables.c | 5 +
net/netfilter/Kconfig | 2 +-
net/netfilter/ipvs/ip_vs_sync.c | 20 +-
net/netfilter/nf_conntrack_netlink.c | 2 +
net/netfilter/nf_conntrack_sip.c | 2 +-
net/netfilter/nf_log_syslog.c | 2 +-
net/netfilter/nfnetlink_cttimeout.c | 2 +-
net/netfilter/nfnetlink_log.c | 15 +-
10 files changed, 34 insertions(+), 507 deletions(-)
^ permalink raw reply [flat|nested] 18+ messages in thread* [PATCH net 1/9] ipvs: reject invalid states in connection template sync records 2026-09-07 17:17 [PATCH net,v2 0/9] Netfilter/IPVS fixes for net Pablo Neira Ayuso @ 2026-09-07 17:17 ` Pablo Neira Ayuso 2026-09-08 21:00 ` patchwork-bot+netdevbpf 2026-09-07 17:17 ` [PATCH net 2/9] ipvs: fix reversed sequence option serialization Pablo Neira Ayuso ` (7 subsequent siblings) 8 siblings, 1 reply; 18+ messages in thread From: Pablo Neira Ayuso @ 2026-09-07 17:17 UTC (permalink / raw) To: netfilter-devel; +Cc: davem, netdev, kuba, pabeni, edumazet, horms, fw, ja From: Kyle Zeng <kylebot@openai.com> IPVS sync receivers validate protocol states before creating or updating a connection. For connection templates, however, they only log states outside the template state range and still store the value in the connection. A template can be returned by ordinary connection lookup. TCP and SCTP then use the invalid state as an index into their transition tables. Reject invalid template states in both sync protocol versions before looking up or modifying a connection. The version 1 path handles both IPv4 and IPv6 records. Fixes: 275411430f89 ("ipvs: add assured state for conn templates") Cc: stable@vger.kernel.org Assisted-by: Codex:gpt-5.6-sol Signed-off-by: Kyle Zeng <kylebot@openai.com> Acked-by: Julian Anastasov <ja@ssi.bg> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> --- net/netfilter/ipvs/ip_vs_sync.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/net/netfilter/ipvs/ip_vs_sync.c b/net/netfilter/ipvs/ip_vs_sync.c index ea5fdd4f4ce7..1deb063cd72c 100644 --- a/net/netfilter/ipvs/ip_vs_sync.c +++ b/net/netfilter/ipvs/ip_vs_sync.c @@ -999,10 +999,10 @@ static void ip_vs_process_message_v0(struct netns_ipvs *ipvs, const char *buffer pp->name, state); continue; } - } else { - if (state >= IP_VS_CTPL_S_LAST) - IP_VS_DBG(7, "BACKUP v0, Invalid tpl state %u\n", - state); + } else if (state >= IP_VS_CTPL_S_LAST) { + IP_VS_DBG(7, "BACKUP v0, Invalid tpl state %u\n", + state); + continue; } ip_vs_conn_fill_param(ipvs, AF_INET, s->protocol, @@ -1159,10 +1159,10 @@ static inline int ip_vs_proc_sync_conn(struct netns_ipvs *ipvs, __u8 *p, __u8 *m retc = 40; goto out; } - } else { - if (state >= IP_VS_CTPL_S_LAST) - IP_VS_DBG(7, "BACKUP, Invalid tpl state %u\n", - state); + } else if (state >= IP_VS_CTPL_S_LAST) { + IP_VS_DBG(7, "BACKUP, Invalid tpl state %u\n", state); + retc = 40; + goto out; } if (ip_vs_conn_fill_param_sync(ipvs, af, s, ¶m, pe_data, pe_data_len, pe_name, pe_name_len)) { -- 2.47.3 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PATCH net 1/9] ipvs: reject invalid states in connection template sync records 2026-09-07 17:17 ` [PATCH net 1/9] ipvs: reject invalid states in connection template sync records Pablo Neira Ayuso @ 2026-09-08 21:00 ` patchwork-bot+netdevbpf 0 siblings, 0 replies; 18+ messages in thread From: patchwork-bot+netdevbpf @ 2026-09-08 21:00 UTC (permalink / raw) To: Pablo Neira Ayuso Cc: netfilter-devel, davem, netdev, kuba, pabeni, edumazet, horms, fw, ja Hello: This series was applied to netdev/net.git (main) by Pablo Neira Ayuso <pablo@netfilter.org>: On Mon, 7 Sep 2026 19:17:24 +0200 you wrote: > From: Kyle Zeng <kylebot@openai.com> > > IPVS sync receivers validate protocol states before creating or updating a > connection. For connection templates, however, they only log states outside > the template state range and still store the value in the connection. > > A template can be returned by ordinary connection lookup. TCP and SCTP then > use the invalid state as an index into their transition tables. > > [...] Here is the summary with links: - [net,1/9] ipvs: reject invalid states in connection template sync records https://git.kernel.org/netdev/net/c/74cb39735b6c - [net,2/9] ipvs: fix reversed sequence option serialization https://git.kernel.org/netdev/net/c/b04578b74f2d - [net,3/9] netfilter: nf_conntrack_sip: fix OOB read in sip_skip_whitespace() https://git.kernel.org/netdev/net/c/e8f8231824b5 - [net,4/9] netfilter: cttimeout: prevent UAF during module unload https://git.kernel.org/netdev/net/c/fec9b1de0d02 - [net,5/9] netfilter: nf_log: unregister loggers before per-net teardown https://git.kernel.org/netdev/net/c/2c018cc4842c - [net,6/9] netfilter: nfnetlink_log: cope with concurrent instance destruction https://git.kernel.org/netdev/net/c/387d744fa7e4 - [net,7/9] netfilter: arp_tables: remove the 32bit compat interface https://git.kernel.org/netdev/net/c/0bd7ed1a3263 - [net,8/9] netfilter: ip6_tables: set F_PROTO when proto value is nonzero https://git.kernel.org/netdev/net/c/da4afc5a956d - [net,9/9] netfilter: report NLM_F_DUMP_FILTERED when all is filtered out https://git.kernel.org/netdev/net/c/7a099b347fef You are awesome, thank you! -- Deet-doot-dot, I am a bot. https://korg.docs.kernel.org/patchwork/pwbot.html ^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH net 2/9] ipvs: fix reversed sequence option serialization 2026-09-07 17:17 [PATCH net,v2 0/9] Netfilter/IPVS fixes for net Pablo Neira Ayuso 2026-09-07 17:17 ` [PATCH net 1/9] ipvs: reject invalid states in connection template sync records Pablo Neira Ayuso @ 2026-09-07 17:17 ` Pablo Neira Ayuso 2026-09-07 17:17 ` [PATCH net 3/9] netfilter: nf_conntrack_sip: fix OOB read in sip_skip_whitespace() Pablo Neira Ayuso ` (6 subsequent siblings) 8 siblings, 0 replies; 18+ messages in thread From: Pablo Neira Ayuso @ 2026-09-07 17:17 UTC (permalink / raw) To: netfilter-devel; +Cc: davem, netdev, kuba, pabeni, edumazet, horms, fw, ja From: Kyle Zeng <kylebot@openai.com> hton_seq() expects the host-order source first and the unaligned network-order destination second. The version 1 sync sender passes these arguments in reverse for both sequence blocks. This leaves 24 bytes of the kmalloc-backed message unwritten. It may disclose stale heap data and replace the live connection sequence state with values read from the buffer. Pass the connection sequence state as the source and the message payload as the destination for both blocks. Fixes: 986a07579533 ("IPVS: Backup, Change sending to Version 1 format") Assisted-by: Codex:gpt-5.6-sol Signed-off-by: Kyle Zeng <kylebot@openai.com> Acked-by: Julian Anastasov <ja@ssi.bg> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> --- net/netfilter/ipvs/ip_vs_sync.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/netfilter/ipvs/ip_vs_sync.c b/net/netfilter/ipvs/ip_vs_sync.c index 1deb063cd72c..5383aeafb0ae 100644 --- a/net/netfilter/ipvs/ip_vs_sync.c +++ b/net/netfilter/ipvs/ip_vs_sync.c @@ -747,9 +747,9 @@ void ip_vs_sync_conn(struct netns_ipvs *ipvs, struct ip_vs_conn *cp, int pkts) if (cp->flags & IP_VS_CONN_F_SEQ_MASK) { *(p++) = IPVS_OPT_SEQ_DATA; *(p++) = sizeof(struct ip_vs_sync_conn_options); - hton_seq((struct ip_vs_seq *)p, &cp->in_seq); + hton_seq(&cp->in_seq, (struct ip_vs_seq *)p); p += sizeof(struct ip_vs_seq); - hton_seq((struct ip_vs_seq *)p, &cp->out_seq); + hton_seq(&cp->out_seq, (struct ip_vs_seq *)p); p += sizeof(struct ip_vs_seq); } /* Handle pe data */ -- 2.47.3 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH net 3/9] netfilter: nf_conntrack_sip: fix OOB read in sip_skip_whitespace() 2026-09-07 17:17 [PATCH net,v2 0/9] Netfilter/IPVS fixes for net Pablo Neira Ayuso 2026-09-07 17:17 ` [PATCH net 1/9] ipvs: reject invalid states in connection template sync records Pablo Neira Ayuso 2026-09-07 17:17 ` [PATCH net 2/9] ipvs: fix reversed sequence option serialization Pablo Neira Ayuso @ 2026-09-07 17:17 ` Pablo Neira Ayuso 2026-09-07 17:17 ` [PATCH net 4/9] netfilter: cttimeout: prevent UAF during module unload Pablo Neira Ayuso ` (5 subsequent siblings) 8 siblings, 0 replies; 18+ messages in thread From: Pablo Neira Ayuso @ 2026-09-07 17:17 UTC (permalink / raw) To: netfilter-devel; +Cc: davem, netdev, kuba, pabeni, edumazet, horms, fw, ja From: Joas Antonio dos Santos <joasantonio108@gmail.com> sip_skip_whitespace() returns dptr unchanged when its own loop exhausts the buffer (dptr == limit), instead of NULL like its sibling sip_follow_continuation() returns on its own "no more data" path. ct_sip_get_header() only checks for NULL after calling it: dptr = sip_skip_whitespace(dptr, limit); if (dptr == NULL) break; if (*dptr != ':' || ++dptr >= limit) break; so a recognized header name followed only by spaces/tabs running to the exact end of the SIP payload, with no colon, makes the very next statement read one byte past the buffer. Make both "no more data" outcomes return NULL, matching the convention sip_follow_continuation() already uses and that both existing callers already check for. Fixes: ea45f12a2766d ("[NETFILTER]: nf_conntrack_sip: parse SIP headers properly") Signed-off-by: Joas Antonio dos Santos <joasantonio108@gmail.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> --- net/netfilter/nf_conntrack_sip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c index 3ccf34fc1c53..64bc440b1181 100644 --- a/net/netfilter/nf_conntrack_sip.c +++ b/net/netfilter/nf_conntrack_sip.c @@ -423,7 +423,7 @@ static const char *sip_skip_whitespace(const char *dptr, const char *limit) dptr = sip_follow_continuation(dptr, limit); break; } - return dptr; + return dptr < limit ? dptr : NULL; } /* Search within a SIP header value, dealing with continuation lines */ -- 2.47.3 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH net 4/9] netfilter: cttimeout: prevent UAF during module unload 2026-09-07 17:17 [PATCH net,v2 0/9] Netfilter/IPVS fixes for net Pablo Neira Ayuso ` (2 preceding siblings ...) 2026-09-07 17:17 ` [PATCH net 3/9] netfilter: nf_conntrack_sip: fix OOB read in sip_skip_whitespace() Pablo Neira Ayuso @ 2026-09-07 17:17 ` Pablo Neira Ayuso 2026-09-08 18:04 ` netdev-bot+sashiko 2026-09-07 17:17 ` [PATCH net 5/9] netfilter: nf_log: unregister loggers before per-net teardown Pablo Neira Ayuso ` (4 subsequent siblings) 8 siblings, 1 reply; 18+ messages in thread From: Pablo Neira Ayuso @ 2026-09-07 17:17 UTC (permalink / raw) To: netfilter-devel; +Cc: davem, netdev, kuba, pabeni, edumazet, horms, fw, ja From: Chengfeng Ye <nicoyip.dev@gmail.com> nf_ct_set_timeout() protects the timeout hook dereference and policy lookup with rcu_read_lock(). cttimeout_exit(), however, unregisters the per-net operations before it clears the hook. This allows the following interleaving: CPU 0 CPU 1 cttimeout_exit() nf_ct_set_timeout() unregister_pernet_subsys() rcu_read_lock() kfree(pernet) h = nf_ct_timeout_hook h->timeout_find_get() nfct_timeout_pernet() The hook still points to ctnl_timeout_find_get() when CPU 1 looks up the already freed per-net timeout list. KASAN reported: BUG: KASAN: slab-use-after-free in ctnl_timeout_find_get Read of size 8 by task poc/90 Call Trace: ctnl_timeout_find_get+0x271/0x2a0 [nfnetlink_cttimeout] nf_ct_set_timeout+0x7b/0x3c0 xt_ct_tg_check+0x724/0xb20 xt_check_target+0x234/0xa90 do_ipt_set_ctl+0x570/0x1270 Allocated by task 89: __kmalloc_noprof+0x16e/0x460 ops_init+0x6d/0x420 register_pernet_operations+0x2f6/0x670 Freed by task 91: kfree+0x131/0x390 ops_undo_list+0x3d4/0x730 unregister_pernet_operations+0x232/0x490 unregister_pernet_subsys+0x1c/0x30 cttimeout_exit+0x52/0x970 [nfnetlink_cttimeout] Clear the hook and wait for existing readers before unregistering the per-net operations. This blocks new policy lookups and ensures readers that observed the hook finish before the per-net storage is freed. Fixes: ebfbe67568a7 ("netfilter: cttimeout: use net_generic infra") Cc: stable@vger.kernel.org Signed-off-by: Chengfeng Ye <nicoyip.dev@gmail.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> --- net/netfilter/nfnetlink_cttimeout.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/netfilter/nfnetlink_cttimeout.c b/net/netfilter/nfnetlink_cttimeout.c index 66c2016f6049..132c02ac7c4e 100644 --- a/net/netfilter/nfnetlink_cttimeout.c +++ b/net/netfilter/nfnetlink_cttimeout.c @@ -652,9 +652,9 @@ static void __exit cttimeout_exit(void) { nfnetlink_subsys_unregister(&cttimeout_subsys); - unregister_pernet_subsys(&cttimeout_ops); RCU_INIT_POINTER(nf_ct_timeout_hook, NULL); synchronize_net(); + unregister_pernet_subsys(&cttimeout_ops); } module_init(cttimeout_init); -- 2.47.3 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PATCH net 4/9] netfilter: cttimeout: prevent UAF during module unload 2026-09-07 17:17 ` [PATCH net 4/9] netfilter: cttimeout: prevent UAF during module unload Pablo Neira Ayuso @ 2026-09-08 18:04 ` netdev-bot+sashiko 2026-09-08 20:24 ` Pablo Neira Ayuso 0 siblings, 1 reply; 18+ messages in thread From: netdev-bot+sashiko @ 2026-09-08 18:04 UTC (permalink / raw) To: pablo; +Cc: netfilter-devel, davem, netdev, kuba, pabeni, edumazet, horms, fw, ja Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: Critical: 0 · High: 1 · Medium: 0 · Low: 0 - [High] cttimeout_exit() only drains RCU readers that reach the per-net timeout storage through nf_ct_timeout_hook. -- netfilter: cttimeout: prevent UAF during module unload This reorders cttimeout_exit() so that nf_ct_timeout_hook is cleared and synchronize_net() is called before unregister_pernet_subsys() frees the per-net timeout storage. That closes the window where nf_ct_set_timeout() could still reach the freed nfct_timeout_pernet blob through the hook. > diff --git a/net/netfilter/nfnetlink_cttimeout.c b/net/netfilter/nfnetlink_cttimeout.c > index 66c2016f6049d..132c02ac7c4ea 100644 > --- a/net/netfilter/nfnetlink_cttimeout.c > +++ b/net/netfilter/nfnetlink_cttimeout.c > @@ -652,9 +652,9 @@ static void __exit cttimeout_exit(void) > { > nfnetlink_subsys_unregister(&cttimeout_subsys); > > - unregister_pernet_subsys(&cttimeout_ops); > RCU_INIT_POINTER(nf_ct_timeout_hook, NULL); > synchronize_net(); > + unregister_pernet_subsys(&cttimeout_ops); > } [Severity: High] Does this leave the same per-net object reachable from the netlink dump path during unload? cttimeout_get_timeout() starts the dump without a module reference: net/netfilter/nfnetlink_cttimeout.c:cttimeout_get_timeout() { if (info->nlh->nlmsg_flags & NLM_F_DUMP) { struct netlink_dump_control c = { .dump = ctnl_timeout_dump, }; return netlink_dump_start(info->sk, skb, info->nlh, &c); } With no .module set, __netlink_dump_start()'s try_module_get(control->module) is try_module_get(NULL), which succeeds without taking anything, and cb->module stays NULL. nf_tables_api.c and nfnetlink_hook.c pass .module = THIS_MODULE in their netlink_dump_control for comparison. ctnl_timeout_dump() reads the per-net blob that unregister_pernet_subsys() frees, and it is not gated by nf_ct_timeout_hook: net/netfilter/nfnetlink_cttimeout.c:ctnl_timeout_dump() { rcu_read_lock(); pernet = nfct_timeout_pernet(net); list_for_each_entry_rcu(cur, &pernet->nfct_timeout_list, head) { Is the following sequence possible? 1. IPCTNL_MSG_TIMEOUT_NEW creates one policy; cttimeout_new_timeout() does __module_get(THIS_MODULE). 2. A NLM_F_DUMP IPCTNL_MSG_TIMEOUT_GET parks the dump: with one entry present ctnl_timeout_dump() returns skb->len > 0, netlink_dump() queues the skb and leaves nlk->cb_running set with cb->dump = ctnl_timeout_dump. 3. IPCTNL_MSG_TIMEOUT_DELETE removes the policy, and ctnl_timeout_del() does module_put(THIS_MODULE), so the module refcount is back to zero while the dump is still parked. 4. rmmod runs cttimeout_exit(). The synchronize_rcu() inside nfnetlink_subsys_unregister() and the new synchronize_net() only wait for RCU read-side sections, and a parked dump is not in one, so unregister_pernet_subsys() frees the nfct_timeout_pernet allocation and the module text goes away. 5. The next recvmsg() on that netlink socket resumes the dump: net/netlink/af_netlink.c:netlink_recvmsg() { if (READ_ONCE(nlk->cb_running) && atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf / 2) { ret = netlink_dump(sk, false); which is an indirect call through cb->dump into freed module text, and then a read of the freed pernet->nfct_timeout_list. Should the dump control also carry .module = THIS_MODULE so the parked dump pins the module across the unload, given the commit is aimed at the same freed nfct_timeout_pernet object during module unload? Note that a dump over an empty policy list does not park: ctnl_timeout_dump() returns 0 there and netlink_dump() finishes the dump immediately, so the create/park/delete order above is what makes it reproducible. -- Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260907171732.1407739-2-pablo%40netfilter.org ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH net 4/9] netfilter: cttimeout: prevent UAF during module unload 2026-09-08 18:04 ` netdev-bot+sashiko @ 2026-09-08 20:24 ` Pablo Neira Ayuso 0 siblings, 0 replies; 18+ messages in thread From: Pablo Neira Ayuso @ 2026-09-08 20:24 UTC (permalink / raw) To: netdev-bot+sashiko Cc: netfilter-devel, davem, netdev, kuba, pabeni, edumazet, horms, fw, ja On Tue, Sep 08, 2026 at 06:04:01PM +0000, netdev-bot+sashiko@kernel.org wrote: > Thank you for your contribution! Sashiko AI review found 1 potential > issue(s) to consider: > > Critical: 0 · High: 1 · Medium: 0 · Low: 0 > > - [High] cttimeout_exit() only drains RCU readers that reach the per-net > timeout storage through nf_ct_timeout_hook. > > -- > > netfilter: cttimeout: prevent UAF during module unload > > This reorders cttimeout_exit() so that nf_ct_timeout_hook is cleared and > synchronize_net() is called before unregister_pernet_subsys() frees the > per-net timeout storage. That closes the window where nf_ct_set_timeout() > could still reach the freed nfct_timeout_pernet blob through the hook. > > > diff --git a/net/netfilter/nfnetlink_cttimeout.c b/net/netfilter/nfnetlink_cttimeout.c > > index 66c2016f6049d..132c02ac7c4ea 100644 > > --- a/net/netfilter/nfnetlink_cttimeout.c > > +++ b/net/netfilter/nfnetlink_cttimeout.c > > @@ -652,9 +652,9 @@ static void __exit cttimeout_exit(void) > > { > > nfnetlink_subsys_unregister(&cttimeout_subsys); > > > > - unregister_pernet_subsys(&cttimeout_ops); > > RCU_INIT_POINTER(nf_ct_timeout_hook, NULL); > > synchronize_net(); > > + unregister_pernet_subsys(&cttimeout_ops); > > } > > [Severity: High] > Does this leave the same per-net object reachable from the netlink dump > path during unload? > > cttimeout_get_timeout() starts the dump without a module reference: > > net/netfilter/nfnetlink_cttimeout.c:cttimeout_get_timeout() { > if (info->nlh->nlmsg_flags & NLM_F_DUMP) { > struct netlink_dump_control c = { > .dump = ctnl_timeout_dump, > }; > return netlink_dump_start(info->sk, skb, info->nlh, &c); > } > > With no .module set, __netlink_dump_start()'s try_module_get(control->module) > is try_module_get(NULL), which succeeds without taking anything, and > cb->module stays NULL. nf_tables_api.c and nfnetlink_hook.c pass > .module = THIS_MODULE in their netlink_dump_control for comparison. This is a pre-existing issue. I can follow up on this. ^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH net 5/9] netfilter: nf_log: unregister loggers before per-net teardown 2026-09-07 17:17 [PATCH net,v2 0/9] Netfilter/IPVS fixes for net Pablo Neira Ayuso ` (3 preceding siblings ...) 2026-09-07 17:17 ` [PATCH net 4/9] netfilter: cttimeout: prevent UAF during module unload Pablo Neira Ayuso @ 2026-09-07 17:17 ` Pablo Neira Ayuso 2026-09-07 17:17 ` [PATCH net 6/9] netfilter: nfnetlink_log: cope with concurrent instance destruction Pablo Neira Ayuso ` (3 subsequent siblings) 8 siblings, 0 replies; 18+ messages in thread From: Pablo Neira Ayuso @ 2026-09-07 17:17 UTC (permalink / raw) To: netfilter-devel; +Cc: davem, netdev, kuba, pabeni, edumazet, horms, fw, ja From: Chengfeng Ye <nicoyip.dev@gmail.com> nf_log_syslog and nfnetlink_log unregister their per-network namespace operations before unregistering their global logger backends. This leaves a window where a sysctl or netlink writer can rebind the still- registered logger after the per-net pre-exit callback cleared the old selection. The race looks like this: CPU 0 CPU 1 ---- ---- unregister_pernet_subsys() nf_log_unset(net, logger) net->nf.nf_loggers[pf] = NULL lock nf_log_mutex find logger in loggers[][] net->nf.nf_loggers[pf] = logger unlock nf_log_mutex nf_log_unregister(logger) lock nf_log_mutex loggers[pf][type] = NULL unlock nf_log_mutex synchronize_rcu() module exit returns module core frees backend memory Later, a sysctl read or packet logging operation can dereference the stale per-net logger pointer. Fix this by unregistering the global logger backends before tearing down per-net state. Once the global registrations are gone, later writers can no longer rebind the logger. unregister_pernet_subsys() already waits for an RCU grace period after the pre-exit callback clears the per-net selection, while nf_log_unregister() continues to cover readers of the global logger table. Apply this ordering fix to both nf_log backends that combine per-net teardown with global logger registration. Fixes: 5b023fc8d8e0 ("netfilter: enable per netns support for nf_loggers") Cc: stable@vger.kernel.org Signed-off-by: Chengfeng Ye <nicoyip.dev@gmail.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> --- net/netfilter/nf_log_syslog.c | 2 +- net/netfilter/nfnetlink_log.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/net/netfilter/nf_log_syslog.c b/net/netfilter/nf_log_syslog.c index f24288088c0d..c3fd398ffcd7 100644 --- a/net/netfilter/nf_log_syslog.c +++ b/net/netfilter/nf_log_syslog.c @@ -1073,12 +1073,12 @@ static int __init nf_log_syslog_init(void) static void __exit nf_log_syslog_exit(void) { - unregister_pernet_subsys(&nf_log_syslog_net_ops); nf_log_unregister(&nf_ip_logger); nf_log_unregister(&nf_arp_logger); nf_log_unregister(&nf_ip6_logger); nf_log_unregister(&nf_netdev_logger); nf_log_unregister(&nf_bridge_logger); + unregister_pernet_subsys(&nf_log_syslog_net_ops); } module_init(nf_log_syslog_init); diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c index 6c7fa2ed34f5..9d7fec570abe 100644 --- a/net/netfilter/nfnetlink_log.c +++ b/net/netfilter/nfnetlink_log.c @@ -1233,8 +1233,8 @@ static void __exit nfnetlink_log_fini(void) { nfnetlink_subsys_unregister(&nfulnl_subsys); netlink_unregister_notifier(&nfulnl_rtnl_notifier); - unregister_pernet_subsys(&nfnl_log_net_ops); nf_log_unregister(&nfulnl_logger); + unregister_pernet_subsys(&nfnl_log_net_ops); } MODULE_DESCRIPTION("netfilter userspace logging"); -- 2.47.3 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH net 6/9] netfilter: nfnetlink_log: cope with concurrent instance destruction 2026-09-07 17:17 [PATCH net,v2 0/9] Netfilter/IPVS fixes for net Pablo Neira Ayuso ` (4 preceding siblings ...) 2026-09-07 17:17 ` [PATCH net 5/9] netfilter: nf_log: unregister loggers before per-net teardown Pablo Neira Ayuso @ 2026-09-07 17:17 ` Pablo Neira Ayuso 2026-09-07 17:17 ` [PATCH net 7/9] netfilter: arp_tables: remove the 32bit compat interface Pablo Neira Ayuso ` (2 subsequent siblings) 8 siblings, 0 replies; 18+ messages in thread From: Pablo Neira Ayuso @ 2026-09-07 17:17 UTC (permalink / raw) To: netfilter-devel; +Cc: davem, netdev, kuba, pabeni, edumazet, horms, fw, ja From: Florian Westphal <fw@strlen.de> Instances are refcounted. However, only memory release happens on the 1 -> 0 transition; the unlink from hashes can occur with any refcount. Uncooperative userspace can force a situation where a queue is pending for destruction from netlink event while a different socket with same portid processes an UNBIND request. With right timing, this will unhash the instance again: Oops: general protection fault, [..] Call Trace: <TASK> nfulnl_recv_config+0x31a/0xd50 nfnetlink_rcv_msg+0x7c2/0xeb0 Fixes: 0597f2680d66 ("[NETFILTER]: Add new "nfnetlink_log" userspace packet logging facility") Reported-by: Eulgyu Kim <eulgyukim@snu.ac.kr> Reported-by: Jaeyoung Chung <jjy600901@snu.ac.kr> Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> --- net/netfilter/nfnetlink_log.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c index 9d7fec570abe..d923f2cb1398 100644 --- a/net/netfilter/nfnetlink_log.c +++ b/net/netfilter/nfnetlink_log.c @@ -228,13 +228,18 @@ static void __nfulnl_flush(struct nfulnl_instance *inst); static void __instance_destroy(struct nfulnl_instance *inst) { + spin_lock(&inst->lock); + if (inst->copy_mode == NFULNL_COPY_DISABLED) { + /* attempt to UNBIND a queue already pending + * destruction via netlink close event. Ignore. + */ + spin_unlock(&inst->lock); + return; + } + /* first pull it out of the global list */ hlist_del_rcu(&inst->hlist); - /* then flush all pending packets from skb */ - - spin_lock(&inst->lock); - /* lockless readers wont be able to use us */ inst->copy_mode = NFULNL_COPY_DISABLED; -- 2.47.3 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH net 7/9] netfilter: arp_tables: remove the 32bit compat interface 2026-09-07 17:17 [PATCH net,v2 0/9] Netfilter/IPVS fixes for net Pablo Neira Ayuso ` (5 preceding siblings ...) 2026-09-07 17:17 ` [PATCH net 6/9] netfilter: nfnetlink_log: cope with concurrent instance destruction Pablo Neira Ayuso @ 2026-09-07 17:17 ` Pablo Neira Ayuso 2026-09-08 18:04 ` netdev-bot+sashiko 2026-09-07 17:17 ` [PATCH net 8/9] netfilter: ip6_tables: set F_PROTO when proto value is nonzero Pablo Neira Ayuso 2026-09-07 17:17 ` [PATCH net 9/9] netfilter: report NLM_F_DUMP_FILTERED when all is filtered out Pablo Neira Ayuso 8 siblings, 1 reply; 18+ messages in thread From: Pablo Neira Ayuso @ 2026-09-07 17:17 UTC (permalink / raw) To: netfilter-devel; +Cc: davem, netdev, kuba, pabeni, edumazet, horms, fw, ja From: Florian Westphal <fw@strlen.de> This feature is required to use 32bit arptables binary on 64bit kernels. It's already off in many distributions including Debian and Fedora for many years. Zap arptables first, it's the most esoteric of the 4 flavors. Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> --- include/linux/netfilter_arp/arp_tables.h | 19 - net/ipv4/netfilter/arp_tables.c | 472 +---------------------- net/netfilter/Kconfig | 2 +- 3 files changed, 4 insertions(+), 489 deletions(-) diff --git a/include/linux/netfilter_arp/arp_tables.h b/include/linux/netfilter_arp/arp_tables.h index 05631a25e622..8b8d472eff34 100644 --- a/include/linux/netfilter_arp/arp_tables.h +++ b/include/linux/netfilter_arp/arp_tables.h @@ -56,23 +56,4 @@ void arpt_unregister_table(struct net *net, const char *name); extern unsigned int arpt_do_table(void *priv, struct sk_buff *skb, const struct nf_hook_state *state); -#ifdef CONFIG_NETFILTER_XTABLES_COMPAT -#include <net/compat.h> - -struct compat_arpt_entry { - struct arpt_arp arp; - __u16 target_offset; - __u16 next_offset; - compat_uint_t comefrom; - struct compat_xt_counters counters; - unsigned char elems[]; -}; - -static inline struct xt_entry_target * -compat_arpt_get_target(struct compat_arpt_entry *e) -{ - return (void *)e + e->target_offset; -} - -#endif /* CONFIG_COMPAT */ #endif /* _ARPTABLES_H */ diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index a87e07e80d0d..db307fa49f3f 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c @@ -23,7 +23,6 @@ #include <linux/init.h> #include <linux/mutex.h> #include <linux/err.h> -#include <net/compat.h> #include <net/sock.h> #include <linux/uaccess.h> @@ -724,80 +723,6 @@ static int copy_entries_to_user(unsigned int total_size, return ret; } -#ifdef CONFIG_NETFILTER_XTABLES_COMPAT -static void compat_standard_from_user(void *dst, const void *src) -{ - int v = *(compat_int_t *)src; - - if (v > 0) - v += xt_compat_calc_jump(NFPROTO_ARP, v); - memcpy(dst, &v, sizeof(v)); -} - -static int compat_standard_to_user(void __user *dst, const void *src) -{ - compat_int_t cv = *(int *)src; - - if (cv > 0) - cv -= xt_compat_calc_jump(NFPROTO_ARP, cv); - return copy_to_user(dst, &cv, sizeof(cv)) ? -EFAULT : 0; -} - -static int compat_calc_entry(const struct arpt_entry *e, - const struct xt_table_info *info, - const void *base, struct xt_table_info *newinfo) -{ - const struct xt_entry_target *t; - unsigned int entry_offset; - int off, i, ret; - - off = sizeof(struct arpt_entry) - sizeof(struct compat_arpt_entry); - entry_offset = (void *)e - base; - - t = arpt_get_target_c(e); - off += xt_compat_target_offset(t->u.kernel.target); - newinfo->size -= off; - ret = xt_compat_add_offset(NFPROTO_ARP, entry_offset, off); - if (ret) - return ret; - - for (i = 0; i < NF_ARP_NUMHOOKS; i++) { - if (info->hook_entry[i] && - (e < (struct arpt_entry *)(base + info->hook_entry[i]))) - newinfo->hook_entry[i] -= off; - if (info->underflow[i] && - (e < (struct arpt_entry *)(base + info->underflow[i]))) - newinfo->underflow[i] -= off; - } - return 0; -} - -static int compat_table_info(const struct xt_table_info *info, - struct xt_table_info *newinfo) -{ - struct arpt_entry *iter; - const void *loc_cpu_entry; - int ret; - - if (!newinfo || !info) - return -EINVAL; - - /* we dont care about newinfo->entries */ - memcpy(newinfo, info, offsetof(struct xt_table_info, entries)); - newinfo->initial_entries = 0; - loc_cpu_entry = info->entries; - ret = xt_compat_init_offsets(NFPROTO_ARP, info->number); - if (ret) - return ret; - xt_entry_foreach(iter, loc_cpu_entry, info->size) { - ret = compat_calc_entry(iter, info, loc_cpu_entry, newinfo); - if (ret != 0) - return ret; - } - return 0; -} -#endif - static int get_info(struct net *net, void __user *user, const int *len) { char name[XT_TABLE_MAXNAMELEN]; @@ -811,23 +736,11 @@ static int get_info(struct net *net, void __user *user, const int *len) return -EFAULT; name[XT_TABLE_MAXNAMELEN-1] = '\0'; -#ifdef CONFIG_NETFILTER_XTABLES_COMPAT - if (in_compat_syscall()) - xt_compat_lock(NFPROTO_ARP); -#endif t = xt_request_find_table_lock(net, NFPROTO_ARP, name); if (!IS_ERR(t)) { struct arpt_getinfo info; const struct xt_table_info *private = t->private; -#ifdef CONFIG_NETFILTER_XTABLES_COMPAT - struct xt_table_info tmp; - if (in_compat_syscall()) { - ret = compat_table_info(private, &tmp); - xt_compat_flush_offsets(NFPROTO_ARP); - private = &tmp; - } -#endif memset(&info, 0, sizeof(info)); info.valid_hooks = t->valid_hooks; memcpy(info.hook_entry, private->hook_entry, @@ -846,10 +759,7 @@ static int get_info(struct net *net, void __user *user, const int *len) module_put(t->me); } else ret = PTR_ERR(t); -#ifdef CONFIG_NETFILTER_XTABLES_COMPAT - if (in_compat_syscall()) - xt_compat_unlock(NFPROTO_ARP); -#endif + return ret; } @@ -1059,367 +969,6 @@ static int do_add_counters(struct net *net, sockptr_t arg, unsigned int len) return ret; } -#ifdef CONFIG_NETFILTER_XTABLES_COMPAT -struct compat_arpt_replace { - char name[XT_TABLE_MAXNAMELEN]; - u32 valid_hooks; - u32 num_entries; - u32 size; - u32 hook_entry[NF_ARP_NUMHOOKS]; - u32 underflow[NF_ARP_NUMHOOKS]; - u32 num_counters; - compat_uptr_t counters; - struct compat_arpt_entry entries[]; -}; - -static inline void compat_release_entry(struct compat_arpt_entry *e) -{ - struct xt_entry_target *t; - - t = compat_arpt_get_target(e); - module_put(t->u.kernel.target->me); -} - -static int -check_compat_entry_size_and_hooks(struct compat_arpt_entry *e, - struct xt_table_info *newinfo, - unsigned int *size, - const unsigned char *base, - const unsigned char *limit) -{ - struct xt_entry_target *t; - struct xt_target *target; - unsigned int entry_offset; - int ret, off; - - if ((unsigned long)e % __alignof__(struct compat_arpt_entry) != 0 || - (unsigned char *)e + sizeof(struct compat_arpt_entry) >= limit || - (unsigned char *)e + e->next_offset > limit) - return -EINVAL; - - if (e->next_offset < sizeof(struct compat_arpt_entry) + - sizeof(struct compat_xt_entry_target)) - return -EINVAL; - - if (!arp_checkentry(&e->arp)) - return -EINVAL; - - ret = xt_compat_check_entry_offsets(e, e->elems, e->target_offset, - e->next_offset); - if (ret) - return ret; - - off = sizeof(struct arpt_entry) - sizeof(struct compat_arpt_entry); - entry_offset = (void *)e - (void *)base; - - t = compat_arpt_get_target(e); - target = xt_request_find_target(NFPROTO_ARP, t->u.user.name, - t->u.user.revision); - if (IS_ERR(target)) { - ret = PTR_ERR(target); - goto out; - } - t->u.kernel.target = target; - - off += xt_compat_target_offset(target); - *size += off; - ret = xt_compat_add_offset(NFPROTO_ARP, entry_offset, off); - if (ret) - goto release_target; - - return 0; - -release_target: - module_put(t->u.kernel.target->me); -out: - return ret; -} - -static void -compat_copy_entry_from_user(struct compat_arpt_entry *e, void **dstptr, - unsigned int *size, - struct xt_table_info *newinfo, unsigned char *base) -{ - struct xt_entry_target *t; - struct arpt_entry *de; - unsigned int origsize; - int h; - - origsize = *size; - de = *dstptr; - memcpy(de, e, sizeof(struct arpt_entry)); - memcpy(&de->counters, &e->counters, sizeof(e->counters)); - - *dstptr += sizeof(struct arpt_entry); - *size += sizeof(struct arpt_entry) - sizeof(struct compat_arpt_entry); - - de->target_offset = e->target_offset - (origsize - *size); - t = compat_arpt_get_target(e); - xt_compat_target_from_user(t, dstptr, size); - - de->next_offset = e->next_offset - (origsize - *size); - for (h = 0; h < NF_ARP_NUMHOOKS; h++) { - if ((unsigned char *)de - base < newinfo->hook_entry[h]) - newinfo->hook_entry[h] -= origsize - *size; - if ((unsigned char *)de - base < newinfo->underflow[h]) - newinfo->underflow[h] -= origsize - *size; - } -} - -static int translate_compat_table(struct net *net, - struct xt_table_info **pinfo, - void **pentry0, - const struct compat_arpt_replace *compatr) -{ - unsigned int i, j; - struct xt_table_info *newinfo, *info; - void *pos, *entry0, *entry1; - struct compat_arpt_entry *iter0; - struct arpt_replace repl; - unsigned int size; - int ret; - - info = *pinfo; - entry0 = *pentry0; - size = compatr->size; - info->number = compatr->num_entries; - - j = 0; - xt_compat_lock(NFPROTO_ARP); - ret = xt_compat_init_offsets(NFPROTO_ARP, compatr->num_entries); - if (ret) - goto out_unlock; - /* Walk through entries, checking offsets. */ - xt_entry_foreach(iter0, entry0, compatr->size) { - ret = check_compat_entry_size_and_hooks(iter0, info, &size, - entry0, - entry0 + compatr->size); - if (ret != 0) - goto out_unlock; - ++j; - } - - ret = -EINVAL; - if (j != compatr->num_entries) - goto out_unlock; - - ret = -ENOMEM; - newinfo = xt_alloc_table_info(size); - if (!newinfo) - goto out_unlock; - - memset(newinfo->entries, 0, size); - - newinfo->number = compatr->num_entries; - for (i = 0; i < NF_ARP_NUMHOOKS; i++) { - newinfo->hook_entry[i] = compatr->hook_entry[i]; - newinfo->underflow[i] = compatr->underflow[i]; - } - entry1 = newinfo->entries; - pos = entry1; - size = compatr->size; - xt_entry_foreach(iter0, entry0, compatr->size) - compat_copy_entry_from_user(iter0, &pos, &size, - newinfo, entry1); - - /* all module references in entry0 are now gone */ - - xt_compat_flush_offsets(NFPROTO_ARP); - xt_compat_unlock(NFPROTO_ARP); - - memcpy(&repl, compatr, sizeof(*compatr)); - - for (i = 0; i < NF_ARP_NUMHOOKS; i++) { - repl.hook_entry[i] = newinfo->hook_entry[i]; - repl.underflow[i] = newinfo->underflow[i]; - } - - repl.num_counters = 0; - repl.counters = NULL; - repl.size = newinfo->size; - ret = translate_table(net, newinfo, entry1, &repl); - if (ret) - goto free_newinfo; - - *pinfo = newinfo; - *pentry0 = entry1; - xt_free_table_info(info); - return 0; - -free_newinfo: - xt_free_table_info(newinfo); - return ret; -out_unlock: - xt_compat_flush_offsets(NFPROTO_ARP); - xt_compat_unlock(NFPROTO_ARP); - xt_entry_foreach(iter0, entry0, compatr->size) { - if (j-- == 0) - break; - compat_release_entry(iter0); - } - return ret; -} - -static int compat_do_replace(struct net *net, sockptr_t arg, unsigned int len) -{ - int ret; - struct compat_arpt_replace tmp; - struct xt_table_info *newinfo; - void *loc_cpu_entry; - struct arpt_entry *iter; - - if (len < sizeof(tmp)) - return -EINVAL; - if (copy_from_sockptr(&tmp, arg, sizeof(tmp)) != 0) - return -EFAULT; - - /* overflow check */ - if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters)) - return -ENOMEM; - if (tmp.num_counters == 0) - return -EINVAL; - if ((u64)len < (u64)tmp.size + sizeof(tmp)) - return -EINVAL; - - tmp.name[sizeof(tmp.name)-1] = 0; - - newinfo = xt_alloc_table_info(tmp.size); - if (!newinfo) - return -ENOMEM; - - loc_cpu_entry = newinfo->entries; - if (copy_from_sockptr_offset(loc_cpu_entry, arg, sizeof(tmp), - tmp.size) != 0) { - ret = -EFAULT; - goto free_newinfo; - } - - ret = translate_compat_table(net, &newinfo, &loc_cpu_entry, &tmp); - if (ret != 0) - goto free_newinfo; - - ret = __do_replace(net, tmp.name, tmp.valid_hooks, newinfo, - tmp.num_counters, compat_ptr(tmp.counters)); - if (ret) - goto free_newinfo_untrans; - return 0; - - free_newinfo_untrans: - xt_entry_foreach(iter, loc_cpu_entry, newinfo->size) - cleanup_entry(iter, net); - free_newinfo: - xt_free_table_info(newinfo); - return ret; -} - -static int compat_copy_entry_to_user(struct arpt_entry *e, void __user **dstptr, - compat_uint_t *size, - struct xt_counters *counters, - unsigned int i) -{ - struct xt_entry_target *t; - struct compat_arpt_entry __user *ce; - u_int16_t target_offset, next_offset; - compat_uint_t origsize; - int ret; - - origsize = *size; - ce = *dstptr; - if (copy_to_user(ce, e, offsetof(struct compat_arpt_entry, counters)) || - copy_to_user(&ce->counters, &counters[i], sizeof(counters[i]))) - return -EFAULT; - - *dstptr += sizeof(struct compat_arpt_entry); - *size -= sizeof(struct arpt_entry) - sizeof(struct compat_arpt_entry); - - target_offset = e->target_offset - (origsize - *size); - - t = arpt_get_target(e); - ret = xt_compat_target_to_user(t, dstptr, size); - if (ret) - return ret; - next_offset = e->next_offset - (origsize - *size); - if (put_user(target_offset, &ce->target_offset) != 0 || - put_user(next_offset, &ce->next_offset) != 0) - return -EFAULT; - return 0; -} - -static int compat_copy_entries_to_user(unsigned int total_size, - struct xt_table *table, - void __user *userptr) -{ - struct xt_counters *counters; - const struct xt_table_info *private = table->private; - void __user *pos; - unsigned int size; - int ret = 0; - unsigned int i = 0; - struct arpt_entry *iter; - - counters = alloc_counters(table); - if (IS_ERR(counters)) - return PTR_ERR(counters); - - pos = userptr; - size = total_size; - xt_entry_foreach(iter, private->entries, total_size) { - ret = compat_copy_entry_to_user(iter, &pos, - &size, counters, i++); - if (ret != 0) - break; - } - vfree(counters); - return ret; -} - -struct compat_arpt_get_entries { - char name[XT_TABLE_MAXNAMELEN]; - compat_uint_t size; - struct compat_arpt_entry entrytable[]; -}; - -static int compat_get_entries(struct net *net, - struct compat_arpt_get_entries __user *uptr, - int *len) -{ - int ret; - struct compat_arpt_get_entries get; - struct xt_table *t; - - if (*len < sizeof(get)) - return -EINVAL; - if (copy_from_user(&get, uptr, sizeof(get)) != 0) - return -EFAULT; - if (*len != sizeof(struct compat_arpt_get_entries) + get.size) - return -EINVAL; - - get.name[sizeof(get.name) - 1] = '\0'; - - xt_compat_lock(NFPROTO_ARP); - t = xt_find_table_lock(net, NFPROTO_ARP, get.name); - if (!IS_ERR(t)) { - const struct xt_table_info *private = t->private; - struct xt_table_info info; - - ret = compat_table_info(private, &info); - if (!ret && get.size == info.size) { - ret = compat_copy_entries_to_user(private->size, - t, uptr->entrytable); - } else if (!ret) - ret = -EAGAIN; - - xt_compat_flush_offsets(NFPROTO_ARP); - module_put(t->me); - xt_table_unlock(t); - } else - ret = PTR_ERR(t); - - xt_compat_unlock(NFPROTO_ARP); - return ret; -} -#endif - static int do_arpt_set_ctl(struct sock *sk, int cmd, sockptr_t arg, unsigned int len) { @@ -1432,12 +981,7 @@ static int do_arpt_set_ctl(struct sock *sk, int cmd, sockptr_t arg, switch (cmd) { case ARPT_SO_SET_REPLACE: -#ifdef CONFIG_NETFILTER_XTABLES_COMPAT - if (in_compat_syscall()) - ret = compat_do_replace(sock_net(sk), arg, len); - else -#endif - ret = do_replace(sock_net(sk), arg, len); + ret = do_replace(sock_net(sk), arg, len); break; case ARPT_SO_SET_ADD_COUNTERS: @@ -1466,12 +1010,7 @@ static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len break; case ARPT_SO_GET_ENTRIES: -#ifdef CONFIG_NETFILTER_XTABLES_COMPAT - if (in_compat_syscall()) - ret = compat_get_entries(sock_net(sk), user, len); - else -#endif - ret = get_entries(sock_net(sk), user, len); + ret = get_entries(sock_net(sk), user, len); break; case ARPT_SO_GET_REVISION_TARGET: { @@ -1568,11 +1107,6 @@ static struct xt_target arpt_builtin_tg[] __read_mostly = { .name = XT_STANDARD_TARGET, .targetsize = sizeof(int), .family = NFPROTO_ARP, -#ifdef CONFIG_NETFILTER_XTABLES_COMPAT - .compatsize = sizeof(compat_int_t), - .compat_from_user = compat_standard_from_user, - .compat_to_user = compat_standard_to_user, -#endif }, { .name = XT_ERROR_TARGET, diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig index 4c04cd8d40a2..09874c26fd13 100644 --- a/net/netfilter/Kconfig +++ b/net/netfilter/Kconfig @@ -739,7 +739,7 @@ config NETFILTER_XTABLES_COMPAT bool "Netfilter Xtables 32bit support" depends on COMPAT help - This option provides a translation layer to run 32bit arp,ip(6),ebtables + This option provides a translation layer to run 32bit ip(6),ebtables binaries on 64bit kernels. If unsure, say N. -- 2.47.3 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PATCH net 7/9] netfilter: arp_tables: remove the 32bit compat interface 2026-09-07 17:17 ` [PATCH net 7/9] netfilter: arp_tables: remove the 32bit compat interface Pablo Neira Ayuso @ 2026-09-08 18:04 ` netdev-bot+sashiko 2026-09-08 20:32 ` Pablo Neira Ayuso 0 siblings, 1 reply; 18+ messages in thread From: netdev-bot+sashiko @ 2026-09-08 18:04 UTC (permalink / raw) To: pablo; +Cc: netfilter-devel, davem, netdev, kuba, pabeni, edumazet, horms, fw, ja Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: Critical: 0 · High: 0 · Medium: 0 · Low: 1 - [Low] The arptables 32-bit compat interface is only partially removed. -- netfilter: arp_tables: remove the 32bit compat interface This removes all arptables-specific 32-bit compat translation code from net/ipv4/netfilter/arp_tables.c, drops struct compat_arpt_entry and its accessor from include/linux/netfilter_arp/arp_tables.h, and updates the NETFILTER_XTABLES_COMPAT help text to no longer mention arp. > diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c > index a87e07e80d0de..db307fa49f3f6 100644 > --- a/net/ipv4/netfilter/arp_tables.c > +++ b/net/ipv4/netfilter/arp_tables.c [ ... ] > @@ -811,23 +736,11 @@ static int get_info(struct net *net, void __user *user, const int *len) > return -EFAULT; > > name[XT_TABLE_MAXNAMELEN-1] = '\0'; > -#ifdef CONFIG_NETFILTER_XTABLES_COMPAT > - if (in_compat_syscall()) > - xt_compat_lock(NFPROTO_ARP); > -#endif > t = xt_request_find_table_lock(net, NFPROTO_ARP, name); > if (!IS_ERR(t)) { > struct arpt_getinfo info; > const struct xt_table_info *private = t->private; > -#ifdef CONFIG_NETFILTER_XTABLES_COMPAT > - struct xt_table_info tmp; > > - if (in_compat_syscall()) { > - ret = compat_table_info(private, &tmp); > - xt_compat_flush_offsets(NFPROTO_ARP); > - private = &tmp; > - } > -#endif > memset(&info, 0, sizeof(info)); > info.valid_hooks = t->valid_hooks; > memcpy(info.hook_entry, private->hook_entry, [ ... ] > @@ -1432,12 +981,7 @@ static int do_arpt_set_ctl(struct sock *sk, int cmd, sockptr_t arg, > > switch (cmd) { > case ARPT_SO_SET_REPLACE: > -#ifdef CONFIG_NETFILTER_XTABLES_COMPAT > - if (in_compat_syscall()) > - ret = compat_do_replace(sock_net(sk), arg, len); > - else > -#endif > - ret = do_replace(sock_net(sk), arg, len); > + ret = do_replace(sock_net(sk), arg, len); > break; > > case ARPT_SO_SET_ADD_COUNTERS: [Severity: Low] Should the two arptables ctl handlers also stop accepting compat callers? Both do_arpt_set_ctl() and do_arpt_get_ctl() still start with: if (!xt_compat_check()) return -EPERM; and that helper intentionally lets 32-bit callers continue when CONFIG_NETFILTER_XTABLES_COMPAT is set: include/linux/netfilter/x_tables.h:xt_compat_check() { if (!in_compat_syscall()) return true; pr_warn_once("%s %s\n", "xtables 32bit compat interface no longer supported", "in namespaces and will be removed soon."); if (!capable(CAP_NET_ADMIN)) return false; #endif return true; } So a 32-bit task with CAP_NET_ADMIN now falls straight into the native handlers, which gives three different behaviours: ARPT_SO_GET_INFO succeeds and copies out the native xt_table_info values, since the compat_table_info() rescaling above is gone: memcpy(info.hook_entry, private->hook_entry, sizeof(info.hook_entry)); memcpy(info.underflow, private->underflow, sizeof(info.underflow)); info.num_entries = private->number; info.size = private->size; Are those offsets and size still meaningful to a caller that will walk them using the 32-bit struct arpt_entry layout? ARPT_SO_SET_REPLACE and ARPT_SO_GET_ENTRIES end up failing with -EINVAL purely as a side effect of header size arithmetic in do_replace() and get_entries() (76 vs 80 bytes for the replace header, 36 + size vs 40 + size for the get_entries header) rather than a defined unsupported error. Would an explicit rejection be clearer here, for example: if (in_compat_syscall()) return -EOPNOTSUPP; ARPT_SO_SET_ADD_COUNTERS keeps a working 32-bit ABI, because do_add_counters() -> xt_copy_counters() still carries its own compat branch that converts compat_xt_counters_info for every family, NFPROTO_ARP included: net/netfilter/x_tables.c:xt_copy_counters() { #ifdef CONFIG_NETFILTER_XTABLES_COMPAT if (in_compat_syscall()) { /* structures only differ in size due to alignment */ struct compat_xt_counters_info compat_tmp; ... } Does "remove the 32bit compat interface" then hold for that sockopt? If leaving the shared counter path compat-capable until the other three flavors are converted is intended, could the commit message say so? One more asymmetry: the ip_tables, ip6_tables and ebtables ctl handlers still branch on in_compat_syscall() after the same xt_compat_check() call, so the shared helper now means "translate" for those flavors and "warn, then run the native path" for arptables. Along the same lines, a 32-bit task without CAP_NET_ADMIN now gets -EPERM plus a warning about a compat interface that no longer exists for this flavor. > @@ -1466,12 +1010,7 @@ static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len > break; > > case ARPT_SO_GET_ENTRIES: > -#ifdef CONFIG_NETFILTER_XTABLES_COMPAT > - if (in_compat_syscall()) > - ret = compat_get_entries(sock_net(sk), user, len); > - else > -#endif > - ret = get_entries(sock_net(sk), user, len); > + ret = get_entries(sock_net(sk), user, len); > break; > > case ARPT_SO_GET_REVISION_TARGET: { [ ... ] -- Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260907171732.1407739-2-pablo%40netfilter.org ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH net 7/9] netfilter: arp_tables: remove the 32bit compat interface 2026-09-08 18:04 ` netdev-bot+sashiko @ 2026-09-08 20:32 ` Pablo Neira Ayuso 0 siblings, 0 replies; 18+ messages in thread From: Pablo Neira Ayuso @ 2026-09-08 20:32 UTC (permalink / raw) To: netdev-bot+sashiko Cc: netfilter-devel, davem, netdev, kuba, pabeni, edumazet, horms, fw, ja On Tue, Sep 08, 2026 at 06:04:02PM +0000, netdev-bot+sashiko@kernel.org wrote: > Thank you for your contribution! Sashiko AI review found 1 potential > issue(s) to consider: > > Critical: 0 · High: 0 · Medium: 0 · Low: 1 This rising a lot of issues, because arptables 32bit gets broken. We can follow up to break it more "nicely", but it is not a big issue. ^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH net 8/9] netfilter: ip6_tables: set F_PROTO when proto value is nonzero 2026-09-07 17:17 [PATCH net,v2 0/9] Netfilter/IPVS fixes for net Pablo Neira Ayuso ` (6 preceding siblings ...) 2026-09-07 17:17 ` [PATCH net 7/9] netfilter: arp_tables: remove the 32bit compat interface Pablo Neira Ayuso @ 2026-09-07 17:17 ` Pablo Neira Ayuso 2026-09-08 18:04 ` netdev-bot+sashiko 2026-09-07 17:17 ` [PATCH net 9/9] netfilter: report NLM_F_DUMP_FILTERED when all is filtered out Pablo Neira Ayuso 8 siblings, 1 reply; 18+ messages in thread From: Pablo Neira Ayuso @ 2026-09-07 17:17 UTC (permalink / raw) To: netfilter-devel; +Cc: davem, netdev, kuba, pabeni, edumazet, horms, fw, ja From: Florian Westphal <fw@strlen.de> The ip6tables traverser doesn't search the extension header chain unless userspace did set the IP6T_F_PROTO flag. This also means that userspace that sets the e->ipv6.proto flag can bypass the protocol check for the rule by not setting this flag. That in turn means that all ip6_tables modules and targets that want to reject rules without '-p' flag MUST also check for that flag. Not all do, likely because they got copied from iptables which lacks this flag (no extension headers). Instead of fixing up all the relevant targets, emulate ip6tables behaviour in the kernel (like nft_compat.c) and set the flag if the protocol is set. Reported-by: Zhiling Zou <zhilinz@nebusec.ai> Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> --- net/ipv6/netfilter/ip6_tables.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index f42fb96ef64b..313c4aac377a 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c @@ -647,6 +647,11 @@ check_entry_size_and_hooks(struct ip6t_entry *e, /* Clear counters and comefrom */ e->counters = ((struct xt_counters) { 0, 0 }); e->comefrom = 0; + + /* set F_PROTO, else ip6_packet_match won't do the right thing. */ + if (e->ipv6.proto) + e->ipv6.flags |= IP6T_F_PROTO; + return 0; } -- 2.47.3 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PATCH net 8/9] netfilter: ip6_tables: set F_PROTO when proto value is nonzero 2026-09-07 17:17 ` [PATCH net 8/9] netfilter: ip6_tables: set F_PROTO when proto value is nonzero Pablo Neira Ayuso @ 2026-09-08 18:04 ` netdev-bot+sashiko 2026-09-08 20:22 ` Pablo Neira Ayuso 2026-09-08 20:35 ` Pablo Neira Ayuso 0 siblings, 2 replies; 18+ messages in thread From: netdev-bot+sashiko @ 2026-09-08 18:04 UTC (permalink / raw) To: pablo; +Cc: netfilter-devel, davem, netdev, kuba, pabeni, edumazet, horms, fw, ja Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: Critical: 0 · High: 0 · Medium: 0 · Low: 1 - [Low] Stale/contradicted UAPI documentation for `struct ip6t_ip6::proto`. -- netfilter: ip6_tables: set F_PROTO when proto value is nonzero This makes the kernel set IP6T_F_PROTO for any rule that carries a nonzero ipv6.proto, so ip6_packet_match() always performs the protocol comparison and extension header walk instead of skipping it when userspace left the flag clear. It mirrors the normalisation already done in nft_compat.c. > diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c > index f42fb96ef64b6..313c4aac377aa 100644 > --- a/net/ipv6/netfilter/ip6_tables.c > +++ b/net/ipv6/netfilter/ip6_tables.c > @@ -647,6 +647,11 @@ check_entry_size_and_hooks(struct ip6t_entry *e, > /* Clear counters and comefrom */ > e->counters = ((struct xt_counters) { 0, 0 }); > e->comefrom = 0; > + > + /* set F_PROTO, else ip6_packet_match won't do the right thing. */ > + if (e->ipv6.proto) > + e->ipv6.flags |= IP6T_F_PROTO; > + > return 0; > } [Severity: Low] Should the uapi header comment be updated in the same patch? The description of struct ip6t_ip6::proto in include/uapi/linux/netfilter_ipv6/ip6_tables.h still documents the opposite contract: /* Upper protocol number * ... * - You also need to set IP6T_FLAGS_PROTO to "flags" to check protocol. */ __u16 proto; After this change, a non-standard userspace that follows that comment and sets proto = IPPROTO_TCP while leaving flags = 0 (expecting a protocol-agnostic rule) gets a protocol-narrowed rule instead, and ip6_packet_match() now takes the flag-gated branch, including the ipv6_find_hdr() walk and its *hotdrop = true path when the lookup fails with _frag_off == 0: if (ip6info->flags & IP6T_F_PROTO) { ... protohdr = ipv6_find_hdr(skb, protoff, -1, &_frag_off, NULL); if (protohdr < 0) { if (_frag_off == 0) *hotdrop = true; Standard ip6tables always sets IP6T_F_PROTO together with -p, so this only affects hand-crafted rule blobs, and the resulting rule is stricter rather than unsafe. Still, the field's documented meaning changes here. While in that comment, IP6T_FLAGS_PROTO does not exist anywhere in the tree; the macro defined a few lines below is IP6T_F_PROTO. That name is a pre-existing typo and was not introduced by this patch, but it sits in the same sentence this change invalidates. -- Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260907171732.1407739-2-pablo%40netfilter.org ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH net 8/9] netfilter: ip6_tables: set F_PROTO when proto value is nonzero 2026-09-08 18:04 ` netdev-bot+sashiko @ 2026-09-08 20:22 ` Pablo Neira Ayuso 2026-09-08 20:35 ` Pablo Neira Ayuso 1 sibling, 0 replies; 18+ messages in thread From: Pablo Neira Ayuso @ 2026-09-08 20:22 UTC (permalink / raw) To: netdev-bot+sashiko Cc: netfilter-devel, davem, netdev, kuba, pabeni, edumazet, horms, fw, ja On Tue, Sep 08, 2026 at 06:04:04PM +0000, netdev-bot+sashiko@kernel.org wrote: > Thank you for your contribution! Sashiko AI review found 1 potential > issue(s) to consider: > > Critical: 0 · High: 0 · Medium: 0 · Low: 1 > > - [Low] Stale/contradicted UAPI documentation for `struct > ip6t_ip6::proto`. > > -- > > netfilter: ip6_tables: set F_PROTO when proto value is nonzero > > This makes the kernel set IP6T_F_PROTO for any rule that carries a nonzero > ipv6.proto, so ip6_packet_match() always performs the protocol comparison > and extension header walk instead of skipping it when userspace left the > flag clear. It mirrors the normalisation already done in nft_compat.c. > > > diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c > > index f42fb96ef64b6..313c4aac377aa 100644 > > --- a/net/ipv6/netfilter/ip6_tables.c > > +++ b/net/ipv6/netfilter/ip6_tables.c > > @@ -647,6 +647,11 @@ check_entry_size_and_hooks(struct ip6t_entry *e, > > /* Clear counters and comefrom */ > > e->counters = ((struct xt_counters) { 0, 0 }); > > e->comefrom = 0; > > + > > + /* set F_PROTO, else ip6_packet_match won't do the right thing. */ > > + if (e->ipv6.proto) > > + e->ipv6.flags |= IP6T_F_PROTO; > > + > > return 0; > > } > > [Severity: Low] > Should the uapi header comment be updated in the same patch? No. ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH net 8/9] netfilter: ip6_tables: set F_PROTO when proto value is nonzero 2026-09-08 18:04 ` netdev-bot+sashiko 2026-09-08 20:22 ` Pablo Neira Ayuso @ 2026-09-08 20:35 ` Pablo Neira Ayuso 1 sibling, 0 replies; 18+ messages in thread From: Pablo Neira Ayuso @ 2026-09-08 20:35 UTC (permalink / raw) To: netdev-bot+sashiko Cc: netfilter-devel, davem, netdev, kuba, pabeni, edumazet, horms, fw, ja On Tue, Sep 08, 2026 at 06:04:04PM +0000, netdev-bot+sashiko@kernel.org wrote: > Thank you for your contribution! Sashiko AI review found 1 potential > issue(s) to consider: > > Critical: 0 · High: 0 · Medium: 0 · Low: 1 > > - [Low] Stale/contradicted UAPI documentation for `struct > ip6t_ip6::proto`. > > -- > > netfilter: ip6_tables: set F_PROTO when proto value is nonzero > > This makes the kernel set IP6T_F_PROTO for any rule that carries a nonzero > ipv6.proto, so ip6_packet_match() always performs the protocol comparison > and extension header walk instead of skipping it when userspace left the > flag clear. It mirrors the normalisation already done in nft_compat.c. > > > diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c > > index f42fb96ef64b6..313c4aac377aa 100644 > > --- a/net/ipv6/netfilter/ip6_tables.c > > +++ b/net/ipv6/netfilter/ip6_tables.c > > @@ -647,6 +647,11 @@ check_entry_size_and_hooks(struct ip6t_entry *e, > > /* Clear counters and comefrom */ > > e->counters = ((struct xt_counters) { 0, 0 }); > > e->comefrom = 0; > > + > > + /* set F_PROTO, else ip6_packet_match won't do the right thing. */ > > + if (e->ipv6.proto) > > + e->ipv6.flags |= IP6T_F_PROTO; > > + > > return 0; > > } > > [Severity: Low] > Should the uapi header comment be updated in the same patch? The > description of struct ip6t_ip6::proto in > include/uapi/linux/netfilter_ipv6/ip6_tables.h still documents the > opposite contract: > > /* Upper protocol number > * ... > * - You also need to set IP6T_FLAGS_PROTO to "flags" to check protocol. > */ That is still the indeed recommended practise, so no, comment must be not updated. This is just makes a work-around for broken userspace code that has no real usecase other than triggering a bug. Quite a bit of noise from LLM, one pre-existing issue found, but other than that, just lengthy text noise. ^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH net 9/9] netfilter: report NLM_F_DUMP_FILTERED when all is filtered out 2026-09-07 17:17 [PATCH net,v2 0/9] Netfilter/IPVS fixes for net Pablo Neira Ayuso ` (7 preceding siblings ...) 2026-09-07 17:17 ` [PATCH net 8/9] netfilter: ip6_tables: set F_PROTO when proto value is nonzero Pablo Neira Ayuso @ 2026-09-07 17:17 ` Pablo Neira Ayuso 8 siblings, 0 replies; 18+ messages in thread From: Pablo Neira Ayuso @ 2026-09-07 17:17 UTC (permalink / raw) To: netfilter-devel; +Cc: davem, netdev, kuba, pabeni, edumazet, horms, fw, ja From: Ilya Maximets <i.maximets@ovn.org> NLM_F_DUMP_FILTERED is only set on data elements in the conntrack dump. But when everything is filtered out it is confusing for the user space, since the flag is not reported anymore and it looks like the table was empty, which may or may not be the case. 'answer_flags' were introduced precisely for this use case, and the conntrack dump should set the flag in there in case the filtering was applied. This is important, for example, to be able to tell if the filters are supported or not by the kernel without modifying the kernel state. With the proper reporting of NLM_F_DUMP_FILTERED on NLMSG_DONE, an application in user space can just try and dump with an arbitrary filter without worrying that there could be no matching entry. The reported flag will signal that the filtering was applied and therefore supported. Fixes: cb8aa9a3affb ("netfilter: ctnetlink: add kernel side filtering for dump") Cc: stable@vger.kernel.org Signed-off-by: Ilya Maximets <i.maximets@ovn.org> Reviewed-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> --- net/netfilter/nf_conntrack_netlink.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 9b4e29557ec3..579ada063b1b 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -1077,6 +1077,8 @@ static int ctnetlink_start(struct netlink_callback *cb) } cb->data = filter; + if (filter) + cb->answer_flags = NLM_F_DUMP_FILTERED; return 0; } -- 2.47.3 ^ permalink raw reply related [flat|nested] 18+ messages in thread
end of thread, other threads:[~2026-09-08 21:01 UTC | newest] Thread overview: 18+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-09-07 17:17 [PATCH net,v2 0/9] Netfilter/IPVS fixes for net Pablo Neira Ayuso 2026-09-07 17:17 ` [PATCH net 1/9] ipvs: reject invalid states in connection template sync records Pablo Neira Ayuso 2026-09-08 21:00 ` patchwork-bot+netdevbpf 2026-09-07 17:17 ` [PATCH net 2/9] ipvs: fix reversed sequence option serialization Pablo Neira Ayuso 2026-09-07 17:17 ` [PATCH net 3/9] netfilter: nf_conntrack_sip: fix OOB read in sip_skip_whitespace() Pablo Neira Ayuso 2026-09-07 17:17 ` [PATCH net 4/9] netfilter: cttimeout: prevent UAF during module unload Pablo Neira Ayuso 2026-09-08 18:04 ` netdev-bot+sashiko 2026-09-08 20:24 ` Pablo Neira Ayuso 2026-09-07 17:17 ` [PATCH net 5/9] netfilter: nf_log: unregister loggers before per-net teardown Pablo Neira Ayuso 2026-09-07 17:17 ` [PATCH net 6/9] netfilter: nfnetlink_log: cope with concurrent instance destruction Pablo Neira Ayuso 2026-09-07 17:17 ` [PATCH net 7/9] netfilter: arp_tables: remove the 32bit compat interface Pablo Neira Ayuso 2026-09-08 18:04 ` netdev-bot+sashiko 2026-09-08 20:32 ` Pablo Neira Ayuso 2026-09-07 17:17 ` [PATCH net 8/9] netfilter: ip6_tables: set F_PROTO when proto value is nonzero Pablo Neira Ayuso 2026-09-08 18:04 ` netdev-bot+sashiko 2026-09-08 20:22 ` Pablo Neira Ayuso 2026-09-08 20:35 ` Pablo Neira Ayuso 2026-09-07 17:17 ` [PATCH net 9/9] netfilter: report NLM_F_DUMP_FILTERED when all is filtered out Pablo Neira Ayuso
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox