@@ -19,6 +19,7 @@
#ifdef CONFIG_32BIT
#define __UA_LIMIT 0x80000000UL
+#define TASK_SIZE_MAX __UA_LIMIT
#define __UA_ADDR ".word"
#define __UA_LA "la"
@@ -33,6 +34,7 @@
extern u64 __ua_limit;
#define __UA_LIMIT __ua_limit
+#define TASK_SIZE_MAX XKSSEG
#define __UA_ADDR ".dword"
#define __UA_LA "dla"
@@ -42,22 +44,6 @@ extern u64 __ua_limit;
#endif /* CONFIG_64BIT */
-/*
- * Is a address valid? This does a straightforward calculation rather
- * than tests.
- *
- * Address valid if:
- * - "addr" doesn't have any high-bits set
- * - AND "size" doesn't have any high-bits set
- * - AND "addr+size" doesn't have any high-bits set
- * - OR we are in kernel mode.
- *
- * __ua_size() is a trick to avoid runtime checking of positive constant
- * sizes; for those we already know at compile time that the size is ok.
- */
-#define __ua_size(size) \
- ((__builtin_constant_p(size) && (signed long) (size) > 0) ? 0 : (size))
-
/*
* access_ok: - Checks if a user space pointer is valid
* @addr: User space pointer to start of block to check
@@ -79,9 +65,9 @@ extern u64 __ua_limit;
static inline int __access_ok(const void __user *p, unsigned long size)
{
unsigned long addr = (unsigned long)p;
- unsigned long end = addr + size - !!size;
+ unsigned long limit = TASK_SIZE_MAX;
- return (__UA_LIMIT & (addr | end | __ua_size(size))) == 0;
+ return (size <= limit) && (addr <= (limit - size));
}
#define access_ok(addr, size) \