From patchwork Tue Feb 14 20:52:38 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 9572869 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 5E48C60578 for ; Tue, 14 Feb 2017 20:55:30 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4D00726C9B for ; Tue, 14 Feb 2017 20:55:30 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4187A2840E; Tue, 14 Feb 2017 20:55:30 +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 4CDC726C9B for ; Tue, 14 Feb 2017 20:55:29 +0000 (UTC) Received: (qmail 26385 invoked by uid 550); 14 Feb 2017 20:55:16 -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 26123 invoked from network); 14 Feb 2017 20:55:12 -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=VtePwSi0OLlpK4NZy9Kf833xoVq5jMfBfm+ByZQYELg=; b=fV4h7a2skjpEwGPbhWmoFDACuV+GqgeQrb/K2B6sEm9iIvfFHmh09rrGXl9zFF4c6u JAi/NzZiKjsy6rIRcmMaeHnyl7SP+TeFHQraMyDD2qV08qdepUhyZZ7+zawH8Rvr5XQY SsVmVj4NI0LXt7cCJeFPF+GPbUMSAp8hOW6wk= 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=VtePwSi0OLlpK4NZy9Kf833xoVq5jMfBfm+ByZQYELg=; b=reqYRhcKZjYLuceudHseFvWZLWAtz+me8SfdVJYD/kazR5GwLSnblTHioYWcgKZA1C +8lI8nXe2q0UGHjyYdBVHae4EzqaWa6nyd4ge9OBe/wHIgZOMrWxNGSuKBJ/eu6YSkxE jWKNDN1HOyqWiUDB3K3Wv2Qf4xVy/fp4VgK2B67JduV56i8GDeultSSFWMPxMUCwDr5/ QrPpeK71/qS9F963NPkyCg9ObQJM9gm//rYTmSNwHUmSgHX5VQlUQ7wQ2ztZtB0dFLzS 6qtpcg9b240fhDG8s268ythsezWSQrAM7t3YRBSPRP+Z7z9nMzy2mo+PYT0mybxEtlyC /xcg== X-Gm-Message-State: AMke39nKWTNuXNz457eMujIEGHmxka9m6CS7gNQv66z6s7zcrXFuhLvExe1GRoxQj+M7H9Jn X-Received: by 10.223.142.1 with SMTP id n1mr26221541wrb.185.1487105701384; Tue, 14 Feb 2017 12:55:01 -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: kernel-hardening@lists.openwall.com, kvmarm@lists.cs.columbia.edu, marc.zyngier@arm.com, andre.przywara@arm.com, suzuki.poulose@arm.com, james.morse@arm.com, keescook@chromium.org, Ard Biesheuvel Date: Tue, 14 Feb 2017 20:52:38 +0000 Message-Id: <1487105558-21897-6-git-send-email-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1487105558-21897-1-git-send-email-ard.biesheuvel@linaro.org> References: <1487105558-21897-1-git-send-email-ard.biesheuvel@linaro.org> Subject: [kernel-hardening] [PATCH v3 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 70a492b36fe7..cb9f2716c4b6 100644 --- a/arch/arm64/mm/mmu.c +++ b/arch/arm64/mm/mmu.c @@ -485,14 +485,18 @@ early_param("rodata", parse_rodata); */ 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; pgprot_t text_prot = rodata_enabled ? PAGE_KERNEL_ROX : PAGE_KERNEL_EXEC; map_kernel_segment(pgd, _text, _etext, text_prot, &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, text_prot, + &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))) {