From: Alex Shi <alex.shi@linaro.org> To: Marc Zyngier <marc.zyngier@arm.com>, Will Deacon <will.deacon@arm.com>, Ard Biesheuvel <ard.biesheuvel@linaro.org>, Catalin Marinas <catalin.marinas@arm.com>, stable@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Cc: Alex Shi <alex.shi@linaro.org> Subject: [PATCH 02/45] arm64: alternatives: apply boot time fixups via the linear mapping Date: Thu, 1 Mar 2018 20:53:39 +0800 [thread overview] Message-ID: <1519908862-11425-3-git-send-email-alex.shi@linaro.org> (raw) In-Reply-To: <1519908862-11425-1-git-send-email-alex.shi@linaro.org> From: Ard Biesheuvel <ard.biesheuvel@linaro.org> 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 <labbott@redhat.com> Reviewed-by: Mark Rutland <mark.rutland@arm.com> Tested-by: Mark Rutland <mark.rutland@arm.com> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com> Signed-off-by: Alex Shi <alex.shi@linaro.org> --- 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
WARNING: multiple messages have this Message-ID (diff)
From: alex.shi@linaro.org (Alex Shi) To: linux-arm-kernel@lists.infradead.org Subject: [PATCH 02/45] arm64: alternatives: apply boot time fixups via the linear mapping Date: Thu, 1 Mar 2018 20:53:39 +0800 [thread overview] Message-ID: <1519908862-11425-3-git-send-email-alex.shi@linaro.org> (raw) In-Reply-To: <1519908862-11425-1-git-send-email-alex.shi@linaro.org> From: Ard Biesheuvel <ard.biesheuvel@linaro.org> 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 <labbott@redhat.com> Reviewed-by: Mark Rutland <mark.rutland@arm.com> Tested-by: Mark Rutland <mark.rutland@arm.com> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com> Signed-off-by: Alex Shi <alex.shi@linaro.org> --- 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
next prev parent reply other threads:[~2018-03-01 12:55 UTC|newest] Thread overview: 119+ messages / expand[flat|nested] mbox.gz Atom feed top 2018-03-01 12:53 [PATCH 00/45] arm Spectre fix backport review for LTS 4.9 Alex Shi 2018-03-01 12:53 ` Alex Shi 2018-03-01 12:53 ` [PATCH 01/45] mm: Introduce lm_alias Alex Shi 2018-03-01 12:53 ` Alex Shi 2018-03-01 12:53 ` Alex Shi [this message] 2018-03-01 12:53 ` [PATCH 02/45] arm64: alternatives: apply boot time fixups via the linear mapping Alex Shi 2018-03-01 12:53 ` [PATCH 03/45] arm64: barrier: Add CSDB macros to control data-value prediction Alex Shi 2018-03-01 12:53 ` Alex Shi 2018-03-01 12:53 ` [PATCH 04/45] arm64: Implement array_index_mask_nospec() Alex Shi 2018-03-01 12:53 ` Alex Shi 2018-03-01 12:53 ` [PATCH 05/45] arm64: move TASK_* definitions to <asm/processor.h> Alex Shi 2018-03-01 12:53 ` Alex Shi 2018-03-01 12:53 ` [PATCH 06/45] arm64: Factor out PAN enabling/disabling into separate uaccess_* macros Alex Shi 2018-03-01 12:53 ` Alex Shi 2018-03-01 12:53 ` [PATCH 07/45] arm64: Factor out TTBR0_EL1 post-update workaround into a specific asm macro Alex Shi 2018-03-01 12:53 ` Alex Shi 2018-03-01 12:53 ` [PATCH 08/45] arm64: uaccess: consistently check object sizes Alex Shi 2018-03-01 12:53 ` Alex Shi 2018-03-01 12:53 ` [PATCH 09/45] arm64: Make USER_DS an inclusive limit Alex Shi 2018-03-01 12:53 ` Alex Shi 2018-03-01 12:53 ` [PATCH 10/45] arm64: Use pointer masking to limit uaccess speculation Alex Shi 2018-03-01 12:53 ` Alex Shi 2018-03-01 12:53 ` [PATCH 11/45] arm64: syscallno is secretly an int, make it official Alex Shi 2018-03-01 12:53 ` Alex Shi 2018-03-01 12:53 ` [PATCH 12/45] arm64: entry: Ensure branch through syscall table is bounded under speculation Alex Shi 2018-03-01 12:53 ` Alex Shi 2018-03-01 12:53 ` [PATCH 13/45] arm64: uaccess: Prevent speculative use of the current addr_limit Alex Shi 2018-03-01 12:53 ` Alex Shi 2018-03-01 12:53 ` [PATCH 14/45] arm64: uaccess: Don't bother eliding access_ok checks in __{get, put}_user Alex Shi 2018-03-01 12:53 ` Alex Shi 2018-03-01 12:53 ` [PATCH 15/45] arm64: uaccess: Mask __user pointers for __arch_{clear, copy_*}_user Alex Shi 2018-03-01 12:53 ` Alex Shi 2018-03-01 12:53 ` [PATCH 16/45] arm64: futex: Mask __user pointers prior to dereference Alex Shi 2018-03-01 12:53 ` Alex Shi 2018-03-01 12:53 ` [PATCH 17/45] drivers/firmware: Expose psci_get_version through psci_ops structure Alex Shi 2018-03-01 12:53 ` Alex Shi 2018-03-01 12:53 ` [PATCH 18/45] arm64: cpufeature: __this_cpu_has_cap() shouldn't stop early Alex Shi 2018-03-01 12:53 ` Alex Shi 2018-03-01 12:53 ` [PATCH 19/45] arm64: cpu_errata: Allow an erratum to be match for all revisions of a core Alex Shi 2018-03-01 12:53 ` Alex Shi 2018-03-01 12:53 ` [PATCH 20/45] arm64: Run enable method for errata work arounds on late CPUs Alex Shi 2018-03-01 12:53 ` Alex Shi 2018-03-01 12:53 ` [PATCH 21/45] arm64: cpufeature: Pass capability structure to ->enable callback Alex Shi 2018-03-01 12:53 ` Alex Shi 2018-03-01 12:53 ` [PATCH 22/45] arm64: Move post_ttbr_update_workaround to C code Alex Shi 2018-03-01 12:53 ` Alex Shi 2018-03-01 12:54 ` [PATCH 23/45] arm64: Add skeleton to harden the branch predictor against aliasing attacks Alex Shi 2018-03-01 12:54 ` Alex Shi 2018-03-01 12:54 ` [PATCH 24/45] arm64: Move BP hardening to check_and_switch_context Alex Shi 2018-03-01 12:54 ` Alex Shi 2018-03-01 12:54 ` [PATCH 25/45] arm64: KVM: Use per-CPU vector when BP hardening is enabled Alex Shi 2018-03-01 12:54 ` Alex Shi 2018-03-01 12:54 ` [PATCH 26/45] arm64: entry: Apply BP hardening for high-priority synchronous exceptions Alex Shi 2018-03-01 12:54 ` Alex Shi 2018-03-01 12:54 ` [PATCH 27/45] arm64: entry: Apply BP hardening for suspicious interrupts from EL0 Alex Shi 2018-03-01 12:54 ` Alex Shi 2018-03-01 12:54 ` [PATCH 28/45] arm64: cputype: Add missing MIDR values for Cortex-A72 and Cortex-A75 Alex Shi 2018-03-01 12:54 ` Alex Shi 2018-03-01 12:54 ` [PATCH 29/45] arm64: Implement branch predictor hardening for affected Cortex-A CPUs Alex Shi 2018-03-01 12:54 ` Alex Shi 2018-03-01 12:54 ` [PATCH 30/45] arm64: KVM: Increment PC after handling an SMC trap Alex Shi 2018-03-01 12:54 ` Alex Shi 2018-03-01 12:54 ` [PATCH 31/45] arm/arm64: KVM: Consolidate the PSCI include files Alex Shi 2018-03-01 12:54 ` Alex Shi 2018-03-01 12:54 ` [PATCH 32/45] arm/arm64: KVM: Add PSCI_VERSION helper Alex Shi 2018-03-01 12:54 ` Alex Shi 2018-03-01 12:54 ` [PATCH 33/45] arm/arm64: KVM: Add smccc accessors to PSCI code Alex Shi 2018-03-01 12:54 ` Alex Shi 2018-03-01 12:54 ` [PATCH 34/45] arm/arm64: KVM: Implement PSCI 1.0 support Alex Shi 2018-03-01 12:54 ` Alex Shi 2018-03-01 12:54 ` [PATCH 35/45] arm/arm64: KVM: Advertise SMCCC v1.1 Alex Shi 2018-03-01 12:54 ` Alex Shi 2018-03-01 12:54 ` [PATCH 36/45] arm64: KVM: Make PSCI_VERSION a fast path Alex Shi 2018-03-01 12:54 ` Alex Shi 2018-03-01 12:54 ` [PATCH 37/45] arm/arm64: KVM: Turn kvm_psci_version into a static inline Alex Shi 2018-03-01 12:54 ` Alex Shi 2018-03-01 12:54 ` [PATCH 38/45] arm64: KVM: Report SMCCC_ARCH_WORKAROUND_1 BP hardening support Alex Shi 2018-03-01 12:54 ` Alex Shi 2018-03-01 12:54 ` [PATCH 39/45] arm64: KVM: Add SMCCC_ARCH_WORKAROUND_1 fast handling Alex Shi 2018-03-01 12:54 ` Alex Shi 2018-03-01 12:54 ` [PATCH 40/45] firmware/psci: Expose PSCI conduit Alex Shi 2018-03-01 12:54 ` Alex Shi 2018-03-01 12:54 ` [PATCH 41/45] firmware/psci: Expose SMCCC version through psci_ops Alex Shi 2018-03-01 12:54 ` Alex Shi 2018-03-01 12:54 ` [PATCH 42/45] arm/arm64: smccc: Make function identifiers an unsigned quantity Alex Shi 2018-03-01 12:54 ` Alex Shi 2018-03-01 12:54 ` [PATCH 43/45] arm/arm64: smccc: Implement SMCCC v1.1 inline primitive Alex Shi 2018-03-01 12:54 ` Alex Shi 2018-03-01 12:54 ` [PATCH 44/45] arm64: Add ARM_SMCCC_ARCH_WORKAROUND_1 BP hardening support Alex Shi 2018-03-01 12:54 ` Alex Shi 2018-03-01 12:54 ` [PATCH 45/45] arm64: Kill PSCI_GET_VERSION as a variant-2 workaround Alex Shi 2018-03-01 12:54 ` Alex Shi 2018-03-01 16:45 ` [PATCH 00/45] arm Spectre fix backport review for LTS 4.9 Greg KH 2018-03-01 16:45 ` Greg KH 2018-03-02 7:26 ` Alex Shi 2018-03-02 7:26 ` Alex Shi 2018-03-01 16:46 ` Greg KH 2018-03-01 16:46 ` Greg KH 2018-03-02 9:02 ` Alex Shi 2018-03-02 9:02 ` Alex Shi 2018-03-02 10:29 ` Marc Zyngier 2018-03-02 10:29 ` Marc Zyngier 2018-03-03 0:52 ` Alex Shi 2018-03-03 0:52 ` Alex Shi 2018-03-02 10:30 ` Will Deacon 2018-03-02 10:30 ` Will Deacon 2018-03-03 0:54 ` Alex Shi 2018-03-03 0:54 ` Alex Shi 2018-03-08 12:27 ` Pavel Machek 2018-03-08 12:27 ` Pavel Machek 2018-03-08 13:21 ` Pali Rohár 2018-03-08 13:21 ` Pali Rohár 2018-03-08 13:33 ` Ivaylo Dimitrov 2018-03-08 13:33 ` Ivaylo Dimitrov 2018-03-08 13:33 ` Ivaylo Dimitrov 2018-03-08 13:35 ` Marc Zyngier 2018-03-08 13:35 ` Marc Zyngier 2018-03-08 17:01 ` Pali Rohár 2018-03-08 17:01 ` Pali Rohár
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=1519908862-11425-3-git-send-email-alex.shi@linaro.org \ --to=alex.shi@linaro.org \ --cc=ard.biesheuvel@linaro.org \ --cc=catalin.marinas@arm.com \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-kernel@vger.kernel.org \ --cc=marc.zyngier@arm.com \ --cc=stable@vger.kernel.org \ --cc=will.deacon@arm.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.