Thank you for your contribution! Sashiko AI review found 2 potential issue(s) 
to consider:
- [High] KHO radix tree is accessed without initialization if KHO is disabled, 
leading to API misuse and potential crashes.
- [High] Concurrent memory withdrawal during kexec tree freeze causes memory 
corruption and use-after-free.
--

commit 9c3872dd668bb8911798d680d377645cc757d8e0
Author: Jork Loeser <[email protected]>

mshv: Use page tracker to manage MSHV-owned pages and preserve with KHO
    
This commit adapts MSHV page deposit and withdrawal paths to use a tracker,
and registers these pages with KHO to preserve them across kexecs.

> diff --git a/drivers/hv/mshv_page_preserve.c b/drivers/hv/mshv_page_preserve.c
> --- /dev/null
> +++ b/drivers/hv/mshv_page_preserve.c

[ ... ]

> +int __init mshv_preserve_init(void)
> +{
> +     int err;
> +
> +     if (!kho_is_enabled()) {
> +             pr_err("KHO is disabled; page deposits will fail.\n");
> +             return 0;
> +     }

[Severity: High]
If kho_is_enabled() returns false, this function returns 0 but sets no global
state to actually reject subsequent deposit requests. Does this mean
hv_call_deposit_pages() will proceed and unconditionally call
mshv_register_preserve_page(), leading to a crash when it tries to operate on
the uninitialized radix tree?

[ ... ]

> diff --git a/drivers/hv/mshv_root_hv_call.c b/drivers/hv/mshv_root_hv_call.c
> --- a/drivers/hv/mshv_root_hv_call.c
> +++ b/drivers/hv/mshv_root_hv_call.c

[ ... ]

> @@ -69,8 +69,16 @@ int hv_call_withdraw_memory(u64 count, int node, u64 
> partition_id)
>  
>               completed = hv_repcomp(status);
>  
> -             for (i = 0; i < completed; i++)
> -                     __free_page(pfn_to_page(output_page->gpa_page_list[i]));
> +             for (i = 0; i < completed; i++) {
> +                     struct page *pg = 
> pfn_to_page(output_page->gpa_page_list[i]);
> +                     int res = mshv_unregister_preserve_page(pg);
> +
> +                     WARN_ONCE(res, "Failed to unregister PFN %#llx\n",
> +                               output_page->gpa_page_list[i]);
> +
> +                     /* Free regardless -- HV has already released the page 
> */
> +                     __free_page(pg);
> +             }

[Severity: High]
Does this code introduce a use-after-free and memory corruption during kexec?

If the reboot notifier calls preserve_tree() and freezes the page tree,
mshv_unregister_preserve_page() will fail. However, the page is still freed
to the buddy allocator here. The concurrent preserve_tree() walk will then
visit this still-registered node and preserve the freed page, corrupting the
buddy allocator state.

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

Reply via email to