---
id: "CVE-2026-98968"
kind: "vulnerability"
aliases: ["CVE-2026-98968"]
title: "Linux kernel amt driver: use-after-free when a queued relay query outlives its tunnel"
severity: "unknown"
cvss: null
epss: 0.00209
exploited: false
status: "open"
category: "runtime"
products: []
ecosystems: []
tags: ["amt", "kernel", "linux", "multicast", "network-appliances", "runtime"]
not_affected_if: ["driver-not-loaded", "no-amt-device"]
published_at: "2026-10-23T13:17:18+00:00"
first_seen_at: "2026-10-23T21:57:33+00:00"
updated_at: "2026-10-25T12:38:50+00:00"
sources: [{"source": "nvd", "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-98968", "first_seen_at": "2026-10-23T21:57:33+00:00"}, {"source": "epss", "url": "https://api.first.org/data/v1/epss?cve=CVE-2026-98968", "first_seen_at": "2026-10-25T12:38:50+00:00"}]
---

# Linux kernel amt driver: use-after-free when a queued relay query outlives its tunnel

In the Linux kernel's amt tunnel driver, a General Query queued in a qdisc keeps a raw pointer to a tunnel that can be freed first, so dequeuing it causes a use-after-free. The sources do not describe what an attacker can do beyond the memory corruption and crash shown in the KASAN trace.

_Summary, check and fix written by a model from the sources; labelled as such._

## How to check

- Check the kernel version with `uname -r` and whether the amt driver is loaded with `lsmod | grep amt`
- Check whether an amt device is configured on the host with `ip -d link show type amt`

## Fix

- Update the Linux kernel to a release that includes the upstream commit titled 'amt: send the relay's General Query directly from the receive path'; the fixed version numbers are unknown from the sources

## Timeline

- 2026-10-23T21:57:33+00:00 nvd https://nvd.nist.gov/vuln/detail/CVE-2026-98968
- 2026-10-25T12:38:50+00:00 epss https://api.first.org/data/v1/epss?cve=CVE-2026-98968

## From the sources

In the Linux kernel, the following vulnerability has been resolved:

amt: send the relay's General Query directly from the receive path

An skb queued in a qdisc can outlive the tunnel it references
through a raw pointer in skb->cb. For example, with igmp_qrv set
to 1 on the relay a tunnel lives for 135s, so a netem delay of
180s on the amt device outlives it; 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

amt_send_igmp_gq() and amt_send_mld_gq() are only called from
amt_request_handler(), inside the rcu_read_lock_bh() section of
amt_rcv(). amt_request_handler() already has the tunnel the query is
for: it found or created it inside that section. Queuing the query with
dev_queue_xmit() only leads back into amt_dev_xmit(), which strips the
Ethernet header and calls amt_send_membership_query() for that tunnel.

Make that call directly from the two senders instead, the same way
amt_send_advertisement() transmits from the receive path. The query
never waits in a qdisc, the tunnel is only dereferenced inside the
RCU section that found or created it, and nothing is stored in
skb->cb, so no lookup or refcount is needed. Remove the query branch
of amt_dev_xmit(), amt_skb_cb() and struct amt_skb_cb, which have no
users left.

Behaviour changes:
 - The relay's own General Queries no longer pass through the amt
   device's egress path: its qdisc, tc egress (clsact/tcx), the
   netfilter egress hook and packet taps. They are still visible as
   UDP on the underlay.
 - A query that is sent successfully is no longer counted as
   tx_dropped. The old query branch left through the unlock label,
   which counted every sent query as dropped.
 - A query that reaches amt_dev_xmit() on a relay from elsewhere,
   such as a userspace querier, is now dropped at the IGMP/MLD type
   switch. Before, it trusted whatever skb->cb held, and a NULL
   tunnel hit the WARN_ON(1).

---

_Free to read at a human pace. An API with keys and an MCP server are in preparation; early access: hello@infrastack.ai_
