]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/4.19.34/arm64-debug-don-t-propagate-unknown-far-into-si_code-for-debug-signals.patch
Linux 4.14.111
[thirdparty/kernel/stable-queue.git] / releases / 4.19.34 / arm64-debug-don-t-propagate-unknown-far-into-si_code-for-debug-signals.patch
1 From b9a4b9d084d978f80eb9210727c81804588b42ff Mon Sep 17 00:00:00 2001
2 From: Will Deacon <will.deacon@arm.com>
3 Date: Fri, 1 Mar 2019 13:28:00 +0000
4 Subject: arm64: debug: Don't propagate UNKNOWN FAR into si_code for debug signals
5
6 From: Will Deacon <will.deacon@arm.com>
7
8 commit b9a4b9d084d978f80eb9210727c81804588b42ff upstream.
9
10 FAR_EL1 is UNKNOWN for all debug exceptions other than those caused by
11 taking a hardware watchpoint. Unfortunately, if a debug handler returns
12 a non-zero value, then we will propagate the UNKNOWN FAR value to
13 userspace via the si_addr field of the SIGTRAP siginfo_t.
14
15 Instead, let's set si_addr to take on the PC of the faulting instruction,
16 which we have available in the current pt_regs.
17
18 Cc: <stable@vger.kernel.org>
19 Reviewed-by: Mark Rutland <mark.rutland@arm.com>
20 Signed-off-by: Will Deacon <will.deacon@arm.com>
21 Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
22 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
23
24
25 ---
26 arch/arm64/mm/fault.c | 9 +++++----
27 1 file changed, 5 insertions(+), 4 deletions(-)
28
29 --- a/arch/arm64/mm/fault.c
30 +++ b/arch/arm64/mm/fault.c
31 @@ -827,11 +827,12 @@ void __init hook_debug_fault_code(int nr
32 debug_fault_info[nr].name = name;
33 }
34
35 -asmlinkage int __exception do_debug_exception(unsigned long addr,
36 +asmlinkage int __exception do_debug_exception(unsigned long addr_if_watchpoint,
37 unsigned int esr,
38 struct pt_regs *regs)
39 {
40 const struct fault_info *inf = debug_fault_info + DBG_ESR_EVT(esr);
41 + unsigned long pc = instruction_pointer(regs);
42 int rv;
43
44 /*
45 @@ -841,10 +842,10 @@ asmlinkage int __exception do_debug_exce
46 if (interrupts_enabled(regs))
47 trace_hardirqs_off();
48
49 - if (user_mode(regs) && instruction_pointer(regs) > TASK_SIZE)
50 + if (user_mode(regs) && pc > TASK_SIZE)
51 arm64_apply_bp_hardening();
52
53 - if (!inf->fn(addr, esr, regs)) {
54 + if (!inf->fn(addr_if_watchpoint, esr, regs)) {
55 rv = 1;
56 } else {
57 struct siginfo info;
58 @@ -853,7 +854,7 @@ asmlinkage int __exception do_debug_exce
59 info.si_signo = inf->sig;
60 info.si_errno = 0;
61 info.si_code = inf->code;
62 - info.si_addr = (void __user *)addr;
63 + info.si_addr = (void __user *)pc;
64 arm64_notify_die(inf->name, regs, &info, esr);
65 rv = 0;
66 }