| From 7263dda41b5a28ae6566fd126d9b06ada73dd721 Mon Sep 17 00:00:00 2001 |
| From: "H. Peter Anvin" <hpa@linux.intel.com> |
| Date: Fri, 30 Aug 2013 15:43:03 -0700 |
| Subject: x86, smap: Handle csum_partial_copy_*_user() |
| |
| From: "H. Peter Anvin" <hpa@linux.intel.com> |
| |
| commit 7263dda41b5a28ae6566fd126d9b06ada73dd721 upstream. |
| |
| 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 |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| arch/x86/include/asm/checksum_32.h | 22 +++++++++++++++++----- |
| arch/x86/lib/csum-wrappers_64.c | 12 ++++++++++-- |
| 2 files changed, 27 insertions(+), 7 deletions(-) |
| |
| --- 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_f |
| 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_us |
| 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; |
| --- a/arch/x86/lib/csum-wrappers_64.c |
| +++ b/arch/x86/lib/csum-wrappers_64.c |
| @@ -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 _ |
| 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 *sr |
| } |
| |
| *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); |
| |