From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-yw1-f177.google.com (mail-yw1-f177.google.com [209.85.128.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A0D6C2E1722 for ; Tue, 25 Aug 2026 05:24:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.177 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787635464; cv=none; b=KxCKagJYZG6MbSTGqAhAK9JlAEubp488Rnhe3UboPoeXlz9kd+ydkXGQfvFXsmDBMe8Q1CT9f08EvZsX9Hf2tEISPvybftVxpmLc3AV4AEEg86CMaYnMe3/T5BEEF/81YvAgryqloHjJY11V/XlsU1mcnh3LU+N18X9Sx0vbrk0= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787635464; c=relaxed/simple; bh=fgiov7i7HJO2EfKcekMHZouZ7euWlEPIRfF43TXbQWQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=BjoDZMGOgvijaAFwpwurnTVHEdfCeSW3fZpRKFqBUYSyHJ9ruZNYmZ0Ld+n5sxdzi2AZIXQLqLo8VdDMuSB/R5MJoOyYYcmQqCoB6ZpZ53IKrLbzR9A89Rg97jqEVu/tbq7r2he3be1i/x+ZJxpavmqgrCsdP4/37B3S+BXCaUM= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=Z4UA8tCG; arc=none smtp.client-ip=209.85.128.177 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Z4UA8tCG" Received: by mail-yw1-f177.google.com with SMTP id 00721157ae682-841f1dfc30fso6018297b3.1 for ; Mon, 24 Aug 2026 22:24:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1787635451; x=1788240251; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=xy0SFkuKWMMtc/SL4g2KE02VlB2M1q8Q/oPABrDzF+4=; b=Z4UA8tCGGowAEDQWpWNIO5FQEarvuY6oYrodo0mvJos7msHnNodRrS043QHU0RNhBc OePERMBnCH9VUkztYYKaJXiBlOBqwCPVUgLwLXyqkgjVNlVgiEjYW1U3tT2ih3dZri75 URMpCTHrijfzDbda3KvWgUlJNdKjRpzLZSE1cNBn32NTofvzp3G9ssWeCAjHmTwu6VHr nKiuwGtEvabmBhUuRmU4BmEeNXBaZf1Mj8qOlOQIESa87+WE6OOE2jVbB46D2iT+vDqN 6c+OcOFFxDgr5U8K4bbPnwWxINwoIl0tPWxazzr6F/t/0fByFYurjWdZw7bxbHLgyAmY oW3A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787635451; x=1788240251; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=xy0SFkuKWMMtc/SL4g2KE02VlB2M1q8Q/oPABrDzF+4=; b=s8fVCXh3HbdXA9PFZ847LmIluETU2wUMygSgIVKw9NkHmV2ZiKb35hjsEn+UGXjsr3 QSq6NdIx9AbrGTTBKLCjCqBllmn7lqDKcbPhyGAXu0ovYKTACZCuQ3zzxzviZ5e4mYKl xMHycenjlDBRVe0bW/KTYxAqdNnNxnhnb6Sq9j+vVf4y1KaZ4JqXrcglrfFyKqIbJ8NZ el+KnLAD07onWz97AITg8iwEi3abmj8sIy/z61jmEmTlMPS3iAZgYySdgIrCDFYjLaCC 6m3w5nKmxhueWYwwy+MVRhDKp2s1Og+nBbNp6pnatfVzlvaOByj8X/6CLzY8CVEDeuAK ipPw== X-Forwarded-Encrypted: i=1; AHgh+RpL/Ib1ITWGrbpEtWeALhiMQ3b6F/IMDdjM/Uf8w5fBVcylwdaQoZQYvPfRJTTdaODuTnTnW29FKUpoEIM=@vger.kernel.org X-Gm-Message-State: AFuF++m7cEjvKQS+xvOsGAuvaFOZngWa++UzaYiCTIwIl7euOYzlU+40 fSWlGeiKDA62V+0xks9BkW4ObfAXJHzr+GWLdj5qhKh1UTcf6x7QMFdz X-Gm-Gg: AR+sD12b9inHR2bUQy3Kwlmypr9a0blRvGvf5Cl/9ek7q+53ZoBG0vtEtiJ4l7qZPMU SZRA78L/N40bjQC1eog7oGRLaTHpT47CTxrAkfDJ3r1+y6YSJ9zlvI3gY9Aec5hzVywIK5Hn6hf ILazLHDqBLj2H6Iax+pm+DNVT9JPSzm/UXkQK3L6qoH1TCexAmOwaq49OfecdvgNX1zruibZ9fH RBMcnKh0szSCwOI7E5GU59vHftnUsm8Mjp7wB8GixWX4I1Ne91kqPkTdCdrM9XhgIqD+4StBwHf 8nwOFTUg/KpAUhjkbZol9Ij9igL7ND86Bt5RzWd0W7bAxHTySDL+c3sG5DvwOgPpGxkyxYe2xLI ww9q6wUcPj3fdKNuug1d6CfVyeYfceCqwNf00VqojnI9E1G27WJ4sd9GtNwclhvHygLSxvajNoF vNFqNHGvPabxNK0Cw+Eukh/U0uyoj3f4GmLWLguFKZ2PieYDqR0qh2pfm8etceRq3NoMU= X-Received: by 2002:a05:690c:e299:10b0:820:10f1:d501 with SMTP id 00721157ae682-85470beb3d0mr14076457b3.6.1787635451332; Mon, 24 Aug 2026 22:24:11 -0700 (PDT) Received: from mac.lan ([136.55.173.105]) by smtp.gmail.com with ESMTPSA id 00721157ae682-851e1419e0bsm21767747b3.26.2026.08.24.22.24.10 (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Mon, 24 Aug 2026 22:24:10 -0700 (PDT) From: "Cen Zhang (Microsoft)" To: pablo@netfilter.org, laforge@gnumonks.org, andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com Cc: horms@kernel.org, anthony.l.nguyen@intel.com, wojciech.drewek@intel.com, osmocom-net-gprs@lists.osmocom.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, AutonomousCodeSecurity@microsoft.com, xmei5@asu.edu, tgopinath@linux.microsoft.com, kys@microsoft.com, blbllhy@gmail.com Subject: [PATCH net v2 2/2] gtp: fix use-after-free during GTP device teardown Date: Tue, 25 Aug 2026 01:24:04 -0400 Message-ID: <20260825052404.45665-3-blbllhy@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260825052404.45665-1-blbllhy@gmail.com> References: <20260825052404.45665-1-blbllhy@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit gtp_encap_disable() releases the kernel-created sockets while sk_created is still true and without waiting for in-flight readers. This allows two concurrent use-after-free scenarios: 1. A softirq packet handler that already observed sk_created == true via smp_load_acquire() can dereference sk0/sk1u after they have been freed. 2. gtp_genl_send_echo_req() runs in process context without RTNL. synchronize_net() waits for RCU-protected softirq handlers but does not cover this non-RCU generic netlink reader, which can dereference freed sk0/sk1u during concurrent teardown: RIP: 0010:ip4_route_output_gtp (drivers/net/gtp.c) gtp_genl_send_echo_req Kernel panic - not syncing: Fatal exception Reorder gtp_encap_disable() to clear sk_created first, then call synchronize_net() to wait for in-flight softirq handlers before releasing the sockets. Hold RTNL in gtp_genl_send_echo_req() to serialize with teardown for the process-context path. Under RTNL, the smp_load_acquire() from patch 1/2 becomes redundant and is replaced with a plain read. Fixes: b20dc3c68458 ("gtp: Allow to create GTP device without FDs") Fixes: d33bd757d362 ("gtp: Implement GTP echo request") Reported-by: AutonomousCodeSecurity@microsoft.com Reported-by: Cen Zhang (Microsoft) Signed-off-by: Cen Zhang (Microsoft) --- v2: New patch. Fix teardown race with synchronize_net() for softirq paths and rtnl_lock() for the process-context genl echo path. v1: https://lore.kernel.org/netdev/20260816035205.57966-1-blbllhy@gmail.com/ --- drivers/net/gtp.c | 61 ++++++++++++++++++++++++++++++----------------- 1 file changed, 39 insertions(+), 22 deletions(-) diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c index ead519ee18d1..7ac9764696f2 100644 --- a/drivers/net/gtp.c +++ b/drivers/net/gtp.c @@ -896,12 +896,14 @@ static void gtp_encap_disable_sock(struct sock *sk) static void gtp_encap_disable(struct gtp_dev *gtp) { if (gtp->sk_created) { - udp_tunnel_sock_release(gtp->sk0); - udp_tunnel_sock_release(gtp->sk1u); - /* Pairs with smp_load_acquire() in the RX and - * genl echo paths. + /* Prevent new readers from entering echo handlers, + * then wait for in-flight softirq readers to complete + * before releasing the sockets. */ smp_store_release(>p->sk_created, false); + synchronize_net(); + udp_tunnel_sock_release(gtp->sk0); + udp_tunnel_sock_release(gtp->sk1u); gtp->sk0 = NULL; gtp->sk1u = NULL; } else { @@ -1473,8 +1475,7 @@ static int gtp_create_sockets(struct gtp_dev *gtp, const struct nlattr *nla, gtp->sk1u = sk1u; /* Ensure sk0/sk1u are visible before sk_created is set. - * Pairs with smp_load_acquire() in the RX and genl - * echo paths. + * Pairs with smp_load_acquire() in the RX echo paths. */ smp_store_release(>p->sk_created, true); @@ -2362,6 +2363,7 @@ static int gtp_genl_send_echo_req(struct sk_buff *skb, struct genl_info *info) struct sock *sk; __be16 port; int len; + int ret; if (!info->attrs[GTPA_VERSION] || !info->attrs[GTPA_LINK] || @@ -2373,17 +2375,22 @@ static int gtp_genl_send_echo_req(struct sk_buff *skb, struct genl_info *info) dst_ip = nla_get_be32(info->attrs[GTPA_PEER_ADDRESS]); src_ip = nla_get_be32(info->attrs[GTPA_MS_ADDRESS]); + rtnl_lock(); + gtp = gtp_find_dev(sock_net(skb->sk), info->attrs); - if (!gtp) - return -ENODEV; + if (!gtp) { + ret = -ENODEV; + goto out_unlock; + } - /* Pairs with smp_store_release() in gtp_create_sockets() - * and gtp_encap_disable(). - */ - if (!smp_load_acquire(>p->sk_created)) - return -EOPNOTSUPP; - if (!(gtp->dev->flags & IFF_UP)) - return -ENETDOWN; + if (!gtp->sk_created) { + ret = -EOPNOTSUPP; + goto out_unlock; + } + if (!(gtp->dev->flags & IFF_UP)) { + ret = -ENETDOWN; + goto out_unlock; + } if (version == GTP_V0) { struct gtp0_header *gtp0_h; @@ -2392,8 +2399,10 @@ static int gtp_genl_send_echo_req(struct sk_buff *skb, struct genl_info *info) sizeof(struct iphdr) + sizeof(struct udphdr); skb_to_send = netdev_alloc_skb_ip_align(gtp->dev, len); - if (!skb_to_send) - return -ENOMEM; + if (!skb_to_send) { + ret = -ENOMEM; + goto out_unlock; + } sk = gtp->sk0; port = htons(GTP0_PORT); @@ -2409,8 +2418,10 @@ static int gtp_genl_send_echo_req(struct sk_buff *skb, struct genl_info *info) sizeof(struct iphdr) + sizeof(struct udphdr); skb_to_send = netdev_alloc_skb_ip_align(gtp->dev, len); - if (!skb_to_send) - return -ENOMEM; + if (!skb_to_send) { + ret = -ENOMEM; + goto out_unlock; + } sk = gtp->sk1u; port = htons(GTP1U_PORT); @@ -2420,7 +2431,8 @@ static int gtp_genl_send_echo_req(struct sk_buff *skb, struct genl_info *info) memset(gtp1u_h, 0, sizeof(struct gtp1_header_long)); gtp1u_build_echo_msg(gtp1u_h, GTP_ECHO_REQ); } else { - return -ENODEV; + ret = -ENODEV; + goto out_unlock; } rt = ip4_route_output_gtp(&fl4, sk, dst_ip, src_ip); @@ -2428,7 +2440,8 @@ static int gtp_genl_send_echo_req(struct sk_buff *skb, struct genl_info *info) netdev_dbg(gtp->dev, "no route for echo request to %pI4\n", &dst_ip); kfree_skb(skb_to_send); - return -ENODEV; + ret = -ENODEV; + goto out_unlock; } local_bh_disable(); @@ -2442,7 +2455,11 @@ static int gtp_genl_send_echo_req(struct sk_buff *skb, struct genl_info *info) dev_net(gtp->dev)), false, 0); local_bh_enable(); - return 0; + ret = 0; + +out_unlock: + rtnl_unlock(); + return ret; } static const struct nla_policy gtp_genl_policy[GTPA_MAX + 1] = { -- 2.55.0