]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
net: geneve: check skb is large enough for IPv4/IPv6 header
authorPhillip Potter <phil@philpotter.co.uk>
Sun, 11 Apr 2021 11:28:24 +0000 (12:28 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 28 Apr 2021 11:16:52 +0000 (13:16 +0200)
[ Upstream commit 6628ddfec7580882f11fdc5c194a8ea781fdadfa ]

Check within geneve_xmit_skb/geneve6_xmit_skb that sk_buff structure
is large enough to include IPv4 or IPv6 header, and reject if not. The
geneve_xmit_skb portion and overall idea was contributed by Eric Dumazet.
Fixes a KMSAN-found uninit-value bug reported by syzbot at:
https://syzkaller.appspot.com/bug?id=abe95dc3e3e9667fc23b8d81f29ecad95c6f106f

Suggested-by: Eric Dumazet <edumazet@google.com>
Reported-by: syzbot+2e406a9ac75bb71d4b7a@syzkaller.appspotmail.com
Signed-off-by: Phillip Potter <phil@philpotter.co.uk>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/net/geneve.c

index 2e2afc824a6a8679adf911b59d1e909f1b4f029d..ce6fecf421f8641ee73f16c8cb886a7f3a12571d 100644 (file)
@@ -839,6 +839,9 @@ static int geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
        __be16 df;
        int err;
 
+       if (!pskb_network_may_pull(skb, sizeof(struct iphdr)))
+               return -EINVAL;
+
        sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true);
        rt = geneve_get_v4_rt(skb, dev, gs4, &fl4, info,
                              geneve->info.key.tp_dst, sport);
@@ -882,6 +885,9 @@ static int geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
        __be16 sport;
        int err;
 
+       if (!pskb_network_may_pull(skb, sizeof(struct ipv6hdr)))
+               return -EINVAL;
+
        sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true);
        dst = geneve_get_v6_dst(skb, dev, gs6, &fl6, info,
                                geneve->info.key.tp_dst, sport);