Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1381814 > unrolled thread
| Started by | Ard Biesheuvel <ard.biesheuvel@linaro.org> |
|---|---|
| First post | 2016-04-18 17:20 +0200 |
| Last post | 2016-04-25 18:40 +0200 |
| Articles | 10 — 5 participants |
Back to article view | Back to linux.kernel
[PATCH 0/8] arm64: kaslr cleanups and improvements Ard Biesheuvel <ard.biesheuvel@linaro.org> - 2016-04-18 17:20 +0200
[PATCH 4/8] arm64: introduce mov_q macro to move a constant into a 64-bit register Ard Biesheuvel <ard.biesheuvel@linaro.org> - 2016-04-18 17:20 +0200
[PATCH 8/8] arm64: kaslr: increase randomization granularity Ard Biesheuvel <ard.biesheuvel@linaro.org> - 2016-04-18 17:20 +0200
Re: [PATCH 8/8] arm64: kaslr: increase randomization granularity Will Deacon <will.deacon@arm.com> - 2016-04-26 13:30 +0200
Re: [PATCH 8/8] arm64: kaslr: increase randomization granularity Matt Fleming <matt@codeblueprint.co.uk> - 2016-04-26 17:30 +0200
[PATCH 1/8] arm64: kernel: don't export local symbols from head.S Ard Biesheuvel <ard.biesheuvel@linaro.org> - 2016-04-18 17:20 +0200
Re: [PATCH 1/8] arm64: kernel: don't export local symbols from head.S Mark Rutland <mark.rutland@arm.com> - 2016-04-18 17:40 +0200
[PATCH 2/8] arm64: kernel: use literal for relocated address of __secondary_switched Ard Biesheuvel <ard.biesheuvel@linaro.org> - 2016-04-18 17:20 +0200
Re: [PATCH 2/8] arm64: kernel: use literal for relocated address of __secondary_switched Mark Rutland <mark.rutland@arm.com> - 2016-04-18 18:00 +0200
Re: [PATCH 0/8] arm64: kaslr cleanups and improvements Catalin Marinas <catalin.marinas@arm.com> - 2016-04-25 18:40 +0200
| From | Ard Biesheuvel <ard.biesheuvel@linaro.org> |
|---|---|
| Date | 2016-04-18 17:20 +0200 |
| Subject | [PATCH 0/8] arm64: kaslr cleanups and improvements |
| Message-ID | <rpj7X-7JL-7@gated-at.bofh.it> |
This is a follow up to my series 'arm64: more granular KASLR' [1] that I sent
out about six weeks ago. It also partially supersedes [2].
The first patch is an unrelated cleanup that is completely orthogonal (but
happens to touch head.S as well) and is arbitrarily listed first.
Patches #2 to #5 address some issues that were introduced by KASLR, primarily
that we now have to take great care to only dereference literals that are
subject to R_AARCH64_AB64 relocations until after the relocation routine has
completed, and, since the latter runs with the caches on, take care not to
derefence such literals on secondaries until the MMU is enabled.
Formerly, this was addressed by using literals holding complicated expressions
that can be resolved at link time via R_AARCH64_PREL64/R_AARCH64_PREL32
relocations, and by explicitly cleaning these literals in the caches so that
the secondaries can see them with the MMU off.
Instead, take care not to use /any/ 64-bit literals until after the relocation
code has executed, and after the MMU is enabled. This makes the code a lot
cleaner, and less error prone.
The final three patches enhance the KASLR code, by dealing with relocatable
kernels whose physical placement is not TEXT_OFFSET bytes beyond a 2 MB aligned
base address, and by using this capability deliberately to allow for 5 bits of
additional entropy to be used.
[1] http://thread.gmane.org/gmane.linux.ports.arm.kernel/483819
[2] http://thread.gmane.org/gmane.linux.ports.arm.kernel/490216
Ard Biesheuvel (8):
arm64: kernel: don't export local symbols from head.S
arm64: kernel: use literal for relocated address of
__secondary_switched
arm64: kernel: perform relocation processing from ID map
arm64: introduce mov_q macro to move a constant into a 64-bit register
arm64: kernel: replace early 64-bit literal loads with move-immediates
arm64: don't map TEXT_OFFSET bytes below the kernel if we can avoid it
arm64: relocatable: deal with physically misaligned kernel images
arm64: kaslr: increase randomization granularity
arch/arm64/include/asm/assembler.h | 20 +++
arch/arm64/kernel/head.S | 136 +++++++++++---------
arch/arm64/kernel/image.h | 2 -
arch/arm64/kernel/kaslr.c | 6 +-
arch/arm64/kernel/vmlinux.lds.S | 7 +-
drivers/firmware/efi/libstub/arm64-stub.c | 15 ++-
6 files changed, 112 insertions(+), 74 deletions(-)
--
2.5.0
[toc] | [next] | [standalone]
| From | Ard Biesheuvel <ard.biesheuvel@linaro.org> |
|---|---|
| Date | 2016-04-18 17:20 +0200 |
| Subject | [PATCH 4/8] arm64: introduce mov_q macro to move a constant into a 64-bit register |
| Message-ID | <rpj7Z-7JL-43@gated-at.bofh.it> |
| In reply to | #1381814 |
Implement a macro mov_q that can be used to move an immediate constant into a 64-bit register, using between 2 and 4 movz/movk instructions (depending on the operand) Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> --- arch/arm64/include/asm/assembler.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h index 70f7b9e04598..9ea846ded55c 100644 --- a/arch/arm64/include/asm/assembler.h +++ b/arch/arm64/include/asm/assembler.h @@ -233,4 +233,24 @@ lr .req x30 // link register .long \sym\()_hi32 .endm + /* + * mov_q - move an immediate constant into a 64-bit register using + * between 2 and 4 movz/movk instructions (depending on the + * magnitude and sign of the operand) + */ + .macro mov_q, reg, val + .if (((\val) >> 31) == 0 || ((\val) >> 31) == 0x1ffffffff) + movz \reg, :abs_g1_s:\val + .else + .if (((\val) >> 47) == 0 || ((\val) >> 47) == 0x1ffff) + movz \reg, :abs_g2_s:\val + .else + movz \reg, :abs_g3:\val + movk \reg, :abs_g2_nc:\val + .endif + movk \reg, :abs_g1_nc:\val + .endif + movk \reg, :abs_g0_nc:\val + .endm + #endif /* __ASM_ASSEMBLER_H */ -- 2.5.0
[toc] | [prev] | [next] | [standalone]
| From | Ard Biesheuvel <ard.biesheuvel@linaro.org> |
|---|---|
| Date | 2016-04-18 17:20 +0200 |
| Subject | [PATCH 8/8] arm64: kaslr: increase randomization granularity |
| Message-ID | <rpj7Z-7JL-45@gated-at.bofh.it> |
| In reply to | #1381814 |
Currently, our KASLR implementation randomizes the placement of the core
kernel at 2 MB granularity. This is based on the arm64 kernel boot
protocol, which mandates that the kernel is loaded TEXT_OFFSET bytes above
a 2 MB aligned base address. This requirement is a result of the fact that
the block size used by the early mapping code may be 2 MB at the most (for
a 4 KB granule kernel)
But we can do better than that: since a KASLR kernel needs to be relocated
in any case, we can tolerate a physical misalignment as long as the virtual
misalignment relative to this 2 MB block size is equal in size, and code to
deal with this is already in place.
Since we align the kernel segments to 64 KB, let's randomize the physical
offset at 64 KB granularity as well (unless CONFIG_DEBUG_ALIGN_RODATA is
enabled). This way, the page table and TLB footprint is not affected.
The higher granularity allows for 5 bits of additional entropy to be used.
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
drivers/firmware/efi/libstub/arm64-stub.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/drivers/firmware/efi/libstub/arm64-stub.c b/drivers/firmware/efi/libstub/arm64-stub.c
index a90f6459f5c6..eae693eb3e91 100644
--- a/drivers/firmware/efi/libstub/arm64-stub.c
+++ b/drivers/firmware/efi/libstub/arm64-stub.c
@@ -81,15 +81,24 @@ efi_status_t handle_kernel_image(efi_system_table_t *sys_table_arg,
if (IS_ENABLED(CONFIG_RANDOMIZE_BASE) && phys_seed != 0) {
/*
+ * If CONFIG_DEBUG_ALIGN_RODATA is not set, produce a
+ * displacement in the interval [0, MIN_KIMG_ALIGN) that
+ * is a multiple of the minimal segment alignment (SZ_64K)
+ */
+ u32 mask = (MIN_KIMG_ALIGN - 1) & ~(SZ_64K - 1);
+ u32 offset = !IS_ENABLED(CONFIG_DEBUG_ALIGN_RODATA) ?
+ (phys_seed >> 32) & mask : TEXT_OFFSET;
+
+ /*
* If KASLR is enabled, and we have some randomness available,
* locate the kernel at a randomized offset in physical memory.
*/
- *reserve_size = kernel_memsize + TEXT_OFFSET;
+ *reserve_size = kernel_memsize + offset;
status = efi_random_alloc(sys_table_arg, *reserve_size,
MIN_KIMG_ALIGN, reserve_addr,
- phys_seed);
+ (u32)phys_seed);
- *image_addr = *reserve_addr + TEXT_OFFSET;
+ *image_addr = *reserve_addr + offset;
} else {
/*
* Else, try a straight allocation at the preferred offset.
--
2.5.0
[toc] | [prev] | [next] | [standalone]
| From | Will Deacon <will.deacon@arm.com> |
|---|---|
| Date | 2016-04-26 13:30 +0200 |
| Subject | Re: [PATCH 8/8] arm64: kaslr: increase randomization granularity |
| Message-ID | <rs9lM-6K3-9@gated-at.bofh.it> |
| In reply to | #1381820 |
On Mon, Apr 18, 2016 at 05:09:48PM +0200, Ard Biesheuvel wrote:
> Currently, our KASLR implementation randomizes the placement of the core
> kernel at 2 MB granularity. This is based on the arm64 kernel boot
> protocol, which mandates that the kernel is loaded TEXT_OFFSET bytes above
> a 2 MB aligned base address. This requirement is a result of the fact that
> the block size used by the early mapping code may be 2 MB at the most (for
> a 4 KB granule kernel)
>
> But we can do better than that: since a KASLR kernel needs to be relocated
> in any case, we can tolerate a physical misalignment as long as the virtual
> misalignment relative to this 2 MB block size is equal in size, and code to
> deal with this is already in place.
>
> Since we align the kernel segments to 64 KB, let's randomize the physical
> offset at 64 KB granularity as well (unless CONFIG_DEBUG_ALIGN_RODATA is
> enabled). This way, the page table and TLB footprint is not affected.
>
> The higher granularity allows for 5 bits of additional entropy to be used.
>
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
> drivers/firmware/efi/libstub/arm64-stub.c | 15 ++++++++++++---
> 1 file changed, 12 insertions(+), 3 deletions(-)
Adding Matt to Cc, since this touches the stub and I'll need his ack
before I can merge it.
Will
> diff --git a/drivers/firmware/efi/libstub/arm64-stub.c b/drivers/firmware/efi/libstub/arm64-stub.c
> index a90f6459f5c6..eae693eb3e91 100644
> --- a/drivers/firmware/efi/libstub/arm64-stub.c
> +++ b/drivers/firmware/efi/libstub/arm64-stub.c
> @@ -81,15 +81,24 @@ efi_status_t handle_kernel_image(efi_system_table_t *sys_table_arg,
>
> if (IS_ENABLED(CONFIG_RANDOMIZE_BASE) && phys_seed != 0) {
> /*
> + * If CONFIG_DEBUG_ALIGN_RODATA is not set, produce a
> + * displacement in the interval [0, MIN_KIMG_ALIGN) that
> + * is a multiple of the minimal segment alignment (SZ_64K)
> + */
> + u32 mask = (MIN_KIMG_ALIGN - 1) & ~(SZ_64K - 1);
> + u32 offset = !IS_ENABLED(CONFIG_DEBUG_ALIGN_RODATA) ?
> + (phys_seed >> 32) & mask : TEXT_OFFSET;
> +
> + /*
> * If KASLR is enabled, and we have some randomness available,
> * locate the kernel at a randomized offset in physical memory.
> */
> - *reserve_size = kernel_memsize + TEXT_OFFSET;
> + *reserve_size = kernel_memsize + offset;
> status = efi_random_alloc(sys_table_arg, *reserve_size,
> MIN_KIMG_ALIGN, reserve_addr,
> - phys_seed);
> + (u32)phys_seed);
>
> - *image_addr = *reserve_addr + TEXT_OFFSET;
> + *image_addr = *reserve_addr + offset;
> } else {
> /*
> * Else, try a straight allocation at the preferred offset.
> --
> 2.5.0
>
[toc] | [prev] | [next] | [standalone]
| From | Matt Fleming <matt@codeblueprint.co.uk> |
|---|---|
| Date | 2016-04-26 17:30 +0200 |
| Subject | Re: [PATCH 8/8] arm64: kaslr: increase randomization granularity |
| Message-ID | <rsd62-1xP-9@gated-at.bofh.it> |
| In reply to | #1387387 |
On Tue, 26 Apr, at 12:27:03PM, Will Deacon wrote: > > Adding Matt to Cc, since this touches the stub and I'll need his ack > before I can merge it. Looks OK, Reviewed-by: Matt Fleming <matt@codeblueprint.co.uk>
[toc] | [prev] | [next] | [standalone]
| From | Ard Biesheuvel <ard.biesheuvel@linaro.org> |
|---|---|
| Date | 2016-04-18 17:20 +0200 |
| Subject | [PATCH 1/8] arm64: kernel: don't export local symbols from head.S |
| Message-ID | <rpj7Z-7JL-47@gated-at.bofh.it> |
| In reply to | #1381814 |
This unexports some symbols from head.S that are only used locally. Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> --- arch/arm64/kernel/head.S | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S index b43417618847..ac27d8d937b2 100644 --- a/arch/arm64/kernel/head.S +++ b/arch/arm64/kernel/head.S @@ -638,7 +638,7 @@ ENDPROC(el2_setup) * Sets the __boot_cpu_mode flag depending on the CPU boot mode passed * in x20. See arch/arm64/include/asm/virt.h for more info. */ -ENTRY(set_cpu_boot_mode_flag) +set_cpu_boot_mode_flag: adr_l x1, __boot_cpu_mode cmp w20, #BOOT_CPU_MODE_EL2 b.ne 1f @@ -691,7 +691,7 @@ ENTRY(secondary_entry) b secondary_startup ENDPROC(secondary_entry) -ENTRY(secondary_startup) +secondary_startup: /* * Common entry point for secondary CPUs. */ @@ -706,7 +706,7 @@ ENTRY(secondary_startup) ENDPROC(secondary_startup) 0: .long (_text - TEXT_OFFSET) - __secondary_switched -ENTRY(__secondary_switched) +__secondary_switched: adr_l x5, vectors msr vbar_el1, x5 isb -- 2.5.0
[toc] | [prev] | [next] | [standalone]
| From | Mark Rutland <mark.rutland@arm.com> |
|---|---|
| Date | 2016-04-18 17:40 +0200 |
| Subject | Re: [PATCH 1/8] arm64: kernel: don't export local symbols from head.S |
| Message-ID | <rpjrj-7Ud-1@gated-at.bofh.it> |
| In reply to | #1381821 |
On Mon, Apr 18, 2016 at 05:09:41PM +0200, Ard Biesheuvel wrote: > This unexports some symbols from head.S that are only used locally. It might be worth s/some/all/, as that makes this sound less arbitrary (and AFAICS this caters for all symbols only used locally). > Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Acked-by: Mark Rutland <mark.rutland@arm.com> Mark. > --- > arch/arm64/kernel/head.S | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > > diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S > index b43417618847..ac27d8d937b2 100644 > --- a/arch/arm64/kernel/head.S > +++ b/arch/arm64/kernel/head.S > @@ -638,7 +638,7 @@ ENDPROC(el2_setup) > * Sets the __boot_cpu_mode flag depending on the CPU boot mode passed > * in x20. See arch/arm64/include/asm/virt.h for more info. > */ > -ENTRY(set_cpu_boot_mode_flag) > +set_cpu_boot_mode_flag: > adr_l x1, __boot_cpu_mode > cmp w20, #BOOT_CPU_MODE_EL2 > b.ne 1f > @@ -691,7 +691,7 @@ ENTRY(secondary_entry) > b secondary_startup > ENDPROC(secondary_entry) > > -ENTRY(secondary_startup) > +secondary_startup: > /* > * Common entry point for secondary CPUs. > */ > @@ -706,7 +706,7 @@ ENTRY(secondary_startup) > ENDPROC(secondary_startup) > 0: .long (_text - TEXT_OFFSET) - __secondary_switched > > -ENTRY(__secondary_switched) > +__secondary_switched: > adr_l x5, vectors > msr vbar_el1, x5 > isb > -- > 2.5.0 >
[toc] | [prev] | [next] | [standalone]
| From | Ard Biesheuvel <ard.biesheuvel@linaro.org> |
|---|---|
| Date | 2016-04-18 17:20 +0200 |
| Subject | [PATCH 2/8] arm64: kernel: use literal for relocated address of __secondary_switched |
| Message-ID | <rpj80-7JL-63@gated-at.bofh.it> |
| In reply to | #1381814 |
We can simply use a relocated 64-bit literal to store the address of __secondary_switched(), and the relocation code will ensure that it holds the correct value at secondary entry time, as long as we make sure that the literal is not dereferenced until after we have enabled the MMU. So jump via a small __secondary_switch() function covered by the ID map that performs the literal load and branch-to-register. Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> --- arch/arm64/kernel/head.S | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S index ac27d8d937b2..f13276d4ca91 100644 --- a/arch/arm64/kernel/head.S +++ b/arch/arm64/kernel/head.S @@ -468,9 +468,7 @@ __mmap_switched: str x15, [x11, x23] b 0b -2: adr_l x8, kimage_vaddr // make relocated kimage_vaddr - dc cvac, x8 // value visible to secondaries - dsb sy // with MMU off +2: #endif adr_l sp, initial_sp, x4 @@ -699,12 +697,9 @@ secondary_startup: adrp x26, swapper_pg_dir bl __cpu_setup // initialise processor - ldr x8, kimage_vaddr - ldr w9, 0f - sub x27, x8, w9, sxtw // address to jump to after enabling the MMU + adr_l x27, __secondary_switch // address to jump to after enabling the MMU b __enable_mmu ENDPROC(secondary_startup) -0: .long (_text - TEXT_OFFSET) - __secondary_switched __secondary_switched: adr_l x5, vectors @@ -806,3 +801,8 @@ __no_granule_support: wfi b 1b ENDPROC(__no_granule_support) + +__secondary_switch: + ldr x8, =__secondary_switched + br x8 +ENDPROC(__secondary_switch) -- 2.5.0
[toc] | [prev] | [next] | [standalone]
| From | Mark Rutland <mark.rutland@arm.com> |
|---|---|
| Date | 2016-04-18 18:00 +0200 |
| Subject | Re: [PATCH 2/8] arm64: kernel: use literal for relocated address of __secondary_switched |
| Message-ID | <rpjKH-82N-15@gated-at.bofh.it> |
| In reply to | #1381828 |
On Mon, Apr 18, 2016 at 05:09:42PM +0200, Ard Biesheuvel wrote: > We can simply use a relocated 64-bit literal to store the address of > __secondary_switched(), and the relocation code will ensure that it > holds the correct value at secondary entry time, as long as we make sure > that the literal is not dereferenced until after we have enabled the MMU. > > So jump via a small __secondary_switch() function covered by the ID map > that performs the literal load and branch-to-register. > > Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Neat! Acked-by: Mark Rutland <mark.rutland@arm.com> Mark. > --- > arch/arm64/kernel/head.S | 14 +++++++------- > 1 file changed, 7 insertions(+), 7 deletions(-) > > diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S > index ac27d8d937b2..f13276d4ca91 100644 > --- a/arch/arm64/kernel/head.S > +++ b/arch/arm64/kernel/head.S > @@ -468,9 +468,7 @@ __mmap_switched: > str x15, [x11, x23] > b 0b > > -2: adr_l x8, kimage_vaddr // make relocated kimage_vaddr > - dc cvac, x8 // value visible to secondaries > - dsb sy // with MMU off > +2: > #endif > > adr_l sp, initial_sp, x4 > @@ -699,12 +697,9 @@ secondary_startup: > adrp x26, swapper_pg_dir > bl __cpu_setup // initialise processor > > - ldr x8, kimage_vaddr > - ldr w9, 0f > - sub x27, x8, w9, sxtw // address to jump to after enabling the MMU > + adr_l x27, __secondary_switch // address to jump to after enabling the MMU > b __enable_mmu > ENDPROC(secondary_startup) > -0: .long (_text - TEXT_OFFSET) - __secondary_switched > > __secondary_switched: > adr_l x5, vectors > @@ -806,3 +801,8 @@ __no_granule_support: > wfi > b 1b > ENDPROC(__no_granule_support) > + > +__secondary_switch: > + ldr x8, =__secondary_switched > + br x8 > +ENDPROC(__secondary_switch) > -- > 2.5.0 >
[toc] | [prev] | [next] | [standalone]
| From | Catalin Marinas <catalin.marinas@arm.com> |
|---|---|
| Date | 2016-04-25 18:40 +0200 |
| Message-ID | <rrRIf-zA-21@gated-at.bofh.it> |
| In reply to | #1381814 |
On Mon, Apr 18, 2016 at 05:09:40PM +0200, Ard Biesheuvel wrote: > Ard Biesheuvel (8): > arm64: kernel: don't export local symbols from head.S > arm64: kernel: use literal for relocated address of > __secondary_switched > arm64: kernel: perform relocation processing from ID map > arm64: introduce mov_q macro to move a constant into a 64-bit register > arm64: kernel: replace early 64-bit literal loads with move-immediates > arm64: don't map TEXT_OFFSET bytes below the kernel if we can avoid it > arm64: relocatable: deal with physically misaligned kernel images > arm64: kaslr: increase randomization granularity I went through these patches and there is indeed a nice clean-up. The increased KASLR granularity also looks fine. So, for the series: Acked-by: Catalin Marinas <catalin.marinas@arm.com>
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web