From: "Cen Zhang (Microsoft Security FORGE Labs)" <cenzhang@linux.microsoft.com>
To: Taehee Yoo <ap420073@gmail.com>,
Andrew Lunn <andrew+netdev@lunn.ch>,
"David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>
Cc: Simon Horman <horms@kernel.org>,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
AutonomousCodeSecurity@microsoft.com, Xiang Mei <xmei5@asu.edu>,
tgopinath@linux.microsoft.com, kys@microsoft.com
Subject: [PATCH net v2] amt: do not store tunnel pointer in skb control block
Date: Tue, 22 Sep 2026 17:41:50 -0400 [thread overview]
Message-ID: <20260922214150.13970-1-cenzhang@linux.microsoft.com> (raw)
An skb queued in a qdisc can outlive the tunnel it references
through a raw pointer in skb->cb. For example, a netem delay of
180s exceeds the default tunnel lifetime of 135s (igmp_qrv=1);
when the tunnel expires and is freed, the subsequent dequeue
triggers a use-after-free in amt_dev_xmit().
BUG: KASAN: slab-use-after-free in amt_dev_xmit+0x2763/0x2e20
Call Trace:
amt_dev_xmit+0x2763/0x2e20 [drivers/net/amt.c:1262]
dev_hard_start_xmit+0x22f/0x620
sch_direct_xmit+0x12e/0xac0
netem_dequeue+0x333/0xc50
net_tx_action+0x35c/0xa60
Store the tunnel identity (ip4 + source_port) in skb->cb instead
of a pointer, and re-lookup the tunnel under RCU in amt_dev_xmit().
If the tunnel is gone, the query is simply dropped.
A refcount fix would be hard to keep balanced here, as the skb may
be dropped or cloned by the qdisc layer before reaching
amt_dev_xmit().
Fixes: cbc21dc1cfe9 ("amt: add data plane of amt interface")
Reported-by: AutonomousCodeSecurity@microsoft.com
Reported-by: Xiang Mei (Microsoft) <xmei5@asu.edu>
Reported-by: Cen Zhang (Microsoft Security FORGE Labs) <cenzhang@linux.microsoft.com>
Signed-off-by: Cen Zhang (Microsoft Security FORGE Labs) <cenzhang@linux.microsoft.com>
---
v2:
- Drop the comment above struct amt_skb_cb (Taehee Yoo)
- Mention in the commit message why a refcount is not used
(Taehee Yoo)
- Rebase on net/main
v1: https://lore.kernel.org/netdev/20260818164825.63967-1-blbllhy@gmail.com/
drivers/net/amt.c | 34 +++++++++++++++++++++++++---------
include/net/amt.h | 3 ++-
2 files changed, 27 insertions(+), 10 deletions(-)
diff --git a/drivers/net/amt.c b/drivers/net/amt.c
index bddc24e1856..b660cebf248 100644
--- a/drivers/net/amt.c
+++ b/drivers/net/amt.c
@@ -791,6 +791,18 @@ static void amt_send_request(struct amt_dev *amt, bool v6)
rcu_read_unlock();
}
+static struct amt_tunnel_list *amt_lookup_tunnel(struct amt_dev *amt,
+ __be32 ip4, __be16 source_port)
+{
+ struct amt_tunnel_list *tunnel;
+
+ list_for_each_entry_rcu(tunnel, &amt->tunnel_list, list)
+ if (tunnel->ip4 == ip4 && tunnel->source_port == source_port)
+ return tunnel;
+
+ return NULL;
+}
+
static void amt_send_igmp_gq(struct amt_dev *amt,
struct amt_tunnel_list *tunnel)
{
@@ -800,7 +812,8 @@ static void amt_send_igmp_gq(struct amt_dev *amt,
if (!skb)
return;
- amt_skb_cb(skb)->tunnel = tunnel;
+ amt_skb_cb(skb)->tunnel_ip4 = tunnel->ip4;
+ amt_skb_cb(skb)->tunnel_port = tunnel->source_port;
dev_queue_xmit(skb);
}
@@ -885,7 +898,8 @@ static void amt_send_mld_gq(struct amt_dev *amt, struct amt_tunnel_list *tunnel)
if (!skb)
return;
- amt_skb_cb(skb)->tunnel = tunnel;
+ amt_skb_cb(skb)->tunnel_ip4 = tunnel->ip4;
+ amt_skb_cb(skb)->tunnel_port = tunnel->source_port;
dev_queue_xmit(skb);
}
#else
@@ -1262,15 +1276,17 @@ static netdev_tx_t amt_dev_xmit(struct sk_buff *skb, struct net_device *dev)
goto unlock;
} else if (amt->mode == AMT_MODE_RELAY) {
if (query) {
- tunnel = amt_skb_cb(skb)->tunnel;
- if (!tunnel) {
- WARN_ON(1);
- goto free;
- }
-
+ rcu_read_lock();
+ tunnel = amt_lookup_tunnel(amt,
+ amt_skb_cb(skb)->tunnel_ip4,
+ amt_skb_cb(skb)->tunnel_port);
/* Do not forward unexpected query */
- if (amt_send_membership_query(amt, skb, tunnel, v6))
+ if (!tunnel ||
+ amt_send_membership_query(amt, skb, tunnel, v6)) {
+ rcu_read_unlock();
goto free;
+ }
+ rcu_read_unlock();
goto unlock;
}
diff --git a/include/net/amt.h b/include/net/amt.h
index a0255491f5b..8727cf007bc 100644
--- a/include/net/amt.h
+++ b/include/net/amt.h
@@ -232,7 +232,8 @@ struct amt_relay_headers {
} __packed;
struct amt_skb_cb {
- struct amt_tunnel_list *tunnel;
+ __be32 tunnel_ip4;
+ __be16 tunnel_port;
};
struct amt_tunnel_list {
--
2.53.0
next reply other threads:[~2026-09-22 21:42 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-22 21:41 Cen Zhang (Microsoft Security FORGE Labs) [this message]
2026-09-23 22:56 ` Omar Ramadan
2026-09-24 19:08 ` Cen Zhang (Microsoft Security FORGE Labs)
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=20260922214150.13970-1-cenzhang@linux.microsoft.com \
--to=cenzhang@linux.microsoft.com \
--cc=AutonomousCodeSecurity@microsoft.com \
--cc=andrew+netdev@lunn.ch \
--cc=ap420073@gmail.com \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=horms@kernel.org \
--cc=kuba@kernel.org \
--cc=kys@microsoft.com \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=tgopinath@linux.microsoft.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®