Re: [PATCH] powerpc/mm: Only read faulting instruction when necessary in do_page_fault()

From: Christophe LEROY
Date: Mon Apr 24 2017 - 06:26:41 EST




Le 24/04/2017 à 11:15, Michael Ellerman a écrit :
Christophe Leroy <christophe.leroy@xxxxxx> 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.

If the inst is NULL, store_updates_sp(inst) returns false so it jumps to bad_area_nosemaphore

Christophe


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