On Wed, 18 Jul 2018, Jiang Biao wrote:

> pti_user_pagetable_walk_p4d() may return NULL, we should check the
> return value to avoid NULL pointer dereference. And add warning
> for fail allocation where NULL returned.
> 
> Signed-off-by: Jiang Biao <[email protected]>
> ---
>  arch/x86/mm/pti.c | 10 ++++++++--
>  1 file changed, 8 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/x86/mm/pti.c b/arch/x86/mm/pti.c
> index 4d418e7..5c33a16 100644
> --- a/arch/x86/mm/pti.c
> +++ b/arch/x86/mm/pti.c
> @@ -176,7 +176,7 @@ static p4d_t *pti_user_pagetable_walk_p4d(unsigned long 
> address)
>  
>       if (pgd_none(*pgd)) {
>               unsigned long new_p4d_page = __get_free_page(gfp);
> -             if (!new_p4d_page)
> +             if (WARN_ON(!new_p4d_page))

WARN_ON_ONCE() please

>                       return NULL;
>  
>               set_pgd(pgd, __pgd(_KERNPG_TABLE | __pa(new_p4d_page)));
> @@ -195,9 +195,12 @@ static p4d_t *pti_user_pagetable_walk_p4d(unsigned long 
> address)
>  static pmd_t *pti_user_pagetable_walk_pmd(unsigned long address)
>  {
>       gfp_t gfp = (GFP_KERNEL | __GFP_NOTRACK | __GFP_ZERO);
> -     p4d_t *p4d = pti_user_pagetable_walk_p4d(address);
>       pud_t *pud;
>  
> +     p4d_t *p4d = pti_user_pagetable_walk_p4d(address);

No. This really is not how it should be done.

        gfp_t gfp = (GFP_KERNEL | __GFP_NOTRACK | __GFP_ZERO);
-       p4d_t *p4d = pti_user_pagetable_walk_p4d(address);
+       p4d_t *p4d;
        pud_t *pud;

+       p4d = pti_user_pagetable_walk_p4d(address);
+       if (!p4d)
+               return NULL;

Ditto for patch 2/2.

>       BUILD_BUG_ON(p4d_large(*p4d) != 0);
>       if (p4d_none(*p4d)) {
>               unsigned long new_pud_page = __get_free_page(gfp);
> @@ -354,6 +357,9 @@ static void __init pti_clone_p4d(unsigned long addr)
>       pgd_t *kernel_pgd;
>  
>       user_p4d = pti_user_pagetable_walk_p4d(addr);
> +     if (!user_p4d)
> +             return; 
> +
>       kernel_pgd = pgd_offset_k(addr);
>       kernel_p4d = p4d_offset(kernel_pgd, addr);
>       *user_p4d = *kernel_p4d;

Aside of that the patch has trailing white space in 2 places. Please take
the patch and apply it to your git tree localy before submitting it.

Thanks,

        tglx

Reply via email to