Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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+

+27 -7
+17 -5
arch/x86/include/asm/checksum_32.h
··· 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 /* ··· 182 176 int len, __wsum sum, 183 177 int *err_ptr) 184 178 { 179 + __wsum ret; 180 + 185 181 might_sleep(); 186 - if (access_ok(VERIFY_WRITE, dst, len)) 187 - return csum_partial_copy_generic(src, (__force void *)dst, 188 - len, sum, NULL, err_ptr); 182 + if (access_ok(VERIFY_WRITE, dst, len)) { 183 + stac(); 184 + ret = csum_partial_copy_generic(src, (__force void *)dst, 185 + len, sum, NULL, err_ptr); 186 + clac(); 187 + return ret; 188 + } 189 189 190 190 if (len) 191 191 *err_ptr = -EFAULT;
+10 -2
arch/x86/lib/csum-wrappers_64.c
··· 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. ··· 53 52 len -= 2; 54 53 } 55 54 } 55 + stac(); 56 56 isum = csum_partial_copy_generic((__force const void *)src, 57 57 dst, len, isum, errp, NULL); 58 + clac(); 58 59 if (unlikely(*errp)) 59 60 goto out_err; 60 61 ··· 85 82 csum_partial_copy_to_user(const void *src, void __user *dst, 86 83 int len, __wsum isum, int *errp) 87 84 { 85 + __wsum ret; 86 + 88 87 might_sleep(); 89 88 90 89 if (unlikely(!access_ok(VERIFY_WRITE, dst, len))) { ··· 110 105 } 111 106 112 107 *errp = 0; 113 - return csum_partial_copy_generic(src, (void __force *)dst, 114 - len, isum, NULL, errp); 108 + stac(); 109 + ret = csum_partial_copy_generic(src, (void __force *)dst, 110 + len, isum, NULL, errp); 111 + clac(); 112 + return ret; 115 113 } 116 114 EXPORT_SYMBOL(csum_partial_copy_to_user); 117 115