summary refs log tree commit diff stats
path: root/linux-user/qemu.h
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2021-02-12 10:48:37 -0800
committerPeter Maydell <peter.maydell@linaro.org>2021-02-16 11:04:53 +0000
commit4feac83a9ca12af2eaa1354867b6cdac0e69a17b (patch)
tree907f16accfba7b072f7436532202afb42fd96834 /linux-user/qemu.h
parent19d3c905fef84ace72010d1cab2d09d69ebfcdcb (diff)
downloadfocaccia-qemu-4feac83a9ca12af2eaa1354867b6cdac0e69a17b.tar.gz
focaccia-qemu-4feac83a9ca12af2eaa1354867b6cdac0e69a17b.zip
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.h17
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.