Christophe Leroy <[email protected]> writes:

> diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
> index 400f2d0d42f8..3d506589236c 100644
> --- a/arch/powerpc/mm/fault.c
> +++ b/arch/powerpc/mm/fault.c
> @@ -356,8 +348,22 @@ int do_page_fault(struct pt_regs *regs, unsigned long 
> address,
>                * between the last mapped region and the stack will
>                * expand the stack rather than segfaulting.
>                */
> -             if (address + 2048 < uregs->gpr[1] && !store_updates_sp(inst))
> -                     goto bad_area;
> +             if (address + 2048 < uregs->gpr[1]) {
> +                     if (!inst) {

That looks like it could lead to an infinite loop, if the instruction
that caused the fault has been overwritten with NULL by another thread.

Or did I miss something? (I only read the diff)

> +                             /*
> +                              * We want to do this outside mmap_sem, because
> +                              * reading code around nip can result in fault,
> +                              * which will cause a deadlock when called with
> +                              * mmap_sem held
> +                              */
> +                             up_read(&mm->mmap_sem);
> +                             __get_user(inst,
> +                                        (unsigned int __user *)regs->nip);
> +                             if (!store_updates_sp(inst))
> +                                     goto bad_area_nosemaphore;
> +                             goto retry;
> +                     }


cheers

Reply via email to