В ядре Linux устранена следующая уязвимость:
net/9p: исправлено состояние гонки в rdma->state в trans_rdma.c
Поле rdma->state изменяется без сохранения req_lock в обоих случаях.
Recv_done() и p9_cm_event_handler(), а rdma_request() обращается к
то же поле под спин-блокировкой req_lock. Эта непоследовательная блокировка
создает состояние гонки:
- Recv_done() работает в наборах контекстов завершения softirq
rdma->state = P9_RDMA_FLUSHING без получения req_lock
— p9_cm_event_handler() изменяет состояние rdma->state в нескольких точках
(ADDR_RESOLVED, ROUTE_RESOLVED, ESTABLISHED, CLOSED) без
req_lock
- rdma_request() использует spin_lock_irqsave(&rdma->req_lock, flags) для
защитить чтение-изменение-запись rdma->state
Гонка может привести к потере переходов между состояниями: Recv_done() или CM.
обработчик событий может установить состояние FLUSHING/CLOSED, пока rdma_request()
одновременно проверяет или изменяет состояние блокировки, что приводит к
переход FLUSHING молча заменяется переходом CLOSING. Это
повреждает конечный автомат соединения и может привести к использованию после освобождения
Объекты запроса RDMA во время удаления.
Исправьте это, добавив защиту req_lock ко всем изменениям rdma->state в
Recv_done() и p9_cm_event_handler(), уже соответствующие шаблону
используется в rdma_request(). Используйте spin_lock_irqsave/spin_unlock_irqrestore.
в обработчике событий CM, поскольку он может участвовать в гонках с помощью Recv_done(), который запускается
в контексте softirq. Протестировано с модулем ядра, который запускает два потока (имитируя
rdma_request и обработчик Recv_done/CM) в rdma->state с правильным
блокировка: 5,5 млн+ FLUSHING записывает более 27 млн итераций с потерей 0
переходы.
Показать оригинальное описание (EN)
In the Linux kernel, the following vulnerability has been resolved: net/9p: fix race condition on rdma->state in trans_rdma.c The rdma->state field is modified without holding req_lock in both recv_done() and p9_cm_event_handler(), while rdma_request() accesses the same field under the req_lock spinlock. This inconsistent locking creates a race condition: - recv_done() running in softirq completion context sets rdma->state = P9_RDMA_FLUSHING without acquiring req_lock - p9_cm_event_handler() modifies rdma->state at multiple points (ADDR_RESOLVED, ROUTE_RESOLVED, ESTABLISHED, CLOSED) without req_lock - rdma_request() uses spin_lock_irqsave(&rdma->req_lock, flags) to protect the read-modify-write of rdma->state The race can cause lost state transitions: recv_done() or the CM event handler could set state to FLUSHING/CLOSED while rdma_request() is concurrently checking or modifying state under the lock, leading to the FLUSHING transition being silently overwritten by CLOSING. This corrupts the connection state machine and can cause use-after-free on RDMA request objects during teardown. Fix by adding req_lock protection to all rdma->state modifications in recv_done() and p9_cm_event_handler(), matching the pattern already used in rdma_request(). Use spin_lock_irqsave/spin_unlock_irqrestore in the CM event handler since it can race with recv_done() which runs in softirq context. Tested with a kernel module that races two threads (simulating rdma_request and recv_done/CM handler) on rdma->state with proper locking: 5.5M+ FLUSHING writes over 27M iterations with 0 lost transitions.
Характеристики атаки
Последствия
Строка CVSS v3.1
Уязвимые продукты 12
| Конфигурация | От (включительно) | До (исключительно) |
|---|---|---|
|
Linux Linux_Kernel
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*
|
4.20
|
5.10.261
|
|
Linux Linux_Kernel
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*
|
4.20
|
5.15.212
|
|
Linux Linux_Kernel
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*
|
4.20
|
6.1.178
|
|
Linux Linux_Kernel
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*
|
4.20
|
6.6.145
|
|
Linux Linux_Kernel
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*
|
4.20
|
6.12.97
|
|
Linux Linux_Kernel
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*
|
4.20
|
6.18.40
|
|
Linux Linux_Kernel
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*
|
4.20
|
7.1.5
|
|
Linux Linux_Kernel
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*
|
4.20
|
7.2-rc1
|
|
Linux Linux_Kernel
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*
|
4.4.185
|
— |
|
Linux Linux_Kernel
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*
|
4.9.185
|
— |
|
Linux Linux_Kernel
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*
|
4.14.132
|
— |
|
Linux Linux_Kernel
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*
|
4.19.57
|
— |