Patch "net: tun: fix bugs for oversize packet when napi frags enabled" has been added to the 4.19-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    net: tun: fix bugs for oversize packet when napi frags enabled

to the 4.19-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     net-tun-fix-bugs-for-oversize-packet-when-napi-frags.patch
and it can be found in the queue-4.19 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 133795fe8d94bbd057d1ac849143db34865b2fa8
Author: Ziyang Xuan <william.xuanziyang@xxxxxxxxxx>
Date:   Sat Oct 29 17:41:01 2022 +0800

    net: tun: fix bugs for oversize packet when napi frags enabled
    
    [ Upstream commit 363a5328f4b0517e59572118ccfb7c626d81dca9 ]
    
    Recently, we got two syzkaller problems because of oversize packet
    when napi frags enabled.
    
    One of the problems is because the first seg size of the iov_iter
    from user space is very big, it is 2147479538 which is bigger than
    the threshold value for bail out early in __alloc_pages(). And
    skb->pfmemalloc is true, __kmalloc_reserve() would use pfmemalloc
    reserves without __GFP_NOWARN flag. Thus we got a warning as following:
    
    ========================================================
    WARNING: CPU: 1 PID: 17965 at mm/page_alloc.c:5295 __alloc_pages+0x1308/0x16c4 mm/page_alloc.c:5295
    ...
    Call trace:
     __alloc_pages+0x1308/0x16c4 mm/page_alloc.c:5295
     __alloc_pages_node include/linux/gfp.h:550 [inline]
     alloc_pages_node include/linux/gfp.h:564 [inline]
     kmalloc_large_node+0x94/0x350 mm/slub.c:4038
     __kmalloc_node_track_caller+0x620/0x8e4 mm/slub.c:4545
     __kmalloc_reserve.constprop.0+0x1e4/0x2b0 net/core/skbuff.c:151
     pskb_expand_head+0x130/0x8b0 net/core/skbuff.c:1654
     __skb_grow include/linux/skbuff.h:2779 [inline]
     tun_napi_alloc_frags+0x144/0x610 drivers/net/tun.c:1477
     tun_get_user+0x31c/0x2010 drivers/net/tun.c:1835
     tun_chr_write_iter+0x98/0x100 drivers/net/tun.c:2036
    
    The other problem is because odd IPv6 packets without NEXTHDR_NONE
    extension header and have big packet length, it is 2127925 which is
    bigger than ETH_MAX_MTU(65535). After ipv6_gso_pull_exthdrs() in
    ipv6_gro_receive(), network_header offset and transport_header offset
    are all bigger than U16_MAX. That would trigger skb->network_header
    and skb->transport_header overflow error, because they are all '__u16'
    type. Eventually, it would affect the value for __skb_push(skb, value),
    and make it be a big value. After __skb_push() in ipv6_gro_receive(),
    skb->data would less than skb->head, an out of bounds memory bug occurred.
    That would trigger the problem as following:
    
    ==================================================================
    BUG: KASAN: use-after-free in eth_type_trans+0x100/0x260
    ...
    Call trace:
     dump_backtrace+0xd8/0x130
     show_stack+0x1c/0x50
     dump_stack_lvl+0x64/0x7c
     print_address_description.constprop.0+0xbc/0x2e8
     print_report+0x100/0x1e4
     kasan_report+0x80/0x120
     __asan_load8+0x78/0xa0
     eth_type_trans+0x100/0x260
     napi_gro_frags+0x164/0x550
     tun_get_user+0xda4/0x1270
     tun_chr_write_iter+0x74/0x130
     do_iter_readv_writev+0x130/0x1ec
     do_iter_write+0xbc/0x1e0
     vfs_writev+0x13c/0x26c
    
    To fix the problems, restrict the packet size less than
    (ETH_MAX_MTU - NET_SKB_PAD - NET_IP_ALIGN) which has considered reserved
    skb space in napi_alloc_skb() because transport_header is an offset from
    skb->head. Add len check in tun_napi_alloc_frags() simply.
    
    Fixes: 90e33d459407 ("tun: enable napi_gro_frags() for TUN/TAP driver")
    Signed-off-by: Ziyang Xuan <william.xuanziyang@xxxxxxxxxx>
    Reviewed-by: Eric Dumazet <edumazet@xxxxxxxxxx>
    Link: https://lore.kernel.org/r/20221029094101.1653855-1-william.xuanziyang@xxxxxxxxxx
    Signed-off-by: Jakub Kicinski <kuba@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index c3390999842a..8d1b34640f79 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -1473,7 +1473,8 @@ static struct sk_buff *tun_napi_alloc_frags(struct tun_file *tfile,
 	int err;
 	int i;
 
-	if (it->nr_segs > MAX_SKB_FRAGS + 1)
+	if (it->nr_segs > MAX_SKB_FRAGS + 1 ||
+	    len > (ETH_MAX_MTU - NET_SKB_PAD - NET_IP_ALIGN))
 		return ERR_PTR(-EMSGSIZE);
 
 	local_bh_disable();



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux