FKIE_CVE-2025-68232
Vulnerability from fkie_nvd - Published: 2025-12-16 14:15 - Updated: 2026-10-14 13:10
Severity
Summary
In the Linux kernel, the following vulnerability has been resolved:
veth: more robust handing of race to avoid txq getting stuck
Commit dc82a33297fc ("veth: apply qdisc backpressure on full ptr_ring to
reduce TX drops") introduced a race condition that can lead to a permanently
stalled TXQ. This was observed in production on ARM64 systems (Ampere Altra
Max).
The race occurs in veth_xmit(). The producer observes a full ptr_ring and
stops the queue (netif_tx_stop_queue()). The subsequent conditional logic,
intended to re-wake the queue if the consumer had just emptied it (if
(__ptr_ring_empty(...)) netif_tx_wake_queue()), can fail. This leads to a
"lost wakeup" where the TXQ remains stopped (QUEUE_STATE_DRV_XOFF) and
traffic halts.
This failure is caused by an incorrect use of the __ptr_ring_empty() API
from the producer side. As noted in kernel comments, this check is not
guaranteed to be correct if a consumer is operating on another CPU. The
empty test is based on ptr_ring->consumer_head, making it reliable only for
the consumer. Using this check from the producer side is fundamentally racy.
This patch fixes the race by adopting the more robust logic from an earlier
version V4 of the patchset, which always flushed the peer:
(1) In veth_xmit(), the racy conditional wake-up logic and its memory barrier
are removed. Instead, after stopping the queue, we unconditionally call
__veth_xdp_flush(rq). This guarantees that the NAPI consumer is scheduled,
making it solely responsible for re-waking the TXQ.
This handles the race where veth_poll() consumes all packets and completes
NAPI *before* veth_xmit() on the producer side has called netif_tx_stop_queue.
The __veth_xdp_flush(rq) will observe rx_notify_masked is false and schedule
NAPI.
(2) On the consumer side, the logic for waking the peer TXQ is moved out of
veth_xdp_rcv() and placed at the end of the veth_poll() function. This
placement is part of fixing the race, as the netif_tx_queue_stopped() check
must occur after rx_notify_masked is potentially set to false during NAPI
completion.
This handles the race where veth_poll() consumes all packets, but haven't
finished (rx_notify_masked is still true). The producer veth_xmit() stops the
TXQ and __veth_xdp_flush(rq) will observe rx_notify_masked is true, meaning
not starting NAPI. Then veth_poll() change rx_notify_masked to false and
stops NAPI. Before exiting veth_poll() will observe TXQ is stopped and wake
it up.
References
Impacted products
| Vendor | Product | Version |
|---|
{
"affected": [
{
"affectedData": [
{
"defaultStatus": "unaffected",
"product": "Linux",
"programFiles": [
"drivers/net/veth.c"
],
"repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
"vendor": "Linux",
"versions": [
{
"lessThan": "dd419a3f2ebc18cc00bc32c57fd052d7a188b78b",
"status": "affected",
"version": "9fe31b3f314534e238aa6d0b6fb492134cbcf8be",
"versionType": "git"
},
{
"lessThan": "6c8a8b9257a660e622689e23c8fbad4ba2b561b9",
"status": "affected",
"version": "dc82a33297fc2c58cb0b2b008d728668d45c0f6a",
"versionType": "git"
},
{
"lessThan": "5442a9da69789741bfda39f34ee7f69552bf0c56",
"status": "affected",
"version": "dc82a33297fc2c58cb0b2b008d728668d45c0f6a",
"versionType": "git"
}
]
},
{
"defaultStatus": "affected",
"product": "Linux",
"programFiles": [
"drivers/net/veth.c"
],
"repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
"vendor": "Linux",
"versions": [
{
"status": "affected",
"version": "6.16"
},
{
"lessThan": "6.16",
"status": "unaffected",
"version": "0",
"versionType": "semver"
},
{
"lessThanOrEqual": "6.17.*",
"status": "unaffected",
"version": "6.17.10",
"versionType": "semver"
},
{
"lessThanOrEqual": "*",
"status": "unaffected",
"version": "6.18",
"versionType": "original_commit_for_fix"
}
]
}
],
"source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67"
}
],
"cveTags": [],
"descriptions": [
{
"lang": "en",
"value": "In the Linux kernel, the following vulnerability has been resolved:\n\nveth: more robust handing of race to avoid txq getting stuck\n\nCommit dc82a33297fc (\"veth: apply qdisc backpressure on full ptr_ring to\nreduce TX drops\") introduced a race condition that can lead to a permanently\nstalled TXQ. This was observed in production on ARM64 systems (Ampere Altra\nMax).\n\nThe race occurs in veth_xmit(). The producer observes a full ptr_ring and\nstops the queue (netif_tx_stop_queue()). The subsequent conditional logic,\nintended to re-wake the queue if the consumer had just emptied it (if\n(__ptr_ring_empty(...)) netif_tx_wake_queue()), can fail. This leads to a\n\"lost wakeup\" where the TXQ remains stopped (QUEUE_STATE_DRV_XOFF) and\ntraffic halts.\n\nThis failure is caused by an incorrect use of the __ptr_ring_empty() API\nfrom the producer side. As noted in kernel comments, this check is not\nguaranteed to be correct if a consumer is operating on another CPU. The\nempty test is based on ptr_ring-\u003econsumer_head, making it reliable only for\nthe consumer. Using this check from the producer side is fundamentally racy.\n\nThis patch fixes the race by adopting the more robust logic from an earlier\nversion V4 of the patchset, which always flushed the peer:\n\n(1) In veth_xmit(), the racy conditional wake-up logic and its memory barrier\nare removed. Instead, after stopping the queue, we unconditionally call\n__veth_xdp_flush(rq). This guarantees that the NAPI consumer is scheduled,\nmaking it solely responsible for re-waking the TXQ.\n This handles the race where veth_poll() consumes all packets and completes\nNAPI *before* veth_xmit() on the producer side has called netif_tx_stop_queue.\nThe __veth_xdp_flush(rq) will observe rx_notify_masked is false and schedule\nNAPI.\n\n(2) On the consumer side, the logic for waking the peer TXQ is moved out of\nveth_xdp_rcv() and placed at the end of the veth_poll() function. This\nplacement is part of fixing the race, as the netif_tx_queue_stopped() check\nmust occur after rx_notify_masked is potentially set to false during NAPI\ncompletion.\n This handles the race where veth_poll() consumes all packets, but haven\u0027t\nfinished (rx_notify_masked is still true). The producer veth_xmit() stops the\nTXQ and __veth_xdp_flush(rq) will observe rx_notify_masked is true, meaning\nnot starting NAPI. Then veth_poll() change rx_notify_masked to false and\nstops NAPI. Before exiting veth_poll() will observe TXQ is stopped and wake\nit up."
},
{
"lang": "es",
"value": "En el kernel de Linux, se ha resuelto la siguiente vulnerabilidad:\n\nveth: manejo m\u00e1s robusto de la condici\u00f3n de carrera para evitar que la txq se atasque\n\nEl commit dc82a33297fc (\u0027veth: apply qdisc backpressure on full ptr_ring to reduce TX drops\u0027) introdujo una condici\u00f3n de carrera que puede llevar a una TXQ permanentemente estancada. Esto se observ\u00f3 en producci\u00f3n en sistemas ARM64 (Ampere Altra Max).\n\nLa condici\u00f3n de carrera ocurre en veth_xmit(). El productor observa un ptr_ring lleno y detiene la cola (netif_tx_stop_queue()). La l\u00f3gica condicional subsiguiente, destinada a reactivar la cola si el consumidor la acababa de vaciar (if (__ptr_ring_empty(...)) netif_tx_wake_queue()), puede fallar. Esto lleva a un \u0027despertar perdido\u0027 (lost wakeup) donde la TXQ permanece detenida (QUEUE_STATE_DRV_XOFF) y el tr\u00e1fico se detiene.\n\nEste fallo es causado por un uso incorrecto de la API __ptr_ring_empty() desde el lado del productor. Como se se\u00f1ala en los comentarios del kernel, no se garantiza que esta comprobaci\u00f3n sea correcta si un consumidor est\u00e1 operando en otra CPU. La prueba de vac\u00edo se basa en ptr_ring -\u003e consumer_head, lo que la hace fiable solo para el consumidor. Usar esta comprobaci\u00f3n desde el lado del productor es fundamentalmente propenso a condiciones de carrera.\n\nEste parche corrige la condici\u00f3n de carrera adoptando la l\u00f3gica m\u00e1s robusta de una versi\u00f3n anterior V4 del conjunto de parches, que siempre vaciaba el par:\n\n(1) En veth_xmit(), se eliminan la l\u00f3gica de activaci\u00f3n condicional propensa a condiciones de carrera y su barrera de memoria. En su lugar, despu\u00e9s de detener la cola, llamamos incondicionalmente a __veth_xdp_flush(rq). Esto garantiza que el consumidor NAPI sea programado, haci\u00e9ndolo el \u00fanico responsable de reactivar la TXQ.\nEsto maneja la condici\u00f3n de carrera donde veth_poll() consume todos los paquetes y completa NAPI antes de que veth_xmit() en el lado del productor haya llamado a netif_tx_stop_queue. La llamada a __veth_xdp_flush(rq) observar\u00e1 que rx_notify_masked es falso y programar\u00e1 NAPI.\n\n(2) En el lado del consumidor, la l\u00f3gica para activar la TXQ par se mueve de veth_xdp_rcv() y se coloca al final de la funci\u00f3n veth_poll(). Esta ubicaci\u00f3n es parte de la correcci\u00f3n de la condici\u00f3n de carrera, ya que la comprobaci\u00f3n netif_tx_queue_stopped() debe ocurrir despu\u00e9s de que rx_notify_masked se establezca potencialmente en falso durante la finalizaci\u00f3n de NAPI.\nEsto maneja la condici\u00f3n de carrera donde veth_poll() consume todos los paquetes, pero no ha terminado (rx_notify_masked sigue siendo verdadero). El productor veth_xmit() detiene la TXQ y __veth_xdp_flush(rq) observar\u00e1 que rx_notify_masked es verdadero, lo que significa no iniciar NAPI. Luego veth_poll() cambia rx_notify_masked a falso y detiene NAPI. Antes de salir, veth_poll() observar\u00e1 que la TXQ est\u00e1 detenida y la activar\u00e1."
}
],
"id": "CVE-2025-68232",
"lastModified": "2026-10-14T13:10:00.187",
"metrics": {
"cvssMetricV31": [
{
"cvssData": {
"attackComplexity": "LOW",
"attackVector": "NETWORK",
"availabilityImpact": "HIGH",
"baseScore": 7.5,
"baseSeverity": "HIGH",
"confidentialityImpact": "NONE",
"integrityImpact": "NONE",
"privilegesRequired": "NONE",
"scope": "UNCHANGED",
"userInteraction": "NONE",
"vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
"version": "3.1"
},
"exploitabilityScore": 3.9,
"impactScore": 3.6,
"source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
"type": "Secondary"
}
]
},
"published": "2025-12-16T14:15:57.633",
"references": [
{
"source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
"url": "https://git.kernel.org/stable/c/5442a9da69789741bfda39f34ee7f69552bf0c56"
},
{
"source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
"url": "https://git.kernel.org/stable/c/6c8a8b9257a660e622689e23c8fbad4ba2b561b9"
},
{
"source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
"url": "https://git.kernel.org/stable/c/dd419a3f2ebc18cc00bc32c57fd052d7a188b78b"
}
],
"sourceIdentifier": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
"vulnStatus": "Deferred"
}
Loading…
Loading…
Drag nodes to arrange them. Double-click a related vulnerability to open it, or a source to visit its link. The Physics button on the left tunes the layout and the simulation; the legend at the bottom left hides or shows nodes by kind and by sighting type.
Experimental. This forecast is provided for visualization only and may change without notice. Do not use it for operational decisions.
Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.
Sightings
| Author | Source | Type | Date | Other |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or observed by the user.
- Confirmed: The vulnerability has been validated from an analyst's perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
- Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
- Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
- Not confirmed: The user expressed doubt about the validity of the vulnerability.
- Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.
Vulnerability timeline
Sightings and recorded dates, grouped by day · UTC
Loading timeline…
Loading…
Loading…
The MITRE ATT&CK techniques below are AI-generated suggestions, inferred from the description of the
vulnerability by the CIRCL/vulnerability-attack-technique-classification-roberta-base
model, served locally by ML-Gateway.
They have not been verified by an analyst and are provided for guidance only.
The approach is described in our paper Mapping CVEs to MITRE ATT&CK Techniques: A Curated Gold-Set Classifier and the Limits of LLM-Assisted Label Expansion.
Browse all ATT&CK techniques and the vulnerabilities related to each.
The approach is described in our paper Mapping CVEs to MITRE ATT&CK Techniques: A Curated Gold-Set Classifier and the Limits of LLM-Assisted Label Expansion.
Browse all ATT&CK techniques and the vulnerabilities related to each.
Loading…
Related by attack behaviour
Vulnerabilities whose description is nearest to this one in the vector space of the CIRCL/vulnerability-attack-technique-biencoder model. This is a similarity search over the bi-encoder space (plain cosine), not a classification, and it has no measured accuracy.