diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2017-06-26 23:51:31 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2017-06-26 23:52:44 -0400 |
commit | 8c6657cb50cb037ff58b3f6a547c6569568f3527 (patch) | |
tree | 05c9742b1e1cbaabf4571ae40105d1d1c60b2957 /fs/fcntl.c | |
parent | ca1579f6c6085ecb1838d9ee052e535682cc0e73 (diff) |
Switch flock copyin/copyout primitives to copy_{from,to}_user()
... and lose HAVE_ARCH_...; if copy_{to,from}_user() on an
architecture sucks badly enough to make it a problem, we have
a worse problem.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/fcntl.c')
-rw-r--r-- | fs/fcntl.c | 59 |
1 files changed, 29 insertions, 30 deletions
diff --git a/fs/fcntl.c b/fs/fcntl.c index afed3b364979..f525bc75c07d 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c | |||
@@ -452,57 +452,56 @@ out: | |||
452 | #endif | 452 | #endif |
453 | 453 | ||
454 | #ifdef CONFIG_COMPAT | 454 | #ifdef CONFIG_COMPAT |
455 | /* careful - don't use anywhere else */ | ||
456 | #define copy_flock_fields(from, to) \ | ||
457 | (to).l_type = (from).l_type; \ | ||
458 | (to).l_whence = (from).l_whence; \ | ||
459 | (to).l_start = (from).l_start; \ | ||
460 | (to).l_len = (from).l_len; \ | ||
461 | (to).l_pid = (from).l_pid; | ||
462 | |||
455 | static int get_compat_flock(struct flock *kfl, struct compat_flock __user *ufl) | 463 | static int get_compat_flock(struct flock *kfl, struct compat_flock __user *ufl) |
456 | { | 464 | { |
457 | if (!access_ok(VERIFY_READ, ufl, sizeof(*ufl)) || | 465 | struct compat_flock fl; |
458 | __get_user(kfl->l_type, &ufl->l_type) || | 466 | |
459 | __get_user(kfl->l_whence, &ufl->l_whence) || | 467 | if (copy_from_user(&fl, ufl, sizeof(struct compat_flock))) |
460 | __get_user(kfl->l_start, &ufl->l_start) || | ||
461 | __get_user(kfl->l_len, &ufl->l_len) || | ||
462 | __get_user(kfl->l_pid, &ufl->l_pid)) | ||
463 | return -EFAULT; | 468 | return -EFAULT; |
469 | copy_flock_fields(*kfl, fl); | ||
464 | return 0; | 470 | return 0; |
465 | } | 471 | } |
466 | 472 | ||
467 | static int put_compat_flock(struct flock *kfl, struct compat_flock __user *ufl) | 473 | static int get_compat_flock64(struct flock *kfl, struct compat_flock64 __user *ufl) |
468 | { | 474 | { |
469 | if (!access_ok(VERIFY_WRITE, ufl, sizeof(*ufl)) || | 475 | struct compat_flock64 fl; |
470 | __put_user(kfl->l_type, &ufl->l_type) || | 476 | |
471 | __put_user(kfl->l_whence, &ufl->l_whence) || | 477 | if (copy_from_user(&fl, ufl, sizeof(struct compat_flock64))) |
472 | __put_user(kfl->l_start, &ufl->l_start) || | ||
473 | __put_user(kfl->l_len, &ufl->l_len) || | ||
474 | __put_user(kfl->l_pid, &ufl->l_pid)) | ||
475 | return -EFAULT; | 478 | return -EFAULT; |
479 | copy_flock_fields(*kfl, fl); | ||
476 | return 0; | 480 | return 0; |
477 | } | 481 | } |
478 | 482 | ||
479 | #ifndef HAVE_ARCH_GET_COMPAT_FLOCK64 | 483 | static int put_compat_flock(struct flock *kfl, struct compat_flock __user *ufl) |
480 | static int get_compat_flock64(struct flock *kfl, struct compat_flock64 __user *ufl) | ||
481 | { | 484 | { |
482 | if (!access_ok(VERIFY_READ, ufl, sizeof(*ufl)) || | 485 | struct compat_flock fl; |
483 | __get_user(kfl->l_type, &ufl->l_type) || | 486 | |
484 | __get_user(kfl->l_whence, &ufl->l_whence) || | 487 | memset(&fl, 0, sizeof(struct compat_flock)); |
485 | __get_user(kfl->l_start, &ufl->l_start) || | 488 | copy_flock_fields(fl, *kfl); |
486 | __get_user(kfl->l_len, &ufl->l_len) || | 489 | if (copy_to_user(ufl, &fl, sizeof(struct compat_flock))) |
487 | __get_user(kfl->l_pid, &ufl->l_pid)) | ||
488 | return -EFAULT; | 490 | return -EFAULT; |
489 | return 0; | 491 | return 0; |
490 | } | 492 | } |
491 | #endif | ||
492 | 493 | ||
493 | #ifndef HAVE_ARCH_PUT_COMPAT_FLOCK64 | ||
494 | static int put_compat_flock64(struct flock *kfl, struct compat_flock64 __user *ufl) | 494 | static int put_compat_flock64(struct flock *kfl, struct compat_flock64 __user *ufl) |
495 | { | 495 | { |
496 | if (!access_ok(VERIFY_WRITE, ufl, sizeof(*ufl)) || | 496 | struct compat_flock64 fl; |
497 | __put_user(kfl->l_type, &ufl->l_type) || | 497 | |
498 | __put_user(kfl->l_whence, &ufl->l_whence) || | 498 | memset(&fl, 0, sizeof(struct compat_flock64)); |
499 | __put_user(kfl->l_start, &ufl->l_start) || | 499 | copy_flock_fields(fl, *kfl); |
500 | __put_user(kfl->l_len, &ufl->l_len) || | 500 | if (copy_to_user(ufl, &fl, sizeof(struct compat_flock64))) |
501 | __put_user(kfl->l_pid, &ufl->l_pid)) | ||
502 | return -EFAULT; | 501 | return -EFAULT; |
503 | return 0; | 502 | return 0; |
504 | } | 503 | } |
505 | #endif | 504 | #undef copy_flock_fields |
506 | 505 | ||
507 | static unsigned int | 506 | static unsigned int |
508 | convert_fcntl_cmd(unsigned int cmd) | 507 | convert_fcntl_cmd(unsigned int cmd) |