summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2026-07-23 14:42:48 +0000
committerJakub Kicinski <kuba@kernel.org>2026-07-27 15:15:13 -0700
commit26bb2dd0a8839617e2c79ffbbe1923f8e4bab9fb (patch)
treec969c8ed732543f57eb22c39df951ff6b18019b1
parent8eca411347e1d38964f9ed2c8d3b6ab0e7e4473d (diff)
vxlan: use pskb_network_may_pull() in route_shortcircuit()
route_shortcircuit() currently calls pskb_may_pull(skb, sizeof(struct iphdr)) (or ipv6hdr), which checks if bytes are available starting from skb->data. However, in vxlan_xmit(), skb->data points to the MAC header, so skb_network_offset(skb) is ETH_HLEN (14 bytes). Using pskb_may_pull(skb, 20) only checks 20 bytes from skb->data (which is 14 bytes MAC header + 6 bytes of IP header), leaving the rest of the IP header potentially un-pulled in non-linear frags. Subsequent dereferences of ip_hdr(skb)->daddr can read beyond the pulled linear buffer length. Fix this by using pskb_network_may_pull(), which adds skb_network_offset(skb) to the length check to ensure the full network header is present in the linear buffer. Fixes: e4f67addf158 ("add DOVE extensions for VXLAN") Cc: stable@vger.kernel.org Signed-off-by: Eric Dumazet <edumazet@google.com> Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev> Link: https://patch.msgid.link/20260723144249.759100-5-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-rw-r--r--drivers/net/vxlan/vxlan_core.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c
index be3c2bc2cd9a..2163e2687db0 100644
--- a/drivers/net/vxlan/vxlan_core.c
+++ b/drivers/net/vxlan/vxlan_core.c
@@ -2111,7 +2111,7 @@ static bool route_shortcircuit(struct net_device *dev, struct sk_buff *skb)
{
struct iphdr *pip;
- if (!pskb_may_pull(skb, sizeof(struct iphdr)))
+ if (!pskb_network_may_pull(skb, sizeof(struct iphdr)))
return false;
pip = ip_hdr(skb);
n = neigh_lookup(&arp_tbl, &pip->daddr, dev);
@@ -2137,7 +2137,7 @@ static bool route_shortcircuit(struct net_device *dev, struct sk_buff *skb)
*/
if (!ipv6_mod_enabled())
return false;
- if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
+ if (!pskb_network_may_pull(skb, sizeof(struct ipv6hdr)))
return false;
pip6 = ipv6_hdr(skb);
n = neigh_lookup(&nd_tbl, &pip6->daddr, dev);