aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/ioctl.c49
-rw-r--r--fs/btrfs/super.c25
2 files changed, 20 insertions, 54 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index db84aa48ab7a..2624b53ea783 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -457,15 +457,9 @@ static int btrfs_ioctl_resize(struct btrfs_root *root, void __user *arg)
457 if (!capable(CAP_SYS_ADMIN)) 457 if (!capable(CAP_SYS_ADMIN))
458 return -EPERM; 458 return -EPERM;
459 459
460 vol_args = kmalloc(sizeof(*vol_args), GFP_NOFS); 460 vol_args = memdup_user(arg, sizeof(*vol_args));
461 461 if (IS_ERR(vol_args))
462 if (!vol_args) 462 return PTR_ERR(vol_args);
463 return -ENOMEM;
464
465 if (copy_from_user(vol_args, arg, sizeof(*vol_args))) {
466 ret = -EFAULT;
467 goto out;
468 }
469 463
470 vol_args->name[BTRFS_PATH_NAME_MAX] = '\0'; 464 vol_args->name[BTRFS_PATH_NAME_MAX] = '\0';
471 namelen = strlen(vol_args->name); 465 namelen = strlen(vol_args->name);
@@ -543,7 +537,6 @@ static int btrfs_ioctl_resize(struct btrfs_root *root, void __user *arg)
543 537
544out_unlock: 538out_unlock:
545 mutex_unlock(&root->fs_info->volume_mutex); 539 mutex_unlock(&root->fs_info->volume_mutex);
546out:
547 kfree(vol_args); 540 kfree(vol_args);
548 return ret; 541 return ret;
549} 542}
@@ -563,15 +556,9 @@ static noinline int btrfs_ioctl_snap_create(struct file *file,
563 if (root->fs_info->sb->s_flags & MS_RDONLY) 556 if (root->fs_info->sb->s_flags & MS_RDONLY)
564 return -EROFS; 557 return -EROFS;
565 558
566 vol_args = kmalloc(sizeof(*vol_args), GFP_NOFS); 559 vol_args = memdup_user(arg, sizeof(*vol_args));
567 560 if (IS_ERR(vol_args))
568 if (!vol_args) 561 return PTR_ERR(vol_args);
569 return -ENOMEM;
570
571 if (copy_from_user(vol_args, arg, sizeof(*vol_args))) {
572 ret = -EFAULT;
573 goto out;
574 }
575 562
576 vol_args->name[BTRFS_PATH_NAME_MAX] = '\0'; 563 vol_args->name[BTRFS_PATH_NAME_MAX] = '\0';
577 namelen = strlen(vol_args->name); 564 namelen = strlen(vol_args->name);
@@ -673,19 +660,13 @@ static long btrfs_ioctl_add_dev(struct btrfs_root *root, void __user *arg)
673 if (!capable(CAP_SYS_ADMIN)) 660 if (!capable(CAP_SYS_ADMIN))
674 return -EPERM; 661 return -EPERM;
675 662
676 vol_args = kmalloc(sizeof(*vol_args), GFP_NOFS); 663 vol_args = memdup_user(arg, sizeof(*vol_args));
664 if (IS_ERR(vol_args))
665 return PTR_ERR(vol_args);
677 666
678 if (!vol_args)
679 return -ENOMEM;
680
681 if (copy_from_user(vol_args, arg, sizeof(*vol_args))) {
682 ret = -EFAULT;
683 goto out;
684 }
685 vol_args->name[BTRFS_PATH_NAME_MAX] = '\0'; 667 vol_args->name[BTRFS_PATH_NAME_MAX] = '\0';
686 ret = btrfs_init_new_device(root, vol_args->name); 668 ret = btrfs_init_new_device(root, vol_args->name);
687 669
688out:
689 kfree(vol_args); 670 kfree(vol_args);
690 return ret; 671 return ret;
691} 672}
@@ -701,19 +682,13 @@ static long btrfs_ioctl_rm_dev(struct btrfs_root *root, void __user *arg)
701 if (root->fs_info->sb->s_flags & MS_RDONLY) 682 if (root->fs_info->sb->s_flags & MS_RDONLY)
702 return -EROFS; 683 return -EROFS;
703 684
704 vol_args = kmalloc(sizeof(*vol_args), GFP_NOFS); 685 vol_args = memdup_user(arg, sizeof(*vol_args));
686 if (IS_ERR(vol_args))
687 return PTR_ERR(vol_args);
705 688
706 if (!vol_args)
707 return -ENOMEM;
708
709 if (copy_from_user(vol_args, arg, sizeof(*vol_args))) {
710 ret = -EFAULT;
711 goto out;
712 }
713 vol_args->name[BTRFS_PATH_NAME_MAX] = '\0'; 689 vol_args->name[BTRFS_PATH_NAME_MAX] = '\0';
714 ret = btrfs_rm_device(root, vol_args->name); 690 ret = btrfs_rm_device(root, vol_args->name);
715 691
716out:
717 kfree(vol_args); 692 kfree(vol_args);
718 return ret; 693 return ret;
719} 694}
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index e99510bfbffd..2ff7cd2db25f 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -502,8 +502,7 @@ static int btrfs_get_sb(struct file_system_type *fs_type, int flags,
502 502
503 if (s->s_root) { 503 if (s->s_root) {
504 if ((flags ^ s->s_flags) & MS_RDONLY) { 504 if ((flags ^ s->s_flags) & MS_RDONLY) {
505 up_write(&s->s_umount); 505 deactivate_locked_super(s);
506 deactivate_super(s);
507 error = -EBUSY; 506 error = -EBUSY;
508 goto error_close_devices; 507 goto error_close_devices;
509 } 508 }
@@ -517,8 +516,7 @@ static int btrfs_get_sb(struct file_system_type *fs_type, int flags,
517 error = btrfs_fill_super(s, fs_devices, data, 516 error = btrfs_fill_super(s, fs_devices, data,
518 flags & MS_SILENT ? 1 : 0); 517 flags & MS_SILENT ? 1 : 0);
519 if (error) { 518 if (error) {
520 up_write(&s->s_umount); 519 deactivate_locked_super(s);
521 deactivate_super(s);
522 goto error_free_subvol_name; 520 goto error_free_subvol_name;
523 } 521 }
524 522
@@ -535,15 +533,13 @@ static int btrfs_get_sb(struct file_system_type *fs_type, int flags,
535 mutex_unlock(&s->s_root->d_inode->i_mutex); 533 mutex_unlock(&s->s_root->d_inode->i_mutex);
536 534
537 if (IS_ERR(root)) { 535 if (IS_ERR(root)) {
538 up_write(&s->s_umount); 536 deactivate_locked_super(s);
539 deactivate_super(s);
540 error = PTR_ERR(root); 537 error = PTR_ERR(root);
541 goto error_free_subvol_name; 538 goto error_free_subvol_name;
542 } 539 }
543 if (!root->d_inode) { 540 if (!root->d_inode) {
544 dput(root); 541 dput(root);
545 up_write(&s->s_umount); 542 deactivate_locked_super(s);
546 deactivate_super(s);
547 error = -ENXIO; 543 error = -ENXIO;
548 goto error_free_subvol_name; 544 goto error_free_subvol_name;
549 } 545 }
@@ -648,14 +644,9 @@ static long btrfs_control_ioctl(struct file *file, unsigned int cmd,
648 if (!capable(CAP_SYS_ADMIN)) 644 if (!capable(CAP_SYS_ADMIN))
649 return -EPERM; 645 return -EPERM;
650 646
651 vol = kmalloc(sizeof(*vol), GFP_KERNEL); 647 vol = memdup_user((void __user *)arg, sizeof(*vol));
652 if (!vol) 648 if (IS_ERR(vol))
653 return -ENOMEM; 649 return PTR_ERR(vol);
654
655 if (copy_from_user(vol, (void __user *)arg, sizeof(*vol))) {
656 ret = -EFAULT;
657 goto out;
658 }
659 650
660 switch (cmd) { 651 switch (cmd) {
661 case BTRFS_IOC_SCAN_DEV: 652 case BTRFS_IOC_SCAN_DEV:
@@ -663,7 +654,7 @@ static long btrfs_control_ioctl(struct file *file, unsigned int cmd,
663 &btrfs_fs_type, &fs_devices); 654 &btrfs_fs_type, &fs_devices);
664 break; 655 break;
665 } 656 }
666out: 657
667 kfree(vol); 658 kfree(vol);
668 return ret; 659 return ret;
669} 660}