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