linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2] x86/KASLR: Use old ident map page table if physical randomization failed
@ 2017-04-27  7:42 Baoquan He
  2017-04-28  6:25 ` Ingo Molnar
  2017-04-28  8:34 ` [tip:x86/boot] x86/KASLR: Fix kexec kernel boot crash when KASLR randomization fails tip-bot for Baoquan He
  0 siblings, 2 replies; 4+ messages in thread
From: Baoquan He @ 2017-04-27  7:42 UTC (permalink / raw)
  To: linux-kernel
  Cc: Baoquan He, Dave Young, H. Peter Anvin, Thomas Gleixner,
	Ingo Molnar, x86, Kees Cook, Yinghai Lu, Borislav Petkov,
	Dave Jiang, Thomas Garnier

Dave found kdump kernel with kaslr enabled will reset to bios immediately
if physical randomization failed to find a new position for kernel. But
kernel with 'nokaslr' option works in this case.

The reason is kaslr will install a new page table for ident mapping,
while it missed to consider building ident mapping for original area
of kernel if kaslr failed on physical randomization.

This only happens in kexec/kdump kernel. Since ident mapping has been
built for kexec/kdump in 1st kernel for the whole memory by calling
init_pgtable(). Here if physical randomizaiton failed, it won't build
ident mapping for the original area of kernel but change to new page
table '_pgtable'. Then kernel will reset to bios immediately caused by
no ident mapping.

While normal kernel won't be impacted because it comes here via
startup_32() and cr3 will be _pgtable already. In startup_32() ident
mapping is built for 0~4G area. In kaslr We just append to the existing
area instead of entirely overwriting it for on-demand ident mapping
building. So ident mapping for the original area of kernel is still
there.

So for fixing it,  We just switch to the new ident mapping page table
when physical kaslr succeeds. Otherwise we keep the old page table
unchanged just like nokaslr does.

Signed-off-by: Baoquan He <bhe@redhat.com>
Signed-off-by: Dave Young <dyoung@redhat.com>
Acked-by: Kees Cook <keescook@chromium.org>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: x86@kernel.org
Cc: Kees Cook <keescook@chromium.org>
Cc: Yinghai Lu <yinghai@kernel.org>
Cc: Borislav Petkov <bp@suse.de>
Cc: Dave Jiang <dave.jiang@intel.com>
Cc: Thomas Garnier <thgarnie@google.com>
---
v1->v2:
  No code change, just improve patch log to make it clearer.

 arch/x86/boot/compressed/kaslr.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/arch/x86/boot/compressed/kaslr.c b/arch/x86/boot/compressed/kaslr.c
index e5eb0c3..7a8b443 100644
--- a/arch/x86/boot/compressed/kaslr.c
+++ b/arch/x86/boot/compressed/kaslr.c
@@ -650,10 +650,16 @@ void choose_random_location(unsigned long input,
 			add_identity_map(random_addr, output_size);
 			*output = random_addr;
 		}
+
+		/*
+		 * This actually loads the identity pagetable on x86_64.
+		 * And this should only be done only if a new position
+		 * is found. Otherwise we should keep the old page table
+		 * to make it be like nokaslr case.
+		 */
+		finalize_identity_maps();
 	}
 
-	/* This actually loads the identity pagetable on x86_64. */
-	finalize_identity_maps();
 
 	/* Pick random virtual address starting from LOAD_PHYSICAL_ADDR. */
 	if (IS_ENABLED(CONFIG_X86_64))
-- 
2.5.5

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH v2] x86/KASLR: Use old ident map page table if physical randomization failed
  2017-04-27  7:42 [PATCH v2] x86/KASLR: Use old ident map page table if physical randomization failed Baoquan He
@ 2017-04-28  6:25 ` Ingo Molnar
  2017-04-28  6:59   ` Baoquan He
  2017-04-28  8:34 ` [tip:x86/boot] x86/KASLR: Fix kexec kernel boot crash when KASLR randomization fails tip-bot for Baoquan He
  1 sibling, 1 reply; 4+ messages in thread
From: Ingo Molnar @ 2017-04-28  6:25 UTC (permalink / raw)
  To: Baoquan He
  Cc: linux-kernel, Dave Young, H. Peter Anvin, Thomas Gleixner,
	Ingo Molnar, x86, Kees Cook, Yinghai Lu, Borislav Petkov,
	Dave Jiang, Thomas Garnier


* Baoquan He <bhe@redhat.com> wrote:

> Dave found kdump kernel with kaslr enabled will reset to bios immediately
> if physical randomization failed to find a new position for kernel. But
> kernel with 'nokaslr' option works in this case.
> 
> The reason is kaslr will install a new page table for ident mapping,
> while it missed to consider building ident mapping for original area
> of kernel if kaslr failed on physical randomization.
> 
> This only happens in kexec/kdump kernel. Since ident mapping has been
> built for kexec/kdump in 1st kernel for the whole memory by calling
> init_pgtable(). Here if physical randomizaiton failed, it won't build
> ident mapping for the original area of kernel but change to new page
> table '_pgtable'. Then kernel will reset to bios immediately caused by
> no ident mapping.
> 
> While normal kernel won't be impacted because it comes here via
> startup_32() and cr3 will be _pgtable already. In startup_32() ident
> mapping is built for 0~4G area. In kaslr We just append to the existing
> area instead of entirely overwriting it for on-demand ident mapping
> building. So ident mapping for the original area of kernel is still
> there.
> 
> So for fixing it,  We just switch to the new ident mapping page table
> when physical kaslr succeeds. Otherwise we keep the old page table
> unchanged just like nokaslr does.
> 
> Signed-off-by: Baoquan He <bhe@redhat.com>
> Signed-off-by: Dave Young <dyoung@redhat.com>
> Acked-by: Kees Cook <keescook@chromium.org>

That's not a valid signoff chain. I made it:

 Reported-by: Dave Young <dyoung@redhat.com>
 Signed-off-by: Baoquan He <bhe@redhat.com>
 Acked-by: Dave Young <dyoung@redhat.com>
 Acked-by: Kees Cook <keescook@chromium.org>

(Let me know if that's not the proper authorship chain.)

Thanks,

	Ingo

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH v2] x86/KASLR: Use old ident map page table if physical randomization failed
  2017-04-28  6:25 ` Ingo Molnar
@ 2017-04-28  6:59   ` Baoquan He
  0 siblings, 0 replies; 4+ messages in thread
From: Baoquan He @ 2017-04-28  6:59 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, Dave Young, H. Peter Anvin, Thomas Gleixner,
	Ingo Molnar, x86, Kees Cook, Yinghai Lu, Borislav Petkov,
	Dave Jiang, Thomas Garnier

On 04/28/17 at 08:25am, Ingo Molnar wrote:
> 
> * Baoquan He <bhe@redhat.com> wrote:
> 
> > Dave found kdump kernel with kaslr enabled will reset to bios immediately
> > if physical randomization failed to find a new position for kernel. But
> > kernel with 'nokaslr' option works in this case.
> > 
> > The reason is kaslr will install a new page table for ident mapping,
> > while it missed to consider building ident mapping for original area
> > of kernel if kaslr failed on physical randomization.
> > 
> > This only happens in kexec/kdump kernel. Since ident mapping has been
> > built for kexec/kdump in 1st kernel for the whole memory by calling
> > init_pgtable(). Here if physical randomizaiton failed, it won't build
> > ident mapping for the original area of kernel but change to new page
> > table '_pgtable'. Then kernel will reset to bios immediately caused by
> > no ident mapping.
> > 
> > While normal kernel won't be impacted because it comes here via
> > startup_32() and cr3 will be _pgtable already. In startup_32() ident
> > mapping is built for 0~4G area. In kaslr We just append to the existing
> > area instead of entirely overwriting it for on-demand ident mapping
> > building. So ident mapping for the original area of kernel is still
> > there.
> > 
> > So for fixing it,  We just switch to the new ident mapping page table
> > when physical kaslr succeeds. Otherwise we keep the old page table
> > unchanged just like nokaslr does.
> > 
> > Signed-off-by: Baoquan He <bhe@redhat.com>
> > Signed-off-by: Dave Young <dyoung@redhat.com>
> > Acked-by: Kees Cook <keescook@chromium.org>
> 
> That's not a valid signoff chain. I made it:
> 
>  Reported-by: Dave Young <dyoung@redhat.com>
>  Signed-off-by: Baoquan He <bhe@redhat.com>
>  Acked-by: Dave Young <dyoung@redhat.com>
>  Acked-by: Kees Cook <keescook@chromium.org>
> 
> (Let me know if that's not the proper authorship chain.)

Yeah, this is fine, thanks. Next time I will notice this.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [tip:x86/boot] x86/KASLR: Fix kexec kernel boot crash when KASLR randomization fails
  2017-04-27  7:42 [PATCH v2] x86/KASLR: Use old ident map page table if physical randomization failed Baoquan He
  2017-04-28  6:25 ` Ingo Molnar
@ 2017-04-28  8:34 ` tip-bot for Baoquan He
  1 sibling, 0 replies; 4+ messages in thread
From: tip-bot for Baoquan He @ 2017-04-28  8:34 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: peterz, mingo, torvalds, hpa, bp, keescook, tglx, dave.jiang,
	linux-kernel, bhe, thgarnie, dyoung, yinghai

Commit-ID:  da63b6b20077469bd6bd96e07991ce145fc4fbc4
Gitweb:     http://git.kernel.org/tip/da63b6b20077469bd6bd96e07991ce145fc4fbc4
Author:     Baoquan He <bhe@redhat.com>
AuthorDate: Thu, 27 Apr 2017 15:42:20 +0800
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Fri, 28 Apr 2017 08:31:15 +0200

x86/KASLR: Fix kexec kernel boot crash when KASLR randomization fails

Dave found that a kdump kernel with KASLR enabled will reset to the BIOS
immediately if physical randomization failed to find a new position for
the kernel. A kernel with the 'nokaslr' option works in this case.

The reason is that KASLR will install a new page table for the identity
mapping, while it missed building it for the original kernel location
if KASLR physical randomization fails.

This only happens in the kexec/kdump kernel, because the identity mapping
has been built for kexec/kdump in the 1st kernel for the whole memory by
calling init_pgtable(). Here if physical randomizaiton fails, it won't build
the identity mapping for the original area of the kernel but change to a
new page table '_pgtable'. Then the kernel will triple fault immediately
caused by no identity mappings.

The normal kernel won't see this bug, because it comes here via startup_32()
and CR3 will be set to _pgtable already. In startup_32() the identity
mapping is built for the 0~4G area. In KASLR we just append to the existing
area instead of entirely overwriting it for on-demand identity mapping
building. So the identity mapping for the original area of kernel is still
there.

To fix it we just switch to the new identity mapping page table when physical
KASLR succeeds. Otherwise we keep the old page table unchanged just like
"nokaslr" does.

Signed-off-by: Baoquan He <bhe@redhat.com>
Signed-off-by: Dave Young <dyoung@redhat.com>
Acked-by: Kees Cook <keescook@chromium.org>
Cc: Borislav Petkov <bp@suse.de>
Cc: Dave Jiang <dave.jiang@intel.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Garnier <thgarnie@google.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Yinghai Lu <yinghai@kernel.org>
Link: http://lkml.kernel.org/r/1493278940-5885-1-git-send-email-bhe@redhat.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/boot/compressed/kaslr.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/arch/x86/boot/compressed/kaslr.c b/arch/x86/boot/compressed/kaslr.c
index 6d9a546..54c24f0 100644
--- a/arch/x86/boot/compressed/kaslr.c
+++ b/arch/x86/boot/compressed/kaslr.c
@@ -597,10 +597,17 @@ void choose_random_location(unsigned long input,
 			add_identity_map(random_addr, output_size);
 			*output = random_addr;
 		}
+
+		/*
+		 * This loads the identity mapping page table.
+		 * This should only be done if a new physical address
+		 * is found for the kernel, otherwise we should keep
+		 * the old page table to make it be like the "nokaslr"
+		 * case.
+		 */
+		finalize_identity_maps();
 	}
 
-	/* This actually loads the identity pagetable on x86_64. */
-	finalize_identity_maps();
 
 	/* Pick random virtual address starting from LOAD_PHYSICAL_ADDR. */
 	if (IS_ENABLED(CONFIG_X86_64))

^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2017-04-28  8:41 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-04-27  7:42 [PATCH v2] x86/KASLR: Use old ident map page table if physical randomization failed Baoquan He
2017-04-28  6:25 ` Ingo Molnar
2017-04-28  6:59   ` Baoquan He
2017-04-28  8:34 ` [tip:x86/boot] x86/KASLR: Fix kexec kernel boot crash when KASLR randomization fails tip-bot for Baoquan He

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).