summaryrefslogtreecommitdiffstats
path: root/arch/blackfin/include/asm/uaccess.h
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-06-17 08:59:01 +0200
committerIngo Molnar <mingo@elte.hu>2009-06-17 08:59:10 +0200
commitcc4949e1fdade5d063e9f8783cf0e2cc92041ce5 (patch)
tree4023bd641bfe464efbde518fb504d6865c9df014 /arch/blackfin/include/asm/uaccess.h
parentx86, boot: use .code16gcc instead of .code16 (diff)
parentMerge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/gi... (diff)
downloadlinux-cc4949e1fdade5d063e9f8783cf0e2cc92041ce5.tar.xz
linux-cc4949e1fdade5d063e9f8783cf0e2cc92041ce5.zip
Merge branch 'linus' into x86/urgent
Merge reason: pull in latest to fix a bug in it. Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/blackfin/include/asm/uaccess.h')
-rw-r--r--arch/blackfin/include/asm/uaccess.h32
1 files changed, 20 insertions, 12 deletions
diff --git a/arch/blackfin/include/asm/uaccess.h b/arch/blackfin/include/asm/uaccess.h
index 3248033531e6..8894e9ffbb57 100644
--- a/arch/blackfin/include/asm/uaccess.h
+++ b/arch/blackfin/include/asm/uaccess.h
@@ -59,12 +59,8 @@ static inline int is_in_rom(unsigned long addr)
#ifndef CONFIG_ACCESS_CHECK
static inline int _access_ok(unsigned long addr, unsigned long size) { return 1; }
#else
-#ifdef CONFIG_ACCESS_OK_L1
-extern int _access_ok(unsigned long addr, unsigned long size)__attribute__((l1_text));
-#else
extern int _access_ok(unsigned long addr, unsigned long size);
#endif
-#endif
/*
* The exception table consists of pairs of addresses: the first is the
@@ -83,9 +79,6 @@ struct exception_table_entry {
unsigned long insn, fixup;
};
-/* Returns 0 if exception not found and fixup otherwise. */
-extern unsigned long search_exception_table(unsigned long);
-
/*
* These are the main single-value transfer routines. They automatically
* use the right size if we just have the right pointer type.
@@ -233,16 +226,29 @@ strncpy_from_user(char *dst, const char *src, long count)
}
/*
- * Return the size of a string (including the ending 0)
+ * Get the size of a string in user space.
+ * src: The string to measure
+ * n: The maximum valid length
*
- * Return 0 on exception, a value greater than N if too long
+ * Get the size of a NUL-terminated string in user space.
+ *
+ * Returns the size of the string INCLUDING the terminating NUL.
+ * On exception, returns 0.
+ * If the string is too long, returns a value greater than n.
*/
-static inline long strnlen_user(const char *src, long n)
+static inline long __must_check strnlen_user(const char *src, long n)
{
- return (strlen(src) + 1);
+ if (!access_ok(VERIFY_READ, src, 1))
+ return 0;
+ return strnlen(src, n) + 1;
}
-#define strlen_user(str) strnlen_user(str, 32767)
+static inline long __must_check strlen_user(const char *src)
+{
+ if (!access_ok(VERIFY_READ, src, 1))
+ return 0;
+ return strlen(src) + 1;
+}
/*
* Zero Userspace
@@ -251,6 +257,8 @@ static inline long strnlen_user(const char *src, long n)
static inline unsigned long __must_check
__clear_user(void *to, unsigned long n)
{
+ if (!access_ok(VERIFY_WRITE, to, n))
+ return n;
memset(to, 0, n);
return 0;
}