• Wen Yang's avatar
    eventfd: prevent underflow for eventfd semaphores · 758b4920
    Wen Yang authored
    For eventfd with flag EFD_SEMAPHORE, when its ctx->count is 0, calling
    eventfd_ctx_do_read will cause ctx->count to overflow to ULLONG_MAX.
    
    An underflow can happen with EFD_SEMAPHORE eventfds in at least the
    following three subsystems:
    
    (1) virt/kvm/eventfd.c
    (2) drivers/vfio/virqfd.c
    (3) drivers/virt/acrn/irqfd.c
    
    where (2) and (3) are just modeled after (1). An eventfd must be
    specified for use with the KVM_IRQFD ioctl(). This can also be an
    EFD_SEMAPHORE eventfd. When the eventfd count is zero or has been
    decremented to zero an underflow can be triggered when the irqfd is shut
    down by raising the KVM_IRQFD_FLAG_DEASSIGN flag in the KVM_IRQFD
    ioctl():
    
            // ctx->count == 0
            kvm_vm_ioctl()
            -> kvm_irqfd()
               -> kvm_irqfd_deassign()
                  -> irqfd_deactivate()
                     -> irqfd_shutdown()
                        -> eventfd_ctx_remove_wait_queue(&cnt)
                           -> eventfd_ctx_do_read(&cnt)
    
    Userspace polling on the eventfd wouldn't notice the underflow because 1
    is always returned as the value from eventfd_read() while ctx->count
    would've underflowed. It's not a huge deal because this should only be
    happening when the irqfd is shutdown but we should still fix it and
    avoid the spurious wakeup.
    
    Fixes: cb289d62 ("eventfd - allow atomic read and waitqueue remove")
    Signed-off-by: default avatarWen Yang <wenyang.linux@foxmail.com>
    Cc: Alexander Viro <viro@zeniv.linux.org.uk>
    Cc: Jens Axboe <axboe@kernel.dk>
    Cc: Christian Brauner <brauner@kernel.org>
    Cc: Christoph Hellwig <hch@lst.de>
    Cc: Dylan Yudaken <dylany@fb.com>
    Cc: David Woodhouse <dwmw@amazon.co.uk>
    Cc: Matthew Wilcox <willy@infradead.org>
    Cc: linux-fsdevel@vger.kernel.org
    Cc: linux-kernel@vger.kernel.org
    Message-Id: <tencent_7588DFD1F365950A757310D764517A14B306@qq.com>
    [brauner: rewrite commit message and add explanation how this underflow can happen]
    Signed-off-by: default avatarChristian Brauner <brauner@kernel.org>
    758b4920
eventfd.c 11.7 KB