Skip to content

Commit 5042d40

Browse files
amlutosuryasaimadhu
authored andcommitted
x86/fault: Bypass no_context() for implicit kernel faults from usermode
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
1 parent 2cc624b commit 5042d40

File tree

1 file changed

+32
-27
lines changed

1 file changed

+32
-27
lines changed

arch/x86/mm/fault.c

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -826,44 +826,49 @@ __bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code,
826826
{
827827
struct task_struct *tsk = current;
828828

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

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

843-
if (is_errata100(regs, address))
844-
return;
840+
/*
841+
* User mode accesses just cause a SIGSEGV.
842+
* It's possible to have interrupts off here:
843+
*/
844+
local_irq_enable();
845845

846-
sanitize_error_code(address, &error_code);
846+
/*
847+
* Valid to do another page fault here because this one came
848+
* from user space:
849+
*/
850+
if (is_prefetch(regs, error_code, address))
851+
return;
847852

848-
if (fixup_vdso_exception(regs, X86_TRAP_PF, error_code, address))
849-
return;
853+
if (is_errata100(regs, address))
854+
return;
850855

851-
if (likely(show_unhandled_signals))
852-
show_signal_msg(regs, error_code, address, tsk);
856+
sanitize_error_code(address, &error_code);
853857

854-
set_signal_archinfo(address, error_code);
858+
if (fixup_vdso_exception(regs, X86_TRAP_PF, error_code, address))
859+
return;
855860

856-
if (si_code == SEGV_PKUERR)
857-
force_sig_pkuerr((void __user *)address, pkey);
861+
if (likely(show_unhandled_signals))
862+
show_signal_msg(regs, error_code, address, tsk);
858863

859-
force_sig_fault(SIGSEGV, si_code, (void __user *)address);
864+
set_signal_archinfo(address, error_code);
860865

861-
local_irq_disable();
866+
if (si_code == SEGV_PKUERR)
867+
force_sig_pkuerr((void __user *)address, pkey);
862868

863-
return;
864-
}
869+
force_sig_fault(SIGSEGV, si_code, (void __user *)address);
865870

866-
no_context(regs, error_code, address, SIGSEGV, si_code);
871+
local_irq_disable();
867872
}
868873

869874
static noinline void

0 commit comments

Comments
 (0)