Vulnerability Change Records for CVE-2024-49993
Change History
CVE Modified by kernel.org 11/10/2024 5:15:04 AM
Action |
Type |
Old Value |
New Value |
Removed |
CPE Configuration |
OR
*cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* versions from (including) 5.16 from (excluding) 6.1.113
*cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* versions from (including) 5.11 from (excluding) 5.15.168
*cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* versions from (excluding) 5.10.227
*cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* versions from (including) 6.7 from (excluding) 6.10.14
*cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* versions from (including) 6.11 from (excluding) 6.11.3
*cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* versions from (including) 6.2 from (excluding) 6.6.55
|
|
Removed |
CVSS V3.1 |
NIST AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H
|
|
Removed |
CWE |
NIST CWE-667
|
|
Changed |
Description |
In the Linux kernel, the following vulnerability has been resolved:
iommu/vt-d: Fix potential lockup if qi_submit_sync called with 0 count
If qi_submit_sync() is invoked with 0 invalidation descriptors (for
instance, for DMA draining purposes), we can run into a bug where a
submitting thread fails to detect the completion of invalidation_wait.
Subsequently, this led to a soft lockup. Currently, there is no impact
by this bug on the existing users because no callers are submitting
invalidations with 0 descriptors. This fix will enable future users
(such as DMA drain) calling qi_submit_sync() with 0 count.
Suppose thread T1 invokes qi_submit_sync() with non-zero descriptors, while
concurrently, thread T2 calls qi_submit_sync() with zero descriptors. Both
threads then enter a while loop, waiting for their respective descriptors
to complete. T1 detects its completion (i.e., T1's invalidation_wait status
changes to QI_DONE by HW) and proceeds to call reclaim_free_desc() to
reclaim all descriptors, potentially including adjacent ones of other
threads that are also marked as QI_DONE.
During this time, while T2 is waiting to acquire the qi->q_lock, the IOMMU
hardware may complete the invalidation for T2, setting its status to
QI_DONE. However, if T1's execution of reclaim_free_desc() frees T2's
invalidation_wait descriptor and changes its status to QI_FREE, T2 will
not observe the QI_DONE status for its invalidation_wait and will
indefinitely remain stuck.
This soft lockup does not occur when only non-zero descriptors are
submitted.In such cases, invalidation descriptors are interspersed among
wait descriptors with the status QI_IN_USE, acting as barriers. These
barriers prevent the reclaim code from mistakenly freeing descriptors
belonging to other submitters.
Considered the following example timeline:
T1 T2
========================================
ID1
WD1
while(WD1!=QI_DONE)
unlock
lock
WD1=QI_DONE* WD2
while(WD2!=QI_DONE)
unlock
lock
WD1==QI_DONE?
ID1=QI_DONE WD2=DONE*
reclaim()
ID1=FREE
WD1=FREE
WD2=FREE
unlock
soft lockup! T2 never sees QI_DONE in WD2
Where:
ID = invalidation descriptor
WD = wait descriptor
* Written by hardware
The root of the problem is that the descriptor status QI_DONE flag is used
for two conflicting purposes:
1. signal a descriptor is ready for reclaim (to be freed)
2. signal by the hardware that a wait descriptor is complete
The solution (in this patch) is state separation by using QI_FREE flag
for #1.
Once a thread's invalidation descriptors are complete, their status would
be set to QI_FREE. The reclaim_free_desc() function would then only
free descriptors marked as QI_FREE instead of those marked as
QI_DONE. This change ensures that T2 (from the previous example) will
correctly observe the completion of its invalidation_wait (marked as
QI_DONE).
|
Rejected reason: This CVE ID has been rejected or withdrawn by its CVE Numbering Authority.
|
Removed |
Reference |
kernel.org https://git.kernel.org/stable/c/07e4e92f84b7d3018b7064ef8d8438aeb54a2ca5
|
|
Removed |
Reference |
kernel.org https://git.kernel.org/stable/c/3cf74230c139f208b7fb313ae0054386eee31a81
|
|
Removed |
Reference |
kernel.org https://git.kernel.org/stable/c/8840dc73ac9e1028291458ef1429ec3c2524ffec
|
|
Removed |
Reference |
kernel.org https://git.kernel.org/stable/c/92ba5b014d5435dd7a1ee02a2c7f2a0e8fe06c36
|
|
Removed |
Reference |
kernel.org https://git.kernel.org/stable/c/de9e7f68762585f7532de8a06de9485bf39dbd38
|
|
Removed |
Reference |
kernel.org https://git.kernel.org/stable/c/dfdbc5ba10fb792c9d6d12ba8cb6e465f97365ed
|
|
Removed |
Reference |
kernel.org https://git.kernel.org/stable/c/e03f00aa4a6c0c49c17857a4048f586636abdc32
|
|
CVE Rejected by kernel.org 11/10/2024 5:15:04 AM
Action |
Type |
Old Value |
New Value |
CVE Translated by kernel.org 11/10/2024 5:15:04 AM
Action |
Type |
Old Value |
New Value |
Removed |
Translation |
Title: kernel de Linux
Description: En el kernel de Linux, se ha resuelto la siguiente vulnerabilidad: iommu/vt-d: Se corrige el bloqueo potencial si se llama a qi_submit_sync con un recuento de 0 Si se invoca qi_submit_sync() con 0 descriptores de invalidación (por ejemplo, para fines de vaciado de DMA), podemos encontrarnos con un error en el que un hilo de envío no detecta la finalización de invalidation_wait. Posteriormente, esto condujo a un bloqueo suave. Actualmente, este error no tiene impacto en los usuarios existentes porque ningún llamante está enviando invalidaciones con 0 descriptores. Esta corrección permitirá a los futuros usuarios (como DMA drain) llamar a qi_submit_sync() con un recuento de 0. Supongamos que el hilo T1 invoca qi_submit_sync() con descriptores distintos de cero, mientras que, al mismo tiempo, el hilo T2 llama a qi_submit_sync() con cero descriptores. Ambos hilos entran entonces en un bucle while, esperando a que se completen sus respectivos descriptores. T1 detecta su finalización (es decir, el estado invalidation_wait de T1 cambia a QI_DONE por HW) y procede a llamar a reclaim_free_desc() para recuperar todos los descriptores, incluyendo potencialmente los adyacentes de otros subprocesos que también están marcados como QI_DONE. Durante este tiempo, mientras T2 espera adquirir el qi->q_lock, el hardware IOMMU puede completar la invalidación para T2, estableciendo su estado en QI_DONE. Sin embargo, si la ejecución de reclaim_free_desc() por parte de T1 libera el descriptor invalidation_wait de T2 y cambia su estado a QI_FREE, T2 no observará el estado QI_DONE para su invalidation_wait y permanecerá bloqueado indefinidamente. Este bloqueo suave no ocurre cuando solo se envían descriptores distintos de cero. En tales casos, los descriptores de invalidación se intercalan entre los descriptores de espera con el estado QI_IN_USE, actuando como barreras. Estas barreras evitan que el código de recuperación libere por error descriptores que pertenecen a otros remitentes. Considere la siguiente línea de tiempo de ejemplo: T1 T2 ========================================= ID1 WD1 while(WD1!=QI_DONE) unlock lock WD1=QI_DONE* WD2 while(WD2!=QI_DONE) unlock lock WD1==QI_DONE? ID1=QI_DONE WD2=DONE* reclaim() ID1=FREE WD1=FREE WD2=FREE unlock soft lockup! T2 nunca ve QI_DONE en WD2 Donde: ID = descriptor de invalidación WD = descriptor de espera * Escrito por hardware La raíz del problema es que el indicador de estado del descriptor QI_DONE se usa para dos propósitos conflictivos: 1. señalar que un descriptor está listo para ser recuperado (para ser liberado) 2. señalar por el hardware que un descriptor de espera está completo La solución (en este parche) es la separación de estados mediante el uso del indicador QI_FREE para #1. Una vez que los descriptores de invalidación de un hilo están completos, su estado se establecería en QI_FREE. La función reclaim_free_desc() solo liberaría los descriptores marcados como QI_FREE en lugar de los marcados como QI_DONE. Este cambio asegura que T2 (del ejemplo anterior) observará correctamente la finalización de su invalidation_wait (marcada como QI_DONE).
|
|
|