Message ID | 20231025-delay-verw-v3-2-52663677ee35@linux.intel.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:d641:0:b0:403:3b70:6f57 with SMTP id cy1csp232344vqb; Wed, 25 Oct 2023 13:55:42 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFh3ECjZ5LahF+BzmUzqoT8EjAWZd+XIckjCxHN5aXJc5uDgerecQabQMRvdwoThFWO+Dci X-Received: by 2002:a81:6984:0:b0:5ac:fe2d:5edf with SMTP id e126-20020a816984000000b005acfe2d5edfmr7575422ywc.44.1698267342398; Wed, 25 Oct 2023 13:55:42 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1698267342; cv=none; d=google.com; s=arc-20160816; b=QTSx33jgI7qc3ucn9T9zr6GwyHic2lV7/caTalFtFLJ9BqjPItpVHc97Fiwisd9dRQ w7maGzvtIUHSfqUO3OnQoaa8Az3+A5J0P4kbtBVWV0rEbsp+U4YP5/YkeGD0Gp568eaZ l4EsvUBSl9wClrOeBFxOhUO7Fu71WEtZNo5PUlGMN03l48LY+1ZVDHZbiOB38NoAQeBt +tOJ9EAgfaciqmwOeVKFHjqLX7FT54IKx7tE8i+CwK8/FqUC0pXElxu3wKEKsXVigeJJ 6L58jwXUWqYytsBeowAiMn0zGTtoNa6ujIWTDKf/PdeUjytxpaHrnhvx7Xkub9UpyeSf 4flw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:in-reply-to:content-disposition:mime-version :references:message-id:subject:cc:to:from:date:dkim-signature; bh=JXW6ncWciaghnfyTdoACNbmv3XQBwz+zUjQClT1iM5A=; fh=pfRkWPzvKcXRDb8bzZOHP7Lfu+YA9O7iyInvCf011xY=; b=LQ3I7sdKsZ9WlcQTGCKrLR+67PhA8NACaKs9hl9YN5JJUw6PjUJRuht6uT33gcPNlZ Rlj3EmoF+xEqNVJSnavwDXZn/0KFgdmnM9R8qTNEKZSBZ32ujzppnNsPT9nE06kTWIay 3tf0NUw/YidRXkRUiRVHd7QgZS2fFa7DUmz3IvJAwsi/ZQJmEFsP3chI1xH/veZnMwKZ 3+eqLtJz42zzgqJ10Hy38ISdPzox1RuWUCpufmrQBDRQoBkOF+Vy8ajE60ZqSy3ippP3 W35cXfepdVKesysL081Da2MNmSSQ6xQygeRPdtU5T7WfGh2OHBfX2RcMwOfXakdfZKak S1NQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=O8hipnOI; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:7 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from snail.vger.email (snail.vger.email. [2620:137:e000::3:7]) by mx.google.com with ESMTPS id r8-20020a815d08000000b0059eb9ebb8d7si12757761ywb.383.2023.10.25.13.55.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 25 Oct 2023 13:55:42 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:7 as permitted sender) client-ip=2620:137:e000::3:7; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=O8hipnOI; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:7 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by snail.vger.email (Postfix) with ESMTP id 0A231806AFE4; Wed, 25 Oct 2023 13:53:30 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at snail.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234967AbjJYUxS (ORCPT <rfc822;a1648639935@gmail.com> + 25 others); Wed, 25 Oct 2023 16:53:18 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43854 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234816AbjJYUxH (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Wed, 25 Oct 2023 16:53:07 -0400 Received: from mgamail.intel.com (mgamail.intel.com [134.134.136.24]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 78DCB18B; Wed, 25 Oct 2023 13:53:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1698267184; x=1729803184; h=date:from:to:cc:subject:message-id:references: mime-version:in-reply-to; bh=KI9R1ykioS10T+zkw0Cw1ATpow7yvlFUWGh3i+Y0oPk=; b=O8hipnOIeYo9aSZqmLQaUd78Iv8mPL7gxnkozwNG5tpLu2jpSnt6AGk9 Gu/EazGF8lsjzQQKqIvnrHf6KXd66/h0rTEDa4QsEY8NCYVWUxEDK7Zgc ptUgtlmxDT7rQO5Dt4VKXfuBSzz6Iq3lHqgdcI3dFpZCK97qSMjkAy9sB yO/8DxTvatxcJLJ+nmvGEu6pbzDusJILFPcnpllLPmH3TJXXcFh/xzi+1 HPRgHVTL6iPd1wgsMz5oSh77ae8m1jmptnV3b6Tm/Ct7TI64kIm9HgTdc Y+j2r7FF26F0TPZ8wyr8U/P0uDGWXpqi3PCJGgwGp04Une6xdeo0JFC/v g==; X-IronPort-AV: E=McAfee;i="6600,9927,10874"; a="390255502" X-IronPort-AV: E=Sophos;i="6.03,250,1694761200"; d="scan'208";a="390255502" Received: from fmviesa002.fm.intel.com ([10.60.135.142]) by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 25 Oct 2023 13:53:01 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.03,250,1694761200"; d="scan'208";a="259627" Received: from kkomeyli-mobl.amr.corp.intel.com (HELO desk) ([10.251.29.139]) by fmviesa002-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 25 Oct 2023 13:52:50 -0700 Date: Wed, 25 Oct 2023 13:52:58 -0700 From: Pawan Gupta <pawan.kumar.gupta@linux.intel.com> To: Thomas Gleixner <tglx@linutronix.de>, Ingo Molnar <mingo@redhat.com>, Borislav Petkov <bp@alien8.de>, Dave Hansen <dave.hansen@linux.intel.com>, x86@kernel.org, "H. Peter Anvin" <hpa@zytor.com>, Peter Zijlstra <peterz@infradead.org>, Josh Poimboeuf <jpoimboe@kernel.org>, Andy Lutomirski <luto@kernel.org>, Jonathan Corbet <corbet@lwn.net>, Sean Christopherson <seanjc@google.com>, Paolo Bonzini <pbonzini@redhat.com>, tony.luck@intel.com, ak@linux.intel.com, tim.c.chen@linux.intel.com Cc: linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, kvm@vger.kernel.org, Alyssa Milburn <alyssa.milburn@linux.intel.com>, Daniel Sneddon <daniel.sneddon@linux.intel.com>, antonio.gomez.iglesias@linux.intel.com, Pawan Gupta <pawan.kumar.gupta@linux.intel.com>, Dave Hansen <dave.hansen@intel.com> Subject: [PATCH v3 2/6] x86/entry_64: Add VERW just before userspace transition Message-ID: <20231025-delay-verw-v3-2-52663677ee35@linux.intel.com> X-Mailer: b4 0.12.3 References: <20231025-delay-verw-v3-0-52663677ee35@linux.intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20231025-delay-verw-v3-0-52663677ee35@linux.intel.com> X-Spam-Status: No, score=-4.3 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_EF,RCVD_IN_DNSWL_MED, RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,SPF_NONE 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: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (snail.vger.email [0.0.0.0]); Wed, 25 Oct 2023 13:53:30 -0700 (PDT) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1780762377291195886 X-GMAIL-MSGID: 1780762377291195886 |
Series |
Delay VERW
|
|
Commit Message
Pawan Gupta
Oct. 25, 2023, 8:52 p.m. UTC
Mitigation for MDS is to use VERW instruction to clear any secrets in
CPU Buffers. Any memory accesses after VERW execution can still remain
in CPU buffers. It is safer to execute VERW late in return to user path
to minimize the window in which kernel data can end up in CPU buffers.
There are not many kernel secrets to be had after SWITCH_TO_USER_CR3.
Add support for deploying VERW mitigation after user register state is
restored. This helps minimize the chances of kernel data ending up into
CPU buffers after executing VERW.
Note that the mitigation at the new location is not yet enabled.
Corner case not handled
=======================
Interrupts returning to kernel don't clear CPUs buffers since the
exit-to-user path is expected to do that anyways. But, there could be
a case when an NMI is generated in kernel after the exit-to-user path
has cleared the buffers. This case is not handled and NMI returning to
kernel don't clear CPU buffers because:
1. It is rare to get an NMI after VERW, but before returning to userspace.
2. For an unprivileged user, there is no known way to make that NMI
less rare or target it.
3. It would take a large number of these precisely-timed NMIs to mount
an actual attack. There's presumably not enough bandwidth.
4. The NMI in question occurs after a VERW, i.e. when user state is
restored and most interesting data is already scrubbed. Whats left
is only the data that NMI touches, and that may or may not be of
any interest.
Suggested-by: Dave Hansen <dave.hansen@intel.com>
Signed-off-by: Pawan Gupta <pawan.kumar.gupta@linux.intel.com>
---
arch/x86/entry/entry_64.S | 11 +++++++++++
arch/x86/entry/entry_64_compat.S | 1 +
2 files changed, 12 insertions(+)
Comments
On 25.10.23 г. 23:52 ч., Pawan Gupta wrote: <snip> > @@ -1520,6 +1530,7 @@ SYM_CODE_START(ignore_sysret) > UNWIND_HINT_END_OF_STACK > ENDBR > mov $-ENOSYS, %eax > + CLEAR_CPU_BUFFERS nit: Just out of curiosity is it really needed in this case or it's doesn for the sake of uniformity so that all ring3 transitions are indeed covered?? > sysretl > SYM_CODE_END(ignore_sysret) > #endif > diff --git a/arch/x86/entry/entry_64_compat.S b/arch/x86/entry/entry_64_compat.S > index 70150298f8bd..245697eb8485 100644 > --- a/arch/x86/entry/entry_64_compat.S > +++ b/arch/x86/entry/entry_64_compat.S > @@ -271,6 +271,7 @@ SYM_INNER_LABEL(entry_SYSRETL_compat_unsafe_stack, SYM_L_GLOBAL) > xorl %r9d, %r9d > xorl %r10d, %r10d > swapgs > + CLEAR_CPU_BUFFERS > sysretl > SYM_INNER_LABEL(entry_SYSRETL_compat_end, SYM_L_GLOBAL) > ANNOTATE_NOENDBR >
On Thu, Oct 26, 2023 at 07:25:27PM +0300, Nikolay Borisov wrote: > > > On 25.10.23 г. 23:52 ч., Pawan Gupta wrote: > > <snip> > > > @@ -1520,6 +1530,7 @@ SYM_CODE_START(ignore_sysret) > > UNWIND_HINT_END_OF_STACK > > ENDBR > > mov $-ENOSYS, %eax > > + CLEAR_CPU_BUFFERS > > nit: Just out of curiosity is it really needed in this case or it's doesn > for the sake of uniformity so that all ring3 transitions are indeed > covered?? Interrupts returning to kernel don't clear the CPU buffers. I believe interrupts will be enabled here, and getting an interrupt here could leak the data that interrupt touched.
On 10/26/23 12:29, Pawan Gupta wrote: > On Thu, Oct 26, 2023 at 07:25:27PM +0300, Nikolay Borisov wrote: >> On 25.10.23 г. 23:52 ч., Pawan Gupta wrote: >>> @@ -1520,6 +1530,7 @@ SYM_CODE_START(ignore_sysret) >>> UNWIND_HINT_END_OF_STACK >>> ENDBR >>> mov $-ENOSYS, %eax >>> + CLEAR_CPU_BUFFERS >> nit: Just out of curiosity is it really needed in this case or it's doesn >> for the sake of uniformity so that all ring3 transitions are indeed >> covered?? > Interrupts returning to kernel don't clear the CPU buffers. I believe > interrupts will be enabled here, and getting an interrupt here could > leak the data that interrupt touched. Specifically NMIs, right? X86_EFLAGS_IF should be clear here.
On Thu, Oct 26, 2023 at 12:40:49PM -0700, Dave Hansen wrote: > On 10/26/23 12:29, Pawan Gupta wrote: > > On Thu, Oct 26, 2023 at 07:25:27PM +0300, Nikolay Borisov wrote: > >> On 25.10.23 г. 23:52 ч., Pawan Gupta wrote: > >>> @@ -1520,6 +1530,7 @@ SYM_CODE_START(ignore_sysret) > >>> UNWIND_HINT_END_OF_STACK > >>> ENDBR > >>> mov $-ENOSYS, %eax > >>> + CLEAR_CPU_BUFFERS > >> nit: Just out of curiosity is it really needed in this case or it's doesn > >> for the sake of uniformity so that all ring3 transitions are indeed > >> covered?? > > Interrupts returning to kernel don't clear the CPU buffers. I believe > > interrupts will be enabled here, and getting an interrupt here could > > leak the data that interrupt touched. > > Specifically NMIs, right? Yes, and VERW can omitted for the same reason as NMI returning to kernel. > X86_EFLAGS_IF should be clear here. I see that SYSCALL has a configuration for IF, but I didn't see it for SYSENTER in the code. But looking at the SDM, it clear IF by default. syscall_init() { ... #else wrmsrl_cstar((unsigned long)ignore_sysret); wrmsrl_safe(MSR_IA32_SYSENTER_CS, (u64)GDT_ENTRY_INVALID_SEG); wrmsrl_safe(MSR_IA32_SYSENTER_ESP, 0ULL); wrmsrl_safe(MSR_IA32_SYSENTER_EIP, 0ULL); #endif /* * Flags to clear on syscall; clear as much as possible * to minimize user space-kernel interference. */ wrmsrl(MSR_SYSCALL_MASK, X86_EFLAGS_CF|X86_EFLAGS_PF|X86_EFLAGS_AF| X86_EFLAGS_ZF|X86_EFLAGS_SF|X86_EFLAGS_TF| X86_EFLAGS_IF|X86_EFLAGS_DF|X86_EFLAGS_OF| X86_EFLAGS_IOPL|X86_EFLAGS_NT|X86_EFLAGS_RF| X86_EFLAGS_AC|X86_EFLAGS_ID);
On Thu, Oct 26, 2023 at 02:15:11PM -0700, Pawan Gupta wrote: > On Thu, Oct 26, 2023 at 12:40:49PM -0700, Dave Hansen wrote: > > On 10/26/23 12:29, Pawan Gupta wrote: > > > On Thu, Oct 26, 2023 at 07:25:27PM +0300, Nikolay Borisov wrote: > > >> On 25.10.23 г. 23:52 ч., Pawan Gupta wrote: > > >>> @@ -1520,6 +1530,7 @@ SYM_CODE_START(ignore_sysret) > > >>> UNWIND_HINT_END_OF_STACK > > >>> ENDBR > > >>> mov $-ENOSYS, %eax > > >>> + CLEAR_CPU_BUFFERS > > >> nit: Just out of curiosity is it really needed in this case or it's doesn > > >> for the sake of uniformity so that all ring3 transitions are indeed > > >> covered?? > > > Interrupts returning to kernel don't clear the CPU buffers. I believe > > > interrupts will be enabled here, and getting an interrupt here could > > > leak the data that interrupt touched. > > > > Specifically NMIs, right? > > Yes, and VERW can omitted for the same reason as NMI returning to > kernel. Thinking more on this, we should not omit verw here, as this spot is way easier to target NMIs. A user executing SYSENTER in a loop has much higher chances of causing an NMI to return to kernel, and skip verw.
On 10/26/23 15:13, Pawan Gupta wrote: >>>> Interrupts returning to kernel don't clear the CPU buffers. I believe >>>> interrupts will be enabled here, and getting an interrupt here could >>>> leak the data that interrupt touched. >>> Specifically NMIs, right? >> Yes, and VERW can omitted for the same reason as NMI returning to >> kernel. > Thinking more on this, we should not omit verw here, as this spot is way > easier to target NMIs. A user executing SYSENTER in a loop has much > higher chances of causing an NMI to return to kernel, and skip verw. Right. This is also a path where we care *ZERO* about performance. It's basically all upside to _add_ VERW and all downside (increased attack surface) to skip it.
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S index 43606de22511..9f97a8bd11e8 100644 --- a/arch/x86/entry/entry_64.S +++ b/arch/x86/entry/entry_64.S @@ -223,6 +223,7 @@ syscall_return_via_sysret: SYM_INNER_LABEL(entry_SYSRETQ_unsafe_stack, SYM_L_GLOBAL) ANNOTATE_NOENDBR swapgs + CLEAR_CPU_BUFFERS sysretq SYM_INNER_LABEL(entry_SYSRETQ_end, SYM_L_GLOBAL) ANNOTATE_NOENDBR @@ -663,6 +664,7 @@ SYM_INNER_LABEL(swapgs_restore_regs_and_return_to_usermode, SYM_L_GLOBAL) /* Restore RDI. */ popq %rdi swapgs + CLEAR_CPU_BUFFERS jmp .Lnative_iret @@ -774,6 +776,8 @@ native_irq_return_ldt: */ popq %rax /* Restore user RAX */ + CLEAR_CPU_BUFFERS + /* * RSP now points to an ordinary IRET frame, except that the page * is read-only and RSP[31:16] are preloaded with the userspace @@ -1502,6 +1506,12 @@ nmi_restore: std movq $0, 5*8(%rsp) /* clear "NMI executing" */ + /* + * Skip CLEAR_CPU_BUFFERS here, since it only helps in rare cases like + * NMI in kernel after user state is restored. For an unprivileged user + * these conditions are hard to meet. + */ + /* * iretq reads the "iret" frame and exits the NMI stack in a * single instruction. We are returning to kernel mode, so this @@ -1520,6 +1530,7 @@ SYM_CODE_START(ignore_sysret) UNWIND_HINT_END_OF_STACK ENDBR mov $-ENOSYS, %eax + CLEAR_CPU_BUFFERS sysretl SYM_CODE_END(ignore_sysret) #endif diff --git a/arch/x86/entry/entry_64_compat.S b/arch/x86/entry/entry_64_compat.S index 70150298f8bd..245697eb8485 100644 --- a/arch/x86/entry/entry_64_compat.S +++ b/arch/x86/entry/entry_64_compat.S @@ -271,6 +271,7 @@ SYM_INNER_LABEL(entry_SYSRETL_compat_unsafe_stack, SYM_L_GLOBAL) xorl %r9d, %r9d xorl %r10d, %r10d swapgs + CLEAR_CPU_BUFFERS sysretl SYM_INNER_LABEL(entry_SYSRETL_compat_end, SYM_L_GLOBAL) ANNOTATE_NOENDBR