• Oleksandr Tyshchenko's avatar
    xen/arm: Fix race in RB-tree based P2M accounting · b75cd218
    Oleksandr Tyshchenko authored
    During the PV driver life cycle the mappings are added to
    the RB-tree by set_foreign_p2m_mapping(), which is called from
    gnttab_map_refs() and are removed by clear_foreign_p2m_mapping()
    which is called from gnttab_unmap_refs(). As both functions end
    up calling __set_phys_to_machine_multi() which updates the RB-tree,
    this function can be called concurrently.
    
    There is already a "p2m_lock" to protect against concurrent accesses,
    but the problem is that the first read of "phys_to_mach.rb_node"
    in __set_phys_to_machine_multi() is not covered by it, so this might
    lead to the incorrect mappings update (removing in our case) in RB-tree.
    
    In my environment the related issue happens rarely and only when
    PV net backend is running, the xen_add_phys_to_mach_entry() claims
    that it cannot add new pfn <-> mfn mapping to the tree since it is
    already exists which results in a failure when mapping foreign pages.
    
    But there might be other bad consequences related to the non-protected
    root reads such use-after-free, etc.
    
    While at it, also fix the similar usage in __pfn_to_mfn(), so
    initialize "struct rb_node *n" with the "p2m_lock" held in both
    functions to avoid possible bad consequences.
    
    This is CVE-2022-33744 / XSA-406.
    Signed-off-by: default avatarOleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
    Reviewed-by: default avatarStefano Stabellini <sstabellini@kernel.org>
    Signed-off-by: default avatarJuergen Gross <jgross@suse.com>
    b75cd218
p2m.c 4.94 KB