linux-user: Check for overflow in access_ok

Verify that addr + size - 1 does not wrap around.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20210212184902.1251044-7-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:37 -08:00 committed by Peter Maydell
parent 19d3c905fe
commit 4feac83a9c

View File

@ -491,12 +491,19 @@ extern unsigned long guest_stack_size;
#define VERIFY_READ 0
#define VERIFY_WRITE 1 /* implies read access */
static inline int access_ok(int type, abi_ulong addr, abi_ulong size)
static inline bool access_ok(int type, abi_ulong addr, abi_ulong size)
{
return guest_addr_valid(addr) &&
(size == 0 || guest_addr_valid(addr + size - 1)) &&
page_check_range((target_ulong)addr, size,
(type == VERIFY_READ) ? PAGE_READ : (PAGE_READ | PAGE_WRITE)) == 0;
if (!guest_addr_valid(addr)) {
return false;
}
if (size != 0 &&
(addr + size - 1 < addr ||
!guest_addr_valid(addr + size - 1))) {
return false;
}
return page_check_range((target_ulong)addr, size,
(type == VERIFY_READ) ? PAGE_READ :
(PAGE_READ | PAGE_WRITE)) == 0;
}
/* NOTE __get_user and __put_user use host pointers and don't check access.