Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

net: vxlan: prevent NULL deref in vxlan_xmit_one

Neither sock4 nor sock6 pointers are guaranteed to be non-NULL in
vxlan_xmit_one, e.g. if the iface is brought down. This can lead to the
following NULL dereference:

BUG: kernel NULL pointer dereference, address: 0000000000000010
Oops: Oops: 0000 [#1] SMP NOPTI
RIP: 0010:vxlan_xmit_one+0xbb3/0x1580
Call Trace:
vxlan_xmit+0x429/0x610
dev_hard_start_xmit+0x55/0xa0
__dev_queue_xmit+0x6d0/0x7f0
ip_finish_output2+0x24b/0x590
ip_output+0x63/0x110

Mentioned commits changed the code path in vxlan_xmit_one and as a side
effect the sock4/6 pointer validity checks in vxlan(6)_get_route were
lost. Fix this by adding back checks.

Since both commits being fixed were released in the same version (v6.7)
and are strongly related, bundle the fixes in a single commit.

Reported-by: Liang Li <liali@redhat.com>
Fixes: 6f19b2c136d9 ("vxlan: use generic function for tunnel IPv4 route lookup")
Fixes: 2aceb896ee18 ("vxlan: use generic function for tunnel IPv6 route lookup")
Cc: Beniamino Galvani <b.galvani@gmail.com>
Signed-off-by: Antoine Tenart <atenart@kernel.org>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Tested-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/20251126102627.74223-1-atenart@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Antoine Tenart and committed by
Jakub Kicinski
1f73a56f 1e43ebcd

+15 -3
+15 -3
drivers/net/vxlan/vxlan_core.c
··· 2349 2349 int addr_family; 2350 2350 __u8 tos, ttl; 2351 2351 int ifindex; 2352 - int err; 2352 + int err = 0; 2353 2353 u32 flags = vxlan->cfg.flags; 2354 2354 bool use_cache; 2355 2355 bool udp_sum = false; ··· 2454 2454 2455 2455 rcu_read_lock(); 2456 2456 if (addr_family == AF_INET) { 2457 - struct vxlan_sock *sock4 = rcu_dereference(vxlan->vn4_sock); 2457 + struct vxlan_sock *sock4; 2458 2458 u16 ipcb_flags = 0; 2459 2459 struct rtable *rt; 2460 2460 __be16 df = 0; 2461 2461 __be32 saddr; 2462 + 2463 + sock4 = rcu_dereference(vxlan->vn4_sock); 2464 + if (unlikely(!sock4)) { 2465 + reason = SKB_DROP_REASON_DEV_READY; 2466 + goto tx_error; 2467 + } 2462 2468 2463 2469 if (!ifindex) 2464 2470 ifindex = sock4->sock->sk->sk_bound_dev_if; ··· 2540 2534 ipcb_flags); 2541 2535 #if IS_ENABLED(CONFIG_IPV6) 2542 2536 } else { 2543 - struct vxlan_sock *sock6 = rcu_dereference(vxlan->vn6_sock); 2537 + struct vxlan_sock *sock6; 2544 2538 struct in6_addr saddr; 2545 2539 u16 ip6cb_flags = 0; 2540 + 2541 + sock6 = rcu_dereference(vxlan->vn6_sock); 2542 + if (unlikely(!sock6)) { 2543 + reason = SKB_DROP_REASON_DEV_READY; 2544 + goto tx_error; 2545 + } 2546 2546 2547 2547 if (!ifindex) 2548 2548 ifindex = sock6->sock->sk->sk_bound_dev_if;