Received: by 10.223.185.116 with SMTP id b49csp7391845wrg; Thu, 1 Mar 2018 04:57:38 -0800 (PST) X-Google-Smtp-Source: AG47ELvDvDIyaniDfqQUALTLpt9CHef1p055L8LYjpZVMObPgnrAoUW520QlDslAfpUmD3LGKEG4 X-Received: by 10.101.64.67 with SMTP id h3mr1459674pgp.200.1519909058649; Thu, 01 Mar 2018 04:57:38 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519909058; cv=none; d=google.com; s=arc-20160816; b=ZPO1G/dtxCGk3nsK2c1O9Bd96ZsvUjIAVY3LO7pVyBv0/Gtrn5qkfXyyeZ2OQLvoEe G4dv5MPkVocvGyToB41zy8GYmBsnBs4zVTVIioOK+BD58GdtqFBctirSp+gpkeApOXza pYMzQF4etXXXDfguKhrQoiW7TepESrf939khPWjLKtFvtCUKS28UTtEJIC9rTmQ1VK20 RJU4SmqpJENAb05IbR4UswDMkumVuOJDgupUpNcNJDqwHWgr5C9Wj+EKmmCR846HqSre H9UdsVFbN4nEI7sa3GlzNSrgFCq31EPRtCiu0ctu6AaakPXIiYbJh+lGt1EeZOadVuV8 i2DQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=GWUSuhRz/PUASjkFIqTWrSa96WhoDAqhFr+yeOukJXE=; b=HE2ZVG56R3QNrXLLI9MJC2hM5AaFCJBsZo96oZFKOQuVd+px9S1uydNaVMqerKmqy0 dSTI5T8zVDlO44sTFqiO4R1GxG361+aVYqbWPw7Gi4VDM1bVhEELfEDNX0pzdIYvaX4f GqDrWNpoQjVF0sOX0ogaMpFoggW/ahgwSntzMOsNGsTlxciK3DyrPe2RkRNhH01qH8PT nEkPmc2SywDM7y5VvCGP55eouX++iFFl7x123SKsQPSFn/xwpMQwbimbPotdW5vg1lEW eSmeZLxLnZ9BqCFfgF6wxruCaxV17e0512Pn5UN/t/8vKo+gDWZzBGiqHzsEenZvg3Td 7Erg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=gPAwTb9+; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id l2si2448443pgu.691.2018.03.01.04.57.23; Thu, 01 Mar 2018 04:57:38 -0800 (PST) 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=@linaro.org header.s=google header.b=gPAwTb9+; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1030613AbeCAMz3 (ORCPT + 99 others); Thu, 1 Mar 2018 07:55:29 -0500 Received: from mail-pf0-f193.google.com ([209.85.192.193]:45918 "EHLO mail-pf0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1030549AbeCAMzZ (ORCPT ); Thu, 1 Mar 2018 07:55:25 -0500 Received: by mail-pf0-f193.google.com with SMTP id h19so1517956pfd.12 for ; Thu, 01 Mar 2018 04:55:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=GWUSuhRz/PUASjkFIqTWrSa96WhoDAqhFr+yeOukJXE=; b=gPAwTb9+u4UmqxN6cbplBWZjmmZnXrijzuHVUDHlI2Zo5MMUlU+ka/izwCLmOH/3h2 hxgVD2QonplV/SnjgIXF7nvzzoq4xHDeEnNzLQMMiwaffviXUoPCckHLV1a+SzwNPDyl kaevhp/MoL77LQqKTryn4jiAwOPuW7C6WDoN4= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=GWUSuhRz/PUASjkFIqTWrSa96WhoDAqhFr+yeOukJXE=; b=kNMXLwt2cmkZxzducqzTTpozyId9l9bR0cwWBmAGsbW+Mro1iYe+OGwAY49HbqBvDN eA6KGiS8Dl4Nt9/A+qJTQYhv7v4beh+U1iSKULBltB6DPCKXVGckL2iMT0csOnpl5Nbv Vi84PRbyDrfAFXNTF7Rfp/resYDkGcHseB0diZV7xyjhjQHNiNRSbdgtmC/9b3gE6w5r krRcudg/JKl+1PLm+2A7kw0DF5TV5YNwCu3SdgPQOzNaSYUYEu70t1w4eeLfRPl9RpNz kl65RKygALEbfLFPA5JyBNvaoOVWx4KniJt1fouW3Hl1WVve0mGeGVeSgLbXzpKjVret z12w== X-Gm-Message-State: APf1xPD/cYMDWctsh9CFrhsMIYpZ/wTNB8512iCF5ZjuP4i+k+PNrzqn 8Z8YDfKcsQj/p0g9DH8iKd7oTQ== X-Received: by 10.99.4.66 with SMTP id 63mr1472139pge.93.1519908923913; Thu, 01 Mar 2018 04:55:23 -0800 (PST) Received: from localhost.localdomain (176.122.172.82.16clouds.com. [176.122.172.82]) by smtp.gmail.com with ESMTPSA id x4sm2289655pfb.46.2018.03.01.04.55.16 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 01 Mar 2018 04:55:23 -0800 (PST) From: Alex Shi To: Marc Zyngier , Will Deacon , Ard Biesheuvel , Catalin Marinas , stable@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Cc: Alex Shi Subject: [PATCH 02/45] arm64: alternatives: apply boot time fixups via the linear mapping Date: Thu, 1 Mar 2018 20:53:39 +0800 Message-Id: <1519908862-11425-3-git-send-email-alex.shi@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1519908862-11425-1-git-send-email-alex.shi@linaro.org> References: <1519908862-11425-1-git-send-email-alex.shi@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Ard Biesheuvel commit 5ea5306c323 upstream. One important rule of thumb when desiging a secure software system is that memory should never be writable and executable at the same time. We mostly adhere to this rule in the kernel, except at boot time, when regions may be mapped RWX until after we are done applying alternatives or making other one-off changes. For the alternative patching, we can improve the situation by applying the fixups via the linear mapping, which is never mapped with executable permissions. So map the linear alias of .text with RW- permissions initially, and remove the write permissions as soon as alternative patching has completed. Reviewed-by: Laura Abbott Reviewed-by: Mark Rutland Tested-by: Mark Rutland Signed-off-by: Ard Biesheuvel Signed-off-by: Catalin Marinas Signed-off-by: Alex Shi --- arch/arm64/include/asm/mmu.h | 1 + arch/arm64/kernel/alternative.c | 11 ++++++----- arch/arm64/kernel/smp.c | 1 + arch/arm64/mm/mmu.c | 22 +++++++++++++++++----- 4 files changed, 25 insertions(+), 10 deletions(-) diff --git a/arch/arm64/include/asm/mmu.h b/arch/arm64/include/asm/mmu.h index 8d9fce0..b075140 100644 --- a/arch/arm64/include/asm/mmu.h +++ b/arch/arm64/include/asm/mmu.h @@ -36,5 +36,6 @@ extern void create_pgd_mapping(struct mm_struct *mm, phys_addr_t phys, unsigned long virt, phys_addr_t size, pgprot_t prot, bool allow_block_mappings); extern void *fixmap_remap_fdt(phys_addr_t dt_phys); +extern void mark_linear_text_alias_ro(void); #endif diff --git a/arch/arm64/kernel/alternative.c b/arch/arm64/kernel/alternative.c index 06d650f..8840c10 100644 --- a/arch/arm64/kernel/alternative.c +++ b/arch/arm64/kernel/alternative.c @@ -105,11 +105,11 @@ static u32 get_alt_insn(struct alt_instr *alt, u32 *insnptr, u32 *altinsnptr) return insn; } -static void __apply_alternatives(void *alt_region) +static void __apply_alternatives(void *alt_region, bool use_linear_alias) { struct alt_instr *alt; struct alt_region *region = alt_region; - u32 *origptr, *replptr; + u32 *origptr, *replptr, *updptr; for (alt = region->begin; alt < region->end; alt++) { u32 insn; @@ -124,11 +124,12 @@ static void __apply_alternatives(void *alt_region) origptr = ALT_ORIG_PTR(alt); replptr = ALT_REPL_PTR(alt); + updptr = use_linear_alias ? (u32 *)lm_alias(origptr) : origptr; nr_inst = alt->alt_len / sizeof(insn); for (i = 0; i < nr_inst; i++) { insn = get_alt_insn(alt, origptr + i, replptr + i); - *(origptr + i) = cpu_to_le32(insn); + updptr[i] = cpu_to_le32(insn); } flush_icache_range((uintptr_t)origptr, @@ -155,7 +156,7 @@ static int __apply_alternatives_multi_stop(void *unused) isb(); } else { BUG_ON(patched); - __apply_alternatives(®ion); + __apply_alternatives(®ion, true); /* Barriers provided by the cache flushing */ WRITE_ONCE(patched, 1); } @@ -176,5 +177,5 @@ void apply_alternatives(void *start, size_t length) .end = start + length, }; - __apply_alternatives(®ion); + __apply_alternatives(®ion, false); } diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c index a70f7d3..66db515 100644 --- a/arch/arm64/kernel/smp.c +++ b/arch/arm64/kernel/smp.c @@ -426,6 +426,7 @@ void __init smp_cpus_done(unsigned int max_cpus) setup_cpu_features(); hyp_mode_check(); apply_alternatives_all(); + mark_linear_text_alias_ro(); } void __init smp_prepare_boot_cpu(void) diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c index d5cc6d7..5dc72c0 100644 --- a/arch/arm64/mm/mmu.c +++ b/arch/arm64/mm/mmu.c @@ -354,16 +354,28 @@ static void __init __map_memblock(pgd_t *pgd, phys_addr_t start, phys_addr_t end !debug_pagealloc_enabled()); /* - * Map the linear alias of the [_text, __init_begin) interval as - * read-only/non-executable. This makes the contents of the - * region accessible to subsystems such as hibernate, but - * protects it from inadvertent modification or execution. + * Map the linear alias of the [_text, __init_begin) interval + * as non-executable now, and remove the write permission in + * mark_linear_text_alias_ro() below (which will be called after + * alternative patching has completed). This makes the contents + * of the region accessible to subsystems such as hibernate, + * but protects it from inadvertent modification or execution. */ __create_pgd_mapping(pgd, kernel_start, __phys_to_virt(kernel_start), - kernel_end - kernel_start, PAGE_KERNEL_RO, + kernel_end - kernel_start, PAGE_KERNEL, early_pgtable_alloc, !debug_pagealloc_enabled()); } +void __init mark_linear_text_alias_ro(void) +{ + /* + * Remove the write permissions from the linear alias of .text/.rodata + */ + create_mapping_late(__pa_symbol(_text), (unsigned long)lm_alias(_text), + (unsigned long)__init_begin - (unsigned long)_text, + PAGE_KERNEL_RO); +} + static void __init map_mem(pgd_t *pgd) { struct memblock_region *reg; -- 2.7.4