x86, smap: Handle csum_partial_copy_*_user()
authorH. Peter Anvin <hpa@linux.intel.com>
Fri, 30 Aug 2013 22:43:03 +0000 (15:43 -0700)
committerH. Peter Anvin <hpa@linux.intel.com>
Sun, 1 Sep 2013 21:09:48 +0000 (14:09 -0700)
Add SMAP annotations to csum_partial_copy_to/from_user().  These
functions legitimately access user space and thus need to set the AC
flag.

TODO: add explicit checks that the side with the kernel space pointer
really points into kernel space.

Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Link: http://lkml.kernel.org/n/tip-2aps0u00eer658fd5xyanan7@git.kernel.org
Cc: <stable@vger.kernel.org> # v3.7+
arch/x86/include/asm/checksum_32.h
arch/x86/lib/csum-wrappers_64.c

index 46fc474..f50de69 100644 (file)
@@ -49,9 +49,15 @@ static inline __wsum csum_partial_copy_from_user(const void __user *src,
                                                 int len, __wsum sum,
                                                 int *err_ptr)
 {
+       __wsum ret;
+
        might_sleep();
-       return csum_partial_copy_generic((__force void *)src, dst,
-                                        len, sum, err_ptr, NULL);
+       stac();
+       ret = csum_partial_copy_generic((__force void *)src, dst,
+                                       len, sum, err_ptr, NULL);
+       clac();
+
+       return ret;
 }
 
 /*
@@ -176,10 +182,16 @@ static inline __wsum csum_and_copy_to_user(const void *src,
                                           int len, __wsum sum,
                                           int *err_ptr)
 {
+       __wsum ret;
+
        might_sleep();
-       if (access_ok(VERIFY_WRITE, dst, len))
-               return csum_partial_copy_generic(src, (__force void *)dst,
-                                                len, sum, NULL, err_ptr);
+       if (access_ok(VERIFY_WRITE, dst, len)) {
+               stac();
+               ret = csum_partial_copy_generic(src, (__force void *)dst,
+                                               len, sum, NULL, err_ptr);
+               clac();
+               return ret;
+       }
 
        if (len)
                *err_ptr = -EFAULT;
index 25b7ae8..7609e0e 100644 (file)
@@ -6,6 +6,7 @@
  */
 #include <asm/checksum.h>
 #include <linux/module.h>
+#include <asm/smap.h>
 
 /**
  * csum_partial_copy_from_user - Copy and checksum from user space.
@@ -52,8 +53,10 @@ csum_partial_copy_from_user(const void __user *src, void *dst,
                        len -= 2;
                }
        }
+       stac();
        isum = csum_partial_copy_generic((__force const void *)src,
                                dst, len, isum, errp, NULL);
+       clac();
        if (unlikely(*errp))
                goto out_err;
 
@@ -82,6 +85,8 @@ __wsum
 csum_partial_copy_to_user(const void *src, void __user *dst,
                          int len, __wsum isum, int *errp)
 {
+       __wsum ret;
+
        might_sleep();
 
        if (unlikely(!access_ok(VERIFY_WRITE, dst, len))) {
@@ -105,8 +110,11 @@ csum_partial_copy_to_user(const void *src, void __user *dst,
        }
 
        *errp = 0;
-       return csum_partial_copy_generic(src, (void __force *)dst,
-                                        len, isum, NULL, errp);
+       stac();
+       ret = csum_partial_copy_generic(src, (void __force *)dst,
+                                       len, isum, NULL, errp);
+       clac();
+       return ret;
 }
 EXPORT_SYMBOL(csum_partial_copy_to_user);