aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@linux.intel.com>2013-08-30 18:43:03 -0400
committerH. Peter Anvin <hpa@linux.intel.com>2013-09-01 17:09:48 -0400
commit7263dda41b5a28ae6566fd126d9b06ada73dd721 (patch)
tree038c70f2e86655fc513ec99e141405a43e3a1632
parentd8dfad3876e4386666b759da3c833d62fb8b2267 (diff)
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+
-rw-r--r--arch/x86/include/asm/checksum_32.h22
-rw-r--r--arch/x86/lib/csum-wrappers_64.c12
2 files changed, 27 insertions, 7 deletions
diff --git a/arch/x86/include/asm/checksum_32.h b/arch/x86/include/asm/checksum_32.h
index 46fc474fd819..f50de6951738 100644
--- a/arch/x86/include/asm/checksum_32.h
+++ b/arch/x86/include/asm/checksum_32.h
@@ -49,9 +49,15 @@ static inline __wsum csum_partial_copy_from_user(const void __user *src,
49 int len, __wsum sum, 49 int len, __wsum sum,
50 int *err_ptr) 50 int *err_ptr)
51{ 51{
52 __wsum ret;
53
52 might_sleep(); 54 might_sleep();
53 return csum_partial_copy_generic((__force void *)src, dst, 55 stac();
54 len, sum, err_ptr, NULL); 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/*
@@ -176,10 +182,16 @@ static inline __wsum csum_and_copy_to_user(const void *src,
176 int len, __wsum sum, 182 int len, __wsum sum,
177 int *err_ptr) 183 int *err_ptr)
178{ 184{
185 __wsum ret;
186
179 might_sleep(); 187 might_sleep();
180 if (access_ok(VERIFY_WRITE, dst, len)) 188 if (access_ok(VERIFY_WRITE, dst, len)) {
181 return csum_partial_copy_generic(src, (__force void *)dst, 189 stac();
182 len, sum, NULL, err_ptr); 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 if (len) 196 if (len)
185 *err_ptr = -EFAULT; 197 *err_ptr = -EFAULT;
diff --git a/arch/x86/lib/csum-wrappers_64.c b/arch/x86/lib/csum-wrappers_64.c
index 25b7ae8d058a..7609e0e421ec 100644
--- a/arch/x86/lib/csum-wrappers_64.c
+++ b/arch/x86/lib/csum-wrappers_64.c
@@ -6,6 +6,7 @@
6 */ 6 */
7#include <asm/checksum.h> 7#include <asm/checksum.h>
8#include <linux/module.h> 8#include <linux/module.h>
9#include <asm/smap.h>
9 10
10/** 11/**
11 * csum_partial_copy_from_user - Copy and checksum from user space. 12 * 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,
52 len -= 2; 53 len -= 2;
53 } 54 }
54 } 55 }
56 stac();
55 isum = csum_partial_copy_generic((__force const void *)src, 57 isum = csum_partial_copy_generic((__force const void *)src,
56 dst, len, isum, errp, NULL); 58 dst, len, isum, errp, NULL);
59 clac();
57 if (unlikely(*errp)) 60 if (unlikely(*errp))
58 goto out_err; 61 goto out_err;
59 62
@@ -82,6 +85,8 @@ __wsum
82csum_partial_copy_to_user(const void *src, void __user *dst, 85csum_partial_copy_to_user(const void *src, void __user *dst,
83 int len, __wsum isum, int *errp) 86 int len, __wsum isum, int *errp)
84{ 87{
88 __wsum ret;
89
85 might_sleep(); 90 might_sleep();
86 91
87 if (unlikely(!access_ok(VERIFY_WRITE, dst, len))) { 92 if (unlikely(!access_ok(VERIFY_WRITE, dst, len))) {
@@ -105,8 +110,11 @@ csum_partial_copy_to_user(const void *src, void __user *dst,
105 } 110 }
106 111
107 *errp = 0; 112 *errp = 0;
108 return csum_partial_copy_generic(src, (void __force *)dst, 113 stac();
109 len, isum, NULL, errp); 114 ret = csum_partial_copy_generic(src, (void __force *)dst,
115 len, isum, NULL, errp);
116 clac();
117 return ret;
110} 118}
111EXPORT_SYMBOL(csum_partial_copy_to_user); 119EXPORT_SYMBOL(csum_partial_copy_to_user);
112 120