Received: by 2002:a05:6358:3188:b0:123:57c1:9b43 with SMTP id q8csp21602251rwd; Thu, 29 Jun 2023 19:27:39 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ7HdQnrEhJGq9BDmwUuwPJ80ur7xi2SdlZTH/DOPCyrThaBSUc5f0p95tfcrf+X1lgHGf+l X-Received: by 2002:a05:6808:1250:b0:3a1:cb53:2c2f with SMTP id o16-20020a056808125000b003a1cb532c2fmr1369535oiv.17.1688092058998; Thu, 29 Jun 2023 19:27:38 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1688092058; cv=none; d=google.com; s=arc-20160816; b=ubfaB/YgBxjsMc+XF5T3U+1mMhqtfWD+VTlF/nNtLPKlLFjSGRWFAkw1NvPS6fuCO+ rwBcL1U3ctreloBjzd4G7gRWYSBXS/AxKl1S+SX2Srwq77h8WgQP5ZbjbRIP0AnL0v0M vNDdWNx0X6qu7I06m64UjpLyjgSLmhcu/GXuJwYIlTJffSe763T7JBZwnkJWGr9I0Awi D7bfVUVihGjgRFRuf74JYCqr+DzXPoXrMjpbtMpV+LjcPt2M8oSDQihFJcZZoZtIKwLW K6PudsevBFpP2Yvn4dNa2fLVJ2KkpEg2KFnTpKfWRlFKAqwZic397TkS7ZUMvlpzFNGo PFJw== 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=yRPIR8OJngukVvFLAvIbJSyD+0MLYQHDmnD9acgQdWo=; fh=DeOZnBVzccBoMVogqqE+VSj3e1SUhickwb1ol76d57s=; b=eIisNoTuqBe30bkxxfsw3VgCVZnXdXRy04h/ME9lSclU9+Dv5mcrDV1ewSMGM5MUix ms318L/rfVpX4r+uwdECUbSvbVlum5OFUPmqGWxuE/VVNGWhoicocpYzBxGau0TR/1YJ AA3vcbOBHdeEyIs+qDbSwdww29UH4dz747r5hVZRuouqj+CDo3bMMgrkadz/UBmWr4Bm T32PC5fQZCj9UfsP0ojd1Cm95CGH5awh9JmpDBDgVyJJg1EBQF3oiNATjBWt/YJQvUY2 KM5/Fl8LTtOvU6MgyKNr7QtaVjKxPRqrt2URkMP0fEvhK3l5osmDRIswUyL4VGLndUp9 UYJw== 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 t23-20020a634617000000b005576fecf094si11726506pga.2.2023.06.29.19.27.23; Thu, 29 Jun 2023 19:27:38 -0700 (PDT) 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 S231777AbjF3CJq (ORCPT + 99 others); Thu, 29 Jun 2023 22:09:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52926 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232079AbjF3CJm (ORCPT ); Thu, 29 Jun 2023 22:09:42 -0400 Received: from szxga08-in.huawei.com (szxga08-in.huawei.com [45.249.212.255]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E6B581BD3; Thu, 29 Jun 2023 19:09:36 -0700 (PDT) Received: from kwepemi500019.china.huawei.com (unknown [172.30.72.55]) by szxga08-in.huawei.com (SkyGuard) with ESMTP id 4Qsdzc12KWz1HCPZ; Fri, 30 Jun 2023 10:09:16 +0800 (CST) Received: from ubuntu1804.huawei.com (10.67.174.174) by kwepemi500019.china.huawei.com (7.221.188.117) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Fri, 30 Jun 2023 10:09:34 +0800 From: Li Huafei To: CC: , , , , , , , , , , , Subject: [PATCH 5.10] kprobes/x86: Fix kprobe debug exception handling logic Date: Fri, 30 Jun 2023 10:08:45 +0800 Message-ID: <20230630020845.227939-1-lihuafei1@huawei.com> X-Mailer: git-send-email 2.17.1 MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [10.67.174.174] X-ClientProxiedBy: dggems704-chm.china.huawei.com (10.3.19.181) To kwepemi500019.china.huawei.com (7.221.188.117) 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_SCC_BODY_TEXT_LINE 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 We get the following crash caused by a null pointer access: BUG: kernel NULL pointer dereference, address: 0000000000000000 ... RIP: 0010:resume_execution+0x35/0x190 ... Call Trace: <#DB> kprobe_debug_handler+0x41/0xd0 exc_debug+0xe5/0x1b0 asm_exc_debug+0x19/0x30 RIP: 0010:copy_from_kernel_nofault.part.0+0x55/0xc0 ... process_fetch_insn+0xfb/0x720 kprobe_trace_func+0x199/0x2c0 ? kernel_clone+0x5/0x2f0 kprobe_dispatcher+0x3d/0x60 aggr_pre_handler+0x40/0x80 ? kernel_clone+0x1/0x2f0 kprobe_ftrace_handler+0x82/0xf0 ? __se_sys_clone+0x65/0x90 ftrace_ops_assist_func+0x86/0x110 ? rcu_nocb_try_bypass+0x1f3/0x370 0xffffffffc07e60c8 ? kernel_clone+0x1/0x2f0 kernel_clone+0x5/0x2f0 The analysis reveals that kprobe and hardware breakpoints conflict in the use of debug exceptions. If we set a hardware breakpoint on a memory address and also have a kprobe event to fetch the memory at this address. Then when kprobe triggers, it goes to read the memory and triggers hardware breakpoint monitoring. This time, since kprobe handles debug exceptions earlier than hardware breakpoints, it will cause kprobe to incorrectly assume that the exception is a kprobe trigger. Notice that after the mainline commit 6256e668b7af ("x86/kprobes: Use int3 instead of debug trap for single-step"), kprobe no longer uses debug trap, avoiding the conflict with hardware breakpoints here. This commit is to remove the IRET that returns to kernel, not to fix the problem we have here. Also there are a bunch of merge conflicts when trying to apply this commit to older kernels, so fixing it directly in older kernels is probably a better option. If the debug exception is triggered by kprobe, then regs->ip should be located in the kprobe instruction slot. Add this check to kprobe_debug_handler() to properly determine if a debug exception should be handled by kprobe. The stable kernels affected are 5.10, 5.4, 4.19, and 4.14. I made the fix in 5.10, and we should probably apply this fix to other stable kernels. Signed-off-by: Li Huafei --- arch/x86/kernel/kprobes/core.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c index 5de757099186..fd8d7d128807 100644 --- a/arch/x86/kernel/kprobes/core.c +++ b/arch/x86/kernel/kprobes/core.c @@ -900,7 +900,14 @@ int kprobe_debug_handler(struct pt_regs *regs) struct kprobe *cur = kprobe_running(); struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); - if (!cur) + if (!cur || !cur->ainsn.insn) + return 0; + + /* regs->ip should be the address of next instruction to + * cur->ainsn.insn. + */ + if (regs->ip < (unsigned long)cur->ainsn.insn || + regs->ip - (unsigned long)cur->ainsn.insn > MAX_INSN_SIZE) return 0; resume_execution(cur, regs, kcb); -- 2.17.1