From: Pablo Neira Ayuso <pablo@netfilter.org>
To: Florian Westphal <fw@strlen.de>
Cc: netfilter-devel@vger.kernel.org, bridge@lists.linux.dev,
netdev@vger.kernel.org, Nikolay Aleksandrov <razor@blackwall.org>,
Ido Schimmel <idosch@nvidia.com>,
"David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
Sabrina Dubroca <sd@queasysnail.net>, Phil Sutter <phil@nwl.cc>,
Simon Horman <horms@kernel.org>,
linux-kernel@vger.kernel.org
Subject: Re: [BUG] net/bridge: out-of-bounds in br_forward()
Date: Thu, 27 Aug 2026 16:54:07 +0200 [thread overview]
Message-ID: <apBPj741ai10Wajf@chamomile> (raw)
In-Reply-To: <apBJyKJ7zs4kUmpd@strlen.de>
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;
prev parent reply other threads:[~2026-08-27 14:54 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
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 message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=apBPj741ai10Wajf@chamomile \
--to=pablo@netfilter.org \
--cc=bridge@lists.linux.dev \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=fw@strlen.de \
--cc=horms@kernel.org \
--cc=idosch@nvidia.com \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=netfilter-devel@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=phil@nwl.cc \
--cc=razor@blackwall.org \
--cc=sd@queasysnail.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.