[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[xen stable-4.15] xen/grant-table: Only decrement the refcounter when grant is fully unmapped



commit 2700abffa5e42cf04dc1c6eba73faaba670c99df
Author:     Julien Grall <jgrall@xxxxxxxxxx>
AuthorDate: Tue Jan 25 13:42:21 2022 +0100
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Tue Jan 25 13:42:21 2022 +0100

    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@xxxxxxxxxx>
    Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx>
    master commit: 975a8fb45ca186b3476e5656c6ad5dad1122dbfd
    master date: 2022-01-25 13:25:49 +0100
---
 xen/common/grant_table.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c
index e2fcb07e27..47b019c750 100644
--- a/xen/common/grant_table.c
+++ b/xen/common/grant_table.c
@@ -1499,8 +1499,15 @@ unmap_common(
     if ( put_handle )
         put_maptrack_handle(lgt, op->handle);
 
-    /* See the respective comment in map_grant_ref(). */
-    if ( rc == GNTST_okay && ld != rd && gnttab_need_iommu_mapping(ld) )
+    /*
+     * map_grant_ref() will only increment the refcount (and update the
+     * IOMMU) once per mapping. So we only want to decrement it once the
+     * maptrack handle has been put, alongside the further IOMMU update.
+     *
+     * For the second and third check, see the respective comment in
+     * map_grant_ref().
+     */
+    if ( put_handle && ld != rd && gnttab_need_iommu_mapping(ld) )
     {
         void **slot;
         union maptrack_node node;
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.15



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.