Commit ee886bb8 authored by Alexander Viro's avatar Alexander Viro Committed by Linus Torvalds

[PATCH] sparse: simplify and tighten sparse typechecking

This takes advantage of the simplified typeof semantics of sparse
address spaces, (should be enough for alpha, i386, ppc, ppc64, sparc,
sparc64, x86_64 - most of them didn't actually need anything to be done)
and couple of missing annotations that got caught by that.
parent 94abb516
...@@ -149,7 +149,7 @@ asmlinkage int sys_ipc (uint call, int first, int second, ...@@ -149,7 +149,7 @@ asmlinkage int sys_ipc (uint call, int first, int second,
union semun fourth; union semun fourth;
if (!ptr) if (!ptr)
return -EINVAL; return -EINVAL;
if (get_user(fourth.__pad, (void * __user *) ptr)) if (get_user(fourth.__pad, (void __user * __user *) ptr))
return -EFAULT; return -EFAULT;
return sys_semctl (first, second, third, fourth); return sys_semctl (first, second, third, fourth);
} }
......
...@@ -78,7 +78,7 @@ sys_ipc (uint call, int first, int second, int third, void __user *ptr, long fif ...@@ -78,7 +78,7 @@ sys_ipc (uint call, int first, int second, int third, void __user *ptr, long fif
if (!ptr) if (!ptr)
break; break;
if ((ret = verify_area (VERIFY_READ, ptr, sizeof(long))) if ((ret = verify_area (VERIFY_READ, ptr, sizeof(long)))
|| (ret = get_user(fourth.__pad, (void *__user *)ptr))) || (ret = get_user(fourth.__pad, (void __user *__user *)ptr)))
break; break;
ret = sys_semctl (first, second, third, fourth); ret = sys_semctl (first, second, third, fourth);
break; break;
......
...@@ -107,7 +107,7 @@ extern void __get_user_unknown(void); ...@@ -107,7 +107,7 @@ extern void __get_user_unknown(void);
#define __get_user_check(x,ptr,size,segment) \ #define __get_user_check(x,ptr,size,segment) \
({ \ ({ \
long __gu_err = -EFAULT, __gu_val = 0; \ long __gu_err = -EFAULT, __gu_val = 0; \
const __typeof__(*(ptr)) *__gu_addr = (ptr); \ const __typeof__(*(ptr)) __user *__gu_addr = (ptr); \
__chk_user_ptr(ptr); \ __chk_user_ptr(ptr); \
if (__access_ok((unsigned long)__gu_addr,size,segment)) { \ if (__access_ok((unsigned long)__gu_addr,size,segment)) { \
__gu_err = 0; \ __gu_err = 0; \
...@@ -222,7 +222,7 @@ extern void __put_user_unknown(void); ...@@ -222,7 +222,7 @@ extern void __put_user_unknown(void);
#define __put_user_check(x,ptr,size,segment) \ #define __put_user_check(x,ptr,size,segment) \
({ \ ({ \
long __pu_err = -EFAULT; \ long __pu_err = -EFAULT; \
__typeof__(*(ptr)) *__pu_addr = (ptr); \ __typeof__(*(ptr)) __user *__pu_addr = (ptr); \
__chk_user_ptr(ptr); \ __chk_user_ptr(ptr); \
if (__access_ok((unsigned long)__pu_addr,size,segment)) { \ if (__access_ok((unsigned long)__pu_addr,size,segment)) { \
__pu_err = 0; \ __pu_err = 0; \
......
...@@ -261,7 +261,7 @@ extern void __put_user_bad(void); ...@@ -261,7 +261,7 @@ extern void __put_user_bad(void);
#define __put_user_check(x,ptr,size) \ #define __put_user_check(x,ptr,size) \
({ \ ({ \
long __pu_err = -EFAULT; \ long __pu_err = -EFAULT; \
__typeof__(*(ptr)) *__pu_addr = (ptr); \ __typeof__(*(ptr)) __user *__pu_addr = (ptr); \
might_sleep(); \ might_sleep(); \
if (access_ok(VERIFY_WRITE,__pu_addr,size)) \ if (access_ok(VERIFY_WRITE,__pu_addr,size)) \
__put_user_size((x),__pu_addr,(size),__pu_err,-EFAULT); \ __put_user_size((x),__pu_addr,(size),__pu_err,-EFAULT); \
......
...@@ -34,7 +34,8 @@ ...@@ -34,7 +34,8 @@
((addr) <= current->thread.fs.seg \ ((addr) <= current->thread.fs.seg \
&& ((size) == 0 || (size) - 1 <= current->thread.fs.seg - (addr))) && ((size) == 0 || (size) - 1 <= current->thread.fs.seg - (addr)))
#define access_ok(type, addr, size) __access_ok((unsigned long)(addr),(size)) #define access_ok(type, addr, size) \
(__chk_user_ptr(addr),__access_ok((unsigned long)(addr),(size)))
extern inline int verify_area(int type, const void __user * addr, unsigned long size) extern inline int verify_area(int type, const void __user * addr, unsigned long size)
{ {
...@@ -105,6 +106,7 @@ extern long __put_user_bad(void); ...@@ -105,6 +106,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; \
__chk_user_ptr(ptr); \
__put_user_size((x),(ptr),(size),__pu_err); \ __put_user_size((x),(ptr),(size),__pu_err); \
__pu_err; \ __pu_err; \
}) })
...@@ -112,7 +114,7 @@ extern long __put_user_bad(void); ...@@ -112,7 +114,7 @@ extern long __put_user_bad(void);
#define __put_user_check(x,ptr,size) \ #define __put_user_check(x,ptr,size) \
({ \ ({ \
long __pu_err = -EFAULT; \ long __pu_err = -EFAULT; \
__typeof__(*(ptr)) *__pu_addr = (ptr); \ __typeof__(*(ptr)) __user *__pu_addr = (ptr); \
if (access_ok(VERIFY_WRITE,__pu_addr,size)) \ if (access_ok(VERIFY_WRITE,__pu_addr,size)) \
__put_user_size((x),__pu_addr,(size),__pu_err); \ __put_user_size((x),__pu_addr,(size),__pu_err); \
__pu_err; \ __pu_err; \
...@@ -179,6 +181,7 @@ do { \ ...@@ -179,6 +181,7 @@ do { \
#define __get_user_nocheck(x, ptr, size) \ #define __get_user_nocheck(x, ptr, size) \
({ \ ({ \
long __gu_err, __gu_val; \ long __gu_err, __gu_val; \
__chk_user_ptr(ptr); \
__get_user_size(__gu_val, (ptr), (size), __gu_err); \ __get_user_size(__gu_val, (ptr), (size), __gu_err); \
(x) = (__typeof__(*(ptr)))__gu_val; \ (x) = (__typeof__(*(ptr)))__gu_val; \
__gu_err; \ __gu_err; \
...@@ -188,6 +191,7 @@ do { \ ...@@ -188,6 +191,7 @@ do { \
({ \ ({ \
long __gu_err; \ long __gu_err; \
long long __gu_val; \ long long __gu_val; \
__chk_user_ptr(ptr); \
__get_user_size64(__gu_val, (ptr), (size), __gu_err); \ __get_user_size64(__gu_val, (ptr), (size), __gu_err); \
(x) = (__typeof__(*(ptr)))__gu_val; \ (x) = (__typeof__(*(ptr)))__gu_val; \
__gu_err; \ __gu_err; \
...@@ -196,7 +200,7 @@ do { \ ...@@ -196,7 +200,7 @@ do { \
#define __get_user_check(x, ptr, size) \ #define __get_user_check(x, ptr, size) \
({ \ ({ \
long __gu_err = -EFAULT, __gu_val = 0; \ long __gu_err = -EFAULT, __gu_val = 0; \
const __typeof__(*(ptr)) *__gu_addr = (ptr); \ const __typeof__(*(ptr)) __user *__gu_addr = (ptr); \
if (access_ok(VERIFY_READ, __gu_addr, (size))) \ if (access_ok(VERIFY_READ, __gu_addr, (size))) \
__get_user_size(__gu_val, __gu_addr, (size), __gu_err); \ __get_user_size(__gu_val, __gu_addr, (size), __gu_err); \
(x) = (__typeof__(*(ptr)))__gu_val; \ (x) = (__typeof__(*(ptr)))__gu_val; \
...@@ -207,7 +211,7 @@ do { \ ...@@ -207,7 +211,7 @@ do { \
({ \ ({ \
long __gu_err = -EFAULT; \ long __gu_err = -EFAULT; \
long long __gu_val = 0; \ long long __gu_val = 0; \
const __typeof__(*(ptr)) *__gu_addr = (ptr); \ const __typeof__(*(ptr)) __user *__gu_addr = (ptr); \
if (access_ok(VERIFY_READ, __gu_addr, (size))) \ if (access_ok(VERIFY_READ, __gu_addr, (size))) \
__get_user_size64(__gu_val, __gu_addr, (size), __gu_err); \ __get_user_size64(__gu_val, __gu_addr, (size), __gu_err); \
(x) = (__typeof__(*(ptr)))__gu_val; \ (x) = (__typeof__(*(ptr)))__gu_val; \
......
...@@ -175,7 +175,7 @@ do { \ ...@@ -175,7 +175,7 @@ do { \
#define __get_user_check(x,ptr,size) \ #define __get_user_check(x,ptr,size) \
({ \ ({ \
long __gu_err = -EFAULT, __gu_val = 0; \ long __gu_err = -EFAULT, __gu_val = 0; \
const __typeof__(*(ptr)) *__gu_addr = (ptr); \ const __typeof__(*(ptr)) __user *__gu_addr = (ptr); \
if (access_ok(VERIFY_READ,__gu_addr,size)) \ if (access_ok(VERIFY_READ,__gu_addr,size)) \
__get_user_size(__gu_val,__gu_addr,(size),__gu_err,-EFAULT);\ __get_user_size(__gu_val,__gu_addr,(size),__gu_err,-EFAULT);\
(x) = (__typeof__(*(ptr)))__gu_val; \ (x) = (__typeof__(*(ptr)))__gu_val; \
......
...@@ -148,7 +148,7 @@ extern void __put_user_bad(void); ...@@ -148,7 +148,7 @@ extern void __put_user_bad(void);
#define __put_user_check(x,ptr,size) \ #define __put_user_check(x,ptr,size) \
({ \ ({ \
int __pu_err = -EFAULT; \ int __pu_err = -EFAULT; \
__typeof__(*(ptr)) *__pu_addr = (ptr); \ __typeof__(*(ptr)) __user *__pu_addr = (ptr); \
if (likely(access_ok(VERIFY_WRITE,__pu_addr,size))) \ if (likely(access_ok(VERIFY_WRITE,__pu_addr,size))) \
__put_user_size((x),__pu_addr,(size),__pu_err); \ __put_user_size((x),__pu_addr,(size),__pu_err); \
__pu_err; \ __pu_err; \
......
...@@ -147,7 +147,7 @@ struct atm_dev_stats { ...@@ -147,7 +147,7 @@ struct atm_dev_stats {
struct atm_iobuf { struct atm_iobuf {
int length; int length;
void *buffer; void __user *buffer;
}; };
/* for ATM_GETCIRANGE / ATM_SETCIRANGE */ /* for ATM_GETCIRANGE / ATM_SETCIRANGE */
......
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