Loading arch/x86/include/asm/uaccess.h +12 −0 Original line number Diff line number Diff line Loading @@ -379,6 +379,18 @@ do { \ : "=r" (err), ltype(x) \ : "m" (__m(addr)), "i" (errret), "0" (err)) #define __get_user_asm_nozero(x, addr, err, itype, rtype, ltype, errret) \ asm volatile("\n" \ "1: mov"itype" %2,%"rtype"1\n" \ "2:\n" \ ".section .fixup,\"ax\"\n" \ "3: mov %3,%0\n" \ " jmp 2b\n" \ ".previous\n" \ _ASM_EXTABLE(1b, 3b) \ : "=r" (err), ltype(x) \ : "m" (__m(addr)), "i" (errret), "0" (err)) /* * This doesn't do __uaccess_begin/end - the exception handling * around it must do that. Loading arch/x86/include/asm/uaccess_64.h +8 −8 Original line number Diff line number Diff line Loading @@ -59,44 +59,44 @@ int __copy_from_user_nocheck(void *dst, const void __user *src, unsigned size) switch (size) { case 1: __uaccess_begin(); __get_user_asm(*(u8 *)dst, (u8 __user *)src, __get_user_asm_nozero(*(u8 *)dst, (u8 __user *)src, ret, "b", "b", "=q", 1); __uaccess_end(); return ret; case 2: __uaccess_begin(); __get_user_asm(*(u16 *)dst, (u16 __user *)src, __get_user_asm_nozero(*(u16 *)dst, (u16 __user *)src, ret, "w", "w", "=r", 2); __uaccess_end(); return ret; case 4: __uaccess_begin(); __get_user_asm(*(u32 *)dst, (u32 __user *)src, __get_user_asm_nozero(*(u32 *)dst, (u32 __user *)src, ret, "l", "k", "=r", 4); __uaccess_end(); return ret; case 8: __uaccess_begin(); __get_user_asm(*(u64 *)dst, (u64 __user *)src, __get_user_asm_nozero(*(u64 *)dst, (u64 __user *)src, ret, "q", "", "=r", 8); __uaccess_end(); return ret; case 10: __uaccess_begin(); __get_user_asm(*(u64 *)dst, (u64 __user *)src, __get_user_asm_nozero(*(u64 *)dst, (u64 __user *)src, ret, "q", "", "=r", 10); if (likely(!ret)) __get_user_asm(*(u16 *)(8 + (char *)dst), __get_user_asm_nozero(*(u16 *)(8 + (char *)dst), (u16 __user *)(8 + (char __user *)src), ret, "w", "w", "=r", 2); __uaccess_end(); return ret; case 16: __uaccess_begin(); __get_user_asm(*(u64 *)dst, (u64 __user *)src, __get_user_asm_nozero(*(u64 *)dst, (u64 __user *)src, ret, "q", "", "=r", 16); if (likely(!ret)) __get_user_asm(*(u64 *)(8 + (char *)dst), __get_user_asm_nozero(*(u64 *)(8 + (char *)dst), (u64 __user *)(8 + (char __user *)src), ret, "q", "", "=r", 8); __uaccess_end(); Loading arch/x86/lib/usercopy.c +5 −4 Original line number Diff line number Diff line Loading @@ -76,10 +76,11 @@ EXPORT_SYMBOL(_copy_to_user); */ unsigned long _copy_from_user(void *to, const void __user *from, unsigned n) { unsigned long res = n; if (access_ok(VERIFY_READ, from, n)) n = __copy_from_user(to, from, n); else memset(to, 0, n); return n; res = __copy_from_user_inatomic(to, from, n); if (unlikely(res)) memset(to + n - res, 0, res); return res; } EXPORT_SYMBOL(_copy_from_user); arch/x86/lib/usercopy_64.c +0 −4 Original line number Diff line number Diff line Loading @@ -80,9 +80,5 @@ copy_user_handle_tail(char *to, char *from, unsigned len) break; } clac(); /* If the destination is a kernel buffer, we always clear the end */ if (!__addr_ok(to)) memset(to, 0, len); return len; } Loading
arch/x86/include/asm/uaccess.h +12 −0 Original line number Diff line number Diff line Loading @@ -379,6 +379,18 @@ do { \ : "=r" (err), ltype(x) \ : "m" (__m(addr)), "i" (errret), "0" (err)) #define __get_user_asm_nozero(x, addr, err, itype, rtype, ltype, errret) \ asm volatile("\n" \ "1: mov"itype" %2,%"rtype"1\n" \ "2:\n" \ ".section .fixup,\"ax\"\n" \ "3: mov %3,%0\n" \ " jmp 2b\n" \ ".previous\n" \ _ASM_EXTABLE(1b, 3b) \ : "=r" (err), ltype(x) \ : "m" (__m(addr)), "i" (errret), "0" (err)) /* * This doesn't do __uaccess_begin/end - the exception handling * around it must do that. Loading
arch/x86/include/asm/uaccess_64.h +8 −8 Original line number Diff line number Diff line Loading @@ -59,44 +59,44 @@ int __copy_from_user_nocheck(void *dst, const void __user *src, unsigned size) switch (size) { case 1: __uaccess_begin(); __get_user_asm(*(u8 *)dst, (u8 __user *)src, __get_user_asm_nozero(*(u8 *)dst, (u8 __user *)src, ret, "b", "b", "=q", 1); __uaccess_end(); return ret; case 2: __uaccess_begin(); __get_user_asm(*(u16 *)dst, (u16 __user *)src, __get_user_asm_nozero(*(u16 *)dst, (u16 __user *)src, ret, "w", "w", "=r", 2); __uaccess_end(); return ret; case 4: __uaccess_begin(); __get_user_asm(*(u32 *)dst, (u32 __user *)src, __get_user_asm_nozero(*(u32 *)dst, (u32 __user *)src, ret, "l", "k", "=r", 4); __uaccess_end(); return ret; case 8: __uaccess_begin(); __get_user_asm(*(u64 *)dst, (u64 __user *)src, __get_user_asm_nozero(*(u64 *)dst, (u64 __user *)src, ret, "q", "", "=r", 8); __uaccess_end(); return ret; case 10: __uaccess_begin(); __get_user_asm(*(u64 *)dst, (u64 __user *)src, __get_user_asm_nozero(*(u64 *)dst, (u64 __user *)src, ret, "q", "", "=r", 10); if (likely(!ret)) __get_user_asm(*(u16 *)(8 + (char *)dst), __get_user_asm_nozero(*(u16 *)(8 + (char *)dst), (u16 __user *)(8 + (char __user *)src), ret, "w", "w", "=r", 2); __uaccess_end(); return ret; case 16: __uaccess_begin(); __get_user_asm(*(u64 *)dst, (u64 __user *)src, __get_user_asm_nozero(*(u64 *)dst, (u64 __user *)src, ret, "q", "", "=r", 16); if (likely(!ret)) __get_user_asm(*(u64 *)(8 + (char *)dst), __get_user_asm_nozero(*(u64 *)(8 + (char *)dst), (u64 __user *)(8 + (char __user *)src), ret, "q", "", "=r", 8); __uaccess_end(); Loading
arch/x86/lib/usercopy.c +5 −4 Original line number Diff line number Diff line Loading @@ -76,10 +76,11 @@ EXPORT_SYMBOL(_copy_to_user); */ unsigned long _copy_from_user(void *to, const void __user *from, unsigned n) { unsigned long res = n; if (access_ok(VERIFY_READ, from, n)) n = __copy_from_user(to, from, n); else memset(to, 0, n); return n; res = __copy_from_user_inatomic(to, from, n); if (unlikely(res)) memset(to + n - res, 0, res); return res; } EXPORT_SYMBOL(_copy_from_user);
arch/x86/lib/usercopy_64.c +0 −4 Original line number Diff line number Diff line Loading @@ -80,9 +80,5 @@ copy_user_handle_tail(char *to, char *from, unsigned len) break; } clac(); /* If the destination is a kernel buffer, we always clear the end */ if (!__addr_ok(to)) memset(to, 0, len); return len; }