diff options
author | Richard Henderson <richard.henderson@linaro.org> | 2021-02-12 10:48:37 -0800 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2021-02-16 11:04:53 +0000 |
commit | 4feac83a9ca12af2eaa1354867b6cdac0e69a17b (patch) | |
tree | 907f16accfba7b072f7436532202afb42fd96834 /linux-user/qemu.h | |
parent | 19d3c905fef84ace72010d1cab2d09d69ebfcdcb (diff) |
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>
Diffstat (limited to 'linux-user/qemu.h')
-rw-r--r-- | linux-user/qemu.h | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/linux-user/qemu.h b/linux-user/qemu.h index 17aa992165..441ba6a78b 100644 --- a/linux-user/qemu.h +++ b/linux-user/qemu.h @@ -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. |