Skip to content

Commit 2dea1d9

Browse files
rnavmpe
authored andcommitted
powerpc/uprobes: Implement arch_uretprobe_is_alive()
This helper is used to detect if a uprobe'd function has returned through a setjmp/longjmp, rather than branching to the LR that was updated previously by us. This fixes a SIGSEGV that gets generated when programs use setjmp/longjmp with uretprobes. We use the arm64 model (arch/arm64/kernel/probes/uprobes.c: arch_uretprobe_is_alive()) for detecting when stack frames have been removed from under us. Reference: https://marc.info/?l=linux-kernel&m=143748610330073 commit 7b868e4 ("uprobes/x86: Reimplement arch_uretprobe_is_alive()") commit db087ef ("uprobes/x86: Make arch_uretprobe_is_alive(RP_CHECK_CALL) more clever") Tested with the test program from: https://sourceware.org/git/gitweb.cgi?p=systemtap.git;a=blob;f=testsuite/systemtap.base/bz5274.c;hb=HEAD And this script: $ cat test.sh #!/bin/bash perf probe -x ./bz5274 -a bz5274_main_return=main%return perf probe -x ./bz5274 -a bz5274_funca_return=funca%return perf probe -x ./bz5274 -a bz5274_funcb_return=funcb%return perf probe -x ./bz5274 -a bz5274_funcc_return=funcc%return perf probe -x ./bz5274 -a bz5274_funcd_return=funcd%return perf record -e 'probe_bz5274:*' -aR ./bz5274 Reported-by: Gustavo Luiz Duarte <[email protected]> Reported-by: [email protected] Signed-off-by: Naveen N. Rao <[email protected]> Acked-by: Srikar Dronamraju <[email protected]> Signed-off-by: Michael Ellerman <[email protected]>
1 parent ec4189c commit 2dea1d9

File tree

1 file changed

+9
-0
lines changed

1 file changed

+9
-0
lines changed

arch/powerpc/kernel/uprobes.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,3 +205,12 @@ arch_uretprobe_hijack_return_addr(unsigned long trampoline_vaddr, struct pt_regs
205205

206206
return orig_ret_vaddr;
207207
}
208+
209+
bool arch_uretprobe_is_alive(struct return_instance *ret, enum rp_check ctx,
210+
struct pt_regs *regs)
211+
{
212+
if (ctx == RP_CHECK_CHAIN_CALL)
213+
return regs->gpr[1] <= ret->stack;
214+
else
215+
return regs->gpr[1] < ret->stack;
216+
}

0 commit comments

Comments
 (0)