|
@@ -28,24 +28,32 @@
|
|
|
|
|
|
#define segment_eq(a, b) ((a).seg == (b).seg)
|
|
|
|
|
|
-#define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))
|
|
|
-/*
|
|
|
- * Explicitly allow NULL pointers here. Parts of the kernel such
|
|
|
- * as readv/writev use access_ok to validate pointers, but want
|
|
|
- * to allow NULL pointers for various reasons. NULL pointers are
|
|
|
- * safe to allow through because the first page is not mappable on
|
|
|
- * Meta.
|
|
|
- *
|
|
|
- * We also wish to avoid letting user code access the system area
|
|
|
- * and the kernel half of the address space.
|
|
|
- */
|
|
|
-#define __user_bad(addr, size) (((addr) > 0 && (addr) < META_MEMORY_BASE) || \
|
|
|
- ((addr) > PAGE_OFFSET && \
|
|
|
- (addr) < LINCORE_BASE))
|
|
|
-
|
|
|
static inline int __access_ok(unsigned long addr, unsigned long size)
|
|
|
{
|
|
|
- return __kernel_ok || !__user_bad(addr, size);
|
|
|
+ /*
|
|
|
+ * Allow access to the user mapped memory area, but not the system area
|
|
|
+ * before it. The check extends to the top of the address space when
|
|
|
+ * kernel access is allowed (there's no real reason to user copy to the
|
|
|
+ * system area in any case).
|
|
|
+ */
|
|
|
+ if (likely(addr >= META_MEMORY_BASE && addr < get_fs().seg &&
|
|
|
+ size <= get_fs().seg - addr))
|
|
|
+ return true;
|
|
|
+ /*
|
|
|
+ * Explicitly allow NULL pointers here. Parts of the kernel such
|
|
|
+ * as readv/writev use access_ok to validate pointers, but want
|
|
|
+ * to allow NULL pointers for various reasons. NULL pointers are
|
|
|
+ * safe to allow through because the first page is not mappable on
|
|
|
+ * Meta.
|
|
|
+ */
|
|
|
+ if (!addr)
|
|
|
+ return true;
|
|
|
+ /* Allow access to core code memory area... */
|
|
|
+ if (addr >= LINCORE_CODE_BASE && addr <= LINCORE_CODE_LIMIT &&
|
|
|
+ size <= LINCORE_CODE_LIMIT + 1 - addr)
|
|
|
+ return true;
|
|
|
+ /* ... but no other areas. */
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
#define access_ok(type, addr, size) __access_ok((unsigned long)(addr), \
|