RE: [PATCH V2] x86/Hyper-V: Fix overflow issue in the fill_gva_list()

From: Michael Kelley
Date: Mon Sep 02 2019 - 10:40:34 EST


From: Tianyu Lan <Tianyu.Lan@xxxxxxxxxxxxx> Sent: Monday, September 2, 2019 5:42 AM
>
> When the 'start' parameter is >= 0xFF000000 on 32-bit
> systems, or >= 0xFFFFFFFF'FF000000 on 64-bit systems,
> fill_gva_list gets into an infinite loop. With such inputs,
> 'cur' overflows after adding HV_TLB_FLUSH_UNIT and always
> compares as less than end. Memory is filled with guest virtual
> addresses until the system crashes
>
> Fix this by never incrementing 'cur' to be larger than 'end'.
>
> Reported-by: Jong Hyun Park <park.jonghyun@xxxxxxxxxxxx>
> Signed-off-by: Tianyu Lan <Tianyu.Lan@xxxxxxxxxxxxx>
> Fixes: 2ffd9e33ce4a ("x86/hyper-v: Use hypercall for remote TLB flush")
> ---
> Change since v1:
> - Simply the commit message
>
> arch/x86/hyperv/mmu.c | 8 +++++---
> 1 file changed, 5 insertions(+), 3 deletions(-)
>
> diff --git a/arch/x86/hyperv/mmu.c b/arch/x86/hyperv/mmu.c
> index e65d7fe6489f..5208ba49c89a 100644
> --- a/arch/x86/hyperv/mmu.c
> +++ b/arch/x86/hyperv/mmu.c
> @@ -37,12 +37,14 @@ static inline int fill_gva_list(u64 gva_list[], int offset,
> * Lower 12 bits encode the number of additional
> * pages to flush (in addition to the 'cur' page).
> */
> - if (diff >= HV_TLB_FLUSH_UNIT)
> + if (diff >= HV_TLB_FLUSH_UNIT) {
> gva_list[gva_n] |= ~PAGE_MASK;
> - else if (diff)
> + cur += HV_TLB_FLUSH_UNIT;
> + } else if (diff) {
> gva_list[gva_n] |= (diff - 1) >> PAGE_SHIFT;
> + cur = end;
> + }
>
> - cur += HV_TLB_FLUSH_UNIT;
> gva_n++;
>
> } while (cur < end);
> --
> 2.14.5

Reviewed-by: Michael Kelley <mikelley@xxxxxxxxxxxxx>