]> Gentwo Git Trees - linux/.git/commitdiff
net: vxlan: prevent NULL deref in vxlan_xmit_one
authorAntoine Tenart <atenart@kernel.org>
Wed, 26 Nov 2025 10:26:25 +0000 (11:26 +0100)
committerJakub Kicinski <kuba@kernel.org>
Fri, 28 Nov 2025 01:48:57 +0000 (17:48 -0800)
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>
drivers/net/vxlan/vxlan_core.c

index a5c55e7e4d795fee46a47175035774f50346c405..e957aa12a8a44afc501d5b72585d5207b23cda6c 100644 (file)
@@ -2349,7 +2349,7 @@ void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
        int addr_family;
        __u8 tos, ttl;
        int ifindex;
-       int err;
+       int err = 0;
        u32 flags = vxlan->cfg.flags;
        bool use_cache;
        bool udp_sum = false;
@@ -2454,12 +2454,18 @@ void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
 
        rcu_read_lock();
        if (addr_family == AF_INET) {
-               struct vxlan_sock *sock4 = rcu_dereference(vxlan->vn4_sock);
+               struct vxlan_sock *sock4;
                u16 ipcb_flags = 0;
                struct rtable *rt;
                __be16 df = 0;
                __be32 saddr;
 
+               sock4 = rcu_dereference(vxlan->vn4_sock);
+               if (unlikely(!sock4)) {
+                       reason = SKB_DROP_REASON_DEV_READY;
+                       goto tx_error;
+               }
+
                if (!ifindex)
                        ifindex = sock4->sock->sk->sk_bound_dev_if;
 
@@ -2534,10 +2540,16 @@ void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
                                    ipcb_flags);
 #if IS_ENABLED(CONFIG_IPV6)
        } else {
-               struct vxlan_sock *sock6 = rcu_dereference(vxlan->vn6_sock);
+               struct vxlan_sock *sock6;
                struct in6_addr saddr;
                u16 ip6cb_flags = 0;
 
+               sock6 = rcu_dereference(vxlan->vn6_sock);
+               if (unlikely(!sock6)) {
+                       reason = SKB_DROP_REASON_DEV_READY;
+                       goto tx_error;
+               }
+
                if (!ifindex)
                        ifindex = sock6->sock->sk->sk_bound_dev_if;