Skip to content
This repository was archived by the owner on Nov 8, 2023. It is now read-only.

Commit cd072da

Browse files
Sean Christophersonsuryasaimadhu
authored andcommitted
x86/fault: Add a helper function to sanitize error code
vDSO exception fixup is a replacement for signals in limited situations. Signals and vDSO exception fixup need to provide similar information to userspace, including the hardware error code. That hardware error code needs to be sanitized. For instance, if userspace accesses a kernel address, the error code could indicate to userspace whether the address had a Present=1 PTE. That can leak information about the kernel layout to userspace, which is bad. The existing signal code does this sanitization, but fairly late in the signal process. The vDSO exception code runs before the sanitization happens. Move error code sanitization out of the signal code and into a helper. Call the helper in the signal code. Signed-off-by: Sean Christopherson <[email protected]> Signed-off-by: Jarkko Sakkinen <[email protected]> Signed-off-by: Borislav Petkov <[email protected]> Acked-by: Jethro Beekman <[email protected]> Link: https://lkml.kernel.org/r/[email protected]
1 parent 8382c66 commit cd072da

File tree

1 file changed

+14
-12
lines changed

1 file changed

+14
-12
lines changed

arch/x86/mm/fault.c

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -602,11 +602,9 @@ pgtable_bad(struct pt_regs *regs, unsigned long error_code,
602602
oops_end(flags, regs, sig);
603603
}
604604

605-
static void set_signal_archinfo(unsigned long address,
606-
unsigned long error_code)
605+
static void sanitize_error_code(unsigned long address,
606+
unsigned long *error_code)
607607
{
608-
struct task_struct *tsk = current;
609-
610608
/*
611609
* To avoid leaking information about the kernel page
612610
* table layout, pretend that user-mode accesses to
@@ -617,7 +615,13 @@ static void set_signal_archinfo(unsigned long address,
617615
* information and does not appear to cause any problems.
618616
*/
619617
if (address >= TASK_SIZE_MAX)
620-
error_code |= X86_PF_PROT;
618+
*error_code |= X86_PF_PROT;
619+
}
620+
621+
static void set_signal_archinfo(unsigned long address,
622+
unsigned long error_code)
623+
{
624+
struct task_struct *tsk = current;
621625

622626
tsk->thread.trap_nr = X86_TRAP_PF;
623627
tsk->thread.error_code = error_code | X86_PF_USER;
@@ -658,6 +662,8 @@ no_context(struct pt_regs *regs, unsigned long error_code,
658662
* faulting through the emulate_vsyscall() logic.
659663
*/
660664
if (current->thread.sig_on_uaccess_err && signal) {
665+
sanitize_error_code(address, &error_code);
666+
661667
set_signal_archinfo(address, error_code);
662668

663669
/* XXX: hwpoison faults will set the wrong code. */
@@ -806,13 +812,7 @@ __bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code,
806812
if (is_errata100(regs, address))
807813
return;
808814

809-
/*
810-
* To avoid leaking information about the kernel page table
811-
* layout, pretend that user-mode accesses to kernel addresses
812-
* are always protection faults.
813-
*/
814-
if (address >= TASK_SIZE_MAX)
815-
error_code |= X86_PF_PROT;
815+
sanitize_error_code(address, &error_code);
816816

817817
if (likely(show_unhandled_signals))
818818
show_signal_msg(regs, error_code, address, tsk);
@@ -931,6 +931,8 @@ do_sigbus(struct pt_regs *regs, unsigned long error_code, unsigned long address,
931931
if (is_prefetch(regs, error_code, address))
932932
return;
933933

934+
sanitize_error_code(address, &error_code);
935+
934936
set_signal_archinfo(address, error_code);
935937

936938
#ifdef CONFIG_MEMORY_FAILURE

0 commit comments

Comments
 (0)