* [PATCH net 0/3] net: don't read an unset MAC header on the raw/qdisc-bypass TX path
@ 2026-07-13 19:40 Doruk Tan Ozturk
2026-07-13 19:40 ` [PATCH net 1/3] net: dsa: tag_ocelot_8021q: don't read an unset MAC header on transmit Doruk Tan Ozturk
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Doruk Tan Ozturk @ 2026-07-13 19:40 UTC (permalink / raw)
To: Vladimir Oltean, Andrew Lunn, Florian Fainelli, Woojung Huh,
Nick Child, David S . Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni
Cc: netdev, linux-kernel, linuxppc-dev, Sabrina Dubroca,
Arun Ramadoss, UNGLinuxDriver, Michael Ellerman, Doruk Tan Ozturk
On the AF_PACKET SOCK_RAW + PACKET_QDISC_BYPASS transmit path, skb->mac_header
is left unset when ndo_start_xmit() runs, so eth_hdr(skb) resolves ~64KB out of
bounds. Commit f5089008f90c ("macsec: don't read an unset MAC header in
macsec_encrypt()") fixed one instance; these three are the same class in other
TX/.xmit paths, each reading eth_hdr(skb)->h_dest. On TX the L2 header is at
skb->data, so use skb_eth_hdr() (a no-op on normal TX where mac_header is set).
Found by static analysis (0sec); verified against source, not runtime-reproduced.
Confirmed by an independent cross-check that mac_header is unset on the bypass
path (__dev_direct_xmit does not reset it). More siblings exist (sja1105 shared
TX/RX helper, atlantic PTP path) and will follow separately.
Doruk Tan Ozturk (3):
net: dsa: tag_ocelot_8021q: don't read an unset MAC header on transmit
net: dsa: tag_ksz: don't read an unset MAC header in lan937x_xmit()
ibmveth: don't read an unset MAC header on transmit
drivers/net/ethernet/ibm/ibmveth.c | 2 +-
net/dsa/tag_ksz.c | 2 +-
net/dsa/tag_ocelot_8021q.c | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH net 1/3] net: dsa: tag_ocelot_8021q: don't read an unset MAC header on transmit
2026-07-13 19:40 [PATCH net 0/3] net: don't read an unset MAC header on the raw/qdisc-bypass TX path Doruk Tan Ozturk
@ 2026-07-13 19:40 ` Doruk Tan Ozturk
2026-07-13 20:04 ` Vladimir Oltean
2026-07-13 19:40 ` [PATCH net 2/3] net: dsa: tag_ksz: don't read an unset MAC header in lan937x_xmit() Doruk Tan Ozturk
2026-07-13 19:40 ` [PATCH net 3/3] ibmveth: don't read an unset MAC header on transmit Doruk Tan Ozturk
2 siblings, 1 reply; 7+ messages in thread
From: Doruk Tan Ozturk @ 2026-07-13 19:40 UTC (permalink / raw)
To: Vladimir Oltean, Andrew Lunn, Florian Fainelli, Woojung Huh,
Nick Child, David S . Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni
Cc: netdev, linux-kernel, linuxppc-dev, Sabrina Dubroca,
Arun Ramadoss, UNGLinuxDriver, Michael Ellerman, Doruk Tan Ozturk,
stable
ocelot_xmit() reads the Ethernet header via eth_hdr(skb) to test the
destination address against the link-local range.
On the AF_PACKET SOCK_RAW + PACKET_QDISC_BYPASS transmit path the skb
reaches ndo_start_xmit() with the MAC header unset, so eth_hdr(skb)
resolves to skb->head + (u16)~0 and the read is out of bounds.
On the TX path the L2 header is at skb->data, so use skb_eth_hdr(), as
done for the same class by
commit f5089008f90c ("macsec: don't read an unset MAC header in macsec_encrypt()")
and commit 96cc4b69581d ("macvlan: do not assume mac_header is set in macvlan_broadcast()").
Fixes: 43ba33b4f143 ("net: dsa: tag_ocelot_8021q: fix inability to inject STP BPDUs into BLOCKING ports")
Cc: stable@vger.kernel.org
Found by 0sec automated security-research tooling (https://0sec.ai).
Assisted-by: 0sec:claude-opus-4-8
Signed-off-by: Doruk Tan Ozturk <doruk@0sec.ai>
---
net/dsa/tag_ocelot_8021q.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/dsa/tag_ocelot_8021q.c b/net/dsa/tag_ocelot_8021q.c
index f50f1cd83f16..4514026897d1 100644
--- a/net/dsa/tag_ocelot_8021q.c
+++ b/net/dsa/tag_ocelot_8021q.c
@@ -71,7 +71,7 @@ static struct sk_buff *ocelot_xmit(struct sk_buff *skb,
u16 queue_mapping = skb_get_queue_mapping(skb);
u8 pcp = netdev_txq_to_tc(netdev, queue_mapping);
u16 tx_vid = dsa_tag_8021q_standalone_vid(dp);
- struct ethhdr *hdr = eth_hdr(skb);
+ struct ethhdr *hdr = skb_eth_hdr(skb);
if (ocelot_ptp_rew_op(skb) || is_link_local_ether_addr(hdr->h_dest))
return ocelot_defer_xmit(dp, skb);
--
2.43.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH net 2/3] net: dsa: tag_ksz: don't read an unset MAC header in lan937x_xmit()
2026-07-13 19:40 [PATCH net 0/3] net: don't read an unset MAC header on the raw/qdisc-bypass TX path Doruk Tan Ozturk
2026-07-13 19:40 ` [PATCH net 1/3] net: dsa: tag_ocelot_8021q: don't read an unset MAC header on transmit Doruk Tan Ozturk
@ 2026-07-13 19:40 ` Doruk Tan Ozturk
2026-07-13 19:40 ` [PATCH net 3/3] ibmveth: don't read an unset MAC header on transmit Doruk Tan Ozturk
2 siblings, 0 replies; 7+ messages in thread
From: Doruk Tan Ozturk @ 2026-07-13 19:40 UTC (permalink / raw)
To: Vladimir Oltean, Andrew Lunn, Florian Fainelli, Woojung Huh,
Nick Child, David S . Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni
Cc: netdev, linux-kernel, linuxppc-dev, Sabrina Dubroca,
Arun Ramadoss, UNGLinuxDriver, Michael Ellerman, Doruk Tan Ozturk,
stable
lan937x_xmit() reads the Ethernet header via eth_hdr(skb) to test the
destination address. The sibling xmit paths in this file (ksz8795_xmit,
ksz9477_xmit, ksz9893_xmit) already use skb_eth_hdr(); lan937x_xmit() is
the lone hold-out.
On the AF_PACKET SOCK_RAW + PACKET_QDISC_BYPASS transmit path the skb
reaches ndo_start_xmit() with the MAC header unset, so eth_hdr(skb)
resolves to skb->head + (u16)~0 and the read is out of bounds.
On the TX path the L2 header is at skb->data, so use skb_eth_hdr(), as
done for the same class by
commit f5089008f90c ("macsec: don't read an unset MAC header in macsec_encrypt()")
and commit 96cc4b69581d ("macvlan: do not assume mac_header is set in macvlan_broadcast()").
Fixes: 092f875131dc ("net: dsa: tag_ksz: add tag handling for Microchip LAN937x")
Cc: stable@vger.kernel.org
Found by 0sec automated security-research tooling (https://0sec.ai).
Assisted-by: 0sec:claude-opus-4-8
Signed-off-by: Doruk Tan Ozturk <doruk@0sec.ai>
---
net/dsa/tag_ksz.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/dsa/tag_ksz.c b/net/dsa/tag_ksz.c
index 67fa89f102e0..4f74336ae396 100644
--- a/net/dsa/tag_ksz.c
+++ b/net/dsa/tag_ksz.c
@@ -430,7 +430,7 @@ static struct sk_buff *lan937x_xmit(struct sk_buff *skb,
u16 queue_mapping = skb_get_queue_mapping(skb);
u8 prio = netdev_txq_to_tc(dev, queue_mapping);
struct dsa_port *dp = dsa_user_to_port(dev);
- const struct ethhdr *hdr = eth_hdr(skb);
+ const struct ethhdr *hdr = skb_eth_hdr(skb);
__be16 *tag;
u16 val;
--
2.43.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH net 3/3] ibmveth: don't read an unset MAC header on transmit
2026-07-13 19:40 [PATCH net 0/3] net: don't read an unset MAC header on the raw/qdisc-bypass TX path Doruk Tan Ozturk
2026-07-13 19:40 ` [PATCH net 1/3] net: dsa: tag_ocelot_8021q: don't read an unset MAC header on transmit Doruk Tan Ozturk
2026-07-13 19:40 ` [PATCH net 2/3] net: dsa: tag_ksz: don't read an unset MAC header in lan937x_xmit() Doruk Tan Ozturk
@ 2026-07-13 19:40 ` Doruk Tan Ozturk
2 siblings, 0 replies; 7+ messages in thread
From: Doruk Tan Ozturk @ 2026-07-13 19:40 UTC (permalink / raw)
To: Vladimir Oltean, Andrew Lunn, Florian Fainelli, Woojung Huh,
Nick Child, David S . Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni
Cc: netdev, linux-kernel, linuxppc-dev, Sabrina Dubroca,
Arun Ramadoss, UNGLinuxDriver, Michael Ellerman, Doruk Tan Ozturk,
stable
ibmveth_is_packet_unsupported(), called from ibmveth_start_xmit(), reads
the Ethernet header via eth_hdr(skb) to test the destination address.
On the AF_PACKET SOCK_RAW + PACKET_QDISC_BYPASS transmit path the skb
reaches ndo_start_xmit() with the MAC header unset, so eth_hdr(skb)
resolves to skb->head + (u16)~0 and the read is out of bounds.
On the TX path the L2 header is at skb->data, so use skb_eth_hdr(), as
done for the same class by
commit f5089008f90c ("macsec: don't read an unset MAC header in macsec_encrypt()")
and commit 96cc4b69581d ("macvlan: do not assume mac_header is set in macvlan_broadcast()").
Fixes: 6f2275433a2f ("ibmveth: Detect unsupported packets before sending to the hypervisor")
Cc: stable@vger.kernel.org
Found by 0sec automated security-research tooling (https://0sec.ai).
Assisted-by: 0sec:claude-opus-4-8
Signed-off-by: Doruk Tan Ozturk <doruk@0sec.ai>
---
drivers/net/ethernet/ibm/ibmveth.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/ibm/ibmveth.c b/drivers/net/ethernet/ibm/ibmveth.c
index 73e051d26b9d..88e8bdfbcd11 100644
--- a/drivers/net/ethernet/ibm/ibmveth.c
+++ b/drivers/net/ethernet/ibm/ibmveth.c
@@ -1218,7 +1218,7 @@ static int ibmveth_is_packet_unsupported(struct sk_buff *skb,
struct ethhdr *ether_header;
int ret = 0;
- ether_header = eth_hdr(skb);
+ ether_header = skb_eth_hdr(skb);
if (ether_addr_equal(ether_header->h_dest, netdev->dev_addr)) {
netdev_dbg(netdev, "veth doesn't support loopback packets, dropping packet.\n");
--
2.43.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH net 1/3] net: dsa: tag_ocelot_8021q: don't read an unset MAC header on transmit
2026-07-13 19:40 ` [PATCH net 1/3] net: dsa: tag_ocelot_8021q: don't read an unset MAC header on transmit Doruk Tan Ozturk
@ 2026-07-13 20:04 ` Vladimir Oltean
2026-07-13 21:12 ` Doruk (0sec)
0 siblings, 1 reply; 7+ messages in thread
From: Vladimir Oltean @ 2026-07-13 20:04 UTC (permalink / raw)
To: Doruk Tan Ozturk
Cc: Andrew Lunn, Florian Fainelli, Woojung Huh, Nick Child,
David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
netdev, linux-kernel, linuxppc-dev, Sabrina Dubroca,
Arun Ramadoss, UNGLinuxDriver, Michael Ellerman, stable
On Mon, Jul 13, 2026 at 09:40:08PM +0200, Doruk Tan Ozturk wrote:
> ocelot_xmit() reads the Ethernet header via eth_hdr(skb) to test the
> destination address against the link-local range.
>
> On the AF_PACKET SOCK_RAW + PACKET_QDISC_BYPASS transmit path the skb
> reaches ndo_start_xmit() with the MAC header unset, so eth_hdr(skb)
> resolves to skb->head + (u16)~0 and the read is out of bounds.
>
> On the TX path the L2 header is at skb->data, so use skb_eth_hdr(), as
> done for the same class by
> commit f5089008f90c ("macsec: don't read an unset MAC header in macsec_encrypt()")
> and commit 96cc4b69581d ("macvlan: do not assume mac_header is set in macvlan_broadcast()").
>
> Fixes: 43ba33b4f143 ("net: dsa: tag_ocelot_8021q: fix inability to inject STP BPDUs into BLOCKING ports")
> Cc: stable@vger.kernel.org
> Found by 0sec automated security-research tooling (https://0sec.ai).
> Assisted-by: 0sec:claude-opus-4-8
> Signed-off-by: Doruk Tan Ozturk <doruk@0sec.ai>
> ---
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
I was not aware of the bug introduced by commit d346a3fae3ff ("packet:
introduce PACKET_QDISC_BYPASS socket option"). Commits
eabb1494c9f2 ("net: dsa: tag_ocelot: do not rely on skb_mac_header() for VLAN xmit")
499b2491d550 ("net: dsa: tag_ksz: do not rely on skb_mac_header() in TX paths")
f9346f00b5af ("net: dsa: tag_sja1105: don't rely on skb_mac_header() in TX paths")
0bcf2e4aca6c ("net: dsa: tag_ocelot: call only the relevant portion of __skb_vlan_pop() on TX")
were made assuming that the bug to avoid would be exclusively a future
one (the revert of commit 6d1ccff62780 ("net: reset mac header in
dev_start_xmit()")) and thus they were not marked as bug fixes.
Are they true bug fixes, as in "can we reproduce these [using
CONFIG_NET_DSA_LOOP=y on virtually any network adapter]"? If so, should
all the commits above also be backported to stable?
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH net 1/3] net: dsa: tag_ocelot_8021q: don't read an unset MAC header on transmit
2026-07-13 20:04 ` Vladimir Oltean
@ 2026-07-13 21:12 ` Doruk (0sec)
2026-07-13 21:37 ` Vladimir Oltean
0 siblings, 1 reply; 7+ messages in thread
From: Doruk (0sec) @ 2026-07-13 21:12 UTC (permalink / raw)
To: Vladimir Oltean
Cc: Andrew Lunn, Florian Fainelli, Woojung Huh, Nick Child,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
netdev, linux-kernel, linuxppc-dev, Sabrina Dubroca,
Arun Ramadoss, UNGLinuxDriver, Michael Ellerman, stable
Hi Vladimir,
Thanks for the review.
I checked the DSA cases with CONFIG_NET_DSA_LOOP=y. Since dsa_loop
normally uses DSA_TAG_PROTO_NONE, I used a local repro-only override
of dsa_loop_get_protocol() to select the relevant tagger, then sent an
AF_PACKET/SOCK_RAW frame with PACKET_QDISC_BYPASS and
sll_protocol=ETH_P_IP through lan1.
That leaves skb->mac_header unset (65535) on the direct-xmit path.
For tag_ocelot_8021q, the eth_hdr(skb) version reproduces as:
BUG: KASAN: slab-out-of-bounds in ocelot_xmit()
Switching that site to skb_eth_hdr(skb) makes the same reproducer run clean.
I also checked the LAN937X path the same way by forcing
DSA_TAG_PROTO_LAN937X. The eth_hdr(skb) version reproduces as:
BUG: KASAN: slab-out-of-bounds in lan937x_xmit()
and the skb_eth_hdr(skb) version runs clean with the same packet sender.
So yes, for these DSA TX paths this is a real bug on the
PACKET_QDISC_BYPASS path, not just a future-proofing cleanup. I have
not yet checked ibmveth with a pseries/ibmveth setup.
For the older DSA commits you listed, I think they should be treated
as stable candidates if they remove eth_hdr()/skb_mac_header() use
from the same TX path. I can go through those individually and send a
follow-up with the exact stable list if that would be useful.
Thanks,
Doruk
On Mon, 13 Jul 2026 23:04:17 +0300, Vladimir Oltean <olteanv@gmail.com> wrote:
> On Mon, Jul 13, 2026 at 09:40:08PM +0200, Doruk Tan Ozturk wrote:
> > ocelot_xmit() reads the Ethernet header via eth_hdr(skb) to test the
> > destination address against the link-local range.
> >
> > On the AF_PACKET SOCK_RAW + PACKET_QDISC_BYPASS transmit path the skb
> > reaches ndo_start_xmit() with the MAC header unset, so eth_hdr(skb)
> > resolves to skb->head + (u16)~0 and the read is out of bounds.
> >
> > On the TX path the L2 header is at skb->data, so use skb_eth_hdr(), as
> > done for the same class by
> > commit f5089008f90c ("macsec: don't read an unset MAC header in macsec_encrypt()")
> > and commit 96cc4b69581d ("macvlan: do not assume mac_header is set in macvlan_broadcast()").
> >
> > Fixes: 43ba33b4f143 ("net: dsa: tag_ocelot_8021q: fix inability to inject STP BPDUs into BLOCKING ports")
> > Cc: stable@vger.kernel.org
> > Found by 0sec automated security-research tooling (https://0sec.ai).
> > Assisted-by: 0sec:claude-opus-4-8
> > Signed-off-by: Doruk Tan Ozturk <doruk@0sec.ai>
> > ---
>
> Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
>
> I was not aware of the bug introduced by commit d346a3fae3ff ("packet:
> introduce PACKET_QDISC_BYPASS socket option"). Commits
> eabb1494c9f2 ("net: dsa: tag_ocelot: do not rely on skb_mac_header() for VLAN xmit")
> 499b2491d550 ("net: dsa: tag_ksz: do not rely on skb_mac_header() in TX paths")
> f9346f00b5af ("net: dsa: tag_sja1105: don't rely on skb_mac_header() in TX paths")
> 0bcf2e4aca6c ("net: dsa: tag_ocelot: call only the relevant portion of __skb_vlan_pop() on TX")
>
> were made assuming that the bug to avoid would be exclusively a future
> one (the revert of commit 6d1ccff62780 ("net: reset mac header in
> dev_start_xmit()")) and thus they were not marked as bug fixes.
>
> Are they true bug fixes, as in "can we reproduce these [using
> CONFIG_NET_DSA_LOOP=y on virtually any network adapter]"? If so, should
> all the commits above also be backported to stable?
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH net 1/3] net: dsa: tag_ocelot_8021q: don't read an unset MAC header on transmit
2026-07-13 21:12 ` Doruk (0sec)
@ 2026-07-13 21:37 ` Vladimir Oltean
0 siblings, 0 replies; 7+ messages in thread
From: Vladimir Oltean @ 2026-07-13 21:37 UTC (permalink / raw)
To: Doruk (0sec)
Cc: Andrew Lunn, Florian Fainelli, Woojung Huh, Nick Child,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
netdev, linux-kernel, linuxppc-dev, Sabrina Dubroca,
Arun Ramadoss, UNGLinuxDriver, Michael Ellerman, stable
On Mon, Jul 13, 2026 at 04:12:20PM -0500, Doruk (0sec) wrote:
> Hi Vladimir,
>
> Thanks for the review.
>
> I checked the DSA cases with CONFIG_NET_DSA_LOOP=y. Since dsa_loop
> normally uses DSA_TAG_PROTO_NONE, I used a local repro-only override
> of dsa_loop_get_protocol() to select the relevant tagger, then sent an
> AF_PACKET/SOCK_RAW frame with PACKET_QDISC_BYPASS and
> sll_protocol=ETH_P_IP through lan1.
>
> That leaves skb->mac_header unset (65535) on the direct-xmit path.
>
> For tag_ocelot_8021q, the eth_hdr(skb) version reproduces as:
>
> BUG: KASAN: slab-out-of-bounds in ocelot_xmit()
>
> Switching that site to skb_eth_hdr(skb) makes the same reproducer run clean.
>
> I also checked the LAN937X path the same way by forcing
> DSA_TAG_PROTO_LAN937X. The eth_hdr(skb) version reproduces as:
>
> BUG: KASAN: slab-out-of-bounds in lan937x_xmit()
>
> and the skb_eth_hdr(skb) version runs clean with the same packet sender.
>
> So yes, for these DSA TX paths this is a real bug on the
> PACKET_QDISC_BYPASS path, not just a future-proofing cleanup. I have
> not yet checked ibmveth with a pseries/ibmveth setup.
Thanks for clarifying your testing procedure (and please do not top-post
replies).
Yes, manually editing dsa_loop_get_protocol() is the current state of
the art technology.
> For the older DSA commits you listed, I think they should be treated
> as stable candidates if they remove eth_hdr()/skb_mac_header() use
> from the same TX path. I can go through those individually and send a
> follow-up with the exact stable list if that would be useful.
Since skb_mac_header() in TX paths is the real problem, I now think
those commits should need backporting too. I only reworked the
first-order callers of skb_mac_header(), not realizing that eth_hdr()
needs rework too - and not having a clear testing procedure at the time.
I think it would be great if you could prepare an email to the stable
mailing list and to the maintainers.
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-07-13 21:37 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-13 19:40 [PATCH net 0/3] net: don't read an unset MAC header on the raw/qdisc-bypass TX path Doruk Tan Ozturk
2026-07-13 19:40 ` [PATCH net 1/3] net: dsa: tag_ocelot_8021q: don't read an unset MAC header on transmit Doruk Tan Ozturk
2026-07-13 20:04 ` Vladimir Oltean
2026-07-13 21:12 ` Doruk (0sec)
2026-07-13 21:37 ` Vladimir Oltean
2026-07-13 19:40 ` [PATCH net 2/3] net: dsa: tag_ksz: don't read an unset MAC header in lan937x_xmit() Doruk Tan Ozturk
2026-07-13 19:40 ` [PATCH net 3/3] ibmveth: don't read an unset MAC header on transmit Doruk Tan Ozturk
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox