Re: KASAN vs. boot-time switching between 4- and 5-level paging

From: Andrey Ryabinin
Date: Tue Jul 11 2017 - 12:43:48 EST


On 07/11/2017 06:15 PM, Andrey Ryabinin wrote:
>
> I reproduced this, and this is kasan bug:
>
> â0xffffffff84864897 <x86_early_init_platform_quirks+5> mov $0xffffffff83f1d0b8,%rdi
> â0xffffffff8486489e <x86_early_init_platform_quirks+12> movabs $0xdffffc0000000000,%rax
> â0xffffffff848648a8 <x86_early_init_platform_quirks+22> push %rbp
> â0xffffffff848648a9 <x86_early_init_platform_quirks+23> mov %rdi,%rdx
> â0xffffffff848648ac <x86_early_init_platform_quirks+26> shr $0x3,%rdx
> â0xffffffff848648b0 <x86_early_init_platform_quirks+30> mov %rsp,%rbp
> >â0xffffffff848648b3 <x86_early_init_platform_quirks+33> mov (%rdx,%rax,1),%al
>
> we crash on the last move which is a read from shadow


Ughh, I forgot about phys_base.
Plus, I added KASAN_SANITIZE_paravirt.o :=n because with PARAVIRTY=y set_pgd() calls native_set_pgd()
from paravirt.c translation unit.



---
arch/x86/kernel/Makefile | 1 +
arch/x86/mm/kasan_init_64.c | 3 ++-
2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 4b994232cb57..5a1f18b87fb2 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -24,6 +24,7 @@ KASAN_SANITIZE_head$(BITS).o := n
KASAN_SANITIZE_dumpstack.o := n
KASAN_SANITIZE_dumpstack_$(BITS).o := n
KASAN_SANITIZE_stacktrace.o := n
+KASAN_SANITIZE_paravirt.o := n

OBJECT_FILES_NON_STANDARD_head_$(BITS).o := y
OBJECT_FILES_NON_STANDARD_relocate_kernel_$(BITS).o := y
diff --git a/arch/x86/mm/kasan_init_64.c b/arch/x86/mm/kasan_init_64.c
index d79a7ea83d05..d5743fd37df9 100644
--- a/arch/x86/mm/kasan_init_64.c
+++ b/arch/x86/mm/kasan_init_64.c
@@ -72,7 +72,8 @@ static void __init kasan_early_p4d_populate(pgd_t *pgd,
* TODO: we need helpers for this shit
*/
if (CONFIG_PGTABLE_LEVELS == 5)
- p4d = ((p4d_t*)((__pa_nodebug(pgd->pgd) & PTE_PFN_MASK) + __START_KERNEL_map))
+ p4d = ((p4d_t*)((__pa_nodebug(pgd->pgd) & PTE_PFN_MASK)
+ + __START_KERNEL_map - phys_base))
+ p4d_index(addr);
else
p4d = (p4d_t*)pgd;
--
2.13.0