• Marc Zyngier's avatar
    KVM: arm/arm64: vgic-its: Fix potential overrun in vgic_copy_lpi_list · 7d8b44c5
    Marc Zyngier authored
    vgic_copy_lpi_list() parses the LPI list and picks LPIs targeting
    a given vcpu. We allocate the array containing the intids before taking
    the lpi_list_lock, which means we can have an array size that is not
    equal to the number of LPIs.
    
    This is particularly obvious when looking at the path coming from
    vgic_enable_lpis, which is not a command, and thus can run in parallel
    with commands:
    
    vcpu 0:                                        vcpu 1:
    vgic_enable_lpis
      its_sync_lpi_pending_table
        vgic_copy_lpi_list
          intids = kmalloc_array(irq_count)
                                                   MAPI(lpi targeting vcpu 0)
          list_for_each_entry(lpi_list_head)
            intids[i++] = irq->intid;
    
    At that stage, we will happily overrun the intids array. Boo. An easy
    fix is is to break once the array is full. The MAPI command will update
    the config anyway, and we won't miss a thing. We also make sure that
    lpi_list_count is read exactly once, so that further updates of that
    value will not affect the array bound check.
    
    Cc: stable@vger.kernel.org
    Fixes: ccb1d791 ("KVM: arm64: vgic-its: Fix pending table sync")
    Reviewed-by: default avatarAndre Przywara <andre.przywara@arm.com>
    Reviewed-by: default avatarEric Auger <eric.auger@redhat.com>
    Signed-off-by: default avatarMarc Zyngier <marc.zyngier@arm.com>
    7d8b44c5
vgic-its.c 64.5 KB