The original kernel still exists in the memory, clear it now.
Signed-off-by: Jason Yan <[email protected]>
Cc: Diana Craciun <[email protected]>
Cc: Michael Ellerman <[email protected]>
Cc: Christophe Leroy <[email protected]>
Cc: Benjamin Herrenschmidt <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Nicholas Piggin <[email protected]>
Cc: Kees Cook <[email protected]>
---
arch/powerpc/kernel/kaslr_booke.c | 11 +++++++++++
arch/powerpc/mm/mmu_decl.h | 2 ++
arch/powerpc/mm/nohash/fsl_booke.c | 1 +
3 files changed, 14 insertions(+)
diff --git a/arch/powerpc/kernel/kaslr_booke.c b/arch/powerpc/kernel/kaslr_booke.c
index 90357f4bd313..00339c05879f 100644
--- a/arch/powerpc/kernel/kaslr_booke.c
+++ b/arch/powerpc/kernel/kaslr_booke.c
@@ -412,3 +412,14 @@ notrace void __init kaslr_early_init(void *dt_ptr, phys_addr_t size)
reloc_kernel_entry(dt_ptr, kimage_vaddr);
}
+
+void __init kaslr_second_init(void)
+{
+ /* If randomized, clear the original kernel */
+ if (kimage_vaddr != KERNELBASE) {
+ unsigned long kernel_sz;
+
+ kernel_sz = (unsigned long)_end - kimage_vaddr;
+ memset((void *)KERNELBASE, 0, kernel_sz);
+ }
+}
diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h
index 754ae1e69f92..9912ee598f9b 100644
--- a/arch/powerpc/mm/mmu_decl.h
+++ b/arch/powerpc/mm/mmu_decl.h
@@ -150,8 +150,10 @@ extern void loadcam_multi(int first_idx, int num, int tmp_idx);
#ifdef CONFIG_RANDOMIZE_BASE
extern void kaslr_early_init(void *dt_ptr, phys_addr_t size);
+extern void kaslr_second_init(void);
#else
static inline void kaslr_early_init(void *dt_ptr, phys_addr_t size) {}
+static inline void kaslr_second_init(void) {}
#endif
struct tlbcam {
diff --git a/arch/powerpc/mm/nohash/fsl_booke.c b/arch/powerpc/mm/nohash/fsl_booke.c
index 8d25a8dc965f..fa5a87f5c08e 100644
--- a/arch/powerpc/mm/nohash/fsl_booke.c
+++ b/arch/powerpc/mm/nohash/fsl_booke.c
@@ -269,6 +269,7 @@ notrace void __init relocate_init(u64 dt_ptr, phys_addr_t start)
kernstart_addr = start;
if (is_second_reloc) {
virt_phys_offset = PAGE_OFFSET - memstart_addr;
+ kaslr_second_init();
return;
}
--
2.17.2
Le 17/07/2019 à 10:06, Jason Yan a écrit :
> The original kernel still exists in the memory, clear it now.
>
> Signed-off-by: Jason Yan <[email protected]>
> Cc: Diana Craciun <[email protected]>
> Cc: Michael Ellerman <[email protected]>
> Cc: Christophe Leroy <[email protected]>
> Cc: Benjamin Herrenschmidt <[email protected]>
> Cc: Paul Mackerras <[email protected]>
> Cc: Nicholas Piggin <[email protected]>
> Cc: Kees Cook <[email protected]>
> ---
> arch/powerpc/kernel/kaslr_booke.c | 11 +++++++++++
> arch/powerpc/mm/mmu_decl.h | 2 ++
> arch/powerpc/mm/nohash/fsl_booke.c | 1 +
> 3 files changed, 14 insertions(+)
>
> diff --git a/arch/powerpc/kernel/kaslr_booke.c b/arch/powerpc/kernel/kaslr_booke.c
> index 90357f4bd313..00339c05879f 100644
> --- a/arch/powerpc/kernel/kaslr_booke.c
> +++ b/arch/powerpc/kernel/kaslr_booke.c
> @@ -412,3 +412,14 @@ notrace void __init kaslr_early_init(void *dt_ptr, phys_addr_t size)
>
> reloc_kernel_entry(dt_ptr, kimage_vaddr);
> }
> +
> +void __init kaslr_second_init(void)
> +{
> + /* If randomized, clear the original kernel */
> + if (kimage_vaddr != KERNELBASE) {
> + unsigned long kernel_sz;
> +
> + kernel_sz = (unsigned long)_end - kimage_vaddr;
> + memset((void *)KERNELBASE, 0, kernel_sz);
Why are we clearing ? Is that just to tidy up or is it of security
importance ?
If so, maybe memzero_explicit() should be used instead ?
> + }
> +}
> diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h
> index 754ae1e69f92..9912ee598f9b 100644
> --- a/arch/powerpc/mm/mmu_decl.h
> +++ b/arch/powerpc/mm/mmu_decl.h
> @@ -150,8 +150,10 @@ extern void loadcam_multi(int first_idx, int num, int tmp_idx);
>
> #ifdef CONFIG_RANDOMIZE_BASE
> extern void kaslr_early_init(void *dt_ptr, phys_addr_t size);
> +extern void kaslr_second_init(void);
No new 'extern' please.
> #else
> static inline void kaslr_early_init(void *dt_ptr, phys_addr_t size) {}
> +static inline void kaslr_second_init(void) {}
> #endif
>
> struct tlbcam {
> diff --git a/arch/powerpc/mm/nohash/fsl_booke.c b/arch/powerpc/mm/nohash/fsl_booke.c
> index 8d25a8dc965f..fa5a87f5c08e 100644
> --- a/arch/powerpc/mm/nohash/fsl_booke.c
> +++ b/arch/powerpc/mm/nohash/fsl_booke.c
> @@ -269,6 +269,7 @@ notrace void __init relocate_init(u64 dt_ptr, phys_addr_t start)
> kernstart_addr = start;
> if (is_second_reloc) {
> virt_phys_offset = PAGE_OFFSET - memstart_addr;
> + kaslr_second_init();
> return;
> }
>
>
Christophe
On 2019/7/29 19:19, Christophe Leroy wrote:
>
>
> Le 17/07/2019 à 10:06, Jason Yan a écrit :
>> The original kernel still exists in the memory, clear it now.
>>
>> Signed-off-by: Jason Yan <[email protected]>
>> Cc: Diana Craciun <[email protected]>
>> Cc: Michael Ellerman <[email protected]>
>> Cc: Christophe Leroy <[email protected]>
>> Cc: Benjamin Herrenschmidt <[email protected]>
>> Cc: Paul Mackerras <[email protected]>
>> Cc: Nicholas Piggin <[email protected]>
>> Cc: Kees Cook <[email protected]>
>> ---
>> arch/powerpc/kernel/kaslr_booke.c | 11 +++++++++++
>> arch/powerpc/mm/mmu_decl.h | 2 ++
>> arch/powerpc/mm/nohash/fsl_booke.c | 1 +
>> 3 files changed, 14 insertions(+)
>>
>> diff --git a/arch/powerpc/kernel/kaslr_booke.c
>> b/arch/powerpc/kernel/kaslr_booke.c
>> index 90357f4bd313..00339c05879f 100644
>> --- a/arch/powerpc/kernel/kaslr_booke.c
>> +++ b/arch/powerpc/kernel/kaslr_booke.c
>> @@ -412,3 +412,14 @@ notrace void __init kaslr_early_init(void
>> *dt_ptr, phys_addr_t size)
>> reloc_kernel_entry(dt_ptr, kimage_vaddr);
>> }
>> +
>> +void __init kaslr_second_init(void)
>> +{
>> + /* If randomized, clear the original kernel */
>> + if (kimage_vaddr != KERNELBASE) {
>> + unsigned long kernel_sz;
>> +
>> + kernel_sz = (unsigned long)_end - kimage_vaddr;
>> + memset((void *)KERNELBASE, 0, kernel_sz);
>
> Why are we clearing ? Is that just to tidy up or is it of security
> importance ?
>
If we leave it there, attackers can still find the kernel object very
easy, it's still dangerous especially if without
CONFIG_STRICT_KERNEL_RWX enabled.
> If so, maybe memzero_explicit() should be used instead ?
>
OK
>> + }
>> +}
>> diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h
>> index 754ae1e69f92..9912ee598f9b 100644
>> --- a/arch/powerpc/mm/mmu_decl.h
>> +++ b/arch/powerpc/mm/mmu_decl.h
>> @@ -150,8 +150,10 @@ extern void loadcam_multi(int first_idx, int num,
>> int tmp_idx);
>> #ifdef CONFIG_RANDOMIZE_BASE
>> extern void kaslr_early_init(void *dt_ptr, phys_addr_t size);
>> +extern void kaslr_second_init(void);
>
> No new 'extern' please.
>
>> #else
>> static inline void kaslr_early_init(void *dt_ptr, phys_addr_t size) {}
>> +static inline void kaslr_second_init(void) {}
>> #endif
>> struct tlbcam {
>> diff --git a/arch/powerpc/mm/nohash/fsl_booke.c
>> b/arch/powerpc/mm/nohash/fsl_booke.c
>> index 8d25a8dc965f..fa5a87f5c08e 100644
>> --- a/arch/powerpc/mm/nohash/fsl_booke.c
>> +++ b/arch/powerpc/mm/nohash/fsl_booke.c
>> @@ -269,6 +269,7 @@ notrace void __init relocate_init(u64 dt_ptr,
>> phys_addr_t start)
>> kernstart_addr = start;
>> if (is_second_reloc) {
>> virt_phys_offset = PAGE_OFFSET - memstart_addr;
>> + kaslr_second_init();
>> return;
>> }
>>
>
> Christophe
>
> .
>