diff options
author | H. Peter Anvin <hpa@linux.intel.com> | 2013-08-30 18:43:03 -0400 |
---|---|---|
committer | H. Peter Anvin <hpa@linux.intel.com> | 2013-09-01 17:09:48 -0400 |
commit | 7263dda41b5a28ae6566fd126d9b06ada73dd721 (patch) | |
tree | 038c70f2e86655fc513ec99e141405a43e3a1632 | |
parent | d8dfad3876e4386666b759da3c833d62fb8b2267 (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.h | 22 | ||||
-rw-r--r-- | arch/x86/lib/csum-wrappers_64.c | 12 |
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 | |||
82 | csum_partial_copy_to_user(const void *src, void __user *dst, | 85 | csum_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 | } |
111 | EXPORT_SYMBOL(csum_partial_copy_to_user); | 119 | EXPORT_SYMBOL(csum_partial_copy_to_user); |
112 | 120 | ||