[PATCH] ext4: fix potential deadlock with setuid files and EXT4_IOC_MOVE_EXT

From: Theodore Ts'o
Date: Tue Dec 20 2011 - 17:06:08 EST


file_remove_suid() must be called with i_mutex down, since it calls
notify_change(). In addition, we really want to remove the suid file
*before* we modify the donor file, to avoid someone from trying to
exploit a race.

Signed-off-by: "Theodore Ts'o" <tytso@xxxxxxx>
Cc: stable@xxxxxxxxxxxxxxx
---
fs/ext4/ioctl.c | 2 --
fs/ext4/move_extent.c | 2 ++
2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
index a567968..ff1aab7 100644
--- a/fs/ext4/ioctl.c
+++ b/fs/ext4/ioctl.c
@@ -247,8 +247,6 @@ setversion_out:
err = ext4_move_extents(filp, donor_filp, me.orig_start,
me.donor_start, me.len, &me.moved_len);
mnt_drop_write(filp->f_path.mnt);
- if (me.moved_len > 0)
- file_remove_suid(donor_filp);

if (copy_to_user((struct move_extent __user *)arg,
&me, sizeof(me)))
diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c
index c5826c6..7403e1b 100644
--- a/fs/ext4/move_extent.c
+++ b/fs/ext4/move_extent.c
@@ -1222,6 +1222,8 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp,
if (ret1)
goto out;

+ file_remove_suid(d_filp);
+
file_end = (i_size_read(orig_inode) - 1) >> orig_inode->i_blkbits;
block_end = block_start + len - 1;
if (file_end < block_end)
--
1.7.8.11.gefc1f.dirty

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/