diff options
| author | Andrew Kanner <andrew.kanner@gmail.com> | 2023-08-03 20:59:48 +0200 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2023-08-16 18:21:01 +0200 |
| commit | 13f7752f4adbb0ed47ad06230e2c86933c45b56c (patch) | |
| tree | ebf9fde672299a77c163eaee8a31a922ebeaf9d9 | |
| parent | 6d701c95ee6463abcbb6da543060d6e444554135 (diff) | |
| download | linux-13f7752f4adbb0ed47ad06230e2c86933c45b56c.tar.gz linux-13f7752f4adbb0ed47ad06230e2c86933c45b56c.tar.bz2 linux-13f7752f4adbb0ed47ad06230e2c86933c45b56c.zip | |
drivers: net: prevent tun_build_skb() to exceed the packet size limit
commit 59eeb232940515590de513b997539ef495faca9a upstream.
Using the syzkaller repro with reduced packet size it was discovered
that XDP_PACKET_HEADROOM is not checked in tun_can_build_skb(),
although pad may be incremented in tun_build_skb(). This may end up
with exceeding the PAGE_SIZE limit in tun_build_skb().
Jason Wang <jasowang@redhat.com> proposed to count XDP_PACKET_HEADROOM
always (e.g. without rcu_access_pointer(tun->xdp_prog)) in
tun_can_build_skb() since there's a window during which XDP program
might be attached between tun_can_build_skb() and tun_build_skb().
Fixes: 7df13219d757 ("tun: reserve extra headroom only when XDP is set")
Link: https://syzkaller.appspot.com/bug?extid=f817490f5bd20541b90a
Signed-off-by: Andrew Kanner <andrew.kanner@gmail.com>
Link: https://lore.kernel.org/r/20230803185947.2379988-1-andrew.kanner@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
| -rw-r--r-- | drivers/net/tun.c | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 0e70877c932c..191bf0df1466 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -1604,7 +1604,7 @@ static bool tun_can_build_skb(struct tun_struct *tun, struct tun_file *tfile, if (zerocopy) return false; - if (SKB_DATA_ALIGN(len + TUN_RX_PAD) + + if (SKB_DATA_ALIGN(len + TUN_RX_PAD + XDP_PACKET_HEADROOM) + SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) > PAGE_SIZE) return false; |
