lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <tip-f9d230e893e864f13ce5ded9a49990fd024bfed5@git.kernel.org>
Date:   Wed, 13 Feb 2019 03:27:55 -0800
From:   tip-bot for Borislav Petkov <tipbot@...or.com>
To:     linux-tip-commits@...r.kernel.org
Cc:     linux@...ck-us.net, mingo@...nel.org, linux-kernel@...r.kernel.org,
        fanc.fnst@...fujitsu.com, tglx@...utronix.de, x86@...nel.org,
        mingo@...hat.com, hpa@...or.com, ard.biesheuvel@...aro.org,
        bp@...e.de, keescook@...omium.org
Subject: [tip:x86/boot] x86/boot: Correct RSDP parsing with 32-bit EFI

Commit-ID:  f9d230e893e864f13ce5ded9a49990fd024bfed5
Gitweb:     https://git.kernel.org/tip/f9d230e893e864f13ce5ded9a49990fd024bfed5
Author:     Borislav Petkov <bp@...e.de>
AuthorDate: Mon, 11 Feb 2019 12:19:45 +0100
Committer:  Borislav Petkov <bp@...e.de>
CommitDate: Wed, 13 Feb 2019 12:19:05 +0100

x86/boot: Correct RSDP parsing with 32-bit EFI

Guenter Roeck reported triple faults of a 64-bit VM using a 32-bit OVMF
EFI image. After some singlestepping of the image in gdb, it turned out
that some of the EFI config tables were at bogus addresses. Which, as
Ard pointed out, results from using the wrong efi_config_table typedef.

So switch all EFI table pointers to unsigned longs and convert them to
the proper typedef only when accessing them. This way, the proper table
type is being used.

Shorten variable names, while at it.

Fixes: 33f0df8d843d ("x86/boot: Search for RSDP in the EFI tables")
Reported-by: Guenter Roeck <linux@...ck-us.net>
Signed-off-by: Borislav Petkov <bp@...e.de>
Tested-by: Chao Fan <fanc.fnst@...fujitsu.com>
Cc: Ard Biesheuvel <ard.biesheuvel@...aro.org>
Cc: bhe@...hat.com
Cc: caoj.fnst@...fujitsu.com
Cc: "H. Peter Anvin" <hpa@...or.com>
Cc: indou.takao@...fujitsu.com
Cc: Ingo Molnar <mingo@...hat.com>
Cc: kasong@...hat.com
Cc: Kees Cook <keescook@...omium.org>
Cc: msys.mizuma@...il.com
Cc: Thomas Gleixner <tglx@...utronix.de>
Cc: x86-ml <x86@...nel.org>
Link: https://lkml.kernel.org/r/20190208190248.GA10854@roeck-us.net
---
 arch/x86/boot/compressed/acpi.c | 50 +++++++++++++++++++++++++----------------
 1 file changed, 31 insertions(+), 19 deletions(-)

diff --git a/arch/x86/boot/compressed/acpi.c b/arch/x86/boot/compressed/acpi.c
index c5a949335d8b..0ef4ad55b29b 100644
--- a/arch/x86/boot/compressed/acpi.c
+++ b/arch/x86/boot/compressed/acpi.c
@@ -50,7 +50,8 @@ static acpi_physical_address efi_get_rsdp_addr(void)
 	acpi_physical_address rsdp_addr = 0;
 
 #ifdef CONFIG_EFI
-	efi_system_table_t *systab;
+	unsigned long systab, systab_tables, config_tables;
+	unsigned int nr_tables;
 	struct efi_info *ei;
 	bool efi_64;
 	int size, i;
@@ -70,46 +71,57 @@ static acpi_physical_address efi_get_rsdp_addr(void)
 
 	/* Get systab from boot params. */
 #ifdef CONFIG_X86_64
-	systab = (efi_system_table_t *)(ei->efi_systab | ((__u64)ei->efi_systab_hi<<32));
+	systab = ei->efi_systab | ((__u64)ei->efi_systab_hi << 32);
 #else
 	if (ei->efi_systab_hi || ei->efi_memmap_hi) {
 		debug_putstr("Error getting RSDP address: EFI system table located above 4GB.\n");
 		return 0;
 	}
-	systab = (efi_system_table_t *)ei->efi_systab;
+	systab = ei->efi_systab;
 #endif
 	if (!systab)
 		error("EFI system table not found.");
 
-	/*
-	 * Get EFI tables from systab.
-	 */
-	size = efi_64 ? sizeof(efi_config_table_64_t) :
-			sizeof(efi_config_table_32_t);
+	/* Handle EFI bitness properly */
+	if (efi_64) {
+		efi_system_table_64_t *stbl = (efi_system_table_64_t *)systab;
+
+		config_tables	= stbl->tables;
+		nr_tables	= stbl->nr_tables;
+		size		= sizeof(efi_config_table_64_t);
+	} else {
+		efi_system_table_32_t *stbl = (efi_system_table_32_t *)systab;
 
-	for (i = 0; i < systab->nr_tables; i++) {
+		config_tables	= stbl->tables;
+		nr_tables	= stbl->nr_tables;
+		size		= sizeof(efi_config_table_32_t);
+	}
+
+	if (!config_tables)
+		error("EFI config tables not found.");
+
+	/* Get EFI tables from systab. */
+	for (i = 0; i < nr_tables; i++) {
 		acpi_physical_address table;
-		void *config_tables;
 		efi_guid_t guid;
 
-		config_tables = (void *)(systab->tables + size * i);
+		config_tables += size;
+
 		if (efi_64) {
-			efi_config_table_64_t *tmp_table;
+			efi_config_table_64_t *tbl = (efi_config_table_64_t *)config_tables;
 
-			tmp_table = config_tables;
-			guid = tmp_table->guid;
-			table = tmp_table->table;
+			guid  = tbl->guid;
+			table = tbl->table;
 
 			if (!IS_ENABLED(CONFIG_X86_64) && table >> 32) {
 				debug_putstr("Error getting RSDP address: EFI config table located above 4GB.\n");
 				return 0;
 			}
 		} else {
-			efi_config_table_32_t *tmp_table;
+			efi_config_table_32_t *tbl = (efi_config_table_32_t *)config_tables;
 
-			tmp_table = config_tables;
-			guid = tmp_table->guid;
-			table = tmp_table->table;
+			guid  = tbl->guid;
+			table = tbl->table;
 		}
 
 		if (!(efi_guidcmp(guid, ACPI_TABLE_GUID)))

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ