function_graph: Fix the ret_stack used by ftrace_graph_ret_addr()
When ftrace_graph_ret_addr() is invoked to convert a found stack return
address to its original value, the function can end up producing the
following crash:
[ 95.442712] BUG: kernel NULL pointer dereference, address:
0000000000000028
[ 95.442720] #PF: supervisor read access in kernel mode
[ 95.442724] #PF: error_code(0x0000) - not-present page
[ 95.442727] PGD 0 P4D 0-
[ 95.442731] Oops: Oops: 0000 [#1] PREEMPT SMP PTI
[ 95.442736] CPU: 1 UID: 0 PID: 2214 Comm: insmod Kdump: loaded Tainted: G OE K 6.11.0-rc1-default #1
67c62a3b3720562f7e7db5f11c1fdb40b7a2857c
[ 95.442747] Tainted: [O]=OOT_MODULE, [E]=UNSIGNED_MODULE, [K]=LIVEPATCH
[ 95.442750] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS
rel-1.16.2-3-gd478f380-rebuilt.opensuse.org 04/01/2014
[ 95.442754] RIP: 0010:ftrace_graph_ret_addr+0x42/0xc0
[ 95.442766] Code: [...]
[ 95.442773] RSP: 0018:
ffff979b80ff7718 EFLAGS:
00010006
[ 95.442776] RAX:
ffffffff8ca99b10 RBX:
ffff979b80ff7760 RCX:
ffff979b80167dc0
[ 95.442780] RDX:
ffffffff8ca99b10 RSI:
ffff979b80ff7790 RDI:
0000000000000005
[ 95.442783] RBP:
0000000000000001 R08:
0000000000000005 R09:
0000000000000000
[ 95.442786] R10:
0000000000000005 R11:
0000000000000000 R12:
ffffffff8e9491e0
[ 95.442790] R13:
ffffffff8d6f70f0 R14:
ffff979b80167da8 R15:
ffff979b80167dc8
[ 95.442793] FS:
00007fbf83895740(0000) GS:
ffff8a0afdd00000(0000) knlGS:
0000000000000000
[ 95.442797] CS: 0010 DS: 0000 ES: 0000 CR0:
0000000080050033
[ 95.442800] CR2:
0000000000000028 CR3:
0000000005070002 CR4:
0000000000370ef0
[ 95.442806] DR0:
0000000000000000 DR1:
0000000000000000 DR2:
0000000000000000
[ 95.442809] DR3:
0000000000000000 DR6:
00000000fffe0ff0 DR7:
0000000000000400
[ 95.442816] Call Trace:
[ 95.442823] <TASK>
[ 95.442896] unwind_next_frame+0x20d/0x830
[ 95.442905] arch_stack_walk_reliable+0x94/0xe0
[ 95.442917] stack_trace_save_tsk_reliable+0x7d/0xe0
[ 95.442922] klp_check_and_switch_task+0x55/0x1a0
[ 95.442931] task_call_func+0xd3/0xe0
[ 95.442938] klp_try_switch_task.part.5+0x37/0x150
[ 95.442942] klp_try_complete_transition+0x79/0x2d0
[ 95.442947] klp_enable_patch+0x4db/0x890
[ 95.442960] do_one_initcall+0x41/0x2e0
[ 95.442968] do_init_module+0x60/0x220
[ 95.442975] load_module+0x1ebf/0x1fb0
[ 95.443004] init_module_from_file+0x88/0xc0
[ 95.443010] idempotent_init_module+0x190/0x240
[ 95.443015] __x64_sys_finit_module+0x5b/0xc0
[ 95.443019] do_syscall_64+0x74/0x160
[ 95.443232] entry_SYSCALL_64_after_hwframe+0x76/0x7e
[ 95.443236] RIP: 0033:0x7fbf82f2c709
[ 95.443241] Code: [...]
[ 95.443247] RSP: 002b:
00007fffd5ea3b88 EFLAGS:
00000246 ORIG_RAX:
0000000000000139
[ 95.443253] RAX:
ffffffffffffffda RBX:
000056359c48e750 RCX:
00007fbf82f2c709
[ 95.443257] RDX:
0000000000000000 RSI:
000056356ed4efc5 RDI:
0000000000000003
[ 95.443260] RBP:
000056356ed4efc5 R08:
0000000000000000 R09:
00007fffd5ea3c10
[ 95.443263] R10:
0000000000000003 R11:
0000000000000246 R12:
0000000000000000
[ 95.443267] R13:
000056359c48e6f0 R14:
0000000000000000 R15:
0000000000000000
[ 95.443272] </TASK>
[ 95.443274] Modules linked in: [...]
[ 95.443385] Unloaded tainted modules: intel_uncore_frequency(E):1 isst_if_common(E):1 skx_edac(E):1
[ 95.443414] CR2:
0000000000000028
The bug can be reproduced with kselftests:
cd linux/tools/testing/selftests
make TARGETS='ftrace livepatch'
(cd ftrace; ./ftracetest test.d/ftrace/fgraph-filter.tc)
(cd livepatch; ./test-livepatch.sh)
The problem is that ftrace_graph_ret_addr() is supposed to operate on the
ret_stack of a selected task but wrongly accesses the ret_stack of the
current task. Specifically, the above NULL dereference occurs when
task->curr_ret_stack is non-zero, but current->ret_stack is NULL.
Correct ftrace_graph_ret_addr() to work with the right ret_stack.
Cc: stable@vger.kernel.org
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Reported-by: Miroslav Benes <mbenes@suse.cz>
Link: https://lore.kernel.org/20240803131211.17255-1-petr.pavlu@suse.com
Fixes: 7aa1eaef9f42 ("function_graph: Allow multiple users to attach to function graph")
Signed-off-by: Petr Pavlu <petr.pavlu@suse.com>
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>