From a8372b5ca618d4ea41b3c7ac3cef8dd6efa68bc6 Mon Sep 17 00:00:00 2001 From: Robin Getz Date: Thu, 4 Jun 2009 00:32:59 +0000 Subject: Blackfin: add missing access_ok() checks to user functions The core string/clear user functions weren't checking the user pointers which caused kernel crashes with some bad programs and tests (like LTP). Signed-off-by: Robin Getz Signed-off-by: Mike Frysinger --- arch/blackfin/include/asm/uaccess.h | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) (limited to 'arch/blackfin/include/asm/uaccess.h') diff --git a/arch/blackfin/include/asm/uaccess.h b/arch/blackfin/include/asm/uaccess.h index 3248033531e..97729be9894 100644 --- a/arch/blackfin/include/asm/uaccess.h +++ b/arch/blackfin/include/asm/uaccess.h @@ -233,16 +233,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 +264,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; } -- cgit From 8d0d8f2a3a57479b695a59ed2f67236f1488b90d Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Thu, 4 Jun 2009 19:11:31 +0000 Subject: Blackfin: punt duplicated search_exception_table() prototype The common code already has a prototype for this function and we don't use it anywhere in the Blackfin code, so punt it from the Blackfin headers. Signed-off-by: Mike Frysinger --- arch/blackfin/include/asm/uaccess.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'arch/blackfin/include/asm/uaccess.h') diff --git a/arch/blackfin/include/asm/uaccess.h b/arch/blackfin/include/asm/uaccess.h index 97729be9894..01f42b02e26 100644 --- a/arch/blackfin/include/asm/uaccess.h +++ b/arch/blackfin/include/asm/uaccess.h @@ -83,9 +83,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. -- cgit From a43b739f257fd2569e11c6c93fbb86df382848e9 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Thu, 4 Jun 2009 19:24:31 +0000 Subject: Blackfin: push access_ok() L1 attribute down There is no need for the L1 attribute to be on the prototype of the access_ok() function as all consumers of the function do not care where it lives -- they'll always use pcrel calls to get to it. This prevents pointless recompiles of most of the system when this config option changes. Signed-off-by: Mike Frysinger --- arch/blackfin/include/asm/uaccess.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'arch/blackfin/include/asm/uaccess.h') diff --git a/arch/blackfin/include/asm/uaccess.h b/arch/blackfin/include/asm/uaccess.h index 01f42b02e26..8894e9ffbb5 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 -- cgit