diff options
author | Marcel Ziswiler <marcel.ziswiler@toradex.com> | 2020-05-21 00:54:36 +0200 |
---|---|---|
committer | Marcel Ziswiler <marcel.ziswiler@toradex.com> | 2020-05-21 00:54:36 +0200 |
commit | 135d39dcedcedd1f44ea0bba52f15ac5922c114f (patch) | |
tree | 12379fc8ef7489eaca1c7245f8bd6af74c619a8f /arch/x86/kernel/unwind_frame.c | |
parent | 187764bd111b27783b6d68ffb3b3dbb3a9bafd38 (diff) | |
parent | 1279cd128bba968ebe0a2df7f7ae38bae90250ef (diff) |
Merge remote-tracking branch 'remotes/fslc/4.9-2.3.x-imx' into toradex_4.9-2.3.x-imx-next
Conflicts:
sound/soc/codecs/sgtl5000.c
sound/soc/fsl/imx-sgtl5000.c
Diffstat (limited to 'arch/x86/kernel/unwind_frame.c')
-rw-r--r-- | arch/x86/kernel/unwind_frame.c | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/arch/x86/kernel/unwind_frame.c b/arch/x86/kernel/unwind_frame.c index a2456d4d286a..9b8b3cb2e934 100644 --- a/arch/x86/kernel/unwind_frame.c +++ b/arch/x86/kernel/unwind_frame.c @@ -6,6 +6,21 @@ #define FRAME_HEADER_SIZE (sizeof(long) * 2) +/* + * This disables KASAN checking when reading a value from another task's stack, + * since the other task could be running on another CPU and could have poisoned + * the stack in the meantime. + */ +#define READ_ONCE_TASK_STACK(task, x) \ +({ \ + unsigned long val; \ + if (task == current) \ + val = READ_ONCE(x); \ + else \ + val = READ_ONCE_NOCHECK(x); \ + val; \ +}) + unsigned long unwind_get_return_address(struct unwind_state *state) { unsigned long addr; @@ -14,7 +29,8 @@ unsigned long unwind_get_return_address(struct unwind_state *state) if (unwind_done(state)) return 0; - addr = ftrace_graph_ret_addr(state->task, &state->graph_idx, *addr_p, + addr = READ_ONCE_TASK_STACK(state->task, *addr_p); + addr = ftrace_graph_ret_addr(state->task, &state->graph_idx, addr, addr_p); return __kernel_text_address(addr) ? addr : 0; @@ -48,7 +64,7 @@ bool unwind_next_frame(struct unwind_state *state) if (unwind_done(state)) return false; - next_bp = (unsigned long *)*state->bp; + next_bp = (unsigned long *)READ_ONCE_TASK_STACK(state->task,*state->bp); /* make sure the next frame's data is accessible */ if (!update_stack_state(state, next_bp, FRAME_HEADER_SIZE)) |