From patchwork Mon Apr 25 20:06:42 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matt Fleming X-Patchwork-Id: 66633 Delivered-To: patch@linaro.org Received: by 10.140.93.198 with SMTP id d64csp1236776qge; Mon, 25 Apr 2016 13:15:56 -0700 (PDT) X-Received: by 10.98.55.131 with SMTP id e125mr51475045pfa.86.1461615356657; Mon, 25 Apr 2016 13:15:56 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id ot4si8647640pab.169.2016.04.25.13.15.56; Mon, 25 Apr 2016 13:15:56 -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 S965024AbcDYUPy (ORCPT + 29 others); Mon, 25 Apr 2016 16:15:54 -0400 Received: from mail-wm0-f45.google.com ([74.125.82.45]:38326 "EHLO mail-wm0-f45.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933160AbcDYUHj (ORCPT ); Mon, 25 Apr 2016 16:07:39 -0400 Received: by mail-wm0-f45.google.com with SMTP id u206so145142344wme.1 for ; Mon, 25 Apr 2016 13:07:38 -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=UjnBC5F/u00KqYrdsz8+l32cpKL1ouooXzWA4rIVtcE=; b=jCFzn4FJ/vfa2UsIIeK9a74/P7rD3pC59Ea/NDZBOEFcWCR1u7nNzyamb/heRHZK7Z Oj0vFW3nwtxOEH36B6nAC2HYCB360DRnVpHfYW5Hh6L7tdDM+hFtiJQfWCgeg7Mtzm/u fXid0vsFqZp2jVKiogwwfk7Z7Pr5FlzF7oQw3dFmpecd5xpVrWjqE9mDRLNSlXisv7mM BuS7J3+BxKg6OHlJGCMPqPPGsabjN15ZMVI3a4fkX+qjPNV7nB7d+yXSZbuHBYSvCXFE wOcifnD4foPLugz6aRqVWARM6hkC/lRmcJvXmu0e4nPT/PQhHxZhVUER27ejABY/SV8P WL9g== 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=UjnBC5F/u00KqYrdsz8+l32cpKL1ouooXzWA4rIVtcE=; b=TFFWJ7B9dJyF+fPEl5relQd5GCLwSMrcsJ0Ezg8ujex1CAtnKRKzFo9WoPqlKQrS9E FrsWiFZZVzdLwg6/EmyCK22QX+/MKNnFY3Nw5L4N9Fs9WGhi7edPYH+aaak74FSbo5BT fBwHRmKry7qwcyLSG00fTNOvcYmhYwO8lJ28y1Q/GtweH+Oor2ssOCxz0vV4oTFkFpj/ MiKQg3v5YuRMPfUZtirNj0qwsd17ABAeDch03CkQZpW0CNJ/ubXsCvfW5cS+C2gufTB1 25LFPFNIivCy3E4qR8TDRGa7aOo+xtvxtq/fhwMmjneNTW6MgZ0clxEyWXPUtDZM1TXr VRnQ== X-Gm-Message-State: AOPr4FUpTTZtkUFFlNDAqvxWEWZkvuc3mUP1LzHhNsasAxWausQVzyG+y9VsZ4E3tG8rtQ== X-Received: by 10.195.3.1 with SMTP id bs1mr39234227wjd.160.1461614853014; Mon, 25 Apr 2016 13:07:33 -0700 (PDT) Received: from localhost (bcdc58e5.skybroadband.com. [188.220.88.229]) by smtp.gmail.com with ESMTPSA id o128sm20301396wmb.19.2016.04.25.13.07.31 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 25 Apr 2016 13:07:32 -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 , Catalin Marinas , Leif Lindholm , Mark Rutland , Peter Jones , Russell King , Sai Praneeth Prakhya , Will Deacon Subject: [PATCH 10/40] ARM: efi: Apply strict permissons for UEFI Runtime Services regions Date: Mon, 25 Apr 2016 21:06:42 +0100 Message-Id: <1461614832-17633-11-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 Recent UEFI versions expose permission attributes for runtime services memory regions, either in the UEFI memory map or in the separate memory attributes table. This allows the kernel to map these regions with stricter permissions, rather than the RWX permissions that are used by default. So wire this up in our mapping routine. Signed-off-by: Ard Biesheuvel Cc: Russell King Cc: Mark Rutland Cc: Catalin Marinas Cc: Will Deacon Cc: Leif Lindholm Cc: Peter Jones Cc: Sai Praneeth Prakhya Signed-off-by: Matt Fleming --- arch/arm/include/asm/efi.h | 1 + arch/arm/kernel/efi.c | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) -- 2.7.3 diff --git a/arch/arm/include/asm/efi.h b/arch/arm/include/asm/efi.h index e0eea72deb87..b0c341d7ceee 100644 --- a/arch/arm/include/asm/efi.h +++ b/arch/arm/include/asm/efi.h @@ -22,6 +22,7 @@ void efi_init(void); int efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md); +int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md); #define efi_call_virt(f, ...) \ ({ \ diff --git a/arch/arm/kernel/efi.c b/arch/arm/kernel/efi.c index ff8a9d8acfac..9f43ba012d10 100644 --- a/arch/arm/kernel/efi.c +++ b/arch/arm/kernel/efi.c @@ -11,6 +11,41 @@ #include #include +static int __init set_permissions(pte_t *ptep, pgtable_t token, + unsigned long addr, void *data) +{ + efi_memory_desc_t *md = data; + pte_t pte = *ptep; + + if (md->attribute & EFI_MEMORY_RO) + pte = set_pte_bit(pte, __pgprot(L_PTE_RDONLY)); + if (md->attribute & EFI_MEMORY_XP) + pte = set_pte_bit(pte, __pgprot(L_PTE_XN)); + set_pte_ext(ptep, pte, PTE_EXT_NG); + return 0; +} + +int __init efi_set_mapping_permissions(struct mm_struct *mm, + efi_memory_desc_t *md) +{ + unsigned long base, size; + + base = md->virt_addr; + size = md->num_pages << EFI_PAGE_SHIFT; + + /* + * We can only use apply_to_page_range() if we can guarantee that the + * entire region was mapped using pages. This should be the case if the + * region does not cover any naturally aligned SECTION_SIZE sized + * blocks. + */ + if (round_down(base + size, SECTION_SIZE) < + round_up(base, SECTION_SIZE) + SECTION_SIZE) + return apply_to_page_range(mm, base, size, set_permissions, md); + + return 0; +} + int __init efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md) { struct map_desc desc = { @@ -34,5 +69,11 @@ int __init efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md) desc.type = MT_DEVICE; create_mapping_late(mm, &desc, true); + + /* + * If stricter permissions were specified, apply them now. + */ + if (md->attribute & (EFI_MEMORY_RO | EFI_MEMORY_XP)) + return efi_set_mapping_permissions(mm, md); return 0; }