public inbox for stable@vger.kernel.org
 help / color / mirror / Atom feed
From: Sasha Levin <sashal@kernel.org>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: Joerg Roedel <jroedel@suse.de>, Borislav Petkov <bp@suse.de>,
	Sasha Levin <sashal@kernel.org>
Subject: [PATCH AUTOSEL 5.11 12/70] x86/boot/compressed/64: Check SEV encryption in the 32-bit boot-path
Date: Sun,  2 May 2021 10:02:46 -0400	[thread overview]
Message-ID: <20210502140344.2719040-12-sashal@kernel.org> (raw)
In-Reply-To: <20210502140344.2719040-1-sashal@kernel.org>

From: Joerg Roedel <jroedel@suse.de>

[ Upstream commit fef81c86262879d4b1176ef51a834c15b805ebb9 ]

Check whether the hypervisor reported the correct C-bit when running
as an SEV guest. Using a wrong C-bit position could be used to leak
sensitive data from the guest to the hypervisor.

Signed-off-by: Joerg Roedel <jroedel@suse.de>
Signed-off-by: Borislav Petkov <bp@suse.de>
Link: https://lkml.kernel.org/r/20210312123824.306-8-joro@8bytes.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 arch/x86/boot/compressed/head_64.S | 83 ++++++++++++++++++++++++++++++
 1 file changed, 83 insertions(+)

diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S
index e94874f4bbc1..f670e0579a3b 100644
--- a/arch/x86/boot/compressed/head_64.S
+++ b/arch/x86/boot/compressed/head_64.S
@@ -172,11 +172,21 @@ SYM_FUNC_START(startup_32)
 	 */
 	call	get_sev_encryption_bit
 	xorl	%edx, %edx
+#ifdef	CONFIG_AMD_MEM_ENCRYPT
 	testl	%eax, %eax
 	jz	1f
 	subl	$32, %eax	/* Encryption bit is always above bit 31 */
 	bts	%eax, %edx	/* Set encryption mask for page tables */
+	/*
+	 * Mark SEV as active in sev_status so that startup32_check_sev_cbit()
+	 * will do a check. The sev_status memory will be fully initialized
+	 * with the contents of MSR_AMD_SEV_STATUS later in
+	 * set_sev_encryption_mask(). For now it is sufficient to know that SEV
+	 * is active.
+	 */
+	movl	$1, rva(sev_status)(%ebp)
 1:
+#endif
 
 	/* Initialize Page tables to 0 */
 	leal	rva(pgtable)(%ebx), %edi
@@ -261,6 +271,9 @@ SYM_FUNC_START(startup_32)
 	movl	%esi, %edx
 1:
 #endif
+	/* Check if the C-bit position is correct when SEV is active */
+	call	startup32_check_sev_cbit
+
 	pushl	$__KERNEL_CS
 	pushl	%eax
 
@@ -786,6 +799,76 @@ SYM_DATA_START_LOCAL(loaded_image_proto)
 SYM_DATA_END(loaded_image_proto)
 #endif
 
+/*
+ * Check for the correct C-bit position when the startup_32 boot-path is used.
+ *
+ * The check makes use of the fact that all memory is encrypted when paging is
+ * disabled. The function creates 64 bits of random data using the RDRAND
+ * instruction. RDRAND is mandatory for SEV guests, so always available. If the
+ * hypervisor violates that the kernel will crash right here.
+ *
+ * The 64 bits of random data are stored to a memory location and at the same
+ * time kept in the %eax and %ebx registers. Since encryption is always active
+ * when paging is off the random data will be stored encrypted in main memory.
+ *
+ * Then paging is enabled. When the C-bit position is correct all memory is
+ * still mapped encrypted and comparing the register values with memory will
+ * succeed. An incorrect C-bit position will map all memory unencrypted, so that
+ * the compare will use the encrypted random data and fail.
+ */
+SYM_FUNC_START(startup32_check_sev_cbit)
+#ifdef CONFIG_AMD_MEM_ENCRYPT
+	pushl	%eax
+	pushl	%ebx
+	pushl	%ecx
+	pushl	%edx
+
+	/* Check for non-zero sev_status */
+	movl	rva(sev_status)(%ebp), %eax
+	testl	%eax, %eax
+	jz	4f
+
+	/*
+	 * Get two 32-bit random values - Don't bail out if RDRAND fails
+	 * because it is better to prevent forward progress if no random value
+	 * can be gathered.
+	 */
+1:	rdrand	%eax
+	jnc	1b
+2:	rdrand	%ebx
+	jnc	2b
+
+	/* Store to memory and keep it in the registers */
+	movl	%eax, rva(sev_check_data)(%ebp)
+	movl	%ebx, rva(sev_check_data+4)(%ebp)
+
+	/* Enable paging to see if encryption is active */
+	movl	%cr0, %edx			 /* Backup %cr0 in %edx */
+	movl	$(X86_CR0_PG | X86_CR0_PE), %ecx /* Enable Paging and Protected mode */
+	movl	%ecx, %cr0
+
+	cmpl	%eax, rva(sev_check_data)(%ebp)
+	jne	3f
+	cmpl	%ebx, rva(sev_check_data+4)(%ebp)
+	jne	3f
+
+	movl	%edx, %cr0	/* Restore previous %cr0 */
+
+	jmp	4f
+
+3:	/* Check failed - hlt the machine */
+	hlt
+	jmp	3b
+
+4:
+	popl	%edx
+	popl	%ecx
+	popl	%ebx
+	popl	%eax
+#endif
+	ret
+SYM_FUNC_END(startup32_check_sev_cbit)
+
 /*
  * Stack and heap for uncompression
  */
-- 
2.30.2


  parent reply	other threads:[~2021-05-02 14:04 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-05-02 14:02 [PATCH AUTOSEL 5.11 01/70] bus: ti-sysc: Probe for l4_wkup and l4_cfg interconnect devices first Sasha Levin
2021-05-02 14:02 ` [PATCH AUTOSEL 5.11 02/70] staging: wimax/i2400m: fix byte-order issue Sasha Levin
2021-05-02 14:02 ` [PATCH AUTOSEL 5.11 03/70] spi: ath79: always call chipselect function Sasha Levin
2021-05-02 14:02 ` [PATCH AUTOSEL 5.11 04/70] spi: ath79: remove spi-master setup and cleanup assignment Sasha Levin
2021-05-02 14:02 ` [PATCH AUTOSEL 5.11 05/70] bus: mhi: core: Destroy SBL devices when moving to mission mode Sasha Levin
2021-05-02 14:02 ` [PATCH AUTOSEL 5.11 06/70] bus: mhi: core: Process execution environment changes serially Sasha Levin
2021-05-02 14:02 ` [PATCH AUTOSEL 5.11 07/70] crypto: api - check for ERR pointers in crypto_destroy_tfm() Sasha Levin
2021-05-02 14:02 ` [PATCH AUTOSEL 5.11 08/70] crypto: qat - fix unmap invalid dma address Sasha Levin
2021-05-02 14:02 ` [PATCH AUTOSEL 5.11 09/70] usb: gadget: uvc: add bInterval checking for HS mode Sasha Levin
2021-05-02 14:02 ` [PATCH AUTOSEL 5.11 10/70] usb: webcam: Invalid size of Processing Unit Descriptor Sasha Levin
2021-05-02 14:02 ` [PATCH AUTOSEL 5.11 11/70] x86/sev: Do not require Hypervisor CPUID bit for SEV guests Sasha Levin
2021-05-02 14:02 ` Sasha Levin [this message]
2021-05-02 14:02 ` [PATCH AUTOSEL 5.11 13/70] crypto: hisilicon/sec - fixes a printing error Sasha Levin
2021-05-02 14:02 ` [PATCH AUTOSEL 5.11 14/70] genirq/matrix: Prevent allocation counter corruption Sasha Levin
2021-05-02 14:02 ` [PATCH AUTOSEL 5.11 15/70] usb: gadget: f_uac2: validate input parameters Sasha Levin
2021-05-02 14:02 ` [PATCH AUTOSEL 5.11 16/70] usb: gadget: f_uac1: " Sasha Levin
2021-05-02 14:02 ` [PATCH AUTOSEL 5.11 17/70] usb: dwc3: gadget: Ignore EP queue requests during bus reset Sasha Levin
2021-05-02 14:02 ` [PATCH AUTOSEL 5.11 18/70] usb: xhci: Fix port minor revision Sasha Levin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210502140344.2719040-12-sashal@kernel.org \
    --to=sashal@kernel.org \
    --cc=bp@suse.de \
    --cc=jroedel@suse.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox