diff --git a/sys/riscv/include/vmparam.h b/sys/riscv/include/vmparam.h --- a/sys/riscv/include/vmparam.h +++ b/sys/riscv/include/vmparam.h @@ -186,6 +186,10 @@ #define VM_MINUSER_ADDRESS (VM_MIN_USER_ADDRESS) #define VM_MAXUSER_ADDRESS (VM_MAX_USER_ADDRESS) +/* Check if an address resides in a mappable region. */ +#define VIRT_IS_VALID(va) \ + (((va) < VM_MAX_USER_ADDRESS) || ((va) >= VM_MIN_KERNEL_ADDRESS)) + #define KERNBASE (VM_MIN_KERNEL_ADDRESS) #define SHAREDPAGE (VM_MAXUSER_ADDRESS - PAGE_SIZE) #define USRSTACK SHAREDPAGE diff --git a/sys/riscv/riscv/pmap.c b/sys/riscv/riscv/pmap.c --- a/sys/riscv/riscv/pmap.c +++ b/sys/riscv/riscv/pmap.c @@ -351,6 +351,8 @@ pmap_l1(pmap_t pmap, vm_offset_t va) { + KASSERT(VIRT_IS_VALID(va), + ("%s: malformed virtual address %#lx", __func__, va)); return (&pmap->pm_l1[pmap_l1_index(va)]); } diff --git a/sys/riscv/riscv/trap.c b/sys/riscv/riscv/trap.c --- a/sys/riscv/riscv/trap.c +++ b/sys/riscv/riscv/trap.c @@ -200,6 +200,11 @@ goto fatal; if (usermode) { + if (!VIRT_IS_VALID(stval)) { + call_trapsignal(td, SIGSEGV, SEGV_MAPERR, (void *)stval, + frame->tf_scause & SCAUSE_CODE); + goto done; + } map = &td->td_proc->p_vmspace->vm_map; } else { /* @@ -208,6 +213,9 @@ */ intr_enable(); + if (!VIRT_IS_VALID(stval)) + goto fatal; + if (stval >= VM_MAX_USER_ADDRESS) { map = kernel_map; } else {