diff options
author | Jiri Kosina <jkosina@suse.cz> | 2010-02-03 01:10:39 +0300 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2010-02-03 01:10:39 +0300 |
commit | e1a0bdd8022317e98650e70850de73eccfcde5ad (patch) | |
tree | 462f63307118b95c8cbacee6954e4d09ee85b8d1 /fs/ext4/ioctl.c | |
parent | 8127f4e883666c9960cfa89cffd36313748f8bab (diff) | |
parent | 1a45dcfe2525e9432cb4aba461d4994fc2befe42 (diff) | |
download | linux-e1a0bdd8022317e98650e70850de73eccfcde5ad.tar.xz |
Merge branch 'master' into upstream
Conflicts:
drivers/hid/hid-ids.h
Diffstat (limited to 'fs/ext4/ioctl.c')
-rw-r--r-- | fs/ext4/ioctl.c | 29 |
1 files changed, 18 insertions, 11 deletions
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c index c1cdf613e725..b63d193126db 100644 --- a/fs/ext4/ioctl.c +++ b/fs/ext4/ioctl.c @@ -221,31 +221,38 @@ setversion_out: struct file *donor_filp; int err; + if (!(filp->f_mode & FMODE_READ) || + !(filp->f_mode & FMODE_WRITE)) + return -EBADF; + if (copy_from_user(&me, (struct move_extent __user *)arg, sizeof(me))) return -EFAULT; + me.moved_len = 0; donor_filp = fget(me.donor_fd); if (!donor_filp) return -EBADF; - if (!capable(CAP_DAC_OVERRIDE)) { - if ((current->real_cred->fsuid != inode->i_uid) || - !(inode->i_mode & S_IRUSR) || - !(donor_filp->f_dentry->d_inode->i_mode & - S_IRUSR)) { - fput(donor_filp); - return -EACCES; - } + if (!(donor_filp->f_mode & FMODE_WRITE)) { + err = -EBADF; + goto mext_out; } + err = mnt_want_write(filp->f_path.mnt); + if (err) + goto mext_out; + err = ext4_move_extents(filp, donor_filp, me.orig_start, me.donor_start, me.len, &me.moved_len); - fput(donor_filp); + mnt_drop_write(filp->f_path.mnt); + if (me.moved_len > 0) + file_remove_suid(donor_filp); if (copy_to_user((struct move_extent *)arg, &me, sizeof(me))) - return -EFAULT; - + err = -EFAULT; +mext_out: + fput(donor_filp); return err; } |