xen/grant-table: Only decrement the refcounter when grant is fully unmapped
authorJulien Grall <jgrall@amazon.com>
Fri, 19 Nov 2021 11:27:47 +0000 (11:27 +0000)
committerJan Beulich <jbeulich@suse.com>
Tue, 25 Jan 2022 12:25:49 +0000 (13:25 +0100)
commit975a8fb45ca186b3476e5656c6ad5dad1122dbfd
tree936c159ea96fb08d3172456f41e4f0b524f1af2a
parenta428b913a002eb2b7425b48029c20a52eeee1b5a
xen/grant-table: Only decrement the refcounter when grant is fully unmapped

The grant unmapping hypercall (GNTTABOP_unmap_grant_ref) is not a
simple revert of the changes done by the grant mapping hypercall
(GNTTABOP_map_grant_ref).

Instead, it is possible to partially (or even not) clear some flags.
This will leave the grant is mapped until a future call where all
the flags would be cleared.

XSA-380 introduced a refcounting that is meant to only be dropped
when the grant is fully unmapped. Unfortunately, unmap_common() will
decrement the refcount for every successful call.

A consequence is a domain would be able to underflow the refcount
and trigger a BUG().

Looking at the code, it is not clear to me why a domain would
want to partially clear some flags in the grant-table. But as
this is part of the ABI, it is better to not change the behavior
for now.

Fix it by checking if the maptrack handle has been released before
decrementing the refcounting.

This is CVE-2022-23034 / XSA-394.

Fixes: 9781b51efde2 ("gnttab: replace mapkind()")
Signed-off-by: Julien Grall <jgrall@amazon.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
xen/common/grant_table.c