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

Merge branch 'uaccess.csum' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs

Pull uaccess/csum updates from Al Viro:
"Regularize the sitation with uaccess checksum primitives:

- fold csum_partial_... into csum_and_copy_..._user()

- on x86 collapse several access_ok()/stac()/clac() into
user_access_begin()/user_access_end()"

* 'uaccess.csum' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
default csum_and_copy_to_user(): don't bother with access_ok()
take the dummy csum_and_copy_from_user() into net/checksum.h
arm: switch to csum_and_copy_from_user()
sh32: convert to csum_and_copy_from_user()
m68k: convert to csum_and_copy_from_user()
xtensa: switch to providing csum_and_copy_from_user()
sparc: switch to providing csum_and_copy_from_user()
parisc: turn csum_partial_copy_from_user() into csum_and_copy_from_user()
alpha: turn csum_partial_copy_from_user() into csum_and_copy_from_user()
ia64: turn csum_partial_copy_from_user() into csum_and_copy_from_user()
ia64: csum_partial_copy_nocheck(): don't abuse csum_partial_copy_from_user()
x86: switch 32bit csum_and_copy_to_user() to user_access_{begin,end}()
x86: switch both 32bit and 64bit to providing csum_and_copy_from_user()
x86_64: csum_..._copy_..._user(): switch to unsafe_..._user()
get rid of csum_partial_copy_to_user()

+88 -225
+2 -1
arch/alpha/include/asm/checksum.h
··· 41 41 * here even more important to align src and dst on a 32-bit (or even 42 42 * better 64-bit) boundary 43 43 */ 44 - __wsum csum_partial_copy_from_user(const void __user *src, void *dst, int len, __wsum sum, int *errp); 44 + #define _HAVE_ARCH_COPY_AND_CSUM_FROM_USER 45 + __wsum csum_and_copy_from_user(const void __user *src, void *dst, int len, __wsum sum, int *errp); 45 46 46 47 __wsum csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum); 47 48
+3 -3
arch/alpha/lib/csum_partial_copy.c
··· 325 325 } 326 326 327 327 __wsum 328 - csum_partial_copy_from_user(const void __user *src, void *dst, int len, 328 + csum_and_copy_from_user(const void __user *src, void *dst, int len, 329 329 __wsum sum, int *errp) 330 330 { 331 331 unsigned long checksum = (__force u32) sum; ··· 369 369 } 370 370 return (__force __wsum)checksum; 371 371 } 372 - EXPORT_SYMBOL(csum_partial_copy_from_user); 372 + EXPORT_SYMBOL(csum_and_copy_from_user); 373 373 374 374 __wsum 375 375 csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum) ··· 377 377 __wsum checksum; 378 378 mm_segment_t oldfs = get_fs(); 379 379 set_fs(KERNEL_DS); 380 - checksum = csum_partial_copy_from_user((__force const void __user *)src, 380 + checksum = csum_and_copy_from_user((__force const void __user *)src, 381 381 dst, len, sum, NULL); 382 382 set_fs(oldfs); 383 383 return checksum;
+14
arch/arm/include/asm/checksum.h
··· 40 40 __wsum 41 41 csum_partial_copy_from_user(const void __user *src, void *dst, int len, __wsum sum, int *err_ptr); 42 42 43 + #define _HAVE_ARCH_COPY_AND_CSUM_FROM_USER 44 + static inline 45 + __wsum csum_and_copy_from_user (const void __user *src, void *dst, 46 + int len, __wsum sum, int *err_ptr) 47 + { 48 + if (access_ok(src, len)) 49 + return csum_partial_copy_from_user(src, dst, len, sum, err_ptr); 50 + 51 + if (len) 52 + *err_ptr = -EFAULT; 53 + 54 + return sum; 55 + } 56 + 43 57 /* 44 58 * Fold a partial checksum without adding pseudo headers 45 59 */
-22
arch/c6x/lib/checksum.c
··· 4 4 #include <linux/module.h> 5 5 #include <net/checksum.h> 6 6 7 - #include <asm/byteorder.h> 8 - 9 - /* 10 - * copy from fs while checksumming, otherwise like csum_partial 11 - */ 12 - __wsum 13 - csum_partial_copy_from_user(const void __user *src, void *dst, int len, 14 - __wsum sum, int *csum_err) 15 - { 16 - int missing; 17 - 18 - missing = __copy_from_user(dst, src, len); 19 - if (missing) { 20 - memset(dst + len - missing, 0, missing); 21 - *csum_err = -EFAULT; 22 - } else 23 - *csum_err = 0; 24 - 25 - return csum_partial(dst, len, sum); 26 - } 27 - EXPORT_SYMBOL(csum_partial_copy_from_user); 28 - 29 7 /* These are from csum_64plus.S */ 30 8 EXPORT_SYMBOL(csum_partial); 31 9 EXPORT_SYMBOL(csum_partial_copy);
-10
arch/ia64/include/asm/checksum.h
··· 37 37 */ 38 38 extern __wsum csum_partial(const void *buff, int len, __wsum sum); 39 39 40 - /* 41 - * Same as csum_partial, but copies from src while it checksums. 42 - * 43 - * Here it is even more important to align src and dst on a 32-bit (or 44 - * even better 64-bit) boundary. 45 - */ 46 - extern __wsum csum_partial_copy_from_user(const void __user *src, void *dst, 47 - int len, __wsum sum, 48 - int *errp); 49 - 50 40 extern __wsum csum_partial_copy_nocheck(const void *src, void *dst, 51 41 int len, __wsum sum); 52 42
+2 -30
arch/ia64/lib/csum_partial_copy.c
··· 103 103 * This is very ugly but temporary. THIS NEEDS SERIOUS ENHANCEMENTS. 104 104 * But it's very tricky to get right even in C. 105 105 */ 106 - extern unsigned long do_csum(const unsigned char *, long); 107 - 108 - __wsum 109 - csum_partial_copy_from_user(const void __user *src, void *dst, 110 - int len, __wsum psum, int *errp) 111 - { 112 - unsigned long result; 113 - 114 - /* XXX Fixme 115 - * for now we separate the copy from checksum for obvious 116 - * alignment difficulties. Look at the Alpha code and you'll be 117 - * scared. 118 - */ 119 - 120 - if (__copy_from_user(dst, src, len) != 0 && errp) 121 - *errp = -EFAULT; 122 - 123 - result = do_csum(dst, len); 124 - 125 - /* add in old sum, and carry.. */ 126 - result += (__force u32)psum; 127 - /* 32+c bits -> 32 bits */ 128 - result = (result & 0xffffffff) + (result >> 32); 129 - return (__force __wsum)result; 130 - } 131 - 132 - EXPORT_SYMBOL(csum_partial_copy_from_user); 133 - 134 106 __wsum 135 107 csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum) 136 108 { 137 - return csum_partial_copy_from_user((__force const void __user *)src, 138 - dst, len, sum, NULL); 109 + memcpy(dst, src, len); 110 + return csum_partial(dst, len, sum); 139 111 } 140 112 141 113 EXPORT_SYMBOL(csum_partial_copy_nocheck);
+2 -1
arch/m68k/include/asm/checksum.h
··· 30 30 * better 64-bit) boundary 31 31 */ 32 32 33 - extern __wsum csum_partial_copy_from_user(const void __user *src, 33 + #define _HAVE_ARCH_COPY_AND_CSUM_FROM_USER 34 + extern __wsum csum_and_copy_from_user(const void __user *src, 34 35 void *dst, 35 36 int len, __wsum sum, 36 37 int *csum_err);
+2 -2
arch/m68k/lib/checksum.c
··· 129 129 */ 130 130 131 131 __wsum 132 - csum_partial_copy_from_user(const void __user *src, void *dst, 132 + csum_and_copy_from_user(const void __user *src, void *dst, 133 133 int len, __wsum sum, int *csum_err) 134 134 { 135 135 /* ··· 316 316 return(sum); 317 317 } 318 318 319 - EXPORT_SYMBOL(csum_partial_copy_from_user); 319 + EXPORT_SYMBOL(csum_and_copy_from_user); 320 320 321 321 322 322 /*
-2
arch/nios2/include/asm/checksum.h
··· 14 14 extern __wsum csum_partial(const void *buff, int len, __wsum sum); 15 15 extern __wsum csum_partial_copy(const void *src, void *dst, int len, 16 16 __wsum sum); 17 - extern __wsum csum_partial_copy_from_user(const void __user *src, void *dst, 18 - int len, __wsum sum, int *csum_err); 19 17 #define csum_partial_copy_nocheck(src, dst, len, sum) \ 20 18 csum_partial_copy((src), (dst), (len), (sum)) 21 19
-7
arch/parisc/include/asm/checksum.h
··· 27 27 extern __wsum csum_partial_copy_nocheck(const void *, void *, int, __wsum); 28 28 29 29 /* 30 - * this is a new version of the above that records errors it finds in *errp, 31 - * but continues and zeros the rest of the buffer. 32 - */ 33 - extern __wsum csum_partial_copy_from_user(const void __user *src, 34 - void *dst, int len, __wsum sum, int *errp); 35 - 36 - /* 37 30 * Optimized for IP headers, which always checksum on 4 octet boundaries. 38 31 * 39 32 * Written by Randolph Chung <tausq@debian.org>, and then mucked with by
-20
arch/parisc/lib/checksum.c
··· 123 123 return sum; 124 124 } 125 125 EXPORT_SYMBOL(csum_partial_copy_nocheck); 126 - 127 - /* 128 - * Copy from userspace and compute checksum. If we catch an exception 129 - * then zero the rest of the buffer. 130 - */ 131 - __wsum csum_partial_copy_from_user(const void __user *src, 132 - void *dst, int len, 133 - __wsum sum, int *err_ptr) 134 - { 135 - int missing; 136 - 137 - missing = copy_from_user(dst, src, len); 138 - if (missing) { 139 - memset(dst + len - missing, 0, missing); 140 - *err_ptr = -EFAULT; 141 - } 142 - 143 - return csum_partial(dst, len, sum); 144 - } 145 - EXPORT_SYMBOL(csum_partial_copy_from_user);
-19
arch/s390/include/asm/checksum.h
··· 39 39 return sum; 40 40 } 41 41 42 - /* 43 - * the same as csum_partial_copy, but copies from user space. 44 - * 45 - * here even more important to align src and dst on a 32-bit (or even 46 - * better 64-bit) boundary 47 - * 48 - * Copy from userspace and compute checksum. 49 - */ 50 - static inline __wsum 51 - csum_partial_copy_from_user(const void __user *src, void *dst, 52 - int len, __wsum sum, 53 - int *err_ptr) 54 - { 55 - if (unlikely(copy_from_user(dst, src, len))) 56 - *err_ptr = -EFAULT; 57 - return csum_partial(dst, len, sum); 58 - } 59 - 60 - 61 42 static inline __wsum 62 43 csum_partial_copy_nocheck (const void *src, void *dst, int len, __wsum sum) 63 44 {
+7 -2
arch/sh/include/asm/checksum_32.h
··· 48 48 return csum_partial_copy_generic(src, dst, len, sum, NULL, NULL); 49 49 } 50 50 51 + #define _HAVE_ARCH_COPY_AND_CSUM_FROM_USER 51 52 static inline 52 - __wsum csum_partial_copy_from_user(const void __user *src, void *dst, 53 + __wsum csum_and_copy_from_user(const void __user *src, void *dst, 53 54 int len, __wsum sum, int *err_ptr) 54 55 { 55 - return csum_partial_copy_generic((__force const void *)src, dst, 56 + if (access_ok(src, len)) 57 + return csum_partial_copy_generic((__force const void *)src, dst, 56 58 len, sum, err_ptr, NULL); 59 + if (len) 60 + *err_ptr = -EFAULT; 61 + return sum; 57 62 } 58 63 59 64 /*
+1
arch/sparc/include/asm/checksum.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0 */ 2 2 #ifndef ___ASM_SPARC_CHECKSUM_H 3 3 #define ___ASM_SPARC_CHECKSUM_H 4 + #define _HAVE_ARCH_COPY_AND_CSUM_FROM_USER 4 5 #if defined(__sparc__) && defined(__arch64__) 5 6 #include <asm/checksum_64.h> 6 7 #else
+10 -5
arch/sparc/include/asm/checksum_32.h
··· 60 60 } 61 61 62 62 static inline __wsum 63 - csum_partial_copy_from_user(const void __user *src, void *dst, int len, 63 + csum_and_copy_from_user(const void __user *src, void *dst, int len, 64 64 __wsum sum, int *err) 65 65 { 66 66 register unsigned long ret asm("o0") = (unsigned long)src; 67 67 register char *d asm("o1") = dst; 68 68 register int l asm("g1") = len; 69 69 register __wsum s asm("g7") = sum; 70 + 71 + if (unlikely(!access_ok(src, len))) { 72 + if (len) 73 + *err = -EFAULT; 74 + return sum; 75 + } 70 76 71 77 __asm__ __volatile__ ( 72 78 ".section __ex_table,#alloc\n\t" ··· 89 83 return (__force __wsum)ret; 90 84 } 91 85 86 + #define HAVE_CSUM_COPY_USER 87 + 92 88 static inline __wsum 93 - csum_partial_copy_to_user(const void *src, void __user *dst, int len, 89 + csum_and_copy_to_user(const void *src, void __user *dst, int len, 94 90 __wsum sum, int *err) 95 91 { 96 92 if (!access_ok(dst, len)) { ··· 120 112 return (__force __wsum)ret; 121 113 } 122 114 } 123 - 124 - #define HAVE_CSUM_COPY_USER 125 - #define csum_and_copy_to_user csum_partial_copy_to_user 126 115 127 116 /* ihl is always 5 or greater, almost always is 5, and iph is word aligned 128 117 * the majority of the time.
+1 -1
arch/sparc/include/asm/checksum_64.h
··· 46 46 __wsum sum); 47 47 48 48 static inline __wsum 49 - csum_partial_copy_from_user(const void __user *src, 49 + csum_and_copy_from_user(const void __user *src, 50 50 void *dst, int len, 51 51 __wsum sum, int *err) 52 52 {
+2
arch/x86/include/asm/checksum.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0 */ 2 + #define _HAVE_ARCH_COPY_AND_CSUM_FROM_USER 1 3 + #define HAVE_CSUM_COPY_USER 2 4 #ifdef CONFIG_X86_32 3 5 # include <asm/checksum_32.h> 4 6 #else
+11 -10
arch/x86/include/asm/checksum_32.h
··· 44 44 return csum_partial_copy_generic(src, dst, len, sum, NULL, NULL); 45 45 } 46 46 47 - static inline __wsum csum_partial_copy_from_user(const void __user *src, 48 - void *dst, 49 - int len, __wsum sum, 50 - int *err_ptr) 47 + static inline __wsum csum_and_copy_from_user(const void __user *src, 48 + void *dst, int len, 49 + __wsum sum, int *err_ptr) 51 50 { 52 51 __wsum ret; 53 52 54 53 might_sleep(); 55 - stac(); 54 + if (!user_access_begin(src, len)) { 55 + if (len) 56 + *err_ptr = -EFAULT; 57 + return sum; 58 + } 56 59 ret = csum_partial_copy_generic((__force void *)src, dst, 57 60 len, sum, err_ptr, NULL); 58 - clac(); 61 + user_access_end(); 59 62 60 63 return ret; 61 64 } ··· 176 173 /* 177 174 * Copy and checksum to user 178 175 */ 179 - #define HAVE_CSUM_COPY_USER 180 176 static inline __wsum csum_and_copy_to_user(const void *src, 181 177 void __user *dst, 182 178 int len, __wsum sum, ··· 184 182 __wsum ret; 185 183 186 184 might_sleep(); 187 - if (access_ok(dst, len)) { 188 - stac(); 185 + if (user_access_begin(dst, len)) { 189 186 ret = csum_partial_copy_generic(src, (__force void *)dst, 190 187 len, sum, NULL, err_ptr); 191 - clac(); 188 + user_access_end(); 192 189 return ret; 193 190 } 194 191
+2 -10
arch/x86/include/asm/checksum_64.h
··· 129 129 */ 130 130 extern __wsum csum_partial(const void *buff, int len, __wsum sum); 131 131 132 - #define _HAVE_ARCH_COPY_AND_CSUM_FROM_USER 1 133 - #define HAVE_CSUM_COPY_USER 1 134 - 135 - 136 132 /* Do not call this directly. Use the wrappers below */ 137 133 extern __visible __wsum csum_partial_copy_generic(const void *src, const void *dst, 138 134 int len, __wsum sum, 139 135 int *src_err_ptr, int *dst_err_ptr); 140 136 141 137 142 - extern __wsum csum_partial_copy_from_user(const void __user *src, void *dst, 138 + extern __wsum csum_and_copy_from_user(const void __user *src, void *dst, 143 139 int len, __wsum isum, int *errp); 144 - extern __wsum csum_partial_copy_to_user(const void *src, void __user *dst, 140 + extern __wsum csum_and_copy_to_user(const void *src, void __user *dst, 145 141 int len, __wsum isum, int *errp); 146 142 extern __wsum csum_partial_copy_nocheck(const void *src, void *dst, 147 143 int len, __wsum sum); 148 - 149 - /* Old names. To be removed. */ 150 - #define csum_and_copy_to_user csum_partial_copy_to_user 151 - #define csum_and_copy_from_user csum_partial_copy_from_user 152 144 153 145 /** 154 146 * ip_compute_csum - Compute an 16bit IP checksum.
+18 -17
arch/x86/lib/csum-wrappers_64.c
··· 10 10 #include <asm/smap.h> 11 11 12 12 /** 13 - * csum_partial_copy_from_user - Copy and checksum from user space. 13 + * csum_and_copy_from_user - Copy and checksum from user space. 14 14 * @src: source address (user space) 15 15 * @dst: destination address 16 16 * @len: number of bytes to be copied. ··· 21 21 * src and dst are best aligned to 64bits. 22 22 */ 23 23 __wsum 24 - csum_partial_copy_from_user(const void __user *src, void *dst, 24 + csum_and_copy_from_user(const void __user *src, void *dst, 25 25 int len, __wsum isum, int *errp) 26 26 { 27 27 might_sleep(); 28 28 *errp = 0; 29 29 30 - if (!likely(access_ok(src, len))) 30 + if (!user_access_begin(src, len)) 31 31 goto out_err; 32 32 33 33 /* ··· 42 42 while (((unsigned long)src & 6) && len >= 2) { 43 43 __u16 val16; 44 44 45 - if (__get_user(val16, (const __u16 __user *)src)) 46 - goto out_err; 45 + unsafe_get_user(val16, (const __u16 __user *)src, out); 47 46 48 47 *(__u16 *)dst = val16; 49 48 isum = (__force __wsum)add32_with_carry( ··· 52 53 len -= 2; 53 54 } 54 55 } 55 - stac(); 56 56 isum = csum_partial_copy_generic((__force const void *)src, 57 57 dst, len, isum, errp, NULL); 58 - clac(); 58 + user_access_end(); 59 59 if (unlikely(*errp)) 60 60 goto out_err; 61 61 62 62 return isum; 63 63 64 + out: 65 + user_access_end(); 64 66 out_err: 65 67 *errp = -EFAULT; 66 68 memset(dst, 0, len); 67 69 68 70 return isum; 69 71 } 70 - EXPORT_SYMBOL(csum_partial_copy_from_user); 72 + EXPORT_SYMBOL(csum_and_copy_from_user); 71 73 72 74 /** 73 - * csum_partial_copy_to_user - Copy and checksum to user space. 75 + * csum_and_copy_to_user - Copy and checksum to user space. 74 76 * @src: source address 75 77 * @dst: destination address (user space) 76 78 * @len: number of bytes to be copied. ··· 82 82 * src and dst are best aligned to 64bits. 83 83 */ 84 84 __wsum 85 - csum_partial_copy_to_user(const void *src, void __user *dst, 85 + csum_and_copy_to_user(const void *src, void __user *dst, 86 86 int len, __wsum isum, int *errp) 87 87 { 88 88 __wsum ret; 89 89 90 90 might_sleep(); 91 91 92 - if (unlikely(!access_ok(dst, len))) { 92 + if (!user_access_begin(dst, len)) { 93 93 *errp = -EFAULT; 94 94 return 0; 95 95 } ··· 100 100 101 101 isum = (__force __wsum)add32_with_carry( 102 102 (__force unsigned)isum, val16); 103 - *errp = __put_user(val16, (__u16 __user *)dst); 104 - if (*errp) 105 - return isum; 103 + unsafe_put_user(val16, (__u16 __user *)dst, out); 106 104 src += 2; 107 105 dst += 2; 108 106 len -= 2; ··· 108 110 } 109 111 110 112 *errp = 0; 111 - stac(); 112 113 ret = csum_partial_copy_generic(src, (void __force *)dst, 113 114 len, isum, NULL, errp); 114 - clac(); 115 + user_access_end(); 115 116 return ret; 117 + out: 118 + user_access_end(); 119 + *errp = -EFAULT; 120 + return isum; 116 121 } 117 - EXPORT_SYMBOL(csum_partial_copy_to_user); 122 + EXPORT_SYMBOL(csum_and_copy_to_user); 118 123 119 124 /** 120 125 * csum_partial_copy_nocheck - Copy and checksum.
-20
arch/x86/um/asm/checksum.h
··· 36 36 return csum_partial(dst, len, sum); 37 37 } 38 38 39 - /* 40 - * the same as csum_partial, but copies from src while it 41 - * checksums, and handles user-space pointer exceptions correctly, when needed. 42 - * 43 - * here even more important to align src and dst on a 32-bit (or even 44 - * better 64-bit) boundary 45 - */ 46 - 47 - static __inline__ 48 - __wsum csum_partial_copy_from_user(const void __user *src, void *dst, 49 - int len, __wsum sum, int *err_ptr) 50 - { 51 - if (copy_from_user(dst, src, len)) { 52 - *err_ptr = -EFAULT; 53 - return (__force __wsum)-1; 54 - } 55 - 56 - return csum_partial(dst, len, sum); 57 - } 58 - 59 39 /** 60 40 * csum_fold - Fold and invert a 32bit checksum. 61 41 * sum: 32bit unfolded sum
+7 -4
arch/xtensa/include/asm/checksum.h
··· 44 44 /* 45 45 * Note: when you get a NULL pointer exception here this means someone 46 46 * passed in an incorrect kernel address to one of these functions. 47 - * 48 - * If you use these functions directly please don't forget the access_ok(). 49 47 */ 50 48 static inline 51 49 __wsum csum_partial_copy_nocheck(const void *src, void *dst, ··· 52 54 return csum_partial_copy_generic(src, dst, len, sum, NULL, NULL); 53 55 } 54 56 57 + #define _HAVE_ARCH_COPY_AND_CSUM_FROM_USER 55 58 static inline 56 - __wsum csum_partial_copy_from_user(const void __user *src, void *dst, 59 + __wsum csum_and_copy_from_user(const void __user *src, void *dst, 57 60 int len, __wsum sum, int *err_ptr) 58 61 { 59 - return csum_partial_copy_generic((__force const void *)src, dst, 62 + if (access_ok(dst, len)) 63 + return csum_partial_copy_generic((__force const void *)src, dst, 60 64 len, sum, err_ptr, NULL); 65 + if (len) 66 + *err_ptr = -EFAULT; 67 + return sum; 61 68 } 62 69 63 70 /*
-9
include/asm-generic/checksum.h
··· 25 25 */ 26 26 extern __wsum csum_partial_copy(const void *src, void *dst, int len, __wsum sum); 27 27 28 - /* 29 - * the same as csum_partial_copy, but copies from user space. 30 - * 31 - * here even more important to align src and dst on a 32-bit (or even 32 - * better 64-bit) boundary 33 - */ 34 - extern __wsum csum_partial_copy_from_user(const void __user *src, void *dst, 35 - int len, __wsum sum, int *csum_err); 36 - 37 28 #ifndef csum_partial_copy_nocheck 38 29 #define csum_partial_copy_nocheck(src, dst, len, sum) \ 39 30 csum_partial_copy((src), (dst), (len), (sum))
+4 -10
include/net/checksum.h
··· 26 26 __wsum csum_and_copy_from_user (const void __user *src, void *dst, 27 27 int len, __wsum sum, int *err_ptr) 28 28 { 29 - if (access_ok(src, len)) 30 - return csum_partial_copy_from_user(src, dst, len, sum, err_ptr); 31 - 32 - if (len) 29 + if (copy_from_user(dst, src, len)) 33 30 *err_ptr = -EFAULT; 34 - 35 - return sum; 31 + return csum_partial(dst, len, sum); 36 32 } 37 33 #endif 38 34 ··· 38 42 { 39 43 sum = csum_partial(src, len, sum); 40 44 41 - if (access_ok(dst, len)) { 42 - if (copy_to_user(dst, src, len) == 0) 43 - return sum; 44 - } 45 + if (copy_to_user(dst, src, len) == 0) 46 + return sum; 45 47 if (len) 46 48 *err_ptr = -EFAULT; 47 49
-20
lib/checksum.c
··· 146 146 EXPORT_SYMBOL(ip_compute_csum); 147 147 148 148 /* 149 - * copy from fs while checksumming, otherwise like csum_partial 150 - */ 151 - __wsum 152 - csum_partial_copy_from_user(const void __user *src, void *dst, int len, 153 - __wsum sum, int *csum_err) 154 - { 155 - int missing; 156 - 157 - missing = __copy_from_user(dst, src, len); 158 - if (missing) { 159 - memset(dst + len - missing, 0, missing); 160 - *csum_err = -EFAULT; 161 - } else 162 - *csum_err = 0; 163 - 164 - return csum_partial(dst, len, sum); 165 - } 166 - EXPORT_SYMBOL(csum_partial_copy_from_user); 167 - 168 - /* 169 149 * copy from ds while checksumming, otherwise like csum_partial 170 150 */ 171 151 __wsum