Commit 7263dda41b5a28ae6566fd126d9b06ada73dd721

Authored by H. Peter Anvin
1 parent d8dfad3876

x86, smap: Handle csum_partial_copy_*_user()

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+

Showing 2 changed files with 27 additions and 7 deletions Side-by-side Diff

arch/x86/include/asm/checksum_32.h
... ... @@ -49,9 +49,15 @@
49 49 int len, __wsum sum,
50 50 int *err_ptr)
51 51 {
  52 + __wsum ret;
  53 +
52 54 might_sleep();
53   - return csum_partial_copy_generic((__force void *)src, dst,
54   - len, sum, err_ptr, NULL);
  55 + stac();
  56 + ret = csum_partial_copy_generic((__force void *)src, dst,
  57 + len, sum, err_ptr, NULL);
  58 + clac();
  59 +
  60 + return ret;
55 61 }
56 62  
57 63 /*
58 64  
... ... @@ -176,10 +182,16 @@
176 182 int len, __wsum sum,
177 183 int *err_ptr)
178 184 {
  185 + __wsum ret;
  186 +
179 187 might_sleep();
180   - if (access_ok(VERIFY_WRITE, dst, len))
181   - return csum_partial_copy_generic(src, (__force void *)dst,
182   - len, sum, NULL, err_ptr);
  188 + if (access_ok(VERIFY_WRITE, dst, len)) {
  189 + stac();
  190 + ret = csum_partial_copy_generic(src, (__force void *)dst,
  191 + len, sum, NULL, err_ptr);
  192 + clac();
  193 + return ret;
  194 + }
183 195  
184 196 if (len)
185 197 *err_ptr = -EFAULT;
arch/x86/lib/csum-wrappers_64.c
... ... @@ -6,6 +6,7 @@
6 6 */
7 7 #include <asm/checksum.h>
8 8 #include <linux/module.h>
  9 +#include <asm/smap.h>
9 10  
10 11 /**
11 12 * csum_partial_copy_from_user - Copy and checksum from user space.
12 13  
... ... @@ -52,8 +53,10 @@
52 53 len -= 2;
53 54 }
54 55 }
  56 + stac();
55 57 isum = csum_partial_copy_generic((__force const void *)src,
56 58 dst, len, isum, errp, NULL);
  59 + clac();
57 60 if (unlikely(*errp))
58 61 goto out_err;
59 62  
... ... @@ -82,6 +85,8 @@
82 85 csum_partial_copy_to_user(const void *src, void __user *dst,
83 86 int len, __wsum isum, int *errp)
84 87 {
  88 + __wsum ret;
  89 +
85 90 might_sleep();
86 91  
87 92 if (unlikely(!access_ok(VERIFY_WRITE, dst, len))) {
... ... @@ -105,8 +110,11 @@
105 110 }
106 111  
107 112 *errp = 0;
108   - return csum_partial_copy_generic(src, (void __force *)dst,
109   - len, isum, NULL, errp);
  113 + stac();
  114 + ret = csum_partial_copy_generic(src, (void __force *)dst,
  115 + len, isum, NULL, errp);
  116 + clac();
  117 + return ret;
110 118 }
111 119 EXPORT_SYMBOL(csum_partial_copy_to_user);
112 120