mshv_vtl_hvcall_call() copies output_size bytes from a freshly allocated hypercall output page back to userspace. The page is currently allocated without __GFP_ZERO, so any bytes not written by the hypervisor are copied from stale page contents.
Allocate the output page zeroed before issuing the hypercall. Also check both bounce-page allocations before using them so memory pressure cannot turn the copy paths into NULL pointer dereferences. Signed-off-by: Yousef Alhouseen <[email protected]> --- drivers/hv/mshv_vtl_main.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/hv/mshv_vtl_main.c b/drivers/hv/mshv_vtl_main.c index 0d3d41619..0365d207c 100644 --- a/drivers/hv/mshv_vtl_main.c +++ b/drivers/hv/mshv_vtl_main.c @@ -1147,7 +1147,11 @@ static int mshv_vtl_hvcall_call(struct mshv_vtl_hvcall_fd *fd, * TODO: Take care of this when CVM support is added. */ in = (void *)__get_free_page(GFP_KERNEL); - out = (void *)__get_free_page(GFP_KERNEL); + out = (void *)__get_free_page(GFP_KERNEL | __GFP_ZERO); + if (!in || !out) { + ret = -ENOMEM; + goto free_pages; + } if (copy_from_user(in, (void __user *)hvcall.input_ptr, hvcall.input_size)) { ret = -EFAULT; @@ -1162,8 +1166,10 @@ static int mshv_vtl_hvcall_call(struct mshv_vtl_hvcall_fd *fd, } ret = put_user(hvcall.status, &hvcall_user->status); free_pages: - free_page((unsigned long)in); - free_page((unsigned long)out); + if (in) + free_page((unsigned long)in); + if (out) + free_page((unsigned long)out); return ret; } -- 2.54.0

