* [PATCH nf] netfilter: bridge: ebt_redirect: don't assume bridge port exists
@ 2026-06-01 9:50 Florian Westphal
2026-06-01 10:29 ` Pablo Neira Ayuso
0 siblings, 1 reply; 3+ messages in thread
From: Florian Westphal @ 2026-06-01 9:50 UTC (permalink / raw)
To: netfilter-devel; +Cc: Florian Westphal, Hacking
ebt_redirect_tg() dereferences br_port_get_rcu() return without a
NULL check, causing a kernel panic when the bridge port has been
removed between the original hook invocation and an NFQUEUE
reinject.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Reported-by: Hacking <eilaimemedsnaimel@gmail.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
---
net/bridge/netfilter/ebt_redirect.c | 21 +++++++++++++++------
1 file changed, 15 insertions(+), 6 deletions(-)
diff --git a/net/bridge/netfilter/ebt_redirect.c b/net/bridge/netfilter/ebt_redirect.c
index 307790562b49..379662961aeb 100644
--- a/net/bridge/netfilter/ebt_redirect.c
+++ b/net/bridge/netfilter/ebt_redirect.c
@@ -20,16 +20,25 @@ static unsigned int
ebt_redirect_tg(struct sk_buff *skb, const struct xt_action_param *par)
{
const struct ebt_redirect_info *info = par->targinfo;
+ const unsigned char *dev_addr;
if (skb_ensure_writable(skb, 0))
return EBT_DROP;
- if (xt_hooknum(par) != NF_BR_BROUTING)
- /* rcu_read_lock()ed by nf_hook_thresh */
- ether_addr_copy(eth_hdr(skb)->h_dest,
- br_port_get_rcu(xt_in(par))->br->dev->dev_addr);
- else
- ether_addr_copy(eth_hdr(skb)->h_dest, xt_in(par)->dev_addr);
+ if (xt_hooknum(par) != NF_BR_BROUTING) {
+ const struct net_bridge_port *port;
+
+ port = br_port_get_rcu(xt_in(par));
+ if (!port)
+ return EBT_DROP;
+
+ dev_addr = port->br->dev->dev_addr;
+ } else {
+ dev_addr = xt_in(par)->dev_addr;
+ }
+
+ ether_addr_copy(eth_hdr(skb)->h_dest, dev_addr);
+
skb->pkt_type = PACKET_HOST;
return info->target;
}
--
2.54.0
^ permalink raw reply related [flat|nested] 3+ messages in thread* Re: [PATCH nf] netfilter: bridge: ebt_redirect: don't assume bridge port exists 2026-06-01 9:50 [PATCH nf] netfilter: bridge: ebt_redirect: don't assume bridge port exists Florian Westphal @ 2026-06-01 10:29 ` Pablo Neira Ayuso 2026-06-01 10:31 ` Florian Westphal 0 siblings, 1 reply; 3+ messages in thread From: Pablo Neira Ayuso @ 2026-06-01 10:29 UTC (permalink / raw) To: Florian Westphal; +Cc: netfilter-devel, Hacking Hi Florian, On Mon, Jun 01, 2026 at 11:50:00AM +0200, Florian Westphal wrote: > ebt_redirect_tg() dereferences br_port_get_rcu() return without a > NULL check, causing a kernel panic when the bridge port has been > removed between the original hook invocation and an NFQUEUE > reinject. Maybe more candidates for the same pattern? net/bridge/netfilter/nft_reject_bridge.c: br_forward(br_port_get_rcu(dev), nskb, false, true); net/bridge/netfilter/nft_reject_bridge.c: br_forward(br_port_get_rcu(dev), nskb, false, true); net/bridge/netfilter/nft_reject_bridge.c: br_forward(br_port_get_rcu(dev), nskb, false, true); net/bridge/netfilter/nft_reject_bridge.c: br_forward(br_port_get_rcu(dev), nskb, false, true); net/netfilter/nfnetlink_log.c: htonl(br_port_get_rcu(indev)->br->dev->ifindex))) net/netfilter/nfnetlink_log.c: htonl(br_port_get_rcu(outdev)->br->dev->ifindex))) net/netfilter/nfnetlink_queue.c: htonl(br_port_get_rcu(indev)->br->dev->ifindex))) net/netfilter/nfnetlink_queue.c: htonl(br_port_get_rcu(outdev)->br->dev->ifindex))) So this can be fix in one patch? Thanks > Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") > Reported-by: Hacking <eilaimemedsnaimel@gmail.com> > Signed-off-by: Florian Westphal <fw@strlen.de> > --- > net/bridge/netfilter/ebt_redirect.c | 21 +++++++++++++++------ > 1 file changed, 15 insertions(+), 6 deletions(-) > > diff --git a/net/bridge/netfilter/ebt_redirect.c b/net/bridge/netfilter/ebt_redirect.c > index 307790562b49..379662961aeb 100644 > --- a/net/bridge/netfilter/ebt_redirect.c > +++ b/net/bridge/netfilter/ebt_redirect.c > @@ -20,16 +20,25 @@ static unsigned int > ebt_redirect_tg(struct sk_buff *skb, const struct xt_action_param *par) > { > const struct ebt_redirect_info *info = par->targinfo; > + const unsigned char *dev_addr; > > if (skb_ensure_writable(skb, 0)) > return EBT_DROP; > > - if (xt_hooknum(par) != NF_BR_BROUTING) > - /* rcu_read_lock()ed by nf_hook_thresh */ > - ether_addr_copy(eth_hdr(skb)->h_dest, > - br_port_get_rcu(xt_in(par))->br->dev->dev_addr); > - else > - ether_addr_copy(eth_hdr(skb)->h_dest, xt_in(par)->dev_addr); > + if (xt_hooknum(par) != NF_BR_BROUTING) { > + const struct net_bridge_port *port; > + > + port = br_port_get_rcu(xt_in(par)); > + if (!port) > + return EBT_DROP; > + > + dev_addr = port->br->dev->dev_addr; > + } else { > + dev_addr = xt_in(par)->dev_addr; > + } > + > + ether_addr_copy(eth_hdr(skb)->h_dest, dev_addr); > + > skb->pkt_type = PACKET_HOST; > return info->target; > } > -- > 2.54.0 > > ^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH nf] netfilter: bridge: ebt_redirect: don't assume bridge port exists 2026-06-01 10:29 ` Pablo Neira Ayuso @ 2026-06-01 10:31 ` Florian Westphal 0 siblings, 0 replies; 3+ messages in thread From: Florian Westphal @ 2026-06-01 10:31 UTC (permalink / raw) To: Pablo Neira Ayuso; +Cc: netfilter-devel, Hacking Pablo Neira Ayuso <pablo@netfilter.org> wrote: > Hi Florian, > > On Mon, Jun 01, 2026 at 11:50:00AM +0200, Florian Westphal wrote: > > ebt_redirect_tg() dereferences br_port_get_rcu() return without a > > NULL check, causing a kernel panic when the bridge port has been > > removed between the original hook invocation and an NFQUEUE > > reinject. > > Maybe more candidates for the same pattern? Did not find any, but I only searched in net/bridge/netfilter. Will send a v2. > net/bridge/netfilter/nft_reject_bridge.c: br_forward(br_port_get_rcu(dev), nskb, false, true); > net/bridge/netfilter/nft_reject_bridge.c: br_forward(br_port_get_rcu(dev), nskb, false, true); > net/bridge/netfilter/nft_reject_bridge.c: br_forward(br_port_get_rcu(dev), nskb, false, true); > net/bridge/netfilter/nft_reject_bridge.c: br_forward(br_port_get_rcu(dev), nskb, false, true); br_forward(NULL, .. is safe. > net/netfilter/nfnetlink_log.c: htonl(br_port_get_rcu(indev)->br->dev->ifindex))) > net/netfilter/nfnetlink_log.c: htonl(br_port_get_rcu(outdev)->br->dev->ifindex))) > net/netfilter/nfnetlink_queue.c: htonl(br_port_get_rcu(indev)->br->dev->ifindex))) > net/netfilter/nfnetlink_queue.c: htonl(br_port_get_rcu(outdev)->br->dev->ifindex))) Those aren't. ^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-06-01 10:31 UTC | newest] Thread overview: 3+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-06-01 9:50 [PATCH nf] netfilter: bridge: ebt_redirect: don't assume bridge port exists Florian Westphal 2026-06-01 10:29 ` Pablo Neira Ayuso 2026-06-01 10:31 ` Florian Westphal
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.