arm64: align randomized TEXT_OFFSET on 4 kB boundary
PATCH 1/1 arm64: align randomized TEXT_OFFSET on 4 kB boundary
When booting via UEFI, the kernel Image is loaded at a 4 kB boundary and the embedded EFI stub is executed in place. The EFI stub relocates the Image to reside TEXT_OFFSET bytes above a 2 MB boundary, and jumps into the kernel proper.
In AArch64, PC relative symbol references are emitted using adrp/add or adrp/ldr pairs, where the offset into a 4 kB page is resolved using a separate :lo12: relocation. This implicitly assumes that the code will always be executed at the same relative offset with respect to a 4 kB boundary, or the references will point to the wrong address.
This means we should link the kernel at a 4 kB aligned base address in order to remain compatible with the base address the UEFI loader uses when doing the initial load of Image. So update the code that generates TEXT_OFFSET to choose a multiple of 4 kB.
At the same time, update the code so it chooses from the interval [0..2MB) as the author originally intended.
--- arch/arm64/Makefile | 2 +- arch/arm64/kernel/head.S | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-)
arch/arm64/Makefile +1 -1
@@ -39,7 +39,7 @@ head-y := arch/arm64/kernel/head.o # The byte offset of the kernel image in RAM from the start of RAM. ifeq ($(CONFIG_ARM64_RANDOMIZE_TEXT_OFFSET), y) -TEXT_OFFSET := $(shell awk 'BEGIN {srand(); printf "0x%04x0\n", int(65535 * rand())}') +TEXT_OFFSET := $(shell awk 'BEGIN {srand(); printf "0x%03x000\n", int(512 * rand())}') else TEXT_OFFSET := 0x00080000 endif
arch/arm64/kernel/head.S +4 -4
@@ -38,11 +38,11 @@ #define KERNEL_RAM_VADDR (PAGE_OFFSET + TEXT_OFFSET) -#if (TEXT_OFFSET & 0xf) != 0 -#error TEXT_OFFSET must be at least 16B aligned -#elif (PAGE_OFFSET & 0xfffff) != 0 +#if (TEXT_OFFSET & 0xfff) != 0 +#error TEXT_OFFSET must be at least 4kB aligned +#elif (PAGE_OFFSET & 0x1fffff) != 0 #error PAGE_OFFSET must be at least 2MB aligned -#elif TEXT_OFFSET > 0xfffff +#elif TEXT_OFFSET > 0x1fffff #error TEXT_OFFSET must be less than 2MB #endif
Signature · 1 line
1.8.3.2
Mark Rutland
reviewerPATCH 1/1 arm64: align randomized TEXT_OFFSET on 4 kB boundary
Hi Ard,
Quoted 43 lines · Ard Biesheuvel
When booting via UEFI, the kernel Image is loaded at a 4 kB boundary and the embedded EFI stub is executed in place. The EFI stub relocates the Image to reside
TEXT_OFFSETbytes above a 2 MB boundary, and jumps into the kernel proper.In AArch64, PC relative symbol references are emitted using adrp/add or adrp/ldr pairs, where the offset into a 4 kB page is resolved using a separate :lo12: relocation. This implicitly assumes that the code will always be executed at the same relative offset with respect to a 4 kB boundary, or the references will point to the wrong address.
This means we should link the kernel at a 4 kB aligned base address in order to remain compatible with the base address the UEFI loader uses when doing the initial load of Image. So update the code that generates
TEXT_OFFSETto choose a multiple of 4 kB.At the same time, update the code so it chooses from the interval [0..2MB) as the author originally intended.
Signed-off-by Ard Biesheuvel <[email protected]>--- arch/arm64/Makefile | 2 +- arch/arm64/kernel/head.S | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-)arch/arm64/Makefile +1
-1@@ -39,7 +39,7 @@ head-y := arch/arm64/kernel/head.o # The byte offset of the kernel image in RAM from the start of RAM. ifeq ($(CONFIG_ARM64_RANDOMIZE_TEXT_OFFSET), y) -TEXT_OFFSET := $(shell awk 'BEGIN {srand(); printf "0x%04x0\n", int(65535 * rand())}') +TEXT_OFFSET := $(shell awk 'BEGIN {srand(); printf "0x%03x000\n", int(512 * rand())}') else TEXT_OFFSET := 0x00080000 endifarch/arm64/kernel/head.S +0
-0
arch/arm64/kernel/head.S line 42
Quoted 8 lines
arch/arm64/kernel/head.S +2
-3@@ -38,11 +38,11 @@ #define KERNEL_RAM_VADDR (PAGE_OFFSET + TEXT_OFFSET) -#if (TEXT_OFFSET & 0xf) != 0 -#error TEXT_OFFSET must be at least 16B aligned -#elif (PAGE_OFFSET & 0xfffff) != 0 +#if (TEXT_OFFSET & 0xfff) != 0 +#error TEXT_OFFSET must be at least 4kB aligned
Minor nit, but can we have "KB" here to match "MB"?
arch/arm64/kernel/head.S line 47
Quoted 6 lines
arch/arm64/kernel/head.S +2
-1+#elif (PAGE_OFFSET & 0x1fffff) != 0 #error PAGE_OFFSET must be at least 2MB aligned -#elif TEXT_OFFSET > 0xfffff +#elif TEXT_OFFSET > 0x1fffff #error TEXT_OFFSET must be less than 2MB #endif
I thought I'd left wording in Kconfig.debug, but that doesn't seem to be the case. This looks sane to me, so:
Catalin, can you pick this up? Without it UEFI boot can be broken by ARM64_RANDOMIZE_TEXT_OFFSET.
Cheers,
Mark.
PATCH 1/1 arm64: align randomized TEXT_OFFSET on 4 kB boundary
Quoted 49 lines · Mark Rutland
Hi Ard,
Quoted 46 lines · Ard Biesheuvel
When booting via UEFI, the kernel Image is loaded at a 4 kB boundary and the embedded EFI stub is executed in place. The EFI stub relocates the Image to reside
TEXT_OFFSETbytes above a 2 MB boundary, and jumps into the kernel proper.In AArch64, PC relative symbol references are emitted using adrp/add or adrp/ldr pairs, where the offset into a 4 kB page is resolved using a separate :lo12: relocation. This implicitly assumes that the code will always be executed at the same relative offset with respect to a 4 kB boundary, or the references will point to the wrong address.
This means we should link the kernel at a 4 kB aligned base address in order to remain compatible with the base address the UEFI loader uses when doing the initial load of Image. So update the code that generates
TEXT_OFFSETto choose a multiple of 4 kB.At the same time, update the code so it chooses from the interval [0..2MB) as the author originally intended.
Signed-off-by Ard Biesheuvel <[email protected]>--- arch/arm64/Makefile | 2 +- arch/arm64/kernel/head.S | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-)arch/arm64/Makefile +1
-1@@ -39,7 +39,7 @@ head-y := arch/arm64/kernel/head.o # The byte offset of the kernel image in RAM from the start of RAM. ifeq ($(CONFIG_ARM64_RANDOMIZE_TEXT_OFFSET), y) -TEXT_OFFSET := $(shell awk 'BEGIN {srand(); printf "0x%04x0\n", int(65535 * rand())}') +TEXT_OFFSET := $(shell awk 'BEGIN {srand(); printf "0x%03x000\n", int(512 * rand())}') else TEXT_OFFSET := 0x00080000 endifarch/arm64/kernel/head.S +0
-0@@ -38,11 +38,11 @@ #define KERNEL_RAM_VADDR (PAGE_OFFSET + TEXT_OFFSET)
Quoted 8 lines
arch/arm64/kernel/head.S line 42
Quoted 5 lines
arch/arm64/kernel/head.S +2
-3-#if (TEXT_OFFSET & 0xf) != 0 -#error TEXT_OFFSET must be at least 16B aligned -#elif (PAGE_OFFSET & 0xfffff) != 0 +#if (TEXT_OFFSET & 0xfff) != 0 +#error TEXT_OFFSET must be at least 4kB alignedMinor nit, but can we have "KB" here to match "MB"?
Ack
Quoted 10 lines
arch/arm64/kernel/head.S line 47
Quoted 6 lines
arch/arm64/kernel/head.S +2
-1+#elif (PAGE_OFFSET & 0x1fffff) != 0 #error PAGE_OFFSET must be at least 2MB aligned -#elif TEXT_OFFSET > 0xfffff +#elif TEXT_OFFSET > 0x1fffff #error TEXT_OFFSET must be less than 2MB #endifI thought I'd left wording in
Kconfig.debug, but that doesn't seem to be the case. This looks sane to me, so:
Quoted 5 lines
Reviewed-by Mark Rutland <[email protected]>Catalin, can you pick this up? Without it UEFI boot can be broken by
ARM64_RANDOMIZE_TEXT_OFFSET.
I assume the above change does not require a v2.
Signature · 1 line
Ard.
Catalin Marinas
maintainerPATCH 1/1 arm64: align randomized TEXT_OFFSET on 4 kB boundary
Quoted 30 lines · Ard Biesheuvel
Quoted 9 lines · Mark Rutland
Quoted 8 lines · Ard Biesheuvel
arch/arm64/kernel/head.S +0
-0@@ -38,11 +38,11 @@ #define KERNEL_RAM_VADDR (PAGE_OFFSET + TEXT_OFFSET)Quoted 7 lines
arch/arm64/kernel/head.S line 42
Quoted 5 lines
arch/arm64/kernel/head.S +2
-3-#if (TEXT_OFFSET & 0xf) != 0 -#error TEXT_OFFSET must be at least 16B aligned -#elif (PAGE_OFFSET & 0xfffff) != 0 +#if (TEXT_OFFSET & 0xfff) != 0 +#error TEXT_OFFSET must be at least 4kB alignedMinor nit, but can we have "KB" here to match "MB"?
Ack
Quoted 10 lines
arch/arm64/kernel/head.S line 47
Quoted 6 lines
arch/arm64/kernel/head.S +2
-1+#elif (PAGE_OFFSET & 0x1fffff) != 0 #error PAGE_OFFSET must be at least 2MB aligned -#elif TEXT_OFFSET > 0xfffff +#elif TEXT_OFFSET > 0x1fffff #error TEXT_OFFSET must be less than 2MB #endifI thought I'd left wording in
Kconfig.debug, but that doesn't seem to be the case. This looks sane to me, so:
Quoted 6 lines
Quoted 4 lines
Reviewed-by Mark Rutland <[email protected]>Catalin, can you pick this up? Without it UEFI boot can be broken by
ARM64_RANDOMIZE_TEXT_OFFSET.I assume the above change does not require a v2.
I can fix it up. Thanks.
Signature · 1 line
Catalin