mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 04:34:03 +02:00
net/packet: reset the MAC header on the packet-socket transmit path
packet_parse_headers() resets the MAC header only for a SOCK_RAW frame whose socket did not bind a protocol. A protocol-bound SOCK_RAW socket, any SOCK_DGRAM frame, and the legacy SOCK_PACKET path therefore leave skb->mac_header unset here. For frames sent via __dev_queue_xmit() this is harmless: it resets the MAC header unconditionally. But the packet-socket PACKET_QDISC_BYPASS path uses dev_direct_xmit(), which does not, so the frame reaches ndo_start_xmit() with the MAC header unset. A driver that reads eth_hdr(skb) on transmit then dereferences skb->head + (u16)~0, an out-of-bounds access ~64 KiB past the head -- the same class fixed for one consumer in commitf5089008f9("macsec: do not read an unset MAC header in macsec_encrypt()"). packet_parse_headers() runs only on the transmit path, where skb->data points at the start of the L2 header for every packet-socket type regardless of its length: SOCK_RAW and SOCK_PACKET carry a user-supplied header and SOCK_DGRAM has one built by dev_hard_header(). Reset the MAC header unconditionally, mirroring __dev_queue_xmit(), so the frame is anchored on the bypass path too. Found by 0sec (https://0sec.ai) using automated source analysis; verified against source and matched to the macsec KASAN report inf5089008f9. Compile-tested. Fixes:75c65772c3("net/packet: Ask driver for protocol if not provided by user") Cc: stable@vger.kernel.org Signed-off-by: Doruk Tan Ozturk <doruk@0sec.ai> Reviewed-by: Willem de Bruijn <willemb@google.com> Link: https://patch.msgid.link/20260724144015.63219-1-doruk@0sec.ai Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
53a43508ee
commit
c2707480cf
|
|
@ -1924,11 +1924,12 @@ static void packet_parse_headers(struct sk_buff *skb, struct socket *sock)
|
|||
{
|
||||
int depth;
|
||||
|
||||
/* On TX skb->data is the L2 header; anchor it for all socket types. */
|
||||
skb_reset_mac_header(skb);
|
||||
|
||||
if ((!skb->protocol || skb->protocol == htons(ETH_P_ALL)) &&
|
||||
sock->type == SOCK_RAW) {
|
||||
skb_reset_mac_header(skb);
|
||||
sock->type == SOCK_RAW)
|
||||
skb->protocol = dev_parse_header_protocol(skb);
|
||||
}
|
||||
|
||||
/* Move network header to the right position for VLAN tagged packets */
|
||||
if (likely(skb->dev->type == ARPHRD_ETHER) &&
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user