Received: by 2002:a05:6a10:8c0a:0:0:0:0 with SMTP id go10csp1198393pxb; Wed, 10 Feb 2021 02:34:25 -0800 (PST) X-Google-Smtp-Source: ABdhPJzv6AOnrsYaGaiNZXO3BVsMansTdxLMalChoi4CrmE23i8h3CqSja+IyF27s9npoVRuDq69 X-Received: by 2002:a17:906:3f8d:: with SMTP id b13mr2254912ejj.464.1612953265210; Wed, 10 Feb 2021 02:34:25 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1612953265; cv=none; d=google.com; s=arc-20160816; b=WtQ9U1BezKW2a4j23HyD4wtIpaRkXsGVF3lP5fd4yzTKNHs8df/rQvUgyRB27qcfr4 jygk0LM4MHcFgaW8Fzs6R35KSRvYvwYhLfM9MtunfQttg75rnJ9SnBn5J9bhfk44i2WV VJRfZg4HHBToPVPs+x/h/uaYtBocc0qALgT194OsI3HMemoUvS2j1/LOXiaRskLe9SNQ MB4I54UJVPEyzw97MamW9roHx9FLFKy+VjRdCH55LDMRb0IMXCLdzK3hgL/jZl89HSpI MQ5Eh9k+QnvJsYqYj77fq7Mr5ltwkYKss2iwSAbeeQZzjbf1ZkwWVJJY8+du7XvG6vgs +uHA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=W5clSns+8rOfTPwUDuWAz//7Aivbf7fglAAcR5bLnNo=; b=QGXxM4xwdtxtXFO/E5LU1WXxIL0K/lb52UvPKiLU2fTu8ruE3F08ifPjtwMklUa8p9 B/olOnviOG0sMQcnzslS93Ov2bMBKPKfuctVTr2Zq3rFgYXQmeXwMN8OFHhycUy+3SW6 P+1O8a4r96/SOtgbzqSZn9kXW0yohh72YF3QWyIp52ejMSmmpuWhOJHKhap48FGic/bx ITBADE/yvqnddI4Vm1R7J6j79itxH9qkplA61bR1WqjX1amyVy9VWc6gkNReGEZml0kH xoxDR0YgR2frWJ8txkT/U9UuqxCSw60o7p79lJN4chTEAXVB/0H+qiRnm/ekn39kkyqe +j8g== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=8bytes.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id h24si1080731ejt.167.2021.02.10.02.34.01; Wed, 10 Feb 2021 02:34:25 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=8bytes.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231373AbhBJKdE (ORCPT + 99 others); Wed, 10 Feb 2021 05:33:04 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44866 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230491AbhBJKWl (ORCPT ); Wed, 10 Feb 2021 05:22:41 -0500 Received: from theia.8bytes.org (8bytes.org [IPv6:2a01:238:4383:600:38bc:a715:4b6d:a889]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F175CC06174A; Wed, 10 Feb 2021 02:22:00 -0800 (PST) Received: from cap.home.8bytes.org (p549adcf6.dip0.t-ipconnect.de [84.154.220.246]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by theia.8bytes.org (Postfix) with ESMTPSA id 27A3B48E; Wed, 10 Feb 2021 11:21:58 +0100 (CET) From: Joerg Roedel To: x86@kernel.org Cc: Joerg Roedel , Joerg Roedel , hpa@zytor.com, Andy Lutomirski , Dave Hansen , Peter Zijlstra , Jiri Slaby , Dan Williams , Tom Lendacky , Juergen Gross , Kees Cook , David Rientjes , Cfir Cohen , Erdem Aktas , Masami Hiramatsu , Mike Stunes , Sean Christopherson , Martin Radev , Arvind Sankar , linux-kernel@vger.kernel.org, kvm@vger.kernel.org, virtualization@lists.linux-foundation.org Subject: [PATCH 6/7] x86/boot/compressed/64: Check SEV encryption in 32-bit boot-path Date: Wed, 10 Feb 2021 11:21:34 +0100 Message-Id: <20210210102135.30667-7-joro@8bytes.org> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210210102135.30667-1-joro@8bytes.org> References: <20210210102135.30667-1-joro@8bytes.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Joerg Roedel 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 --- arch/x86/boot/compressed/head_64.S | 80 ++++++++++++++++++++++++++ arch/x86/boot/compressed/mem_encrypt.S | 1 + 2 files changed, 81 insertions(+) diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S index eadaa0a082b8..047af1cba041 100644 --- a/arch/x86/boot/compressed/head_64.S +++ b/arch/x86/boot/compressed/head_64.S @@ -185,11 +185,18 @@ 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 */ + /* + * Store the sme_me_mask as an indicator that SEV is active. It will be + * set again in startup_64(). + */ + movl %edx, rva(sme_me_mask+4)(%ebp) 1: +#endif /* Initialize Page tables to 0 */ leal rva(pgtable)(%ebx), %edi @@ -274,6 +281,9 @@ SYM_FUNC_START(startup_32) movl %esi, %edx 1: #endif + /* Check if the C-bit position is correct when SEV is active */ + call sev_startup32_cbit_check + pushl $__KERNEL_CS pushl %eax @@ -870,6 +880,76 @@ SYM_FUNC_START(startup32_load_idt) ret SYM_FUNC_END(startup32_load_idt) #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(sev_startup32_cbit_check) +#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(sev_startup32_cbit_check) /* * Stack and heap for uncompression */ diff --git a/arch/x86/boot/compressed/mem_encrypt.S b/arch/x86/boot/compressed/mem_encrypt.S index 091502cde070..b80fed167903 100644 --- a/arch/x86/boot/compressed/mem_encrypt.S +++ b/arch/x86/boot/compressed/mem_encrypt.S @@ -7,6 +7,7 @@ * Author: Tom Lendacky */ +#define rva(X) ((X) - startup_32) #include #include -- 2.30.0