diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2016-08-21 22:30:44 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2016-09-13 17:50:14 -0400 |
commit | b615e3c74621e06cd97f86373ca90d43d6d998aa (patch) | |
tree | 48fd1de339d3af1f5a1fd2e829419ea814b03add | |
parent | c2f18fa4cbb3ad92e033a24efa27583978ce9600 (diff) |
score: fix copy_from_user() and friends
Cc: stable@vger.kernel.org
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | arch/score/include/asm/uaccess.h | 41 |
1 files changed, 20 insertions, 21 deletions
diff --git a/arch/score/include/asm/uaccess.h b/arch/score/include/asm/uaccess.h index c5d43111a5cc..01aec8ccde83 100644 --- a/arch/score/include/asm/uaccess.h +++ b/arch/score/include/asm/uaccess.h | |||
@@ -301,35 +301,34 @@ extern int __copy_tofrom_user(void *to, const void *from, unsigned long len); | |||
301 | static inline unsigned long | 301 | static inline unsigned long |
302 | copy_from_user(void *to, const void *from, unsigned long len) | 302 | copy_from_user(void *to, const void *from, unsigned long len) |
303 | { | 303 | { |
304 | unsigned long over; | 304 | unsigned long res = len; |
305 | 305 | ||
306 | if (access_ok(VERIFY_READ, from, len)) | 306 | if (likely(access_ok(VERIFY_READ, from, len))) |
307 | return __copy_tofrom_user(to, from, len); | 307 | res = __copy_tofrom_user(to, from, len); |
308 | 308 | ||
309 | if ((unsigned long)from < TASK_SIZE) { | 309 | if (unlikely(res)) |
310 | over = (unsigned long)from + len - TASK_SIZE; | 310 | memset(to + (len - res), 0, res); |
311 | return __copy_tofrom_user(to, from, len - over) + over; | 311 | |
312 | } | 312 | return res; |
313 | return len; | ||
314 | } | 313 | } |
315 | 314 | ||
316 | static inline unsigned long | 315 | static inline unsigned long |
317 | copy_to_user(void *to, const void *from, unsigned long len) | 316 | copy_to_user(void *to, const void *from, unsigned long len) |
318 | { | 317 | { |
319 | unsigned long over; | 318 | if (likely(access_ok(VERIFY_WRITE, to, len))) |
320 | 319 | len = __copy_tofrom_user(to, from, len); | |
321 | if (access_ok(VERIFY_WRITE, to, len)) | ||
322 | return __copy_tofrom_user(to, from, len); | ||
323 | 320 | ||
324 | if ((unsigned long)to < TASK_SIZE) { | ||
325 | over = (unsigned long)to + len - TASK_SIZE; | ||
326 | return __copy_tofrom_user(to, from, len - over) + over; | ||
327 | } | ||
328 | return len; | 321 | return len; |
329 | } | 322 | } |
330 | 323 | ||
331 | #define __copy_from_user(to, from, len) \ | 324 | static inline unsigned long |
332 | __copy_tofrom_user((to), (from), (len)) | 325 | __copy_from_user(void *to, const void *from, unsigned long len) |
326 | { | ||
327 | unsigned long left = __copy_tofrom_user(to, from, len); | ||
328 | if (unlikely(left)) | ||
329 | memset(to + (len - left), 0, left); | ||
330 | return left; | ||
331 | } | ||
333 | 332 | ||
334 | #define __copy_to_user(to, from, len) \ | 333 | #define __copy_to_user(to, from, len) \ |
335 | __copy_tofrom_user((to), (from), (len)) | 334 | __copy_tofrom_user((to), (from), (len)) |
@@ -343,17 +342,17 @@ __copy_to_user_inatomic(void *to, const void *from, unsigned long len) | |||
343 | static inline unsigned long | 342 | static inline unsigned long |
344 | __copy_from_user_inatomic(void *to, const void *from, unsigned long len) | 343 | __copy_from_user_inatomic(void *to, const void *from, unsigned long len) |
345 | { | 344 | { |
346 | return __copy_from_user(to, from, len); | 345 | return __copy_tofrom_user(to, from, len); |
347 | } | 346 | } |
348 | 347 | ||
349 | #define __copy_in_user(to, from, len) __copy_from_user(to, from, len) | 348 | #define __copy_in_user(to, from, len) __copy_tofrom_user(to, from, len) |
350 | 349 | ||
351 | static inline unsigned long | 350 | static inline unsigned long |
352 | copy_in_user(void *to, const void *from, unsigned long len) | 351 | copy_in_user(void *to, const void *from, unsigned long len) |
353 | { | 352 | { |
354 | if (access_ok(VERIFY_READ, from, len) && | 353 | if (access_ok(VERIFY_READ, from, len) && |
355 | access_ok(VERFITY_WRITE, to, len)) | 354 | access_ok(VERFITY_WRITE, to, len)) |
356 | return copy_from_user(to, from, len); | 355 | return __copy_tofrom_user(to, from, len); |
357 | } | 356 | } |
358 | 357 | ||
359 | /* | 358 | /* |