From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-bl2nam02on0139.outbound.protection.outlook.com ([104.47.38.139]:41618 "EHLO NAM02-BL2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1031861AbeCAPXb (ORCPT ); Thu, 1 Mar 2018 10:23:31 -0500 From: Sasha Levin To: "stable@vger.kernel.org" , "stable-commits@vger.kernel.org" CC: Masami Hiramatsu , Jon Medhurst , Sasha Levin Subject: [added to the 4.1 stable tree] arm: kprobes: Fix the return address of multiple kretprobes Date: Thu, 1 Mar 2018 15:22:36 +0000 Message-ID: <20180301152116.1486-16-alexander.levin@microsoft.com> References: <20180301152116.1486-1-alexander.levin@microsoft.com> In-Reply-To: <20180301152116.1486-1-alexander.levin@microsoft.com> Content-Language: en-US Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Sender: stable-owner@vger.kernel.org List-ID: From: Masami Hiramatsu This patch has been added to the 4.1 stable tree. If you have any objections, please let us know. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D [ Upstream commit 06553175f585b52509c7df37d6f4a50aacb7b211 ] This is arm port of commit 737480a0d525 ("kprobes/x86: Fix the return address of multiple kretprobes"). Fix the return address of subsequent kretprobes when multiple kretprobes are set on the same function. For example: # cd /sys/kernel/debug/tracing # echo "r:event1 sys_symlink" > kprobe_events # echo "r:event2 sys_symlink" >> kprobe_events # echo 1 > events/kprobes/enable # ln -s /tmp/foo /tmp/bar (without this patch) # cat trace | grep -v ^# ln-82 [000] dn.2 68.446525: event1: (kretprobe_trampoli= ne+0x0/0x18 <- SyS_symlink) ln-82 [000] dn.2 68.447831: event2: (ret_fast_syscall+0= x0/0x1c <- SyS_symlink) (with this patch) # cat trace | grep -v ^# ln-81 [000] dn.1 39.463469: event1: (ret_fast_syscall+0= x0/0x1c <- SyS_symlink) ln-81 [000] dn.1 39.464701: event2: (ret_fast_syscall+0= x0/0x1c <- SyS_symlink) Signed-off-by: Masami Hiramatsu Cc: KUMANO Syuhei Signed-off-by: Jon Medhurst Signed-off-by: Sasha Levin --- arch/arm/probes/kprobes/core.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/arch/arm/probes/kprobes/core.c b/arch/arm/probes/kprobes/core.= c index a4ec240ee7ba..3eb018fa1a1f 100644 --- a/arch/arm/probes/kprobes/core.c +++ b/arch/arm/probes/kprobes/core.c @@ -433,6 +433,7 @@ static __used __kprobes void *trampoline_handler(struct= pt_regs *regs) struct hlist_node *tmp; unsigned long flags, orig_ret_address =3D 0; unsigned long trampoline_address =3D (unsigned long)&kretprobe_trampoline= ; + kprobe_opcode_t *correct_ret_addr =3D NULL; =20 INIT_HLIST_HEAD(&empty_rp); kretprobe_hash_lock(current, &head, &flags); @@ -455,14 +456,34 @@ static __used __kprobes void *trampoline_handler(stru= ct pt_regs *regs) /* another task is sharing our hash bucket */ continue; =20 + orig_ret_address =3D (unsigned long)ri->ret_addr; + + if (orig_ret_address !=3D trampoline_address) + /* + * This is the real return address. Any other + * instances associated with this task are for + * other calls deeper on the call stack + */ + break; + } + + kretprobe_assert(ri, orig_ret_address, trampoline_address); + + correct_ret_addr =3D ri->ret_addr; + hlist_for_each_entry_safe(ri, tmp, head, hlist) { + if (ri->task !=3D current) + /* another task is sharing our hash bucket */ + continue; + + orig_ret_address =3D (unsigned long)ri->ret_addr; if (ri->rp && ri->rp->handler) { __this_cpu_write(current_kprobe, &ri->rp->kp); get_kprobe_ctlblk()->kprobe_status =3D KPROBE_HIT_ACTIVE; + ri->ret_addr =3D correct_ret_addr; ri->rp->handler(ri, regs); __this_cpu_write(current_kprobe, NULL); } =20 - orig_ret_address =3D (unsigned long)ri->ret_addr; recycle_rp_inst(ri, &empty_rp); =20 if (orig_ret_address !=3D trampoline_address) @@ -474,7 +495,6 @@ static __used __kprobes void *trampoline_handler(struct= pt_regs *regs) break; } =20 - kretprobe_assert(ri, orig_ret_address, trampoline_address); kretprobe_hash_unlock(current, &flags); =20 hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) { --=20 2.14.1