All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Cen Zhang (Microsoft)" <blbllhy@gmail.com>
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	[thread overview]
Message-ID: <20260825052404.45665-3-blbllhy@gmail.com> (raw)
In-Reply-To: <20260825052404.45665-1-blbllhy@gmail.com>

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) <blbllhy@gmail.com>
Signed-off-by: Cen Zhang (Microsoft) <blbllhy@gmail.com>
---
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(&gtp->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(&gtp->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(&gtp->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

  parent reply	other threads:[~2026-08-25  5:24 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-25  5:24 [PATCH net v2 0/2] gtp: fix sk_created race conditions Cen Zhang (Microsoft)
2026-08-25  5:24 ` [PATCH net v2 1/2] gtp: fix sk_created publication race in gtp_create_sockets() Cen Zhang (Microsoft)
2026-08-25  5:24 ` Cen Zhang (Microsoft) [this message]
2026-08-26 12:20 ` [PATCH net v2 0/2] gtp: fix sk_created race conditions Pablo Neira Ayuso

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260825052404.45665-3-blbllhy@gmail.com \
    --to=blbllhy@gmail.com \
    --cc=AutonomousCodeSecurity@microsoft.com \
    --cc=andrew+netdev@lunn.ch \
    --cc=anthony.l.nguyen@intel.com \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=horms@kernel.org \
    --cc=kuba@kernel.org \
    --cc=kys@microsoft.com \
    --cc=laforge@gnumonks.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=osmocom-net-gprs@lists.osmocom.org \
    --cc=pabeni@redhat.com \
    --cc=pablo@netfilter.org \
    --cc=tgopinath@linux.microsoft.com \
    --cc=wojciech.drewek@intel.com \
    --cc=xmei5@asu.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.