Received: by 2002:a05:6358:d09b:b0:dc:cd0c:909e with SMTP id jc27csp259584rwb; Thu, 1 Dec 2022 01:45:41 -0800 (PST) X-Google-Smtp-Source: AA0mqf53bZdjeDY2vu61IyhH1htGpJ1vY+Xb7yd94g2SrNdr3aW5rwTP6P4x1Xb71lS43nX7acd6 X-Received: by 2002:a17:907:d047:b0:7ba:530:223a with SMTP id vb7-20020a170907d04700b007ba0530223amr32989412ejc.215.1669887941635; Thu, 01 Dec 2022 01:45:41 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1669887941; cv=none; d=google.com; s=arc-20160816; b=hXCAf3FYivKgTB8ivjz7sE7MCGVqQBq7DkeD5jY5ZPaQLQOFXZUqSHMrdM5EVBl0Vz t/kafp4hMwT/Cus2PNGiDGP5qxngI4qvlpw2/gr1WLl1TOKRgegNL+pr6jNxu+CbPD4j 6vZ9EqgtsLCA4OBdVZw/MkwzC0V4CmlAbyirQpk873YYhQcBY2xsgurfoKbvKmga+ilg +BXMREikEL+sfttkdvi3dr/P2oNyK5zUhlb3k3fp3nyrxoOaYDUSwwKOnuV6AzBXtxQQ jDu7RO0Aj3w0QuMkub0J+0i8VcRIVL2p6HtZLnUaRaltlxEbD6iGwhevbfoAscjI9WVc pG5Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:mime-version:message-id:date:subject:cc:to:from; bh=Fuh9l78mG9+SIHFbin3SV+S/DkTfEeVowl8uXiLXLYk=; b=y1LDnIGyYN0eMFxLkAHdhtJrYeW+9YGAN4Ew0CWKnxp1fsEMShZJ2P3SFY/7JV6ZAS CllI3Ad+gzMzig6haBBlYmnRhWd4Dk0CyFjg8XZVl1agL+kGrGktq+yHroAlFcQUph95 GKBV1xBVDHJFzDqH6OxozF/3WS6/NN3zv9J/1pZ/eY4rRz2jnVRvWKScZYxhtBklSdgC xl+uEUv7F8u8hzSvCX61QLUuYyr2n9QzWXVCD2yZwNwDI16XUx9JAPdXL0FmajPZvjxv sfzGiXhdj+0gyx5JU4VF9++l3wgjEC9niqiEZXaR0ayu53VOeRyAlyAllDKzY3WeuOWL FqQg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=huawei.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id m14-20020a50ef0e000000b004678fd66f41si3246909eds.71.2022.12.01.01.45.21; Thu, 01 Dec 2022 01:45:41 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=huawei.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229775AbiLAI4Q (ORCPT + 82 others); Thu, 1 Dec 2022 03:56:16 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56438 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229452AbiLAI4P (ORCPT ); Thu, 1 Dec 2022 03:56:15 -0500 Received: from szxga01-in.huawei.com (szxga01-in.huawei.com [45.249.212.187]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 41BAD3D92D for ; Thu, 1 Dec 2022 00:56:13 -0800 (PST) Received: from dggpemm500020.china.huawei.com (unknown [172.30.72.56]) by szxga01-in.huawei.com (SkyGuard) with ESMTP id 4NN8zj1tt2zmWNl; Thu, 1 Dec 2022 16:55:29 +0800 (CST) Received: from dggpemm500013.china.huawei.com (7.185.36.172) by dggpemm500020.china.huawei.com (7.185.36.49) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.31; Thu, 1 Dec 2022 16:56:10 +0800 Received: from ubuntu1804.huawei.com (10.67.175.36) by dggpemm500013.china.huawei.com (7.185.36.172) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.31; Thu, 1 Dec 2022 16:56:10 +0800 From: Chen Zhongjin To: CC: , , , , , , , , Subject: [PATCH] x86/unwind/orc: Fix unwind ip when kprobes hits push/pop Date: Thu, 1 Dec 2022 16:53:11 +0800 Message-ID: <20221201085311.249883-1-chenzhongjin@huawei.com> X-Mailer: git-send-email 2.17.1 MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [10.67.175.36] X-ClientProxiedBy: dggems704-chm.china.huawei.com (10.3.19.181) To dggpemm500013.china.huawei.com (7.185.36.172) X-CFilter-Loop: Reflected X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_MED, SPF_HELO_NONE,SPF_PASS,T_FILL_THIS_FORM_SHORT autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org When unwind stack at asm_exc_int3, the orc type is UNWIND_HINT_TYPE_REGS and the unwinder will use pt_regs->ip to find next orc, which point to the probed insn + INT3_INSN_SIZE. If the probed insn is push/pop, it will point to the next insn which has different orc state. Before the probed insn has been really excuted in single step, using next insn ip to find orc will get a wrong unwinding result. So, when there is kprobe running and the previous op code is int3, state->signal should be false so that ip - 1 will be used to find next orc, until the probed push/pop has been single steped and kprobe set kprobe_status as KPROBE_HIT_SSDONE. Fixes: ee9f8fce9964 ("x86/unwind: Add the ORC unwinder") Signed-off-by: Chen Zhongjin --- dump_stack() in pre_handler probing push: Call Trace: dump_stack_lvl+0x79/0x9b push_handler_pre+0x1b/0x2e [kp_unwind] aggr_pre_handler+0xd8/0x180 ? opt_pre_handler+0x160/0x160 ? run_push+0xd/0x61 [kp_unwind] kprobe_int3_handler+0x3f3/0x530 do_int3+0x3b/0x80 exc_int3+0x2b/0x80 asm_exc_int3+0x35/0x40 RIP: 0010:run_push+0xd/0x61 [kp_unwind] RSP: 0018:ffff88800650f998 EFLAGS: 00000293 RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffffffffc0708060 RDX: ffff8880124b0000 RSI: 0000000000000000 RDI: ffffed1000ca1f28 RBP: 0000000000000000 R08: 0000000000000020 R09: ffffed1000ca1ef7 R10: ffff88800650f7b7 R11: ffffed1000ca1ef6 R12: ffffffffc0668000 R13: 0000000000000000 R14: fffffbfff80e14f8 R15: 1ffffffff80e14f9 ? 0xffffffffc0668000 ? run_push+0xb/0x61 [kp_unwind] ? run_push+0xd/0x61 [kp_unwind] ? kprobe_init+0x8a/0x1000 [kp_unwind] ? do_one_initcall+0xd0/0x4e0 ? trace_event_raw_event_initcall_level+0x1c0/0x1c0 ? rcu_read_lock_sched_held+0xa5/0xd0 ? rcu_read_lock_bh_held+0xc0/0xc0 ? __kmem_cache_alloc_node+0x1da/0x780 ? kasan_unpoison+0x23/0x50 ? 0xffffffffc0668000 ? do_init_module+0x1cc/0x6a0 ? load_module+0x5eee/0x7210 ? ext4_file_read_iter+0x161/0x3a0 ? module_frob_arch_sections+0x40/0x40 ? security_file_permission+0x408/0x600 ? security_kernel_post_read_file+0x93/0xc0 ? __do_sys_finit_module+0x13c/0x200 ? __do_sys_finit_module+0x13c/0x200 ? __ia32_sys_init_module+0xb0/0xb0 ? rcu_read_lock_bh_held+0xc0/0xc0 ? rcu_read_lock_bh_held+0xc0/0xc0 ? syscall_enter_from_user_mode+0x1d/0x50 ? syscall_enter_from_user_mode+0x1d/0x50 ? do_syscall_64+0x38/0x90 ? entry_SYSCALL_64_after_hwframe+0x63/0xcd After apply this patch, stack trace is correct: Call Trace: dump_stack_lvl+0x79/0x9b push_handler_post+0x1b/0x27 [kp_unwind] aggr_post_handler+0xdc/0x160 ? aggr_pre_handler+0x180/0x180 ? run_push+0xc/0x61 [kp_unwind] kprobe_post_process+0x7b/0x210 kprobe_int3_handler+0x307/0x530 ? 0xffffffffc0770000 ? 0xffffffffc0770002 do_int3+0x3b/0x80 exc_int3+0x2b/0x80 asm_exc_int3+0x35/0x40 RIP: 0010:run_push+0xd/0x61 [kp_unwind] RSP: 0018:ffff88801014f9a0 EFLAGS: 00000293 RAX: 0000000000000293 RBX: 0000000000000000 RCX: ffffffffc0760060 RDX: ffff88800d1f8000 RSI: 0000000000000000 RDI: ffffed1002029f28 RBP: 0000000000000000 R08: 0000000000000020 R09: ffffed1002029ef7 R10: ffff88801014f7b7 R11: ffffed1002029ef6 R12: ffffffffc0768000 R13: 0000000000000003 R14: fffffbfff80ec4f8 R15: 1ffffffff80ec4f9 ? 0xffffffffc0768000 ? run_push+0xb/0x61 [kp_unwind] ? 0xffffffffc0770002 kprobe_init+0x8a/0x1000 [kp_unwind] do_one_initcall+0xd0/0x4e0 ? trace_event_raw_event_initcall_level+0x1c0/0x1c0 ? rcu_read_lock_sched_held+0xa5/0xd0 ? rcu_read_lock_bh_held+0xc0/0xc0 ? __kmem_cache_alloc_node+0x1da/0x780 ? kasan_unpoison+0x23/0x50 ? 0xffffffffc0768000 do_init_module+0x1cc/0x6a0 load_module+0x5eee/0x7210 ? ext4_file_read_iter+0x161/0x3a0 ? module_frob_arch_sections+0x40/0x40 ? security_file_permission+0x408/0x600 ? security_kernel_post_read_file+0x93/0xc0 ? __do_sys_finit_module+0x13c/0x200 __do_sys_finit_module+0x13c/0x200 ? __ia32_sys_init_module+0xb0/0xb0 ? rcu_read_lock_bh_held+0xc0/0xc0 ? rcu_read_lock_bh_held+0xc0/0xc0 ? syscall_enter_from_user_mode+0x1d/0x50 ? syscall_enter_from_user_mode+0x1d/0x50 do_syscall_64+0x38/0x90 entry_SYSCALL_64_after_hwframe+0x63/0xcd RIP: 0033:0x7fe46ad1b839 --- arch/x86/kernel/unwind_orc.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/arch/x86/kernel/unwind_orc.c b/arch/x86/kernel/unwind_orc.c index c059820dfaea..81e74b7e7fda 100644 --- a/arch/x86/kernel/unwind_orc.c +++ b/arch/x86/kernel/unwind_orc.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -425,6 +426,7 @@ bool unwind_next_frame(struct unwind_state *state) enum stack_type prev_type = state->stack_info.type; struct orc_entry *orc; bool indirect = false; + u8 op; if (unwind_done(state)) return false; @@ -568,7 +570,21 @@ bool unwind_next_frame(struct unwind_state *state) state->regs = (struct pt_regs *)sp; state->prev_regs = NULL; state->full_regs = true; - state->signal = true; +#ifdef CONFIG_KPROBES + /* + * When kprobe replaces push/pop to int3, pt_regs->ip points to + * the next insn which has different orc state. + * Before push/pop is really excuted in single step, signal should + * be set to false so we will use ip - 1 to find correct next orc. + */ + if (kprobe_running() && + get_kprobe_ctlblk()->kprobe_status != KPROBE_HIT_SSDONE && + !get_kernel_nofault(op, (u8 *)state->ip - 1) && + op == INT3_INSN_OPCODE) + state->signal = false; + else +#endif + state->signal = true; break; case UNWIND_HINT_TYPE_REGS_PARTIAL: -- 2.17.1