Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752737AbcD1Kbm (ORCPT ); Thu, 28 Apr 2016 06:31:42 -0400 Received: from terminus.zytor.com ([198.137.202.10]:47266 "EHLO terminus.zytor.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750923AbcD1Kbl (ORCPT ); Thu, 28 Apr 2016 06:31:41 -0400 Date: Thu, 28 Apr 2016 03:30:45 -0700 From: tip-bot for Ard Biesheuvel Message-ID: Cc: linux-kernel@vger.kernel.org, hpa@zytor.com, matt@codeblueprint.co.uk, bp@alien8.de, mingo@kernel.org, peterz@infradead.org, ard.biesheuvel@linaro.org, tglx@linutronix.de, mark.rutland@arm.com, leif.lindholm@linaro.org Reply-To: ard.biesheuvel@linaro.org, mark.rutland@arm.com, leif.lindholm@linaro.org, tglx@linutronix.de, peterz@infradead.org, mingo@kernel.org, bp@alien8.de, matt@codeblueprint.co.uk, linux-kernel@vger.kernel.org, hpa@zytor.com In-Reply-To: <1461614832-17633-3-git-send-email-matt@codeblueprint.co.uk> References: <1461614832-17633-3-git-send-email-matt@codeblueprint.co.uk> To: linux-tip-commits@vger.kernel.org Subject: [tip:efi/core] efi/arm*: Drop writable mapping of the UEFI System table Git-Commit-ID: 14c43be60166981f0b1f034ad9c59252c6f99e0d X-Mailer: tip-git-log-daemon Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset=UTF-8 Content-Disposition: inline Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 4633 Lines: 125 Commit-ID: 14c43be60166981f0b1f034ad9c59252c6f99e0d Gitweb: http://git.kernel.org/tip/14c43be60166981f0b1f034ad9c59252c6f99e0d Author: Ard Biesheuvel AuthorDate: Mon, 25 Apr 2016 21:06:34 +0100 Committer: Ingo Molnar CommitDate: Thu, 28 Apr 2016 11:33:47 +0200 efi/arm*: Drop writable mapping of the UEFI System table Commit: 2eec5dedf770 ("efi/arm-init: Use read-only early mappings") updated the early ARM UEFI init code to create the temporary, early mapping of the UEFI System table using read-only attributes, as a hardening measure against inadvertent modification. However, this still leaves the permanent, writable mapping of the UEFI System table, which is only ever referenced during invocations of UEFI Runtime Services, at which time the UEFI virtual mapping is available, which also covers the system table. (This is guaranteed by the fact that SetVirtualAddressMap(), which is a runtime service itself, converts various entries in the table to their virtual equivalents, which implies that the table must be covered by a RuntimeServicesData region that has the EFI_MEMORY_RUNTIME attribute.) So instead of creating this permanent mapping, record the virtual address of the system table inside the UEFI virtual mapping, and dereference that when accessing the table. This protects the contents of the system table from inadvertent (or deliberate) modification when no UEFI Runtime Services calls are in progress. Signed-off-by: Ard Biesheuvel Signed-off-by: Matt Fleming Cc: Borislav Petkov Cc: Leif Lindholm Cc: Mark Rutland Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: linux-efi@vger.kernel.org Link: http://lkml.kernel.org/r/1461614832-17633-3-git-send-email-matt@codeblueprint.co.uk Signed-off-by: Ingo Molnar --- drivers/firmware/efi/arm-init.c | 2 ++ drivers/firmware/efi/arm-runtime.c | 27 ++++++++++++++++----------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/drivers/firmware/efi/arm-init.c b/drivers/firmware/efi/arm-init.c index 8714f8c..008ed19 100644 --- a/drivers/firmware/efi/arm-init.c +++ b/drivers/firmware/efi/arm-init.c @@ -85,6 +85,8 @@ static int __init uefi_init(void) efi.systab->hdr.revision >> 16, efi.systab->hdr.revision & 0xffff); + efi.runtime_version = efi.systab->hdr.revision; + /* Show what we know for posterity */ c16 = early_memremap_ro(efi_to_phys(efi.systab->fw_vendor), sizeof(vendor) * sizeof(efi_char16_t)); diff --git a/drivers/firmware/efi/arm-runtime.c b/drivers/firmware/efi/arm-runtime.c index 16c7d2a..771750d 100644 --- a/drivers/firmware/efi/arm-runtime.c +++ b/drivers/firmware/efi/arm-runtime.c @@ -42,10 +42,12 @@ static struct mm_struct efi_mm = { static bool __init efi_virtmap_init(void) { efi_memory_desc_t *md; + bool systab_found; efi_mm.pgd = pgd_alloc(&efi_mm); init_new_context(NULL, &efi_mm); + systab_found = false; for_each_efi_memory_desc(&memmap, md) { phys_addr_t phys = md->phys_addr; int ret; @@ -64,8 +66,20 @@ static bool __init efi_virtmap_init(void) &phys, ret); return false; } + /* + * If this entry covers the address of the UEFI system table, + * calculate and record its virtual address. + */ + if (efi_system_table >= phys && + efi_system_table < phys + (md->num_pages * EFI_PAGE_SIZE)) { + efi.systab = (void *)(unsigned long)(efi_system_table - + phys + md->virt_addr); + systab_found = true; + } } - return true; + if (!systab_found) + pr_err("No virtual mapping found for the UEFI System Table\n"); + return systab_found; } /* @@ -99,15 +113,8 @@ static int __init arm_enable_runtime_services(void) memmap.map_end = memmap.map + mapsize; efi.memmap = &memmap; - efi.systab = (__force void *)ioremap_cache(efi_system_table, - sizeof(efi_system_table_t)); - if (!efi.systab) { - pr_err("Failed to remap EFI System Table\n"); - return -ENOMEM; - } - if (!efi_virtmap_init()) { - pr_err("No UEFI virtual mapping was installed -- runtime services will not be available\n"); + pr_err("UEFI virtual mapping missing or invalid -- runtime services will not be available\n"); return -ENOMEM; } @@ -115,8 +122,6 @@ static int __init arm_enable_runtime_services(void) efi_native_runtime_setup(); set_bit(EFI_RUNTIME_SERVICES, &efi.flags); - efi.runtime_version = efi.systab->hdr.revision; - return 0; } early_initcall(arm_enable_runtime_services);