linux-user: Use cpu_untagged_addr in access_ok; split out *_untagged

Provide both tagged and untagged versions of access_ok.
In a few places use thread_cpu, as the user is several
callees removed from do_syscall1.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20210212184902.1251044-17-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Richard Henderson 2021-02-12 10:48:47 -08:00 committed by Peter Maydell
parent 46b12f461c
commit c7169b022b
6 changed files with 24 additions and 13 deletions

View File

@ -3510,7 +3510,7 @@ static int vma_get_mapping_count(const struct mm_struct *mm)
static abi_ulong vma_dump_size(const struct vm_area_struct *vma) static abi_ulong vma_dump_size(const struct vm_area_struct *vma)
{ {
/* if we cannot even read the first page, skip it */ /* if we cannot even read the first page, skip it */
if (!access_ok(VERIFY_READ, vma->vma_start, TARGET_PAGE_SIZE)) if (!access_ok_untagged(VERIFY_READ, vma->vma_start, TARGET_PAGE_SIZE))
return (0); return (0);
/* /*

View File

@ -35,7 +35,7 @@ static abi_ulong hppa_lws(CPUHPPAState *env)
return -TARGET_ENOSYS; return -TARGET_ENOSYS;
case 0: /* elf32 atomic 32bit cmpxchg */ case 0: /* elf32 atomic 32bit cmpxchg */
if ((addr & 3) || !access_ok(VERIFY_WRITE, addr, 4)) { if ((addr & 3) || !access_ok(cs, VERIFY_WRITE, addr, 4)) {
return -TARGET_EFAULT; return -TARGET_EFAULT;
} }
old = tswap32(old); old = tswap32(old);
@ -50,9 +50,9 @@ static abi_ulong hppa_lws(CPUHPPAState *env)
return -TARGET_ENOSYS; return -TARGET_ENOSYS;
} }
if (((addr | old | new) & ((1 << size) - 1)) if (((addr | old | new) & ((1 << size) - 1))
|| !access_ok(VERIFY_WRITE, addr, 1 << size) || !access_ok(cs, VERIFY_WRITE, addr, 1 << size)
|| !access_ok(VERIFY_READ, old, 1 << size) || !access_ok(cs, VERIFY_READ, old, 1 << size)
|| !access_ok(VERIFY_READ, new, 1 << size)) { || !access_ok(cs, VERIFY_READ, new, 1 << size)) {
return -TARGET_EFAULT; return -TARGET_EFAULT;
} }
/* Note that below we use host-endian loads so that the cmpxchg /* Note that below we use host-endian loads so that the cmpxchg

View File

@ -99,7 +99,7 @@ static bool write_ok_or_segv(CPUX86State *env, abi_ptr addr, size_t len)
* For all the vsyscalls, NULL means "don't write anything" not * For all the vsyscalls, NULL means "don't write anything" not
* "write it at address 0". * "write it at address 0".
*/ */
if (addr == 0 || access_ok(VERIFY_WRITE, addr, len)) { if (addr == 0 || access_ok(env_cpu(env), VERIFY_WRITE, addr, len)) {
return true; return true;
} }

View File

@ -513,9 +513,10 @@ restore_sigcontext(CPUX86State *env, struct target_sigcontext *sc)
fpstate_addr = tswapl(sc->fpstate); fpstate_addr = tswapl(sc->fpstate);
if (fpstate_addr != 0) { if (fpstate_addr != 0) {
if (!access_ok(VERIFY_READ, fpstate_addr, if (!access_ok(env_cpu(env), VERIFY_READ, fpstate_addr,
sizeof(struct target_fpstate))) sizeof(struct target_fpstate))) {
goto badframe; goto badframe;
}
#ifndef TARGET_X86_64 #ifndef TARGET_X86_64
cpu_x86_frstor(env, fpstate_addr, 1); cpu_x86_frstor(env, fpstate_addr, 1);
#else #else

View File

@ -491,7 +491,7 @@ extern unsigned long guest_stack_size;
#define VERIFY_READ PAGE_READ #define VERIFY_READ PAGE_READ
#define VERIFY_WRITE (PAGE_READ | PAGE_WRITE) #define VERIFY_WRITE (PAGE_READ | PAGE_WRITE)
static inline bool access_ok(int type, abi_ulong addr, abi_ulong size) static inline bool access_ok_untagged(int type, abi_ulong addr, abi_ulong size)
{ {
if (size == 0 if (size == 0
? !guest_addr_valid_untagged(addr) ? !guest_addr_valid_untagged(addr)
@ -501,6 +501,12 @@ static inline bool access_ok(int type, abi_ulong addr, abi_ulong size)
return page_check_range((target_ulong)addr, size, type) == 0; return page_check_range((target_ulong)addr, size, type) == 0;
} }
static inline bool access_ok(CPUState *cpu, int type,
abi_ulong addr, abi_ulong size)
{
return access_ok_untagged(type, cpu_untagged_addr(cpu, addr), size);
}
/* NOTE __get_user and __put_user use host pointers and don't check access. /* NOTE __get_user and __put_user use host pointers and don't check access.
These are usually used to access struct data members once the struct has These are usually used to access struct data members once the struct has
been locked - usually with lock_user_struct. */ been locked - usually with lock_user_struct. */
@ -636,8 +642,9 @@ abi_long copy_to_user(abi_ulong gaddr, void *hptr, size_t len);
host area will have the same contents as the guest. */ host area will have the same contents as the guest. */
static inline void *lock_user(int type, abi_ulong guest_addr, long len, int copy) static inline void *lock_user(int type, abi_ulong guest_addr, long len, int copy)
{ {
if (!access_ok(type, guest_addr, len)) if (!access_ok_untagged(type, guest_addr, len)) {
return NULL; return NULL;
}
#ifdef DEBUG_REMAP #ifdef DEBUG_REMAP
{ {
void *addr; void *addr;

View File

@ -3526,8 +3526,9 @@ static abi_long do_accept4(int fd, abi_ulong target_addr,
return -TARGET_EINVAL; return -TARGET_EINVAL;
} }
if (!access_ok(VERIFY_WRITE, target_addr, addrlen)) if (!access_ok(thread_cpu, VERIFY_WRITE, target_addr, addrlen)) {
return -TARGET_EFAULT; return -TARGET_EFAULT;
}
addr = alloca(addrlen); addr = alloca(addrlen);
@ -3557,8 +3558,9 @@ static abi_long do_getpeername(int fd, abi_ulong target_addr,
return -TARGET_EINVAL; return -TARGET_EINVAL;
} }
if (!access_ok(VERIFY_WRITE, target_addr, addrlen)) if (!access_ok(thread_cpu, VERIFY_WRITE, target_addr, addrlen)) {
return -TARGET_EFAULT; return -TARGET_EFAULT;
}
addr = alloca(addrlen); addr = alloca(addrlen);
@ -3588,8 +3590,9 @@ static abi_long do_getsockname(int fd, abi_ulong target_addr,
return -TARGET_EINVAL; return -TARGET_EINVAL;
} }
if (!access_ok(VERIFY_WRITE, target_addr, addrlen)) if (!access_ok(thread_cpu, VERIFY_WRITE, target_addr, addrlen)) {
return -TARGET_EFAULT; return -TARGET_EFAULT;
}
addr = alloca(addrlen); addr = alloca(addrlen);