Restoring corrupted ITS tables could lead to a misbehaving ITS, and possibly a failed ITS save as the save performs more checks than the restore. Add sanity checks when restoring DTEs and ITEs. Signed-off-by: Ricardo Koller <ricarkol@xxxxxxxxxx> --- arch/arm64/kvm/vgic/vgic-its.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/arch/arm64/kvm/vgic/vgic-its.c b/arch/arm64/kvm/vgic/vgic-its.c index d7c1a3a01af4..dfd73fa1ed43 100644 --- a/arch/arm64/kvm/vgic/vgic-its.c +++ b/arch/arm64/kvm/vgic/vgic-its.c @@ -2209,6 +2209,12 @@ static int vgic_its_restore_ite(struct vgic_its *its, u32 event_id, if (!collection) return -EINVAL; + if (find_ite(its, dev->device_id, event_id)) + return -EINVAL; + + if (!vgic_its_check_ite(its, dev, event_id)) + return -EINVAL; + ite = vgic_its_alloc_ite(dev, collection, event_id); if (IS_ERR(ite)) return PTR_ERR(ite); @@ -2330,6 +2336,7 @@ static int vgic_its_restore_dte(struct vgic_its *its, u32 id, void *ptr, void *opaque) { struct its_device *dev; + u64 baser = its->baser_device_table; gpa_t itt_addr; u8 num_eventid_bits; u64 entry = *(u64 *)ptr; @@ -2350,6 +2357,12 @@ static int vgic_its_restore_dte(struct vgic_its *its, u32 id, /* dte entry is valid */ offset = (entry & KVM_ITS_DTE_NEXT_MASK) >> KVM_ITS_DTE_NEXT_SHIFT; + if (find_its_device(its, id)) + return -EINVAL; + + if (!vgic_its_check_id(its, baser, id, NULL)) + return -EINVAL; + dev = vgic_its_alloc_device(its, id, itt_addr, num_eventid_bits); if (IS_ERR(dev)) return PTR_ERR(dev); -- 2.36.0.rc2.479.g8af0fa9b8e-goog