commit
0fbcd8abf3375052cc7627cc53aba6f2eb189fbb upstream.
Mark arch_stack_walk() as noinstr instead of notrace and inline functions
called from arch_stack_walk() as __always_inline so that user does not
put any instrumentations on it, because this function can be used from
return_address() which is used by lockdep.
Without this, if the kernel built with CONFIG_LOCKDEP=y, just probing
arch_stack_walk() via <tracefs>/kprobe_events will crash the kernel on
arm64.
# echo p arch_stack_walk >> ${TRACEFS}/kprobe_events
# echo 1 > ${TRACEFS}/events/kprobes/enable
kprobes: Failed to recover from reentered kprobes.
kprobes: Dump kprobe:
.symbol_name = arch_stack_walk, .offset = 0, .addr = arch_stack_walk+0x0/0x1c0
------------[ cut here ]------------
kernel BUG at arch/arm64/kernel/probes/kprobes.c:241!
kprobes: Failed to recover from reentered kprobes.
kprobes: Dump kprobe:
.symbol_name = arch_stack_walk, .offset = 0, .addr = arch_stack_walk+0x0/0x1c0
------------[ cut here ]------------
kernel BUG at arch/arm64/kernel/probes/kprobes.c:241!
PREEMPT SMP
Modules linked in:
CPU: 0 PID: 17 Comm: migration/0 Tainted: G N 6.1.0-rc5+ #6
Hardware name: linux,dummy-virt (DT)
Stopper: 0x0 <- 0x0
pstate:
600003c5 (nZCv DAIF -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
pc : kprobe_breakpoint_handler+0x178/0x17c
lr : kprobe_breakpoint_handler+0x178/0x17c
sp :
ffff8000080d3090
x29:
ffff8000080d3090 x28:
ffff0df5845798c0 x27:
ffffc4f59057a774
x26:
ffff0df5ffbba770 x25:
ffff0df58f420f18 x24:
ffff49006f641000
x23:
ffffc4f590579768 x22:
ffff0df58f420f18 x21:
ffff8000080d31c0
x20:
ffffc4f590579768 x19:
ffffc4f590579770 x18:
0000000000000006
x17:
5f6b636174735f68 x16:
637261203d207264 x15:
64612e202c30203d
x14:
2074657366666f2e x13:
30633178302f3078 x12:
302b6b6c61775f6b
x11:
636174735f686372 x10:
ffffc4f590dc5bd8 x9 :
ffffc4f58eb31958
x8 :
00000000ffffefff x7 :
ffffc4f590dc5bd8 x6 :
80000000fffff000
x5 :
000000000000bff4 x4 :
0000000000000000 x3 :
0000000000000000
x2 :
0000000000000000 x1 :
ffff0df5845798c0 x0 :
0000000000000064
Call trace:
kprobes: Failed to recover from reentered kprobes.
kprobes: Dump kprobe:
.symbol_name = arch_stack_walk, .offset = 0, .addr = arch_stack_walk+0x0/0x1c0
------------[ cut here ]------------
kernel BUG at arch/arm64/kernel/probes/kprobes.c:241!
Fixes:
39ef362d2d45 ("arm64: Make return_address() use arch_stack_walk()")
Cc: stable@vger.kernel.org
Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Acked-by: Mark Rutland <mark.rutland@arm.com>
Link: https://lore.kernel.org/r/166994751368.439920.3236636557520824664.stgit@devnote3
Signed-off-by: Will Deacon <will@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
*
* The regs must be on a stack currently owned by the calling task.
*/
-static inline void unwind_init_from_regs(struct unwind_state *state,
- struct pt_regs *regs)
+static __always_inline void unwind_init_from_regs(struct unwind_state *state,
+ struct pt_regs *regs)
{
unwind_init_common(state, current);
* duration of the unwind, or the unwind will be bogus. It is never valid to
* call this for the current task.
*/
-static inline void unwind_init_from_task(struct unwind_state *state,
- struct task_struct *task)
+static __always_inline void unwind_init_from_task(struct unwind_state *state,
+ struct task_struct *task)
{
unwind_init_common(state, task);
: stackinfo_get_unknown(); \
})
-noinline notrace void arch_stack_walk(stack_trace_consume_fn consume_entry,
+noinline noinstr void arch_stack_walk(stack_trace_consume_fn consume_entry,
void *cookie, struct task_struct *task,
struct pt_regs *regs)
{