Skip to content

Commit

Permalink
x86/fault: Bypass no_context() for implicit kernel faults from usermode
Browse files Browse the repository at this point in the history
Drop an indentation level and remove the last user_mode(regs) == true
caller of no_context() by directly OOPSing for implicit kernel faults
from usermode.

Signed-off-by: Andy Lutomirski <[email protected]>
Signed-off-by: Borislav Petkov <[email protected]>
Link: https://lkml.kernel.org/r/6e3d1129494a8de1e59d28012286e3a292a2296e.1612924255.git.luto@kernel.org
  • Loading branch information
amluto authored and suryasaimadhu committed Feb 10, 2021
1 parent 2cc624b commit 5042d40
Showing 1 changed file with 32 additions and 27 deletions.
59 changes: 32 additions & 27 deletions arch/x86/mm/fault.c
Original file line number Diff line number Diff line change
Expand Up @@ -826,44 +826,49 @@ __bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code,
{
struct task_struct *tsk = current;

/* User mode accesses just cause a SIGSEGV */
if (user_mode(regs) && (error_code & X86_PF_USER)) {
/*
* It's possible to have interrupts off here:
*/
local_irq_enable();
if (!user_mode(regs)) {
no_context(regs, error_code, address, pkey, si_code);
return;
}

/*
* Valid to do another page fault here because this one came
* from user space:
*/
if (is_prefetch(regs, error_code, address))
return;
if (!(error_code & X86_PF_USER)) {
/* Implicit user access to kernel memory -- just oops */
page_fault_oops(regs, error_code, address);
return;
}

if (is_errata100(regs, address))
return;
/*
* User mode accesses just cause a SIGSEGV.
* It's possible to have interrupts off here:
*/
local_irq_enable();

sanitize_error_code(address, &error_code);
/*
* Valid to do another page fault here because this one came
* from user space:
*/
if (is_prefetch(regs, error_code, address))
return;

if (fixup_vdso_exception(regs, X86_TRAP_PF, error_code, address))
return;
if (is_errata100(regs, address))
return;

if (likely(show_unhandled_signals))
show_signal_msg(regs, error_code, address, tsk);
sanitize_error_code(address, &error_code);

set_signal_archinfo(address, error_code);
if (fixup_vdso_exception(regs, X86_TRAP_PF, error_code, address))
return;

if (si_code == SEGV_PKUERR)
force_sig_pkuerr((void __user *)address, pkey);
if (likely(show_unhandled_signals))
show_signal_msg(regs, error_code, address, tsk);

force_sig_fault(SIGSEGV, si_code, (void __user *)address);
set_signal_archinfo(address, error_code);

local_irq_disable();
if (si_code == SEGV_PKUERR)
force_sig_pkuerr((void __user *)address, pkey);

return;
}
force_sig_fault(SIGSEGV, si_code, (void __user *)address);

no_context(regs, error_code, address, SIGSEGV, si_code);
local_irq_disable();
}

static noinline void
Expand Down

0 comments on commit 5042d40

Please sign in to comment.