From ce094f30df733c0909e7d1dc83c0eafbe089b75c Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Tue, 29 Sep 2026 17:06:37 +0100 Subject: [PATCH] gnttab: address fallout from XSA-501 A v1 -> v2 change isn't the only scenario where "status" may go stale in map_grant_ref(). Across a v2 -> v1 -> v2 change the status pages would have been freed and re-populated, possibly changing the pages used for the array. Check the pointer against the expected version-dependent value. This is XSA-517 / CVE-2026-79610. Fixes: 96dfeb41774a ("gnttab: cope with version changes racing other operations") Assisted-by: Claude Reported-by: Teddy Astie Signed-off-by: Jan Beulich Reviewed-by: Teddy Astie (cherry picked from commit e0a0823ee0a97f7e3c43dd7307b008eeb6120cbf) --- xen/common/grant_table.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c index 0a5c23ff1a..c0ca4f3057 100644 --- a/xen/common/grant_table.c +++ b/xen/common/grant_table.c @@ -1348,13 +1348,19 @@ map_grant_ref( grant_read_lock(rgt); - if ( unlikely(evaluate_nospec((rgt->gt_version == 1) != - (status == &shah->flags))) ) + /* + * After a v1 -> v2 change behind our backs "ref" may now be out of + * bounds. While after a v2 -> v1 -> v2 change "ref" would still be + * suitably bounded, the underlying status page may have moved. + */ + if ( evaluate_nospec(rgt->gt_version == 1 + ? status != &shah->flags + : (ref >= nr_grant_entries(rgt) || + status != &status_entry(rgt, ref))) ) { /* - * After a v1 -> v2 change behind our backs "ref" may now be out of - * bounds. Recalculate it, but only for reserved entries. Others - * will have been cleared anyway by the version change. + * Recalculate status, but only for reserved entries. Others will + * have been cleared anyway by the version change(s). */ if ( ref < GNTTAB_NR_RESERVED_ENTRIES ) status = evaluate_nospec(rgt->gt_version == 1)