On 04/10/20 01:27, Suravee Suthikulpanit wrote: > The function amd_ir_set_vcpu_affinity makes use of the parameter struct > amd_iommu_pi_data.prev_ga_tag to determine if it should delete struct > amd_iommu_pi_data from a list when not running in AVIC mode. > > However, prev_ga_tag is initialized only when AVIC is enabled. The non-zero > uninitialized value can cause unintended code path, which ends up making > use of the struct vcpu_svm.ir_list and ir_list_lock without being > initialized (since they are intended only for the AVIC case). > > This triggers NULL pointer dereference bug in the function vm_ir_list_del > with the following call trace: > > svm_update_pi_irte+0x3c2/0x550 [kvm_amd] > ? proc_create_single_data+0x41/0x50 > kvm_arch_irq_bypass_add_producer+0x40/0x60 [kvm] > __connect+0x5f/0xb0 [irqbypass] > irq_bypass_register_producer+0xf8/0x120 [irqbypass] > vfio_msi_set_vector_signal+0x1de/0x2d0 [vfio_pci] > vfio_msi_set_block+0x77/0xe0 [vfio_pci] > vfio_pci_set_msi_trigger+0x25c/0x2f0 [vfio_pci] > vfio_pci_set_irqs_ioctl+0x88/0xb0 [vfio_pci] > vfio_pci_ioctl+0x2ea/0xed0 [vfio_pci] > ? alloc_file_pseudo+0xa5/0x100 > vfio_device_fops_unl_ioctl+0x26/0x30 [vfio] > ? vfio_device_fops_unl_ioctl+0x26/0x30 [vfio] > __x64_sys_ioctl+0x96/0xd0 > do_syscall_64+0x37/0x80 > entry_SYSCALL_64_after_hwframe+0x44/0xa9 > > Therefore, initialize prev_ga_tag to zero before use. This should be safe > because ga_tag value 0 is invalid (see function avic_vm_init). > > Fixes: dfa20099e26e ("KVM: SVM: Refactor AVIC vcpu initialization into avic_init_vcpu()") > Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@xxxxxxx> > --- > arch/x86/kvm/svm/avic.c | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c > index ac830cd50830..381d22daa4ac 100644 > --- a/arch/x86/kvm/svm/avic.c > +++ b/arch/x86/kvm/svm/avic.c > @@ -868,6 +868,7 @@ int svm_update_pi_irte(struct kvm *kvm, unsigned int host_irq, > * - Tell IOMMU to use legacy mode for this interrupt. > * - Retrieve ga_tag of prior interrupt remapping data. > */ > + pi.prev_ga_tag = 0; > pi.is_guest_mode = false; > ret = irq_set_vcpu_affinity(host_irq, &pi); > > Queued (with Cc: stable), thanks. Paolo