diff options
Diffstat (limited to 'arch/x86/lib/usercopy.c')
-rw-r--r-- | arch/x86/lib/usercopy.c | 20 |
1 files changed, 8 insertions, 12 deletions
diff --git a/arch/x86/lib/usercopy.c b/arch/x86/lib/usercopy.c index d6ae30bbd7bb..2e4e4b02c37a 100644 --- a/arch/x86/lib/usercopy.c +++ b/arch/x86/lib/usercopy.c | |||
@@ -44,13 +44,6 @@ copy_from_user_nmi(void *to, const void __user *from, unsigned long n) | |||
44 | } | 44 | } |
45 | EXPORT_SYMBOL_GPL(copy_from_user_nmi); | 45 | EXPORT_SYMBOL_GPL(copy_from_user_nmi); |
46 | 46 | ||
47 | static inline unsigned long count_bytes(unsigned long mask) | ||
48 | { | ||
49 | mask = (mask - 1) & ~mask; | ||
50 | mask >>= 7; | ||
51 | return count_masked_bytes(mask); | ||
52 | } | ||
53 | |||
54 | /* | 47 | /* |
55 | * Do a strncpy, return length of string without final '\0'. | 48 | * Do a strncpy, return length of string without final '\0'. |
56 | * 'count' is the user-supplied count (return 'count' if we | 49 | * 'count' is the user-supplied count (return 'count' if we |
@@ -69,16 +62,19 @@ static inline long do_strncpy_from_user(char *dst, const char __user *src, long | |||
69 | max = count; | 62 | max = count; |
70 | 63 | ||
71 | while (max >= sizeof(unsigned long)) { | 64 | while (max >= sizeof(unsigned long)) { |
72 | unsigned long c; | 65 | unsigned long c, mask; |
73 | 66 | ||
74 | /* Fall back to byte-at-a-time if we get a page fault */ | 67 | /* Fall back to byte-at-a-time if we get a page fault */ |
75 | if (unlikely(__get_user(c,(unsigned long __user *)(src+res)))) | 68 | if (unlikely(__get_user(c,(unsigned long __user *)(src+res)))) |
76 | break; | 69 | break; |
77 | /* This can write a few bytes past the NUL character, but that's ok */ | 70 | mask = has_zero(c); |
71 | if (mask) { | ||
72 | mask = (mask - 1) & ~mask; | ||
73 | mask >>= 7; | ||
74 | *(unsigned long *)(dst+res) = c & mask; | ||
75 | return res + count_masked_bytes(mask); | ||
76 | } | ||
78 | *(unsigned long *)(dst+res) = c; | 77 | *(unsigned long *)(dst+res) = c; |
79 | c = has_zero(c); | ||
80 | if (c) | ||
81 | return res + count_bytes(c); | ||
82 | res += sizeof(unsigned long); | 78 | res += sizeof(unsigned long); |
83 | max -= sizeof(unsigned long); | 79 | max -= sizeof(unsigned long); |
84 | } | 80 | } |