]> git.baikalelectronics.ru Git - kernel.git/commit
KVM: arm/arm64: vgic-its: Fix potential overrun in vgic_copy_lpi_list
authorMarc Zyngier <marc.zyngier@arm.com>
Fri, 23 Mar 2018 14:57:09 +0000 (14:57 +0000)
committerMarc Zyngier <marc.zyngier@arm.com>
Mon, 26 Mar 2018 09:56:49 +0000 (10:56 +0100)
commit1bbbb38235a9a8382e484f0a96de8bd6f1e9c8c3
tree07d535b275fd4e4d76660fc554d483382e98641a
parent5b0ec7dc8c5818fdf3d239fef218165970423ee8
KVM: arm/arm64: vgic-its: Fix potential overrun in vgic_copy_lpi_list

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: e2ab435a49ea ("KVM: arm64: vgic-its: Fix pending table sync")
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
virt/kvm/arm/vgic/vgic-its.c