Permit supervisor to access user VA space for certain functions only.
This is done by setting SUM (permit Supervisor User Memory access) bit in sstatus register. The functions we allow access for are routines in assembly that explicitly handle crossing the user kernel boundary. Approved by: re (kib) Sponsored by: DARPA, AFRL
This commit is contained in:
parent
95fb6bf7ba
commit
54f3f3f9dc
@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 2015 Ruslan Bukin <br@bsdpad.com>
|
||||
* Copyright (c) 2015-2018 Ruslan Bukin <br@bsdpad.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions of this software were developed by SRI International and the
|
||||
@ -63,4 +63,12 @@
|
||||
ld tmp, TD_PCB(tmp); /* Load the pcb */ \
|
||||
sd handler, PCB_ONFAULT(tmp) /* Set the handler */
|
||||
|
||||
#define ENTER_USER_ACCESS(tmp) \
|
||||
li tmp, SSTATUS_SUM; \
|
||||
csrs sstatus, tmp
|
||||
|
||||
#define EXIT_USER_ACCESS(tmp) \
|
||||
li tmp, SSTATUS_SUM; \
|
||||
csrc sstatus, tmp
|
||||
|
||||
#endif /* _MACHINE_ASM_H_ */
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include <machine/asm.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <machine/riscvreg.h>
|
||||
#include <sys/errno.h>
|
||||
|
||||
#include "assym.inc"
|
||||
@ -44,6 +45,7 @@ __FBSDID("$FreeBSD$");
|
||||
*/
|
||||
ENTRY(copyio_fault)
|
||||
SET_FAULT_HANDLER(x0, a1) /* Clear the handler */
|
||||
EXIT_USER_ACCESS(a1)
|
||||
copyio_fault_nopcb:
|
||||
li a0, EFAULT
|
||||
ret
|
||||
@ -62,6 +64,7 @@ ENTRY(copyout)
|
||||
|
||||
la a6, copyio_fault /* Get the handler address */
|
||||
SET_FAULT_HANDLER(a6, a7) /* Set the handler */
|
||||
ENTER_USER_ACCESS(a7)
|
||||
|
||||
1: lb a4, 0(a0) /* Load from kaddr */
|
||||
addi a0, a0, 1
|
||||
@ -70,6 +73,7 @@ ENTRY(copyout)
|
||||
addi a2, a2, -1 /* len-- */
|
||||
bnez a2, 1b
|
||||
|
||||
EXIT_USER_ACCESS(a7)
|
||||
SET_FAULT_HANDLER(x0, a7) /* Clear the handler */
|
||||
|
||||
2: li a0, 0 /* return 0 */
|
||||
@ -89,6 +93,7 @@ ENTRY(copyin)
|
||||
|
||||
la a6, copyio_fault /* Get the handler address */
|
||||
SET_FAULT_HANDLER(a6, a7) /* Set the handler */
|
||||
ENTER_USER_ACCESS(a7)
|
||||
|
||||
1: lb a4, 0(a0) /* Load from uaddr */
|
||||
addi a0, a0, 1
|
||||
@ -97,6 +102,7 @@ ENTRY(copyin)
|
||||
addi a2, a2, -1 /* len-- */
|
||||
bnez a2, 1b
|
||||
|
||||
EXIT_USER_ACCESS(a7)
|
||||
SET_FAULT_HANDLER(x0, a7) /* Clear the handler */
|
||||
|
||||
2: li a0, 0 /* return 0 */
|
||||
@ -114,6 +120,7 @@ ENTRY(copyinstr)
|
||||
|
||||
la a6, copyio_fault /* Get the handler address */
|
||||
SET_FAULT_HANDLER(a6, a7) /* Set the handler */
|
||||
ENTER_USER_ACCESS(a7)
|
||||
|
||||
li a7, VM_MAXUSER_ADDRESS
|
||||
1: bgt a0, a7, copyio_fault
|
||||
@ -125,8 +132,9 @@ ENTRY(copyinstr)
|
||||
addi a2, a2, -1 /* len-- */
|
||||
addi a5, a5, 1 /* count++ */
|
||||
bnez a2, 1b
|
||||
|
||||
2: SET_FAULT_HANDLER(x0, a7) /* Clear the handler */
|
||||
|
||||
2: EXIT_USER_ACCESS(a7)
|
||||
SET_FAULT_HANDLER(x0, a7) /* Clear the handler */
|
||||
|
||||
3: beqz a3, 4f /* Check if done != NULL */
|
||||
addi a5, a5, 1 /* count++ */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 2015-2017 Ruslan Bukin <br@bsdpad.com>
|
||||
* Copyright (c) 2015-2018 Ruslan Bukin <br@bsdpad.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions of this software were developed by SRI International and the
|
||||
@ -116,11 +116,8 @@ __FBSDID("$FreeBSD$");
|
||||
.macro load_registers el
|
||||
ld t0, (TF_SSTATUS)(sp)
|
||||
.if \el == 0
|
||||
/*
|
||||
* Ensure user interrupts will be enabled on eret
|
||||
* and supervisor mode can access userspace on trap.
|
||||
*/
|
||||
li t1, (SSTATUS_SPIE | SSTATUS_SUM)
|
||||
/* Ensure user interrupts will be enabled on eret */
|
||||
li t1, SSTATUS_SPIE
|
||||
or t0, t0, t1
|
||||
.else
|
||||
/*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 2015-2017 Ruslan Bukin <br@bsdpad.com>
|
||||
* Copyright (c) 2015-2018 Ruslan Bukin <br@bsdpad.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions of this software were developed by SRI International and the
|
||||
@ -62,9 +62,6 @@ _start:
|
||||
mv s10, a0 /* s10 = hart id */
|
||||
mv s11, a1 /* s11 = dtbp */
|
||||
|
||||
li t0, SSTATUS_SUM
|
||||
csrs sstatus, t0
|
||||
|
||||
/* Direct secondary cores to mpentry */
|
||||
bnez s10, mpentry
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 2015 Ruslan Bukin <br@bsdpad.com>
|
||||
* Copyright (c) 2015-2018 Ruslan Bukin <br@bsdpad.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions of this software were developed by SRI International and the
|
||||
@ -36,6 +36,7 @@
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <machine/setjmp.h>
|
||||
#include <machine/riscvreg.h>
|
||||
|
||||
#include "assym.inc"
|
||||
|
||||
@ -44,6 +45,7 @@ __FBSDID("$FreeBSD$");
|
||||
*/
|
||||
ENTRY(fsu_fault)
|
||||
SET_FAULT_HANDLER(x0, a1) /* Reset the handler function */
|
||||
EXIT_USER_ACCESS(a1)
|
||||
fsu_fault_nopcb:
|
||||
li a0, -1
|
||||
ret
|
||||
@ -57,11 +59,13 @@ ENTRY(casueword32)
|
||||
bgt a0, a4, fsu_fault_nopcb
|
||||
la a6, fsu_fault /* Load the fault handler */
|
||||
SET_FAULT_HANDLER(a6, a4) /* And set it */
|
||||
ENTER_USER_ACCESS(a4)
|
||||
1: lr.w a4, 0(a0) /* Load-exclusive the data */
|
||||
bne a4, a1, 2f /* If not equal then exit */
|
||||
sc.w a5, a3, 0(a0) /* Store the new data */
|
||||
bnez a5, 1b /* Retry on failure */
|
||||
2: SET_FAULT_HANDLER(x0, a5) /* Reset the fault handler */
|
||||
2: EXIT_USER_ACCESS(a5)
|
||||
SET_FAULT_HANDLER(x0, a5) /* Reset the fault handler */
|
||||
sw a4, 0(a2) /* Store the read data */
|
||||
li a0, 0 /* Success */
|
||||
ret /* Return */
|
||||
@ -75,11 +79,13 @@ ENTRY(casueword)
|
||||
bgt a0, a4, fsu_fault_nopcb
|
||||
la a6, fsu_fault /* Load the fault handler */
|
||||
SET_FAULT_HANDLER(a6, a4) /* And set it */
|
||||
ENTER_USER_ACCESS(a4)
|
||||
1: lr.d a4, 0(a0) /* Load-exclusive the data */
|
||||
bne a4, a1, 2f /* If not equal then exit */
|
||||
sc.d a5, a3, 0(a0) /* Store the new data */
|
||||
bnez a5, 1b /* Retry on failure */
|
||||
2: SET_FAULT_HANDLER(x0, a5) /* Reset the fault handler */
|
||||
2: EXIT_USER_ACCESS(a5)
|
||||
SET_FAULT_HANDLER(x0, a5) /* Reset the fault handler */
|
||||
sd a4, 0(a2) /* Store the read data */
|
||||
li a0, 0 /* Success */
|
||||
ret /* Return */
|
||||
@ -93,7 +99,9 @@ ENTRY(fubyte)
|
||||
bgt a0, a1, fsu_fault_nopcb
|
||||
la a6, fsu_fault /* Load the fault handler */
|
||||
SET_FAULT_HANDLER(a6, a1) /* And set it */
|
||||
ENTER_USER_ACCESS(a1)
|
||||
lb a0, 0(a0) /* Try loading the data */
|
||||
EXIT_USER_ACCESS(a1)
|
||||
SET_FAULT_HANDLER(x0, a1) /* Reset the fault handler */
|
||||
ret /* Return */
|
||||
END(fubyte)
|
||||
@ -106,7 +114,9 @@ ENTRY(fuword16)
|
||||
bgt a0, a1, fsu_fault_nopcb
|
||||
la a6, fsu_fault /* Load the fault handler */
|
||||
SET_FAULT_HANDLER(a6, a1) /* And set it */
|
||||
ENTER_USER_ACCESS(a1)
|
||||
lh a0, 0(a0) /* Try loading the data */
|
||||
EXIT_USER_ACCESS(a1)
|
||||
SET_FAULT_HANDLER(x0, a1) /* Reset the fault handler */
|
||||
ret /* Return */
|
||||
END(fuword16)
|
||||
@ -119,7 +129,9 @@ ENTRY(fueword32)
|
||||
bgt a0, a2, fsu_fault_nopcb
|
||||
la a6, fsu_fault /* Load the fault handler */
|
||||
SET_FAULT_HANDLER(a6, a2) /* And set it */
|
||||
ENTER_USER_ACCESS(a2)
|
||||
lw a0, 0(a0) /* Try loading the data */
|
||||
EXIT_USER_ACCESS(a2)
|
||||
SET_FAULT_HANDLER(x0, a2) /* Reset the fault handler */
|
||||
sw a0, 0(a1) /* Save the data in kernel space */
|
||||
li a0, 0 /* Success */
|
||||
@ -136,7 +148,9 @@ EENTRY(fueword64)
|
||||
bgt a0, a2, fsu_fault_nopcb
|
||||
la a6, fsu_fault /* Load the fault handler */
|
||||
SET_FAULT_HANDLER(a6, a2) /* And set it */
|
||||
ENTER_USER_ACCESS(a2)
|
||||
ld a0, 0(a0) /* Try loading the data */
|
||||
EXIT_USER_ACCESS(a2)
|
||||
SET_FAULT_HANDLER(x0, a2) /* Reset the fault handler */
|
||||
sd a0, 0(a1) /* Save the data in kernel space */
|
||||
li a0, 0 /* Success */
|
||||
@ -152,7 +166,9 @@ ENTRY(subyte)
|
||||
bgt a0, a2, fsu_fault_nopcb
|
||||
la a6, fsu_fault /* Load the fault handler */
|
||||
SET_FAULT_HANDLER(a6, a2) /* And set it */
|
||||
ENTER_USER_ACCESS(a2)
|
||||
sb a1, 0(a0) /* Try storing the data */
|
||||
EXIT_USER_ACCESS(a2)
|
||||
SET_FAULT_HANDLER(x0, a2) /* Reset the fault handler */
|
||||
li a0, 0 /* Success */
|
||||
ret /* Return */
|
||||
@ -166,7 +182,9 @@ ENTRY(suword16)
|
||||
bgt a0, a2, fsu_fault_nopcb
|
||||
la a6, fsu_fault /* Load the fault handler */
|
||||
SET_FAULT_HANDLER(a6, a2) /* And set it */
|
||||
ENTER_USER_ACCESS(a2)
|
||||
sh a1, 0(a0) /* Try storing the data */
|
||||
EXIT_USER_ACCESS(a2)
|
||||
SET_FAULT_HANDLER(x0, a2) /* Reset the fault handler */
|
||||
li a0, 0 /* Success */
|
||||
ret /* Return */
|
||||
@ -180,7 +198,9 @@ ENTRY(suword32)
|
||||
bgt a0, a2, fsu_fault_nopcb
|
||||
la a6, fsu_fault /* Load the fault handler */
|
||||
SET_FAULT_HANDLER(a6, a2) /* And set it */
|
||||
ENTER_USER_ACCESS(a2)
|
||||
sw a1, 0(a0) /* Try storing the data */
|
||||
EXIT_USER_ACCESS(a2)
|
||||
SET_FAULT_HANDLER(x0, a2) /* Reset the fault handler */
|
||||
li a0, 0 /* Success */
|
||||
ret /* Return */
|
||||
@ -195,7 +215,9 @@ EENTRY(suword64)
|
||||
bgt a0, a2, fsu_fault_nopcb
|
||||
la a6, fsu_fault /* Load the fault handler */
|
||||
SET_FAULT_HANDLER(a6, a2) /* And set it */
|
||||
ENTER_USER_ACCESS(a2)
|
||||
sd a1, 0(a0) /* Try storing the data */
|
||||
EXIT_USER_ACCESS(a2)
|
||||
SET_FAULT_HANDLER(x0, a2) /* Reset the fault handler */
|
||||
li a0, 0 /* Success */
|
||||
ret /* Return */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 2015-2017 Ruslan Bukin <br@bsdpad.com>
|
||||
* Copyright (c) 2015-2018 Ruslan Bukin <br@bsdpad.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions of this software were developed by SRI International and the
|
||||
@ -105,7 +105,6 @@ cpu_fork(struct thread *td1, struct proc *p2, struct thread *td2, int flags)
|
||||
tf->tf_a[0] = 0;
|
||||
tf->tf_a[1] = 0;
|
||||
tf->tf_sstatus |= (SSTATUS_SPIE); /* Enable interrupts. */
|
||||
tf->tf_sstatus |= (SSTATUS_SUM); /* Supervisor can access userspace. */
|
||||
tf->tf_sstatus &= ~(SSTATUS_SPP); /* User mode. */
|
||||
|
||||
td2->td_frame = tf;
|
||||
|
Loading…
Reference in New Issue
Block a user