Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/arm Some KASAN fixes and tweaks
details: https://anonhg.NetBSD.org/src/rev/b18ed02b1181
branches: trunk
changeset: 937884:b18ed02b1181
user: skrll <skrll%NetBSD.org@localhost>
date: Fri Aug 28 13:36:52 2020 +0000
description:
Some KASAN fixes and tweaks
- don't access BSS variables when __md_early
- centralise the INIT_ARM_STACK_{SHIFT,SIZE} defines and create a new
INIT_ARM_TOTAL_STACK
- Only create L1PT entries in kasan_md_shadow_map_page if
arm32_kernel_vm_init hasn't created the L2PTs (and their L1PT entries)
- Add some comments to explain what's going on
diffstat:
sys/arch/arm/arm/armv6_start.S | 7 +--
sys/arch/arm/arm32/arm32_kvminit.c | 6 +-
sys/arch/arm/arm32/genassym.cf | 7 ++-
sys/arch/arm/arm32/locore.S | 8 +--
sys/arch/arm/include/arm32/machdep.h | 6 ++-
sys/arch/arm/include/asan.h | 83 +++++++++++++++++++++++++----------
6 files changed, 78 insertions(+), 39 deletions(-)
diffs (273 lines):
diff -r 849680816be8 -r b18ed02b1181 sys/arch/arm/arm/armv6_start.S
--- a/sys/arch/arm/arm/armv6_start.S Fri Aug 28 13:15:05 2020 +0000
+++ b/sys/arch/arm/arm/armv6_start.S Fri Aug 28 13:36:52 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: armv6_start.S,v 1.26 2020/08/28 13:15:05 skrll Exp $ */
+/* $NetBSD: armv6_start.S,v 1.27 2020/08/28 13:36:52 skrll Exp $ */
/*-
* Copyright (c) 2012, 2017, 2018 The NetBSD Foundation, Inc.
@@ -43,9 +43,6 @@
#include <arm/armreg.h>
#include "assym.h"
-#define INIT_ARM_STACK_SHIFT 10
-#define INIT_ARM_STACK_SIZE (1 << INIT_ARM_STACK_SHIFT)
-
#if defined(CONSADDR) && defined(CONADDR)
#error Only one of CONSADDR and CONADDR should be defined
#endif
@@ -234,7 +231,7 @@
.global start_stacks_bottom
.global start_stacks_top
start_stacks_bottom:
- .space INIT_ARM_STACK_SIZE * MAXCPUS
+ .space INIT_ARM_TOTAL_STACK
start_stacks_top:
.section "_init_memory", "aw", %nobits
diff -r 849680816be8 -r b18ed02b1181 sys/arch/arm/arm32/arm32_kvminit.c
--- a/sys/arch/arm/arm32/arm32_kvminit.c Fri Aug 28 13:15:05 2020 +0000
+++ b/sys/arch/arm/arm32/arm32_kvminit.c Fri Aug 28 13:36:52 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: arm32_kvminit.c,v 1.64 2020/07/10 12:25:09 skrll Exp $ */
+/* $NetBSD: arm32_kvminit.c,v 1.65 2020/08/28 13:36:52 skrll Exp $ */
/*
* Copyright (c) 2002, 2003, 2005 Genetec Corporation. All rights reserved.
@@ -127,7 +127,7 @@
#include "opt_multiprocessor.h"
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: arm32_kvminit.c,v 1.64 2020/07/10 12:25:09 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: arm32_kvminit.c,v 1.65 2020/08/28 13:36:52 skrll Exp $");
#include <sys/param.h>
@@ -184,6 +184,7 @@
vaddr_t kasan_kernelsize;
#define KERNEL_L2PT_KASAN_NUM howmany(VM_KERNEL_KASAN_SIZE, L2_S_SEGSIZE)
+bool kasan_l2pts_created __attribute__((__section__(".data"))) = false;
pv_addr_t kasan_l2pt[KERNEL_L2PT_KASAN_NUM];
#else
#define KERNEL_L2PT_KASAN_NUM 0
@@ -741,6 +742,7 @@
__func__, kasan_l2pt[idx].pv_va, kasan_l2pt[idx].pv_pa,
va, "(kasan)");
}
+ kasan_l2pts_created = true;
#endif
/* update the top of the kernel VM */
diff -r 849680816be8 -r b18ed02b1181 sys/arch/arm/arm32/genassym.cf
--- a/sys/arch/arm/arm32/genassym.cf Fri Aug 28 13:15:05 2020 +0000
+++ b/sys/arch/arm/arm32/genassym.cf Fri Aug 28 13:36:52 2020 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: genassym.cf,v 1.94 2020/08/14 16:18:36 skrll Exp $
+# $NetBSD: genassym.cf,v 1.95 2020/08/28 13:36:52 skrll Exp $
# Copyright (c) 1982, 1990 The Regents of the University of California.
# All rights reserved.
@@ -58,6 +58,7 @@
include <arm/vfpreg.h>
include <arm/undefined.h>
+include <arm/arm32/machdep.h>
include <arm/arm32/pte.h>
include <machine/pmap.h>
@@ -160,6 +161,10 @@
#define CPU_CONTROL_DC_ENABLE CPU_CONTROL_DC_ENABLE
#define TTBCR_S_PD0 TTBCR_S_PD0
+define INIT_ARM_STACK_SHIFT INIT_ARM_STACK_SHIFT
+define INIT_ARM_STACK_SIZE INIT_ARM_STACK_SIZE
+define INIT_ARM_TOTAL_STACK INIT_ARM_TOTAL_STACK
+
# Important offsets into the lwp and proc structs & associated constants
define L_PCB offsetof(struct lwp, l_addr)
define L_CPU offsetof(struct lwp, l_cpu)
diff -r 849680816be8 -r b18ed02b1181 sys/arch/arm/arm32/locore.S
--- a/sys/arch/arm/arm32/locore.S Fri Aug 28 13:15:05 2020 +0000
+++ b/sys/arch/arm/arm32/locore.S Fri Aug 28 13:36:52 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: locore.S,v 1.42 2020/08/28 12:31:44 skrll Exp $ */
+/* $NetBSD: locore.S,v 1.43 2020/08/28 13:36:52 skrll Exp $ */
/*
* Copyright (C) 1994-1997 Mark Brinicombe
@@ -40,10 +40,7 @@
#include <arm/asm.h>
#include <arm/locore.h>
-/* What size should this really be ? It is only used by initarm() */
-#define INIT_ARM_STACK_SIZE 2048
-
- RCSID("$NetBSD: locore.S,v 1.42 2020/08/28 12:31:44 skrll Exp $")
+ RCSID("$NetBSD: locore.S,v 1.43 2020/08/28 13:36:52 skrll Exp $")
/*
* This is for kvm_mkdb, and should be the address of the beginning
@@ -137,6 +134,7 @@
#ifdef __ARM_EABI__
.align 3
#endif
+/* What size should this really be ? It is only used by initarm() */
svcstk:
.space INIT_ARM_STACK_SIZE
svcstk_end:
diff -r 849680816be8 -r b18ed02b1181 sys/arch/arm/include/arm32/machdep.h
--- a/sys/arch/arm/include/arm32/machdep.h Fri Aug 28 13:15:05 2020 +0000
+++ b/sys/arch/arm/include/arm32/machdep.h Fri Aug 28 13:36:52 2020 +0000
@@ -1,10 +1,14 @@
-/* $NetBSD: machdep.h,v 1.34 2020/07/04 07:02:35 skrll Exp $ */
+/* $NetBSD: machdep.h,v 1.35 2020/08/28 13:36:52 skrll Exp $ */
#ifndef _ARM32_MACHDEP_H_
#define _ARM32_MACHDEP_H_
#ifdef _KERNEL
+#define INIT_ARM_STACK_SHIFT 12
+#define INIT_ARM_STACK_SIZE (1 << INIT_ARM_STACK_SHIFT)
+#define INIT_ARM_TOTAL_STACK (INIT_ARM_STACK_SIZE * MAXCPUS)
+
/* Define various stack sizes in pages */
#ifndef IRQ_STACK_SIZE
#define IRQ_STACK_SIZE 1
diff -r 849680816be8 -r b18ed02b1181 sys/arch/arm/include/asan.h
--- a/sys/arch/arm/include/asan.h Fri Aug 28 13:15:05 2020 +0000
+++ b/sys/arch/arm/include/asan.h Fri Aug 28 13:36:52 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: asan.h,v 1.3 2020/07/19 11:47:48 skrll Exp $ */
+/* $NetBSD: asan.h,v 1.4 2020/08/28 13:36:52 skrll Exp $ */
/*
* Copyright (c) 2020 The NetBSD Foundation, Inc.
@@ -62,9 +62,24 @@
* that VA = PA + KERNEL_BASE.
*/
-#define KASAN_NEARLYPAGES 3
+/*
+ * KASAN_NEARLYPAGES is hard to work out.
+ *
+ * The INIT_ARM_TOTAL_STACK shadow is reduced by the KASAN_SHADOW_SCALE_SIZE
+ * factor. This shadow mapping is likely to span more than one L2 page tables
+ * and, as a result, more than one PAGE_SIZE block. The L2 page tables might
+ * span more than one L1 page table entry as well.
+ *
+ * To ensure we have enough start with the assumption of 1 L1 page table, and
+ * the number of pages to map the shadow... then double for the spanning as
+ * described above
+ */
+
+#define KASAN_NEARLYPAGES \
+ (2 * (1 + howmany(INIT_ARM_TOTAL_STACK / KASAN_SHADOW_SCALE_SIZE, PAGE_SIZE)))
static bool __md_early __read_mostly;
+static size_t __md_nearlyl1pts __attribute__((__section__(".data"))) = 0;
static size_t __md_nearlypages __attribute__((__section__(".data")));
static uint8_t __md_earlypages[KASAN_NEARLYPAGES * PAGE_SIZE]
__aligned(PAGE_SIZE) __attribute__((__section__(".data")));
@@ -115,22 +130,9 @@
vaddr_t l2ptva;
KASSERT((va & PAGE_MASK) == 0);
- KASSERT(__md_early || l1pte_page_p(pdep[l1slot]));
- if (!l1pte_page_p(pdep[l1slot])) {
- KASSERT(__md_early);
- const paddr_t l2ptpa = __md_palloc();
- const vaddr_t segl2va = va & -L2_S_SEGSIZE;
- const size_t segl1slot = l1pte_index(segl2va);
-
- const pd_entry_t npde =
- L1_C_PROTO | l2ptpa | L1_C_DOM(PMAP_DOMAIN_KERNEL);
-
- l1pte_set(pdep + segl1slot, npde);
- PDE_SYNC_RANGE(pdep, PAGE_SIZE / L2_T_SIZE);
-
- l2ptva = KERN_PHYSTOV(l1pte_pa(pdep[l1slot]));
- } else {
+ extern bool kasan_l2pts_created;
+ if (__predict_true(kasan_l2pts_created)) {
/*
* The shadow map area L2PTs were allocated and mapped
* by arm32_kernel_vm_init. Use the array of pv_addr_t
@@ -142,6 +144,29 @@
const size_t idx = off / L2_S_SEGSIZE;
const vaddr_t segl2ptva = kasan_l2pt[idx].pv_va;
l2ptva = segl2ptva + l1pte_index(segoff) * L2_TABLE_SIZE_REAL;
+ } else {
+ /*
+ * An L1PT entry is/may be required for bootstrap tables. As a
+ * page gives enough space to multiple L2PTs the previous call
+ * might have already created the L2PT.
+ */
+ if (!l1pte_page_p(pdep[l1slot])) {
+ const paddr_t l2ptpa = __md_palloc();
+ const vaddr_t segl2va = va & -L2_S_SEGSIZE;
+ const size_t segl1slot = l1pte_index(segl2va);
+
+ __md_nearlyl1pts++;
+
+ const pd_entry_t npde =
+ L1_C_PROTO | l2ptpa | L1_C_DOM(PMAP_DOMAIN_KERNEL);
+
+ l1pte_set(pdep + segl1slot, npde);
+ /*
+ * No need for PDE_SYNC_RANGE here as we're creating
+ * the bootstrap tables
+ */
+ }
+ l2ptva = KERN_PHYSTOV(l1pte_pa(pdep[l1slot]));
}
pt_entry_t * l2pt = (pt_entry_t *)l2ptva;
@@ -153,11 +178,13 @@
pt_entry_t npte =
L2_S_PROTO |
pa |
- pte_l2_s_cache_mode_pt |
+ (__md_early ? 0 : pte_l2_s_cache_mode_pt) |
L2_S_PROT(PTE_KERNEL, prot);
+ l2pte_set(ptep, npte, 0);
- l2pte_set(ptep, npte, 0);
- PTE_SYNC(ptep);
+ if (!__md_early)
+ PTE_SYNC(ptep);
+
__builtin_memset((void *)va, 0, PAGE_SIZE);
}
}
@@ -165,16 +192,22 @@
/*
* Map the init stacks of the BP and APs. We will map the rest in kasan_init.
*/
-#define INIT_ARM_STACK_SHIFT 10
-#define INIT_ARM_STACK_SIZE (1 << INIT_ARM_STACK_SHIFT)
-
static void
kasan_md_early_init(void *stack)
{
+ /*
+ * We come through here twice. The first time is for generic_start
+ * and the bootstrap tables. The second is for arm32_kernel_vm_init
+ * and the real tables.
+ *
+ * In the first we have to create L1PT entries, whereas in the
+ * second arm32_kernel_vm_init has setup kasan_l1pts (and the L1PT
+ * entries for them
+ */
__md_early = true;
- __md_nearlypages = 0;
- kasan_shadow_map(stack, INIT_ARM_STACK_SIZE * MAXCPUS);
+ __md_nearlypages = __md_nearlyl1pts;
+ kasan_shadow_map(stack, INIT_ARM_TOTAL_STACK);
__md_early = false;
}
Home |
Main Index |
Thread Index |
Old Index