Commit 5d146f2c authored by Linus Torvalds's avatar Linus Torvalds

sparse: use new generic __chk_user_ptr() macro in x86/ppc64/sparc*

Older versions of gcc were unhappy with our previous trick, and
just separating out the __CHECKER__ case made it much simpler.
parent 0444d9b3
...@@ -34,10 +34,6 @@ ...@@ -34,10 +34,6 @@
#define segment_eq(a,b) ((a).seg == (b).seg) #define segment_eq(a,b) ((a).seg == (b).seg)
extern long not_a_user_address;
#define check_user_ptr(x) \
(void) ({ void __user * __userptr = (__typeof__(*(x)) *)&not_a_user_address; __userptr; })
/* /*
* movsl can be slow when source and dest are not both 8-byte aligned * movsl can be slow when source and dest are not both 8-byte aligned
*/ */
...@@ -60,7 +56,7 @@ extern struct movsl_mask { ...@@ -60,7 +56,7 @@ extern struct movsl_mask {
*/ */
#define __range_ok(addr,size) ({ \ #define __range_ok(addr,size) ({ \
unsigned long flag,sum; \ unsigned long flag,sum; \
check_user_ptr(addr); \ __chk_user_ptr(addr); \
asm("addl %3,%1 ; sbbl %0,%0; cmpl %1,%4; sbbl $0,%0" \ asm("addl %3,%1 ; sbbl %0,%0; cmpl %1,%4; sbbl $0,%0" \
:"=&r" (flag), "=r" (sum) \ :"=&r" (flag), "=r" (sum) \
:"1" (addr),"g" ((int)(size)),"g" (current_thread_info()->addr_limit.seg)); \ :"1" (addr),"g" ((int)(size)),"g" (current_thread_info()->addr_limit.seg)); \
...@@ -175,7 +171,7 @@ extern void __get_user_4(void); ...@@ -175,7 +171,7 @@ extern void __get_user_4(void);
*/ */
#define get_user(x,ptr) \ #define get_user(x,ptr) \
({ int __ret_gu,__val_gu; \ ({ int __ret_gu,__val_gu; \
check_user_ptr(ptr); \ __chk_user_ptr(ptr); \
switch(sizeof (*(ptr))) { \ switch(sizeof (*(ptr))) { \
case 1: __get_user_x(1,__ret_gu,__val_gu,ptr); break; \ case 1: __get_user_x(1,__ret_gu,__val_gu,ptr); break; \
case 2: __get_user_x(2,__ret_gu,__val_gu,ptr); break; \ case 2: __get_user_x(2,__ret_gu,__val_gu,ptr); break; \
...@@ -294,7 +290,7 @@ extern void __put_user_bad(void); ...@@ -294,7 +290,7 @@ extern void __put_user_bad(void);
#define __put_user_size(x,ptr,size,retval,errret) \ #define __put_user_size(x,ptr,size,retval,errret) \
do { \ do { \
retval = 0; \ retval = 0; \
check_user_ptr(ptr); \ __chk_user_ptr(ptr); \
switch (size) { \ switch (size) { \
case 1: __put_user_asm(x,ptr,retval,"b","b","iq",errret);break; \ case 1: __put_user_asm(x,ptr,retval,"b","b","iq",errret);break; \
case 2: __put_user_asm(x,ptr,retval,"w","w","ir",errret);break; \ case 2: __put_user_asm(x,ptr,retval,"w","w","ir",errret);break; \
...@@ -353,7 +349,7 @@ extern long __get_user_bad(void); ...@@ -353,7 +349,7 @@ extern long __get_user_bad(void);
#define __get_user_size(x,ptr,size,retval,errret) \ #define __get_user_size(x,ptr,size,retval,errret) \
do { \ do { \
retval = 0; \ retval = 0; \
check_user_ptr(ptr); \ __chk_user_ptr(ptr); \
switch (size) { \ switch (size) { \
case 1: __get_user_asm(x,ptr,retval,"b","b","=q",errret);break; \ case 1: __get_user_asm(x,ptr,retval,"b","b","=q",errret);break; \
case 2: __get_user_asm(x,ptr,retval,"w","w","=r",errret);break; \ case 2: __get_user_asm(x,ptr,retval,"w","w","=r",errret);break; \
......
...@@ -16,10 +16,6 @@ ...@@ -16,10 +16,6 @@
#define VERIFY_READ 0 #define VERIFY_READ 0
#define VERIFY_WRITE 1 #define VERIFY_WRITE 1
extern long not_a_user_address;
#define check_user_ptr(x) \
(void) ({ void __user * __userptr = (__typeof__(*(x)) *)&not_a_user_address; __userptr; })
/* /*
* The fs value determines whether argument validity checking should be * The fs value determines whether argument validity checking should be
* performed or not. If get_fs() == USER_DS, checking is performed, with * performed or not. If get_fs() == USER_DS, checking is performed, with
...@@ -120,7 +116,7 @@ extern long __put_user_bad(void); ...@@ -120,7 +116,7 @@ extern long __put_user_bad(void);
#define __put_user_nocheck(x,ptr,size) \ #define __put_user_nocheck(x,ptr,size) \
({ \ ({ \
long __pu_err; \ long __pu_err; \
check_user_ptr(ptr); \ __chk_user_ptr(ptr); \
__put_user_size((x),(ptr),(size),__pu_err,-EFAULT); \ __put_user_size((x),(ptr),(size),__pu_err,-EFAULT); \
__pu_err; \ __pu_err; \
}) })
...@@ -192,7 +188,7 @@ extern long __get_user_bad(void); ...@@ -192,7 +188,7 @@ extern long __get_user_bad(void);
do { \ do { \
might_sleep(); \ might_sleep(); \
retval = 0; \ retval = 0; \
check_user_ptr(ptr); \ __chk_user_ptr(ptr); \
switch (size) { \ switch (size) { \
case 1: __get_user_asm(x,ptr,retval,"lbz",errret); break; \ case 1: __get_user_asm(x,ptr,retval,"lbz",errret); break; \
case 2: __get_user_asm(x,ptr,retval,"lhz",errret); break; \ case 2: __get_user_asm(x,ptr,retval,"lhz",errret); break; \
......
...@@ -83,10 +83,6 @@ extern unsigned long search_extables_range(unsigned long addr, unsigned long *g2 ...@@ -83,10 +83,6 @@ extern unsigned long search_extables_range(unsigned long addr, unsigned long *g2
extern void __ret_efault(void); extern void __ret_efault(void);
extern long not_a_user_address;
#define check_user_ptr(x) \
(void) ({ void __user * __userptr = (__typeof__(*(x)) *)&not_a_user_address; __userptr; })
/* Uh, these should become the main single-value transfer routines.. /* Uh, these should become the main single-value transfer routines..
* They automatically use the right size if we just have the right * They automatically use the right size if we just have the right
* pointer type.. * pointer type..
...@@ -98,12 +94,12 @@ extern long not_a_user_address; ...@@ -98,12 +94,12 @@ extern long not_a_user_address;
*/ */
#define put_user(x,ptr) ({ \ #define put_user(x,ptr) ({ \
unsigned long __pu_addr = (unsigned long)(ptr); \ unsigned long __pu_addr = (unsigned long)(ptr); \
check_user_ptr(ptr); \ __chk_user_ptr(ptr); \
__put_user_check((__typeof__(*(ptr)))(x),__pu_addr,sizeof(*(ptr))); }) __put_user_check((__typeof__(*(ptr)))(x),__pu_addr,sizeof(*(ptr))); })
#define get_user(x,ptr) ({ \ #define get_user(x,ptr) ({ \
unsigned long __gu_addr = (unsigned long)(ptr); \ unsigned long __gu_addr = (unsigned long)(ptr); \
check_user_ptr(ptr); \ __chk_user_ptr(ptr); \
__get_user_check((x),__gu_addr,sizeof(*(ptr)),__typeof__(*(ptr))); }) __get_user_check((x),__gu_addr,sizeof(*(ptr)),__typeof__(*(ptr))); })
/* /*
......
...@@ -90,10 +90,6 @@ unsigned long search_extables_range(unsigned long addr, unsigned long *g2); ...@@ -90,10 +90,6 @@ unsigned long search_extables_range(unsigned long addr, unsigned long *g2);
extern void __ret_efault(void); extern void __ret_efault(void);
extern long not_a_user_address;
#define check_user_ptr(x) \
(void) ({ void __user * __userptr = (__typeof__(*(x)) *)&not_a_user_address; __userptr; })
/* Uh, these should become the main single-value transfer routines.. /* Uh, these should become the main single-value transfer routines..
* They automatically use the right size if we just have the right * They automatically use the right size if we just have the right
* pointer type.. * pointer type..
...@@ -105,12 +101,12 @@ extern long not_a_user_address; ...@@ -105,12 +101,12 @@ extern long not_a_user_address;
*/ */
#define put_user(x,ptr) ({ \ #define put_user(x,ptr) ({ \
unsigned long __pu_addr = (unsigned long)(ptr); \ unsigned long __pu_addr = (unsigned long)(ptr); \
check_user_ptr(ptr); \ __chk_user_ptr(ptr); \
__put_user_nocheck((__typeof__(*(ptr)))(x),__pu_addr,sizeof(*(ptr))); }) __put_user_nocheck((__typeof__(*(ptr)))(x),__pu_addr,sizeof(*(ptr))); })
#define get_user(x,ptr) ({ \ #define get_user(x,ptr) ({ \
unsigned long __gu_addr = (unsigned long)(ptr); \ unsigned long __gu_addr = (unsigned long)(ptr); \
check_user_ptr(ptr); \ __chk_user_ptr(ptr); \
__get_user_nocheck((x),__gu_addr,sizeof(*(ptr)),__typeof__(*(ptr))); }) __get_user_nocheck((x),__gu_addr,sizeof(*(ptr)),__typeof__(*(ptr))); })
#define __put_user(x,ptr) put_user(x,ptr) #define __put_user(x,ptr) put_user(x,ptr)
......
...@@ -6,11 +6,13 @@ ...@@ -6,11 +6,13 @@
# define __kernel /* default address space */ # define __kernel /* default address space */
# define __safe __attribute__((safe)) # define __safe __attribute__((safe))
# define __force __attribute__((force)) # define __force __attribute__((force))
extern void __chk_user_ptr(void __user *);
#else #else
# define __user # define __user
# define __kernel # define __kernel
# define __safe # define __safe
# define __force # define __force
# define __chk_user_ptr(x) (void)0
#endif #endif
#ifdef __KERNEL__ #ifdef __KERNEL__
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment