Thank you for your contribution! Sashiko AI review found 1 potential issue(s) 
to consider:
- [Medium] x86/ioremap: KMSAN shadow/origin page leak in __ioremap_caller()
--

commit 17e6df6da515e9dac650cd6369fda70f312c2a6a
Author: Jason Andryuk <[email protected]>

x86/paravirt: Add ioremap_verify_range hook and implement it for Xen PV

This commit adds an ioremap_verify_range hook to pv_mmu_ops so 
__ioremap_caller() can verify that page table entries were actually mapped 
after ioremap_page_range(). On Xen PV, it walks the virtual address range with 
lookup_address() and fails if any PTE is not present, causing ioremap() to 
return NULL when Xen rejects mapping machine frames.

Link: 
https://lore.kernel.org/xen-devel/[email protected]/

> diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
> index 12c8180ca1ba7..6b45a7eef5934 100644
> --- a/arch/x86/mm/ioremap.c
> +++ b/arch/x86/mm/ioremap.c
> @@ -301,6 +301,9 @@ __ioremap_caller(resource_size_t phys_addr, unsigned long 
> size,
>       if (ioremap_page_range(vaddr, vaddr + size, phys_addr, prot))
>               goto err_free_area;
>  
> +     if (ioremap_verify_range(vaddr, size))
> +             goto err_free_area;

[Severity: Medium]
When CONFIG_KMSAN=y is enabled, can failing ioremap_verify_range() in
__ioremap_caller() leak the KMSAN shadow and origin pages allocated by
ioremap_page_range()?

In ioremap_page_range() -> vmap_page_range(), kmsan_ioremap_page_range()
allocates and maps order-1 shadow and origin pages (which are normal guest
RAM and succeed on Xen PV even when Xen refuses the MMIO PTEs):

mm/vmalloc.c:vmap_page_range() {
        err = vmap_range_noflush(addr, end, phys_addr, pgprot_nx(prot),
                                 ioremap_max_page_shift);
        flush_cache_vmap(addr, end);
        if (!err)
                err = kmsan_ioremap_page_range(addr, end, phys_addr, prot,
                                               ioremap_max_page_shift);
        return err;
}

When ioremap_verify_range() subsequently fails and jumps to err_free_area,
free_vm_area(area) calls remove_vm_area() -> free_unmap_vmap_area() ->
vunmap_range_noflush() -> kmsan_vunmap_range_noflush(), which unmaps the
shadow and origin PTEs without freeing the underlying pages.

In contrast, iounmap() in arch/x86/mm/ioremap.c explicitly calls
kmsan_iounmap_page_range() before remove_vm_area() so KMSAN can look up and
free the shadow and origin pages before their PTEs are cleared:

arch/x86/mm/ioremap.c:iounmap() {
        ...
        kmsan_iounmap_page_range((unsigned long)addr,
                (unsigned long)addr + get_vm_area_size(p));
        memtype_free(p->phys_addr, p->phys_addr + get_vm_area_size(p));

        /* Finally remove it */
        o = remove_vm_area((void __force *)addr);
        ...
}

Should the failure path after ioremap_page_range() call
kmsan_iounmap_page_range(vaddr, vaddr + size) before free_vm_area(area)?

-- 
Sashiko AI review ยท 
https://sashiko.dev/#/patchset/[email protected]?part=1

Reply via email to