[PATCH] i386: Add a temporary to make put_user more type safe
authorEric W. Biederman <ebiederm@xmission.com>
Thu, 23 Mar 2006 10:59:35 +0000 (02:59 -0800)
committerLinus Torvalds <torvalds@g5.osdl.org>
Thu, 23 Mar 2006 15:38:04 +0000 (07:38 -0800)
In some code I am developing I had occasion to change the type of a
variable.  This made the value put_user was putting to user space wrong.
But the code continued to build cleanly without errors.

Introducing a temporary fixes this problem and at least with gcc-3.3.5 does
not cause gcc any problems with optimizing out the temporary.  gcc-4.x
using SSA internally ought to be even better at optimizing out temporaries,
so I don't expect a temporary to become a problem.  Especially because in
all correct cases the types on both sides of the assignment to the
temporary are the same.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
include/asm-i386/uaccess.h

index 3f1337c..371457b 100644 (file)
@@ -197,13 +197,15 @@ extern void __put_user_8(void);
 
 #define put_user(x,ptr)                                                \
 ({     int __ret_pu;                                           \
+       __typeof__(*(ptr)) __pu_val;                            \
        __chk_user_ptr(ptr);                                    \
+       __pu_val = x;                                           \
        switch(sizeof(*(ptr))) {                                \
-       case 1: __put_user_1(x, ptr); break;                    \
-       case 2: __put_user_2(x, ptr); break;                    \
-       case 4: __put_user_4(x, ptr); break;                    \
-       case 8: __put_user_8(x, ptr); break;                    \
-       default:__put_user_X(x, ptr); break;                    \
+       case 1: __put_user_1(__pu_val, ptr); break;             \
+       case 2: __put_user_2(__pu_val, ptr); break;             \
+       case 4: __put_user_4(__pu_val, ptr); break;             \
+       case 8: __put_user_8(__pu_val, ptr); break;             \
+       default:__put_user_X(__pu_val, ptr); break;             \
        }                                                       \
        __ret_pu;                                               \
 })