forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Cover kernel addresses above 0x90000000 by the shadow map. Enable HAVE_ARCH_KASAN when MMU is enabled. Provide kasan_early_init that fills shadow map with writable copies of kasan_zero_page. Call kasan_early_init right after mmu initialization in the setup_arch. Provide kasan_init that allocates proper shadow map pages from the memblock and puts these pages into the shadow map for addresses from VMALLOC area to the end of KSEG. Call kasan_init right after memblock initialization. Don't use KASAN for the boot code, MMU and KASAN initialization and page fault handler. Make kernel stack size 4 times larger when KASAN is enabled to avoid stack overflows. GCC 7.3, 8 or newer is required to build the xtensa kernel with KASAN. Signed-off-by: Max Filippov <[email protected]>
- Loading branch information
Showing
15 changed files
with
201 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -35,5 +35,5 @@ | |
| um: | TODO | | ||
| unicore32: | TODO | | ||
| x86: | ok | | ||
| xtensa: | TODO | | ||
| xtensa: | ok | | ||
----------------------- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
/* SPDX-License-Identifier: GPL-2.0 */ | ||
#ifndef __ASM_KASAN_H | ||
#define __ASM_KASAN_H | ||
|
||
#ifndef __ASSEMBLY__ | ||
|
||
#ifdef CONFIG_KASAN | ||
|
||
#include <linux/kernel.h> | ||
#include <linux/sizes.h> | ||
#include <asm/kmem_layout.h> | ||
|
||
/* Start of area covered by KASAN */ | ||
#define KASAN_START_VADDR __XTENSA_UL_CONST(0x90000000) | ||
/* Start of the shadow map */ | ||
#define KASAN_SHADOW_START (XCHAL_PAGE_TABLE_VADDR + XCHAL_PAGE_TABLE_SIZE) | ||
/* Size of the shadow map */ | ||
#define KASAN_SHADOW_SIZE (-KASAN_START_VADDR >> KASAN_SHADOW_SCALE_SHIFT) | ||
/* Offset for mem to shadow address transformation */ | ||
#define KASAN_SHADOW_OFFSET __XTENSA_UL_CONST(CONFIG_KASAN_SHADOW_OFFSET) | ||
|
||
void __init kasan_early_init(void); | ||
void __init kasan_init(void); | ||
|
||
#else | ||
|
||
static inline void kasan_early_init(void) | ||
{ | ||
} | ||
|
||
static inline void kasan_init(void) | ||
{ | ||
} | ||
|
||
#endif | ||
#endif | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
/* | ||
* Xtensa KASAN shadow map initialization | ||
* | ||
* This file is subject to the terms and conditions of the GNU General Public | ||
* License. See the file "COPYING" in the main directory of this archive | ||
* for more details. | ||
* | ||
* Copyright (C) 2017 Cadence Design Systems Inc. | ||
*/ | ||
|
||
#include <linux/bootmem.h> | ||
#include <linux/init_task.h> | ||
#include <linux/kasan.h> | ||
#include <linux/kernel.h> | ||
#include <linux/memblock.h> | ||
#include <asm/initialize_mmu.h> | ||
#include <asm/tlbflush.h> | ||
#include <asm/traps.h> | ||
|
||
void __init kasan_early_init(void) | ||
{ | ||
unsigned long vaddr = KASAN_SHADOW_START; | ||
pgd_t *pgd = pgd_offset_k(vaddr); | ||
pmd_t *pmd = pmd_offset(pgd, vaddr); | ||
int i; | ||
|
||
for (i = 0; i < PTRS_PER_PTE; ++i) | ||
set_pte(kasan_zero_pte + i, | ||
mk_pte(virt_to_page(kasan_zero_page), PAGE_KERNEL)); | ||
|
||
for (vaddr = 0; vaddr < KASAN_SHADOW_SIZE; vaddr += PMD_SIZE, ++pmd) { | ||
BUG_ON(!pmd_none(*pmd)); | ||
set_pmd(pmd, __pmd((unsigned long)kasan_zero_pte)); | ||
} | ||
early_trap_init(); | ||
} | ||
|
||
static void __init populate(void *start, void *end) | ||
{ | ||
unsigned long n_pages = (end - start) / PAGE_SIZE; | ||
unsigned long n_pmds = n_pages / PTRS_PER_PTE; | ||
unsigned long i, j; | ||
unsigned long vaddr = (unsigned long)start; | ||
pgd_t *pgd = pgd_offset_k(vaddr); | ||
pmd_t *pmd = pmd_offset(pgd, vaddr); | ||
pte_t *pte = memblock_virt_alloc(n_pages * sizeof(pte_t), PAGE_SIZE); | ||
|
||
pr_debug("%s: %p - %p\n", __func__, start, end); | ||
|
||
for (i = j = 0; i < n_pmds; ++i) { | ||
int k; | ||
|
||
for (k = 0; k < PTRS_PER_PTE; ++k, ++j) { | ||
phys_addr_t phys = | ||
memblock_alloc_base(PAGE_SIZE, PAGE_SIZE, | ||
MEMBLOCK_ALLOC_ANYWHERE); | ||
|
||
set_pte(pte + j, pfn_pte(PHYS_PFN(phys), PAGE_KERNEL)); | ||
} | ||
} | ||
|
||
for (i = 0; i < n_pmds ; ++i, pte += PTRS_PER_PTE) | ||
set_pmd(pmd + i, __pmd((unsigned long)pte)); | ||
|
||
local_flush_tlb_all(); | ||
memset(start, 0, end - start); | ||
} | ||
|
||
void __init kasan_init(void) | ||
{ | ||
int i; | ||
|
||
BUILD_BUG_ON(KASAN_SHADOW_OFFSET != KASAN_SHADOW_START - | ||
(KASAN_START_VADDR >> KASAN_SHADOW_SCALE_SHIFT)); | ||
BUILD_BUG_ON(VMALLOC_START < KASAN_START_VADDR); | ||
|
||
/* | ||
* Replace shadow map pages that cover addresses from VMALLOC area | ||
* start to the end of KSEG with clean writable pages. | ||
*/ | ||
populate(kasan_mem_to_shadow((void *)VMALLOC_START), | ||
kasan_mem_to_shadow((void *)XCHAL_KSEG_BYPASS_VADDR)); | ||
|
||
/* Write protect kasan_zero_page and zero-initialize it again. */ | ||
for (i = 0; i < PTRS_PER_PTE; ++i) | ||
set_pte(kasan_zero_pte + i, | ||
mk_pte(virt_to_page(kasan_zero_page), PAGE_KERNEL_RO)); | ||
|
||
local_flush_tlb_all(); | ||
memset(kasan_zero_page, 0, PAGE_SIZE); | ||
|
||
/* At this point kasan is fully initialized. Enable error messages. */ | ||
current->kasan_depth = 0; | ||
pr_info("KernelAddressSanitizer initialized\n"); | ||
} |