12 Jan, 2017

1 commit

  • Reported syzkaller:

    BUG: unable to handle kernel NULL pointer dereference at 0000000000000008
    IP: irq_bypass_unregister_consumer+0x9d/0xb70 [irqbypass]
    PGD 0

    Oops: 0002 [#1] SMP
    CPU: 1 PID: 125 Comm: kworker/1:1 Not tainted 4.9.0+ #1
    Workqueue: kvm-irqfd-cleanup irqfd_shutdown [kvm]
    task: ffff9bbe0dfbb900 task.stack: ffffb61802014000
    RIP: 0010:irq_bypass_unregister_consumer+0x9d/0xb70 [irqbypass]
    Call Trace:
    irqfd_shutdown+0x66/0xa0 [kvm]
    process_one_work+0x16b/0x480
    worker_thread+0x4b/0x500
    kthread+0x101/0x140
    ? process_one_work+0x480/0x480
    ? kthread_create_on_node+0x60/0x60
    ret_from_fork+0x25/0x30
    RIP: irq_bypass_unregister_consumer+0x9d/0xb70 [irqbypass] RSP: ffffb61802017e20
    CR2: 0000000000000008

    The syzkaller folks reported a NULL pointer dereference that due to
    unregister an consumer which fails registration before. The syzkaller
    creates two VMs w/ an equal eventfd occasionally. So the second VM
    fails to register an irqbypass consumer. It will make irqfd as inactive
    and queue an workqueue work to shutdown irqfd and unregister the irqbypass
    consumer when eventfd is closed. However, the second consumer has been
    initialized though it fails registration. So the token(same as the first
    VM's) is taken to unregister the consumer through the workqueue, the
    consumer of the first VM is found and unregistered, then NULL deref incurred
    in the path of deleting consumer from the consumers list.

    This patch fixes it by making irq_bypass_register/unregister_consumer()
    looks for the consumer entry based on consumer pointer itself instead of
    token matching.

    Reported-by: Dmitry Vyukov
    Suggested-by: Alex Williamson
    Cc: stable@vger.kernel.org
    Cc: Paolo Bonzini
    Cc: Radim Krčmář
    Cc: Dmitry Vyukov
    Cc: Alex Williamson
    Signed-off-by: Wanpeng Li
    Signed-off-by: Paolo Bonzini

    Wanpeng Li
     

12 May, 2016

1 commit


01 Oct, 2015

1 commit

  • When a physical I/O device is assigned to a virtual machine through
    facilities like VFIO and KVM, the interrupt for the device generally
    bounces through the host system before being injected into the VM.
    However, hardware technologies exist that often allow the host to be
    bypassed for some of these scenarios. Intel Posted Interrupts allow
    the specified physical edge interrupts to be directly injected into a
    guest when delivered to a physical processor while the vCPU is
    running. ARM IRQ Forwarding allows forwarded physical interrupts to
    be directly deactivated by the guest.

    The IRQ bypass manager here is meant to provide the shim to connect
    interrupt producers, generally the host physical device driver, with
    interrupt consumers, generally the hypervisor, in order to configure
    these bypass mechanism. To do this, we base the connection on a
    shared, opaque token. For KVM-VFIO this is expected to be an
    eventfd_ctx since this is the connection we already use to connect an
    eventfd to an irqfd on the in-kernel path. When a producer and
    consumer with matching tokens is found, callbacks via both registered
    participants allow the bypass facilities to be automatically enabled.

    Signed-off-by: Alex Williamson
    Reviewed-by: Eric Auger
    Tested-by: Eric Auger
    Tested-by: Feng Wu
    Signed-off-by: Feng Wu
    Signed-off-by: Paolo Bonzini

    Alex Williamson