From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1162432AbdD0Hmm (ORCPT ); Thu, 27 Apr 2017 03:42:42 -0400 Received: from mx1.redhat.com ([209.132.183.28]:33452 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S965750AbdD0Hmc (ORCPT ); Thu, 27 Apr 2017 03:42:32 -0400 DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com B07E4A08EF Authentication-Results: ext-mx10.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx10.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=bhe@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com B07E4A08EF From: Baoquan He To: linux-kernel@vger.kernel.org Cc: Baoquan He , Dave Young , "H. Peter Anvin" , Thomas Gleixner , Ingo Molnar , x86@kernel.org, Kees Cook , Yinghai Lu , Borislav Petkov , Dave Jiang , Thomas Garnier Subject: [PATCH v2] x86/KASLR: Use old ident map page table if physical randomization failed Date: Thu, 27 Apr 2017 15:42:20 +0800 Message-Id: <1493278940-5885-1-git-send-email-bhe@redhat.com> X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Thu, 27 Apr 2017 07:42:31 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 Signed-off-by: Dave Young Acked-by: Kees Cook Cc: "H. Peter Anvin" Cc: Thomas Gleixner Cc: Ingo Molnar Cc: x86@kernel.org Cc: Kees Cook Cc: Yinghai Lu Cc: Borislav Petkov Cc: Dave Jiang Cc: Thomas Garnier --- 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