summaryrefslogtreecommitdiffstats
path: root/sys/arm64
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2015-10-17 13:20:42 +0000
committerkib <kib@FreeBSD.org>2015-10-17 13:20:42 +0000
commita1cbced296301ad40506e3a0fc6ae3bfa505ed91 (patch)
tree692b0ac7eb7fdb41c9e3becdf5ef3bca67564f3a /sys/arm64
parent16294b3699f26c533525aac9a852c8259e5a5f2c (diff)
downloadFreeBSD-src-a1cbced296301ad40506e3a0fc6ae3bfa505ed91.zip
FreeBSD-src-a1cbced296301ad40506e3a0fc6ae3bfa505ed91.tar.gz
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
Diffstat (limited to 'sys/arm64')
-rw-r--r--sys/arm64/arm64/copyinout.S14
-rw-r--r--sys/arm64/arm64/genassym.c2
-rw-r--r--sys/arm64/arm64/support.S37
3 files changed, 52 insertions, 1 deletions
diff --git a/sys/arm64/arm64/copyinout.S b/sys/arm64/arm64/copyinout.S
index 0982c70..1ba8106 100644
--- a/sys/arm64/arm64/copyinout.S
+++ b/sys/arm64/arm64/copyinout.S
@@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
*/
ENTRY(copyio_fault)
SET_FAULT_HANDLER(xzr, x1) /* Clear the handler */
+copyio_fault_nopcb:
mov x0, #EFAULT
ret
END(copyio_fault)
@@ -51,6 +52,10 @@ END(copyio_fault)
*/
ENTRY(copyout)
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 */
SET_FAULT_HANDLER(x6, x7) /* Set the handler */
@@ -73,6 +78,10 @@ END(copyout)
*/
ENTRY(copyin)
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 */
SET_FAULT_HANDLER(x6, x7) /* Set the handler */
@@ -97,11 +106,14 @@ ENTRY(copyinstr)
mov x5, xzr /* count = 0 */
mov w4, #1 /* If zero return faulure */
cbz x2, 3f /* If len == 0 then skip loop */
+ ldr x7, =VM_MAXUSER_ADDRESS
adr x6, copyio_fault /* Get the handler address */
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 */
add x5, x5, #1 /* count++ */
cbz w4, 2f /* Break when NUL-terminated */
diff --git a/sys/arm64/arm64/genassym.c b/sys/arm64/arm64/genassym.c
index 33b2042..f8dfeda 100644
--- a/sys/arm64/arm64/genassym.c
+++ b/sys/arm64/arm64/genassym.c
@@ -38,6 +38,8 @@ __FBSDID("$FreeBSD$");
#include <machine/vmparam.h>
ASSYM(KERNBASE, KERNBASE);
+ASSYM(VM_MAXUSER_ADDRESS, VM_MAXUSER_ADDRESS);
+
ASSYM(TDF_ASTPENDING, TDF_ASTPENDING);
ASSYM(TDF_NEEDRESCHED, TDF_NEEDRESCHED);
diff --git a/sys/arm64/arm64/support.S b/sys/arm64/arm64/support.S
index 914a6e3..749fc6e 100644
--- a/sys/arm64/arm64/support.S
+++ b/sys/arm64/arm64/support.S
@@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$");
*/
ENTRY(fsu_fault)
SET_FAULT_HANDLER(xzr, x1) /* Reset the handler function */
+fsu_fault_nopcb:
mov x0, #-1
ret
END(fsu_fault)
@@ -49,6 +50,9 @@ END(fsu_fault)
* int casueword32(volatile uint32_t *, uint32_t, uint32_t *, uint32_t)
*/
ENTRY(casueword32)
+ ldr x4, =(VM_MAXUSER_ADDRESS-3)
+ cmp x0, x4
+ b.cs fsu_fault_nopcb
adr x6, fsu_fault /* Load the fault handler */
SET_FAULT_HANDLER(x6, x4) /* And set it */
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)
*/
ENTRY(casueword)
+ ldr x4, =(VM_MAXUSER_ADDRESS-7)
+ cmp x0, x4
+ b.cs fsu_fault_nopcb
adr x6, fsu_fault /* Load the fault handler */
SET_FAULT_HANDLER(x6, x4) /* And set it */
1: ldxr x4, [x0] /* Load-exclusive the data */
@@ -85,6 +92,9 @@ END(casueword)
* int fubyte(volatile const void *)
*/
ENTRY(fubyte)
+ ldr x1, =VM_MAXUSER_ADDRESS
+ cmp x0, x1
+ b.cs fsu_fault_nopcb
adr x6, fsu_fault /* Load the fault handler */
SET_FAULT_HANDLER(x6, x1) /* And set it */
ldrb w0, [x0] /* Try loading the data */
@@ -96,6 +106,9 @@ END(fubyte)
* int fuword(volatile const void *)
*/
ENTRY(fuword16)
+ ldr x1, =(VM_MAXUSER_ADDRESS-1)
+ cmp x0, x1
+ b.cs fsu_fault_nopcb
adr x6, fsu_fault /* Load the fault handler */
SET_FAULT_HANDLER(x6, x1) /* And set it */
ldrh w0, [x0] /* Try loading the data */
@@ -107,6 +120,9 @@ END(fuword16)
* int32_t fueword32(volatile const void *, int32_t *)
*/
ENTRY(fueword32)
+ ldr x2, =(VM_MAXUSER_ADDRESS-3)
+ cmp x0, x2
+ b.cs fsu_fault_nopcb
adr x6, fsu_fault /* Load the fault handler */
SET_FAULT_HANDLER(x6, x2) /* And set it */
ldr w0, [x0] /* Try loading the data */
@@ -122,6 +138,9 @@ END(fueword32)
*/
ENTRY(fueword)
EENTRY(fueword64)
+ ldr x2, =(VM_MAXUSER_ADDRESS-7)
+ cmp x0, x2
+ b.cs fsu_fault_nopcb
adr x6, fsu_fault /* Load the fault handler */
SET_FAULT_HANDLER(x6, x2) /* And set it */
ldr x0, [x0] /* Try loading the data */
@@ -136,6 +155,9 @@ END(fueword)
* int subyte(volatile void *, int)
*/
ENTRY(subyte)
+ ldr x2, =VM_MAXUSER_ADDRESS
+ cmp x0, x2
+ b.cs fsu_fault_nopcb
adr x6, fsu_fault /* Load the fault handler */
SET_FAULT_HANDLER(x6, x2) /* And set it */
strb w1, [x0] /* Try storing the data */
@@ -148,6 +170,9 @@ END(subyte)
* int suword16(volatile void *, int)
*/
ENTRY(suword16)
+ ldr x2, =(VM_MAXUSER_ADDRESS-1)
+ cmp x0, x2
+ b.cs fsu_fault_nopcb
adr x6, fsu_fault /* Load the fault handler */
SET_FAULT_HANDLER(x6, x2) /* And set it */
strh w1, [x0] /* Try storing the data */
@@ -160,6 +185,9 @@ END(suword16)
* int suword32(volatile void *, int)
*/
ENTRY(suword32)
+ ldr x2, =(VM_MAXUSER_ADDRESS-3)
+ cmp x0, x2
+ b.cs fsu_fault_nopcb
adr x6, fsu_fault /* Load the fault handler */
SET_FAULT_HANDLER(x6, x2) /* And set it */
str w1, [x0] /* Try storing the data */
@@ -173,6 +201,9 @@ END(suword32)
*/
ENTRY(suword)
EENTRY(suword64)
+ ldr x2, =(VM_MAXUSER_ADDRESS-7)
+ cmp x0, x2
+ b.cs fsu_fault_nopcb
adr x6, fsu_fault /* Load the fault handler */
SET_FAULT_HANDLER(x6, x2) /* And set it */
str x1, [x0] /* Try storing the data */
@@ -201,6 +232,9 @@ END(fsu_fault)
* int fuswintr(void *)
*/
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 */
SET_FAULT_HANDLER(x6, x1) /* And set it */
ldr w0, [x0] /* Try loading the data */
@@ -212,6 +246,9 @@ END(fuswintr)
* int suswintr(void *base, int word)
*/
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 */
SET_FAULT_HANDLER(x6, x2) /* And set it */
str w1, [x0] /* Try storing the data */
OpenPOWER on IntegriCloud