Add checks for kernel VA accesses to the copyin(9) and related
functions on arm64. Reviewed by: andrew Sponsored by: The FreeBSD Foundation Differential revision: https://reviews.freebsd.org/D3907
This commit is contained in:
parent
16294b3699
commit
a1cbced296
@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
*/
|
*/
|
||||||
ENTRY(copyio_fault)
|
ENTRY(copyio_fault)
|
||||||
SET_FAULT_HANDLER(xzr, x1) /* Clear the handler */
|
SET_FAULT_HANDLER(xzr, x1) /* Clear the handler */
|
||||||
|
copyio_fault_nopcb:
|
||||||
mov x0, #EFAULT
|
mov x0, #EFAULT
|
||||||
ret
|
ret
|
||||||
END(copyio_fault)
|
END(copyio_fault)
|
||||||
@ -51,6 +52,10 @@ END(copyio_fault)
|
|||||||
*/
|
*/
|
||||||
ENTRY(copyout)
|
ENTRY(copyout)
|
||||||
cbz x2, 2f /* If len == 0 then skip loop */
|
cbz x2, 2f /* If len == 0 then skip loop */
|
||||||
|
add x3, x1, x2
|
||||||
|
ldr x4, =VM_MAXUSER_ADDRESS
|
||||||
|
cmp x3, x4
|
||||||
|
b.hi copyio_fault_nopcb
|
||||||
|
|
||||||
adr x6, copyio_fault /* Get the handler address */
|
adr x6, copyio_fault /* Get the handler address */
|
||||||
SET_FAULT_HANDLER(x6, x7) /* Set the handler */
|
SET_FAULT_HANDLER(x6, x7) /* Set the handler */
|
||||||
@ -73,6 +78,10 @@ END(copyout)
|
|||||||
*/
|
*/
|
||||||
ENTRY(copyin)
|
ENTRY(copyin)
|
||||||
cbz x2, 2f /* If len == 0 then skip loop */
|
cbz x2, 2f /* If len == 0 then skip loop */
|
||||||
|
add x3, x0, x2
|
||||||
|
ldr x4, =VM_MAXUSER_ADDRESS
|
||||||
|
cmp x3, x4
|
||||||
|
b.hi copyio_fault_nopcb
|
||||||
|
|
||||||
adr x6, copyio_fault /* Get the handler address */
|
adr x6, copyio_fault /* Get the handler address */
|
||||||
SET_FAULT_HANDLER(x6, x7) /* Set the handler */
|
SET_FAULT_HANDLER(x6, x7) /* Set the handler */
|
||||||
@ -97,11 +106,14 @@ ENTRY(copyinstr)
|
|||||||
mov x5, xzr /* count = 0 */
|
mov x5, xzr /* count = 0 */
|
||||||
mov w4, #1 /* If zero return faulure */
|
mov w4, #1 /* If zero return faulure */
|
||||||
cbz x2, 3f /* If len == 0 then skip loop */
|
cbz x2, 3f /* If len == 0 then skip loop */
|
||||||
|
ldr x7, =VM_MAXUSER_ADDRESS
|
||||||
|
|
||||||
adr x6, copyio_fault /* Get the handler address */
|
adr x6, copyio_fault /* Get the handler address */
|
||||||
SET_FAULT_HANDLER(x6, x7) /* Set the handler */
|
SET_FAULT_HANDLER(x6, x7) /* Set the handler */
|
||||||
|
|
||||||
1: ldrb w4, [x0], #1 /* Load from uaddr */
|
1: cmp x0, x7
|
||||||
|
b.cs copyio_fault
|
||||||
|
ldrb w4, [x0], #1 /* Load from uaddr */
|
||||||
strb w4, [x1], #1 /* Store in kaddr */
|
strb w4, [x1], #1 /* Store in kaddr */
|
||||||
add x5, x5, #1 /* count++ */
|
add x5, x5, #1 /* count++ */
|
||||||
cbz w4, 2f /* Break when NUL-terminated */
|
cbz w4, 2f /* Break when NUL-terminated */
|
||||||
|
@ -38,6 +38,8 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <machine/vmparam.h>
|
#include <machine/vmparam.h>
|
||||||
|
|
||||||
ASSYM(KERNBASE, KERNBASE);
|
ASSYM(KERNBASE, KERNBASE);
|
||||||
|
ASSYM(VM_MAXUSER_ADDRESS, VM_MAXUSER_ADDRESS);
|
||||||
|
|
||||||
ASSYM(TDF_ASTPENDING, TDF_ASTPENDING);
|
ASSYM(TDF_ASTPENDING, TDF_ASTPENDING);
|
||||||
ASSYM(TDF_NEEDRESCHED, TDF_NEEDRESCHED);
|
ASSYM(TDF_NEEDRESCHED, TDF_NEEDRESCHED);
|
||||||
|
|
||||||
|
@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
*/
|
*/
|
||||||
ENTRY(fsu_fault)
|
ENTRY(fsu_fault)
|
||||||
SET_FAULT_HANDLER(xzr, x1) /* Reset the handler function */
|
SET_FAULT_HANDLER(xzr, x1) /* Reset the handler function */
|
||||||
|
fsu_fault_nopcb:
|
||||||
mov x0, #-1
|
mov x0, #-1
|
||||||
ret
|
ret
|
||||||
END(fsu_fault)
|
END(fsu_fault)
|
||||||
@ -49,6 +50,9 @@ END(fsu_fault)
|
|||||||
* int casueword32(volatile uint32_t *, uint32_t, uint32_t *, uint32_t)
|
* int casueword32(volatile uint32_t *, uint32_t, uint32_t *, uint32_t)
|
||||||
*/
|
*/
|
||||||
ENTRY(casueword32)
|
ENTRY(casueword32)
|
||||||
|
ldr x4, =(VM_MAXUSER_ADDRESS-3)
|
||||||
|
cmp x0, x4
|
||||||
|
b.cs fsu_fault_nopcb
|
||||||
adr x6, fsu_fault /* Load the fault handler */
|
adr x6, fsu_fault /* Load the fault handler */
|
||||||
SET_FAULT_HANDLER(x6, x4) /* And set it */
|
SET_FAULT_HANDLER(x6, x4) /* And set it */
|
||||||
1: ldxr w4, [x0] /* Load-exclusive the data */
|
1: ldxr w4, [x0] /* Load-exclusive the data */
|
||||||
@ -67,6 +71,9 @@ END(casueword32)
|
|||||||
* int casueword(volatile u_long *, u_long, u_long *, u_long)
|
* int casueword(volatile u_long *, u_long, u_long *, u_long)
|
||||||
*/
|
*/
|
||||||
ENTRY(casueword)
|
ENTRY(casueword)
|
||||||
|
ldr x4, =(VM_MAXUSER_ADDRESS-7)
|
||||||
|
cmp x0, x4
|
||||||
|
b.cs fsu_fault_nopcb
|
||||||
adr x6, fsu_fault /* Load the fault handler */
|
adr x6, fsu_fault /* Load the fault handler */
|
||||||
SET_FAULT_HANDLER(x6, x4) /* And set it */
|
SET_FAULT_HANDLER(x6, x4) /* And set it */
|
||||||
1: ldxr x4, [x0] /* Load-exclusive the data */
|
1: ldxr x4, [x0] /* Load-exclusive the data */
|
||||||
@ -85,6 +92,9 @@ END(casueword)
|
|||||||
* int fubyte(volatile const void *)
|
* int fubyte(volatile const void *)
|
||||||
*/
|
*/
|
||||||
ENTRY(fubyte)
|
ENTRY(fubyte)
|
||||||
|
ldr x1, =VM_MAXUSER_ADDRESS
|
||||||
|
cmp x0, x1
|
||||||
|
b.cs fsu_fault_nopcb
|
||||||
adr x6, fsu_fault /* Load the fault handler */
|
adr x6, fsu_fault /* Load the fault handler */
|
||||||
SET_FAULT_HANDLER(x6, x1) /* And set it */
|
SET_FAULT_HANDLER(x6, x1) /* And set it */
|
||||||
ldrb w0, [x0] /* Try loading the data */
|
ldrb w0, [x0] /* Try loading the data */
|
||||||
@ -96,6 +106,9 @@ END(fubyte)
|
|||||||
* int fuword(volatile const void *)
|
* int fuword(volatile const void *)
|
||||||
*/
|
*/
|
||||||
ENTRY(fuword16)
|
ENTRY(fuword16)
|
||||||
|
ldr x1, =(VM_MAXUSER_ADDRESS-1)
|
||||||
|
cmp x0, x1
|
||||||
|
b.cs fsu_fault_nopcb
|
||||||
adr x6, fsu_fault /* Load the fault handler */
|
adr x6, fsu_fault /* Load the fault handler */
|
||||||
SET_FAULT_HANDLER(x6, x1) /* And set it */
|
SET_FAULT_HANDLER(x6, x1) /* And set it */
|
||||||
ldrh w0, [x0] /* Try loading the data */
|
ldrh w0, [x0] /* Try loading the data */
|
||||||
@ -107,6 +120,9 @@ END(fuword16)
|
|||||||
* int32_t fueword32(volatile const void *, int32_t *)
|
* int32_t fueword32(volatile const void *, int32_t *)
|
||||||
*/
|
*/
|
||||||
ENTRY(fueword32)
|
ENTRY(fueword32)
|
||||||
|
ldr x2, =(VM_MAXUSER_ADDRESS-3)
|
||||||
|
cmp x0, x2
|
||||||
|
b.cs fsu_fault_nopcb
|
||||||
adr x6, fsu_fault /* Load the fault handler */
|
adr x6, fsu_fault /* Load the fault handler */
|
||||||
SET_FAULT_HANDLER(x6, x2) /* And set it */
|
SET_FAULT_HANDLER(x6, x2) /* And set it */
|
||||||
ldr w0, [x0] /* Try loading the data */
|
ldr w0, [x0] /* Try loading the data */
|
||||||
@ -122,6 +138,9 @@ END(fueword32)
|
|||||||
*/
|
*/
|
||||||
ENTRY(fueword)
|
ENTRY(fueword)
|
||||||
EENTRY(fueword64)
|
EENTRY(fueword64)
|
||||||
|
ldr x2, =(VM_MAXUSER_ADDRESS-7)
|
||||||
|
cmp x0, x2
|
||||||
|
b.cs fsu_fault_nopcb
|
||||||
adr x6, fsu_fault /* Load the fault handler */
|
adr x6, fsu_fault /* Load the fault handler */
|
||||||
SET_FAULT_HANDLER(x6, x2) /* And set it */
|
SET_FAULT_HANDLER(x6, x2) /* And set it */
|
||||||
ldr x0, [x0] /* Try loading the data */
|
ldr x0, [x0] /* Try loading the data */
|
||||||
@ -136,6 +155,9 @@ END(fueword)
|
|||||||
* int subyte(volatile void *, int)
|
* int subyte(volatile void *, int)
|
||||||
*/
|
*/
|
||||||
ENTRY(subyte)
|
ENTRY(subyte)
|
||||||
|
ldr x2, =VM_MAXUSER_ADDRESS
|
||||||
|
cmp x0, x2
|
||||||
|
b.cs fsu_fault_nopcb
|
||||||
adr x6, fsu_fault /* Load the fault handler */
|
adr x6, fsu_fault /* Load the fault handler */
|
||||||
SET_FAULT_HANDLER(x6, x2) /* And set it */
|
SET_FAULT_HANDLER(x6, x2) /* And set it */
|
||||||
strb w1, [x0] /* Try storing the data */
|
strb w1, [x0] /* Try storing the data */
|
||||||
@ -148,6 +170,9 @@ END(subyte)
|
|||||||
* int suword16(volatile void *, int)
|
* int suword16(volatile void *, int)
|
||||||
*/
|
*/
|
||||||
ENTRY(suword16)
|
ENTRY(suword16)
|
||||||
|
ldr x2, =(VM_MAXUSER_ADDRESS-1)
|
||||||
|
cmp x0, x2
|
||||||
|
b.cs fsu_fault_nopcb
|
||||||
adr x6, fsu_fault /* Load the fault handler */
|
adr x6, fsu_fault /* Load the fault handler */
|
||||||
SET_FAULT_HANDLER(x6, x2) /* And set it */
|
SET_FAULT_HANDLER(x6, x2) /* And set it */
|
||||||
strh w1, [x0] /* Try storing the data */
|
strh w1, [x0] /* Try storing the data */
|
||||||
@ -160,6 +185,9 @@ END(suword16)
|
|||||||
* int suword32(volatile void *, int)
|
* int suword32(volatile void *, int)
|
||||||
*/
|
*/
|
||||||
ENTRY(suword32)
|
ENTRY(suword32)
|
||||||
|
ldr x2, =(VM_MAXUSER_ADDRESS-3)
|
||||||
|
cmp x0, x2
|
||||||
|
b.cs fsu_fault_nopcb
|
||||||
adr x6, fsu_fault /* Load the fault handler */
|
adr x6, fsu_fault /* Load the fault handler */
|
||||||
SET_FAULT_HANDLER(x6, x2) /* And set it */
|
SET_FAULT_HANDLER(x6, x2) /* And set it */
|
||||||
str w1, [x0] /* Try storing the data */
|
str w1, [x0] /* Try storing the data */
|
||||||
@ -173,6 +201,9 @@ END(suword32)
|
|||||||
*/
|
*/
|
||||||
ENTRY(suword)
|
ENTRY(suword)
|
||||||
EENTRY(suword64)
|
EENTRY(suword64)
|
||||||
|
ldr x2, =(VM_MAXUSER_ADDRESS-7)
|
||||||
|
cmp x0, x2
|
||||||
|
b.cs fsu_fault_nopcb
|
||||||
adr x6, fsu_fault /* Load the fault handler */
|
adr x6, fsu_fault /* Load the fault handler */
|
||||||
SET_FAULT_HANDLER(x6, x2) /* And set it */
|
SET_FAULT_HANDLER(x6, x2) /* And set it */
|
||||||
str x1, [x0] /* Try storing the data */
|
str x1, [x0] /* Try storing the data */
|
||||||
@ -201,6 +232,9 @@ END(fsu_fault)
|
|||||||
* int fuswintr(void *)
|
* int fuswintr(void *)
|
||||||
*/
|
*/
|
||||||
ENTRY(fuswintr)
|
ENTRY(fuswintr)
|
||||||
|
ldr x1, =(VM_MAXUSER_ADDRESS-3)
|
||||||
|
cmp x0, x1
|
||||||
|
b.cs fsu_fault_nopcb
|
||||||
adr x6, fsu_intr_fault /* Load the fault handler */
|
adr x6, fsu_intr_fault /* Load the fault handler */
|
||||||
SET_FAULT_HANDLER(x6, x1) /* And set it */
|
SET_FAULT_HANDLER(x6, x1) /* And set it */
|
||||||
ldr w0, [x0] /* Try loading the data */
|
ldr w0, [x0] /* Try loading the data */
|
||||||
@ -212,6 +246,9 @@ END(fuswintr)
|
|||||||
* int suswintr(void *base, int word)
|
* int suswintr(void *base, int word)
|
||||||
*/
|
*/
|
||||||
ENTRY(suswintr)
|
ENTRY(suswintr)
|
||||||
|
ldr x2, =(VM_MAXUSER_ADDRESS-3)
|
||||||
|
cmp x0, x2
|
||||||
|
b.cs fsu_fault_nopcb
|
||||||
adr x6, fsu_intr_fault /* Load the fault handler */
|
adr x6, fsu_intr_fault /* Load the fault handler */
|
||||||
SET_FAULT_HANDLER(x6, x2) /* And set it */
|
SET_FAULT_HANDLER(x6, x2) /* And set it */
|
||||||
str w1, [x0] /* Try storing the data */
|
str w1, [x0] /* Try storing the data */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user