From patchwork Mon Dec 28 11:20:51 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 59014 Delivered-To: patch@linaro.org Received: by 10.112.130.2 with SMTP id oa2csp1648584lbb; Mon, 28 Dec 2015 03:26:21 -0800 (PST) X-Received: by 10.66.129.232 with SMTP id nz8mr40325541pab.102.1451301981730; Mon, 28 Dec 2015 03:26:21 -0800 (PST) Return-Path: Received: from bombadil.infradead.org (bombadil.infradead.org. [2001:1868:205::9]) by mx.google.com with ESMTPS id tl10si8566836pab.154.2015.12.28.03.26.21 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 28 Dec 2015 03:26:21 -0800 (PST) Received-SPF: pass (google.com: domain of linux-arm-kernel-bounces+patch=linaro.org@lists.infradead.org designates 2001:1868:205::9 as permitted sender) client-ip=2001:1868:205::9; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-arm-kernel-bounces+patch=linaro.org@lists.infradead.org designates 2001:1868:205::9 as permitted sender) smtp.mailfrom=linux-arm-kernel-bounces+patch=linaro.org@lists.infradead.org; dkim=neutral (body hash did not verify) header.i=@linaro.org Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1aDVvC-0005IS-2V; Mon, 28 Dec 2015 11:25:02 +0000 Received: from mail-wm0-x229.google.com ([2a00:1450:400c:c09::229]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1aDVrr-0002j6-84 for linux-arm-kernel@lists.infradead.org; Mon, 28 Dec 2015 11:21:40 +0000 Received: by mail-wm0-x229.google.com with SMTP id l126so265565301wml.1 for ; Mon, 28 Dec 2015 03:21:14 -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=vvKIQRFLTDihFMSbcBFxkWqIxODwv144i2uyP9S9j54=; b=d1OOcmmT7F1XKh40E7eUXgHRrr6+E94nPpD3Tffv+LmcFownKdFZiatP4Shr27ieCn 5G6Jj/5QFmz3ctt4Ac+kyUmSDUDwxR1fWD44JfMhi5vVj35JuOublQNFhHCKdO89CQ57 KcR1FjO18i6x4TsSbLj5k2atCvrUk0clfmQYM= 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=vvKIQRFLTDihFMSbcBFxkWqIxODwv144i2uyP9S9j54=; b=IYuNcWeAPI62Hd4oU9Uke5i9L5kEaPQhFxfKX+IGfl3LJNqXFlLOm40U4eHeg5wVzN sbeu0T5UF5hmVNOpJGIC15JUah0EiIe0VpgouRMrsP7hhRstP++Y7SVyqsY81NtQayG7 +OxHfUJ0OnRHQCrnndhGhQvvi+ESRcemFbREhGGdt1F7ClVe3q1hrrSn54JM2yxIU9LR gqD83O2haIaoYmZp0swr9nzmFXuz9I7yh23iCCyjs54yOXQq78wKGlsX+oaOZAgWZ/PV ZxgBxdpXu19BL4lWtMfB8RZsj5LHt45QKxAKhhvPUfi8JgEMqjqsNzYSD3MxGFFIbuGy vzXA== X-Gm-Message-State: ALoCoQkYfzEZJjqSL5jtMMNfAK+ChUCbKkrzVMg2gTXqbieUho7y428lMd6LHOs0OtMzl0a5/vhd5MekRiPByQicbqYqm6odsg== X-Received: by 10.28.21.19 with SMTP id 19mr538206wmv.43.1451301673754; Mon, 28 Dec 2015 03:21:13 -0800 (PST) Received: from localhost.localdomain (cag06-7-83-153-85-71.fbx.proxad.net. [83.153.85.71]) by smtp.gmail.com with ESMTPSA id i63sm22556235wmf.24.2015.12.28.03.21.12 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 28 Dec 2015 03:21:13 -0800 (PST) From: Ard Biesheuvel To: linux-arm-kernel@lists.infradead.org, kernel-hardening@lists.openwall.com, will.deacon@arm.com, catalin.marinas@arm.com, mark.rutland@arm.com, leif.lindholm@linaro.org, keescook@chromium.org, lkml@vger.kernel.org Subject: [RFC PATCH 07/10] arm64: use assembly time constants for Image header fields Date: Mon, 28 Dec 2015 12:20:51 +0100 Message-Id: <1451301654-32019-8-git-send-email-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1451301654-32019-1-git-send-email-ard.biesheuvel@linaro.org> References: <1451301654-32019-1-git-send-email-ard.biesheuvel@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20151228_032135_810198_00791188 X-CRM114-Status: GOOD ( 19.77 ) X-Spam-Score: -2.7 (--) X-Spam-Report: SpamAssassin version 3.4.0 on bombadil.infradead.org summary: Content analysis details: (-2.7 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low trust [2a00:1450:400c:c09:0:0:0:229 listed in] [list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: bhupesh.sharma@freescale.com, stuart.yoder@freescale.com, Ard Biesheuvel MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patch=linaro.org@lists.infradead.org Unfortunately, using the linker to emit build time constants into the Image header will no longer work once we switch to the use of PIE executables. The reason is that such constants are emitted into the binary using R_AARCH64_ABS64 relocations, which we will resolve at runtime, not at build time, and the places targeted by those relocations will contain zeroes before that. So move back to assembly time constants. These will be emitted in the endianness of the target binary, so we will need a post-link fixup step to byte swap the header fields. Signed-off-by: Ard Biesheuvel --- arch/arm64/boot/Makefile | 1 + arch/arm64/kernel/head.S | 32 ++++++++++------ arch/arm64/kernel/image.h | 40 -------------------- arch/arm64/kernel/vmlinux.lds.S | 2 - scripts/arm64fixhdr.pl | 25 ++++++++++++ 5 files changed, 46 insertions(+), 54 deletions(-) -- 2.5.0 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel diff --git a/arch/arm64/boot/Makefile b/arch/arm64/boot/Makefile index abcbba2f01ba..b2da54b4b796 100644 --- a/arch/arm64/boot/Makefile +++ b/arch/arm64/boot/Makefile @@ -18,6 +18,7 @@ targets := Image Image.gz $(obj)/Image: vmlinux FORCE $(call if_changed,objcopy) + @$(srctree)/scripts/arm64fixhdr.pl $@ $(obj)/Image.bz2: $(obj)/Image FORCE $(call if_changed,bzip2) diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S index 6434c844a0e4..a03ffffd84cb 100644 --- a/arch/arm64/kernel/head.S +++ b/arch/arm64/kernel/head.S @@ -51,6 +51,17 @@ #define KERNEL_START _text #define KERNEL_END _end +#ifdef CONFIG_CPU_BIG_ENDIAN +#define __HEAD_FLAG_BE 1 +#else +#define __HEAD_FLAG_BE 0 +#endif + +#define __HEAD_FLAG_PAGE_SIZE ((PAGE_SHIFT - 10) / 2) + +#define __HEAD_FLAGS ((__HEAD_FLAG_BE << 0) | \ + (__HEAD_FLAG_PAGE_SIZE << 1)) + /* * Kernel startup entry point. * --------------------------- @@ -67,12 +78,12 @@ * in the entry routines. */ __HEAD +_head: /* * DO NOT MODIFY. Image header expected by Linux boot-loaders. */ #ifdef CONFIG_EFI -efi_head: /* * This add instruction has no meaningful effect except that * its opcode forms the magic "MZ" signature required by UEFI. @@ -83,25 +94,22 @@ efi_head: b stext // branch to kernel start, magic .long 0 // reserved #endif - .quad _kernel_offset_le // Image load offset from start of RAM, little-endian - .quad _kernel_size_le // Effective size of kernel image, little-endian - .quad _kernel_flags_le // Informative flags, little-endian + .quad TEXT_OFFSET // Image load offset from start of RAM, little-endian + .quad _end - _head // Effective size of kernel image, little-endian + .quad __HEAD_FLAGS // Informative flags, little-endian .quad 0 // reserved .quad 0 // reserved .quad 0 // reserved - .byte 0x41 // Magic number, "ARM\x64" - .byte 0x52 - .byte 0x4d - .byte 0x64 + .long 0x644d5241 // Magic number, "ARM\x64" #ifdef CONFIG_EFI - .long pe_header - efi_head // Offset to the PE header. + .long pe_header - _head // Offset to the PE header. #else .word 0 // reserved #endif #ifdef CONFIG_EFI .globl __efistub_stext_offset - .set __efistub_stext_offset, stext - efi_head + .set __efistub_stext_offset, stext - _head .align 3 pe_header: .ascii "PE" @@ -124,7 +132,7 @@ optional_header: .long _end - stext // SizeOfCode .long 0 // SizeOfInitializedData .long 0 // SizeOfUninitializedData - .long __efistub_entry - efi_head // AddressOfEntryPoint + .long __efistub_entry - _head // AddressOfEntryPoint .long __efistub_stext_offset // BaseOfCode extra_header_fields: @@ -139,7 +147,7 @@ extra_header_fields: .short 0 // MinorSubsystemVersion .long 0 // Win32VersionValue - .long _end - efi_head // SizeOfImage + .long _end - _head // SizeOfImage // Everything before the kernel image is considered part of the header .long __efistub_stext_offset // SizeOfHeaders diff --git a/arch/arm64/kernel/image.h b/arch/arm64/kernel/image.h index bc2abb8b1599..5f34770ba924 100644 --- a/arch/arm64/kernel/image.h +++ b/arch/arm64/kernel/image.h @@ -22,46 +22,6 @@ #error This file should only be included in vmlinux.lds.S #endif -/* - * There aren't any ELF relocations we can use to endian-swap values known only - * at link time (e.g. the subtraction of two symbol addresses), so we must get - * the linker to endian-swap certain values before emitting them. - */ -#ifdef CONFIG_CPU_BIG_ENDIAN -#define DATA_LE64(data) \ - ((((data) & 0x00000000000000ff) << 56) | \ - (((data) & 0x000000000000ff00) << 40) | \ - (((data) & 0x0000000000ff0000) << 24) | \ - (((data) & 0x00000000ff000000) << 8) | \ - (((data) & 0x000000ff00000000) >> 8) | \ - (((data) & 0x0000ff0000000000) >> 24) | \ - (((data) & 0x00ff000000000000) >> 40) | \ - (((data) & 0xff00000000000000) >> 56)) -#else -#define DATA_LE64(data) ((data) & 0xffffffffffffffff) -#endif - -#ifdef CONFIG_CPU_BIG_ENDIAN -#define __HEAD_FLAG_BE 1 -#else -#define __HEAD_FLAG_BE 0 -#endif - -#define __HEAD_FLAG_PAGE_SIZE ((PAGE_SHIFT - 10) / 2) - -#define __HEAD_FLAGS ((__HEAD_FLAG_BE << 0) | \ - (__HEAD_FLAG_PAGE_SIZE << 1)) - -/* - * These will output as part of the Image header, which should be little-endian - * regardless of the endianness of the kernel. While constant values could be - * endian swapped in head.S, all are done here for consistency. - */ -#define HEAD_SYMBOLS \ - _kernel_size_le = DATA_LE64(_end - _text); \ - _kernel_offset_le = DATA_LE64(TEXT_OFFSET); \ - _kernel_flags_le = DATA_LE64(__HEAD_FLAGS); - #ifdef CONFIG_EFI /* diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S index 363c2f529951..69dfa376e843 100644 --- a/arch/arm64/kernel/vmlinux.lds.S +++ b/arch/arm64/kernel/vmlinux.lds.S @@ -171,8 +171,6 @@ SECTIONS _end = .; STABS_DEBUG - - HEAD_SYMBOLS } /* diff --git a/scripts/arm64fixhdr.pl b/scripts/arm64fixhdr.pl new file mode 100755 index 000000000000..09895f412e5d --- /dev/null +++ b/scripts/arm64fixhdr.pl @@ -0,0 +1,25 @@ +#!/usr/bin/perl -w + +# Copyright (C) 2015 Linaro Ltd +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. + +use strict; + +undef $/; + +my $image = "arch/arm64/boot/Image"; +$image = $ARGV[0] if ($ARGV[0]); + +open(my $INFILE, "<", $image) or die("Failed to open $image for reading\n"); +my ($c,$to,$is,$fl,$r2,$r3,$r4,$magic,$pe) = unpack("Q<7L<2", <$INFILE>); +close($INFILE); + +exit 0 if ($magic == 0x644d5241); +die sprintf("ERROR: incorrect magic 0x%x\n",$magic) if ($magic != 0x41524d64); + +open(my $OUTFILE, "+<", $image) or die("Failed to open $image for writing\n"); +print $OUTFILE pack("Q6L>2",$c,$to,$is,$fl,$r2,$r3,$r4,$magic,$pe); +close($OUTFILE);