Skip to content

Commit d3ca587

Browse files
ozbenhmpe
authored andcommitted
powerpc/mm: Fix reporting of kernel execute faults
We currently test for is_exec and DSISR_PROTFAULT but that doesn't make sense as this is the wrong error bit to test for an execute permission failure. In fact, we had code that would return early if we had an exec fault in kernel mode so I think that was just dead code anyway. Finally the location of that test is awkward and prevents further simplifications. So instead move that test into a helper along with the existing early test for kernel exec faults and out of range accesses, and put it all in a "bad_kernel_fault()" helper. While at it test the correct error bits. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
1 parent 65d47fd commit d3ca587

File tree

1 file changed

+15
-6
lines changed

1 file changed

+15
-6
lines changed

arch/powerpc/mm/fault.c

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,20 @@ static int mm_fault_error(struct pt_regs *regs, unsigned long addr, int fault)
180180
return MM_FAULT_CONTINUE;
181181
}
182182

183+
/* Is this a bad kernel fault ? */
184+
static bool bad_kernel_fault(bool is_exec, unsigned long error_code,
185+
unsigned long address)
186+
{
187+
if (is_exec && (error_code & (DSISR_NOEXEC_OR_G | DSISR_KEYFAULT))) {
188+
printk_ratelimited(KERN_CRIT "kernel tried to execute"
189+
" exec-protected page (%lx) -"
190+
"exploit attempt? (uid: %d)\n",
191+
address, from_kuid(&init_user_ns,
192+
current_uid()));
193+
}
194+
return is_exec || (address >= TASK_SIZE);
195+
}
196+
183197
/*
184198
* Define the correct "is_write" bit in error_code based
185199
* on the processor family
@@ -252,7 +266,7 @@ static int __do_page_fault(struct pt_regs *regs, unsigned long address,
252266
* The kernel should never take an execute fault nor should it
253267
* take a page fault to a kernel address.
254268
*/
255-
if (!is_user && (is_exec || (address >= TASK_SIZE)))
269+
if (unlikely(!is_user && bad_kernel_fault(is_exec, error_code, address)))
256270
return SIGSEGV;
257271

258272
/* We restore the interrupt state now */
@@ -491,11 +505,6 @@ static int __do_page_fault(struct pt_regs *regs, unsigned long address,
491505
return 0;
492506
}
493507

494-
if (is_exec && (error_code & DSISR_PROTFAULT))
495-
printk_ratelimited(KERN_CRIT "kernel tried to execute NX-protected"
496-
" page (%lx) - exploit attempt? (uid: %d)\n",
497-
address, from_kuid(&init_user_ns, current_uid()));
498-
499508
return SIGSEGV;
500509
}
501510
NOKPROBE_SYMBOL(__do_page_fault);

0 commit comments

Comments
 (0)