Page MenuHomeFreeBSD

D35449.id106825.diff
No OneTemporary

D35449.id106825.diff

Index: sys/amd64/amd64/locore.S
===================================================================
--- sys/amd64/amd64/locore.S
+++ sys/amd64/amd64/locore.S
@@ -48,6 +48,8 @@
.set dmapbase,DMAP_MIN_ADDRESS
.set dmapend,DMAP_MAX_ADDRESS
+#define BOOTSTACK_SIZE 4096
+
.text
/**********************************************************************
*
@@ -75,6 +77,18 @@
movq $bootstack,%rsp
xorl %ebp, %ebp
+#ifdef KASAN
+ /* Bootstrap a shadow map for the boot stack. */
+ movq %rdi, %r12
+ movq %rsi, %r13
+ movq $bootstack, %rdi
+ subq $BOOTSTACK_SIZE, %rdi
+ movq $BOOTSTACK_SIZE, %rsi
+ call kasan_init_early
+ movq %r12, %rdi
+ movq %r13, %rsi
+#endif
+
call hammer_time /* set up cpu for unix operation */
movq %rax,%rsp /* set up kstack for mi_startup() */
call mi_startup /* autoconfiguration, mountroot etc */
@@ -140,5 +154,5 @@
.bss
ALIGN_DATA /* just to be sure */
.globl bootstack
- .space 0x1000 /* space for bootstack - temporary stack */
+ .space BOOTSTACK_SIZE /* space for bootstack - temporary stack */
bootstack:
Index: sys/amd64/amd64/pmap.c
===================================================================
--- sys/amd64/amd64/pmap.c
+++ sys/amd64/amd64/pmap.c
@@ -11432,6 +11432,112 @@
}
#if defined(KASAN) || defined(KMSAN)
+
+#ifdef KASAN
+#define SAN_EARLY_PAGES (NKASANPML4E + 3)
+#else
+#define SAN_EARLY_PAGES (NKMSANSHADPML4E + NKMSANORIGPML4E + 2 * 3)
+#endif
+
+static uint64_t __nosanitizeaddress __nosanitizememory
+pmap_san_enter_early_alloc_4k(uint64_t pabase)
+{
+ static uint8_t data[PAGE_SIZE * SAN_EARLY_PAGES] __aligned(PAGE_SIZE);
+ static size_t offset = 0;
+ uint64_t pa;
+
+ if (offset == sizeof(data)) {
+ panic("%s: ran out of memory for the bootstrap shadow map",
+ __func__);
+ }
+
+ pa = pabase + ((vm_offset_t)&data[offset] - KERNSTART);
+ offset += PAGE_SIZE;
+ return (pa);
+}
+
+/*
+ * Map a shadow page, before the kernel has bootstrapped its page tables. This
+ * is currently only used to shadow the temporary boot stack set up by locore.
+ */
+static void __nosanitizeaddress __nosanitizememory
+pmap_san_enter_early(vm_offset_t va)
+{
+ static bool first = true;
+ pml4_entry_t *pml4e;
+ pdp_entry_t *pdpe;
+ pd_entry_t *pde;
+ pt_entry_t *pte;
+ uint64_t pa, base, cr3;
+ int i;
+
+ cr3 = rcr3() & ~CR3_PCID_MASK;
+
+ /*
+ * Where was the kernel loaded?
+ */
+ pml4e = (pml4_entry_t *)cr3 + pmap_pml4e_index(KERNSTART);
+ pdpe = (pdp_entry_t *)(*pml4e & PG_FRAME) + pmap_pdpe_index(KERNSTART);
+ pde = (pd_entry_t *)(*pdpe & PG_FRAME) + pmap_pde_index(KERNSTART);
+ base = *pde & PG_FRAME;
+
+ if (first) {
+ /*
+ * If this the first call, we need to allocate new PML4Es for
+ * the bootstrap shadow map(s). We don't know how the PML4 page
+ * was initialized by the boot loader, so we can't simply test
+ * whether the shadow map's PML4Es are zero.
+ */
+ first = false;
+#ifdef KASAN
+ for (i = 0; i < NKASANPML4E; i++) {
+ pa = pmap_san_enter_early_alloc_4k(base);
+
+ pml4e = (pml4_entry_t *)cr3 +
+ pmap_pml4e_index(KASAN_MIN_ADDRESS + i * NBPML4);
+ *pml4e = (pml4_entry_t)(pa | X86_PG_RW | X86_PG_V);
+ }
+#else
+ for (i = 0; i < NKMSANORIGPML4E; i++) {
+ pa = pmap_san_enter_early_alloc_4k(base);
+
+ pml4e = (pml4_entry_t *)cr3 +
+ pmap_pml4e_index(KMSAN_ORIG_MIN_ADDRESS +
+ i * NBPML4);
+ *pml4e = (pml4_entry_t)(pa | X86_PG_RW | X86_PG_V);
+ }
+ for (i = 0; i < NKMSANSHADPML4E; i++) {
+ pa = pmap_san_enter_early_alloc_4k(base);
+
+ pml4e = (pml4_entry_t *)cr3 +
+ pmap_pml4e_index(KMSAN_SHAD_MIN_ADDRESS +
+ i * NBPML4);
+ *pml4e = (pml4_entry_t)(pa | X86_PG_RW | X86_PG_V);
+ }
+#endif
+ }
+ pml4e = (pml4_entry_t *)cr3 + pmap_pml4e_index(va);
+ pdpe = (pdp_entry_t *)(*pml4e & PG_FRAME) + pmap_pdpe_index(va);
+ if (*pdpe != 0)
+ panic("%s: have PDPE for bootstrap shadow map", __func__);
+ if (*pdpe == 0) {
+ pa = pmap_san_enter_early_alloc_4k(base);
+ *pdpe = (pdp_entry_t)(pa | X86_PG_RW | X86_PG_V);
+ }
+ pde = (pd_entry_t *)(*pdpe & PG_FRAME) + pmap_pde_index(va);
+ if (*pde != 0)
+ panic("%s: have PDE for bootstrap shadow map", __func__);
+ if (*pde == 0) {
+ pa = pmap_san_enter_early_alloc_4k(base);
+ *pde = (pd_entry_t)(pa | X86_PG_RW | X86_PG_V);
+ }
+ pte = (pt_entry_t *)(*pde & PG_FRAME) + pmap_pte_index(va);
+ if (*pte != 0)
+ panic("%s: PTE for %#lx is already initialized", __func__, va);
+ pa = pmap_san_enter_early_alloc_4k(base);
+ *pte = (pt_entry_t)(pa | X86_PG_A | X86_PG_M | X86_PG_RW | X86_PG_V);
+}
+
static vm_page_t
pmap_san_enter_alloc_4k(void)
{
@@ -11455,7 +11561,7 @@
* Grow a shadow map by at least one 4KB page at the specified address. Use 2MB
* pages when possible.
*/
-void
+void __nosanitizeaddress __nosanitizememory
pmap_san_enter(vm_offset_t va)
{
pdp_entry_t *pdpe;
@@ -11463,6 +11569,14 @@
pt_entry_t *pte;
vm_page_t m;
+ if (kernphys == 0) {
+ /*
+ * We're creating a temporary shadow map for the boot stack.
+ */
+ pmap_san_enter_early(va);
+ return;
+ }
+
mtx_assert(&kernel_map->system_mtx, MA_OWNED);
pdpe = pmap_pdpe(kernel_pmap, va);
Index: sys/amd64/include/asan.h
===================================================================
--- sys/amd64/include/asan.h
+++ sys/amd64/include/asan.h
@@ -66,6 +66,12 @@
{
}
+static inline void
+kasan_md_init_early(vm_offset_t bootstack, size_t size)
+{
+ kasan_shadow_map(bootstack, size);
+}
+
#endif /* KASAN */
#endif /* !_MACHINE_ASAN_H_ */
Index: sys/amd64/include/pmap.h
===================================================================
--- sys/amd64/include/pmap.h
+++ sys/amd64/include/pmap.h
@@ -529,6 +529,7 @@
vm_page_t pmap_page_alloc_below_4g(bool zeroed);
#if defined(KASAN) || defined(KMSAN)
+void pmap_san_bootstrap(void);
void pmap_san_enter(vm_offset_t);
#endif
Index: sys/kern/subr_asan.c
===================================================================
--- sys/kern/subr_asan.c
+++ sys/kern/subr_asan.c
@@ -139,6 +139,12 @@
kasan_enabled = true;
}
+void
+kasan_init_early(vm_offset_t stack, size_t size)
+{
+ kasan_md_init_early(stack, size);
+}
+
static inline const char *
kasan_code_name(uint8_t code)
{
Index: sys/sys/asan.h
===================================================================
--- sys/sys/asan.h
+++ sys/sys/asan.h
@@ -56,11 +56,10 @@
#define KASAN_EXEC_ARGS_FREED 0xFF
void kasan_init(void);
+void kasan_init_early(vm_offset_t, size_t);
void kasan_shadow_map(vm_offset_t, size_t);
-
void kasan_mark(const void *, size_t, size_t, uint8_t);
#else /* KASAN */
-#define kasan_early_init(u)
#define kasan_init()
#define kasan_shadow_map(a, s)
#define kasan_mark(p, s, l, c)

File Metadata

Mime Type
text/plain
Expires
Sat, Nov 22, 2:56 PM (2 h, 46 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
25976770
Default Alt Text
D35449.id106825.diff (6 KB)

Event Timeline