riscv: fix VM_MAXUSER_ADDRESS checks in asm routines
There are two issues with the checks against VM_MAXUSER_ADDRESS. First, the comparison should consider the values as unsigned, otherwise addresses with the high bit set will fail to branch. Second, the value of VM_MAXUSER_ADDRESS is, by convention, one larger than the maximum mappable user address and invalid itself. Thus, use the bgeu instruction for these comparisons. Add a regression test case for copyin(9). PR: 257193 Reported by: Robert Morris <rtm@lcs.mit.edu> Reviewed by: markj Differential Revision: https://reviews.freebsd.org/D31209
This commit is contained in:
parent
4a9f2f8b07
commit
8babb5582e
@ -118,7 +118,7 @@ ENTRY(copyout)
|
||||
beqz a2, copyout_end /* If len == 0 then skip loop */
|
||||
add a3, a1, a2
|
||||
li a4, VM_MAXUSER_ADDRESS
|
||||
bgt a3, a4, copyio_fault_nopcb
|
||||
bgeu a3, a4, copyio_fault_nopcb
|
||||
|
||||
copycommon
|
||||
|
||||
@ -136,7 +136,7 @@ ENTRY(copyin)
|
||||
beqz a2, copyin_end /* If len == 0 then skip loop */
|
||||
add a3, a0, a2
|
||||
li a4, VM_MAXUSER_ADDRESS
|
||||
bgt a3, a4, copyio_fault_nopcb
|
||||
bgeu a3, a4, copyio_fault_nopcb
|
||||
|
||||
copycommon
|
||||
|
||||
@ -159,7 +159,7 @@ ENTRY(copyinstr)
|
||||
ENTER_USER_ACCESS(a7)
|
||||
|
||||
li a7, VM_MAXUSER_ADDRESS
|
||||
1: bgt a0, a7, copyio_fault
|
||||
1: bgeu a0, a7, copyio_fault
|
||||
lb a4, 0(a0) /* Load from uaddr */
|
||||
addi a0, a0, 1
|
||||
sb a4, 0(a1) /* Store in kaddr */
|
||||
|
@ -56,7 +56,7 @@ END(fsu_fault)
|
||||
*/
|
||||
ENTRY(casueword32)
|
||||
li a4, (VM_MAXUSER_ADDRESS-3)
|
||||
bgt a0, a4, fsu_fault_nopcb
|
||||
bgeu 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)
|
||||
@ -77,7 +77,7 @@ END(casueword32)
|
||||
*/
|
||||
ENTRY(casueword)
|
||||
li a4, (VM_MAXUSER_ADDRESS-7)
|
||||
bgt a0, a4, fsu_fault_nopcb
|
||||
bgeu 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)
|
||||
@ -98,7 +98,7 @@ END(casueword)
|
||||
*/
|
||||
ENTRY(fubyte)
|
||||
li a1, VM_MAXUSER_ADDRESS
|
||||
bgt a0, a1, fsu_fault_nopcb
|
||||
bgeu 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)
|
||||
@ -113,7 +113,7 @@ END(fubyte)
|
||||
*/
|
||||
ENTRY(fuword16)
|
||||
li a1, (VM_MAXUSER_ADDRESS-1)
|
||||
bgt a0, a1, fsu_fault_nopcb
|
||||
bgeu 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)
|
||||
@ -128,7 +128,7 @@ END(fuword16)
|
||||
*/
|
||||
ENTRY(fueword32)
|
||||
li a2, (VM_MAXUSER_ADDRESS-3)
|
||||
bgt a0, a2, fsu_fault_nopcb
|
||||
bgeu 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)
|
||||
@ -147,7 +147,7 @@ END(fueword32)
|
||||
ENTRY(fueword)
|
||||
EENTRY(fueword64)
|
||||
li a2, (VM_MAXUSER_ADDRESS-7)
|
||||
bgt a0, a2, fsu_fault_nopcb
|
||||
bgeu 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)
|
||||
@ -165,7 +165,7 @@ END(fueword)
|
||||
*/
|
||||
ENTRY(subyte)
|
||||
li a2, VM_MAXUSER_ADDRESS
|
||||
bgt a0, a2, fsu_fault_nopcb
|
||||
bgeu 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)
|
||||
@ -181,7 +181,7 @@ END(subyte)
|
||||
*/
|
||||
ENTRY(suword16)
|
||||
li a2, (VM_MAXUSER_ADDRESS-1)
|
||||
bgt a0, a2, fsu_fault_nopcb
|
||||
bgeu 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)
|
||||
@ -197,7 +197,7 @@ END(suword16)
|
||||
*/
|
||||
ENTRY(suword32)
|
||||
li a2, (VM_MAXUSER_ADDRESS-3)
|
||||
bgt a0, a2, fsu_fault_nopcb
|
||||
bgeu 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)
|
||||
@ -214,7 +214,7 @@ END(suword32)
|
||||
ENTRY(suword)
|
||||
EENTRY(suword64)
|
||||
li a2, (VM_MAXUSER_ADDRESS-7)
|
||||
bgt a0, a2, fsu_fault_nopcb
|
||||
bgeu 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)
|
||||
|
@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/exec.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -54,6 +55,21 @@ copyin_checker(uintptr_t uaddr, size_t len)
|
||||
return (ret == -1 ? errno : 0);
|
||||
}
|
||||
|
||||
#if __SIZEOF_POINTER__ == 8
|
||||
/*
|
||||
* A slightly more direct path to calling copyin(), but without the ability
|
||||
* to specify a length.
|
||||
*/
|
||||
static int
|
||||
copyin_checker2(uintptr_t uaddr)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = fcntl(scratch_file, F_GETLK, (const void *)uaddr);
|
||||
return (ret == -1 ? errno : 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __amd64__
|
||||
static uintptr_t
|
||||
get_maxuser_address(void)
|
||||
@ -83,6 +99,10 @@ get_maxuser_address(void)
|
||||
#endif
|
||||
|
||||
#define FMAX ULONG_MAX
|
||||
#if __SIZEOF_POINTER__ == 8
|
||||
/* PR 257193 */
|
||||
#define ADDR_SIGNED 0x800000c000000000
|
||||
#endif
|
||||
|
||||
ATF_TC_WITHOUT_HEAD(kern_copyin);
|
||||
ATF_TC_BODY(kern_copyin, tc)
|
||||
@ -122,6 +142,10 @@ ATF_TC_BODY(kern_copyin, tc)
|
||||
ATF_CHECK(copyin_checker(FMAX - 10, 9) == EFAULT);
|
||||
ATF_CHECK(copyin_checker(FMAX - 10, 10) == EFAULT);
|
||||
ATF_CHECK(copyin_checker(FMAX - 10, 11) == EFAULT);
|
||||
#if __SIZEOF_POINTER__ == 8
|
||||
ATF_CHECK(copyin_checker(ADDR_SIGNED, 1) == EFAULT);
|
||||
ATF_CHECK(copyin_checker2(ADDR_SIGNED) == EFAULT);
|
||||
#endif
|
||||
}
|
||||
|
||||
ATF_TP_ADD_TCS(tp)
|
||||
|
Loading…
Reference in New Issue
Block a user