From patchwork Sat Feb 11 20:23:06 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 9568155 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 0F0AD6043D for ; Sat, 11 Feb 2017 20:24:33 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F3F47284F6 for ; Sat, 11 Feb 2017 20:24:32 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E88F128567; Sat, 11 Feb 2017 20:24:32 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.1 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from mother.openwall.net (mother.openwall.net [195.42.179.200]) by mail.wl.linuxfoundation.org (Postfix) with SMTP id 1D452284F6 for ; Sat, 11 Feb 2017 20:24:31 +0000 (UTC) Received: (qmail 22028 invoked by uid 550); 11 Feb 2017 20:24:27 -0000 Mailing-List: contact kernel-hardening-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Delivered-To: mailing list kernel-hardening@lists.openwall.com Received: (qmail 21756 invoked from network); 11 Feb 2017 20:24:24 -0000 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=81ig16RksrLJ5Q7fpEmIxqmS6X13YiI/yuM7HfNcxBA=; b=dU9iPRFy01/iW783fl438B0No6plJXvFcPFc+uYkmPaTHF3SqceKR0oy/30WFPl7+w TQdZB31XLjmqj4jLtMrlzLRqNHt3PJuc2o5xzcoGU2G9JbRslib15LEXeiGedJXeRbAP EobIRbZNxRj//FrMjO3S2f66Xg5bPvkKUiRwA= 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=81ig16RksrLJ5Q7fpEmIxqmS6X13YiI/yuM7HfNcxBA=; b=Oi4S+ciDlbok2qWSErpM3ZH2Xwc6vsxsrtqErKCTyH7jd7D5dJC+ZwMLWL5vRhLaHt 5sEOJa6TSM8Y6UV0AxlEB1t604yKbeSLTmik/KDMbkAsxMgnR4W7lnrwAyR0BxBmmA3h NJDPx5V6PaYVPkQVF3mRCVx3t5aYJe4X6QdLocqb02xZeVqkRQ5rymuSe6nYirBEePqS VQkLVMm5Dxt6oUcWn0+Rqz53P+//327uZ0UYCS1KMwYOkb7dgCO1Lly6mC0UWw5tCokn JOXsZ08j6ZWbj2W41aplNpNAvF1s9TsCZHNVnnneHMptWarW0QKwx1a1prEHG+CZ8RtH tOww== X-Gm-Message-State: AMke39n9IhJfRbwWSalq/6WwYSlUmFe0tCzdz3cQKtWaR8/1E7vLkUQq80UoSAkIrIDjJm9F X-Received: by 10.223.172.136 with SMTP id o8mr12779545wrc.76.1486844653477; Sat, 11 Feb 2017 12:24:13 -0800 (PST) From: Ard Biesheuvel To: linux-arm-kernel@lists.infradead.org, mark.rutland@arm.com, catalin.marinas@arm.com, will.deacon@arm.com, labbott@fedoraproject.org Cc: kvmarm@lists.cs.columbia.edu, marc.zyngier@arm.com, andre.przywara@arm.com, Suzuki.Poulose@arm.com, james.morse@arm.com, keescook@chromium.org, kernel-hardening@lists.openwall.com, Ard Biesheuvel Date: Sat, 11 Feb 2017 20:23:06 +0000 Message-Id: <1486844586-26135-6-git-send-email-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1486844586-26135-1-git-send-email-ard.biesheuvel@linaro.org> References: <1486844586-26135-1-git-send-email-ard.biesheuvel@linaro.org> Subject: [kernel-hardening] [PATCH v2 5/5] arm64: mmu: apply strict permissions to .init.text and .init.data X-Virus-Scanned: ClamAV using ClamSMTP To avoid having mappings that are writable and executable at the same time, split the init region into a .init.text region that is mapped read-only, and a .init.data region that is mapped non-executable. This is possible now that the alternative patching occurs via the linear mapping, and the linear alias of the init region is always mapped writable (but never executable). Since the alternatives descriptions themselves are read-only data, move those into the .init.text region. Reviewed-by: Laura Abbott Signed-off-by: Ard Biesheuvel --- arch/arm64/include/asm/sections.h | 3 ++- arch/arm64/kernel/vmlinux.lds.S | 25 +++++++++++++------- arch/arm64/mm/mmu.c | 12 ++++++---- 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/arch/arm64/include/asm/sections.h b/arch/arm64/include/asm/sections.h index 4e7e7067afdb..22582819b2e5 100644 --- a/arch/arm64/include/asm/sections.h +++ b/arch/arm64/include/asm/sections.h @@ -24,7 +24,8 @@ extern char __hibernate_exit_text_start[], __hibernate_exit_text_end[]; extern char __hyp_idmap_text_start[], __hyp_idmap_text_end[]; extern char __hyp_text_start[], __hyp_text_end[]; extern char __idmap_text_start[], __idmap_text_end[]; +extern char __initdata_begin[], __initdata_end[]; +extern char __inittext_begin[], __inittext_end[]; extern char __irqentry_text_start[], __irqentry_text_end[]; extern char __mmuoff_data_start[], __mmuoff_data_end[]; - #endif /* __ASM_SECTIONS_H */ diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S index b8deffa9e1bf..2c93d259046c 100644 --- a/arch/arm64/kernel/vmlinux.lds.S +++ b/arch/arm64/kernel/vmlinux.lds.S @@ -143,12 +143,27 @@ SECTIONS . = ALIGN(SEGMENT_ALIGN); __init_begin = .; + __inittext_begin = .; INIT_TEXT_SECTION(8) .exit.text : { ARM_EXIT_KEEP(EXIT_TEXT) } + . = ALIGN(4); + .altinstructions : { + __alt_instructions = .; + *(.altinstructions) + __alt_instructions_end = .; + } + .altinstr_replacement : { + *(.altinstr_replacement) + } + + . = ALIGN(PAGE_SIZE); + __inittext_end = .; + __initdata_begin = .; + .init.data : { INIT_DATA INIT_SETUP(16) @@ -164,15 +179,6 @@ SECTIONS PERCPU_SECTION(L1_CACHE_BYTES) - . = ALIGN(4); - .altinstructions : { - __alt_instructions = .; - *(.altinstructions) - __alt_instructions_end = .; - } - .altinstr_replacement : { - *(.altinstr_replacement) - } .rela : ALIGN(8) { *(.rela .rela*) } @@ -181,6 +187,7 @@ SECTIONS __rela_size = SIZEOF(.rela); . = ALIGN(SEGMENT_ALIGN); + __initdata_end = .; __init_end = .; _data = .; diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c index e97f1ce967ec..c53c43b4ed3f 100644 --- a/arch/arm64/mm/mmu.c +++ b/arch/arm64/mm/mmu.c @@ -479,12 +479,16 @@ static void __init map_kernel_segment(pgd_t *pgd, void *va_start, void *va_end, */ static void __init map_kernel(pgd_t *pgd) { - static struct vm_struct vmlinux_text, vmlinux_rodata, vmlinux_init, vmlinux_data; + static struct vm_struct vmlinux_text, vmlinux_rodata, vmlinux_inittext, + vmlinux_initdata, vmlinux_data; map_kernel_segment(pgd, _text, _etext, PAGE_KERNEL_ROX, &vmlinux_text); - map_kernel_segment(pgd, __start_rodata, __init_begin, PAGE_KERNEL, &vmlinux_rodata); - map_kernel_segment(pgd, __init_begin, __init_end, PAGE_KERNEL_EXEC, - &vmlinux_init); + map_kernel_segment(pgd, __start_rodata, __inittext_begin, PAGE_KERNEL, + &vmlinux_rodata); + map_kernel_segment(pgd, __inittext_begin, __inittext_end, PAGE_KERNEL_ROX, + &vmlinux_inittext); + map_kernel_segment(pgd, __initdata_begin, __initdata_end, PAGE_KERNEL, + &vmlinux_initdata); map_kernel_segment(pgd, _data, _end, PAGE_KERNEL, &vmlinux_data); if (!pgd_val(*pgd_offset_raw(pgd, FIXADDR_START))) {