aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2016-08-21 22:30:44 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2016-09-13 17:50:14 -0400
commitb615e3c74621e06cd97f86373ca90d43d6d998aa (patch)
tree48fd1de339d3af1f5a1fd2e829419ea814b03add
parentc2f18fa4cbb3ad92e033a24efa27583978ce9600 (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.h41
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);
301static inline unsigned long 301static inline unsigned long
302copy_from_user(void *to, const void *from, unsigned long len) 302copy_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
316static inline unsigned long 315static inline unsigned long
317copy_to_user(void *to, const void *from, unsigned long len) 316copy_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) \ 324static 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)
343static inline unsigned long 342static 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
351static inline unsigned long 350static inline unsigned long
352copy_in_user(void *to, const void *from, unsigned long len) 351copy_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/*