Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F137225341
D35449.id106825.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D35449.id106825.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D35449: kasan: Create a shadow for the bootstack prior to hammer_time()
Attached
Detach File
Event Timeline
Log In to Comment