From: Ard Biesheuvel <ardb@kernel.org>
To: linux-arm-kernel@lists.infradead.org
Cc: clang-built-linux@googlegroups.com, will@kernel.org,
catalin.marinas@arm.com, keescook@chromium.org,
mark.rutland@arm.com, nathan@kernel.org,
Ard Biesheuvel <ardb@kernel.org>,
Sami Tolvanen <samitolvanen@google.com>,
Nick Desaulniers <ndesaulniers@google.com>
Subject: [RFC PATCH 2/2] arm64: kernel: switch to PIE code generation for relocatable kernels
Date: Wed, 27 Apr 2022 19:12:41 +0200 [thread overview]
Message-ID: <20220427171241.2426592-3-ardb@kernel.org> (raw)
In-Reply-To: <20220427171241.2426592-1-ardb@kernel.org>
We currently use ordinary, position dependent code generation for the
core kernel, which happens to default to the 'small' code model on both
GCC and Clang. This is the code model that relies on ADRP/ADD or
ADRP/LDR pairs for symbol references, which are PC-relative with a range
of -/+ 4 GiB, and therefore happen to be position independent in
practice.
This means that the fact that we can link the relocatable KASLR kernel
using the -pie linker flag (which generates the runtime relocations and
inserts them into the binary) is somewhat of a coincidence, and not
something which is explicitly supported by the toolchains.
The reason we have not used -fpie for code generation so far (which is
the compiler flag that should be used to generate code that is to be
linked with -pie) is that by default, it generates code based on
assumptions that only hold for shared libraries and PIE executables,
i.e., that gathering all relocatable quantities into a Global Offset
Table (GOT) is desirable because it reduces the CoW footprint, and
because it permits ELF symbol preemption (which lets an executable
override symbols defined in a shared library, in a way that forces the
shared library to update all of its internal references as well).
Ironically, this means we end up with many more absolute references that
all need to be fixed up at boot.
Fortunately, we can convince the compiler to handle this in a way that
is a bit more suitable for freestanding binaries such as the kernel, by
setting the 'hidden' visibility #pragma, which informs the compiler that
symbol preemption or CoW footprint are of no concern to us, and so
PC-relative references that are resolved at link time are perfectly
fine.
So let's enable this #pragma and build with -fpie when building a
relocatable kernel. This also means that all constant data items that
carry statically initialized pointer variables are now emitted into the
.data.rel.ro* sections, so move these into .rodata where they belong.
Code size impact (GCC):
Before:
text data bss total filename
16712396 18659064 534556 35906016 vmlinux
After:
text data bss total filename
16804400 18612876 534556 35951832 vmlinux
Code size impact (Clang):
Before:
text data bss total filename
17194584 13335060 535268 31064912 vmlinux
After:
text data bss total filename
17194536 13310032 535268 31039836 vmlinux
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
arch/arm64/Makefile | 4 ++++
arch/arm64/kernel/vmlinux.lds.S | 9 ++++-----
2 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
index 2f1de88651e6..94b6c51f5de6 100644
--- a/arch/arm64/Makefile
+++ b/arch/arm64/Makefile
@@ -18,6 +18,10 @@ ifeq ($(CONFIG_RELOCATABLE), y)
# with the relocation offsets always being zero.
LDFLAGS_vmlinux += -shared -Bsymbolic -z notext \
$(call ld-option, --no-apply-dynamic-relocs)
+
+# Generate position independent code without relying on a Global Offset Table
+KBUILD_CFLAGS_KERNEL += -fpie -include $(srctree)/include/linux/hidden.h
+
endif
ifeq ($(CONFIG_ARM64_ERRATUM_843419),y)
diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S
index edaf0faf766f..b1e071ac1acf 100644
--- a/arch/arm64/kernel/vmlinux.lds.S
+++ b/arch/arm64/kernel/vmlinux.lds.S
@@ -174,8 +174,6 @@ SECTIONS
KEXEC_TEXT
TRAMP_TEXT
*(.gnu.warning)
- . = ALIGN(16);
- *(.got) /* Global offset table */
}
/*
@@ -192,6 +190,8 @@ SECTIONS
/* everything from this point to __init_begin will be marked RO NX */
RO_DATA(PAGE_SIZE)
+ .data.rel.ro : ALIGN(8) { *(.got) *(.data.rel.ro*) }
+
HYPERVISOR_DATA_SECTIONS
idmap_pg_dir = .;
@@ -273,6 +273,8 @@ SECTIONS
_sdata = .;
RW_DATA(L1_CACHE_BYTES, PAGE_SIZE, THREAD_ALIGN)
+ .data.rel : ALIGN(8) { *(.data.rel*) }
+
/*
* Data written with the MMU off but read with the MMU on requires
* cache lines to be invalidated, discarding up to a Cache Writeback
@@ -320,9 +322,6 @@ SECTIONS
*(.plt) *(.plt.*) *(.iplt) *(.igot .igot.plt)
}
ASSERT(SIZEOF(.plt) == 0, "Unexpected run-time procedure linkages detected!")
-
- .data.rel.ro : { *(.data.rel.ro) }
- ASSERT(SIZEOF(.data.rel.ro) == 0, "Unexpected RELRO detected!")
}
#include "image-vars.h"
--
2.30.2
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2022-04-27 17:26 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-04-27 17:12 [RFC PATCH 0/2] arm64: use PIE code generation for KASLR kernel Ard Biesheuvel
2022-04-27 17:12 ` [RFC PATCH 1/2] arm64: jump_label: use more precise asm constraints Ard Biesheuvel
2022-04-27 18:58 ` Nick Desaulniers
2022-04-27 21:50 ` Ard Biesheuvel
2022-04-28 9:35 ` Ard Biesheuvel
2022-04-28 9:51 ` Mark Rutland
2022-04-28 16:05 ` Ard Biesheuvel
2022-04-27 17:12 ` Ard Biesheuvel [this message]
2022-04-28 2:40 ` [RFC PATCH 2/2] arm64: kernel: switch to PIE code generation for relocatable kernels Fangrui Song
2022-04-28 6:23 ` Ard Biesheuvel
2022-04-28 6:57 ` Fangrui Song
2022-04-28 16:03 ` Ard Biesheuvel
2022-04-28 18:53 ` Nick Desaulniers
2022-04-28 19:36 ` Ard Biesheuvel
2022-04-29 7:03 ` Fangrui Song
2022-04-29 7:27 ` Ard Biesheuvel
2022-04-29 7:53 ` Fangrui Song
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=20220427171241.2426592-3-ardb@kernel.org \
--to=ardb@kernel.org \
--cc=catalin.marinas@arm.com \
--cc=clang-built-linux@googlegroups.com \
--cc=keescook@chromium.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=mark.rutland@arm.com \
--cc=nathan@kernel.org \
--cc=ndesaulniers@google.com \
--cc=samitolvanen@google.com \
--cc=will@kernel.org \
/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: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).