X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=include%2Fasm-sh%2Fuaccess_32.h;h=1e41fda74bd38a0ae459ba884b598b9ed78425ce;hb=13c48c490208d9e70d8d66d56f96c5054db69af7;hp=59a9f20c2dc7696c893f6025375563ad3c7d95b2;hpb=0fb19dcb64ec4bd9934eee26ce66417fe028ffd8;p=linux-2.6 diff --git a/include/asm-sh/uaccess_32.h b/include/asm-sh/uaccess_32.h index 59a9f20c2d..1e41fda74b 100644 --- a/include/asm-sh/uaccess_32.h +++ b/include/asm-sh/uaccess_32.h @@ -10,8 +10,8 @@ * Copyright (C) 1996, 1997, 1998 by Ralf Baechle * and i386 version. */ -#ifndef __ASM_SH_UACCESS_H -#define __ASM_SH_UACCESS_H +#ifndef __ASM_SH_UACCESS_32_H +#define __ASM_SH_UACCESS_32_H #include #include @@ -55,13 +55,10 @@ static inline void set_fs(mm_segment_t s) * If we don't have an MMU (or if its disabled) the only thing we really have * to look out for is if the address resides somewhere outside of what * available RAM we have. - * - * TODO: This check could probably also stand to be restricted somewhat more.. - * though it still does the Right Thing(tm) for the time being. */ static inline int __access_ok(unsigned long addr, unsigned long size) { - return ((addr >= memory_start) && ((addr + size) < memory_end)); + return 1; } #else /* CONFIG_MMU */ #define __addr_ok(addr) \ @@ -95,11 +92,9 @@ static inline int __access_ok(unsigned long addr, unsigned long size) } #endif /* CONFIG_MMU */ -static inline int access_ok(int type, const void __user *p, unsigned long size) -{ - unsigned long addr = (unsigned long)p; - return __access_ok(addr, size); -} +#define access_ok(type, addr, size) \ + (__chk_user_ptr(addr), \ + __access_ok((unsigned long __force)(addr), (size))) /* * Uh, these should become the main single-value transfer routines ... @@ -113,18 +108,16 @@ static inline int access_ok(int type, const void __user *p, unsigned long size) * (a) re-use the arguments for side effects (sizeof is ok) * (b) require any knowledge of processes at this stage */ -#define put_user(x,ptr) __put_user_check((x),(ptr),sizeof(*(ptr))) -#define get_user(x,ptr) __get_user_check((x),(ptr),sizeof(*(ptr))) +#define put_user(x,ptr) __put_user_check((x), (ptr), sizeof(*(ptr))) +#define get_user(x,ptr) __get_user_check((x), (ptr), sizeof(*(ptr))) /* * The "__xxx" versions do not do address space checking, useful when * doing multiple accesses to the same area (the user has to do the * checks by hand with "access_ok()") */ -#define __put_user(x,ptr) \ - __put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr))) -#define __get_user(x,ptr) \ - __get_user_nocheck((x),(ptr),sizeof(*(ptr))) +#define __put_user(x,ptr) __put_user_nocheck((x), (ptr), sizeof(*(ptr))) +#define __get_user(x,ptr) __get_user_nocheck((x), (ptr), sizeof(*(ptr))) struct __large_struct { unsigned long buf[100]; }; #define __m(x) (*(struct __large_struct __user *)(x)) @@ -132,7 +125,6 @@ struct __large_struct { unsigned long buf[100]; }; #define __get_user_size(x,ptr,size,retval) \ do { \ retval = 0; \ - __chk_user_ptr(ptr); \ switch (size) { \ case 1: \ __get_user_asm(x, ptr, retval, "b"); \ @@ -151,24 +143,22 @@ do { \ #define __get_user_nocheck(x,ptr,size) \ ({ \ - long __gu_err, __gu_val; \ - __typeof__(*(ptr)) *__pu_addr = (ptr); \ - __get_user_size(__gu_val, (__pu_addr), (size), __gu_err); \ + long __gu_err; \ + unsigned long __gu_val; \ + const __typeof__(*(ptr)) __user *__gu_addr = (ptr); \ + __chk_user_ptr(ptr); \ + __get_user_size(__gu_val, __gu_addr, (size), __gu_err); \ (x) = (__typeof__(*(ptr)))__gu_val; \ __gu_err; \ }) #define __get_user_check(x,ptr,size) \ ({ \ - long __gu_err, __gu_val; \ - __typeof__(*(ptr)) *__pu_addr = (ptr); \ - __chk_user_ptr(__pu_addr); \ - if (likely(__addr_ok((unsigned long)(__pu_addr)))) { \ - __get_user_size(__gu_val, (__pu_addr), (size), __gu_err);\ - } else { \ - __gu_err = -EFAULT; \ - __gu_val = 0; \ - } \ + long __gu_err = -EFAULT; \ + unsigned long __gu_val = 0; \ + const __typeof__(*(ptr)) *__gu_addr = (ptr); \ + if (likely(access_ok(VERIFY_READ, __gu_addr, (size)))) \ + __get_user_size(__gu_val, __gu_addr, (size), __gu_err); \ (x) = (__typeof__(*(ptr)))__gu_val; \ __gu_err; \ }) @@ -199,7 +189,6 @@ extern void __get_user_unknown(void); #define __put_user_size(x,ptr,size,retval) \ do { \ retval = 0; \ - __chk_user_ptr(ptr); \ switch (size) { \ case 1: \ __put_user_asm(x, ptr, retval, "b"); \ @@ -218,22 +207,22 @@ do { \ } \ } while (0) -#define __put_user_nocheck(x,ptr,size) \ -({ \ - long __pu_err; \ - __put_user_size((x),(ptr),(size),__pu_err); \ - __pu_err; \ +#define __put_user_nocheck(x,ptr,size) \ +({ \ + long __pu_err; \ + __typeof__(*(ptr)) __user *__pu_addr = (ptr); \ + __chk_user_ptr(ptr); \ + __put_user_size((x), __pu_addr, (size), __pu_err); \ + __pu_err; \ }) #define __put_user_check(x,ptr,size) \ ({ \ - long __pu_err; \ + long __pu_err = -EFAULT; \ __typeof__(*(ptr)) __user *__pu_addr = (ptr); \ - \ - if (likely(__addr_ok((unsigned long)__pu_addr))) \ - __put_user_size((x),__pu_addr,(size),__pu_err); \ - else \ - __pu_err = -EFAULT; \ + if (likely(access_ok(VERIFY_WRITE, __pu_addr, size))) \ + __put_user_size((x), __pu_addr, (size), \ + __pu_err); \ __pu_err; \ }) @@ -310,24 +299,6 @@ extern void __put_user_unknown(void); /* Return the number of bytes NOT copied */ __kernel_size_t __copy_user(void *to, const void *from, __kernel_size_t n); -#define copy_to_user(to,from,n) ({ \ -void *__copy_to = (void *) (to); \ -__kernel_size_t __copy_size = (__kernel_size_t) (n); \ -__kernel_size_t __copy_res; \ -if(__copy_size && __access_ok((unsigned long)__copy_to, __copy_size)) { \ -__copy_res = __copy_user(__copy_to, (void *) (from), __copy_size); \ -} else __copy_res = __copy_size; \ -__copy_res; }) - -#define copy_from_user(to,from,n) ({ \ -void *__copy_to = (void *) (to); \ -void *__copy_from = (void *) (from); \ -__kernel_size_t __copy_size = (__kernel_size_t) (n); \ -__kernel_size_t __copy_res; \ -if(__copy_size && __access_ok((unsigned long)__copy_from, __copy_size)) { \ -__copy_res = __copy_user(__copy_to, __copy_from, __copy_size); \ -} else __copy_res = __copy_size; \ -__copy_res; }) static __always_inline unsigned long __copy_from_user(void *to, const void __user *from, unsigned long n) @@ -515,4 +486,4 @@ struct exception_table_entry extern int fixup_exception(struct pt_regs *regs); -#endif /* __ASM_SH_UACCESS_H */ +#endif /* __ASM_SH_UACCESS_32_H */