From: Yizhou Zhao Date: Sun, 7 Jun 2026 11:24:04 +0000 (+0800) Subject: fddi: validate skb length before parsing headers X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=04fc949bd3aad390e61e73549070d00277404d64;p=thirdparty%2Flinux.git fddi: validate skb length before parsing headers fddi_type_trans() reads FDDI header fields from skb->data without first checking that the received frame is long enough for those fields. The destination address spans offsets 1-6 and the LLC dsap field is at offset 13. For SNAP frames, fddi->hdr.llc_snap.ethertype is at offsets 19-20. A truncated 15-byte frame with dsap != 0xe0 therefore enters the SNAP branch and reads the ethertype past the end of the frame. KASAN reports this when such a frame is processed through a dummy FDDI netdev that calls the real fddi_type_trans() on an exact kmalloc() copy of the frame: BUG: KASAN: slab-out-of-bounds in fddi_type_trans+0x385/0x3a0 Read of size 2 at addr ffff888009c6fe33 The buggy address is located 4 bytes to the right of allocated 15-byte region [ffff888009c6fe20, ffff888009c6fe2f) Reject short frames before reading the fields: require the minimum 802.2 header length before accessing dsap or daddr, and require the full SNAP header length before reading the SNAP ethertype. Returning protocol 0 causes the malformed packet to be ignored by protocol handlers. Cc: # devices should drop runt frames, repro uses a fake driver Reported-by: Yizhou Zhao Reported-by: Yuxiang Yang Reported-by: Ao Wang Reported-by: Xuewei Feng Reported-by: Qi Li Reported-by: Ke Xu Signed-off-by: Yizhou Zhao Reviewed-by: Simon Horman Link: https://patch.msgid.link/20260607112408.92988-1-zhaoyz24@mails.tsinghua.edu.cn Signed-off-by: Jakub Kicinski --- diff --git a/net/802/fddi.c b/net/802/fddi.c index 888379ae35ec..e26f4549e904 100644 --- a/net/802/fddi.c +++ b/net/802/fddi.c @@ -103,6 +103,9 @@ __be16 fddi_type_trans(struct sk_buff *skb, struct net_device *dev) skb->dev = dev; skb_reset_mac_header(skb); /* point to frame control (FC) */ + if (skb->len < FDDI_K_8022_HLEN) + return htons(0); + if(fddi->hdr.llc_8022_1.dsap==0xe0) { skb_pull(skb, FDDI_K_8022_HLEN-3); @@ -110,6 +113,8 @@ __be16 fddi_type_trans(struct sk_buff *skb, struct net_device *dev) } else { + if (skb->len < FDDI_K_SNAP_HLEN) + return htons(0); skb_pull(skb, FDDI_K_SNAP_HLEN); /* adjust for 21 byte header */ type=fddi->hdr.llc_snap.ethertype; }