From patchwork Wed Dec 30 15:26:08 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 59086 Delivered-To: patch@linaro.org Received: by 10.112.130.2 with SMTP id oa2csp2910168lbb; Wed, 30 Dec 2015 07:28:11 -0800 (PST) X-Received: by 10.98.18.136 with SMTP id 8mr76312582pfs.62.1451489291586; Wed, 30 Dec 2015 07:28:11 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id cm4si25440406pad.81.2015.12.30.07.28.11; Wed, 30 Dec 2015 07:28:11 -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; 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; dkim=neutral (body hash did not verify) header.i=@linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755103AbbL3P2J (ORCPT + 29 others); Wed, 30 Dec 2015 10:28:09 -0500 Received: from mail-wm0-f54.google.com ([74.125.82.54]:37142 "EHLO mail-wm0-f54.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754670AbbL3P0j (ORCPT ); Wed, 30 Dec 2015 10:26:39 -0500 Received: by mail-wm0-f54.google.com with SMTP id f206so81614545wmf.0 for ; Wed, 30 Dec 2015 07:26:38 -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=oQon6h8uxoyuOKk4CJYpFikBpeM1uaabjmFZU4innt8=; b=P5Bgl73A/MROIJOeAqCR5LeqpF2c6B0TzqRtryvEphRzHVPxqT2VlIIhrdjL4TO9Xt T87O/bhLe+r3ojQQ+M0a9UfB+RLOdVyfZUL05ISmflLuW6e5HTjGMgMsmt5rq0YCyrP4 SYNscuqAnlYpQjuxw1kgfW2PCyKA4LTIRNz0A= 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=oQon6h8uxoyuOKk4CJYpFikBpeM1uaabjmFZU4innt8=; b=Ub/of7MPpDCPIfGt/F3ZaWlcq1Av0AZAgPcShNAXrziPUr1fMOSpZDhBFs+TnhH1tD nc5KnOcxlfa9L2TrIDF1fxCscHJY76ukA+4sRbNNofXw/QF1mj2JrKWhR6bzuA5FFe5p 5j9J5tD2ApgSA/RJXCxGInz1e7SHJ5b+Kaj3iQqSYtjEh6aiEzWxWJm36wTB7CHcHXhZ JTXhdw8INKms4cKba6TtRZsQjd0sNEClvbKpt0uRunVccAOIVIyqikJXrkLMKkXtD3fP p0Hu2QKI8Ub2kUJUtYct09YkU5v+Lyejz/GmtbE17tp/w+8IgeYScKBTVdpzYHt1ai9S P+oA== X-Gm-Message-State: ALoCoQmlDmMGvejm+0rj1mtTOe3p2Ad8yJoWNpE4SIBVF38261LiUrxvz6QDMKbD280DSSLDnv83m3dHDuSQVUz9Mh5LgVJfoA== X-Received: by 10.194.174.73 with SMTP id bq9mr72181673wjc.115.1451489197865; Wed, 30 Dec 2015 07:26:37 -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 z137sm31510865wmc.8.2015.12.30.07.26.36 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 30 Dec 2015 07:26:37 -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, linux-kernel@vger.kernel.org Cc: stuart.yoder@freescale.com, bhupesh.sharma@freescale.com, arnd@arndb.de, marc.zyngier@arm.com, christoffer.dall@linaro.org, Ard Biesheuvel Subject: [PATCH v2 09/13] arm64: avoid R_AARCH64_ABS64 relocations for Image header fields Date: Wed, 30 Dec 2015 16:26:08 +0100 Message-Id: <1451489172-17420-10-git-send-email-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1451489172-17420-1-git-send-email-ard.biesheuvel@linaro.org> References: <1451489172-17420-1-git-send-email-ard.biesheuvel@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Unfortunately, the current way of 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 or R_AARCH64_ABS32 relocations (which, interestingly enough, do get resolved at build time) Signed-off-by: Ard Biesheuvel --- arch/arm64/include/asm/assembler.h | 15 ++++++++ arch/arm64/kernel/head.S | 17 +++++++-- arch/arm64/kernel/image.h | 37 ++++++-------------- 3 files changed, 40 insertions(+), 29 deletions(-) -- 2.5.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/ diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h index 8094d50f05bc..39bf158255d7 100644 --- a/arch/arm64/include/asm/assembler.h +++ b/arch/arm64/include/asm/assembler.h @@ -204,4 +204,19 @@ lr .req x30 // link register .size __pi_##x, . - x; \ ENDPROC(x) + .macro le16, val + .byte \val & 0xff + .byte (\val >> 8) & 0xff + .endm + + .macro le32, val + le16 \val + le16 \val >> 16 + .endm + + .macro le64, val + le32 \val + le32 \val >> 32 + .endm + #endif /* __ASM_ASSEMBLER_H */ diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S index 6434c844a0e4..ccbb1bd46026 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. * --------------------------- @@ -83,9 +94,9 @@ 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 + le64 TEXT_OFFSET // Image load offset from start of RAM, little-endian + .long _kernel_size_le, 0 // Effective size of kernel image, little-endian + le64 __HEAD_FLAGS // Informative flags, little-endian .quad 0 // reserved .quad 0 // reserved .quad 0 // reserved diff --git a/arch/arm64/kernel/image.h b/arch/arm64/kernel/image.h index bc2abb8b1599..bb6b0e69d0a4 100644 --- a/arch/arm64/kernel/image.h +++ b/arch/arm64/kernel/image.h @@ -26,41 +26,26 @@ * 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. + * Note that this will not work for 64-bit values: these are resolved using + * R_AARCH64_ABS64 relocations, which are fixed up at runtime rather than at + * build time when building the PIE executable (for KASLR). */ #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)) +#define DATA_LE32(data) \ + ((((data) & 0x000000ff) << 24) | \ + (((data) & 0x0000ff00) << 8) | \ + (((data) & 0x00ff0000) >> 8) | \ + (((data) & 0xff000000) >> 24)) #else -#define DATA_LE64(data) ((data) & 0xffffffffffffffff) +#define DATA_LE32(data) ((data) & 0xffffffff) #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. + * regardless of the endianness of the kernel. */ #define HEAD_SYMBOLS \ - _kernel_size_le = DATA_LE64(_end - _text); \ - _kernel_offset_le = DATA_LE64(TEXT_OFFSET); \ - _kernel_flags_le = DATA_LE64(__HEAD_FLAGS); + _kernel_size_le = DATA_LE32(_end - _text); #ifdef CONFIG_EFI