aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2009-01-05 16:57:23 -0500
committerChris Mason <chris.mason@oracle.com>2009-01-05 16:57:23 -0500
commite441d54de4fd97dd381f3e73636f5ba51ff4c7d9 (patch)
treeb0d664ffaa89cec80e6aaac11977c7f6aa92ff63 /fs/btrfs
parentb34b086c1c1d934c5314d46ba25ccfa9acc471ae (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')
-rw-r--r--fs/btrfs/ioctl.c25
-rw-r--r--fs/btrfs/super.c3
2 files changed, 26 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 659out:
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
653static long btrfs_ioctl_add_dev(struct btrfs_root *root, void __user *arg) 664static 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;
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 84c3b66564d0..3814238d6eba 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -589,6 +589,9 @@ static long btrfs_control_ioctl(struct file *file, unsigned int cmd,
589 int ret = 0; 589 int ret = 0;
590 int len; 590 int len;
591 591
592 if (!capable(CAP_SYS_ADMIN))
593 return -EPERM;
594
592 vol = kmalloc(sizeof(*vol), GFP_KERNEL); 595 vol = kmalloc(sizeof(*vol), GFP_KERNEL);
593 if (copy_from_user(vol, (void __user *)arg, sizeof(*vol))) { 596 if (copy_from_user(vol, (void __user *)arg, sizeof(*vol))) {
594 ret = -EFAULT; 597 ret = -EFAULT;