From patchwork Mon Apr 25 20:06:34 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matt Fleming X-Patchwork-Id: 66643 Delivered-To: patch@linaro.org Received: by 10.140.93.198 with SMTP id d64csp1238445qge; Mon, 25 Apr 2016 13:19:47 -0700 (PDT) X-Received: by 10.98.101.198 with SMTP id z189mr6315958pfb.76.1461615587594; Mon, 25 Apr 2016 13:19:47 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id kj7si3698831pab.136.2016.04.25.13.19.47; Mon, 25 Apr 2016 13:19:47 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@codeblueprint-co-uk.20150623.gappssmtp.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S964929AbcDYUTq (ORCPT + 29 others); Mon, 25 Apr 2016 16:19:46 -0400 Received: from mail-wm0-f43.google.com ([74.125.82.43]:37607 "EHLO mail-wm0-f43.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S964859AbcDYUHS (ORCPT ); Mon, 25 Apr 2016 16:07:18 -0400 Received: by mail-wm0-f43.google.com with SMTP id n3so145572912wmn.0 for ; Mon, 25 Apr 2016 13:07:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=codeblueprint-co-uk.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=PsRKnwbZQPXyC2DH/8SkGo1ArA4/SsycqpJm0uls1X8=; b=B796IxmYg0lBwo4b6bf2UxGhMPZQfEhFTwAXG2nBV8C6ldoOXzM2cm8ATv2j5Zfk8v 220xB5w7X5ZpQnFlJjIMRnNAr7nrLmuZ6Tm/vrn+Cq/f99zkj+SfACbQzgQZjLyfAP/M 81f6YXsxMtUVaVvs1vS0bmwtlnJElo/kos1WLbRTXzrfqPCBDlxrv45mPJLzNX3NVX59 i6vrxQwBjsh5AhD+/WeX1K4ZzvifAMVkSLzXkCr+XetbqzIasWbpEfIlGGYJwGi//fl3 Cibaf6MXfvRB0x6oNj/60ELgmxD7hzcbaI36RMe5pcZOJfAhS/GitLDZzsa8wZBRYy8u Eu0g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=PsRKnwbZQPXyC2DH/8SkGo1ArA4/SsycqpJm0uls1X8=; b=LbXbp/wflAkLWgGM/J0m+OGVUMi63CFip163Yy9lEnJdtXgMRLrVMkIyhkBKYFBDyh iKoz48+PWHn8lc9XTksEp2SYubDR7DOthBLXO7FL02l28oFER/D0K/RkTeXNe9gxZOdE Sq+0cPaIkwCZN4ZWZpyOmTbR/pKyX8YDU3GQhF1TuvyIlGreF3Qxfnz3/Fj+Oe3of3Cs asJ7Ox2PkXWHygRmPlAwmBoQ9midZx4HZutGQjxNNtRPHZ6YJqz7kv5gCguTI9uuTQXb smWWYWFGTmyqEVAQIpUomYw4DibEucJO85zADXep+5ywQwxe9Ox4p6yOjwQu/f7ECrsO UtPA== X-Gm-Message-State: AOPr4FVKTLK7Nt8LZ5Rqipp4umMMKlLE4IUf3+uHwppbz9Ldlvs7OM8xpvBILibKhn9wAQ== X-Received: by 10.28.149.205 with SMTP id x196mr14973434wmd.67.1461614837089; Mon, 25 Apr 2016 13:07:17 -0700 (PDT) Received: from localhost (bcdc58e5.skybroadband.com. [188.220.88.229]) by smtp.gmail.com with ESMTPSA id g132sm20463056wme.0.2016.04.25.13.07.15 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 25 Apr 2016 13:07:16 -0700 (PDT) From: Matt Fleming To: Ingo Molnar , Thomas Gleixner , "H . Peter Anvin" Cc: Ard Biesheuvel , linux-kernel@vger.kernel.org, linux-efi@vger.kernel.org, Matt Fleming , Leif Lindholm , Mark Rutland Subject: [PATCH 02/40] efi/arm*: Drop writable mapping of the UEFI System table Date: Mon, 25 Apr 2016 21:06:34 +0100 Message-Id: <1461614832-17633-3-git-send-email-matt@codeblueprint.co.uk> X-Mailer: git-send-email 2.7.3 In-Reply-To: <1461614832-17633-1-git-send-email-matt@codeblueprint.co.uk> References: <1461614832-17633-1-git-send-email-matt@codeblueprint.co.uk> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Ard Biesheuvel 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 Cc: Mark Rutland Cc: Leif Lindholm Signed-off-by: Matt Fleming --- drivers/firmware/efi/arm-init.c | 2 ++ drivers/firmware/efi/arm-runtime.c | 27 ++++++++++++++++----------- 2 files changed, 18 insertions(+), 11 deletions(-) -- 2.7.3 diff --git a/drivers/firmware/efi/arm-init.c b/drivers/firmware/efi/arm-init.c index 8714f8c271ba..008ed1993b72 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 16c7d2a71156..771750df6b7d 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);