diff options
author | Chris Mason <chris.mason@oracle.com> | 2009-01-05 16:57:23 -0500 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2009-01-05 16:57:23 -0500 |
commit | e441d54de4fd97dd381f3e73636f5ba51ff4c7d9 (patch) | |
tree | b0d664ffaa89cec80e6aaac11977c7f6aa92ff63 /fs/btrfs/ioctl.c | |
parent | b34b086c1c1d934c5314d46ba25ccfa9acc471ae (diff) |
Btrfs: add permission checks to the ioctls
Only root can add/remove devices
Only root can defrag subtrees
Only files open for writing can be defragged
Only files open for writing can be the destination for a clone
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/ioctl.c')
-rw-r--r-- | fs/btrfs/ioctl.c | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index ab429fe0fa0f..150784e936e6 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -453,6 +453,9 @@ static int btrfs_ioctl_resize(struct btrfs_root *root, void __user *arg) | |||
453 | if (root->fs_info->sb->s_flags & MS_RDONLY) | 453 | if (root->fs_info->sb->s_flags & MS_RDONLY) |
454 | return -EROFS; | 454 | return -EROFS; |
455 | 455 | ||
456 | if (!capable(CAP_SYS_ADMIN)) | ||
457 | return -EPERM; | ||
458 | |||
456 | vol_args = kmalloc(sizeof(*vol_args), GFP_NOFS); | 459 | vol_args = kmalloc(sizeof(*vol_args), GFP_NOFS); |
457 | 460 | ||
458 | if (!vol_args) | 461 | if (!vol_args) |
@@ -638,16 +641,24 @@ static int btrfs_ioctl_defrag(struct file *file) | |||
638 | 641 | ||
639 | switch (inode->i_mode & S_IFMT) { | 642 | switch (inode->i_mode & S_IFMT) { |
640 | case S_IFDIR: | 643 | case S_IFDIR: |
644 | if (!capable(CAP_SYS_ADMIN)) { | ||
645 | ret = -EPERM; | ||
646 | goto out; | ||
647 | } | ||
641 | btrfs_defrag_root(root, 0); | 648 | btrfs_defrag_root(root, 0); |
642 | btrfs_defrag_root(root->fs_info->extent_root, 0); | 649 | btrfs_defrag_root(root->fs_info->extent_root, 0); |
643 | break; | 650 | break; |
644 | case S_IFREG: | 651 | case S_IFREG: |
652 | if (!(file->f_mode & FMODE_WRITE)) { | ||
653 | ret = -EINVAL; | ||
654 | goto out; | ||
655 | } | ||
645 | btrfs_defrag_file(file); | 656 | btrfs_defrag_file(file); |
646 | break; | 657 | break; |
647 | } | 658 | } |
648 | 659 | out: | |
649 | mnt_drop_write(file->f_path.mnt); | 660 | mnt_drop_write(file->f_path.mnt); |
650 | return 0; | 661 | return ret; |
651 | } | 662 | } |
652 | 663 | ||
653 | static long btrfs_ioctl_add_dev(struct btrfs_root *root, void __user *arg) | 664 | static long btrfs_ioctl_add_dev(struct btrfs_root *root, void __user *arg) |
@@ -655,6 +666,9 @@ static long btrfs_ioctl_add_dev(struct btrfs_root *root, void __user *arg) | |||
655 | struct btrfs_ioctl_vol_args *vol_args; | 666 | struct btrfs_ioctl_vol_args *vol_args; |
656 | int ret; | 667 | int ret; |
657 | 668 | ||
669 | if (!capable(CAP_SYS_ADMIN)) | ||
670 | return -EPERM; | ||
671 | |||
658 | vol_args = kmalloc(sizeof(*vol_args), GFP_NOFS); | 672 | vol_args = kmalloc(sizeof(*vol_args), GFP_NOFS); |
659 | 673 | ||
660 | if (!vol_args) | 674 | if (!vol_args) |
@@ -677,6 +691,9 @@ static long btrfs_ioctl_rm_dev(struct btrfs_root *root, void __user *arg) | |||
677 | struct btrfs_ioctl_vol_args *vol_args; | 691 | struct btrfs_ioctl_vol_args *vol_args; |
678 | int ret; | 692 | int ret; |
679 | 693 | ||
694 | if (!capable(CAP_SYS_ADMIN)) | ||
695 | return -EPERM; | ||
696 | |||
680 | if (root->fs_info->sb->s_flags & MS_RDONLY) | 697 | if (root->fs_info->sb->s_flags & MS_RDONLY) |
681 | return -EROFS; | 698 | return -EROFS; |
682 | 699 | ||
@@ -726,6 +743,10 @@ static long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | |||
726 | * they don't overlap)? | 743 | * they don't overlap)? |
727 | */ | 744 | */ |
728 | 745 | ||
746 | /* the destination must be opened for writing */ | ||
747 | if (!(file->f_mode & FMODE_WRITE)) | ||
748 | return -EINVAL; | ||
749 | |||
729 | ret = mnt_want_write(file->f_path.mnt); | 750 | ret = mnt_want_write(file->f_path.mnt); |
730 | if (ret) | 751 | if (ret) |
731 | return ret; | 752 | return ret; |