Received: by 2002:a25:7ec1:0:0:0:0:0 with SMTP id z184csp1098657ybc; Sat, 23 Nov 2019 15:10:12 -0800 (PST) X-Google-Smtp-Source: APXvYqwyPR/IwUSwOuHRG0d1b/yk4g7l0/rN740AZ2pfp96j1pYVk9u+NMD2VOyDItXAmfnlpvMz X-Received: by 2002:a17:906:5246:: with SMTP id y6mr29645480ejm.330.1574550611995; Sat, 23 Nov 2019 15:10:11 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1574550611; cv=none; d=google.com; s=arc-20160816; b=r44BChyuJ8O5r0XcbGsTnBASNLhdSX3VcxwTwFAS40EYr0ZsNE/SbNvqPJXAIskY4D ivnHqp91ys+2PXCeZgV/AyW5rHyT/j36MORsVGlhuItdtFItvlFk2NQCuvhMkcX24saI 9RtIct/zijjVFueISA5sET+0hLN0LAO5uhTQEgGldHXwtep3T4GvV8aGp9mDs+pwPq52 cS7wJnDwBhAX4KEZ8PP8LX+Q8yFfm53w/hmmmErl4hl+mRgEjCoUL8OTy0EDsD4a4fyb fhkPidJJSPnlZ822SnZHNJuoqmumZB9Gyn9lqErvXiP/4UoNmXOilBZdPHGnWA6+5Zb8 96Ug== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:dkim-signature; bh=Pu/8OX6HlfSaoPCzgUtGzljI+oHPoVje9Ch4WmQwZdE=; b=TDCc7VU7G721rx5EcVhLGItwNIJOyIm4MC2tWnXG4qCBbkj+1op+ap3ReVGq8TLv/I 4XOeX7ZD7k4LiynI4fKKGfrRfQb5pFIyhWyme3df8brDCVH1RV3M39Rc6Fmababrckro IMVbwsQWoxJAeOhZdoBYJrB7AWqyQhkt5HZBmDCbXwHwyFo5w7+riGtfpGiJllrv2G4L Getl5DtgHX0N6UXzjm9/1vRC5ZhOeD740QRPNNMMHOxX2cIehPUxDgD7IrqqozrFq8Le zpBT1FZxltJxdjITrju/0PbVdsEkCHC/5/D2FTTlUohv/MzG3TJrsSgDSP4xGw5WkY01 zQfw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=juPH+U2U; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id p20si1593299ejn.273.2019.11.23.15.09.48; Sat, 23 Nov 2019 15:10:11 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=juPH+U2U; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726910AbfKWXH7 (ORCPT + 99 others); Sat, 23 Nov 2019 18:07:59 -0500 Received: from mail.kernel.org ([198.145.29.99]:38834 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726759AbfKWXH6 (ORCPT ); Sat, 23 Nov 2019 18:07:58 -0500 Received: from mail-wm1-f45.google.com (mail-wm1-f45.google.com [209.85.128.45]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 0DEAB2070E for ; Sat, 23 Nov 2019 23:07:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1574550477; bh=hI60mFmeNURJlV87kKA4zetms7sVC99iKsf0b+qp8zE=; h=References:In-Reply-To:From:Date:Subject:To:Cc:From; b=juPH+U2Uf8cD96sbedsh5RHGozPsz/wQTjsRnuXOiZF9Sd55S4YKWLJsmHaBMOCo/ JCj9JwDu046Pc8JvaZr0WLvCpML6LLsTH49Rn1gjZspTdHPv7w8lSSSugW4mfY1s+O 0/qmYe3Ki7/hujOSiIjmM7HOeLTAdUUbjG2V0IjY= Received: by mail-wm1-f45.google.com with SMTP id b11so11316247wmb.5 for ; Sat, 23 Nov 2019 15:07:56 -0800 (PST) X-Gm-Message-State: APjAAAUD6qyJNqLbW3RQ1V1VL8oIvjQm6pKprAD0qgHykgWdEv47QUN2 bLLgbCNV96KhKskFPVY6kEAhkBA9ahbAzw2ZOqdmyw== X-Received: by 2002:a1c:1f8d:: with SMTP id f135mr11373714wmf.79.1574550475449; Sat, 23 Nov 2019 15:07:55 -0800 (PST) MIME-Version: 1.0 References: <20191115191728.87338-1-jannh@google.com> <20191115191728.87338-2-jannh@google.com> In-Reply-To: <20191115191728.87338-2-jannh@google.com> From: Andy Lutomirski Date: Sat, 23 Nov 2019 15:07:43 -0800 X-Gmail-Original-Message-ID: Message-ID: Subject: Re: [PATCH v2 2/3] x86/traps: Print non-canonical address on #GP To: Jann Horn Cc: Thomas Gleixner , Ingo Molnar , Borislav Petkov , "H. Peter Anvin" , X86 ML , Andrey Ryabinin , Alexander Potapenko , Dmitry Vyukov , kasan-dev , LKML , Andrey Konovalov , Andy Lutomirski , Sean Christopherson Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Fri, Nov 15, 2019 at 11:17 AM Jann Horn wrote: > > A frequent cause of #GP exceptions are memory accesses to non-canonical > addresses. Unlike #PF, #GP doesn't come with a fault address in CR2, so > the kernel doesn't currently print the fault address for #GP. > Luckily, we already have the necessary infrastructure for decoding X86 > instructions and computing the memory address that is being accessed; > hook it up to the #GP handler so that we can figure out whether the #GP > looks like it was caused by a non-canonical address, and if so, print > that address. > > While it is already possible to compute the faulting address manually by > disassembling the opcode dump and evaluating the instruction against the > register dump, this should make it slightly easier to identify crashes > at a glance. > > Signed-off-by: Jann Horn > --- > > Notes: > v2: > - print different message for segment-related GP (Borislav) > - rewrite check for non-canonical address (Sean) > - make it clear we don't know for sure why the GP happened (Andy) > > arch/x86/kernel/traps.c | 45 +++++++++++++++++++++++++++++++++++++++-- > 1 file changed, 43 insertions(+), 2 deletions(-) > > diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c > index c90312146da0..12d42697a18e 100644 > --- a/arch/x86/kernel/traps.c > +++ b/arch/x86/kernel/traps.c > @@ -56,6 +56,8 @@ > #include > #include > #include > +#include > +#include > > #ifdef CONFIG_X86_64 > #include > @@ -509,6 +511,38 @@ dotraplinkage void do_bounds(struct pt_regs *regs, long error_code) > do_trap(X86_TRAP_BR, SIGSEGV, "bounds", regs, error_code, 0, NULL); > } > > +/* > + * On 64-bit, if an uncaught #GP occurs while dereferencing a non-canonical > + * address, print that address. > + */ > +static void print_kernel_gp_address(struct pt_regs *regs) > +{ > +#ifdef CONFIG_X86_64 > + u8 insn_bytes[MAX_INSN_SIZE]; > + struct insn insn; > + unsigned long addr_ref; > + > + if (probe_kernel_read(insn_bytes, (void *)regs->ip, MAX_INSN_SIZE)) > + return; > + > + kernel_insn_init(&insn, insn_bytes, MAX_INSN_SIZE); > + insn_get_modrm(&insn); > + insn_get_sib(&insn); > + addr_ref = (unsigned long)insn_get_addr_ref(&insn, regs); > + > + /* Bail out if insn_get_addr_ref() failed or we got a kernel address. */ > + if (addr_ref >= ~__VIRTUAL_MASK) > + return; > + > + /* Bail out if the entire operand is in the canonical user half. */ > + if (addr_ref + insn.opnd_bytes - 1 <= __VIRTUAL_MASK) > + return; > + > + pr_alert("probably dereferencing non-canonical address 0x%016lx\n", > + addr_ref); > +#endif > +} Could you refactor this a little bit so that we end up with a helper that does the computation? Something like: int probe_insn_get_memory_ref(void **addr, size_t *len, void *insn_addr); returns 1 if there was a memory operand and fills in addr and len, returns 0 if there was no memory operand, and returns a negative error on error. I think we're going to want this for #AC handling, too :)