* [BUG] net/bridge: out-of-bounds in br_forward()
@ 2026-08-27 12:43 co
2026-08-27 14:29 ` Florian Westphal
0 siblings, 1 reply; 4+ messages in thread
From: co @ 2026-08-27 12:43 UTC (permalink / raw)
To: netfilter-devel, coreteam, bridge, netdev, Pablo Neira Ayuso,
Florian Westphal, Nikolay Aleksandrov, Ido Schimmel,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Sabrina Dubroca, Phil Sutter, Simon Horman, linux-kernel
We found a bug reachable in:
path net/bridge/netfilter
crash out-of-bounds in br_forward()
commit 7b5344954050 ("Merge tag 'nf-26-08-10' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf")
Config, environment, the sanitizer report and a C reproducer follow.
== Notes ===============================================================
If you patch the bug based on our artifacts, a tag would be
appreciated:
Reported-by: co+63bad23bb3b4cd85@bugs.sh
Everything in this mail is validated by the reproducer below.
We also hold an LLM-generated root-cause analysis and a candidate
patch. The patch passes an A/B test: the same reproducer panics the
unpatched kernel and runs clean on the patched one. Neither has had
human review, so both still require validation before you send or
apply them. Available on:
patch.diff https://bugs.sh/b/63bad23bb3b4cd85/patch.diff
report.md https://bugs.sh/b/63bad23bb3b4cd85/report.md
This is an open science project. The code and the full set of PoCs
are not public at this moment, as we intend to disclose our findings
in an ethical way.
Happy to test patches. Complaints and suggestions about our work
are welcome at:
cedalion@bugs.sh
== Environment =========================================================
Reproduced on 7b5344954050 ("Merge tag 'nf-26-08-10' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf")
VM setup https://bugs.sh/b/63bad23bb3b4cd85/run.sh
config https://bugs.sh/b/63bad23bb3b4cd85/config.gz
poc https://bugs.sh/b/63bad23bb3b4cd85/repro.c
== Sanitizer Report ====================================================
BUG: KASAN: slab-out-of-bounds in br_forward+0x3c2/0x420
Read of size 8 at addr ffff888023fc3938 by task exploit/5007
CPU: 0 UID: 1000 PID: 5007 Comm: exploit Not tainted 7.2.0-rc6-00285-g7b5344954050 #20 PREEMPT(full)
Call Trace:
<IRQ>
dump_stack_lvl+0x10e/0x1f0 (lib/dump_stack.c:123)
print_report+0xf7/0x600 (mm/kasan/report.c:379)
kasan_report+0xe4/0x120 (mm/kasan/report.c:597)
br_forward+0x3c2/0x420 (net/bridge/br_forward.c:151 (discriminator 2))
nft_reject_br_send_v4_unreach+0x9c/0x130 (net/bridge/netfilter/nft_reject_bridge.c:75)
nft_reject_bridge_eval+0x4f0/0xcc0 (net/bridge/netfilter/nft_reject_bridge.c:129)
nft_do_chain+0x2e5/0x19d0 (net/netfilter/nf_tables_core.c:287)
nft_do_chain_bridge+0x199/0x290 (net/netfilter/nft_chain_filter.c:235)
nf_hook_slow+0xbf/0x220 (net/netfilter/core.c:620)
br_nf_hook_thresh+0x286/0x410 (net/bridge/br_netfilter_hooks.c:1164)
br_nf_pre_routing_finish+0xb7c/0x1830 (net/bridge/br_netfilter_hooks.c:432)
br_nf_pre_routing+0xfb6/0x1600 (./include/linux/netfilter.h:319)
br_handle_frame+0xcbb/0x1520 (net/bridge/br_input.c:292)
__netif_receive_skb_core.constprop.0+0x6bf/0x3610 (net/core/dev.c:6103 (discriminator 1))
__netif_receive_skb_one_core+0xb0/0x1e0 (net/core/dev.c:6215)
__netif_receive_skb+0x1f/0x120 (net/core/dev.c:6329)
process_backlog+0x399/0x15b0 (./include/linux/rcupdate.h:869)
__napi_poll.constprop.0+0xb3/0x550 (net/core/dev.c:7740)
net_rx_action+0xa5e/0x1020 (net/core/dev.c:7804)
handle_softirqs+0x1ea/0x9b0 (./arch/x86/include/asm/jump_label.h:37)
do_softirq+0xad/0xe0 (kernel/softirq.c:523 (discriminator 20))
</IRQ>
__local_bh_enable_ip+0xfc/0x120 (kernel/softirq.c:450)
__dev_queue_xmit+0xa2c/0x47f0 (net/core/dev.c:4914)
packet_xmit+0x243/0x360 (./include/linux/netdevice.h:3448)
packet_sendmsg+0x32fa/0x5010 (net/packet/af_packet.c:3109 (discriminator 1))
__sys_sendto+0x480/0x4d0 (net/socket.c:775 (discriminator 1))
__x64_sys_sendto+0xe0/0x1c0 (net/socket.c:2255)
do_syscall_64+0x116/0x7d0 (arch/x86/entry/syscall_64.c:63 (discriminator 1))
The buggy address belongs to the object at ffff888023fc3920
which belongs to the cache kmalloc-16 of size 16
The buggy address is located 8 bytes to the right of
allocated 16-byte region [ffff888023fc3920, ffff888023fc3930)
Kernel panic - not syncing: KASAN: panic_on_warn set ...
---
The report format is based on syzbot bug report.
This report is generated by a bot. It may contain errors.
See https://github.com/n132/cedalion for more information.
For any issue with this report, reach out to cedalion@bugs.sh
If the report is already addressed, let us know by replying with:
#co fix: <commit hash>
If the report is a duplicate of another one, reply with:
#co dup: <lore link>
If you want to undo deduplication, reply with:
#co undup
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [BUG] net/bridge: out-of-bounds in br_forward() 2026-08-27 12:43 [BUG] net/bridge: out-of-bounds in br_forward() co @ 2026-08-27 14:29 ` Florian Westphal 2026-08-27 14:35 ` Nikolay Aleksandrov 2026-08-27 14:54 ` Pablo Neira Ayuso 0 siblings, 2 replies; 4+ messages in thread From: Florian Westphal @ 2026-08-27 14:29 UTC (permalink / raw) To: netfilter-devel Cc: bridge, netdev, Pablo Neira Ayuso, Nikolay Aleksandrov, Ido Schimmel, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni, Sabrina Dubroca, Phil Sutter, Simon Horman, linux-kernel co <co+63bad23bb3b4cd85@bugs.sh> wrote: > We found a bug reachable in: > > path net/bridge/netfilter > crash out-of-bounds in br_forward() > commit 7b5344954050 ("Merge tag 'nf-26-08-10' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf") I'm looking into these reports, I think this is the same underlying bug as the other report; a variant of ccb9fd4b8753 ("netfilter: revalidate bridge ports") That bug uses nfnetlink_queue for RCU escape, the other two reports use defrag engine. And sure, its br_netfilter again -- I think we will have to consider removing it even though it will break existing setups. As a compromise, I suggest to reject br_netfilter in user namespaces, i.e. call_iptables cannot be enabled anymore unless you have CAP_NET_ADMIN in init net. ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [BUG] net/bridge: out-of-bounds in br_forward() 2026-08-27 14:29 ` Florian Westphal @ 2026-08-27 14:35 ` Nikolay Aleksandrov 2026-08-27 14:54 ` Pablo Neira Ayuso 1 sibling, 0 replies; 4+ messages in thread From: Nikolay Aleksandrov @ 2026-08-27 14:35 UTC (permalink / raw) To: Florian Westphal, netfilter-devel Cc: bridge, netdev, Pablo Neira Ayuso, Ido Schimmel, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni, Sabrina Dubroca, Phil Sutter, Simon Horman, linux-kernel On 27/08/2026 17:29, Florian Westphal wrote: > co <co+63bad23bb3b4cd85@bugs.sh> wrote: >> We found a bug reachable in: >> >> path net/bridge/netfilter >> crash out-of-bounds in br_forward() >> commit 7b5344954050 ("Merge tag 'nf-26-08-10' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf") > > I'm looking into these reports, I think this is the same > underlying bug as the other report; a variant of > > ccb9fd4b8753 ("netfilter: revalidate bridge ports") > > That bug uses nfnetlink_queue for RCU escape, the other two reports > use defrag engine. > > And sure, its br_netfilter again -- I think we will have to consider > removing it even though it will break existing setups. > +10 > As a compromise, I suggest to reject br_netfilter in user namespaces, > i.e. call_iptables cannot be enabled anymore unless you have > CAP_NET_ADMIN in init net. +1000 :) I absolutely agree on both counts. ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [BUG] net/bridge: out-of-bounds in br_forward() 2026-08-27 14:29 ` Florian Westphal 2026-08-27 14:35 ` Nikolay Aleksandrov @ 2026-08-27 14:54 ` Pablo Neira Ayuso 1 sibling, 0 replies; 4+ messages in thread From: Pablo Neira Ayuso @ 2026-08-27 14:54 UTC (permalink / raw) To: Florian Westphal Cc: netfilter-devel, bridge, netdev, Nikolay Aleksandrov, Ido Schimmel, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni, Sabrina Dubroca, Phil Sutter, Simon Horman, linux-kernel On Thu, Aug 27, 2026 at 04:29:28PM +0200, Florian Westphal wrote: > co <co+63bad23bb3b4cd85@bugs.sh> wrote: > > We found a bug reachable in: > > > > path net/bridge/netfilter > > crash out-of-bounds in br_forward() > > commit 7b5344954050 ("Merge tag 'nf-26-08-10' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf") > > I'm looking into these reports, I think this is the same > underlying bug as the other report; a variant of > > ccb9fd4b8753 ("netfilter: revalidate bridge ports") > > That bug uses nfnetlink_queue for RCU escape, the other two reports > use defrag engine. I started this patch. I think this can still happen with native nfnetlink_queue support for the bridge family? diff --git a/net/bridge/netfilter/nft_reject_bridge.c b/net/bridge/netfilter/nft_reject_bridge.c index cd2b04236a99..b3a51ba72e9c 100644 --- a/net/bridge/netfilter/nft_reject_bridge.c +++ b/net/bridge/netfilter/nft_reject_bridge.c @@ -44,7 +44,7 @@ static void nft_reject_br_push_etherhdr(struct sk_buff *oldskb, */ static void nft_reject_br_send_v4_tcp_reset(struct net *net, struct sk_buff *oldskb, - const struct net_device *dev, + struct net_bridge_port *port, int hook) { struct sk_buff *nskb; @@ -55,12 +55,12 @@ static void nft_reject_br_send_v4_tcp_reset(struct net *net, nft_reject_br_push_etherhdr(oldskb, nskb); - br_forward(br_port_get_rcu(dev), nskb, false, true); + br_forward(port, nskb, false, true); } static void nft_reject_br_send_v4_unreach(struct net *net, struct sk_buff *oldskb, - const struct net_device *dev, + struct net_bridge_port *port, int hook, u8 code) { struct sk_buff *nskb; @@ -71,12 +71,12 @@ static void nft_reject_br_send_v4_unreach(struct net *net, nft_reject_br_push_etherhdr(oldskb, nskb); - br_forward(br_port_get_rcu(dev), nskb, false, true); + br_forward(port, nskb, false, true); } static void nft_reject_br_send_v6_tcp_reset(struct net *net, struct sk_buff *oldskb, - const struct net_device *dev, + struct net_bridge_port *port, int hook) { struct sk_buff *nskb; @@ -87,13 +87,13 @@ static void nft_reject_br_send_v6_tcp_reset(struct net *net, nft_reject_br_push_etherhdr(oldskb, nskb); - br_forward(br_port_get_rcu(dev), nskb, false, true); + br_forward(port, nskb, false, true); } static void nft_reject_br_send_v6_unreach(struct net *net, struct sk_buff *oldskb, - const struct net_device *dev, + struct net_bridge_port *port, int hook, u8 code) { struct sk_buff *nskb; @@ -104,37 +104,47 @@ static void nft_reject_br_send_v6_unreach(struct net *net, nft_reject_br_push_etherhdr(oldskb, nskb); - br_forward(br_port_get_rcu(dev), nskb, false, true); + br_forward(port, nskb, false, true); } static void nft_reject_bridge_eval(const struct nft_expr *expr, struct nft_regs *regs, const struct nft_pktinfo *pkt) { - struct nft_reject *priv = nft_expr_priv(expr); const unsigned char *dest = eth_hdr(pkt->skb)->h_dest; + struct nft_reject *priv = nft_expr_priv(expr); + const struct net_device *dev = nft_in(pkt); + struct net_bridge_port *port; if (is_broadcast_ether_addr(dest) || is_multicast_ether_addr(dest)) goto out; + if (!dev || !netif_is_bridge_port(dev) || + netdev_master_upper_dev_get_rcu((struct net_device *)dev)) + goto out; + + port = br_port_get_rcu(dev); + if (!port) + goto out; + switch (eth_hdr(pkt->skb)->h_proto) { case htons(ETH_P_IP): switch (priv->type) { case NFT_REJECT_ICMP_UNREACH: nft_reject_br_send_v4_unreach(nft_net(pkt), pkt->skb, - nft_in(pkt), + port, nft_hook(pkt), priv->icmp_code); break; case NFT_REJECT_TCP_RST: nft_reject_br_send_v4_tcp_reset(nft_net(pkt), pkt->skb, - nft_in(pkt), + port, nft_hook(pkt)); break; case NFT_REJECT_ICMPX_UNREACH: nft_reject_br_send_v4_unreach(nft_net(pkt), pkt->skb, - nft_in(pkt), + port, nft_hook(pkt), nft_reject_icmp_code(priv->icmp_code)); break; @@ -144,18 +154,18 @@ static void nft_reject_bridge_eval(const struct nft_expr *expr, switch (priv->type) { case NFT_REJECT_ICMP_UNREACH: nft_reject_br_send_v6_unreach(nft_net(pkt), pkt->skb, - nft_in(pkt), + port, nft_hook(pkt), priv->icmp_code); break; case NFT_REJECT_TCP_RST: nft_reject_br_send_v6_tcp_reset(nft_net(pkt), pkt->skb, - nft_in(pkt), + port, nft_hook(pkt)); break; case NFT_REJECT_ICMPX_UNREACH: nft_reject_br_send_v6_unreach(nft_net(pkt), pkt->skb, - nft_in(pkt), + port, nft_hook(pkt), nft_reject_icmpv6_code(priv->icmp_code)); break; ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-08-27 14:54 UTC | newest] Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2026-08-27 12:43 [BUG] net/bridge: out-of-bounds in br_forward() co 2026-08-27 14:29 ` Florian Westphal 2026-08-27 14:35 ` Nikolay Aleksandrov 2026-08-27 14:54 ` 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
all inboxes | Powered by JetHome®