* better 64-bit) boundary
*/
-asmlinkage unsigned int csum_partial_copy_generic( const char *src, char *dst, int len, int sum,
+asmlinkage unsigned int direct_csum_partial_copy_generic( const char *src, char *dst, int len, int sum,
int *src_err_ptr, int *dst_err_ptr);
/*
unsigned int csum_partial_copy_nocheck ( const char *src, char *dst,
int len, int sum)
{
- return csum_partial_copy_generic ( src, dst, len, sum, NULL, NULL);
+ /*
+ * The direct function is OK for kernel-space => kernel-space copies:
+ */
+ return direct_csum_partial_copy_generic ( src, dst, len, sum, NULL, NULL);
}
static __inline__
unsigned int csum_partial_copy_from_user ( const char __user *src, char *dst,
int len, int sum, int *err_ptr)
{
- return csum_partial_copy_generic ( (__force char *)src, dst, len, sum, err_ptr, NULL);
+ if (copy_from_user(dst, src, len))
+ *err_ptr = -EFAULT;
+ return csum_partial(dst, len, sum);
}
/*
* Copy and checksum to user
*/
#define HAVE_CSUM_COPY_USER
-static __inline__ unsigned int csum_and_copy_to_user(const char *src,
+static __inline__ unsigned int direct_csum_and_copy_to_user(const char *src,
char __user *dst,
int len, int sum,
int *err_ptr)
{
if (access_ok(VERIFY_WRITE, dst, len))
- return csum_partial_copy_generic(src, (__force char *)dst, len, sum, NULL, err_ptr);
+ return direct_csum_partial_copy_generic(src, dst, len, sum, NULL, err_ptr);
+
+ if (len)
+ *err_ptr = -EFAULT;
+
+ return -1; /* invalid checksum */
+}
+
+static __inline__ unsigned int csum_and_copy_to_user(const char *src, char __user *dst,
+ int len, int sum, int *err_ptr)
+{
+ if (access_ok(VERIFY_WRITE, dst, len)) {
+ if (copy_to_user(dst, src, len))
+ *err_ptr = -EFAULT;
+ return csum_partial(src, len, sum);
+ }
if (len)
*err_ptr = -EFAULT;