aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm64/kernel/kaslr.c
diff options
context:
space:
mode:
authorNeeraj Upadhyay <neeraju@codeaurora.org>2017-03-22 07:38:25 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-03-30 03:41:26 -0400
commitb9ed800f71889795e1f329d4ee84d7778a16797f (patch)
tree526c704dda28077ba161c1a2c56c0eba1f7cd966 /arch/arm64/kernel/kaslr.c
parent2ab97521ce11d92f3ccca61561621214a370e2e5 (diff)
arm64: kaslr: Fix up the kernel image alignment
commit afd0e5a876703accb95894f23317a13e2c49b523 upstream. If kernel image extends across alignment boundary, existing code increases the KASLR offset by size of kernel image. The offset is masked after resizing. There are cases, where after masking, we may still have kernel image extending across boundary. This eventually results in only 2MB block getting mapped while creating the page tables. This results in data aborts while accessing unmapped regions during second relocation (with kaslr offset) in __primary_switch. To fix this problem, round up the kernel image size, by swapper block size, before adding it for correction. For example consider below case, where kernel image still crosses 1GB alignment boundary, after masking the offset, which is fixed by rounding up kernel image size. SWAPPER_TABLE_SHIFT = 30 Swapper using section maps with section size 2MB. CONFIG_PGTABLE_LEVELS = 3 VA_BITS = 39 _text : 0xffffff8008080000 _end : 0xffffff800aa1b000 offset : 0x1f35600000 mask = ((1UL << (VA_BITS - 2)) - 1) & ~(SZ_2M - 1) (_text + offset) >> SWAPPER_TABLE_SHIFT = 0x3fffffe7c (_end + offset) >> SWAPPER_TABLE_SHIFT = 0x3fffffe7d offset after existing correction (before mask) = 0x1f37f9b000 (_text + offset) >> SWAPPER_TABLE_SHIFT = 0x3fffffe7d (_end + offset) >> SWAPPER_TABLE_SHIFT = 0x3fffffe7d offset (after mask) = 0x1f37e00000 (_text + offset) >> SWAPPER_TABLE_SHIFT = 0x3fffffe7c (_end + offset) >> SWAPPER_TABLE_SHIFT = 0x3fffffe7d new offset w/ rounding up = 0x1f38000000 (_text + offset) >> SWAPPER_TABLE_SHIFT = 0x3fffffe7d (_end + offset) >> SWAPPER_TABLE_SHIFT = 0x3fffffe7d Fixes: f80fb3a3d508 ("arm64: add support for kernel ASLR") Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Signed-off-by: Neeraj Upadhyay <neeraju@codeaurora.org> Signed-off-by: Srinivas Ramana <sramana@codeaurora.org> Signed-off-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'arch/arm64/kernel/kaslr.c')
-rw-r--r--arch/arm64/kernel/kaslr.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/arch/arm64/kernel/kaslr.c b/arch/arm64/kernel/kaslr.c
index 769f24ef628c..d7e90d97f5c4 100644
--- a/arch/arm64/kernel/kaslr.c
+++ b/arch/arm64/kernel/kaslr.c
@@ -131,11 +131,15 @@ u64 __init kaslr_early_init(u64 dt_phys, u64 modulo_offset)
131 /* 131 /*
132 * The kernel Image should not extend across a 1GB/32MB/512MB alignment 132 * The kernel Image should not extend across a 1GB/32MB/512MB alignment
133 * boundary (for 4KB/16KB/64KB granule kernels, respectively). If this 133 * boundary (for 4KB/16KB/64KB granule kernels, respectively). If this
134 * happens, increase the KASLR offset by the size of the kernel image. 134 * happens, increase the KASLR offset by the size of the kernel image
135 * rounded up by SWAPPER_BLOCK_SIZE.
135 */ 136 */
136 if ((((u64)_text + offset + modulo_offset) >> SWAPPER_TABLE_SHIFT) != 137 if ((((u64)_text + offset + modulo_offset) >> SWAPPER_TABLE_SHIFT) !=
137 (((u64)_end + offset + modulo_offset) >> SWAPPER_TABLE_SHIFT)) 138 (((u64)_end + offset + modulo_offset) >> SWAPPER_TABLE_SHIFT)) {
138 offset = (offset + (u64)(_end - _text)) & mask; 139 u64 kimg_sz = _end - _text;
140 offset = (offset + round_up(kimg_sz, SWAPPER_BLOCK_SIZE))
141 & mask;
142 }
139 143
140 if (IS_ENABLED(CONFIG_KASAN)) 144 if (IS_ENABLED(CONFIG_KASAN))
141 /* 145 /*