From: Jan Beulich Subject: 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 --- v2: Add parentheses around the || expression. --- a/xen/common/grant_table.c +++ b/xen/common/grant_table.c @@ -1350,13 +1350,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)