From: Sean Christopherson <sean.j.christopher...@intel.com>

Add helper function to sanitize error code to prepare for vDSO exception
fixup, which will expose the error code to userspace and runs before
set_signal_archinfo(), i.e. suppresses the signal when fixup is successful.

Acked-by: Jethro Beekman <jet...@fortanix.com>
Signed-off-by: Sean Christopherson <sean.j.christopher...@intel.com>
Signed-off-by: Jarkko Sakkinen <jarkko.sakki...@linux.intel.com>
---
 arch/x86/mm/fault.c | 24 +++++++++++++++++-------
 1 file changed, 17 insertions(+), 7 deletions(-)

diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index 1a7cc6d3281a..9e5ec861aba0 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -555,6 +555,18 @@ pgtable_bad(struct pt_regs *regs, unsigned long error_code,
        oops_end(flags, regs, sig);
 }
 
+static void sanitize_error_code(unsigned long address,
+                               unsigned long *error_code)
+{
+       /*
+        * To avoid leaking information about the kernel page
+        * table layout, pretend that user-mode accesses to
+        * kernel addresses are always protection faults.
+        */
+       if (address >= TASK_SIZE_MAX)
+               *error_code |= X86_PF_PROT;
+}
+
 static void set_signal_archinfo(unsigned long address,
                                unsigned long error_code)
 {
@@ -611,6 +623,8 @@ no_context(struct pt_regs *regs, unsigned long error_code,
                 * faulting through the emulate_vsyscall() logic.
                 */
                if (current->thread.sig_on_uaccess_err && signal) {
+                       sanitize_error_code(address, &error_code);
+
                        set_signal_archinfo(address, error_code);
 
                        /* XXX: hwpoison faults will set the wrong code. */
@@ -759,13 +773,7 @@ __bad_area_nosemaphore(struct pt_regs *regs, unsigned long 
error_code,
                if (is_errata100(regs, address))
                        return;
 
-               /*
-                * To avoid leaking information about the kernel page table
-                * layout, pretend that user-mode accesses to kernel addresses
-                * are always protection faults.
-                */
-               if (address >= TASK_SIZE_MAX)
-                       error_code |= X86_PF_PROT;
+               sanitize_error_code(address, &error_code);
 
                if (likely(show_unhandled_signals))
                        show_signal_msg(regs, error_code, address, tsk);
@@ -884,6 +892,8 @@ do_sigbus(struct pt_regs *regs, unsigned long error_code, 
unsigned long address,
        if (is_prefetch(regs, error_code, address))
                return;
 
+       sanitize_error_code(address, &error_code);
+
        set_signal_archinfo(address, error_code);
 
 #ifdef CONFIG_MEMORY_FAILURE
-- 
2.25.1

Reply via email to