* Copyright 1997 Linus Torvalds
* Copyright 2002 Andi Kleen <ak@suse.de>
*/
+#include <linux/module.h>
#include <asm/uaccess.h>
/*
#define __do_strncpy_from_user(dst,src,count,res) \
do { \
long __d0, __d1, __d2; \
+ might_sleep(); \
__asm__ __volatile__( \
" testq %1,%1\n" \
" jz 2f\n" \
} while (0)
long
-__strncpy_from_user(char *dst, const char *src, long count)
+__strncpy_from_user(char *dst, const char __user *src, long count)
{
long res;
__do_strncpy_from_user(dst, src, count, res);
return res;
}
+EXPORT_SYMBOL(__strncpy_from_user);
long
-strncpy_from_user(char *dst, const char *src, long count)
+strncpy_from_user(char *dst, const char __user *src, long count)
{
long res = -EFAULT;
if (access_ok(VERIFY_READ, src, 1))
- __do_strncpy_from_user(dst, src, count, res);
+ return __strncpy_from_user(dst, src, count);
return res;
}
+EXPORT_SYMBOL(strncpy_from_user);
/*
* Zero Userspace
*/
-unsigned long __clear_user(void *addr, unsigned long size)
+unsigned long __clear_user(void __user *addr, unsigned long size)
{
long __d0;
+ might_sleep();
/* no memory constraint because it doesn't change any memory gcc knows
about */
asm volatile(
[zero] "r" (0UL), [eight] "r" (8UL));
return size;
}
+EXPORT_SYMBOL(__clear_user);
-
-unsigned long clear_user(void *to, unsigned long n)
+unsigned long clear_user(void __user *to, unsigned long n)
{
if (access_ok(VERIFY_WRITE, to, n))
return __clear_user(to, n);
return n;
}
+EXPORT_SYMBOL(clear_user);
/*
* Return the size of a string (including the ending 0)
* Return 0 on exception, a value greater than N if too long
*/
-long strnlen_user(const char *s, long n)
+long __strnlen_user(const char __user *s, long n)
{
long res = 0;
char c;
- if (!access_ok(VERIFY_READ, s, n))
- return 0;
-
while (1) {
if (res>n)
return n+1;
s++;
}
}
+EXPORT_SYMBOL(__strnlen_user);
+
+long strnlen_user(const char __user *s, long n)
+{
+ if (!access_ok(VERIFY_READ, s, n))
+ return 0;
+ return __strnlen_user(s, n);
+}
+EXPORT_SYMBOL(strnlen_user);
-long strlen_user(const char *s)
+long strlen_user(const char __user *s)
{
long res = 0;
char c;
s++;
}
}
+EXPORT_SYMBOL(strlen_user);
-unsigned long copy_in_user(void *to, const void *from, unsigned len)
+unsigned long copy_in_user(void __user *to, const void __user *from, unsigned len)
{
if (access_ok(VERIFY_WRITE, to, len) && access_ok(VERIFY_READ, from, len)) {
- return copy_user_generic(to, from, len);
+ return copy_user_generic((__force void *)to, (__force void *)from, len);
}
return len;
}
+EXPORT_SYMBOL(copy_in_user);
+