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
next prev 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