В ядре Linux устранена следующая уязвимость:
virtio: rtc: удалить старые очереди виртуализации перед восстановлением
virtio_device_restore() сбрасывает устройство и восстанавливает согласованное состояние.
функции перед вызовом ->restore(). viortc_freeze() намеренно
оставляет существующие виртуальные очереди на месте, чтобы очередь тревог по-прежнему могла
пробуждает систему, но viortc_restore() немедленно вызывает
viortc_init_vqs() без предварительного удаления этих старых очередей. Если повторная инициализация очереди virtqueue завершается неудачей на virtio-pci, возникает ошибка транспорта.
путь может запускать vp_del_vqs() для недавно выделенного массива vp_dev->vqs
в то время как vdev->vqs все еще содержит старые виртуальные очереди. vp_del_vqs(), тогда
ищет состояние очереди через новый массив и может разыменовать NULL
информационный указатель в vp_del_vq(), приводящий к сбою гостевого ядра во время восстановления. Это также может произойти во время исправной повторной инициализации, когда один из
попытки vp_find_vqs_msix() оказались неудачными перед последующей попыткой
преуспеет.
Удалите устаревшие виртуальные очереди перед их восстановлением. Если восстановление не удалось
перед virtio_device_ready() повторно используйте путь удаления, чтобы остановить устройство. Как только устройство будет готово, верните ошибки напрямую, а не удаляйте
снова виртуальные очереди.
Показать оригинальное описание (EN)
In the Linux kernel, the following vulnerability has been resolved: virtio: rtc: tear down old virtqueues before restore virtio_device_restore() resets the device and restores the negotiated features before calling ->restore(). viortc_freeze() intentionally leaves the existing virtqueues in place so the alarm queue can still wake the system, but viortc_restore() immediately calls viortc_init_vqs() without first deleting those old queues. If virtqueue reinitialization fails on virtio-pci, the transport error path can run vp_del_vqs() against a newly allocated vp_dev->vqs array while vdev->vqs still contains the old virtqueues. vp_del_vqs() then looks up queue state through the new array and can dereference a NULL info pointer in vp_del_vq(), crashing the guest kernel during restore. This can also happen during a non-faulty reinitialization, when one of the vp_find_vqs_msix() attempts is unsuccessful before a later attempt would succeed. Delete the stale virtqueues before rebuilding them. If restore fails before virtio_device_ready(), reuse the remove path to stop the device. Once the device is ready, return errors directly instead of deleting the virtqueues again.
Характеристики атаки
Последствия
Строка CVSS v3.1