[PATCH 3/3] KVM: arm64: vgic-its: Don't write past the end of the collection table
Fuad Tabba <[email protected]> Wed, 5 Aug 2026 10:38:28 +0100
| Newsgroups | dev.linux.lists.kvmarm,org.infradead.lists.linux-arm-kernel,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
vgic_its_save_collection_table() computes max_size but uses it only to
decide whether to append a terminator, leaving the walk over
its->collection_list unbounded. A guest that disables the ITS and
rewrites GITS_BASER with fewer pages, VALID still set, keeps every
collection it mapped against the larger table, because KVM stores the
new BASER unconditionally and frees the list only when VALID is
cleared. A save then writes up to 448K past the end of the table.
The writes stay in guest memory, as vgic_write_guest_lock() validates
every gfn, so the guest only corrupts itself. Stop at the boundary
regardless and return -EINVAL, which is what
vgic_its_save_device_tables() returns when a device falls outside its
own table. -ENOSPC describes the condition better, but -EINVAL is
already in the error set documented for KVM_DEV_ARM_VGIC_GRP_CTRL,
and -ENOSPC is not.
Fixes: ea1ad53e1e31a ("KVM: arm64: vgic-its: Collection table save/restore")
Signed-off-by: Fuad Tabba <[email protected]>
---
arch/arm64/kvm/vgic/vgic-its.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/arch/arm64/kvm/vgic/vgic-its.c b/arch/arm64/kvm/vgic/vgic-its.c
index ed281fbf008b9..c709fc5e17cda 100644
--- a/arch/arm64/kvm/vgic/vgic-its.c
+++ b/arch/arm64/kvm/vgic/vgic-its.c
@@ -2540,6 +2540,9 @@ static int vgic_its_save_collection_table(struct vgic_its *its)
max_size = GITS_BASER_NR_PAGES(baser) * SZ_64K;
list_for_each_entry(collection, &its->collection_list, coll_list) {
+ if (filled == max_size)
+ return -EINVAL;
+
ret = vgic_its_save_cte(its, collection, gpa);
if (ret)
return ret;
--
2.39.5