From: Julien Grall Date: Mon, 18 Mar 2019 18:06:55 +0000 (+0000) Subject: xen/arm: mm: Protect Xen page-table update with a spinlock X-Git-Tag: archive/raspbian/4.14.0+80-gd101b417b7-1+rpi1^2~63^2~2051 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=36a1c7c213e13eb64d2c2d8aa9c5c805fe19020a;p=xen.git xen/arm: mm: Protect Xen page-table update with a spinlock The function create_xen_entries() may be called concurrently. For instance, while the vmap allocation is protected by a spinlock, the mapping is not. The implementation create_xen_entries() contains quite a few TOCTOU races such as when allocating the 3rd-level page-tables. Thankfully, they are pretty hard to reach as page-tables are allocated once and never released. Yet it is possible, so we need to protect with a spinlock to avoid corrupting the page-tables. Signed-off-by: Julien Grall Reviewed-by: Andrii Anisov Reviewed-by: Stefano Stabellini --- diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c index 7ed8400993..6d69d7abf4 100644 --- a/xen/arch/arm/mm.c +++ b/xen/arch/arm/mm.c @@ -939,6 +939,8 @@ enum xenmap_operation { RESERVE }; +static DEFINE_SPINLOCK(xen_pt_lock); + static int create_xen_entries(enum xenmap_operation op, unsigned long virt, mfn_t mfn, @@ -950,6 +952,8 @@ static int create_xen_entries(enum xenmap_operation op, lpae_t pte, *entry; lpae_t *third = NULL; + spin_lock(&xen_pt_lock); + for(; addr < addr_end; addr += PAGE_SIZE, mfn = mfn_add(mfn, 1)) { entry = &xen_second[second_linear_offset(addr)]; @@ -1024,6 +1028,8 @@ out: */ flush_xen_tlb_range_va(virt, PAGE_SIZE * nr_mfns); + spin_unlock(&xen_pt_lock); + return rc; }