В ядре Linux устранена следующая уязвимость:
RISC-V: KVM: исправлено переполнение размера массива информации о событиях PMU. SBI PMU EVENT_GET_INFO хранит контролируемые гостем num_events * sizeof(*einfo)
в 32-битном целом числе. На RV64 num_events = 0x10000001 составляет 0x100000010.
усекается до 16.
Затем KVM выделяет одну запись, но повторяет исходную
num_events, что приводит к выходу за пределы операций чтения и записи. Вложенный гость
сработало:
ОШИБКА: KASAN: плита выходит за пределы поля в kvm_riscv_vcpu_pmu_event_info+0xa4/0x142. Чтение размера 4 по адресу ff600000074d46b0 с помощью задачи init/1.
Отслеживание вызова:
[<ffffffff8006471c>] kvm_riscv_vcpu_pmu_event_info+0xa4/0x142
[<ffffffff800690c0>] kvm_sbi_ext_pmu_handler+0xca/0x268
[<ffffffff8006779e>] kvm_riscv_vcpu_sbi_ecall+0xec/0x1e6
[<ffffffff8006008c>] kvm_riscv_vcpu_exit+0x48c/0x540
[<ffffffff8005ea0a>] kvm_arch_vcpu_ioctl_run+0x37e/0xc80
Выделено по задаче 1:
__kmalloc_noprof+0x19e/0x4b0
kvm_riscv_vcpu_pmu_event_info+0x72/0x142
kvm_sbi_ext_pmu_handler+0xca/0x268
kvm_riscv_vcpu_sbi_ecall+0xec/0x1e6
kvm_riscv_vcpu_exit+0x48c/0x540
kvm_arch_vcpu_ioctl_run+0x37e/0xc80
Глючный адрес расположен в 0 байтах справа от
выделенная 16-байтовая область [ff600000074d46a0, ff600000074d46b0)
Сохраните размер общей памяти в size_t и отклоните переполнение умножения. Выделите гостевой массив с помощью GFP_KERNEL_ACCOUNT, чтобы с него взималась плата.
в kmemcg и используйте __GFP_NOWARN для подавления предупреждений об ошибках выделения. Используйте kvcalloc(), чтобы разрешить откат vmalloc и беззнаковый индекс длинного цикла.
чтобы соответствовать num_events.
Показать оригинальное описание (EN)
In the Linux kernel, the following vulnerability has been resolved: RISC-V: KVM: Fix PMU event info array size overflow SBI PMU EVENT_GET_INFO stores guest-controlled num_events * sizeof(*einfo) in a 32-bit integer. On RV64, num_events = 0x10000001 makes 0x100000010 truncate to 16. KVM then allocates one entry but loops over the original num_events, causing out-of-bounds reads and writes. A nested guest triggered: BUG: KASAN: slab-out-of-bounds in kvm_riscv_vcpu_pmu_event_info+0xa4/0x142 Read of size 4 at addr ff600000074d46b0 by task init/1 Call Trace: [<ffffffff8006471c>] kvm_riscv_vcpu_pmu_event_info+0xa4/0x142 [<ffffffff800690c0>] kvm_sbi_ext_pmu_handler+0xca/0x268 [<ffffffff8006779e>] kvm_riscv_vcpu_sbi_ecall+0xec/0x1e6 [<ffffffff8006008c>] kvm_riscv_vcpu_exit+0x48c/0x540 [<ffffffff8005ea0a>] kvm_arch_vcpu_ioctl_run+0x37e/0xc80 Allocated by task 1: __kmalloc_noprof+0x19e/0x4b0 kvm_riscv_vcpu_pmu_event_info+0x72/0x142 kvm_sbi_ext_pmu_handler+0xca/0x268 kvm_riscv_vcpu_sbi_ecall+0xec/0x1e6 kvm_riscv_vcpu_exit+0x48c/0x540 kvm_arch_vcpu_ioctl_run+0x37e/0xc80 The buggy address is located 0 bytes to the right of allocated 16-byte region [ff600000074d46a0, ff600000074d46b0) Store the shared-memory size in size_t and reject multiplication overflow. Allocate the guest-driven array with GFP_KERNEL_ACCOUNT so it is charged to kmemcg, and use __GFP_NOWARN to suppress allocation failure warnings. Use kvcalloc() to allow vmalloc fallback and an unsigned long loop index to match num_events.
Характеристики атаки
Последствия
Строка CVSS v3.1