aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2016-08-20 17:05:21 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2016-09-13 17:49:44 -0400
commitacb2505d0119033a80c85ac8d02dccae41271667 (patch)
tree5537954675e9bd923ab1bfe1fea29806e6334ae6
parent2e29f50ad5e23db37dde9be71410d95d50241ecd (diff)
openrisc: fix copy_from_user()
... that should zero on faults. Also remove the <censored> helpful logics wrt range truncation copied from ppc32. Where it had ever been needed only in case of copy_from_user() *and* had not been merged into the mainline until a month after the need had disappeared. A decade before openrisc went into mainline, I might add... Cc: stable@vger.kernel.org Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--arch/openrisc/include/asm/uaccess.h35
1 files changed, 11 insertions, 24 deletions
diff --git a/arch/openrisc/include/asm/uaccess.h b/arch/openrisc/include/asm/uaccess.h
index a6bd07ca3d6c..cbad29b5a131 100644
--- a/arch/openrisc/include/asm/uaccess.h
+++ b/arch/openrisc/include/asm/uaccess.h
@@ -273,28 +273,20 @@ __copy_tofrom_user(void *to, const void *from, unsigned long size);
273static inline unsigned long 273static inline unsigned long
274copy_from_user(void *to, const void *from, unsigned long n) 274copy_from_user(void *to, const void *from, unsigned long n)
275{ 275{
276 unsigned long over; 276 unsigned long res = n;
277 277
278 if (access_ok(VERIFY_READ, from, n)) 278 if (likely(access_ok(VERIFY_READ, from, n)))
279 return __copy_tofrom_user(to, from, n); 279 n = __copy_tofrom_user(to, from, n);
280 if ((unsigned long)from < TASK_SIZE) { 280 if (unlikely(res))
281 over = (unsigned long)from + n - TASK_SIZE; 281 memset(to + (n - res), 0, res);
282 return __copy_tofrom_user(to, from, n - over) + over; 282 return res;
283 }
284 return n;
285} 283}
286 284
287static inline unsigned long 285static inline unsigned long
288copy_to_user(void *to, const void *from, unsigned long n) 286copy_to_user(void *to, const void *from, unsigned long n)
289{ 287{
290 unsigned long over; 288 if (likely(access_ok(VERIFY_WRITE, to, n)))
291 289 n = __copy_tofrom_user(to, from, n);
292 if (access_ok(VERIFY_WRITE, to, n))
293 return __copy_tofrom_user(to, from, n);
294 if ((unsigned long)to < TASK_SIZE) {
295 over = (unsigned long)to + n - TASK_SIZE;
296 return __copy_tofrom_user(to, from, n - over) + over;
297 }
298 return n; 290 return n;
299} 291}
300 292
@@ -303,13 +295,8 @@ extern unsigned long __clear_user(void *addr, unsigned long size);
303static inline __must_check unsigned long 295static inline __must_check unsigned long
304clear_user(void *addr, unsigned long size) 296clear_user(void *addr, unsigned long size)
305{ 297{
306 298 if (likely(access_ok(VERIFY_WRITE, addr, size)))
307 if (access_ok(VERIFY_WRITE, addr, size)) 299 size = __clear_user(addr, size);
308 return __clear_user(addr, size);
309 if ((unsigned long)addr < TASK_SIZE) {
310 unsigned long over = (unsigned long)addr + size - TASK_SIZE;
311 return __clear_user(addr, size - over) + over;
312 }
313 return size; 300 return size;
314} 301}
315 302