|
@@ -911,3 +911,87 @@ extern size_t __copy_user_inatomic(void *__to, const void *__from, size_t __n);
|
|
|
const void __user *__cu_from; \
|
|
|
long __cu_len; \
|
|
|
\
|
|
|
+ __cu_to = (to); \
|
|
|
+ __cu_from = (from); \
|
|
|
+ __cu_len = (n); \
|
|
|
+ if (likely(access_ok(VERIFY_READ, __cu_from, __cu_len) && \
|
|
|
+ access_ok(VERIFY_WRITE, __cu_to, __cu_len))) { \
|
|
|
+ might_fault(); \
|
|
|
+ __cu_len = __invoke_copy_from_user(__cu_to, __cu_from, \
|
|
|
+ __cu_len); \
|
|
|
+ } \
|
|
|
+ __cu_len; \
|
|
|
+})
|
|
|
+
|
|
|
+/*
|
|
|
+ * __clear_user: - Zero a block of memory in user space, with less checking.
|
|
|
+ * @to: Destination address, in user space.
|
|
|
+ * @n: Number of bytes to zero.
|
|
|
+ *
|
|
|
+ * Zero a block of memory in user space. Caller must check
|
|
|
+ * the specified block with access_ok() before calling this function.
|
|
|
+ *
|
|
|
+ * Returns number of bytes that could not be cleared.
|
|
|
+ * On success, this will be zero.
|
|
|
+ */
|
|
|
+static inline __kernel_size_t
|
|
|
+__clear_user(void __user *addr, __kernel_size_t size)
|
|
|
+{
|
|
|
+ __kernel_size_t res;
|
|
|
+
|
|
|
+ might_fault();
|
|
|
+ __asm__ __volatile__(
|
|
|
+ "move\t$4, %1\n\t"
|
|
|
+ "move\t$5, $0\n\t"
|
|
|
+ "move\t$6, %2\n\t"
|
|
|
+ __MODULE_JAL(__bzero)
|
|
|
+ "move\t%0, $6"
|
|
|
+ : "=r" (res)
|
|
|
+ : "r" (addr), "r" (size)
|
|
|
+ : "$4", "$5", "$6", __UA_t0, __UA_t1, "$31");
|
|
|
+
|
|
|
+ return res;
|
|
|
+}
|
|
|
+
|
|
|
+#define clear_user(addr,n) \
|
|
|
+({ \
|
|
|
+ void __user * __cl_addr = (addr); \
|
|
|
+ unsigned long __cl_size = (n); \
|
|
|
+ if (__cl_size && access_ok(VERIFY_WRITE, \
|
|
|
+ __cl_addr, __cl_size)) \
|
|
|
+ __cl_size = __clear_user(__cl_addr, __cl_size); \
|
|
|
+ __cl_size; \
|
|
|
+})
|
|
|
+
|
|
|
+/*
|
|
|
+ * __strncpy_from_user: - Copy a NUL terminated string from userspace, with less checking.
|
|
|
+ * @dst: Destination address, in kernel space. This buffer must be at
|
|
|
+ * least @count bytes long.
|
|
|
+ * @src: Source address, in user space.
|
|
|
+ * @count: Maximum number of bytes to copy, including the trailing NUL.
|
|
|
+ *
|
|
|
+ * Copies a NUL-terminated string from userspace to kernel space.
|
|
|
+ * Caller must check the specified block with access_ok() before calling
|
|
|
+ * this function.
|
|
|
+ *
|
|
|
+ * On success, returns the length of the string (not including the trailing
|
|
|
+ * NUL).
|
|
|
+ *
|
|
|
+ * If access to userspace fails, returns -EFAULT (some data may have been
|
|
|
+ * copied).
|
|
|
+ *
|
|
|
+ * If @count is smaller than the length of the string, copies @count bytes
|
|
|
+ * and returns @count.
|
|
|
+ */
|
|
|
+static inline long
|
|
|
+__strncpy_from_user(char *__to, const char __user *__from, long __len)
|
|
|
+{
|
|
|
+ long res;
|
|
|
+
|
|
|
+ might_fault();
|
|
|
+ __asm__ __volatile__(
|
|
|
+ "move\t$4, %1\n\t"
|
|
|
+ "move\t$5, %2\n\t"
|
|
|
+ "move\t$6, %3\n\t"
|
|
|
+ __MODULE_JAL(__strncpy_from_user_nocheck_asm)
|
|
|
+ "move\t%0, $2"
|